Click here to Skip to main content
12,299,086 members (52,518 online)
Click here to Skip to main content
Add your own
alternative version


58 bookmarked

WLAN Scan with NDIS Miniport and Much More

, 29 Oct 2007
Rate this:
Please Sign up or sign in to vote.
An article about using NDIS Miniport from userspace to access several functions of the WLANcard
Screenshot - screen.jpg


I spent some time with WLAN, and I wondered how NetStumbler performed this nice scan, but the source is not free. I programmed a lot of stuff but nothing worked. I tried to code my own driver and used WinPcap, but nothing worked very well. Then I read an article, "Scanning for Wireless Networks" in 29A magazine 8 from GriYo. My work is mainly based on this article and you can find a lot of sources on the internet that do the same thing.


It's possible via NDIS Miniport (from userspace) to access a lot of functions of the WLANcard. To get access to all these nice functions you need the Windows DDK.

Take a look at ntddndis.h and you will find a lot of actions you can perform. For example, you can get or set the WEP key. I only implemeted the scanning function, but you can improve it. To build your own application, you can take my article class or write our own.

Using the Code

Well, I put a lot of comments in the code so you will be able to understand it easily. All the functions you need are in the airctl class. Take a look at the header file.

class airctl
    HANDLE m_handle;
    deviceInfo* m_devices;
        // Frees the list of wlans
    void freeScanList(void);
    //scans for wlan and returns pointer to the list.
    NDIS_802_11_BSSID_LIST* scan(void);

bool open( char *device_name);
    //lists all devices and saves them in an internal list.
    BOOL list_devices( void);
    // return the pointer to the list
    inline deviceInfo* getDevList( ){return m_devices;};
    // adds one device to the list
    void AddDevice(char * desc, char * name);
    // clears the intern list
    void clearDeviceList(void);
    NDIS_802_11_BSSID_LIST* m_pBSSIDList;

    // intern used to get more informations about an interface
    BOOL get_device_info(   int Index,
                        char *key_name,
                        char *device_info,
                        char *device_description);


First we need a list of all devices. Call list_devices() and it will list everything in an single linked list. Then the demo program shows the user a list of all available devices. The structure for the list is as follows.

struct deviceInfo
    char *description;//information for the user
    char *name;// important to open the device
    deviceInfo* next;//single linked list
Look at the following piece of code. It is from the demo program.
//return me the pointer to the list
 deviceInfo* dv = win->m_airctl.getDevList();

 if (dv == NULL)
     List.AddString("No available interface found !");
     while (dv != NULL)//step through the linked list
         List.AddString(dv->description);// adds it to the list.
         dv = dv->next;

After the user selects a device, it will be opened.

To open the device with the aitctl class we only need to call open() with the device name in it.

if(>name)!= true)
        MessageBox("Cant open selected device","fehler",0);
        ::AfxBeginThread( threadFunc , (LPVOID) this);


But we are curious and will take a small look into that function.

//we open the physical device with CreateFileA
    m_handle = CreateFileA(   device_file,
                            FILE_SHARE_READ | FILE_SHARE_WRITE,// share 
                                                               // mode 
                            NULL, // default security attributes 
                            OPEN_EXISTING,// disposition 
                            0,// file attributes
                            NULL) ;// do not copy file attributes

    if( m_handle == INVALID_HANDLE_VALUE)
           return false;
           // ... open
        return true;


Now it's time to search the WLANs. We will call scan() from the aitctl class.

NDIS_802_11_BSSID_LIST * pBSSIDList = pDlg->m_airctl.scan();

How is this performed? It's done via DeviceIoControl. This is for direct input and output, or for retrieving information from a physical device. For more infomration read this article. It's a really nice series of articles.

First we force the WLAN device to scan for WLANs; we wait for a moment and then we ask the device again to tell us an answer. The source code for this looks like this:

oidcode = OID_802_11_BSSID_LIST_SCAN ;//action to perform

   DeviceIoControl(        m_handle,
                           sizeof( oidcode),
                           ( ULONG *) NULL,
                           NULL) ;

   Sleep( 2000) ;// we give him some time

   memset( m_pBSSIDList, 0, sizeof( NDIS_802_11_BSSID_LIST) *
   oidcode = OID_802_11_BSSID_LIST ;//action to perform

   if( DeviceIoControl(    m_handle,// device to be queried
                           IOCTL_NDIS_QUERY_GLOBAL_STATS,// operation to 
                                                         // perform
                           sizeof( oidcode),//  input buffer
                           ( ULONG *) m_pBSSIDList,// output buffer
                           sizeof( NDIS_802_11_BSSID_LIST) *
                           &bytesreturned,// # bytes returned
                           NULL) == 0)// synchronous I/O
          // List failed
         return NULL;
   else {
         return m_pBSSIDList;

Now we have a pointer to the NDIS_802_11_BSSID_LIST take a look in ntddndis.h where it's defined.

typedef struct _NDIS_802_11_BSSID_LIST
    ULONG           NumberOfItems;      // in list below, at least 1
    NDIS_WLAN_BSSID Bssid[1];

So far so good, but what does NDIS_WLAN_BSSID look like?

typedef struct _NDIS_WLAN_BSSID
    ULONG                               Length;             // Length of this
                                                            // structure
    NDIS_802_11_MAC_ADDRESS             MacAddress;         // BSSID
    UCHAR                               Reserved[2];
    NDIS_802_11_SSID                    Ssid;               // SSID
    ULONG                               Privacy;            // WEP encryption
                                                            // requirement
    NDIS_802_11_RSSI                    Rssi;               // receive signal
                                                            // strength in dBm
    NDIS_802_11_NETWORK_TYPE            NetworkTypeInUse;
    NDIS_802_11_CONFIGURATION           Configuration;
    NDIS_802_11_NETWORK_INFRASTRUCTURE  InfrastructureMode;
    NDIS_802_11_RATES                   SupportedRates;

This looks much better. This is the information we would like to obtain. Now we can show them to the user.

But, we have one thing left to discuss: how to get the next item. For this we will use another pointer which points to NDIS_WLAN_BSSID. Now the variable ULONG Length tells us how long this entry is. After this a certain number of bytes the next entry "lies."

Well, the following is not a good solution, but it shows you what I mean and what it could look like.

//NumberOfItems indecates how many are now in the list
for(unsigned int i =0 ;i < pBSSIDList->NumberOfItems;i++){
    int temp=i;//used to build the differens
    //step to the next in list...
    PNDIS_WLAN_BSSID cpSsid=pBSSIDList->Bssid;//save

    //if we aren't in the first loop we have to set the pointer 
    //to the next
    while(temp!=0 ){
        // go forward
        cpSsid=(PNDIS_WLAN_BSSID)((char*)cpSsid+ cpSsid->Length);

    //do something with your data

That's it man. Thank you for reading, now it's up to you.

Points of Interest

You can perform a lot of more functions to the WLAN device. Just take a look into ntddndis.h under 802.11 OIDs.


First release version 0.1


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Germany Germany
No Biography provided

You may also be interested in...

Comments and Discussions

QuestionHow to perform active scan Pin
sunlikui13-Dec-11 2:41
membersunlikui13-Dec-11 2:41 
Questioncan not work Pin
zhkingsmac12-Oct-11 3:54
memberzhkingsmac12-Oct-11 3:54 
QuestionDeviceIoControl return 0 in XP sp3 Pin
andawu10-Aug-11 23:32
memberandawu10-Aug-11 23:32 
GeneralAbout the AP Scan Pin
fibers17-Dec-09 21:23
memberfibers17-Dec-09 21:23 
QuestionProblems that are in this code: How to flush old scanned data and perform Active sacn ? Pin
amitalonm4-Oct-09 6:43
memberamitalonm4-Oct-09 6:43 
AnswerRe: Problems that are in this code: How to flush old scanned data and perform Active sacn ? Pin
fibers17-Dec-09 21:35
memberfibers17-Dec-09 21:35 
General[My vote of 1] Doesn't work at all Pin
wv-pankaj12-Jun-09 23:45
memberwv-pankaj12-Jun-09 23:45 
Generalthe wlanscan_demo cannot work Pin
apm70pro20-Dec-08 18:52
memberapm70pro20-Dec-08 18:52 
Generalerror link 2028 and 2019 Pin
waty0019-Oct-09 6:46
memberwaty0019-Oct-09 6:46 
GeneralNo Scan Results Pin
masterluu21-Oct-08 22:26
membermasterluu21-Oct-08 22:26 
GeneralDeviceIoControl Pin
Jacano5-Sep-08 1:29
memberJacano5-Sep-08 1:29 
QuestionHow To Connect to a Access Point? Pin
atrip200812-Jul-08 20:49
memberatrip200812-Jul-08 20:49 
AnswerRe: How To Connect to a Access Point? Pin
sud_net23-Jul-08 22:28
membersud_net23-Jul-08 22:28 
GeneralRe: How To Connect to a Access Point? Pin
ggfernandez3-Nov-08 8:42
memberggfernandez3-Nov-08 8:42 
Generalcan't CreateFile in xp Pin
pyd_jeike7-Jul-08 17:50
memberpyd_jeike7-Jul-08 17:50 
GeneralRe: can't CreateFile in xp Pin
fibers17-Dec-09 21:38
memberfibers17-Dec-09 21:38 
GeneralBugs in code Pin
Cory Atkin2-Jul-08 9:16
memberCory Atkin2-Jul-08 9:16 
GeneralRe: Bugs in code Pin
capitel20-Jul-08 17:58
membercapitel20-Jul-08 17:58 
GeneralRe: Bugs in code - question and more problems to report Pin
amitalonm4-Oct-09 6:24
memberamitalonm4-Oct-09 6:24 
GeneralRe: Bugs in code - question and more problems to report Pin
sunlikui13-Dec-11 2:22
membersunlikui13-Dec-11 2:22 
GeneralRe: Bugs in code - question and more problems to report Pin
amitalonm13-Dec-11 9:52
memberamitalonm13-Dec-11 9:52 
GeneralRe: Bugs in code - question and more problems to report Pin
sunlikui13-Dec-11 13:45
membersunlikui13-Dec-11 13:45 
GeneralRe: Bugs in code - question and more problems to report Pin
amitalonm13-Dec-11 21:39
memberamitalonm13-Dec-11 21:39 
GeneralRe: Bugs in code - question and more problems to report Pin
sunlikui14-Dec-11 13:43
membersunlikui14-Dec-11 13:43 
GeneralSignal Strength Pin
carlosteleco28-Apr-08 22:56
membercarlosteleco28-Apr-08 22:56 
QuestionConnected Network Pin
RickNash14-Apr-08 22:36
memberRickNash14-Apr-08 22:36 
Generalporting to DLL Pin
Amrykid23-Mar-08 13:40
memberAmrykid23-Mar-08 13:40 
AnswerRegarding OID_802_11_BSSID_LIST_SCAN Pin
raptor_funky9-Mar-08 20:44
memberraptor_funky9-Mar-08 20:44 
GeneralRe: Regarding OID_802_11_BSSID_LIST_SCAN Pin
Malcolm Hall27-Mar-08 3:10
memberMalcolm Hall27-Mar-08 3:10 
GeneralRe: Regarding OID_802_11_BSSID_LIST_SCAN Pin
Malcolm Hall27-Mar-08 3:13
memberMalcolm Hall27-Mar-08 3:13 
GeneralRe: Regarding OID_802_11_BSSID_LIST_SCAN Pin
Malcolm Hall27-Mar-08 3:52
memberMalcolm Hall27-Mar-08 3:52 
GeneralRe: Regarding OID_802_11_BSSID_LIST_SCAN Pin
amitalonm4-Oct-09 6:35
memberamitalonm4-Oct-09 6:35 
GeneralRe: Regarding OID_802_11_BSSID_LIST_SCAN Pin
fibers17-Dec-09 21:47
memberfibers17-Dec-09 21:47 
QuestionWhat about Windows CE? Pin
Win32nipuh5-Nov-07 20:47
memberWin32nipuh5-Nov-07 20:47 
GeneralScan IPs Pin
rrrado30-Oct-07 2:09
memberrrrado30-Oct-07 2:09 
GeneralRe: Scan IPs Pin
sirb5-Nov-07 21:36
membersirb5-Nov-07 21:36 
GeneralRe: Scan IPs Pin
rrrado5-Nov-07 22:28
memberrrrado5-Nov-07 22:28 
GeneralRe: Scan IPs Pin
sirb5-Nov-07 22:51
membersirb5-Nov-07 22:51 
GeneralRe: Scan IPs Pin
rrrado6-Nov-07 4:20
memberrrrado6-Nov-07 4:20 

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.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160525.2 | Last Updated 29 Oct 2007
Article Copyright 2007 by sirb
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid