Seite 1 von 1

WinApi Funktion NetUserGetLocalGroups

Verfasst: 11.01.2014 17:14
von Oskar
Hallo,

ich stelle hier die Windows API funktion "NetUserGetLocalGroups" ein.

Die Funktion gibt die Gruppenmitgliedschaft eines Users am lokalen PCs wieder. Diese Funktion braucht keine Admin-Rechte.
Sie funktioniert auch einwandfrei im Heim-Netzwerk. Wenn ich allerdings an einem Remot-PC eine Anfrage stelle muss ein
User an diesem eingeloggt sein. Die Funktion selber braucht am Remote-PC ansonsten keine Rechte oder Passwörter.
Nur der Name des Remote-PC muss vorhanden sein.

Ich brauch diese Funktion, habe allerdings nichts passendes gefunden, ausser alles mit C++ oder C# Code.
Ich habe diese Funktion weitestgehend durch Kommentiert, damit man auch alles nachvollziehen kann.
In dieser Funktion ist auch eine Prozedur die Unicode nach ASCI umwandelt bzw. filtert, sie ist auch in andern Windows APIs
sehr nützlich. Vieleicht hat der eine oder andere an diese Funktion einen Verwendungszweck.

Viel Spass damit



Code: Alles auswählen

;Orginal Beschreibung MSDN zur Funktion
;nStatus = NetUserGetLocalGroups(Servername, UserName, dwLevel, dwFlags, pBuf,   dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries)
;In Purebasic umgesetzt         ( #Null    , UserName, #Null  , #Null  ,@Ptr_Buf, PrefMaxLen , @CountRead    , @CountTotal    )

Declare.s NetUser_GetGroup(Str1.s, Str2.s)       ;Procedure "NetUserGetLocalGroups()" dem Programm bekannt geben
Declare.s Convert_Unicode_to_ASCI(ab.i, bc.i)    ;Procedure "Convert_Unicode_to_ASCI(ab.i, bc.i)"

PC_Name.s = ""                                   ;Falls der PC im Netzwerk steht PC_Name angeben (Heim-Netzwerk) ein User muss eingeloggt sein
UsrGroup.s = UserName()
MessageRequester("", "Der User " + UsrGroup + " ist Mitglied in: " + NetUser_GetGroup(UsrGroup, PC_Name), 0)  ;Ergebniss der Funktion ausgeben




Procedure.s NetUser_GetGroup(UserName.s, ServerName.s)        ;Anfang Procedure NetUserGetLocalGroups()
DLL = OpenLibrary(#PB_Any, "netapi32.dll")         ;Die DLL "netapi32.dll" fuer Funktionsaufrufe bereitstellen

  Protected MeineGruppe.s = ""                     ;MeineGruppe Mitgliedschaft des Benutzer wird von der Funktion zurueck gegeben
  Protected Ptr_Buf.i = 0                          ;Ein Zeiger auf den Puffer, der die Daten empfaengt 
  Protected Flags.i = 0                            ;Eine Bitmaske von Flags, Derzeit ist nur der Wert "LG_INCLUDE_INDIRECT" definiert = "0"
  Protected PrefMaxLen.i = 512                     ;Laenge in Bytes, des Puffers
  Protected CountRead.i = 0                        ;Ein Zeiger, der die Anzahl der tatsaechlichen Elemente gezaehlt hat
  Protected CountTotal.i = 0                       ;Ein Zeiger, der die Gesamtzahl der Eintraege erhaelt, die aufgezaehlt werden konnten
  Protected nStatus.i = 0                          ;Ergebniss = 0 OK andernfalls Fehler

  If DLL
    NUGLG = GetFunction(DLL, "NetUserGetLocalGroups")  ;Ist die Funktion in der OpenLibrary vorhanden ?
    nStatus = NetUserGetLocalGroups_(ServerName, UserName, #Null, #Null, @Ptr_Buf, PrefMaxLen, @CountRead, @CountTotal)
  Else
    MessageRequester("", "Achtung: Funktion nicht bekannt ", 0)
  EndIf

  If nStatus = 0                                   ; Wenn Funktions-Aufruf fehlerfrei dann
    MeineGruppe = Convert_Unicode_to_ASCI(Ptr_Buf, PrefMaxLen)   ;Mit "Convert_Unicode_to_ASCI" den Speicher auslesen und Umwandeln
  Else
    MeineGruppe = "Benutzer oder Computer nicht gefunden"
  EndIf

  NetApiBufferFree_(Ptr_Buf)
  CloseLibrary(DLL)
  ProcedureReturn MeineGruppe
EndProcedure


Procedure.s Convert_Unicode_to_ASCI(CUTA_Par1, CUTA_Par2)   ;Liest den reservierten Speicher aus und wandelt Unicode nach ASCI
  
  Protected AnfangMEM.i = CUTA_Par1                         ;Speicher Adresse aus Rueckgabe der Funktion NetUserGetLocalGroups
  Protected EndeMEM.i = CUTA_Par1 + CUTA_Par2 - 2           ;Groesse des reservierten Puffers aus NetUserGetLocalGroups
  Protected NullCount.b = 0                                 ;- 2 weil UniCode 2 Byte, dies ist das letzte Zeichen vo dem Ende
  Protected CountLoop.i = 0
  Protected StartASCI.i = 0
  Protected Test.i = 0
  Protected Result.s = ""
                                                            ;Hier wird das erste ASCI Zeichen gesucht ACHTUNG UniCode immer 2 Bytes
  For CountLoop = EndeMEM To AnfangMEM Step - 2             ;Start Lesen immer 2 Bytes wegen Unicode
    Test = PeekU(CountLoop)                                 ;Aus Speicher lesen
      If Test=0                                             ;Testen ob ASCI Zeichen oder Null Byte
        NullCount = NullCount + 1                           ;Ist Null Byte dann Zaehler erhoehen
      Else                                                  ;Ist ASCI Zeichen dann Zaehler zurueck setzen
        NullCount = 0
      EndIf  
    If NullCount = 2                                        ;Ist Zaehler auf 2 dann ist das Ende der ASCII Zeichen erreicht
      StartASCI = CountLoop + 4                             ;CountLoop = 4, hiermit wird der Zeiger auf das 1 Zeichen am Anfang gesetzt
      CountLoop = AnfangMEM                                 ;Bedingung fuer Schleifen-Abbruch setzen
    EndIf
  Next CountLoop                                            ;Lese solange bis Endadresse erreicht ist
  
  
  For CountLoop = StartASCI To EndeMEM Step 2               ;Start Lesen immer 2 Bytes wegen Unicode
    Test = PeekU(CountLoop)                                 ;Aus Speicher lesen
    If Test=<31 Or Test=>123                                ;Da Unicode Werte von 0 bis 65535 haben kann muss gefiltert werden
      If Test=0                                             ;Ist Test = 0 so ist das 1 Wort komplett gelesen und es wird
        Result = Result + ","                               ;zur besseren lesbarkeit ein Komma als Trennung eingefuegt
      EndIf
      Test = 0                                              ;
    Else                                                    ;Ein ASCI Zeichen ab "32 = Space bis 122 = z" ist enthalten baue, den
      Result = Result + Chr(Test)                           ;String zusammen
      Test = 0
    EndIf
  Next CountLoop                                            ;Lese solange bis Endadresse erreicht ist
  
 ProcedureReturn Result
EndProcedure
__________________________________________________
Code-Tags hinzugefügt
11.01.2014
RSBasic

Re: WinApi Funktion NetUserGetLocalGroups

Verfasst: 11.01.2014 17:21
von ts-soft
Bitte Code Tags setzen:
[ code ] hier der code [ /code ]
aber ohne die Spaces in den eckigen Klammern.

>> In dieser Funktion ist auch eine Prozedur die Unicode nach ASCI umwandelt
Das kann man aber in PB wesentlich eleganter lösen, siehe Dir hierzu mal die
PeekS und PokeS funktionen an :wink:

Gruß
Thomas

Re: WinApi Funktion NetUserGetLocalGroups

Verfasst: 11.01.2014 18:03
von Oskar
Ist mein erster Code,
wusste nichts von den Klammern. Entschuldigung

Ich habe eigentlich PeekU benutzt um die Anfangs-Position des Strings
zu ermitteln. Der Pointer der von der Funktion zurück gegeben wird
ist der Anfang des Puffers. Der Puffer muss natülich gross genug sein.
Die Funktion schreibt aber den Puffer vom Ende zum Anfang voll.

Am Anfang dieses Puffers liegen jede menge Sonderzeichen. Das
kann man mit der Speicheranzeige sehen. Bei PeekS muss ich aber eine
Adresse vorgeben wo der String liegt die habe ich aber noch nicht.
Erst wenn ich die Adresse des ersten Sting ermittelt habe könnte
ich PeekS einsetzen. Das ist in der Tat dann eleganter.

Aber was soll ich mit Poke machen.
Ich muss doch den Speicher auslesen. Mit Poke schreibt man doch ?

Gruss
Oskar

Re: WinApi Funktion NetUserGetLocalGroups

Verfasst: 11.01.2014 18:11
von ts-soft
Mit PeekS ... kannst Du Unicode, ASCII oder UTF-8 auslesen. Mit PokeS kannst Du strings
in anderer Kodierung in den Speicher poken. Damit sollte sich eigentlich jede erforderliche
Umwandlung "Crossplattform" möglich sein. Mehr wollte ich damit nicht sagen.
Keine API und kein kriechen durch ein chararray nötig :mrgreen:

Nur immer bedenken, sobald der String einer PB-Stringvariablen zugeordnet wird, hat der
String das Format, welches in den Compileroptionen gewählt wurde, also ASCII oder Unicode.