Visual Basic Network Services
NetSessionEnum: Enumerate Sessions on a Server
     
Posted:   Tuesday May 22, 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:  

WNetAddConnection2: Transparently Connect to Network Shares
     
 Prerequisites
For this demo one of the operating systems listed under OS Restrictions above. Declares for the Win9x version of the call are provided, but not tested nor demoed.

NetSessionEnum provides information about sessions established on a server. The SESSION_INFO_502 structure returned from a call to an NT or 2000 machine contains information about the session, including name of the computer; name of the user; open files, pipes, and devices on the computer; and the name of the transport the client is using.

The demo illustration shows the connections and open files on my local machine acting as a server to a remote Windows 2000 machine. The data indicates that on the local machine there are seven files opened via a locally mapped share, while the remote machine connecting to the same share has 12 open. If you compare this to the illustration at NetConnectionEnum: Enumerating Share Connection Information, the numbers correctly reflect the connections via the share.

Both machines in the demo are running Windows 2000. When the demo is run from NT or 2000, the SESSION_INFO_502 data type is used to return information from the call, with the method as defined in this demo. The SESSION_INFO_502 structure also returns the correct data when querying a Windows 9x machine from an Windows 2000 (or NT) machine. 

When the method is called from a Windows 9x machine, the method must use the SESSION_INFO_50 data type and a modified set of API parameters for the NetSessionEnum call, provided in the declares below. The SESSION_INFO_50 data type returns different data from the SESSION_INFO_502 type, and the types can not be used interchangeably on differing operating systems. In addition, when calling from 9x using the SESSION_INFO_50 structure, the caller must allocate and deallocate memory for the buffer before and after the call. On NT/2000, this is handled by the API via the MAX_PREFERRED_LENGTH flag and the NetApiBufferFree API. The Win9x method of calling this API is not demonstrated.

The first parameter of either API declare points to the string representing the remote server on which the function is to execute. If this is null (vbNullString), the local computer is used.

Only members of the Administrators or Account Operators local group can successfully execute the NetSessionEnum function at level 1 or level 2. No special group membership is required for level 0 or level 10 calls.

 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 SESS_GUEST = &H1         'session logged on as a guest
Private Const SESS_NOENCRYPTION = &H2  'session not using encryption
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 SESSION_INFO_502
  sesi502_cname As Long
  sesi502_username As Long
  sesi502_num_open As Long
  sesi502_time As Long
  sesi502_idle_time As Long
  sesi502_user_flags As Long
  sesi502_cltype_name As Long
  sesi502_transport As Long
End Type

Private Declare Function NetSessionEnum Lib "netapi32" _
  (ByVal servername As Long, _
   ByVal UncClientName As Long, _
   ByVal username 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
   
'for use on Win9x only
Private Type SESSION_INFO_50
  sesi50_cname As Long
  sesi50_username As Long
  sesi50_key As Long
  sesi50_num_conns As Long
  sesi50_num_opens As Long
  sesi50_time As Long
  sesi50_idle_time As Long
  sesi50_protocol As Long
  pad1 As Long
End Type

Private Declare Function NetSessionEnum9x Lib "netapi32" _
   Alias "NetSessionEnum" _
  (ByVal pszServer As Long, _
   ByVal level As Long, _
   bufptr As Long, _
   cbBuffer As Long, _
   entriesread As Long, _
   totalentries As Long) As Long

'common routines
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 5) As Long
   
   TabArray(0) = 58
   TabArray(1) = 140
   TabArray(2) = 171
   TabArray(3) = 198
   TabArray(4) = 229
   TabArray(5) = 468
      
  'Clear existing tabs and set
   Call SendMessage(List1.hwnd, LB_SETTABSTOPS, 0&, ByVal 0&)
   Call SendMessage(List1.hwnd, LB_SETTABSTOPS, 6&, TabArray(0))
   List1.Refresh
   
   Command1.Caption = "NetSessionEnum"
   Label1.Caption = "call success (0) or error :"
   Label2.Caption = ""
   
End Sub


Private Sub Command1_Click()

   Dim bufptr          As Long  'output
   Dim dwServer        As Long  'pointer to the server 
   Dim dwEntriesread   As Long  'out
   Dim dwTotalentries  As Long  'out
   Dim dwResumehandle  As Long  'out
   Dim success         As Long
   Dim nStructSize     As Long
   Dim cnt             As Long
   Dim usrname         As String
   Dim bServer         As String
   Dim si502           As SESSION_INFO_502
     
   bServer = "\\" & Environ$("COMPUTERNAME") & vbNullString
   dwServer = StrPtr(bServer)
   
   success = NetSessionEnum(dwServer, _
                            0&, _
                            0&, _
                            502, _
                            bufptr, _
                            MAX_PREFERRED_LENGTH, _
                            dwEntriesread, _
                            dwTotalentries, _
                            dwResumehandle)

   List1.Clear
   Label2.Caption = success
   
   If success = NERR_SUCCESS And _
      success <> ERROR_MORE_DATA Then
      
      nStructSize = LenB(si502)
      
      For cnt = 0 To dwEntriesread - 1
         
        'get one chunk of data and cast
        'into an SESSION_INFO_502 type, and
        'add the data to a list
         CopyMemory si502, ByVal bufptr + (nStructSize * cnt), nStructSize

       'sesi502_cname      : name of the computer that established the session.
       'sesi502_username   : name of the user who established the session.
       'sesi502_num_open   : number of files, devices, and pipes opened during the session.
       'sesi502_time       : number of seconds the session has been active.
       'sesi502_idle_time  : number of seconds the session has been idle.
       'sesi502_user_flags : how the user established the session.
       'sesi502_cltype_name: type of client that established the session.
       'sesi502_transport  : name of transport client is using to communicate with the server.
        usrname = GetPointerToByteStringW(si502.sesi502_username)
        
       'if you only want to see sessions with identified
       'users, leave the If statement in. Commenting
       'it out will show all server sessions.
        If Len(usrname) > 0 Then
         
           'sesi502_time and sesi502_idle_time
           'return time in seconds, so divide
           'by 60 to display minutes. Note that 
           'not all type data is shown in this list.
            List1.AddItem usrname & vbTab & _
                          GetPointerToByteStringW(si502.sesi502_cname) & vbTab & _
                          si502.sesi502_time \ 60 & vbTab & _
                          si502.sesi502_idle_time \ 60 & vbTab & _
                          si502.sesi502_num_open & vbTab & _
                          GetPointerToByteStringW(si502.sesi502_cltype_name)
                          

         End If
      Next
   End If
   
   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


Private Function GetSessionUserType(ByVal dwSessionType As Long) As String

   Select Case dwSessionType
      Case SESS_GUEST:        GetSessionUserType = "guest"
      Case SESS_NOENCRYPTION: GetSessionUserType = "no encryption"
      Case Else:              GetSessionUserType = ""
   End Select
   
End Function
 Comments

 
 

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