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