Tuesday, December 07, 2004

A question has recently popped up on CF newsgroups on how to connect to a network resource programmatically. There's no managed API's exist to handle that, but as always native API's and P/Invoke comes to our rescue. On a desktop as well as in Windows CE this functionality's been handled by a network API's such as WNetAddConnection3, WNetCancelConnection2 etc... The documentation on them is pretty straightforward.

[DllImport("coredll")]

private static extern int WNetAddConnection3(

                  IntPtr hwndOwner,

                  NETRESOURCE lpNetResource,

                  string lpPassword,

                  string lpUserName,

                  int dwFlags);

 

[DllImport("coredll")]

private static extern int WNetCancelConnection2(

                  string lpName,

                  int dwFlags,

                  int fForce);

The WNetAddConnection3 accepts as a parameter the pointer to the NETRESOURCE structure so I declared it as the following:

private class NETRESOURCE

{

      public int dwScope;

      public int dwType;

      public int dwDisplayType;

      public int dwUsage;

      public IntPtr lpLocalName;

      public IntPtr lpRemoteName;

      public IntPtr lpComment;

      public IntPtr lpProvider;

}

In order to assign the values to lpLocalName and lpRemoteName members we'll use the MarshalEx.StringToHGlobalUni call from SDF. So, the call to WNetAddConnection3 looks like that:

NETRESOURCE NetRes = new NETRESOURCE();              

      NetRes.dwScope = RESOURCE_GLOBALNET | RESOURCE_REMEMBERED;

      NetRes.dwType = RESOURCETYPE_DISK;

      NetRes.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;

      NetRes.dwUsage = RESOURCEUSAGE_CONNECTABLE;

      NetRes.lpRemoteName = MarshalEx.StringToHGlobalUni(netRes);

      NetRes.lpLocalName = MarshalEx.StringToHGlobalUni(shareName);

      NetRes.lpComment = IntPtr.Zero;

      NetRes.lpProvider = IntPtr.Zero;

                       

      int ret = WNetAddConnection3(hwnd, NetRes, password, userName, 1);

 

      if (ret != 0)

      {

            throw new System.ComponentModel.Win32Exception(ret, ((NetworkErrors)ret).ToString());

      }                      

 After you've made successfull mapping you should be able to access your network resource by using System.IO's functionality like File.Copy, File.Create, File.Delete etc... Keep in mind that since Windows CE does not support drive letters, your share name will be mapped to the reserved root \Network. So if you named your share as “REMOTE“, you'll access it as “\Network\REMOTE\somefile.txt”.

You can download the source code for the Network class and a sample here.

MapDriveProject.zip (7.34 KB)
12/7/2004 3:25:23 PM (GMT Standard Time, UTC+00:00)  #     |