Private Const LG_INCLUDE_INDIRECT As Long = &H1&
Private Type LOCALGROUP_MEMBERS_INFO_2 lgrmi2_sid As Long lgrmi2_sidusage As Long lgrmi2_domainandname As Long End Type
Private Type LOCALGROUP_USERS_INFO_0 lgrui0_name As Long End Type
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _ (Destination As Any, Source As Any, ByVal length As Long)
Private Declare Function NetAPIBufferFree Lib "NETAPI32.dll" Alias _ "NetApiBufferFree" (ByVal Ptr As Long) As Long Private Declare Function NetAPIBufferAllocate Lib "NETAPI32.dll" Alias _ "NetApiBufferAllocate" (ByVal ByteCount As Long, Ptr As Long) As Long Private Declare Function PtrToStr Lib "kernel32" Alias "lstrcpyW" _ (RetVal As Byte, ByVal Ptr As Long) As Long
Private Declare Function NetUserEnum Lib "NETAPI32.dll" _ (servername As Byte, ByVal level As Long, ByVal lFilter As Long, _ Buffer As Long, ByVal prefmaxlen As Long, entriesread As Long, _ totalentries As Long, ResumeHandle As Long) As Long
Private Declare Function NetUserGetGroups Lib "NETAPI32.dll" _ (servername As Byte, UserName As Byte, ByVal level As Long, _ Buffer As Long, ByVal prefmaxlen As Long, _ entriesread As Long, totalentries As Long) As Long Private Declare Function NetUserGetLocalGroups Lib "NETAPI32.dll" _ (servername As Byte, UserName As Byte, ByVal level As Long, _ ByVal Flags As Long, Buffer As Long, ByVal prefmaxlen As Long, _ entriesread As Long, totalentries As Long) As Long
Private Declare Function NetGroupEnum Lib "NETAPI32.dll" _ (servername As Byte, ByVal level As Long, Buffer As Long, ByVal _ prefmaxlen As Long, entriesread As Long, totalentries As Long, _ ResumeHandle As Long) As Long Private Declare Function NetLocalGroupEnum Lib "NETAPI32.dll" _ (servername As Byte, ByVal level As Long, Buffer As Long, ByVal _ prefmaxlen As Long, entriesread As Long, totalentries As Long, _ ResumeHandle As Long) As Long
Private Declare Function NetGroupGetUsers Lib "NETAPI32.dll" _ (servername As Byte, GroupName As Byte, _ ByVal level As Long, Buffer As Long, ByVal prefmaxlen As Long, _ entriesread As Long, totalentries As Long, ResumeHandle As Long) As Long Private Declare Function NetLocalGroupGetMembers Lib "NETAPI32.dll" _ (servername As Byte, localgroupname As Byte, _ ByVal level As Long, Buffer As Long, ByVal prefmaxlen As Long, _ entriesread As Long, totalentries As Long, ResumeHandle As Long) As Long
Const MACHINE_NAME = "." Const DOMAIN_NAME = ""
Function EnumerateGroups(ByVal SName As String, ByVal UName As String, _ retGroupCol As Collection, Optional IsLocalGroup As Boolean = True) As Long
Dim result As Long, bufptr As Long, entriesread As Long, _ totalentries As Long, ResumeHandle As Long, BufLen As Long, _ SNArray() As Byte, GNArray(99) As Byte, UNArray() As Byte, _ GName As String, i As Integer, UNPtr As Long SNArray = SName & vbNullChar UNArray = UName & vbNullChar BufLen = 255 ResumeHandle = 0
If UName = "" Then If IsLocalGroup = True Then result = NetLocalGroupEnum(SNArray(0), 0, bufptr, BufLen, _ entriesread, totalentries, ResumeHandle) Else result = NetGroupEnum(SNArray(0), 0, bufptr, BufLen, _ entriesread, totalentries, ResumeHandle) End If Else If IsLocalGroup = True Then result = NetUserGetLocalGroups(SNArray(0), UNArray(0), 0, 0, bufptr, _ BufLen, entriesread, totalentries) Else result = NetUserGetGroups(SNArray(0), UNArray(0), 0, bufptr, _ BufLen, entriesread, totalentries) End If End If
EnumerateGroups = result If result <> 0 And result <> 234 Then Debug.Print "Error " & result & " enumerating group " Exit Function End If
Dim ptrGroup As Long Dim nStructSize As Long
For i = 1 To entriesread Erase GNArray CopyMemory ptrGroup, ByVal bufptr + (4 * (i - 1)), 4 result = PtrToStr(GNArray(0), ptrGroup) GName = GNArray retGroupCol.Add GName Next i
result = NetAPIBufferFree(bufptr) End Function
Function EnumerateUsers(ByVal SName As String, ByVal GName As String, _ retUserCol As Collection, Optional IsLocalGroup As Boolean = True) As Long
Dim result As Long, bufptr As Long, entriesread As Long, _ totalentries As Long, ResumeHandle As Long, BufLen As Long, _ SNArray() As Byte, GNArray() As Byte, UNArray(99) As Byte, _ UName As String, i As Integer, UNPtr As Long
SNArray = SName & vbNullChar GNArray = GName & vbNullChar BufLen = 255 ResumeHandle = 0
If GName = "" Then result = NetUserEnum(SNArray(0), 0, FILTER_NORMAL_ACCOUNT, _ bufptr, BufLen, entriesread, totalentries, ResumeHandle) Else If IsLocalGroup = True Then result = NetLocalGroupGetMembers(SNArray(0), GNArray(0), 2, bufptr, _ BufLen, entriesread, totalentries, ResumeHandle) Else result = NetGroupGetUsers(SNArray(0), GNArray(0), 0, bufptr, _ BufLen, entriesread, totalentries, ResumeHandle)
End If End If
EnumerateUsers = result If result <> 0 And result <> 234 Then Debug.Print "Error " & result & " enumerating user " If result = 2220 Then Debug.Print "There is no **GLOBAL** group '" & GName & "'" Exit Function End If
Dim ptrUser As Long Dim lgr2 As LOCALGROUP_MEMBERS_INFO_2 Dim nStructSize As Long nStructSize = Len(lgr2) For i = 1 To entriesread Erase UNArray If GName <> "" And IsLocalGroup = True Then CopyMemory lgr2, ByVal bufptr + (nStructSize * (i - 1)), nStructSize result = PtrToStr(UNArray(0), lgr2.lgrmi2_domainandname) Else CopyMemory ptrUser, ByVal bufptr + (4 * (i - 1)), 4 result = PtrToStr(UNArray(0), ptrUser) End If
UName = UNArray retUserCol.Add UName Next i
result = NetAPIBufferFree(bufptr) End Function
Private Sub Form_Load() Dim ret As Long, i As Integer Dim colGroups As New Collection, colUsers As New Collection
ret = EnumerateGroups(MACHINE_NAME, "", colGroups, True) For i = 1 To colGroups.Count List1.AddItem colGroups(i) Next
ret = EnumerateUsers(MACHINE_NAME, "", colUsers, True) For i = 1 To colUsers.Count List2.AddItem colUsers(i) Next End Sub
Sub RefreshGroupUsersList() Dim ret As Long, i As Integer, GroupName As String Dim colGroupUsers As New Collection
If List1.ListIndex < 0 Then Exit Sub
List2.Clear GroupName = DOMAINNAME & "\" & List1.List(List1.ListIndex) & vbNullChar ret = EnumerateUsers(MACHINE_NAME, GroupName, colGroupUsers, True)
For i = 1 To colGroupUsers.Count List2.AddItem colGroupUsers(i) Next End Sub
Sub RefreshUserGroupsList() Dim ret As Long, i As Integer, UserName As String Dim colUserGroups As New Collection
If List2.ListIndex < 0 Then Exit Sub
List3.Clear UserName = DOMAINNAME & "\" & List2.List(List2.ListIndex) & vbNullChar ret = EnumerateGroups(MACHINE_NAME, UserName, colUserGroups, True)
For i = 1 To colUserGroups.Count List3.AddItem colUserGroups(i) Next End Sub
Private Sub List1_Click() RefreshGroupUsersList If List2.ListCount > 0 Then List2.ListIndex = 0 End Sub
Private Sub List2_Click() RefreshUserGroupsList End Sub |