Visual Basic Network Services
WNetEnumResource: Enumerating Local Network Resources
     
Posted:   Monday June 25, 2001
Updated:   Monday December 26, 2011
     
Applies to:   VB4-32, VB5, VB6
Developed with:   VB6, Windows 2000
OS restrictions:   None
Author:   VBnet - Randy Birch
     

Related:  

WNetAddConnection2: Transparently Connect to Network Shares
NetShareCheck: Determine Remote Folder or Device Share Status
WNetEnumResource: Enumerating Local Network Resources
NetConnectionEnum: Enumerating Share Connection Information
NetShareEnum: Enumerating Shared Resources on Other Machines  
NetShareAdd: Create a Local or Remote Share
WNetGetUser: User, Share and Share User for Network Resources
WNetGetConnection: Get UNC Path for Mapped Drive
     
 Prerequisites
None. 

The WNetEnumResource API continues enumeration of network resources on the local computer that was started by a call to the WNetOpenEnum API function. It will not retrieve the shares in use on remote machines. The illustration shows the function enumerating all network resources on my development network, which consisted of seven mapped drives.

On receiving a valid handle to an enumeration from WNetOpenEnum, WNetEnumResource returns a buffer filled with network resources of the type requested in the WNetOpenEnum call. Straightforward code extracts both the local drive letter and its corresponding UNC path, as shown, along with additional information about each resource such as the type of resource (disk, print or unknown), display type (a domain, server, share or "generic"), the usage of the resource (connectable or container), as well as any comment provided by the network provider, as well as the name of the provider that owns the resource. Only the lpLocalName and lpRemoteName (UNC) members are shown in this demo. 

Unlike other Net APIs that, when called with a buffer of MAX_PREFERRED_LENGTH (-1), retrieves the required buffer size into the call's buffer-size parameter, WNetEnumResource instead requires the application to pre-allocate a buffer of a reasonable size — 32k in this demo. However the value of lpBufferSize for can be used error detection, allowing code to reallocate a larger block for the buffer before trying the call again..  

When the resource type specified in the WNetOpenEnum dwType member is RESOURCEUSAGE_CONTAINER or RESOURCETYPE_ANY, and the return value of a NETRESOURCE dwUsage member indicates RESOURCEUSAGE_CONTAINER, WNetEnumResource can be called recursively by passing the address of the NETRESOURCE structure to the WNetOpenEnum function to open the container and continue the enumeration. If dwUsage is equal to RESOURCEUSAGE_CONNECTABLE, the application can pass the structure's address to the WNetAddConnection2 function or the WNetAddConnection3 function to connect to the resource. 

WNetEnumResource does not enumerate users connected to a share; NetConnectionEnum will accomplish this task. To enumerate hidden shares, call the NetShareEnum function. 

 BAS Module Code
None.

 Form Code
To a form add a command button (Command1), list box (List1). 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 RESOURCETYPE_ANY = &H0
Private Const RESOURCE_CONNECTED = &H1

Private Type NETRESOURCE
   dwScope        As Long
   dwType         As Long
   dwDisplayType  As Long
   dwUsage        As Long
   lpLocalName    As Long
   lpRemoteName   As Long
   lpComment      As Long
   lpProvider     As Long
End Type

Private Declare Function WNetOpenEnum Lib "mpr.dll" _
   Alias "WNetOpenEnumA" _
  (ByVal dwScope As Long, _
   ByVal dwType As Long, _
   ByVal dwUsage As Long, _
   lpNetResource As Any, _
   lphEnum As Long) As Long

Private Declare Function WNetEnumResource Lib "mpr.dll" _
   Alias "WNetEnumResourceA" _
  (ByVal hEnum As Long, _
   lpcCount As Long, _
   lpBuffer As Any, _
   lpBufferSize As Long) As Long

Private Declare Function WNetCloseEnum Lib "mpr.dll" _
  (ByVal hEnum As Long) As Long

Private Declare Function lstrlen Lib "kernel32" _
   Alias "lstrlenA" _
  (ByVal lpString As Any) As Long

Private Declare Function lstrcpy Lib "kernel32" _
  Alias "lstrcpyA" _
 (ByVal lpString1 As Any, _
  ByVal lpString2 As Any) As Long



Private Sub Form_Load()

   Command1.Caption = "Enum Net Resources"
   
End Sub


Private Sub Command1_Click()

   Dim hEnum           As Long
   Dim bufptr          As Long
   Dim dwBuffSize      As Long
   Dim nStructSize     As Long
   Dim dwEntries       As Long
   Dim success         As Long
   Dim cnt             As Long
   Dim netres()        As NETRESOURCE
   Dim sLocalName      As String
   Dim sUncName        As String

   List1.Clear
   
  'obtain an enumeration handle that
  'can be used in a subsequent call
  'to WNetEnumResource
   success = WNetOpenEnum(RESOURCE_CONNECTED, _
                          RESOURCETYPE_ANY, _
                          0&, _
                          ByVal 0&, _
                          hEnum)

  'if no error and a handle obtained..
   If success = NERR_SUCCESS And _
      hEnum <> 0 Then
      
     'set number of dwEntries and redim
     'a NETRESOURCE array to hold the
     'data returned
      dwEntries = 1024
      ReDim netres(0 To dwEntries - 1) As NETRESOURCE
      
     'calculate the size of the buffer
     'being passed
      nStructSize = LenB(netres(0))
      dwBuffSize = 1024& * nStructSize
      
     'and call WNetEnumResource
      success = WNetEnumResource(hEnum, _
                                 dwEntries, _
                                 netres(0), _
                                 dwBuffSize)

      If success = 0 Then
      
         For cnt = 0 To dwEntries - 1
         
           'clear the variables
            sLocalName = ""
            sUncName = ""
         
           'Get the local name (drive letter) and
           'strip null the trailing null
            If netres(cnt).lpLocalName <> 0 Then
               sLocalName = GetStrFromPtrA(netres(cnt).lpLocalName)
               sLocalName = TrimNull(sLocalName)
            End If

           'Get the remote name (the UNC path)
           'and strip null the trailing null
            If netres(cnt).lpRemoteName <> 0 Then
               sUncName = GetStrFromPtrA(netres(cnt).lpRemoteName)
               sUncName = TrimNull(sUncName)
            End If

           'add item to the list
            List1.AddItem sLocalName & vbTab & sUncName

         Next cnt  'For cnt = 0
               
      Else
      
         List1.AddItem "WNetEnumResource error or no mapped drives"
         
      End If  'If success = 0 (WNetEnumResource)
   End If  'If success = 0 (WNetOpenEnum)

  'clean up
   Call WNetCloseEnum(hEnum)

End Sub


Public Function GetStrFromPtrA(ByVal lpszA As Long) As String

   GetStrFromPtrA = String$(lstrlen(ByVal lpszA), 0)
   Call lstrcpy(ByVal GetStrFromPtrA, ByVal lpszA)
   
End Function


Private Function TrimNull(item As String)

    Dim pos As Integer
   
   'double check that there is a chr$(0) in the string
    pos = InStr(item, Chr$(0))
    If pos Then
       TrimNull = Left$(item, pos - 1)
    Else
       TrimNull = item
    End If
  
End Function
 Comments
By easily modifying this code, you can create a routine that, when passed a local drive letter in the format X: returns the current mapped UNC path for that drive:
Private Function GetUncPath(ByVal sLocalDrive As String) As String

   Dim hEnum           As Long
   Dim bufptr          As Long
   Dim dwBuffSize      As Long
   Dim nStructSize     As Long
   Dim dwEntries       As Long
   Dim success         As Long
   Dim cnt             As Long
   Dim netres()        As NETRESOURCE
   Dim sLocalName      As String
   Dim sUncName        As String

  'obtain an enumeration handle that
  'can be used in a subsequent call
  'to WNetEnumResource
   success = WNetOpenEnum(RESOURCE_CONNECTED, _
                          RESOURCETYPE_ANY, _
                          0&, _
                          ByVal 0&, _
                          hEnum)

  'if no error and a handle obtained..
   If success = NERR_SUCCESS And _
      hEnum <> 0 Then
      
     'set number of dwEntries and redim
     'a NETRESOURCE array to hold the
     'data returned
      dwEntries = 1024
      ReDim netres(0 To dwEntries - 1) As NETRESOURCE
      
     'calculate the size of the buffer
     'being passed
      nStructSize = LenB(netres(0))
      dwBuffSize = 1024& * nStructSize
      
     'and call WNetEnumResource
      success = WNetEnumResource(hEnum, _
                                 dwEntries, _
                                 netres(0), _
                                 dwBuffSize)

      If success = 0 Then
      
        'loop through the returned data
         For cnt = 0 To dwEntries - 1
         
           'clear the variables
            sLocalName = ""
            sUncName = ""
         
           'If the returned NETRESOURCE
           'members are valid
            If netres(cnt).lpLocalName <> 0 And _
               netres(cnt).lpRemoteName <> 0 Then
               
              'Get the local name
              '(drive letter) returned
               sLocalName = GetStrFromPtrA(netres(cnt).lpLocalName)
               
              'compare this to the drive passed
               If Left$(sLocalDrive, 1) = Left$(sLocalName, 1) Then
               
                 'The drives match, so retrieve
                 'the remote name (the UNC path),
                 'stripping the trailing null and
                 'return, being sure to turn out
                 'the lights on the way out the door.
                  sUncName = GetStrFromPtrA(netres(cnt).lpRemoteName)
                  GetUncPath = TrimNull(sUncName)
                     
                  Call WNetCloseEnum(hEnum)
                  Exit Function
                     
               End If 'If Left$(sLocalDrive

            End If  'If netres(cnt)

         Next cnt  'For cnt = 0
               
      Else
      
        'there was a WNetEnumResource error
        'or there are no mapped drives so
        'return an empty string
         GetUncPath = ""
         
      End If  'If success = 0 (WNetEnumResource)
   End If  'If success = 0 (WNetOpenEnum)

  'clean up
   Call WNetCloseEnum(hEnum)
   
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