Click here to Skip to main content
15,885,216 members
Articles / Mobile Apps / Windows Mobile

Managed Wrapper to Connection Manager and How to Bypass the Connection Planner

Rate me:
Please Sign up or sign in to vote.
4.33/5 (11 votes)
24 Sep 2008Public Domain4 min read 69.1K   1.5K   37  
This article explains how we can bypass the Connection Planner and establish a connection using the Connection Manager APIs on Windows Mobile devices.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

using Microsoft.Practices.Mobile.ConnectionMonitor.Implementations;
namespace CMConsole
{
    public partial class ConnectionList : Form
    {
        #region "Native Connection Manager APIs"
        [DllImport("CellCore.dll")]
        static extern int ConnMgrMapURL(string url, ref Guid networkGuid, int passZero);
        [DllImport("CellCore.dll")]
        static extern int ConnMgrEstablishConnection(ConnMgrConnectionInfo connectionInfo, ref IntPtr connectionHandle);
        [DllImport("CellCore.dll")]
        static extern int ConnMgrEstablishConnectionSync(ConnMgrConnectionInfo connectionInfo, ref IntPtr connectionHandle, uint dwTimeout, ref ConnMgrStatus dwStatus);
        [DllImport("CellCore.dll")]
        static extern int ConnMgrReleaseConnection(IntPtr connectionHandle, int cache);
        [DllImport("CellCore.dll")]
        static extern int ConnMgrConnectionStatus(IntPtr connectionHandle, ref ConnMgrStatus status);

        [DllImport("CellCore.dll")]
        static extern int ConnMgrMapConRef(ConnMgrConRefTypeEnum e, string szConRef, ref Guid pGUID);

        //[DllImport("CellCore.dll")]
        //static extern int ConnMgrEnumDestinations(int Index,ref CONNMGR_DESTINATION_INFO pDestInfo);  

        // [DllImport("CellCore.dll")]
        // static extern int ConnMgrQueryDetailedStatus(ref CONNMGR_CONNECTION_DETAILED_STATUS pStatusBuffer, ref Int32 pcbBufferSize);

        #endregion

        #region "Constants & Structures"
        [Flags]
        enum ConnMgrParam : int
        {
            GuidDestNet = 0x1,
            MaxCost = 0x2,
            MinRcvBw = 0x4,
            MaxConnLatency = 0x8
        }

        [Flags]
        enum ConnMgrProxy : int
        {
            NoProxy = 0x0,
            Http = 0x1,
            Wap = 0x2,
            Socks4 = 0x4,
            Socks5 = 0x8
        }

        enum ConnMgrPriority
        {
            UserInteractive = 0x8000,
            HighPriorityBackground = 0x0200,
            LowPriorityBackground = 0x0008
        }

        enum ConnMgrStatus
        {
            Unknown = 0x00,
            Connected = 0x10,
            Suspended = 0x11,
            Disconnected = 0x20,
            ConnectionFailed = 0x21,
            ConnectionCanceled = 0x22,
            ConnectionDisabled = 0x23,
            NoPathToDestination = 0x24,
            WaitingForPath = 0x25,
            WaitingForPhone = 0x26,
            PhoneOff = 0x27,
            ExclusiveConflict = 0x28,
            NoResources = 0x29,
            ConnectionLinkFailed = 0x2a,
            AuthenticationFailed = 0x2b,
            NoPathWithProperty = 0x2c,
            WaitingConnection = 0x40,
            WaitingForResource = 0x41,
            WaitingForNetwork = 0x42,
            WaitingDisconnection = 0x80,
            WaitingConnectionAbort = 0x81
        }

        enum ConnMgrConRefTypeEnum
        {
            ConRefType_NAP = 0,
            ConRefType_PROXY
        }


        [StructLayout(LayoutKind.Sequential)]
        class ConnMgrConnectionInfo
        {
            Int32 cbSize;                          // DWORD
            public ConnMgrParam dwParams = 0;      // DWORD
            public ConnMgrProxy dwFlags = 0;       // DWORD
            public ConnMgrPriority dwPriority = 0; // DWORD
            public Int32 bExclusive = 0;           // BOOL
            public Int32 bDisabled = 0;            // BOOL
            public Guid guidDestNet = Guid.Empty;  // GUID
            public IntPtr hWnd = IntPtr.Zero;      // HWND
            public UInt32 uMsg = 0;                // UINT
            public Int32 lParam = 0;               // LPARAM
            public UInt32 ulMaxCost = 0;           // ULONG
            public UInt32 ulMinRcvBw = 0;          // ULONG
            public UInt32 ulMaxConnLatency = 0;    // ULONG 

            public ConnMgrConnectionInfo()
            {
                cbSize = Marshal.SizeOf(typeof(ConnMgrConnectionInfo));
            }

            public ConnMgrConnectionInfo(Guid destination, ConnMgrPriority priority, ConnMgrProxy proxy)
                : this()
            {
                guidDestNet = destination;
                dwParams = ConnMgrParam.GuidDestNet;
                dwPriority = priority;
                dwFlags = proxy;
            }

            public ConnMgrConnectionInfo(Guid destination, ConnMgrPriority priority)
                : this(destination, priority, ConnMgrProxy.NoProxy) { }

            public ConnMgrConnectionInfo(Guid destination)
                : this(destination, ConnMgrPriority.UserInteractive) { }
        } ;

        /*
        const int CONNMGR_MAX_DESC = 128;
        [StructLayout(LayoutKind.Sequential)]
        class CONNMGR_DESTINATION_INFO
        {
          public Guid guid;
          public char[] szDescription = (char [])Marshal.AllocHGlobal(CONNMGR_MAX_DESC * sizeof(char)); //new char[CONNMGR_MAX_DESC];
          public bool fSecure;
           ~CONNMGR_DESTINATION_INFO()
          {
              Marshal.FreeHGlobal((IntPtr)szDescription);
          }
        };

        [StructLayout(LayoutKind.Sequential)]
        class CONNMGR_CONNECTION_DETAILED_STATUS{
            
              public CONNMGR_CONNECTION_DETAILED_STATUS pNext;
              public Int32 dwVer;                               //DWORD
              public Int32 dwParams;                            //DWORD
              public Int32 dwType;                              //DWORD
              public Int32 dwSubtype;                           //DWORD
              public Int32 dwFlags;                             //DWORD
              public Int32 dwSecure;                            //DWORD
              public Guid  guidDestNet;                         //GUID
              public Guid  guidSourceNet;                       //GUID 
              public string szDescription;                      //TCHAR*
              public string szAdapterName;                      //TCHAR*
              public Int32 dwConnectionStatus;                  //DWORD
              public SYSTEMTIME LastConnectTime;
              public Int32 dwSignalQuality; 
              public CONNMGR_CONNECTION_IPADDR pIPAddr;
        };
        [StructLayout(LayoutKind.Sequential)]
        struct SYSTEMTIME {
              Int16 wYear;                                       //WORD
              Int16 wMonth;                                     //WORD
              Int16 wDayOfWeek;                                 //WORD
              Int16 wDay;                                       //WORD
              Int16 wHour;                                      //WORD
              Int16 wMinute;                                    //WORD
              Int16 wSecond;                                    //WORD
              Int16 wMilliseconds;                              //WORD
        };


        const int _SS_MAXSIZE = 128;                  // Maximum size.
        const int _SS_ALIGNSIZE = (sizeof(Int64));  // Desired alignment.

        
        //Definitions used for sockaddr_storage structure paddings design.
         

        const int _SS_PAD1SIZE = (_SS_ALIGNSIZE - sizeof (short));
        const int _SS_PAD2SIZE = (_SS_MAXSIZE - (sizeof (short) + _SS_PAD1SIZE + _SS_ALIGNSIZE));
        [StructLayout(LayoutKind.Sequential)]
        class CONNMGR_CONNECTION_IPADDR{
          Int32 cIPAddr;
          SOCKADDR_STORAGE[] IPAddr = Marshal.AllocHGlobal(sizeof(SOCKADDR_STORAGE));//new SOCKADDR_STORAGE[1];
            ~CONNMGR_CONNECTION_IPADDR()
            {
                Marshal.FreeHGlobal(IPAddr);
            }
        };

        [StructLayout(LayoutKind.Sequential)]
        class SOCKADDR_STORAGE {
          public short ss_family;
          public char[] __ss_pad1 = Marshal.AllocHGlobal(_SS_PAD1SIZE * sizeof(char));//new char[_SS_PAD1SIZE];
          public Int64 __ss_align;
          public char[] __ss_pad2 = Marshal.AllocHGlobal(_SS_PAD2SIZE * sizeof(char));//new char[_SS_PAD2SIZE];
            ~SOCKADDR_STORAGE()
            {
                Marshal.FreeHGlobal(__ss_pad1);
                Marshal.FreeHGlobal(__ss_pad2); 
            }
        };*/

        #endregion

        List<ConnectionMonitorNativeHelper.CONNMONITOR_CONNECTION_DETAILED_STATUS> cnList;

        public ConnectionList()
        {
            InitializeComponent();
        }
        public ConnectionList(List<ConnectionMonitorNativeHelper.CONNMONITOR_CONNECTION_DETAILED_STATUS> lcnList)
        {
            cnList = lcnList;
            InitializeComponent();
            for (int i = 0; i < cnList.Count; i++)
                if (cnList[i].pszDescription != null)
                    lstConnection.Items.Add(cnList[i].pszDescription);
        }

        IntPtr _connectionHandle = IntPtr.Zero; // Class-level field
        const int _syncConnectTimeout = 60000; // 60 seconds

        private void mnuConnect_Click(object sender, EventArgs e)
        {
            const int CONNMONITOR_STATUS_CONNECTED = 0x10;
            ConnectionMonitorNativeHelper.CONNMONITOR_CONNECTION_DETAILED_STATUS cnStatus = cnList[lstConnection.SelectedIndex];
            if (_connectionHandle != IntPtr.Zero)
            {
                ConnMgrReleaseConnection(_connectionHandle, 0);
                _connectionHandle = IntPtr.Zero;
            }
            if (cnStatus.dwConnectionStatus != CONNMONITOR_STATUS_CONNECTED)
            {
                ConnMgrStatus status = ConnMgrStatus.Unknown;
                Guid forceConnGuid = new Guid();
                if (ConnMgrMapConRef(ConnMgrConRefTypeEnum.ConRefType_NAP, cnStatus.pszDescription, ref forceConnGuid) != 0)
                {
                    ConnMgrMapConRef(ConnMgrConRefTypeEnum.ConRefType_PROXY, cnStatus.pszDescription, ref forceConnGuid);
                }

                ConnMgrConnectionInfo info = new ConnMgrConnectionInfo(forceConnGuid, ConnMgrPriority.HighPriorityBackground);
                ConnMgrEstablishConnectionSync(info, ref _connectionHandle, _syncConnectTimeout, ref status);

                if (status == ConnMgrStatus.Connected)
                    MessageBox.Show("Connect Succeeded");
                else
                    MessageBox.Show("Connect failed: " + status.ToString());
                
            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication


Written By
Architect Tata Consultancy Services
India India
Naynesh Shah is a senior solution architect working with the Mobile Solutions - Technology Excellency Group of TATA Consultancy Services.

He specializes in architecting enterprise and embedded mobile solutions based on Windows CE and Windows Mobile. He is also involved in helping customers define the mobile middleware adoption strategy.

Comments and Discussions