Visual Basic Network Services
NetWkstaUserEnum: Workstation Logon Information
Posted:   Monday June 25, 2001
Updated:   Monday December 26, 2011
Applies to:   VB4-32, VB5, VB6
Developed with:   VB6, Windows 2000
OS restrictions:   Windows NT3.1, Windows NT4, Windows 2000, Windows XP
Author:   VBnet - Randy Birch


NetServerEnum: Obtain Domain/Workgroup Servers and Machines
NetServerEnum: Get Version Info for Domain/Workgroup Servers and Machines

NetWkstaGetInfo: Workstation Configuration Information
NetWkstaGetInfo: Workstation Configuration and Current User 
NetWkstaGetInfo: Workstation Configuration and Logon Information 

For this demo, one of the operating systems listed under OS Restrictions above.

NetWkstaUserEnum lists information about all users currently logged on to the workstation, including service and batch logons, as well as interactive user logons. No flag is provided in the returned WKSTA_USER_INFO_0 or WKSTA_USER_INFO_1 data that specifies what a particular entry type is. 

As the illustration shows, NetWkstaUserEnum lists currently logged users to the specified workstation showing the username, logon domain, logon server and, where applicable, additional domains (returned in a single string separated by spaces). On my machine, set up only as a workgroup (no logon domain internally), the call returns (quite correctly) my primary Win2000 development computer's name as both the logon server and domain as the illustration reflects. NetWkstaUserEnum requires NT or later, and is unsupported on Win9x. 

On Windows NT, only members of the Administrators local group can successfully execute NetWkstaUserEnum function both locally and on a remote server.

On Windows 2000 or later, on servers running Active Directory, access is allowed or denied based on the access-control list (ACL) for the securable object. By default, the ACL permits all authenticated users and members of the "Pre-Windows 2000 compatible access" group to view the information, which includes Everyone as a default members. This functionality enables anonymous access to the information if the system allows anonymous access. Calling NetWkstaUserEnum on a Windows 2000 member server or workstation not running Active Directory allows all authenticated users can view the information. Anonymous access is also permitted if the RestrictAnonymous policy setting allows anonymous access.

In addition, because entries for service, batch and user logons are all returned, the function may return entries for users who have since logged off a workstation. This can occur, for example, when a user calls a service that impersonates the user. In this instance, NetWkstaUserEnum returns an entry for the user until the service stops impersonating the user.

NetWkstaUserEnum is designed to list all users logged onto a specific machine. What is unclear from the MSDN documentation, and something I am not able to test, is whether NetWkstaUserEnum would be the correct API to use to obtain a listing of all local and remote users who have logged on to the domain by specifying the PDC as servername, or whether to obtain this information would require the developer to first enumerate the network for computers, and then use the machines returned in individual calls to NetWkstaUserEnum. I'd like to know so as to update this page with definitive information.

 BAS Module Code

 Form Code
To a form add a command button (Command1), list box (List1), and two labels (Label1, Label2). A third set of labels in a control array can be used for the list item captions. Add the following to the form:

Option Explicit
' Copyright 1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
Private Const NERR_SUCCESS As Long = 0&
Private Const MAX_PREFERRED_LENGTH As Long = -1
Private Const ERROR_MORE_DATA As Long = 234&
Private Const LB_SETTABSTOPS As Long = &H192

'for use on Win NT/2000 only
Private Type WKSTA_USER_INFO_0
  wkui0_username  As Long
End Type

Private Type WKSTA_USER_INFO_1
  wkui1_username As Long
  wkui1_logon_domain As Long
  wkui1_oth_domains As Long
  wkui1_logon_server As Long
End Type

Private Declare Function NetWkstaUserEnum Lib "netapi32" _
  (ByVal servername As Long, _
   ByVal level As Long, _
   bufptr As Long, _
   ByVal prefmaxlen As Long, _
   entriesread As Long, _
   totalentries As Long, _
   resume_handle As Long) As Long
Private Declare Function NetApiBufferFree Lib "netapi32" _
   (ByVal Buffer As Long) As Long

Private Declare Sub CopyMemory Lib "kernel32" _
   Alias "RtlMoveMemory" _
  (pTo As Any, uFrom As Any, _
   ByVal lSize As Long)
Private Declare Function lstrlenW Lib "kernel32" _
  (ByVal lpString As Long) As Long

Private Declare Function SendMessage Lib "user32" _
   Alias "SendMessageA" _
  (ByVal hwnd As Long, _
   ByVal wMsg As Long, _
   ByVal wParam As Long, _
   lParam As Any) As Long

Private Sub Form_Load()

   ReDim TabArray(0 To 3) As Long
   TabArray(0) = 58
   TabArray(1) = 140
   TabArray(2) = 171
   TabArray(3) = 217
  'Clear existing tabs and set list tabstops
   Call SendMessage(List1.hwnd, LB_SETTABSTOPS, 0&, ByVal 0&)
   Call SendMessage(List1.hwnd, LB_SETTABSTOPS, 4&, TabArray(0))

   Command1.Caption = "NetWkstaUserEnum 1"
   Label1.Caption = "call success (0) or error :"
   Label2.Caption = ""
End Sub

Private Sub Command1_Click()

   Dim bufptr          As Long
   Dim dwServer        As Long
   Dim dwEntriesread   As Long
   Dim dwTotalentries  As Long
   Dim dwResumehandle  As Long
   Dim nStatus         As Long
   Dim nStructSize     As Long
   Dim cnt             As Long
   Dim bServer         As String
   Dim wui1            As WKSTA_USER_INFO_1
   bServer = "\\" & Environ$("COMPUTERNAME") & vbNullString
   dwServer = StrPtr(bServer)
  'begin do
     'call NetWkstaUserEnum function,
     'specifying level 1 data
      nStatus = NetWkstaUserEnum(dwServer, _
                                 1, _
                                 bufptr, _
                                 MAX_PREFERRED_LENGTH, _
                                 dwEntriesread, _
                                 dwTotalentries, _

      Label2.Caption = nStatus
     'Does the call succeed? Only members of the
     'Administrators local group can successfully
     'execute NetWkstaUserEnum locally and on
     'a remote server.
      If nStatus = NERR_SUCCESS Or _
         nStatus = ERROR_MORE_DATA Then
         If dwEntriesread > 0 Then
            nStructSize = LenB(wui1)
           'Loop through the entries
            For cnt = 0 To dwEntriesread - 1
              'cast data into a WKSTA_USER_INFO_1
              'type and add the data to a list
               CopyMemory wui1, ByVal bufptr + (nStructSize * cnt), nStructSize
               List1.AddItem GetPointerToByteStringW(wui1.wkui1_username) & vbTab & _
                             GetPointerToByteStringW(wui1.wkui1_logon_domain) & vbTab & _
                             GetPointerToByteStringW(wui1.wkui1_logon_server) & vbTab & _
           'error: this will fire if the call
           'succeeded, but no data was returned,
           'such as when interrogating a Win9x machine.
            List1.AddItem "No data returned - possible Win9x machine  "
         End If
      Else  'error
         List1.AddItem "Call failed - error " & nStatus
      End If
  'continue to call NetWkstaUserEnum while
  'there are more entries.
   Loop While nStatus = ERROR_MORE_DATA
  'clean up
   Call NetApiBufferFree(bufptr)

End Sub

Private Function GetPointerToByteStringW(ByVal dwData As Long) As String
   Dim tmp() As Byte
   Dim tmplen As Long
   If dwData <> 0 Then
      tmplen = lstrlenW(dwData) * 2
      If tmplen <> 0 Then
         ReDim tmp(0 To (tmplen - 1)) As Byte
         CopyMemory tmp(0), ByVal dwData, tmplen
         GetPointerToByteStringW = tmp
     End If
   End If
End Function


PayPal Link
Make payments with PayPal - it's fast, free and secure!


Copyright 1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy


Hit Counter