c.haslam Posted November 15, 2018 Posted November 15, 2018 Kafu wrote in 2013: " 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... " Has anyone succeeded in doing this? I have been trying but I guess I have to admit that I failed! The C/C++ code fromm Microsoft is #ifndef UNICODE #define UNICODE #endif #pragma comment(lib, "mpr.lib") #include <windows.h> #include <stdio.h> #include <winnetwk.h> BOOL WINAPI EnumerateFunc(LPNETRESOURCE lpnr); void DisplayStruct(int i, LPNETRESOURCE lpnrLocal); int main() { LPNETRESOURCE lpnr = NULL; if (EnumerateFunc(lpnr) == FALSE) { printf("Call to EnumerateFunc failed\n"); return 1; } else return 0; } BOOL WINAPI EnumerateFunc(LPNETRESOURCE lpnr) { DWORD dwResult, dwResultEnum; HANDLE hEnum; DWORD cbBuffer = 16384; // 16K is a good size DWORD cEntries = -1; // enumerate all possible entries LPNETRESOURCE lpnrLocal; // pointer to enumerated structures DWORD i; // // Call the WNetOpenEnum function to begin the enumeration. // dwResult = WNetOpenEnum(RESOURCE_GLOBALNET, // all network resources RESOURCETYPE_ANY, // all resources 0, // enumerate all resources lpnr, // NULL first time the function is called &hEnum); // handle to the resource if (dwResult != NO_ERROR) { printf("WnetOpenEnum failed with error %d\n", dwResult); return FALSE; } // // Call the GlobalAlloc function to allocate resources. // lpnrLocal = (LPNETRESOURCE) GlobalAlloc(GPTR, cbBuffer); if (lpnrLocal == NULL) { printf("WnetOpenEnum failed with error %d\n", dwResult); // NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetOpenEnum"); return FALSE; } do { dwResultEnum = WNetEnumResource(hEnum, // resource handle &cEntries, // defined locally as -1 lpnrLocal, // LPNETRESOURCE &cbBuffer); // buffer size if (dwResultEnum == NO_ERROR) { for (i = 0; i < cEntries; i++) { DisplayStruct(i, &lpnrLocal[i]); if (RESOURCEUSAGE_CONTAINER == (lpnrLocal[i].dwUsage & RESOURCEUSAGE_CONTAINER)) if (!EnumerateFunc(&lpnrLocal[i])) printf("EnumerateFunc returned FALSE\n"); } } else if (dwResultEnum != ERROR_NO_MORE_ITEMS) { printf("WNetEnumResource failed with error %d\n", dwResultEnum); break; } } while (dwResultEnum != ERROR_NO_MORE_ITEMS); dwResult = WNetCloseEnum(hEnum); if (dwResult != NO_ERROR) { printf("WNetCloseEnum failed with error %d\n", dwResult); return FALSE; } return TRUE; } void DisplayStruct(int i, LPNETRESOURCE lpnrLocal) { printf("NETRESOURCE[%d] Scope: ", i); switch (lpnrLocal->dwScope) { case (RESOURCE_CONNECTED): printf("connected\n"); break; case (RESOURCE_GLOBALNET): printf("all resources\n"); break; case (RESOURCE_REMEMBERED): printf("remembered\n"); break; default: printf("unknown scope %d\n", lpnrLocal->dwScope); break; } printf("NETRESOURCE[%d] Type: ", i); switch (lpnrLocal->dwType) { case (RESOURCETYPE_ANY): printf("any\n"); break; case (RESOURCETYPE_DISK): printf("disk\n"); break; case (RESOURCETYPE_PRINT): printf("print\n"); break; default: printf("unknown type %d\n", lpnrLocal->dwType); break; } printf("NETRESOURCE[%d] DisplayType: ", i); switch (lpnrLocal->dwDisplayType) { case (RESOURCEDISPLAYTYPE_GENERIC): printf("generic\n"); break; case (RESOURCEDISPLAYTYPE_DOMAIN): printf("domain\n"); break; case (RESOURCEDISPLAYTYPE_SERVER): printf("server\n"); break; case (RESOURCEDISPLAYTYPE_SHARE): printf("share\n"); break; case (RESOURCEDISPLAYTYPE_FILE): printf("file\n"); break; case (RESOURCEDISPLAYTYPE_GROUP): printf("group\n"); break; case (RESOURCEDISPLAYTYPE_NETWORK): printf("network\n"); break; default: printf("unknown display type %d\n", lpnrLocal->dwDisplayType); break; } printf("NETRESOURCE[%d] Usage: 0x%x = ", i, lpnrLocal->dwUsage); if (lpnrLocal->dwUsage & RESOURCEUSAGE_CONNECTABLE) printf("connectable "); if (lpnrLocal->dwUsage & RESOURCEUSAGE_CONTAINER) printf("container "); printf("\n"); printf("NETRESOURCE[%d] Localname: %S\n", i, lpnrLocal->lpLocalName); printf("NETRESOURCE[%d] Remotename: %S\n", i, lpnrLocal->lpRemoteName); printf("NETRESOURCE[%d] Comment: %S\n", i, lpnrLocal->lpComment); printf("NETRESOURCE[%d] Provider: %S\n", i, lpnrLocal->lpProvider); printf("\n"); } It's proably not work me posting my code. Spoiler CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard
Danyfirex Posted November 15, 2018 Posted November 15, 2018 Hello. Check this: Saludos Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut
water Posted November 15, 2018 Posted November 15, 2018 That's exactly the thread the OP referred to with his quote My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki
c.haslam Posted November 15, 2018 Author Posted November 15, 2018 I am wondering whether the C/C++ code works. The Microsoft article is at https://docs.microsoft.com/en-us/windows/desktop/WNet/enumerating-network-resources Spoiler CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard
Earthshine Posted November 15, 2018 Posted November 15, 2018 (edited) can't you build it and find out? there are free versions of Visual Studio you can download I just built it as a console exe in Visual Studio 2017, latest updates and it works fine. expandcollapse popup// ConsoleApplication1.cpp : This file contains the 'main' function. Program execution begins and ends there. // #include "pch.h" #include <iostream> #ifndef UNICODE #define UNICODE #endif #pragma comment(lib, "mpr.lib") #include <windows.h> #include <stdio.h> #include <winnetwk.h> BOOL WINAPI EnumerateFunc(LPNETRESOURCE lpnr); void DisplayStruct(int i, LPNETRESOURCE lpnrLocal); int main() { LPNETRESOURCE lpnr = NULL; if (EnumerateFunc(lpnr) == FALSE) { printf("Call to EnumerateFunc failed\n"); return 1; } else return 0; } BOOL WINAPI EnumerateFunc(LPNETRESOURCE lpnr) { DWORD dwResult, dwResultEnum; HANDLE hEnum; DWORD cbBuffer = 16384; // 16K is a good size DWORD cEntries = -1; // enumerate all possible entries LPNETRESOURCE lpnrLocal; // pointer to enumerated structures DWORD i; // // Call the WNetOpenEnum function to begin the enumeration. // dwResult = WNetOpenEnum(RESOURCE_GLOBALNET, // all network resources RESOURCETYPE_ANY, // all resources 0, // enumerate all resources lpnr, // NULL first time the function is called &hEnum); // handle to the resource if (dwResult != NO_ERROR) { printf("WnetOpenEnum failed with error %d\n", dwResult); return FALSE; } // // Call the GlobalAlloc function to allocate resources. // lpnrLocal = (LPNETRESOURCE)GlobalAlloc(GPTR, cbBuffer); if (lpnrLocal == NULL) { printf("WnetOpenEnum failed with error %d\n", dwResult); // NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetOpenEnum"); return FALSE; } do { dwResultEnum = WNetEnumResource(hEnum, // resource handle &cEntries, // defined locally as -1 lpnrLocal, // LPNETRESOURCE &cbBuffer); // buffer size if (dwResultEnum == NO_ERROR) { for (i = 0; i < cEntries; i++) { DisplayStruct(i, &lpnrLocal[i]); if (RESOURCEUSAGE_CONTAINER == (lpnrLocal[i].dwUsage & RESOURCEUSAGE_CONTAINER)) if (!EnumerateFunc(&lpnrLocal[i])) printf("EnumerateFunc returned FALSE\n"); } } else if (dwResultEnum != ERROR_NO_MORE_ITEMS) { printf("WNetEnumResource failed with error %d\n", dwResultEnum); break; } } while (dwResultEnum != ERROR_NO_MORE_ITEMS); dwResult = WNetCloseEnum(hEnum); if (dwResult != NO_ERROR) { printf("WNetCloseEnum failed with error %d\n", dwResult); return FALSE; } return TRUE; } void DisplayStruct(int i, LPNETRESOURCE lpnrLocal) { printf("NETRESOURCE[%d] Scope: ", i); switch (lpnrLocal->dwScope) { case (RESOURCE_CONNECTED): printf("connected\n"); break; case (RESOURCE_GLOBALNET): printf("all resources\n"); break; case (RESOURCE_REMEMBERED): printf("remembered\n"); break; default: printf("unknown scope %d\n", lpnrLocal->dwScope); break; } printf("NETRESOURCE[%d] Type: ", i); switch (lpnrLocal->dwType) { case (RESOURCETYPE_ANY): printf("any\n"); break; case (RESOURCETYPE_DISK): printf("disk\n"); break; case (RESOURCETYPE_PRINT): printf("print\n"); break; default: printf("unknown type %d\n", lpnrLocal->dwType); break; } printf("NETRESOURCE[%d] DisplayType: ", i); switch (lpnrLocal->dwDisplayType) { case (RESOURCEDISPLAYTYPE_GENERIC): printf("generic\n"); break; case (RESOURCEDISPLAYTYPE_DOMAIN): printf("domain\n"); break; case (RESOURCEDISPLAYTYPE_SERVER): printf("server\n"); break; case (RESOURCEDISPLAYTYPE_SHARE): printf("share\n"); break; case (RESOURCEDISPLAYTYPE_FILE): printf("file\n"); break; case (RESOURCEDISPLAYTYPE_GROUP): printf("group\n"); break; case (RESOURCEDISPLAYTYPE_NETWORK): printf("network\n"); break; default: printf("unknown display type %d\n", lpnrLocal->dwDisplayType); break; } printf("NETRESOURCE[%d] Usage: 0x%x = ", i, lpnrLocal->dwUsage); if (lpnrLocal->dwUsage & RESOURCEUSAGE_CONNECTABLE) printf("connectable "); if (lpnrLocal->dwUsage & RESOURCEUSAGE_CONTAINER) printf("container "); printf("\n"); printf("NETRESOURCE[%d] Localname: %S\n", i, lpnrLocal->lpLocalName); printf("NETRESOURCE[%d] Remotename: %S\n", i, lpnrLocal->lpRemoteName); printf("NETRESOURCE[%d] Comment: %S\n", i, lpnrLocal->lpComment); printf("NETRESOURCE[%d] Provider: %S\n", i, lpnrLocal->lpProvider); printf("\n"); } pch.cpp pch.h Edited November 16, 2018 by Earthshine My resources are limited. You must ask the right questions
Earthshine Posted November 15, 2018 Posted November 15, 2018 you could easily turn it into a dll My resources are limited. You must ask the right questions
c.haslam Posted November 17, 2018 Author Posted November 17, 2018 Thank you for trying Microsoft's code. Good to hear that it works. It appears that I have something wrong in my AutoIt code. Spoiler CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard
c.haslam Posted November 18, 2018 Author Posted November 18, 2018 Here is my translation to AutoIt: expandcollapse popup#include <APIErrorsConstants.au3> #include <Memory.au3> #include <WinAPIMisc.au3> #include <WinNet.au3> ; DisplayType Global Const $RESOURCEDISPLAYTYPE_GENERIC = 0x00000000 Global Const $RESOURCEDISPLAYTYPE_DOMAIN = 0x00000001 Global Const $RESOURCEDISPLAYTYPE_SERVER = 0x00000002 Global Const $RESOURCEDISPLAYTYPE_SHARE = 0x00000003 Global Const $RESOURCEDISPLAYTYPE_FILE = 0x00000004 Global Const $RESOURCEDISPLAYTYPE_GROUP = 0x00000005 Global Const $RESOURCEDISPLAYTYPE_NETWORK = 0x00000006 Global Const $RESOURCEDISPLAYTYPE_ROOT = 0x00000007 Global Const $RESOURCEDISPLAYTYPE_SHAREADMIN = 0x00000008 Global Const $RESOURCEDISPLAYTYPE_DIRECTORY = 0x00000009 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" says Kafu If Not Enumerate(0) Then ConsoleWrite('Call to Enumerate failed'&@CRLF) EndIf Func Enumerate($lpnr) Local $dwResult Local $hEnum Local $icBuffer = 16384 Local $icEntries = -1 ; Updated by _WinNet_EnumResource to actual number of entries ; Call _WNet_OpenEnum to begin enumeration $dwResult = _cWinNet_OpenEnum( _ $RESOURCE_GLOBALNET, _ ; $iScope all network resoruces $RESOURCETYPE_ANY, _ ; $iType all i.e. print and disk 0, _ ; $iUsage all usages $lpnr, _ ; $tResource 0 first time $hEnum) ; BYRef If Not $dwResult Then ConsoleWrite('_cWinNet_OpenEnum failed with error '&@error&@CRLF) Return False EndIf Local $lpnrLocal = _MemGlobalAlloc($icBuffer, $GMEM_ZEROINIT ) Local $dwResultEnum Do ; Call _WinNet_EnumResource to continue enumeration $dwResultEnum = _WinNet_EnumResource($hEnum, _ ; resource handle $icEntries, _ ; ByRef: before call -1 so updatued to number of that fit in buffer $lpnrLocal, _ ; 1 or more $ttagRESOURCEs $icBuffer) ; ByRef: if buffer too small for 1 resource, updated to needed size If $dwResultEnum=0 Then $lpnr = $lpnrLocal For $i = 1 To $icEntries DisplayStruct($i,$lpnr) ; If $tNETRESOURCE struct represents a container resource, call Enumerate recursively Local $tstruct = DllStructCreate($tagNETRESOURCE_New,$lpnr) Local $iN = DllStructGetData($tstruct,'Usage') If BitAND($iN,$RESOURCEUSAGE_CONTAINER)=$RESOURCEUSAGE_CONTAINER Then If Not Enumerate($tstruct) Then ConsoleWrite('Enumerate returned False'&@CRLF) EndIf EndIf $lpnr += 32 ; = DllStructGetSize(DllStructCreate($tagNETRESOURCE)) Next ElseIf $dwResultEnum<>$ERROR_NO_MORE_ITEMS Then ConsoleWrite('Enumerate failed with error '&$dwResultEnum) ExitLoop EndIf Until $dwResultEnum=$ERROR_NO_MORE_ITEMS ; Call WinNet_CloseEnum to end enumeration $dwResult = _cWinNet_CloseEnum($hEnum) If Not $dwResult<>0 Then ConsoleWrite('_WinNet_CloseEnum failed with error '&@error) Return False EndIf Return True EndFunc Func DisplayStruct($i,$lpnr) Local $tstruct = DllStructCreate($tagNETRESOURCE_New,$lpnr) ConsoleWrite('NETRESOURCE['&$i&'] Scope: ') Local $iN = DllStructGetData($tstruct,'Scope ') Switch $iN Case $RESOURCE_CONNECTED ConsoleWrite('connected'&@CRLF) Case $RESOURCE_GLOBALNET ConsoleWrite('all resources'&@CRLF) Case $RESOURCE_REMEMBERED ConsoleWrite('remembered'&@CRLF) Case Else ConsoleWrite('unknown scope '&$iN&@CRLF) EndSwitch ConsoleWrite('NETRESOURCE['&$i&'] Type: ') $iN = DllStructGetData($tstruct,'Type') Switch $iN Case $RESOURCETYPE_ANY ConsoleWrite('any'&@CRLF) Case $RESOURCETYPE_DISK ConsoleWrite('disk'&@CRLF) Case $RESOURCETYPE_PRINT ConsoleWrite('print'&@CRLF) Case Else ConsoleWrite('unknown type '&$iN&@CRLF) EndSwitch ConsoleWrite('NETRESOURCE['&$i&'] DisplayType: ') $iN = DllStructGetData($tstruct,'DisplayType') Switch $iN Case $RESOURCEDISPLAYTYPE_GENERIC ConsoleWrite('generic'&@CRLF) Case $RESOURCEDISPLAYTYPE_SERVER ConsoleWrite('server'&@CRLF) Case $RESOURCEDISPLAYTYPE_SHARE ConsoleWrite('share'&@CRLF) Case $RESOURCEDISPLAYTYPE_FILE ConsoleWrite('file'&@CRLF) Case $RESOURCEDISPLAYTYPE_GROUP ConsoleWrite('group'&@CRLF) Case $RESOURCEDISPLAYTYPE_NETWORK ConsoleWrite('network'&@CRLF) Case Else ConsoleWrite('unknown display type '&$iN) EndSwitch $iN = DllStructGetData($tstruct,'Usage') ConsoleWrite('NETRESOURCE['&$i&'] Usage: '&Hex($iN)&' = ') If BitAND($iN,$RESOURCEUSAGE_CONNECTABLE)<>0 Then ConsoleWrite('connectable ') EndIf If BitAND($iN,$RESOURCEUSAGE_CONTAINER)<>0 Then ConsoleWrite('container ') EndIf ConsoleWrite(@CRLF) ConsoleWrite('NETRESOURCE['&$i&'] LocalName: '&_PointerToStringW(DllStructGetData($tstruct,'LocalName'))&@CRLF) ConsoleWrite('NETRESOURCE['&$i&'] RemoteName: '&_PointerToStringW(DllStructGetData($tstruct,'RemoteName'))&@CRLF) ConsoleWrite('NETRESOURCE['&$i&'] Comment: '&_PointerToStringW(DllStructGetData($tstruct,'Comment'))&@CRLF) ConsoleWrite('NETRESOURCE['&$i&'] Provider: '&_PointerToStringW(DllStructGetData($tstruct,'Provider'))&@CRLF) ConsoleWrite(@CRLF) EndFunc Func _PointerToStringW($ptr) Return DllStructGetData(DllStructCreate("wchar[" & _WinAPI_StringLenW($ptr) & "]", $ptr), 1) EndFunc ; Overcomes limitation(s) in WinNet.au3 version Func _cWinNet_OpenEnum($iScope, $iType, $iUsage, $tResource, ByRef $hEnum) Local $aResult = DllCall("mpr.dll", "dword", "WNetOpenEnum", "dword", $iScope, "dword", $iType, "dword", _ $iUsage, "struct*", $tResource, "handle*", 0) If $aResult[0]=0 Then $hEnum = $aResult[5] Return True Else Return SetError($aResult[0], 0,False) EndIf EndFunc ;==>_WinNet_OpenEnum Func _cWinNet_CloseEnum($hEnum) Local $aResult = DllCall("mpr.dll", "dword", "WNetCloseEnum", "handle", $hEnum) If $aResult[0]=0 Then Return True Else Return SetError($aResult[0], 0,False) EndIf EndFunc ;==>_WinNet_CloseEnum Its output to the console is: >"F:\Program Files\AutoIt3\SciTE\..\AutoIt3.exe" "F:\Program Files\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "F:\AutoIt scripts\cFileSelectFolder\to forum.au3" /UserParams +>18:50:02 Starting AutoIt3Wrapper v.17.224.935.0 SciTE v.3.7.3.0 Keyboard:00000409 OS:WIN_7/Service Pack 1 CPU:X64 OS:X86 Environment(Language:0409) CodePage:0 utf8.auto.check:4 +> SciTEDir => F:\Program Files\AutoIt3\SciTE UserDir => C:\Users\Chris\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper SCITE_USERHOME => C:\Users\Chris\AppData\Local\AutoIt v3\SciTE >Running AU3Check (3.3.14.5) from:F:\Program Files\AutoIt3 input:F:\AutoIt scripts\cFileSelectFolder\to forum.au3 +>18:50:03 AU3Check ended.rc:0 >Running:(3.3.14.5):F:\Program Files\AutoIt3\autoit3.exe "F:\AutoIt scripts\cFileSelectFolder\to forum.au3" --> Press Ctrl+Alt+Break to Restart or Ctrl+Break to Stop NETRESOURCE[1] Scope: unknown scope 0 NETRESOURCE[1] Type: any NETRESOURCE[1] DisplayType: network NETRESOURCE[1] Usage: 0000000080000002 = container NETRESOURCE[1] LocalName: 0 NETRESOURCE[1] RemoteName: Microsoft Terminal Services NETRESOURCE[1] Comment: 0 NETRESOURCE[1] Provider: Microsoft Terminal Services _cWinNet_OpenEnum failed with error 1204 Enumerate returned False NETRESOURCE[2] Scope: unknown scope 0 NETRESOURCE[2] Type: any NETRESOURCE[2] DisplayType: network NETRESOURCE[2] Usage: 0000000080000002 = container NETRESOURCE[2] LocalName: 0 NETRESOURCE[2] RemoteName: Microsoft Windows Network NETRESOURCE[2] Comment: 0 NETRESOURCE[2] Provider: Microsoft Windows Network _cWinNet_OpenEnum failed with error 1204 Enumerate returned False NETRESOURCE[3] Scope: unknown scope 0 NETRESOURCE[3] Type: any NETRESOURCE[3] DisplayType: network NETRESOURCE[3] Usage: 0000000080000002 = container NETRESOURCE[3] LocalName: 0 NETRESOURCE[3] RemoteName: Web Client Network NETRESOURCE[3] Comment: 0 NETRESOURCE[3] Provider: Web Client Network _cWinNet_OpenEnum failed with error 1204 Enumerate returned False +>18:50:05 AutoIt3.exe ended.rc:0 +>18:50:05 AutoIt3Wrapper Finished. >Exit code: 0 Time: 4.437 and the error is: $ERROR_BAD_PROVIDER = 1204 ; The specified network provider name is invalid. It is occurring in the recursion. In the C/C++ code, I don't understand lpnrLocal[i].dwUsage because, to me, lpnrLocal is not an array. Help would be greatly appreciated. My network is 2 computers, one (mine) having mapped drives and one printer. The other printer is on the network. Microsoft's description of their methodology is at https://docs.microsoft.com/en-us/windows/desktop/WNet/enumerating-network-resources Spoiler CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard
Danyfirex Posted November 18, 2018 Posted November 18, 2018 (edited) Hello. You code is almost correct. the issue is that you're using the ANSI version of WNetOpenEnum in your Dllcall(By default, AutoIt tries to use the ANSI version of a function name when you don't specific the A-W termination ) so WNetOpenEnum expects ANSI version of NETRESOURCE structure, But you're using Unicode one. So just call WNetOpenEnumW. Here is your code fixed. expandcollapse popup#include <APIErrorsConstants.au3> #include <Memory.au3> #include <WinAPIMisc.au3> #include <WinNet.au3> ; DisplayType Global Const $RESOURCEDISPLAYTYPE_GENERIC = 0x00000000 Global Const $RESOURCEDISPLAYTYPE_DOMAIN = 0x00000001 Global Const $RESOURCEDISPLAYTYPE_SERVER = 0x00000002 Global Const $RESOURCEDISPLAYTYPE_SHARE = 0x00000003 Global Const $RESOURCEDISPLAYTYPE_FILE = 0x00000004 Global Const $RESOURCEDISPLAYTYPE_GROUP = 0x00000005 Global Const $RESOURCEDISPLAYTYPE_NETWORK = 0x00000006 Global Const $RESOURCEDISPLAYTYPE_ROOT = 0x00000007 Global Const $RESOURCEDISPLAYTYPE_SHAREADMIN = 0x00000008 Global Const $RESOURCEDISPLAYTYPE_DIRECTORY = 0x00000009 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" says Kafu If Not Enumerate(0) Then ConsoleWrite('Call to Enumerate failed'&@CRLF) EndIf Func Enumerate($lpnr) Local $dwResult Local $hEnum Local $icBuffer = 16384 Local $icEntries = -1 ; Updated by _WinNet_EnumResource to actual number of entries ; Call _WNet_OpenEnum to begin enumeration $dwResult = _cWinNet_OpenEnum( _ $RESOURCE_GLOBALNET, _ ; $iScope all network resoruces $RESOURCETYPE_ANY, _ ; $iType all i.e. print and disk 0, _ ; $iUsage all usages $lpnr, _ ; $tResource 0 first time $hEnum) ; BYRef If Not $dwResult Then ConsoleWrite('_cWinNet_OpenEnum failed with error '&@error&@CRLF) Return False EndIf Local $lpnrLocal = _MemGlobalAlloc($icBuffer, $GMEM_ZEROINIT ) Local $dwResultEnum Do ; Call _WinNet_EnumResource to continue enumeration $dwResultEnum = _WinNet_EnumResource($hEnum, _ ; resource handle $icEntries, _ ; ByRef: before call -1 so updatued to number of that fit in buffer $lpnrLocal, _ ; 1 or more $ttagRESOURCEs $icBuffer) ; ByRef: if buffer too small for 1 resource, updated to needed size If $dwResultEnum=0 Then $lpnr = $lpnrLocal For $i = 1 To $icEntries DisplayStruct($i,$lpnr) ; If $tNETRESOURCE struct represents a container resource, call Enumerate recursively Local $tstruct = DllStructCreate($tagNETRESOURCE_New,$lpnr) Local $iN = DllStructGetData($tstruct,'Usage') If BitAND($iN,$RESOURCEUSAGE_CONTAINER)=$RESOURCEUSAGE_CONTAINER Then If Not Enumerate($tstruct) Then ConsoleWrite('Enumerate returned False'&@CRLF) EndIf EndIf $lpnr += 32 ; = DllStructGetSize(DllStructCreate($tagNETRESOURCE)) Next ElseIf $dwResultEnum<>$ERROR_NO_MORE_ITEMS Then ConsoleWrite('Enumerate failed with error '&$dwResultEnum) ExitLoop EndIf Until $dwResultEnum=$ERROR_NO_MORE_ITEMS ; Call WinNet_CloseEnum to end enumeration $dwResult = _cWinNet_CloseEnum($hEnum) If Not $dwResult<>0 Then ConsoleWrite('_WinNet_CloseEnum failed with error '&@error) Return False EndIf Return True EndFunc Func DisplayStruct($i,$lpnr) Local $tstruct = DllStructCreate($tagNETRESOURCE_New,$lpnr) ConsoleWrite('NETRESOURCE['&$i&'] Scope: ') Local $iN = DllStructGetData($tstruct,'Scope ') Switch $iN Case $RESOURCE_CONNECTED ConsoleWrite('connected'&@CRLF) Case $RESOURCE_GLOBALNET ConsoleWrite('all resources'&@CRLF) Case $RESOURCE_REMEMBERED ConsoleWrite('remembered'&@CRLF) Case Else ConsoleWrite('unknown scope '&$iN&@CRLF) EndSwitch ConsoleWrite('NETRESOURCE['&$i&'] Type: ') $iN = DllStructGetData($tstruct,'Type') Switch $iN Case $RESOURCETYPE_ANY ConsoleWrite('any'&@CRLF) Case $RESOURCETYPE_DISK ConsoleWrite('disk'&@CRLF) Case $RESOURCETYPE_PRINT ConsoleWrite('print'&@CRLF) Case Else ConsoleWrite('unknown type '&$iN&@CRLF) EndSwitch ConsoleWrite('NETRESOURCE['&$i&'] DisplayType: ') $iN = DllStructGetData($tstruct,'DisplayType') Switch $iN Case $RESOURCEDISPLAYTYPE_GENERIC ConsoleWrite('generic'&@CRLF) Case $RESOURCEDISPLAYTYPE_SERVER ConsoleWrite('server'&@CRLF) Case $RESOURCEDISPLAYTYPE_SHARE ConsoleWrite('share'&@CRLF) Case $RESOURCEDISPLAYTYPE_FILE ConsoleWrite('file'&@CRLF) Case $RESOURCEDISPLAYTYPE_GROUP ConsoleWrite('group'&@CRLF) Case $RESOURCEDISPLAYTYPE_NETWORK ConsoleWrite('network'&@CRLF) Case Else ConsoleWrite('unknown display type '&$iN) EndSwitch $iN = DllStructGetData($tstruct,'Usage') ConsoleWrite('NETRESOURCE['&$i&'] Usage: '&Hex($iN)&' = ') If BitAND($iN,$RESOURCEUSAGE_CONNECTABLE)<>0 Then ConsoleWrite('connectable ') EndIf If BitAND($iN,$RESOURCEUSAGE_CONTAINER)<>0 Then ConsoleWrite('container ') EndIf ConsoleWrite(@CRLF) ConsoleWrite('NETRESOURCE['&$i&'] LocalName: '&_PointerToStringW(DllStructGetData($tstruct,'LocalName'))&@CRLF) ConsoleWrite('NETRESOURCE['&$i&'] RemoteName: '&_PointerToStringW(DllStructGetData($tstruct,'RemoteName'))&@CRLF) ConsoleWrite('NETRESOURCE['&$i&'] Comment: '&_PointerToStringW(DllStructGetData($tstruct,'Comment'))&@CRLF) ConsoleWrite('NETRESOURCE['&$i&'] Provider: '&_PointerToStringW(DllStructGetData($tstruct,'Provider'))&@CRLF) ConsoleWrite(@CRLF) EndFunc Func _PointerToStringW($ptr) Return DllStructGetData(DllStructCreate("wchar[" & _WinAPI_StringLenW($ptr) & "]", $ptr), 1) EndFunc ; Overcomes limitation(s) in WinNet.au3 version Func _cWinNet_OpenEnum($iScope, $iType, $iUsage, $tResource, ByRef $hEnum) Local $aResult = DllCall("mpr.dll", "dword", "WNetOpenEnumW", "dword", $iScope, "dword", $iType, "dword", _ $iUsage, "struct*", $tResource, "handle*", 0) If $aResult[0]=0 Then $hEnum = $aResult[5] Return True Else Return SetError($aResult[0], 0,False) EndIf EndFunc ;==>_WinNet_OpenEnum Func _cWinNet_CloseEnum($hEnum) Local $aResult = DllCall("mpr.dll", "dword", "WNetCloseEnum", "handle", $hEnum) If $aResult[0]=0 Then Return True Else Return SetError($aResult[0], 0,False) EndIf EndFunc ;==>_WinNet_CloseEnum PD: Make 32 pointer index step functional for 64 bits too Saludos Edited November 18, 2018 by Danyfirex Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut
c.haslam Posted November 19, 2018 Author Posted November 19, 2018 Thank you. I will look at it in the morning. Spoiler CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard
c.haslam Posted November 19, 2018 Author Posted November 19, 2018 The corrected script runs AOK. What would the ANSI version of $tagRESOURCE_New look like? By ' Make 32 pointer index step functional for 64 bits too " I am thinking that you mean change $lpnr += 32 What would be the change for this script to also work on an X64 computer? The 32 comes from 4 dwords of 8 bytes each. Spoiler CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard
Danyfirex Posted November 19, 2018 Posted November 19, 2018 (edited) Acutally $tagNETRESOURCE works for x64 and x86. Don't touch it. something like this is enough: local $iStep= DllStructGetSize(DllStructCreate($tagNETRESOURCE)) $lpnr+=iStep Saludos Edited November 19, 2018 by Danyfirex Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut
Earthshine Posted November 19, 2018 Posted November 19, 2018 (edited) tested it against the c++ exe, it doesn't work. update, we have been switching equipment out, network issues. i retested on another machine on different network and it looks like it's working Edited November 19, 2018 by Earthshine My resources are limited. You must ask the right questions
c.haslam Posted November 19, 2018 Author Posted November 19, 2018 (edited) As you can see, I have already written my own versions of _WinNet_OpenEnum and _WinNet_CloseEnum. My versions return True on success, and False on Failure. If the call fails, @error is set to the system error code. I believe that this is the way AutoIt UDFs usually work. I have my own version of _WinNet_EnumResources (not called in the script I posted and you fixed) which I have not implemented yet. I do see that another function in WinNet.au3 has the same problem: it returns @error if there is an error in the call to DllCall rather than returning @error if the _WinNet function fails. Perhaps other functions in WinNet.au3 also do this. In writing my _cWinEnumResources I deviated from Microsoft in one way: M$ considers ERROR_NO_MORE_ITEMS to indicate success. I consider it to be failure, as the best way to go: if there are no more items, no data is returned. Func _cWinNet_EnumResource($hEnum, ByRef $iCount, $pBuffer, ByRef $iBufSize) Local $aResult = DllCall("mpr.dll", "dword", "WNetEnumResourceW", "handle", $hEnum, "dword*", $iCount, "struct*", $pBuffer, "dword*", $iBufSize) If $aResult=0 Then $iCount = $aResult[2] $iBufSize = $aResult[4] Return True Else Return SetError($aResult[0],0,False) EndIf EndFunc I think that it would be beneficial to all for WinNet.au3 to be changed, but this would be script-breaking changes; however, it may be that no one is using the versions of these functions in WinNet.au3 because they are defective, so perhaps no one's script will be broken. Thoughts? Edited November 19, 2018 by c.haslam Spoiler CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard
c.haslam Posted November 19, 2018 Author Posted November 19, 2018 Earthshine: Thanks for more testing Earthshine 1 Spoiler CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard
c.haslam Posted November 19, 2018 Author Posted November 19, 2018 (edited) I take back "defective". The Help says: "Success: True ; Failure: False", which is not so. Edited November 19, 2018 by c.haslam Spoiler CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now