WNet Functions

< BACK  NEXT >
[oR]

Windows CE is designed to work with networks. When several Windows machines exist on a net, they can easily share disk drives and printers with one another. The Explorer provides an easy way for users to connect to these shared devices. The Windows CE API also gives you mechanisms to connect to these devices from within your applications.

Windows sees the network as a tree. Any Windows network is divided into a series of domains, each of which contains a set of machines. Each machine can share zero or more drives, directories, or printers on the network.

Windows CE supports a subset of the Win32 API WNet functions that can be used to maintain connections to network resources (such as folder and printer shares). Before using the WNet functions you must have a valid network connection through a Remote Access Services (RAS) or direct network connection using a network adapter (such as PCMCIA compatible NE2000). WNet functions cannot be used through an ActiveSync connection to a desktopPC.

The Win32 API contains a set of functions that allow you to enumerate all the shares available throughout the network and then connect to any one of these shares. The network itself, its domains, and the machines in the domains are called containers. You open containers with the WNetOpenEnum function. A container can contain other containers (for example, domains contain machines), or it can contain actual drive and printer resources, called objects. You enumerate all the items in a container that is, you request a list of everything that a container holds using the WNetEnumResources function. Once you get down to the share level, you can connect to a drive with the WNetAddConnection2 function.

This section shows you how to walk through the resource tree and also how to gather information about connected resources. Note you will need to include winnetwk.h to call the WNet functions.

Enumerating Network Resources

The code shown in Listing 3.7 demonstrates how to walk recursively through all the resources available on your network. It starts with the network itself and opens every container it finds until it reaches actual drives and printers that each machine shares on the network. It is these drive and printer objects that receive connections.

Listing 3.7 Lists all objects (shares and printers) on a network
 // NB: include winnetwk.h // This function handles WNet errors void ErrorHandler(DWORD dwErrorNum, LPTSTR s) {   cout    _T("Failure in: ")   s   _T(" ")           GetLastError()   endl; } // This function displays the information in a // NETRESOURCE structure void DisplayStruct(LPNETRESOURCE nr) {   cout   _T("Type: ");   switch(nr->dwType)   {   case RESOURCETYPE_DISK:     cout   _T("Disk")   endl;     break;   case RESOURCETYPE_PRINT:     cout   _T("Printer")   endl;     break;   case RESOURCETYPE_ANY:     cout   _T("Any")   endl;   }   cout   _T("Display Type: ");   switch(nr->dwDisplayType)   {   case RESOURCEDISPLAYTYPE_DOMAIN:     cout   _T("Domain")   endl;     break;   case RESOURCEDISPLAYTYPE_GENERIC:     cout   _T("Generic")   endl;     break;   case RESOURCEDISPLAYTYPE_SERVER:     cout   _T("Server")   endl;     break;   case RESOURCEDISPLAYTYPE_SHARE:     cout   _T("Share")   endl;   }   if(nr->lpLocalName)     cout    _T("Local Name: ")   nr->lpLocalName             endl;   if(nr->lpRemoteName)     cout    _T("Remote Name: ")   nr->lpRemoteName             endl;   if(nr->lpComment)     cout   _T("Comment: ")   nr->lpComment   endl;   if(nr->lpProvider)     cout    _T("Provider: ")   nr->lpProvider             endl;   cout   endl; } // Recursive function to enumerate resources BOOL EnumerateResources(LPNETRESOURCE nrStartingPoint) {   DWORD dwResult, dwResultEnum, i;   LPNETRESOURCE lpNRBuffer;   DWORD dwBufferSize = 16384;   DWORD dwNumEntries = 0xFFFFFFFF;   HANDLE hEnum;   dwResult = WNetOpenEnum(RESOURCE_GLOBALNET,       RESOURCETYPE_ANY,       0, nrStartingPoint, &hEnum);   if(dwResult != NO_ERROR)   {     ErrorHandler(dwResult, _T("WNetOpenEnum"));     return FALSE;   }   // allocate a buffer to hold resources   lpNRBuffer = (LPNETRESOURCE)       LocalAlloc(LPTR, dwBufferSize);   // loop through all the elements in the container   do   {      dwBufferSize = 16384;      dwNumEntries = 0xFFFFFFFF;      // Get resources      dwResultEnum = WNetEnumResource(hEnum,        &dwNumEntries, lpNRBuffer, &dwBufferSize);      if(dwResultEnum == NO_ERROR)      {        // loop through each of the entries        for(i = 0; i  dwNumEntries; i++)        {           DisplayStruct(&lpNRBuffer[i]);           // if container, recursively open it           if(lpNRBuffer[i].dwUsage &               RESOURCEUSAGE_CONTAINER)           {           if(!EnumerateResources(                &lpNRBuffer[i]))              cout                 _T("Enumeration Failed.")                  endl;           }        }     }     else if(dwResultEnum != ERROR_NO_MORE_ITEMS)     {        ErrorHandler(dwResultEnum,          _T("WNetEnumResource"));        break;     }   }   while(dwResultEnum != ERROR_NO_MORE_ITEMS);   // Clean up   LocalFree(lpNRBuffer);   dwResult = WNetCloseEnum(hEnum);   if(dwResult != NO_ERROR)   {      ErrorHandler(dwResult, _T("WNetCloseEnum"));      return FALSE;   }   return TRUE; } void Listing3_7() {   // Start the recursion at the net level   NETRESOURCE nr;   TCHAR szContainer[MAX_PATH + 1];   if(!GetTextResponse(      _T("Enter Container to list:"), szContainer,              MAX_PATH))      return;   memset(&nr, 0, sizeof(nr));   nr.lpRemoteName = szContainer;   nr.dwUsage = RESOURCEUSAGE_CONTAINER;   EnumerateResources(&nr); } 

The program in Listing 3.7 starts in its Listing3_7 function by prompting the user for the container (either a domain or a server). It passes this container to the EnumerateResources function, which recursively traverses the container. The EnumerateResources function calls WNetOpenEnum.

Table 3.8. WNetOpenEnum Opens a container
WNetOpenEnum
DWORD scope Scope of the search. This can be:
RESOURCE_CONNECTED for all currently connected resources.
RESOURCE_GLOBALNET for all resources on the network.
RESOURCE_REMEMBERED for all persistent connections.
DWORD type Type of items to enumerate. This can be:
RESOURCETYPE_ANY for all resources.
RESOURCETYPE_DISK for disk resources.
RESOURCETYPE_PRINT for print resources.
DWORD usage Type of objects to open. This can be:
0 for all resources.
RESOURCEUSAGE_CONNECTABLE for resources that can be connected to.
RESOURCEUSAGE_CONTAINER for container objects.
LPNETRESOURCE resource Specifies container (server or domain) to open. NULL for network.
LPHANDLE enumHandle Returned handle to the opened container.
DWORD Return Value NO_ERROR on success, or an error code.

The WNetOpenEnum function opens a container, returning a handle to that container so that you can enumerate its contents. The Resource parameter specifies the container that you want to open. The Scope, Type, and Usage parameters specify the type of objects that will be enumerated by the WNetEnumResources function.

Initially, the WNetOpenEnum function receives the container specified by the user for its resource. Once the container is open, Listing 3.7 enters a loop that calls WNetEnumResources to get all the objects inside the container.

Table 3.9. WNetEnumResources Enumerates resources in an open container
WNetEnumResources
HANDLE enumHandle Handle to an open container
LPDWORD numEntries Number of entries desired/returned
LPVOID buffer Buffer to hold returned entries
LPDWORD bufferSize Original/returned size of buffer
DWORD Return Value NO_ERROR or ERROR_NO_MORE_ITEMS on success, or an error code

The WNetEnumResources function accepts the handle returned by WNetOpenEnum, the number of entries desired (or 0xFFFFFFFF if you want them all), a buffer to place the entries into (allocated by LocalAlloc; see Chapter 12 for details), and the size of the buffer (the documentation specifies that 16K is a reasonable value). In the buffer the function returns an array of NETRESOURCE structures that contains information about each entry in the container.

 typedef struct _NETRESOURCE {   DWORD  dwScope;   DWORD  dwType;   DWORD  dwDisplayType;   DWORD  dwUsage;   LPTSTR lpLocalName;   LPTSTR lpRemoteName;   LPTSTR lpComment;   LPTSTR lpProvider; } NETRESOURCE; 

Much useful information is contained in a NETRESOURCE structure. The DisplayStruct function near the top of Listing 3.7 displays most of this information. The Scope field tells the status of an enumeration.

  • RESOURCE_CONNECTED The device is already connected.

  • RESOURCE_GLOBALNET The enumeration is not connected.

  • RESOURCE_REMEMBERED There is a persistent connection to the device.

If connected or remembered, the enumeration must be a device, either a printer or a drive, and the LocalName field contains the local name of the device. An enumeration marked as USAGE_GLOBALNET gives more information about itself in the Usage field, which can have one of the following values:

  • RESOURCEUSAGE_CONNECTABLEThe enumeration is a connectable device.

  • RESOURCEUSAGE_CONTAINERThe enumeration is a container (a domain or a machine).

In either case, the RemoteName field contains the name used to connect to or open the enumeration. The Type field tells whether a connectable object is a disk or a printer.

  • RESOURCETYPE_ANY

  • RESOURCETYPE_DISK

  • RESOURCETYPE_PRINT

The DisplayType field tells how to display the object. This field is used in Windows' connection dialogs to determine the icon placed next to each item.

  • RESOURCEDISPLAYTYPE_DOMAIN

  • RESOURCEDISPLAYTYPE_GENERIC

  • RESOURCEDISPLAYTYPE_SERVER

  • RESOURCEDISPLAYTYPE_SHARE

The NETRESOURCE structure also contains the comment and the name of the provider.

Following the call to WNetEnumResources, Listing 3.7 loops through all the NETRESOURCE structures in the buffer. First it displays each record's contents. Then it inspects each record to decide whether or not it is a container. If it is a container, the EnumerateResources function recursively calls itself so that it can open and display the container. If it is not a container, it is a drive or a printer and a connection can be formed to it. Once the code has examined all the entries in the buffer, it cleans up and returns.

The first time that you call WNetEnumResources for any container it should return the error code NO_ERROR, as well as a buffer full of entries. However, there is no guarantee that the function was able to place all the entries for a given container into the buffer on the first call. Therefore, you should call it repeatedly until it returns ERROR_NO_MORE_ITEMS. This is the reason for the do . . . while loop in the code.

If something goes wrong, the ErrorHandler function seen in Listing 3.7 handles any WNet error. In cases where the network provider reports an error, the ErrorHandler function calls the GetLastError function to obtain error information.


< BACK  NEXT >


Windows CE 3. 0 Application Programming
Windows CE 3.0: Application Programming (Prentice Hall Series on Microsoft Technologies)
ISBN: 0130255920
EAN: 2147483647
Year: 2002
Pages: 181

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net