Basic tutorials for using Windows system native Wifi APIs in C + + programs _c language

Source: Internet
Author: User
Tags goto

Windows applications want to connect WiFi, listen for wifi signals, disconnect, and so on, with the Nativewifi API is a good choice.

Open MSDN, search the Nativewifi Api, and find the native WiFi page. Over here.

Information is very large, if I am anxious to achieve the above functions, see a lot of documents some time too late. If you give me an example directly, debug in the run, read the code, the efficiency will be higher.
However, I did not succeed. First, sample is in the SDK, see here. I failed to download a few times and finally gave up the road. Later, my colleague gave me a sample, I am not sure if this is the case, but the code is also very obscure. My original intention was to simply use the examples of these APIs.

It seems that you have to do it yourself. See the relevant API, if you do not understand, you can find examples of experienced people.

After a few setbacks, finally realize my needs. Let me go slowly.
1. Get a list of available AP
See the official documentation for Wlangetavailablenetworklist, here's an example.

DWORD WINAPI Wlangetavailablenetworklist ( 
 _in_  HANDLE hclienthandle, 
 _in_  Const GUID * Pinterfaceguid, 
 _in_  DWORD dwflags, 
 _reserved_ pvoid preserved, 
 _out_  pwlan_available_ Network_list *ppavailablenetworklist 
); 

The available list allows you to find which AP is currently connected and displays the signal strength.
2. Monitor Current connection
on the basis of getting a list of available APs, traverse the current AP to see who is connecting and get its signal. The code snippet is as follows:

BOOL Isconnect = false; 
int numberofitems = pwlan_available_network_list->dwnumberofitems; 
  for (int i = 0; I <= numberofitems i++) 
  { 
   Wlan_available_network Wlanan = pwlan_available_network_list-> Network[i]; 
   if (Wlanan.dwflags & wlan_available_network_connected) 
   { 
    wprintf (WLAN signal is%s:%d\n), Wlanan.strprofilename, wlanan.wlansignalquality); 
    Isconnect = true;     
   } 
  } 
  if (!isconnect) {    
 wprintf ("Wifi is disconnected!\n");} 

3. Disconnect the connection
Disconnect the WiFi if it is in a connected state. Wlandisconnect is still easy to use. The prototype is as follows:

DWORD WINAPI Wlandisconnect ( 
 _in_  HANDLE hclienthandle, 
 _in_  const GUID *pinterfaceguid, 
 _ Reserved_ pvoid preserved 
); 

The code demo is in the back.
4. Connect an AP with profile (saved password)
This is the focus of this article.
Although the connection function Wlanconnect prototype is simple:

DWORD WINAPI Wlanconnect ( 
 _in_  HANDLE hclienthandle, 
 _in_  const GUID *pinterfaceguid,  _in_ Const Pwlan_connection_parameters pconnectionparameters, 
 _reserved_ pvoid preserved 
); 

But the parameter pwlan_connection_parameters is very complex, as long as there is a mismatch, the connection will fail.
Fortunately my demand is quite simple, as long as the link to the existing profile of the AP. Then my work will be targeted to carry out. Frustration for many days, every time the connection failed, the reason is error_invalid_parameter.
Just today, I finally succeeded. It's easy to be a good person.
Look at the structural body of the connection parameter:
typedef struct _WLAN_CONNECTION_PARAMETERS { 
 wlan_connection_mode wlanconnectionmode; 
 LPCWSTR    Strprofile; 
 Pdot11_ssid   Pdot11ssid; 
 Pdot11_bssid_list pdesiredbssidlist; 
 Dot11_bss_type  Dot11bsstype; 
 DWORD    dwflags; 
} Wlan_connection_parameters, *pwlan_connection_parameters; 

To achieve my requirements, you can assign a value like this:
Wlanconnectionmode here set to Wlan_connection_mode_profile;
Strprofile write the name of the AP you want to connect to (usually the profile name);
Pdot11ssid is not used, set null;
pdesiredbssidlist also null;
Dot11bsstype me to set up dot11_bss_type_infrastructure (infrastructure?) ;
dwflags is set to Wlan_connection_hidden_network. The
does work, how does strprofile get it? See the access to the first profile in the available AP list in the listening connection signal. The
complete code is as follows:

#include "stdafx.h" #include <windows.h> #include <wlanapi.h> #include <objbase.h> #include ;wtypes.h> #include <string> #include <stdio.h> #include <stdlib.h>//Need to link with Wlanap 
 
I.lib and Ole32.lib #pragma comment (lib, "Wlanapi.lib") #pragma comment (lib, "Ole32.lib") using namespace std; 
 int Listenstatus () {HANDLE hclient = NULL;   
 DWORD dwmaxclient = 2; 
 DWORD dwcurversion = 0; 
 DWORD dwresult = 0; 
 DWORD dwretval = 0; 
  
 int iRet = 0; 
 WCHAR guidstring[39] = {0}; 
 Listen the status of the AP you connected. 
  while (1) {Sleep (5000); Pwlan_interface_info_list piflist = null;//i-i-WLAN INTERFACE means network card pwlan_interface_info Pifinfo = NUL 
 
  L   
  
  DWORD dwflags = 0; 
  Dwresult = Wlanopenhandle (dwmaxclient, NULL, &dwcurversion, &hclient); 
   if (dwresult!= error_success) {wprintf (L "Wlanopenhandle failed with ERROR:%u\n", dwresult); 
  return 1; } dwreSult = Wlanenuminterfaces (hclient, NULL, &piflist); 
   if (dwresult!= error_success) {wprintf (L "Wlanenuminterfaces failed with ERROR:%u\n", dwresult); 
  return 1; 
 
   else {wprintf (L "wlan_interface_info_list for this system\n"); 
   wprintf (L "Num Entries:%lu\n", piflist->dwnumberofitems); 
   wprintf (L "Current Index:%lu\n\n", Piflist->dwindex); 
   int i; for (i = 0; i < (int) piflist->dwnumberofitems; i++) {pifinfo = (Wlan_interface_info *) &piflist->inter 
    Faceinfo[i]; 
    wprintf (L "Interface index[%u]:\t%lu\n", I, I); IRet = StringFromGUID2 (Pifinfo->interfaceguid, (LPOLESTR) &guidstring, sizeof (guidstring)/sizeof (*guidstring 
 
    )); 
    if (IRet = = 0) wprintf (L "StringFromGUID2 failed\n"); 
    else {wprintf (L "interfaceguid[%d]:%ws\n", I, guidstring); 
    } wprintf (L "Interface description[%d]:%ws", I, pifinfo->strinterfacedescription); 
 
    wprintf (L "\ n"); wprintf (L "InterfacE state[%d]:\t ", i); 
     Switch (pifinfo->isstate) {case wlan_interface_state_not_ready:wprintf (L ' not ready\n '); 
    Break 
     Case wlan_interface_state_connected:wprintf (L "connected\n"); 
    Break 
     Case wlan_interface_state_ad_hoc_network_formed:wprintf (L "a ad hoc network\n"); 
    Break 
     Case wlan_interface_state_disconnecting:wprintf (L "disconnecting\n"); 
    Break 
     Case wlan_interface_state_disconnected:wprintf (L "not connected\n"); 
    Break 
     Case wlan_interface_state_associating:wprintf (L "attempting-associate with a network\n"); 
    Break 
     Case wlan_interface_state_discovering:wprintf (L "Auto configuration are discovering settings for the network\n"); 
    Break 
     Case wlan_interface_state_authenticating:wprintf (L "In process of authenticating\n"); 
    Break 
     default:wprintf (L "Unknown State%ld\n", pifinfo->isstate); 
    Break } 
   }
  '} ' int _tmain (int argc, _tchar* argv[]) {HANDLE hclient = NULL;   
 DWORD dwmaxclient = 2; 
 DWORD dwcurversion = 0; 
 DWORD dwresult = 0; 
 DWORD dwretval = 0;  
 
 int iRet = 0; 
 /* variables used for wlanenuminterfaces * * pwlan_interface_info_list piflist = NULL; 
 
 Pwlan_interface_info pifinfo = NULL; 
 LPCWSTR Pprofilename = NULL; 
 LPWSTR pprofilexml = NULL; 
  
 DWORD dwflags = 0; 
  
 Pprofilename = argv[1]; 
  
 wprintf (L "Information for Profile:%ws\n\n", pprofilename); 
 Dwresult = Wlanopenhandle (dwmaxclient, NULL, &dwcurversion, &hclient); 
  if (dwresult!= error_success) {wprintf (L "Wlanopenhandle failed with ERROR:%u\n", dwresult); 
 return 1; 
 } dwresult = Wlanenuminterfaces (hclient, NULL, &piflist); 
  if (dwresult!= error_success) {wprintf (L "Wlanenuminterfaces failed with ERROR:%u\n", dwresult); 
 return 1; else {dwresult = Wlandisconnect (hclient, &piflist->interfaceinfo[0). Interfaceguid,null);//disconnECT. (dwresult!= error_success) {printf ("Wlandisconnect failed with ERROR:%u\n", dwresult); 
  return-1; 
  } pwlan_available_network_list pwlan_available_network_list = NULL; Dwresult = Wlangetavailablenetworklist (hclient, &piflist->interfaceinfo[0). Interfaceguid, Wlan_available_network_include_all_manual_hidden_profiles, NULL, &pwlan_available_network_lis 
  T); 
   if (dwresult!= error_success) {printf ("Wlangetavailablenetworklist failed with ERROR:%u\n", dwresult); 
   Wlanfreememory (pwlan_available_network_list); 
  return-1; } wlan_available_network Wlanan = Pwlan_available_network_list->network[0];//please CHECK this YOURSELF if (PProfi  
  Lename = = NULL) Pprofilename = Wlanan.strprofilename; 
  Wlan_connection_parameters Wlanconnpara; Wlanconnpara.wlanconnectionmode =wlan_connection_mode_profile;       Yes,we CONNECT AP VIA the profile wlanconnpara.strprofile =pprofilename; 
  Set the profile nameWlanconnpara.pdot11ssid = NULL;  SET SSID NULL wlanconnpara.dot11bsstype = dot11_bss_type_infrastructure;   
  Dot11_bss_type_any,i do not need it.       Wlanconnpara.pdesiredbssidlist = NULL;   The desired BSSID list is empty wlanconnpara.dwflags = wlan_connection_hidden_network; It works in my win7\8 dwresult=wlanconnect (hclient,&piflist->interfaceinfo[0). 
  Interfaceguid,&wlanconnpara, NULL); 
  if (dwresult==error_success) {printf ("Wlanconnect success!\n"); 
  else {printf ("Wlanconnect failed err is%d\n", dwresult); } listenstatus (); 
  LISTEN the STATUS if (pprofilexml!= NULL) {wlanfreememory (pprofilexml); 
 Pprofilexml = NULL; 
  } if (Piflist!= NULL) {wlanfreememory (piflist); 
 Piflist = NULL; 
return dwretval; 
 }


5. Open the Network Setup interface
access to a previously disconnected AP, you need to enter a password, then, directly open the configuration interface for users to do it themselves.

ShellExecute ( 
 NULL, 
 L "open", 
 L "shell:::{21ec2020-3aea-1069-a2dd-08002b30309d}\\::{ 38A98528-6CBF-4CA9-8DC0-B1E1D10F7B1B} ", 
 null, 
 null, 
 SW_SHOWNORMAL); 

6.RSSI
when a "Wlanconnect success!" is printed on the screen , don't mention how happy you are.
Just like Edison Test filament, after countless failures, finally found a material can be competent for the filament work. This joy is really exciting, the past haze and discomfort finally swept.
In fact I have tried Wlangetprofile and Wlansetprofile, although sometimes the result is to be able to connect to the specified AP, but the function returns the result is always error_invalid_parameter.
Online examples, many are copied to copy, write the unclear, although there have been help, but also some misleading.
Today I successfully connected to the designated AP (run my example with the command line, enter the parameter profile name), I must publish it and let others have a reference.
I think this is a piece of good faith, and here I also thank the friends who have helped me.
Finally, get the signal. The standard signal rssi is negative, and the signal here is positive (0~100), and in some places where rssi is needed, we need to convert:

if (pbssentry->wlansignalquality = = 0) 
  Irssi = -100; 
 else if (pbssentry->wlansignalquality =)  
  Irssi = -50; 
 else 
  Irssi = -100 + (PBSSENTRY->WLANSIGNALQUALITY/2);  
  
 wprintf (L "Signal quality[%u]:\t%u (RSSI:%i dBm) \ n", J, 
  Pbssentry->wlansignalquality, Irssi); 


7.Wifi on and Wifi off
The following is to say at the software level to control the wireless card on and off.
The problem sounds simple, it's complicated to investigate, but it's simple to solve. The key function is the wlansetinterface in the native WiFi API. In fact, this API function is also right and wrong
Often powerful, I only use the function that controls the WiFi radio state. The official website documents here.
Function Prototypes:

DWORD WINAPI Wlansetinterface ( 
 _in_  HANDLE hclienthandle, 
 _in_  const GUID *pinterfaceguid, 
 _in_  Wlan_intf_opcode OPCODE, 
 _in_  DWORD dwdatasize, 
 _in_  const pvoid pData, 
 _reserved_ pvoid Preserved 
); 

Focus on three parameters:
(1) OpCode, specify the parameters to set. We choose Wlan_intf_opcode_radio_state
(2) The size of the dwdatasize,pdata. The incoming time is obtained with sizeof.
(3) Pdata,radio state corresponds to the data is wlan_phy_radio_state.
Look at this state structure:

typedef struct _WLAN_PHY_RADIO_STATE { 
 DWORD    dwphyindex; 
 Dot11_radio_state dot11softwareradiostate; 
 Dot11_radio_state dot11hardwareradiostate; 
} Wlan_phy_radio_state, *pwlan_phy_radio_state; 

The index is set to 0.
State is set as follows:

typedef enum _DOT11_RADIO_STATE { 
 dot11_radio_state_unknown, 
 dot11_radio_state_on, 
 dot11_radio_state _off 
} dot11_radio_state, *pdot11_radio_state; 

This function is much simpler to use than the first few APIs (such as Wlanconnect). The full source code is as follows:

ManageWirelessNetwork.cpp:Defines the entry point for the console application. #include "stdafx.h" #include <stdio.h> #include <windows.h> #include <shellapi.h> #include ;wlanapi.h>//Need to link with Shell32.lib #pragma comment (lib, "Shell32.lib") #pragma comment (lib, "Wlanapi.lib") 
 ") int _tmain (int argc, _tchar* argv[]) {DWORD dwresult = 0; 
 DWORD dwmaxclient = 2; 
 DWORD dwcurversion = 0; 
 HANDLE hclient = NULL; 
 Pwlan_interface_info_list piflist = NULL; 
 
 Pwlan_interface_info pifinfo = NULL; 
 Dwresult = Wlanopenhandle (dwmaxclient, NULL, &dwcurversion, &hclient); 
  if (dwresult!= error_success) {wprintf (L "Wlanopenhandle failed with ERROR:%u\n", dwresult); 
 return false; 
 } dwresult = Wlanenuminterfaces (hclient, NULL, &piflist); 
  if (dwresult!= error_success) {wprintf (L "Wlanenuminterfaces failed with ERROR:%u\n", dwresult); 
 return false; 
 } wlan_phy_radio_state State; State.dwphyindex = 0; 
 State.dot11softwareradiostate = dot11_radio_state_on; 
 
 PVOID PData = &state; Dwresult = Wlansetinterface (hclient,&piflist->interfaceinfo[0]. 
 
 Interfaceguid, Wlan_intf_opcode_radio_state,sizeof (wlan_phy_radio_state), pdata,null); 
 if (dwresult = = ERROR_SUCCESS) {wprintf (L "set state success!\n"); 
 else {wprintf (L "set state Failed!err is%d\n", dwresult); 
return 0; 
 }

The role of

8.GOTO in releasing resources
goto statements have a foul reputation, and our teachers often teach us not to use it lightly. There are three
C + + jump statements: Goto, break, and continue. They are just tools, I think the problem is not the tool, the problem is people.
Just like a pointer, goto this unconditional jump statement power is still very strong, if abused, there are difficult to troubleshoot problems.
But sometimes Goto is really the choice, such as I encountered, there are multiple exits in the function, and each exit encounters the release of resources, and instead of the release statements tired of writing,
less than a goto statement to the crisp.
The following example is derived from the previous native WiFi API article, which must be paid attention to to release resources due to the on and off of WiFi that our program often controls. Take Wlanopenhandle,
If you do not pay attention to symmetric Wlanclosehandler, the program several times after running the error: error_remote_session_limit_exceeded
Official website explained: Too Many Handles have been issued by the server.
So we will confirm the return value after each API call, and if the error, the program will no longer continue to run down, we must release the resource before returning. When exporting a lot, we have to write a lot of the same code,
very annoying, difficult to read, the rapid expansion of the code. But after using Goto, the problem is a lot easier, see simple example:

ManageWirelessNetwork.cpp:Defines the entry point for the console application. #include "stdafx.h" #include <stdio.h> #include <windows.h> #include <shellapi.h> #include ;wlanapi.h>//Need to link with Shell32.lib #pragma comment (lib, "Shell32.lib") #pragma comment (lib, "Wlanapi.lib") 
  ") int _tmain (int argc, _tchar* argv[]) {DWORD dwresult = 0; 
  DWORD dwmaxclient = 2; 
  DWORD dwcurversion = 0; 
  HANDLE hclient = NULL; 
  Pwlan_interface_info_list piflist = NULL; 
 
  Pwlan_interface_info pifinfo = NULL; 
  Dwresult = Wlanopenhandle (dwmaxclient, NULL, &dwcurversion, &hclient); 
    if (dwresult!= error_success) {wprintf (L "Wlanopenhandle failed with ERROR:%u\n", dwresult); 
  return false; 
  } dwresult = Wlanenuminterfaces (hclient, NULL, &piflist); 
    if (dwresult!= error_success) {wprintf (L "Wlanenuminterfaces failed with ERROR:%u\n", dwresult); 
  Goto Release_resource; } Wlan_phy_radio_state State; 
  State.dwphyindex = 0; 
  State.dot11softwareradiostate = Dot11_radio_state_on;//off here too. 
 
  PVOID PData = &state; Dwresult = Wlansetinterface (hclient,&piflist->interfaceinfo[0]. 
 
  Interfaceguid, Wlan_intf_opcode_radio_state,sizeof (wlan_phy_radio_state), pdata,null); 
  if (dwresult = = ERROR_SUCCESS) {wprintf (L "set state success!\n"); 
  else {wprintf (L "set state Failed!err is%d\n", dwresult); 
    } release_resource:if (hclient) {wlanclosehandle (hclient,null); 
  Hclient = NULL; 
    } if (piflist) {wlanfreememory (piflist); 
  Piflist = NULL; 
    } if (Pifinfo) {wlanfreememory (pifinfo); 
  Pifinfo = NULL; 
return 0; 
 }

Finally, Goto will also be used to jump out of multiple loops. But it should be noted that only from the inner layer jump to the outer, irreversible operation.

Postscript:
in fact, a few months ago to implement the Windows WiFi on and off, ask a lot of people, sent a lot of posts, and finally nothing. A lot of things happened in the days that followed. of domestic
Search results, coupled with Google's inability to use, are a bit more difficult to investigate. Let's focus on a few ways to native the WiFi API, and see the previous article on Topsy. But
That's not what I want.
I thought Windows would want Android as well, and the general app didn't have the authority to control the WiFi switch. This also announces my judgment mistake before.
Until today, several clues were found through Bing. That's the question of calling the native WiFi API via C #, which mentions the wlansetinterface that didn't pay attention to before.
Interface, here I think can be understood as a wireless network card. The functionality implemented in similar wlanenuminterfaces is ROM listing the current wireless network card.
Wireless card settings, one of which is radio state.
Sure enough, all this was broken.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.