|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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 |
|
|
|
|||||
|
|||||
|
|||||
Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved. |