Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do I use the NetSessionEnum API from VB?

Windows API

How do I use the NetSessionEnum API from VB?

by  strongm  Posted    (Edited  )
This is an example of how to use the NetSessionEnum API from VB. The example allows you to determine what users and what machines have sessions connected to a remote server.

Usage:

call EnumerateUsers(Servername, Username)

if username is an empty, then get all users on server



Option Explicit

' Declare following two types for a nasty hack
Type MungeLong
X As Long
dummy As Integer
End Type

Type MungeInt
XLo As Integer
XHi As Integer
dummy As Integer
End Type

' Structure is 24 bytes long
Type SESSION_INFO_1
sesi1_cname As Long '4
sesi1_username As Long '4
sesi1_num_opens As Long
sesi1_time As Long
sesi1_idel_time As Long
sesi1_user_flags As Long
End Type

Global Const SESSION_INFO_1_Length = 24

Declare Function NetSessionEnumUser Lib "netapi32.dll" Alias "NetSessionEnum" (ServerName As Byte, dummy As Long, UserName As Byte, ByVal Level As Long, Buffer As Long, ByVal prefmaxlen As Long, entriesread As Long, totalentries As Long, ResumeHandle As Long) As Long
Declare Function NetSessionEnumAll Lib "netapi32.dll" Alias "NetSessionEnum" (ServerName As Byte, dummy As Long, dummy As Long, ByVal Level As Long, Buffer As Long, ByVal prefmaxlen As Long, entriesread As Long, totalentries As Long, ResumeHandle As Long) As Long

' Declare undocumented calls, thanks to Hardcore Visual Basic
Declare Function PtrToInt Lib "Kernel32" Alias "lstrcpynW" (RetVal As Any, ByVal Ptr As Long, ByVal nCharCount As Long) As Long
Declare Function PtrToStr Lib "Kernel32" Alias "lstrcpyW" (RetVal As Byte, ByVal Ptr As Long) As Long
Declare Function StrLen Lib "Kernel32" Alias "lstrlenW" (ByVal Ptr As Long) As Long

Declare Function NetAPIBufferFree Lib "netapi32.dll" Alias "NetApiBufferFree" (ByVal Ptr As Long) As Long


Function EnumerateUsers(ByVal ServerName As String, ByVal UserName As String) As Long

'
' SName should be "\\servername"
' and only works on NT/2000 since W9x reurns a different structure
' Check out session_info_50 structure on MSDN to derive correct length,
' and then just change SESSION_INFO_1_Length appropriately


Dim result As Long

' Bits and pieces for NetSession call
Dim bufptr As Long
Dim entriesread As Long
Dim totalentries As Long
Dim ResumeHandle As Long
Dim buflen As Long

' Declare byte arrays, which we need to pass to NetSession call
Dim arrServerName() As Byte
Dim arrUser() As Byte

' Results array. Arbitarily decide on size
Dim UNArray(99) As Byte

Dim UName As String
Dim ComputerName As String

' Some working variables
Dim lp As Integer
Dim TempPtr As MungeLong
Dim TempStr As MungeInt

arrServerName = ServerName & vbNullChar ' Move to byte array
arrUser = UserName + vbNullChar ' Move string to byte array

buflen = 1024 * 8 ' Max buffer size (buffer is actually allocated by NetSession call)
ResumeHandle = 0 ' Start with the first entry

Do
If UserName = "" Then
result = NetSessionEnumAll(arrServerName(0), 0&, 0&, 1, bufptr, buflen, entriesread, totalentries, ResumeHandle)
Else
result = NetSessionEnumUser(arrServerName(0), 0&, arrUser(0), 1, bufptr, buflen, entriesread, totalentries, ResumeHandle)
End If

EnumerateUsers = result

If result <> 0 Then ' oops!
MsgBox "Error " & result & " enumerating user " & entriesread & " of " & totalentries, , "Error"
Exit Function
End If

For lp = 0 To entriesread - 1 'Deal with all the entries
' We could now read pointers from the buffer and stick them into structure
' but we are only interested in first two pointers which indicate
' computer and user name

' OK, start cheating like hell: undocumented calls etc.

' Get pointer to string from beginning of buffer
' Copy 4-byte block of memory in 2 steps
' get Username from pointer in buffer
result = PtrToInt(TempStr.XLo, bufptr + lp * SESSION_INFO_1_Length, 2)
result = PtrToInt(TempStr.XHi, bufptr + lp * SESSION_INFO_1_Length + 2, 2)
LSet TempPtr = TempStr ' munge 2 integers into a Long

' Copy string pointed to into array
result = PtrToStr(UNArray(0), TempPtr.X)
ComputerName = Left(UNArray, StrLen(TempPtr.X))


' get next pointer from buffer
result = PtrToInt(TempStr.XLo, bufptr + lp * SESSION_INFO_1_Length + 4, 2)
result = PtrToInt(TempStr.XHi, bufptr + lp * SESSION_INFO_1_Length + 2 + 4, 2)
LSet TempPtr = TempStr ' munge 2 integers into a Long

' Copy string pointed to into array
result = PtrToStr(UNArray(0), TempPtr.X)
UName = Left(UNArray, StrLen(TempPtr.X))
If UName <> "" Then 'OK, we've got a user
Debug.Print ComputerName & ": " & UName
' Alternatively, do whatever you want to do here
End If
Next lp
Loop Until entriesread = totalentries

result = NetAPIBufferFree(bufptr) ' Don't leak memory

End Function
Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top