Jump to content

Enumerate Network Resources


KaFu
 Share

Recommended Posts

I was always curious on how to enumarate network resources. Used the search function and only found for _WinNet_EnumResource() here, which did not fully work for me... so I tinkered a little and came up with this :). Comments and improvments as always are welcome, esp. the _PointerToString() function seems a little jury-rigged to me, but couldn't find a more elegant solution (oh well, maybe I've not looked hard enough :lol:).

; By KaFu, based on this post by HansGrubber
; http://www.autoitscript.com/forum/topic/86064-winnet-openenum-winnet-enumresource-are-evil/#entry730852

; WNetOpenEnum function
; http://msdn.microsoft.com/en-us/library/windows/desktop/aa385478(v=vs.85).aspx

; WNetEnumResource function
; http://msdn.microsoft.com/en-us/library/windows/desktop/aa385449(v=vs.85).aspx

; NETRESOURCE structure
; http://msdn.microsoft.com/en-us/library/windows/desktop/aa385353(v=vs.85).aspx

#include <WinNet.au3>

Local Const $tagNETRESOURCE_New = "dword Scope;dword Type;dword DisplayType;dword Usage;ptr LocalName;ptr RemoteName;ptr Comment;ptr Provider"
; $tagNETRESOURCE contains "int" instead of "dword"

;## Open Enum
Local $iScope = 0 ; 0 - Enumerate all currently connected resources, 1 - Enumerate all resources on the network, 2 - Enumerate all remembered (persistent) connections, 3 - Enumerate only resources in the network context of the caller
Local $iType = 1 ; 0 - All resources, 1 - Disk resources, 2 - Print resources
Local $iUsage = 4 ; 0 - All resources, 1 - All connectable resources, 2 - All container resources, 4 - Forces the function to fail if the user is not authenticated

Local $hEnum, $RC

$RC = _WinNet_OpenEnum($iScope, $iType, $iUsage, 0, $hEnum)
If $RC <> True Or @error Then
    #cs
        Global Const $ERROR_INVALID_PARAMETER = 87                                        ; The parameter is incorrect.
        Global Const $ERROR_INVALID_ADDRESS = 487                                         ; Attempt to access invalid address.
        Global Const $ERROR_NOT_CONTAINER = 1207                                          ; Cannot enumerate a noncontainer.
        Global Const $ERROR_EXTENDED_ERROR = 1208                                         ; An extended error has occurred.
        Global Const $ERROR_NO_NETWORK = 1222                                             ; The network is not present or not started.
    #ce
    Local $_Extended_Error_Code, $_Extended_Error_Message, $_Extended_Error_Provider, $sError
    Switch @error
        Case 87
            $sError = "ERROR_INVALID_PARAMETER"
        Case 487
            $sError = "ERROR_INVALID_ADDRESS"
        Case 1207
            $sError = "ERROR_NOT_CONTAINER"
        Case 1208
            $sError = "ERROR_EXTENDED_ERROR"
        Case 1222
            $sError = "ERROR_NO_NETWORK"
        Case Else
            $sError = "Unknown Error"
    EndSwitch
    _WinNet_GetLastError($_Extended_Error_Code, $_Extended_Error_Message, $_Extended_Error_Provider)
    ConsoleWrite("! Error in _WinNet_OpenEnum / WNetOpenEnum" & @TAB & $RC & @TAB & $sError & @TAB & $_Extended_Error_Code & @TAB & $_Extended_Error_Message & @TAB & $_Extended_Error_Provider & @CRLF)
    Exit 1
EndIf
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $hEnum = ' & $hEnum & @CRLF)

;## Enum Resource
Local $iCount = -1 ; Number of entries requested. If the number requested is –1, the function returns as many entries as possible
Local $iBufSize = 16384
Local $tBuffer = DllStructCreate("byte[" & $iBufSize & "]") ; Pointer to the buffer that receives the enumeration results. The results are returned as an array of $tagNETRESOURCE structures. The buffer must be large enough to hold the structures plus the strings to which their members point.
Local $pBuffer = DllStructGetPtr($tBuffer)

ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $iBufSize = ' & $iBufSize & @CRLF)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $iBufSize / 32 (size of $tagNETRESOURCE) = ' & $iBufSize / 32 & " (must be greater than $iCount, otherwise increase buffersize)" & @CRLF)

$RC = _WinNet_EnumResource($hEnum, $iCount, $pBuffer, $iBufSize)
If $RC <> 0 Or @error Then
    Local $_Extended_Error_Code, $_Extended_Error_Message, $_Extended_Error_Provider, $sError
    _WinNet_GetLastError($_Extended_Error_Code, $_Extended_Error_Message, $_Extended_Error_Provider)
    If @error Then
        ConsoleWrite("! Error in _WinNet_EnumResource / WNetEnumResource #2" & @TAB & $RC & @error & @TAB & @extended & @TAB & $_Extended_Error_Code & @TAB & $_Extended_Error_Message & @TAB & $_Extended_Error_Provider & @CRLF)
        Exit 2
    EndIf
    #cs
        Global Const $ERROR_INVALID_HANDLE = 6                                            ; The handle is invalid.
        Global Const $ERROR_MORE_DATA = 234                                               ; More data is available.
        Global Const $ERROR_NO_MORE_ITEMS = 259                                           ; No more data is available.
        Global Const $ERROR_EXTENDED_ERROR = 1208                                         ; An extended error has occurred, to obtain a description of the error, call the WNetGetLastError function.
        Global Const $ERROR_NO_NETWORK = 1222                                             ; The network is not present or not started.
    #ce
    Switch $RC
        Case 6
            $sError = "ERROR_INVALID_HANDLE"
        Case 234
            $sError = "ERROR_MORE_DATA"
        Case 259
            $sError = "ERROR_NO_MORE_ITEMS"
        Case 1208
            $sError = "ERROR_EXTENDED_ERROR"
        Case 1222
            $sError = "ERROR_NO_NETWORK"
        Case Else
            $sError = "Unknown Error"
    EndSwitch
    ConsoleWrite("! Error in _WinNet_EnumResource / WNetEnumResource #2" & @TAB & $RC & @TAB & $sError & @TAB & $_Extended_Error_Code & @TAB & $_Extended_Error_Message & @TAB & $_Extended_Error_Provider & @CRLF)
    Exit 3
EndIf
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $iCount = ' & $iCount & " (number of resources found)" & @CRLF & @CRLF)

Local $pEnum = $pBuffer
For $i = 1 To $iCount
    ConsoleWrite("Resource #" & $i & ": ")
    _tagNETRESOURCE_Display($pEnum)
    $pEnum += 32 ; = DllStructGetSize(DllStructCreate($tagNETRESOURCE))
Next

Func _tagNETRESOURCE_Display($ptr)
    Local $data = DllStructCreate($tagNETRESOURCE_New, $ptr)
    ConsoleWrite('Scope = ' & DllStructGetData($data, 'Scope') & " | ")
    ConsoleWrite('Type = ' & DllStructGetData($data, 'Type') & " | ")
    ConsoleWrite('DisplayType = ' & DllStructGetData($data, 'DisplayType') & " | ")
    ConsoleWrite('Usage = ' & DllStructGetData($data, 'Usage') & " | ")
    ConsoleWrite('LocalName = ' & _PointerToStringW(DllStructGetData($data, 'LocalName')) & " | ")
    ConsoleWrite('RemoteName = ' & _PointerToStringW(DllStructGetData($data, 'RemoteName')) & " | ")
    ConsoleWrite('Comment = ' & _PointerToStringW(DllStructGetData($data, 'Comment')) & " | ")
    ConsoleWrite('Provider = ' & _PointerToStringW(DllStructGetData($data, 'Provider')) & @CRLF)
EndFunc   ;==>_tagNETRESOURCE_Display

Func _PointerToStringW($ptr)
    Return DllStructGetData(DllStructCreate("wchar[" & _WinAPI_StringLenW($ptr) & "]", $ptr), 1)
EndFunc   ;==>_PointerToStringW
Edited by KaFu
Link to comment
Share on other sites

Hi KaFu, looks really nice, but i get this :

@@ Debug(27) : $hEnum = 0x008E1710
@@ Debug(35) : $iBufSize = 16384
@@ Debug(36) : $iBufSize / 32 (size of $tagNETRESOURCE) = 512 (must be greater than $iCount, otherwise increase buffersize)

[font="verdana, geneva, sans-serif"] [/font]

Link to comment
Share on other sites

Hi KaFu, looks really nice, but i get this :

Please try again, I've added some more error checking.

...is simply...

First I've tried it with a call to lstrlen, which did not work... I've realized that its a W string already and changed the function to reflect that... but truth to be told I hoped YOU would step up and post the right way to do it :thumbsup:...
Link to comment
Share on other sites

This is what i get now :

@@ Debug(53) : $hEnum = 0x008E1708
@@ Debug(61) : $iBufSize = 16384
@@ Debug(62) : $iBufSize / 32 (size of $tagNETRESOURCE) = 512 (must be greater than $iCount, otherwise increase buffersize)
! Error in _WinNet_EnumResource / WNetEnumResource #2 259 ERROR_NO_MORE_ITEMS 0  1024
!>18:38:40 AutoIT3.exe ended.rc:3

[font="verdana, geneva, sans-serif"] [/font]

Link to comment
Share on other sites

Well, I would guess that you don't have any network drives attached, do you?

Local $iScope = 0 ; 0 - Enumerate all currently connected resources

This is only a basic example enumerating just one node.

Next step would be to create nested function calls, first with $iScope = 1, then pass the resulting $tagNETRESOURCE structure to the next _WinNet_OpenEnum() call to enumerate the child resources of that one...

Edited by KaFu
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...