|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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 |
Related: |
NetServerEnum: Obtain Domain/Workgroup Servers and Machines |
Prerequisites |
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 |
None. |
|
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)) List1.Refresh 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) List1.Clear 'begin do Do 'call NetWkstaUserEnum function, 'specifying level 1 data nStatus = NetWkstaUserEnum(dwServer, _ 1, _ bufptr, _ MAX_PREFERRED_LENGTH, _ dwEntriesread, _ dwTotalentries, _ dwResumehandle) 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 & _ GetPointerToByteStringW(wui1.wkui1_oth_domains) Next Else '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 |
Comments |
|
|
|
|||||
|
|||||
|
|||||
Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved. |