⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 connectionmonitornativehelper.cs

📁 Microsoft Mobile Development Handbook的代码,有C#,VB,C++的
💻 CS
字号:
//===============================================================================
// Microsoft patterns & practices
// Mobile Client Software Factory - July 2006
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Practices.Mobile.ConnectionMonitor.Properties;
using System.Globalization;

namespace Microsoft.Practices.Mobile.ConnectionMonitor.Implementations
{
    /// <summary>
    ///		This class is a native API wrapper for two native APIs:
    ///					- ConnMgrEnumDestinations
    ///					- ConnMgrQueryDetailedStatus
    /// 	These APIs are part of the Windows Mobile 5.0 Connection Manager functions.
    ///		This class uses this native functions to get the network list (exposed as
    ///		<see cref="GetNetworkList"/>) and to get the current connection and 
    ///		network (exposed as <see cref="GetCurrentConnectionType"/>).
    /// </summary>
    public static class ConnectionMonitorNativeHelper
    {
        //
        // API Constants
        //
        enum UnmanagedConnectionType : uint
        {
            CM_CONNTYPE_UNKNOWN = 0,
            CM_CONNTYPE_CELLULAR = 1, //GPRS/EDGE/1x
            CM_CONNTYPE_NIC = 2, //Ethernet/WiFi
            CM_CONNTYPE_BLUETOOTH = 3,
            CM_CONNTYPE_UNIMODEM = 4,
            CM_CONNTYPE_VPN = 5,
            CM_CONNTYPE_PROXY = 6,
            CM_CONNTYPE_PC = 7  //DTPT
        }

        //
        // API Structures
        //
        class CONNMONITOR_DESTINATION_INFO
        {
            public System.Guid guid;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
            public String szDescription;

        }
        struct SYSTEMTIME
        {
            public Int16 wYear;
            public Int16 wMonth;
            public Int16 wDayOfWeek;
            public Int16 wDay;
            public Int16 wHour;
            public Int16 wMinute;
            public Int16 wSecond;
            public Int16 wMilliseconds;
        };
        class CONNMONITOR_CONNECTION_DETAILED_STATUS
        {
            public IntPtr pNext;
            public uint dwVer;
            public uint dwParams;
            public UnmanagedConnectionType dwType;
            public uint dwSubtype;
            public uint dwFlags;
            public uint dwSecure;
            public Guid guidDestNet;
            public Guid guidSourceNet;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string pszDescription;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string pszAdapterName;
            public uint dwConnectionStatus;
            public SYSTEMTIME lastConnectionTime;
            public uint dwSignalQuality;
			public uint pIPAddr; //Actually this is a void*
        }

        //
        // Imports
        //
        [DllImport("cellcore.dll", EntryPoint = "ConnMgrEnumDestinations", SetLastError = true)]
        internal static extern int ConnMgrEnumDestinations(int nIndex, IntPtr pDestinationInfo);

        [DllImport("cellcore.dll", EntryPoint = "ConnMgrQueryDetailedStatus", SetLastError = true)]
        internal static extern int ConnMgrQueryDetailedStatus(IntPtr pStatusBuffer, ref uint pcBufferSize);

		[DllImport("ws2.dll", EntryPoint = "WSAAddressToString", SetLastError = true)]
		internal static extern int WSAAddressToString(uint lpsaAddress, uint dwAddressLength, IntPtr lpProtocolInfo, StringBuilder lpszAddressString, ref uint lpdwAddressStringLength);

		// String helper
		static string NewLine = "\r\n";
        
		//
        // Managed API
        //

        /// <summary>
        ///		Get the current connection type and network.
        /// </summary>
        /// <param name="type">
        ///		Out parameter to get the current connection type.
        /// </param>
        /// <param name="currentNetworkName">
        ///		Out parameter to get the current network name.
        /// </param>
        static public string GetCurrentNetworkNameForConnection(NativeConnectionType type)
        {
            //API Constants
            const int CONNMONITOR_STATUS_CONNECTED = 0x10;

            //1. Initialize out parameters
			//type = CurrentConnectionType.Disconnected;
            string currentNetworkName = string.Empty;

            //2. Get info from unmanaged API

            CONNMONITOR_CONNECTION_DETAILED_STATUS inStatus = new CONNMONITOR_CONNECTION_DETAILED_STATUS();
            uint bufferSize = 0;
            //This call is only to get the real buffer size needed
            int hResult = ConnMgrQueryDetailedStatus(IntPtr.Zero, ref bufferSize);
            //Now I can alloc the buffers
            IntPtr buffer = IntPtr.Zero;
            IntPtr destBuffer = IntPtr.Zero;

            try
            {
                buffer = Marshal.AllocCoTaskMem((int)bufferSize);
                destBuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(CONNMONITOR_DESTINATION_INFO)));

                hResult = ConnMgrQueryDetailedStatus(buffer, ref bufferSize);

				if (hResult != 0)
				{
					throw new ConnectionMonitorException(string.Format(CultureInfo.InvariantCulture, Resources.ExceptionDetailedStatusQueryFailed, hResult), hResult);
				}

                //3. Browse the linked list looking for the current connection
                for (IntPtr curItem = buffer; curItem != IntPtr.Zero; curItem = inStatus.pNext)
                {
                    Marshal.PtrToStructure(curItem, inStatus);
                    //If this is the current connection ... and it's not a Proxy, VPN or Bluetooth information
                    if (inStatus.dwConnectionStatus == CONNMONITOR_STATUS_CONNECTED &&
						(  (type == NativeConnectionType.Cell && inStatus.dwType == UnmanagedConnectionType.CM_CONNTYPE_CELLULAR) ||
						   (type == NativeConnectionType.NIC && inStatus.dwType == UnmanagedConnectionType.CM_CONNTYPE_NIC) ||
						   (type == NativeConnectionType.PC && inStatus.dwType == UnmanagedConnectionType.CM_CONNTYPE_PC) ))
                    {
                        //3.2. Get the network name
                        CONNMONITOR_DESTINATION_INFO destInfo = new CONNMONITOR_DESTINATION_INFO();
                        int index = 0;
                        while (ConnMgrEnumDestinations(index++, destBuffer) >= 0)
                        {
                            Marshal.PtrToStructure(destBuffer, destInfo);
                            if (destInfo.guid == inStatus.guidDestNet)
                            {
                                currentNetworkName = destInfo.szDescription;
                                break;
                            }
                        }
                        break;
                    }
                }
            }
            finally
            {
                //Free alocated memory
                if (destBuffer != IntPtr.Zero) Marshal.FreeCoTaskMem(destBuffer);
                if (buffer != IntPtr.Zero) Marshal.FreeCoTaskMem(buffer);
            }

			return currentNetworkName;
        }

        /// <summary>
        /// Get the destination networks list.
        /// </summary>
        /// <returns>
        ///		A list of strings with the network names.
        /// </returns>
        static public List<string> GetNetworkList()
        {
            List<string> networks = new List<string>();

            CONNMONITOR_DESTINATION_INFO destInfo = new CONNMONITOR_DESTINATION_INFO();
            IntPtr destBuffer = IntPtr.Zero;
			try
			{
				//Memory allocation
				destBuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(CONNMONITOR_DESTINATION_INFO)));
				int index = 0;
				while (ConnMgrEnumDestinations(index++, destBuffer) >= 0)
				{
					Marshal.PtrToStructure(destBuffer, destInfo);
					networks.Add(destInfo.szDescription);
				}
			}
            finally
            {
                //Always free allocated memory
                if (destBuffer != IntPtr.Zero) Marshal.FreeCoTaskMem(destBuffer);
            }
            return networks;
        }

        /// <summary>
        ///		Gets an string with detailed information about the status of the given
		///		native connection type.
        /// </summary>
        /// <param name="type">NativeConnectionType to get the detailed status information string.</param>
        /// <returns>
		///		String with detailed connection status information.
		/// </returns>
        static public string GetConnectionDetailedStatusText(NativeConnectionType type)
        {
            StringBuilder result = new StringBuilder();
			result.Append(type.ToString()).Append(NewLine);
            result.Append(Resources.DetailedInfoTitle).Append(NewLine);
			result.Append(Resources.DetailedInfoTitle2).Append(NewLine);

            //Get info from unmanaged API

            CONNMONITOR_CONNECTION_DETAILED_STATUS inStatus = new CONNMONITOR_CONNECTION_DETAILED_STATUS();
            uint bufferSize = 0;
            //This call is only to get the real buffer size needed
            int hResult = ConnMgrQueryDetailedStatus(IntPtr.Zero, ref bufferSize);
            //Now I can alloc the buffers
            IntPtr buffer = IntPtr.Zero;
            IntPtr destBuffer = IntPtr.Zero;

            try
            {
                buffer = Marshal.AllocCoTaskMem((int)bufferSize);
                destBuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(CONNMONITOR_DESTINATION_INFO)));

                hResult = ConnMgrQueryDetailedStatus(buffer, ref bufferSize);

				if (hResult != 0)
				{
					throw new ConnectionMonitorException(string.Format(Resources.ExceptionDetailedStatusQueryFailed, hResult), hResult);
				}

                //3. Browse the linked list
                for (IntPtr curItem = buffer; curItem != IntPtr.Zero; curItem = inStatus.pNext)
                {
                    Marshal.PtrToStructure(curItem, inStatus);
                    //If this is the current connection ... and it's not a Proxy, VPN or Bluetooth information
                    if (  (type == NativeConnectionType.Cell && 
                            inStatus.dwType == UnmanagedConnectionType.CM_CONNTYPE_CELLULAR) ||
                            (type == NativeConnectionType.NIC &&
                            inStatus.dwType == UnmanagedConnectionType.CM_CONNTYPE_NIC) ||
                            (type == NativeConnectionType.PC &&
                            inStatus.dwType == UnmanagedConnectionType.CM_CONNTYPE_PC)
                            )
                    {
                        //Build the string
                        result.Append("[").Append(inStatus.pszDescription).Append("]\r\n");
						result.Append(string.Format(Resources.DetailedStatusSubtype, inStatus.dwSubtype.ToString())).Append(NewLine);
						result.Append(string.Format(Resources.DetailedStatusFlags, inStatus.dwFlags.ToString())).Append(NewLine);
						result.Append(string.Format(Resources.DetailedStatusSecure, inStatus.dwSecure.ToString())).Append(NewLine);
						result.Append(string.Format(Resources.DetailedStatusGuidDestNet, inStatus.guidDestNet.ToString())).Append(NewLine);
						result.Append(string.Format(Resources.DetailedStatusGuidSourceNet, inStatus.guidSourceNet.ToString())).Append(NewLine);
						result.Append(string.Format(Resources.DetailedStatusAdapterName, inStatus.pszAdapterName)).Append(NewLine);
						result.Append(string.Format(Resources.DetailedStatusConnectionStatus, inStatus.dwConnectionStatus.ToString())).Append(NewLine);
                        result.Append(string.Format(Resources.DetailedStatusLastConnectionTime,
                                        inStatus.lastConnectionTime.wDay.ToString(),
                                        inStatus.lastConnectionTime.wMonth.ToString(),
                                        inStatus.lastConnectionTime.wYear.ToString(),
                                        inStatus.lastConnectionTime.wHour.ToString(),
                                        inStatus.lastConnectionTime.wMinute.ToString(),
										inStatus.lastConnectionTime.wSecond.ToString())).Append(NewLine);
						result.Append(string.Format(Resources.DetailedStatusSignalQuality, inStatus.dwSignalQuality.ToString(CultureInfo.InvariantCulture))).Append(NewLine);
						result.Append(string.Format(Resources.DetailedStatusIPAddressInfo, GetStringFromIPInfo(inStatus.pIPAddr))).Append(NewLine);

                        //3.2. Get the network name
                        CONNMONITOR_DESTINATION_INFO destInfo = new CONNMONITOR_DESTINATION_INFO();
                        int index = 0;
                        while (ConnMgrEnumDestinations(index++, destBuffer) >= 0)
                        {
                            Marshal.PtrToStructure(destBuffer, destInfo);
                            if (destInfo.guid == inStatus.guidDestNet)
                            {
								result.Append(Resources.DestNetworkName).Append(destInfo.szDescription).Append(NewLine);
                                break;
                            }
                        }
                        result.Append(Resources.LineSeparator);
                    }
                }
            }
            finally
            {
                //Free alocated memory
                if (destBuffer != IntPtr.Zero) Marshal.FreeCoTaskMem(destBuffer);
                if (buffer != IntPtr.Zero) Marshal.FreeCoTaskMem(buffer);
            }

            return result.ToString();
        }

		private static string GetStringFromIPInfo(uint intPtr)
		{
			if (intPtr == (uint)IntPtr.Zero) return string.Empty;
			if (intPtr == 0) return string.Empty;

			uint IPAddr = intPtr + 4; //first 4 bytes for count (always 1)
			StringBuilder ipAddressString = new StringBuilder(250);
			uint length = (uint)ipAddressString.Capacity;
			int hResult = WSAAddressToString(IPAddr, 128, IntPtr.Zero, ipAddressString, ref length);

			if (hResult != 0)
			{
				throw new ConnectionMonitorException(string.Format(CultureInfo.InvariantCulture, Resources.ExceptionGetStringFromIPFailed, hResult), hResult);
			}
			
			return ipAddressString.ToString();
		}
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -