April 20, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Mastering Windows Networking (WNet)

  • October 20, 2004
  • By Alex Gusev
  • Send Email »
  • More Articles »

A Bit of Theory

Windows CE, being a little brother of its desktop counterpart, now exposes most PC communications capabilities. In many cases, they are just a subset of desktop versions, but still may be quite useful. In this article, we will discuss Windows Networking API (WNet).

Mobile applications may access a remote host's file system and other resources via WNet. Your program can establish and terminate network connections, retrieve configuration information, and so forth. Similar to the desktop, WNet communicates to the outer world via CIFS—Common Internet File System redirector—a module, through which one computer can access another one. Network resources are named using Usiversal Naming Convention (UNC).

As noted above, Windows CE supports only some restricted subsets of WNet API. The main limitations are:

  • Microsoft Windows Network is the only network provider currently supported
  • No connections are restored during a warm boot. A persistent connection is stored in the Registry and then may be enumerated and retrieved by calling the WNetOpenEnum function with the dwScope parameter set to RESOURCE_REMEMBERED
  • You can't use any drive letters to map network resources
  • No Mail slots or Named Pipes are supported
  • No LaN Manager functions are supported
  • Windows CE does not support the concept of a computer or device belonging to a specific network context
  • WNet API doesn't communicate over ActiveSync connection

WNet API is compact enough and may be easily overviewed. The following table briefly describes its functions.

Function Description
Enumeration Functions
WNetOpenEnum Starts an enumeration of network resources or existing connections
WNetEnumResource Continues a network enumeration started by WNetOpenEnum
WNetCloseEnum Ends a network enumeration started by WNetOpenEnum
Connection-related Functions
WNetAddConnection3 Makes a connection to a network resource and can specify a local name for the resource
WNetCancelConnection2 Terminates an existing network connection
WNetConnectionDialog1 Displays a general browsing dialog box for connecting to a network
WNetDisconnectDialog Displays a dialog box listing all currently connected resources and permits the user to select which resources to disconnect
WNetDisconnectDialog1 Attempts to disconnect from a network; notifies the user of any errors
Network Information Functions
WNetGetConnection Retrieves the remote name of a network resource associated with a local name
WNetGetUniversalName Maps a local path for a network resource to a data structure containing the UNC-based name
WNetGetUser Retrieves user name used to establish a network connection

Keeping all this stuff in mind, you nevertheless can use WNet pretty effectively for different data transmission tasks. The basic idea here is that, once you know network resource name, you can treat this resource in terms of standard file I/O. The next sections will illustrate some common scenarios your applications may need to implement.

Foreword for MFC Applications

The recent implementation of MFC for Windows CE does not allow using WNet in MFC-based applications. This is a strange fact, but that's how it is. To work around this issue, add the following lines to stdafx.h:

#undef _WINNETWK_
#include <winnetwk.h>

The origin of all this stuff comes from wce.h header files under the MFC Include folder, where you can find that many API are stored even though there are appropriate headers in the SDK folder. But all in all, WNet is easy to revive by such a simple trick.

Enumerating Domain Resources

The first sample we will discuss produces the list of domain network resources. It recursively surfs through domain entries and puts them into the listbox for simplicity. The basic points of this process are listed below:

  • Call WNetOpenEnum to open the enumeration
  • Sequentually call WNetEnumResource until it returns ERROR_NO_MORE_ITEMS
  • On each successful call of WNetEnumResource process, receive NETRESOURCE data
  • If the current node is of the RESOURCEUSAGE_CONTAINER type, you can use it as a starting point for nested enumeration
  • Close the enumeration handle by using a WNetCloseEnum call

So, please take a look at the following code snippet:

BOOL EnumerateDomainResources(LPNETRESOURCE lpnrStartFrom,
                              CListBox& ListBox)
{
   DWORD dwResult, dwResultEnum, i;
   LPNETRESOURCE lpNRBuffer;
   DWORD dwBufferSize = 16384;
   DWORD dwNumEntries = (DWORD)-1;
   HANDLE hEnum;
   CString sErr;

   dwResult = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY,
                           0, lpnrStartFrom, &hEnum);
   if(dwResult != NO_ERROR)
   {
      sErr.Format(L"WNetOpenEnum err = %d",dwResult);
      AfxMessageBox(sErr);
      return FALSE;
   }

   // allocate a buffer
   lpNRBuffer = (LPNETRESOURCE) new BYTE[dwBufferSize];

   // loop through all the stuff
   do
   {
      dwBufferSize = 16384;
      dwNumEntries = (DWORD)-1;
      // Get resources
      dwResultEnum = WNetEnumResource(hEnum, &dwNumEntries,
                                      lpNRBuffer, &dwBufferSize);
      if(dwResultEnum == NO_ERROR)
      {
         // loop through each of the entries
         for(i = 0; i < dwNumEntries; i++)
         {
            sErr.Format(L"%s",lpNRBuffer[i].lpRemoteName);
            ListBox.AddString(sErr);
            if( (lpNRBuffer[i].dwUsage & RESOURCEUSAGE_CONTAINER)
               == RESOURCEUSAGE_CONTAINER )
            {
               if( !EnumerateDomainResources(&lpNRBuffer[i],
                   ListBox) )
               {
                  AfxMessageBox(L"Enumeration Failed");
                  continue;
               }
            }
         }
      }
      else if(dwResultEnum != ERROR_NO_MORE_ITEMS)
      {
         sErr.Format(L"WNetEnumResource err = %d",dwResultEnum);
         AfxMessageBox(sErr);
         break;
      }
   }
   while(dwResultEnum != ERROR_NO_MORE_ITEMS);

   delete lpNRBuffer;

   dwResult = WNetCloseEnum(hEnum);
   if(dwResult != NO_ERROR)
   {
      sErr.Format(L"WNetCloseEnum err = %d",dwResult);
      AfxMessageBox(sErr);
      return FALSE;
   }

   return TRUE;
}

Let's briefly overview this sample. As we have said before, a call to WNetOpenEnum opens a new enumeration. The first parameter, dwScope, controls what should be enumerated. The sample uses a RESOURCE_GLOBALNET value to get all resources on the network. RESOURCE_CONNECTED and RESOURCE_REMEMBERED will give us active connections and previously stored resources respectively. After enumeration has been initiated, the application sequentually calls WNetEnumResource to achieve the next resource data. You are free to do all required processing of this data depending on resource type and usage. The code snippet takes the simplest way—proceeds nested enumerations. This loop ends up when WNetEnumResource returns ERROR_NO_MORE_ITEMS. And finally, WNetCloseEnum releases the enumeration handle.





Page 1 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel