Click here to Skip to main content
15,884,717 members
Articles / Programming Languages / C#

How to access wireless network parameters using native WiFi API

Rate me:
Please Sign up or sign in to vote.
4.70/5 (11 votes)
29 Dec 2009CPOL2 min read 178.5K   6.9K   57   26
Query wireless network parameters using native WiFi API.

Introduction

In my previous two articles, I have shown you how to access an NDIS miniport driver using the DeviceIOControl and the Windows Management Instrumentation (WMI) mechanisms. This article focuses more on the Native Wifi API. Native Wifi API is basically designed for C/C++ programmers. This API contains a lot of functions for wireless network connectivity and profile management.

Earlier, programmers would query OIDs using DeviceIOControl or WMI for accessing the various parameters of a wireless network. Microsoft makes this easy by introducing the native Wifi API. Now, we don't have to query miniport drivers directly. We can use Wifi APIs from our applications just like using Win32 APIs.

Background

Microsoft has come up with the Native Wifi API; a new API for managing wireless network connectivity and profiles. Client applications running Windows Vista or Windows XP SP2 can use this API. Microsoft has incorporated this API into Vista, by default.

Windows XP SP2 also supports a subset of the native Wifi API. But the user has to install an additional package/hotfix for getting this API support in a Windows XP ASP2 environment. You can check more about the wireless LAN API for Windows XP SP2 from the Microsoft website.

Using the code

In the example given below, we will see how to enumerate wireless adapters using the Wifi API. The Wifi API provides a lot of functions for querying various parameters of wireless networks.

C#
//
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            PlatformInvoke.wifi wifiAPI = new PlatformInvoke.wifi();
            wifiAPI.EnumerateNICs();
        }
    }
       
}
 
namespace PlatformInvoke
{
    /// <summary >
    /// This class encapsulates basic functions required
    /// for enumerating wireless adapaters in the system. This class consumes 
    /// wifi api developed and supported from Microsoft Vista onwards
    /// </summary >
    class wifi
    {
        //************************************************************
        #region declarations
 
        private const int WLAN_API_VERSION_2_0 = 2; //Windows Vista WiFi API Version
        private const int ERROR_SUCCESS = 0;
 
        /// <summary >
        /// Opens a connection to the server
        /// </summary >
        [DllImport("wlanapi.dll", SetLastError = true)]
        private static extern UInt32 WlanOpenHandle(UInt32 dwClientVersion, 
                IntPtr pReserved, out UInt32 pdwNegotiatedVersion, 
                out IntPtr phClientHandle);
 
        /// <summary >
        /// Closes a connection to the server
        /// </summary >
        [DllImport("wlanapi.dll", SetLastError = true)]
        private static extern UInt32 WlanCloseHandle(IntPtr hClientHandle, 
                                                     IntPtr pReserved);
 
        /// <summary >
        /// Enumerates all wireless interfaces in the laptop
        /// </summary >
        [DllImport("wlanapi.dll", SetLastError = true)]
        private static extern UInt32 WlanEnumInterfaces(IntPtr hClientHandle, 
                       IntPtr pReserved, out IntPtr ppInterfaceList);
 
        /// <summary >
        /// Frees memory returned by native WiFi functions
        /// </summary >
        [DllImport("wlanapi.dll", SetLastError = true)]
        private static extern void WlanFreeMemory(IntPtr pmemory);
 
        /// <summary >
        /// Interface state enums
        /// </summary >
        public enum WLAN_INTERFACE_STATE : int
        {
            wlan_interface_state_not_ready = 0,
            wlan_interface_state_connected,
            wlan_interface_state_ad_hoc_network_formed,
            wlan_interface_state_disconnecting,
            wlan_interface_state_disconnected,
            wlan_interface_state_associating,
            wlan_interface_state_discovering,
            wlan_interface_state_authenticating
        };
 
        /// <summary >
        /// Stores interface info
        /// </summary >
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct WLAN_INTERFACE_INFO
        {
            /// GUID->_GUID
            public Guid InterfaceGuid;
 
            /// WCHAR[256]
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
            public string strInterfaceDescription;
 
            /// WLAN_INTERFACE_STATE->_WLAN_INTERFACE_STATE
            public WLAN_INTERFACE_STATE isState;
        }
        /// <summary >
        /// This structure contains an array of NIC information
        /// </summary >
       [StructLayout(LayoutKind.Sequential)]
        public struct WLAN_INTERFACE_INFO_LIST
        {
            public Int32 dwNumberofItems;
            public Int32 dwIndex;
            public WLAN_INTERFACE_INFO[] InterfaceInfo;
 
            public WLAN_INTERFACE_INFO_LIST(IntPtr pList)
            {
                // The first 4 bytes are the number of WLAN_INTERFACE_INFO structures.
                dwNumberofItems = Marshal.ReadInt32(pList, 0);
 
                // The next 4 bytes are the index of the current item in the unmanaged API.
                dwIndex = Marshal.ReadInt32(pList, 4);
 
                // Construct the array of WLAN_INTERFACE_INFO structures.
                InterfaceInfo = new WLAN_INTERFACE_INFO[dwNumberofItems];
 
                for (int i = 0; i < dwNumberofItems; i++)
                {
                    // The offset of the array of structures is 8 bytes past the beginning.
                    // Then, take the index and multiply it by the number of bytes in the
                    // structure.
                    // the length of the WLAN_INTERFACE_INFO structure is 532 bytes - this
                    // was determined by doing a sizeof(WLAN_INTERFACE_INFO) in an
                    // unmanaged C++ app.
                    IntPtr pItemList = new IntPtr(pList.ToInt32() + (i * 532) + 8);
 
                    // Construct the WLAN_INTERFACE_INFO structure, marshal the unmanaged
                    // structure into it, then copy it to the array of structures.
                    WLAN_INTERFACE_INFO wii = new WLAN_INTERFACE_INFO();
                    wii = (WLAN_INTERFACE_INFO)Marshal.PtrToStructure(pItemList,
                        typeof(WLAN_INTERFACE_INFO));
                    InterfaceInfo[i] = wii;
                }
            }
        }
 
        #endregion
 
        //************************************************************
        #region Private Functions
        /// <summary >
        ///get NIC state  
        /// </summary >
        private string getStateDescription(WLAN_INTERFACE_STATE state)
        {
            string stateDescription=string.Empty;
            switch (state)
            {
                case WLAN_INTERFACE_STATE.wlan_interface_state_not_ready:
                    stateDescription = "not ready to operate";
                    break;
                case WLAN_INTERFACE_STATE.wlan_interface_state_connected:
                    stateDescription = "connected";
                    break;
                case WLAN_INTERFACE_STATE.wlan_interface_state_ad_hoc_network_formed:
                    stateDescription = "first node in an adhoc network";
                    break;
                case WLAN_INTERFACE_STATE.wlan_interface_state_disconnecting:
                    stateDescription = "disconnecting";
                    break;
                case WLAN_INTERFACE_STATE.wlan_interface_state_disconnected:
                    stateDescription = "disconnected";
                    break;
                case WLAN_INTERFACE_STATE.wlan_interface_state_associating:
                    stateDescription = "associating";
                    break;
                case WLAN_INTERFACE_STATE.wlan_interface_state_discovering:
                    stateDescription = "discovering";
                    break;
                case WLAN_INTERFACE_STATE.wlan_interface_state_authenticating:
                    stateDescription = "authenticating";
                    break;
            }
 
            return stateDescription;
        }
        #endregion
 
        //************************************************************
        #region Public Functions
 
        /// <summary >
        /// enumerate wireless network adapters using wifi api
        /// </summary >
        public void EnumerateNICs()
        {
            uint serviceVersion = 0;
            IntPtr handle = IntPtr.Zero;
            if(WlanOpenHandle(WLAN_API_VERSION_2_0, IntPtr.Zero, 
                out serviceVersion, out handle) == ERROR_SUCCESS)
            {
                IntPtr ppInterfaceList = IntPtr.Zero;
                WLAN_INTERFACE_INFO_LIST interfaceList;
 
                if (WlanEnumInterfaces(handle, IntPtr.Zero, 
                              out ppInterfaceList) == ERROR_SUCCESS)
                {
                    //Tranfer all values from IntPtr to WLAN_INTERFACE_INFO_LIST structure 
                    interfaceList = new WLAN_INTERFACE_INFO_LIST(ppInterfaceList);
 
                    Console.WriteLine("Enumerating Wireless Network Adapters...");
                    for (int i = 0; i < interfaceList.dwNumberofItems; i++)
                        Console.WriteLine("{0}-->{1}", 
                          interfaceList.InterfaceInfo[i].strInterfaceDescription,
                          getStateDescription(interfaceList.InterfaceInfo[i].isState));
 
                    //frees memory
                    if (ppInterfaceList != IntPtr.Zero)
                        WlanFreeMemory(ppInterfaceList);
                }
                //close handle
                WlanCloseHandle(handle, IntPtr.Zero);
            }
        }
        #endregion
    }
}

The above code is written in C# using the Platform Invoke mechanism, and it shows each wirless adapter name and its state.

Conclusion

This article demonstrates how to access the Wifi API from a C# .NET application. The Wifi API exposes a lot of functionality and you can explore each one of them.

References

  1. http://www.codeproject.com/KB/system/DeviceIOControl1.aspx
  2. http://www.codeproject.com/KB/system/WMIInterface.aspx

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionHID over WiFi Pin
Mehrdad_K20-Aug-18 21:28
professionalMehrdad_K20-Aug-18 21:28 
QuestionWiFI On/Off API Pin
Member 112936057-Dec-14 19:28
Member 112936057-Dec-14 19:28 
Questioncan you contact me please ? (some project proposal) Pin
Member 1064640519-Aug-14 10:57
Member 1064640519-Aug-14 10:57 
QuestionMay i know your contact details Pin
pokirimca17-Apr-14 17:33
pokirimca17-Apr-14 17:33 
QuestionBest way of querying/setting NDIS miniport OIDs Pin
Ashish Kumar21-Feb-14 14:50
Ashish Kumar21-Feb-14 14:50 
QuestionAutomatically connect ? Pin
Mazen el Senih3-Sep-12 9:36
professionalMazen el Senih3-Sep-12 9:36 
GeneralMy vote of 3 Pin
wangyanke52030-Jul-12 2:25
wangyanke52030-Jul-12 2:25 
QuestionGreat article and code! Pin
User 198493312-Apr-12 6:48
User 198493312-Apr-12 6:48 
QuestionWifi with java Pin
Member 805479114-Mar-12 1:15
Member 805479114-Mar-12 1:15 
QuestionDoes not work on Windows 7 Pin
AnupMistry9-Nov-11 11:30
AnupMistry9-Nov-11 11:30 
AnswerRe: Does not work on Windows 7 Pin
wtl2224-Dec-11 21:34
wtl2224-Dec-11 21:34 
Questioncan we use native WiFi API to measure the bytes downloaded or uploaded? Pin
RAJEEV_RSD6-Oct-11 15:03
RAJEEV_RSD6-Oct-11 15:03 
Generalreading packet header Pin
newsawal9-May-10 5:19
newsawal9-May-10 5:19 
Generalwlanapi.dll not found Pin
Bilal A. D. 21-Mar-10 22:05
Bilal A. D. 21-Mar-10 22:05 
GeneralRe: wlanapi.dll not found Pin
Maju M8-Apr-10 4:54
Maju M8-Apr-10 4:54 
QuestionUsing Native Wifi API Pin
galileog3-Mar-10 22:26
galileog3-Mar-10 22:26 
QuestionHow about Wifi API for Windows XP Pin
ChiSmile12-Dec-09 0:41
ChiSmile12-Dec-09 0:41 
AnswerRe: How about Wifi API for Windows XP Pin
Maju M27-Dec-09 19:32
Maju M27-Dec-09 19:32 
GeneralNice tutorial Pin
sesar30-Aug-09 14:29
sesar30-Aug-09 14:29 
GeneralRe: Nice tutorial Pin
Maju M7-Sep-09 21:06
Maju M7-Sep-09 21:06 
You need to connect/associate your wifi adapter to a network.


Use WlanQueryInterface() with opcode as wlan_intf_opcode_current_connection. This returns current connection attributes which includes ssid,signal quality etc.
GeneralRe: Nice tutorial Pin
seensesippy16-Nov-09 3:23
seensesippy16-Nov-09 3:23 
GeneralRe: Nice tutorial Pin
Maju M28-Dec-09 18:09
Maju M28-Dec-09 18:09 
GeneralThanks for your information Pin
ajay_coepit17-Apr-09 12:27
ajay_coepit17-Apr-09 12:27 
GeneralRe: Thanks for your information Pin
Maju M19-Apr-09 19:19
Maju M19-Apr-09 19:19 
QuestionRe: Thanks for your information Pin
seensesippy9-Nov-09 7:02
seensesippy9-Nov-09 7:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.