|
|
![]() |
|
||
|
|
|||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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. |
![]() |