Sign in to follow this  
Followers 0
KaFu

Enumerate Network Resources

6 posts in this topic

#1 ·  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

Share this post


Link to post
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]

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

KaFu that _PointerToString() is simply

DllStructGetData(DllStructCreate("wchar[" & _WinAPI_StringLenW($ptr) & "]", $ptr), 1)

... or instead of _WinAPI_StringLenW() call to kernel32's lstrlenW.

Other than that I get the same as fluttery.

Edited by trancexx

♡♡♡

.

eMyvnE

Share this post


Link to post
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:...

Share this post


Link to post
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]

Share this post


Link to post
Share on other sites

#6 ·  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
1 person likes this

Share this post


Link to post
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
Sign in to follow this  
Followers 0

  • Similar Content

    • Ascend4nt
      By Ascend4nt
      _EnumChildWindows
      Enumerate controls/children of a Window

      This code enumerates all controls/children of a given Window and returns them in an array.
      Example code is included.

      *small change 9/15/2010:

      removed a #include line from the example code posted here (not required) *update 3/28/2010: Control ID is now retrieved. Unfortunately the indexing was reworked (sorry). But at least now I believe all the relevant information needed is retrieved. Parameters to the function now have a slightly different meaning. Basically, this was done to allow searching for controls with an empty-string for a Title. All defaults are now 0, so a call can be made like this to find all Controls with a 'Button' classname: _EnumChildWindows($hWnd,0,0,"Button")
      #include <_EnumChildWindows.au3> ; =============================================================================================================================== ; <TestEnumChildWindows.au3> ; ; Test for _EnumChildWindows UDF. ; ; Author: Ascend4nt ; =============================================================================================================================== ; =================================================================================================================== ; TEST ; =================================================================================================================== #include <Array.au3> Local $hWnd="",$hControl="",$sTitle="",$sClass="",$aEnumList Local $iCalcPID,$hNumber1Button=-1,$hNumber4Button=-1,$hPlusButton=-1,$hEqualButton=-1 $iCalcPID=Run("calc.exe") If @error Then Exit $hWnd=WinWait("Calculator") If $hWnd=0 Then Exit ProcessClose($iCalcPID) ; Important to wait for the window to fully 'create' itself before getting child windows! ; Note that other processes that become activated somewhere between _WinWaitEx and this will cause WinWaitActive() to wait for manual activation ;WinWaitActive($hWnd) ; bad idea in busy environment WinActivate($hWnd) ; this seems to be a better alternative, the window seems fully created after this is called in my tests ; Parameters to function ;$hControl=HWnd(0x########) ;$sTitle="^(\d|\+|=){:content:}quot; ;$sClass="Button" $aEnumList=_EnumChildWindows($hWnd,$hControl,$sTitle,$sClass) ;,2) for RegExp Title If @Error Then Exit ProcessClose($iCalcPID) ; Find specific items [Certain versions of Calc won't return any text] For $i=1 to $aEnumList[0][0] Switch $aEnumList[$i][3] Case "1" $hNumber1Button=$aEnumList[$i][0] ConsoleWrite("'1' Advanced Mode Name (in current state): [CLASS:Button; INSTANCE:"&$aEnumList[$i][2]&"]"&@CRLF) Case "4" $hNumber4Button=$aEnumList[$i][0] ConsoleWrite("'4' Advanced Mode Name (in current state): [CLASS:Button; INSTANCE:"&$aEnumList[$i][2]&"]"&@CRLF) Case "+" $hPlusButton=$aEnumList[$i][0] ConsoleWrite("'+' Advanced Mode Name (in current state): [CLASS:Button; INSTANCE:"&$aEnumList[$i][2]&"]"&@CRLF) Case "=" $hEqualButton=$aEnumList[$i][0] ConsoleWrite("'=' Advanced Mode Name (in current state): [CLASS:Button; INSTANCE:"&$aEnumList[$i][2]&"]"&@CRLF) EndSwitch Next ; Add Headers $aEnumList[0][0]="Handle" $aEnumList[0][1]="Classname" $aEnumList[0][2]="Iteration" $aEnumList[0][3]="Title/Text" ; Bring the window forward WinActivate($hWnd) ; Perform a simple calculation to show interaction If $hNumber1Button<>-1 Then ControlClick($hWnd,"",$hNumber1Button,"primary",3) ControlClick($hWnd,"",$hNumber4Button) Sleep(1000) ControlClick($hWnd,"",$hPlusButton) Sleep(1000) ControlClick($hWnd,"",$hNumber4Button,"primary",2) ; double click, but that's fine Sleep(1000) ControlClick($hWnd,"",$hEqualButton) EndIf ; And Display ALL Enumerated Windows _ArrayDisplay($aEnumList,"Enumerated controls for 'Calculator'") ProcessClose($iCalcPID) Download the ZIP from my site
      Ascend4nt's AutoIT Code License agreement:
      While I provide this source code freely, if you do use the code in your projects, all I ask is that:
      If you provide source, keep the header as I have put it, OR, if you expand it, then at least acknowledge me as the original author, and any other authors I credit If the program is released, acknowledge me in your credits (it doesn't have to state which functions came from me, though again if the source is provided - see #1) The source on it's own (as opposed to part of a project) can not be posted unless a link to the page(s) where the code were retrieved from is provided and a message stating that the latest updates will be available on the page(s) linked to. Pieces of the code can however be discussed on the threads where Ascend4nt has posted the code without worrying about further linking.