C++程序中使用Windows系统Native Wifi API的基本教程

2020-01-06 14:45:31丽君
但参数PWLAN_CONNECTION_PARAMETERS却是很复杂,只要有一个配错,连接就会失败。
还好我的需求还是蛮简单的,只要连接已有的profile的AP。那么我的工作就会有针对性的开展。挫折了好多天,每次都连接失败,原因是ERROR_INVALID_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; 

为了实现我的要求,可以这样赋值:
wlanConnectionMode这里设成wlan_connection_mode_profile;
strProfile写上你要连接ap的名称(通常是profile名称);
pDot11Ssid用不上,设置NULL;
pDesiredBssidList同样置成NULL;
dot11BssType我给设成dot11_BSS_type_infrastructure(基础设施?);
dwFlags设置为WLAN_CONNECTION_HIDDEN_NETWORK。
确实是工作了,strProfile如何获取呢?参见监听连接信号中对可用AP列表中第一个profile的获取。
完整代码如下:


// 
#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 Wlanapi.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 think wlan interface means network card 
  PWLAN_INTERFACE_INFO pIfInfo = NULL; 
 
  DWORD dwFlags = 0;   
  
  dwResult = WlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient); 
  if (dwResult != ERROR_SUCCESS) { 
   wprintf(L"WlanOpenHandle failed with error: %un", dwResult); 
   return 1; 
  } 
 
  dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList); 
  if (dwResult != ERROR_SUCCESS) { 
   wprintf(L"WlanEnumInterfaces failed with error: %un", dwResult); 
   return 1; 
  } else { 
 
   wprintf(L"WLAN_INTERFACE_INFO_LIST for this systemn"); 
 
   wprintf(L"Num Entries: %lun", pIfList->dwNumberOfItems); 
   wprintf(L"Current Index: %lunn", pIfList->dwIndex); 
   int i; 
   for (i = 0; i < (int) pIfList->dwNumberOfItems; i++) { 
    pIfInfo = (WLAN_INTERFACE_INFO *) &pIfList->InterfaceInfo[i]; 
    wprintf(L" Interface Index[%u]:t %lun", i, i); 
    iRet = StringFromGUID2(pIfInfo->InterfaceGuid, (LPOLESTR) &GuidString, 
     sizeof(GuidString)/sizeof(*GuidString)); 
 
    if (iRet == 0) 
     wprintf(L"StringFromGUID2 failedn"); 
    else { 
     wprintf(L" InterfaceGUID[%d]: %wsn",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 readyn"); 
     break; 
    case wlan_interface_state_connected: 
     wprintf(L"Connectedn"); 
     break; 
    case wlan_interface_state_ad_hoc_network_formed: 
     wprintf(L"First node in a ad hoc networkn"); 
     break; 
    case wlan_interface_state_disconnecting: 
     wprintf(L"Disconnectingn"); 
     break; 
    case wlan_interface_state_disconnected: 
     wprintf(L"Not connectedn"); 
     break; 
    case wlan_interface_state_associating: 
     wprintf(L"Attempting to associate with a networkn"); 
     break; 
    case wlan_interface_state_discovering: 
     wprintf(L"Auto configuration is discovering settings for the networkn"); 
     break; 
    case wlan_interface_state_authenticating: 
     wprintf(L"In process of authenticatingn"); 
     break; 
    default: 
     wprintf(L"Unknown state %ldn", 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: %wsnn", pProfileName); 
  
 dwResult = WlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient); 
 if (dwResult != ERROR_SUCCESS) { 
  wprintf(L"WlanOpenHandle failed with error: %un", dwResult); 
  return 1; 
 } 
 
 dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList); 
 if (dwResult != ERROR_SUCCESS) { 
  wprintf(L"WlanEnumInterfaces failed with error: %un", dwResult); 
  return 1; 
 } else { 
  dwResult = WlanDisconnect(hClient, &pIfList->InterfaceInfo[0].InterfaceGuid,NULL);//DISCONNECT FIRST 
  if(dwResult != ERROR_SUCCESS) 
  { 
   printf("WlanDisconnect failed with error: %un",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_LIST); 
  if (dwResult != ERROR_SUCCESS) 
  {    
   printf("WlanGetAvailableNetworkList failed with error: %un",dwResult); 
   WlanFreeMemory(pWLAN_AVAILABLE_NETWORK_LIST); 
   return -1; 
  } 
  WLAN_AVAILABLE_NETWORK wlanAN = pWLAN_AVAILABLE_NETWORK_LIST->Network[0];//PLEASE CHECK THIS YOURSELF 
  if(pProfileName == 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 name 
  wlanConnPara.pDot11Ssid = NULL;         // SET SSID NULL 
  wlanConnPara.dot11BssType = dot11_BSS_type_infrastructure;  //dot11_BSS_type_any,I do not need it this time.   
  wlanConnPara.pDesiredBssidList = NULL;       // the desired BSSID list is empty 
  wlanConnPara.dwFlags = WLAN_CONNECTION_HIDDEN_NETWORK;   //it works on my WIN78 
 
  dwResult=WlanConnect(hClient,&pIfList->InterfaceInfo[0].InterfaceGuid,&wlanConnPara ,NULL); 
  if (dwResult==ERROR_SUCCESS) 
  { 
   printf("WlanConnect success!n"); 
  } 
  else 
  { 
   printf("WlanConnect failed err is %dn",dwResult); 
  } 
 } 
 
 listenStatus(); //LISTEN THE STATUS 
 
 if (pProfileXml != NULL) { 
  WlanFreeMemory(pProfileXml); 
  pProfileXml = NULL; 
 } 
 
 if (pIfList != NULL) { 
  WlanFreeMemory(pIfList); 
  pIfList = NULL; 
 } 
 return dwRetVal; 
}