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());
}
}
}
}