Jump to content

Recommended Posts

Posted (edited)

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
Posted

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]

Posted

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:...
Posted

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]

Posted (edited)

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

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
×
×
  • Create New...