Enumerating Network Resources

To enumerate a network container resource, your application should pass the address of a NETRESOURCE structure to the WNetOpenEnum function. WNetOpenEnum creates a handle to the resource described by the NETRESOURCE structure. The application then passes this handle to the WNetEnumResource function, which returns information about the resource in the form of an array of NETRESOURCE structures. When the handle is no longer needed, the application can close it by calling the WNetCloseEnum function.

Your application can continue enumerating any container resource described in the array of NETRESOURCE structures retrieved by WNetEnumResource. If the dwUsage member of the NETRESOURCE structure is RESOURCEUSAGE_CONTAINER, the application can pass the address of that structure to WNetOpenEnum to open the container and continue the enumeration. If dwUsage is RESOURCEUSAGE_CONNECTABLE, the application can pass the structure's address to the WNetAddConnection2 function.

The following example illustrates an application-defined function (EnumerateFunc) that enumerates all the resources on a network. When calling this function, specify NULL for the pointer to the NETRESOURCE structure. When WNetOpenEnum receives the NULL pointer, it retrieves a handle to the root of the network. Whenever a NETRESOURCE structure retrieved by WNetEnumResource is RESOURCEUSAGE_CONTAINER, the EnumerateFunc function calls itself and uses a pointer to that structure in its call to WNetOpenEnum.

BOOL WINAPI EnumerateFunc(HWND hwnd,

HDC hdc,

LPNETRESOURCE lpnr)

{

DWORD dwResult, dwResultEnum;

HANDLE hEnum;

DWORD cbBuffer = 16384; // 16K is a good size

DWORD cEntries = 0xFFFFFFFF; // enumerate all possible entries

LPNETRESOURCE lpnrLocal; // pointer to enumerated structures

DWORD i;

dwResult = WNetOpenEnum(RESOURCE_GLOBALNET,

RESOURCETYPE_ANY,

0, // enumerate all resources

lpnr, // NULL first time this function is called

&hEnum); // handle to resource

if (dwResult != NO_ERROR) {

// An application-defined error handler is demonstrated in the

// section titled "Retrieving Network Errors."

NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetOpenEnum");

return FALSE;

}

do {

// Allocate memory for NETRESOURCE structures.

lpnrLocal = (LPNETRESOURCE) GlobalAlloc(GPTR, cbBuffer);

dwResultEnum = WNetEnumResource(hEnum, // resource handle

&cEntries, // defined locally as 0xFFFFFFFF

lpnrLocal, // LPNETRESOURCE

&cbBuffer); // buffer size

if (dwResultEnum == NO_ERROR) {

for(i = 0; i < cEntries; i++)

{

// Following is an application-defined function for

// displaying contents of NETRESOURCE structures.

DisplayStruct(hdc, &lpnrLocal[i]);

//

// If this NETRESOURCE is a container, call the function

// recursively.

if(RESOURCEUSAGE_CONTAINER ==

(lpnrLocal[i].dwUsage & RESOURCEUSAGE_CONTAINER))

if(!EnumerateFunc(hwnd, hdc, &lpnrLocal[i]))

TextOut(hdc, 10, 10,

"EnumerateFunc returned FALSE.", 29);

}

}

else if (dwResultEnum != ERROR_NO_MORE_ITEMS) {

NetErrorHandler(hwnd, dwResultEnum, (LPSTR)"WNetEnumResource");

break;

}

}

while(dwResultEnum != ERROR_NO_MORE_ITEMS);

GlobalFree((HGLOBAL) lpnrLocal);

dwResult = WNetCloseEnum(hEnum);

if(dwResult != NO_ERROR) {

NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetCloseEnum");

return FALSE;

}

return TRUE;

}