Determining Available Network Resources

To determine the resources available on a network, an application passes the address of a NETRESOURCE structure to the WNetOpenEnum function. Calling WNetOpenEnum initializes an enumeration instance with the NETRESOURCE structure specifying the enumeration parameters.

    To identify available network resources

  1. Set up the NETRESOURCE structure to define enumeration.

    To enumerate a shared directory on a server, change the lpRemoteName member in NETRESOURCE to the name of the server. Similarly, to enumerate servers in a domain, change the lpRemoteName to the name of the domain.

    The following code example shows how to enumerate a shared directory on a server.

    NETRESOURCE nr;
    
    nr.dwScope = RESOURCE_GLOBALNET;
    nr.dwType = RESOURCETYPE_DISK;  
    nr.dwUsage = RESOURCEUSAGE_CONTAINER;
    nr.lpLocalName = TEXT("");
    nr.lpRemoteName = TEXT("\\\\MyServer");
    nr.lpComment = TEXT("");
    nr.lpProvider = TEXT("");
    
    EnumerateFunc (hwnd, &nr); 
    
    

    The following code example shows how to enumerate servers in a domain.

    NETRESOURCE nr;
    
    nr.dwScope = RESOURCE_GLOBALNET;
    nr.dwType = RESOURCETYPE_DISK;  
    nr.dwUsage = RESOURCEUSAGE_CONTAINER;
    nr.lpLocalName = TEXT("");
    nr.lpRemoteName = TEXT("MyDomain");
    nr.lpComment = TEXT("");
    nr.lpProvider = TEXT("");
    
    EnumerateFunc (hwnd, &nr); 
    
    
  2. Call WNetOpenEnum to create an enumeration handle to the resource defined by NETRESOURCE.
  3. Call WNetEnumResource with the enumeration handle created in the previous step to package the resource data in an array of NETRESOURCE structures.
  4. Call WNetCloseEnum to close the enumeration handle.

    An application can continue enumerating any container's resources.

If the dwUsage member of NETRESOURCE returned by WNetEnumResource is RESOURCEUSAGE_CONTAINER, an application can continue enumerating that container by passing the address of that structure to WNetOpenEnum. If dwUsage is RESOURCEUSAGE_CONNECTABLE, an application can add a connection to the resource by passing the structure address to the WNetAddConnection3 function. For more information, see Establishing a Network Connection.

The following code example shows how an application-defined function, EnumerateFunc, that enumerates all the resources in a subdirectory on a network. This function takes a pointer to a NETRESOURCE structure describing the subdirectory. Whenever WNetEnumResource returns a NETRESOURCE structure with the dwUsage member corresponding to RESOURCEUSAGE_CONTAINER, EnumerateFunc calls itself and passes a pointer to this structure in its call to WNetOpenEnum.

BOOL WINAPI EnumerateFunc (HWND hwnd, LPNETRESOURCE lpnr)
{
  HANDLE hEnum;

  DWORD dwIndex,
        dwResult,
        dwBufferSize = 16384,       
        dwNumEntries = 0xFFFFFFFF;  // Enumerate all possible entries.

  LPNETRESOURCE lpnrLocal;          // Pointer to enumerated structures.

  dwResult = WNetOpenEnum (
                    RESOURCE_GLOBALNET, // All resources on the network
                    RESOURCETYPE_ANY,   // All resources 
                    0,                  // Enumerate all resources.
                    lpnr,               // The container to enumerate
                    &hEnum);            // Handle to resource

  if (dwResult != ERROR_SUCCESS) 
  {
    ErrorHandler (hwnd, dwResult, TEXT("WNetOpenEnum"));
    return FALSE;
  }

  // Allocate memory for NETRESOURCE structures.
  if (!(lpnrLocal = (LPNETRESOURCE) LocalAlloc (LPTR, dwBufferSize)))
    MessageBox (hwnd, TEXT("Not enough memory"), TEXT("Error"), MB_OK);
    
  do 
  {
    dwResult = WNetEnumResource (
                    hEnum,              // Resource handle
                    &dwNumEntries,      // Number of entries
                    lpnrLocal,          // LPNETRESOURCE
                    &dwBufferSize);     // Buffer size

    if (dwResult == ERROR_SUCCESS) 
    {
      for (dwIndex = 0; dwIndex < dwNumEntries; dwIndex++)
      {
        // Insert code here to perform operations with lpnrLocal
        // for example, to display contents of NETRESOURCE structures.
        // ...

        // If this NETRESOURCE is a container, call the function
        // recursively.
        if (RESOURCEUSAGE_CONTAINER ==
            (lpnrLocal[dwIndex].dwUsage & RESOURCEUSAGE_CONTAINER))
        {
          if(!EnumerateFunc (hwnd, &lpnrLocal[dwIndex]))
              MessageBox (hwnd, TEXT("EnumerateFunc returned FALSE."), 
                          TEXT("Error"), MB_OK);
        }
      }
    }
    else if (dwResult != ERROR_NO_MORE_ITEMS) 
    {
      ErrorHandler (hwnd, dwResult, TEXT("WNetEnumResource"));
      break;
    }
  } while (dwResult != ERROR_NO_MORE_ITEMS);

  LocalFree (lpnrLocal);

  dwResult = WNetCloseEnum (hEnum);

  if (dwResult != ERROR_SUCCESS) 
  {
    ErrorHandler (hwnd, dwResult, TEXT("WNetCloseEnum"));
    return FALSE;
  }

  return TRUE;
}