Atlanta Custom Software Development 

 
   Search        Code/Page
 

User Login
Email

Password

 

Forgot the Password?
Services
» Web Development
» Maintenance
» Data Integration/BI
» Information Management
Programming
  Database
Automation
OS/Networking
Graphics
Links
Tools
» Regular Expr Tester
» Free Tools


This article will show you use of NetGroupAdd/NetGroupDel, NetGroupAddUser/NetGroupDelUser, NetLocalGroupAdd/NetLocalGroupDel and NetLocalGroupAddMembers/NetLocalGroupDelMembers API to for group management.

Windows NT and Windows 2000 exposes LanMan 32-bit Application Programming Interfaces (APIs) to provide network services. These APIs are called only from 32-bit programs running on a Windows NT or Windows 2000 and are used to control both the local and remote Windows NT (or Windows 2000) machines that you have permission to access.

Note:
WhileWindows2000supportsLanManAPIsforbackwardscompatibilityitisrecommendedthatADSIbeusedinsteadformostofthefunctionsbelow.FormoreinformationaboutADSIsearchforActiveDirectoryServicesInterfaceorADSIintheMicrosoftKnowledgeBaseorMSDN
This article contains code examples of using the following LanMan APIs:
NetGroupAddNetGroupDelNetGroupAddUserNetGroupDelUserNetLocalGroupAddNetLocalGroupDelNetLocalGroupAddMembersNetLocalGroupDelMembersNetAPIBufferFreeNetAPIBufferAllocateStrToPt
Note: LAN Manager APIs use various level of structures. You can use any supported level depending on information required. For example in this article I have used NetGroupAdd API with level-1 structure GROUP_INFO_1 but you can also use GROUP_INFO_2 or GROUP_INFO_3 depending on information you want to specify when you add the group.

Although, Visual Basic stores strings internally as UNICODE, it converts them to ANSI when it calls APIs. Normally this isn't a problem because most 32-bit APIs have both an ANSI and a UNICODE version. However, LanMan APIs only support UNICODE. The code snippet below demonstrates how to use Byte arrays to pass UNICODE parameters.

Instead of using strings, for example:

Click here to copy the following block
X = My_ANSI_API("Some String")


use Byte arrays, such the one below, because they aren't converted to ANSI:

Click here to copy the following block
Dim Temp() As Byte, Message As String
Message = "Some String"
Temp = Message & vbNullChar   '
MyUnicodeAPI Temp(0)
Message = Temp         ' modified me

Now lets check the actual code which will first add sample user TestUser1 on local machine and then it will delete that account.

Step-By-Step Example

- Create a standard exe project
- Add the following code in form1

Click here to copy the following block
Const NERR_BASE = 2100
Const ERROR_ACCESS_DENIED = 5&
Const NERR_GroupNotFound As Long = (NERR_BASE + 120)
Const ERROR_NO_SUCH_MEMBER As Long = 1387&
Const ERROR_MEMBER_IN_ALIAS As Long = 1378&
Const ERROR_INVALID_MEMBER As Long = 1388&

Private Type GROUP_INFO_1
  ptrname As Long
  ptrcomment As Long
End Type

Private Type LOCALGROUP_MEMBERS_INFO_3
  lgrmi3_domainandname As Long
End Type

'//
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 StrToPtr Lib "Kernel32" Alias "lstrcpyW" _
    (ByVal Ptr As Long, Source As Byte) As Long

'//global group functions
Private Declare Function NetGroupAdd1 Lib "NETAPI32.dll" Alias "NetGroupAdd" _
    (servername As Byte, ByVal Level As Long, Buffer As GROUP_INFO_1, ParmError As Long) As Long
Private Declare Function NetGroupDel Lib "NETAPI32.dll" _
    (servername As Byte, groupname As Byte) As Long
Private Declare Function NetGroupAddUser Lib "NETAPI32.dll" _
    (servername As Byte, groupname As Byte, UserName As Byte) As Long
Private Declare Function NetGroupDelUser Lib "NETAPI32.dll" _
    (servername As Byte, groupname As Byte, UserName As Byte) As Long

'//local group functions
Private Declare Function NetLocalGroupAdd1 Lib "NETAPI32.dll" Alias "NetLocalGroupAdd" _
    (servername As Byte, ByVal Level As Long, Buffer As GROUP_INFO_1, ParmError As Long) As Long
Private Declare Function NetLocalGroupDel Lib "NETAPI32.dll" _
    (servername As Byte, groupname As Byte) As Long
Private Declare Function NetLocalGroupAddMembers Lib "NETAPI32.dll" _
    (servername As Byte, groupname As Byte, _
    ByVal Level As Long, buf As LOCALGROUP_MEMBERS_INFO_3, ByVal totalentries As Long) As Long
Private Declare Function NetLocalGroupDelMembers Lib "NETAPI32.dll" _
    (servername As Byte, groupname As Byte, _
    ByVal Level As Long, buf As LOCALGROUP_MEMBERS_INFO_3, ByVal totalentries As Long) As Long

Function AddUsersToGroup(ByVal servername As String, ByVal groupname As String, _
  Users() As String, Optional IsLocalGroup As Boolean = True) As Long

  On Error GoTo errHandler

  Dim UNPtr() As Long, nUsers As Long, i As Long
  Dim SNArray() As Byte, GNArray() As Byte, UNArray() As Byte
  Dim ULocalArray() As LOCALGROUP_MEMBERS_INFO_3

  ' Move to byte arrays
  SNArray = IIf(Left(servername, 2) = "\\", servername & vbNullChar, "\\" & servername & vbNullChar)
  GNArray = groupname & vbNullChar

  nUsers = UBound(Users) + 1

  If IsLocalGroup = True Then
    ReDim ULocalArray(nUsers - 1)  '//Resize the array to hold all user info
    ReDim UNPtr(nUsers - 1)  '//Resize the array to hold pointers to name strings

    For i = 0 To nUsers - 1
      If InStr(1, Users(i), "\") >= 1 Then
        UNArray = Users(i) & vbNullChar  '//domainname included (e.g. mydomain\user1)
      Else
        UNArray = "\" & Users(i) & vbNullChar  '//domainname not included so just add "\"
      End If

      result = NetAPIBufferAllocate(UBound(UNArray) + 1, UNPtr(i))
      result = StrToPtr(UNPtr(i), UNArray(0))

      '//ok assign the pointer which contains <domain>\<username> (e.g. mydomain\testuser1)
      ULocalArray(i).lgrmi3_domainandname = UNPtr(i)
    Next
    '//Add n users in one API call
    AddUsersToGroup = NetLocalGroupAddMembers(SNArray(0), GNArray(0), 3, ULocalArray(0), nUsers)
    For i = 0 To nUsers - 1
      Call NetAPIBufferFree(UNPtr(i))
    Next
  Else
    '//Unlike NetLocalGroupAddMembers here you have to execute NetGroupAddUser API n times to add n users
    For i = 0 To nUsers - 1
      If InStr(1, Users(i), "\") >= 1 Then
        UNArray = Users(i) & vbNullChar  '//domainname included (e.g. mydomain\user1)
      Else
        UNArray = "\" & Users(i) & vbNullChar  '//domainname not included so just add "\"
      End If

      AddUsersToGroup = NetGroupAddUser(SNArray(0), GNArray(0), UNArray(0))
      Debug.Print AddUsersToGroup
    Next
  End If

errHandler:
End Function

Function DelUsersFromGroup(ByVal servername As String, ByVal groupname As String, _
  Users() As String, Optional IsLocalGroup As Boolean = True) As Long

  On Error GoTo errHandler

  Dim UNPtr() As Long, nUsers As Long, i As Long
  Dim SNArray() As Byte, GNArray() As Byte, UNArray() As Byte
  Dim ULocalArray() As LOCALGROUP_MEMBERS_INFO_3

  ' Move to byte arrays
  SNArray = IIf(Left(servername, 2) = "\\", servername & vbNullChar, "\\" & servername & vbNullChar)
  GNArray = groupname & vbNullChar

  nUsers = UBound(Users) + 1

  If IsLocalGroup = True Then
    ReDim ULocalArray(nUsers - 1)  '//Resize the array to hold all user info
    ReDim UNPtr(nUsers - 1)  '//Resize the array to hold pointers to name strings

    For i = 0 To nUsers - 1
      If InStr(1, Users(i), "\") >= 1 Then
        UNArray = Users(i) & vbNullChar  '//domainname included (e.g. mydomain\user1)
      Else
        UNArray = "\" & Users(i) & vbNullChar  '//domainname not included so just add "\"
      End If

      result = NetAPIBufferAllocate(UBound(UNArray) + 1, UNPtr(i))
      result = StrToPtr(UNPtr(i), UNArray(0))

      '//ok assign the pointer which contains <domain>\<username> (e.g. mydomain\testuser1)
      ULocalArray(i).lgrmi3_domainandname = UNPtr(i)
    Next
    '//Add n users in one API call
    DelUsersFromGroup = NetLocalGroupDelMembers(SNArray(0), GNArray(0), 3, ULocalArray(0), nUsers)

    For i = 0 To nUsers - 1
      Call NetAPIBufferFree(UNPtr(i))
    Next
  Else
    '//Unlike NetLocalGroupAddMembers here you have to execute NetGroupAddUser API n times to add n users
    For i = 0 To nUsers - 1
      If InStr(1, Users(i), "\") >= 1 Then
        UNArray = Users(i) & vbNullChar  '//domainname included (e.g. mydomain\user1)
      Else
        UNArray = "\" & Users(i) & vbNullChar  '//domainname not included so just add "\"
      End If

      DelUsersFromGroup = NetGroupDelUser(SNArray(0), GNArray(0), UNArray(0))
    Next
  End If

errHandler:
End Function

Function AddGroup(ByVal servername As String, ByVal groupname As String, _
  ByVal GroupComment As String, Optional IsLocalGroup As Boolean = True) As Long

  Dim result As Long, GNPtr As Long, GCPtr As Long, ParmError As Long
  Dim SNArray() As Byte, GNArray() As Byte, GCArray() As Byte
  Dim GroupStruct As GROUP_INFO_1
  '
  ' Move to byte arrays
  '
  SNArray = servername & vbNullChar
  GNArray = groupname & vbNullChar
  GCArray = GroupComment & vbNullChar

  '
  ' Allocate buffer space
  '
  result = NetAPIBufferAllocate(UBound(GNArray) + 1, GNPtr)
  result = NetAPIBufferAllocate(UBound(GCArray) + 1, GCPtr)
  '
  ' Copy arrays to the buffer
  '
  result = StrToPtr(GNPtr, GNArray(0))
  result = StrToPtr(GCPtr, GCArray(0))

  '
  ' Fill the structure
  '
  With GroupStruct
    .ptrname = GNPtr
    .ptrcomment = GCPtr
  End With
  '
  ' Add the Group
  '
  If IsLocalGroup = False Then
    result = NetGroupAdd1(SNArray(0), 1, GroupStruct, ParmError)
  Else
    result = NetLocalGroupAdd1(SNArray(0), 1, GroupStruct, ParmError)
  End If

  AddGroup = result
  If result <> 0 Then
    Debug.Print "Error " & result & " in parameter " & ParmError _
        & " when adding group " & groupname
  End If
  '
  ' Release buffers from memory
  '
  result = NetAPIBufferFree(GNPtr)
  result = NetAPIBufferFree(GCPtr)
End Function

Function DelGroup(ByVal servername As String, ByVal groupname As String, _
  Optional IsLocalGroup As Boolean = True) As Long

  Dim GNArray() As Byte, SNArray() As Byte
  GNArray = groupname & vbNullChar
  SNArray = servername & vbNullChar
  If IsLocalGroup = True Then
    DelGroup = NetLocalGroupDel(SNArray(0), GNArray(0))
  Else
    DelGroup = NetGroupDel(SNArray(0), GNArray(0))
  End If
End Function

Function GetError(errCode As Long) As String
  Select Case errCode
    Case NERR_GroupNotFound
      GetError = "The local group specified by the groupname parameter does not exist."
    Case ERROR_INVALID_MEMBER
      GetError = "One or more of the members cannot be added because their " & _
          "account type is invalid. No new members were added."
    Case ERROR_MEMBER_IN_ALIAS
      GetError = "One or more of the members specified were already members " & _
          "of the local group. No new members were added."
    Case ERROR_NO_SUCH_MEMBER
      GetError = "One or more of the members specified do not exist. " & _
          "Therefore, no new members were added."
    Case ERROR_ACCESS_DENIED
      GetError = "Access is denied"
    Case Else
      GetError = "Error#" & Err.LastDllError
  End Select
End Function

Private Sub Form_Load()
  Dim ret As Long

  '========================================
  '[1] Create a local/global group
  '========================================
  '//Note: If server is remote machine then you must specify name starting with "\\"
  '//You can leave servername blank or put "." if its local machine
  ret = AddGroup(".", "TestGroup1", "This is jsut testing group", True)

  If ret = 0 Then
    MsgBox "Group added", vbInformation
  Else
    MsgBox GetError(ret)
  End If

  '========================================
  '[2] Add users to local/global group
  '========================================

  '//Add guest to TestGroup1 group
  '//Note: By default guest user is created when u install so its easy for demo

  '//To Add Multiple users
  'Dim Users(2) As String
  'Users(0) = "it100626\User1"
  'Users(1) = "it100626\User2"
  'Users(2) = "it100626\User2"

  Dim UsersToAdd(1) As String
  'Users(0) = "mymachine\guest" 'or "guest" or "\guest
  UsersToAdd(0) = "guest"
  UsersToAdd(1) = "administrator"

  ret = AddUsersToGroup(".", "TestGroup1", UsersToAdd, True)

  If ret = 0 Then
    MsgBox "User added to group", vbInformation
  Else
    MsgBox GetError(ret)
  End If

  '========================================
  '[3] Remove users from local/global group
  '========================================
  ret = MsgBox("Do you want to remove user(s) from the group which you just added?", vbQuestion + vbYesNo)
  If ret = vbYes Then

    Dim UsersToRemove(0) As String
    'Users(0) = "mymachine\guest" 'or "guest" or "\guest
    UsersToRemove(0) = "guest"

    ret = DelUsersFromGroup(".", "TestGroup1", UsersToRemove, True)

    If ret = 0 Then
      MsgBox "User removed from group", vbInformation
    Else
      MsgBox GetError(ret)
    End If
  End If

  '========================================
  '[4] Delete local/global group
  '========================================
  ret = MsgBox("Do you want to delete the Group which you just added?", vbQuestion + vbYesNo)
  If ret = vbYes Then
    ret = DelGroup(".", "TestGroup1", True)
    If ret = 0 Then
      MsgBox "Group Deleted", vbInformation
    Else
      MsgBox GetError(ret)
    End If
  End If
End Sub


Submitted By : Nayan Patel  (Member Since : 5/26/2004 12:23:06 PM)

Job Description : He is the moderator of this site and currently working as an independent consultant. He works with VB.net/ASP.net, SQL Server and other MS technologies. He is MCSD.net, MCDBA and MCSE. In his free time he likes to watch funny movies and doing oil painting.
View all (893) submissions by this author  (Birth Date : 7/14/1981 )


Home   |  Comment   |  Contact Us   |  Privacy Policy   |  Terms & Conditions   |  BlogsZappySys

© 2008 BinaryWorld LLC. All rights reserved.