HOWTO: Call NetUserGetInfo API from Visual Basic

ID: Q151774


The information in this article applies to:


SUMMARY

The NetUserGetInfo function is a Unicode-only Windows NT API. The last parameter of this function is a pointer to a pointer to a structure whose members contain DWORD data and pointers to Unicode strings. In order to call this function correctly from a Visual Basic application, you need to de-reference the pointer returned by the function and then you need to convert the Visual Basic string to a Unicode string and vice versa. This article illustrates these techniques in an example that calls NetUserGetInfo to retrieve a USER_INFO_3 structure from a Visual Basic application.


MORE INFORMATION

The example below uses the Win32 RtlMoveMemory function to de-reference the pointer returned by the NetUserGetInfo call. For more information on how to declare and use RtlMoveMemory function in Visual Basic, please see the following article in the Microsoft Knowledge Base:

Q129947 : INFO: Win32 Replacement for the hmemecpy Function

For more information on how to convert Visual Basic string to Unicode string and vice versa, please see the following article in the Microsoft Knowledge Base:
Q145727 : HOWTO: Call the Unicode Version of an API Function with VB

NOTE: In order to run the code in the example, you need to change the NT domain logon name in step 5 to your valid NT domain logon name. An invalid domain logon name will cause the application to GPF.

Step-by-Step Example

  1. Start Visual Basic. If Visual Basic is already running, from the File menu, choose New Project. Form1 is created by default.


  2. Add a Command button, Command1, to Form1.


  3. Add the following code to the General Declarations section of Form1
    
         Option Explicit
               'USER_INFO_3 structure is defined in Win32 SDK, below is the VB
               'declare.
               'LPWSTR is a pointer to a Unicode string.
               'The storage of the USER_INFO_3  structure, including the string
               'buffer referred by its LPWSTR members, are all allocated by
               'Windows NT so the function caller doesn't have to allocate
               'memory.
    
               Private Type USER_INFO_3
                   usri3_name As Long           'LPWSTR in SDK
                   usri3_password As Long       'LPWSTR in SDK
                   usri3_password_age As Long      'DWORD in SDK
                   usri3_priv As Long           'DWORD in SDK
                   usri3_home_dir As Long       'LPWSTR in SDK
                   usri3_comment As Long        'LPWSTR in SDK
                   usri3_flags As Long          'DWORD in SDK
                   usri3_script_path As Long    'LPWSTR in SDK
                   usri3_auth_flags As Long        'DWORD in SDK
                   usri3_full_name As Long         'LPWSTR in SDK
                   usri3_usr_comment As Long    'LPWSTR in SDK
                   usri3_parms As Long          'LPWSTR in SDK
                   usri3_workstations As Long      'LPWSTR in SDK
                   usri3_last_logon As Long        'DWORD in SDK
                   usri3_last_logoff As Long    'DWORD in SDK
                   usri3_acct_expires As Long      'DWORD in SDK
                   usri3_max_storage As Long    'DWORD in SDK
                   usri3_units_per_week As Long    'DWORD in SDK
                   usri3_logon_hours As Long    'PBYTE in SDK
                   usri3_bad_pw_count As Long      'DWORD in SDK
                   usri3_num_logons As Long        'DWORD in SDK
                   usri3_logon_server As Long      'LPWSTR in SDK
                   usri3_country_code As Long      'DWORD in SDK
                   usri3_code_page As Long         'DWORD in SDK
                   usri3_user_id As Long        'DWORD in SDK
                   usri3_primary_group_id As Long  'DWORD in SDK
                   usri3_profile As Long        'LPWSTR in SDK
                   usri3_home_dir_drive As Long    'LPWSTR in SDK
                   usri3_password_expired As Long  'DWORD in SDK
               End Type
    
               Private Declare Function NetUserGetInfo Lib "netapi32.dll" ( _
                  strServerName As Any, strUserName As Any, ByVal dwLevel As
         Long, _
                  pBuffer As Long) As Long
    
               Private Declare Sub CopyMemory Lib "kernel32" Alias
         "RtlMoveMemory" _
                  (hpvDest As Any, ByVal hpvSource As Long, ByVal cbCopy As
         Long)
    
               Private Declare Function NetApiBufferFree Lib "netapi32" _
                 (ByVal Buffer As Long) As Long
    
               Private Declare Sub lstrcpyW Lib "kernel32" _
                  (dest As Any, ByVal src As Any)
    
               Private Declare Function NetGetDCName Lib "netapi32.dll" ( _
                  ServerName As Long, domainname As Byte, bufptr As Long) _
                  As Long
    
               Private Sub Command1_Click()
                   Dim result As Long
                   Dim pServer() As Byte, pUser() As Byte
    
                   Dim sDomainDCName As String
                   'You need to change "Your_User_Account_Domain" in the next
                   'line to your valid NT User domain name.
                   sDomainDCName = GetPrimaryDCName("Your_User_Account_Domain")
                   MsgBox sDomainDCName
    
                   'You need to change "Your_Domain_Logon_Name" in the next
                   'line to your valid NT domain logon name.
    
                   pUser = "Your_Domain_Logon_Name" & vbNullChar
                   pServer = sDomainDCName & vbNullChar
    
                   'The above two lines convert VB string to Unicode string.
    
                   'To check a local user account on local machine
                   'pUser = "Local_User_Name" & vbNullChar
                   'pServer = "\\Machine_Name" & vbNullChar
    
                   Dim dwLevel As Long
                   dwLevel = 3
    
                   Dim tmpBuffer As USER_INFO_3
                   Dim ptmpBuffer As Long
    
                   'As last param is dimmed as long, the pointer to ptmpBuffer
                   'is passed to dll, and the function returns a pointer to a
                   'pointer to our UDT. Therefore ptmpBuffer on return holds a
                   'pointer to our UDT.
                   result = NetUserGetInfo(pServer(0), pUser(0), dwLevel, _
                            ptmpBuffer)
                   If result <> 0 Then
                     MsgBox "Error: " & result
                     Exit Sub
                   End If
    
                   'Deference it!!!
                   CopyMemory tmpBuffer, ptmpBuffer, LenB(tmpBuffer)
    
                   Dim sUser As String
                   Dim sByte() As Byte
                   ReDim sByte(255)
    
                   'Convert LPWSTR (Unicode string) to VB string.
                   CopyMemory sByte(0), tmpBuffer.usri3_name, 256
                   sUser = sByte
                   sUser = sUser & vbNullChar
                   MsgBox Trim$(sUser)
                   'Now I get my user name back, it's VB string now'
                   result = NetApiBufferFree(ptmpBuffer)
                   If result <> 0 Then
                     MsgBox "Error: " & result
                     Exit Sub
                   End If
               End Sub
    
             Public Function GetPrimaryDCName(ByVal DName As String) As String
    
                Dim DCName As String, DCNPtr As Long
                Dim DNArray() As Byte, DCNArray(100) As Byte
                Dim result As Long
    
                DNArray = DName & vbNullChar
                ' Lookup the Primary Domain Controller
                result = NetGetDCName(0&, DNArray(0), DCNPtr)
                If result <> 0 Then
                   MsgBox "Error: " & result
                   Exit Function
                End If
                lstrcpyW DCNArray(0), DCNPtr
                result = NetApiBufferFree(DCNPtr)
                DCName = DCNArray()
                GetPrimaryDCName = Left(DCName, InStr(DCName, Chr(0)) - 1)
    
                End Function
     


Additional query words: Unicode kbVBp600 kbVBp500 kbVBp400


Keywords          : kbnetwork kbAPI kbSDKPlatform kbVBp400 kbVBp500 kbVBp600 kbNetAPI kbGrpNet 
Version           : WINDOWS:5.0,6.0
Platform          : WINDOWS 
Issue type        : kbhowto 

Last Reviewed: May 11, 1999