WLAN API应用介绍(含实例程序)

来源:互联网 发布:淘宝购买服务在哪里 编辑:程序博客网 时间:2024/05/16 14:12

第一步:打开WLAN服务 

bool CWLANConnectDlg::OpenWLANService(){dwResult = WlanOpenHandle(WLAN_API_VERSION    //客户端支持的WLAN API的最高版本, NULL, &dwCurVersion    //指定这次会话中将会使用的版本, &hClient    //指定客户端在这次会话中使用的句柄,这个句柄会贯穿整个会话被其他函数使用 。);     if(ERROR_SUCCESS != dwResult)    {        switch (dwResult)        {            case ERROR_INVALID_PARAMETER:    //参数一、四为空或参数二不为空                wprintf(L"Para is NULL\n");                 break;            case ERROR_NOT_ENOUGH_MEMORY:    //没有足够的内存空间                wprintf(L"Failed to allocate memory \n");                break;             case ERROR_REMOTE_SESSION_LIMIT_EXCEEDED:    //超过服务器限定的句柄数量                wprintf(L"Server is Busy\n");                break;            default:                dwResult = GetLastError();                wprintf(L"WlanOpenHandle Fail:%wd\n", dwResult);                break;        }return false;    }return true;}
 

第二步:枚举处当前系统安装的所有无线网卡的接口信息。

WLAN_INTERFACE_INFO_LIST

   这个结构体是包含着网卡接口信息的阵列。

 typedef struct _WLAN_INTERFACE_INFO_LIST {                 DWORD dwNumberOfItems;                 DWORD dwIndex;                 WLAN_INTERFACE_INFO InterfaceInfo[]; 
 } WLAN_INTERFACE_INFO_LIST,   *PWLAN_INTERFACE_INFO_LIST; 

       dwNumberOfItems InterfaceInfo[ ] 中包含的单元的个数。

       dwIndex :当前单元的索引,从0开始到 dwNumberOfItems-1。

                这个参数一般用于在 WLAN_INTERFACE_INFO_LIST 被用作参数传递时的一个传递偏移量。这个参数在用之前必须要进行初始化。

       InterfaceInfo[ ] :包含WLAN_INTERFACE_INFO 结构体的阵列,用于记录接口信息。

bool WLANNetwork(){dwResult = WlanEnumInterfaces(hClient    //客户端会话句柄。由 WlanOpenHandle 得到。, NULL, &pInterfaceList    //指向包含无线网卡接口信息list的结构体 PWLAN_INTERFACE_INFO_LIST 的指针。);    if(ERROR_SUCCESS != dwResult)    {        switch (dwResult)        {        case ERROR_INVALID_PARAMETER:    //参数一、三为空,或参数二不为空            wprintf(L"Para is NULL\n");            break;        case ERROR_INVALID_HANDLE:    //无效的句柄            wprintf(L"Failed to INVALID HANDLE \n");            break;         case ERROR_NOT_ENOUGH_MEMORY:    //没有足够的内存空间            wprintf(L"Failed to allocate memory \n");            break;         default:            dwResult = GetLastError();            wprintf(L"WlanEnumInterfaces Fail: %wd\n", dwResult);            break;        }return false;    }wprintf(L"WlanEnumInterfaces Number %wd\n", pInterfaceList->dwNumberOfItems);    //输出网卡数量return true;}
 

第三步:搜索接口上可用的网络。

WLAN_AVAILABLE_NETWORK_LIST

结构体,包含可用网络(network)的信息的列表。

typedef struct _WLAN_AVAILABLE_NETWORK_LIST {           DWORD dwNumberOfItems;           DWORD dwIndex;          WLAN_AVAILABLE_NETWORK Network[1]; 
 }  WLAN_AVAILABLE_NETWORK_LIST,   *PWLAN_AVAILABLE_NETWORK_LIST; 

  dwNumberOfItems :Network中包含的单元的个数

  dwIndex :当前单元的索引,从0开始到dwNumberOfItems-1;

当这个结构体作为参数时用到。用之前必须赋初值。

  Network :一个WLAN_AVAILABLE_NETWORK 的列表,包含接口信息。

WLAN_AVAILABLE_NETWORK

结构体,包含可用无线网络(network)单元的信息。

typedef struct _WLAN_AVAILABLE_NETWORK {           WCHAR strProfileName[256];           DOT11_SSID dot11Ssid;  //SSID          DOT11_BSS_TYPE dot11BssType;           ULONG uNumberOfBssids;           BOOL bNetworkConnectable;           WLAN_REASON_CODE wlanNotConnectableReason;           ULONG uNumberOfPhyTypes;           DOT11_PHY_TYPE dot11PhyTypes[WLAN_MAX_PHY_TYPE_NUMBER];           BOOL bMorePhyTypes;           WLAN_SIGNAL_QUALITY wlanSignalQuality;  //信号强度          BOOL bSecurityEnabled;           DOT11_AUTH_ALGORITHM dot11DefaultAuthAlgorithm;           DOT11_CIPHER_ALGORITHM dot11DefaultCipherAlgorithm;           DWORD dwFlags;           DWORD dwReserved; 
} WLAN_AVAILABLE_NETWORK,  

*PWLAN_AVAILABLE_NETWORK;

DOT11_BSS_TYPE

枚举类型,用于定义BSS网络的类型

typedef enum _DOT11_BSS_TYPE {
                   dot11_BSS_type_infrastructure,
                   dot11_BSS_type_independent,
                   dot11_BSS_type_any,
          DOT11_BSS_TYPE, *PDOT11_BSS_TYPE;

dot11_BSS_type_infrastructure : 为 infrastructure BSS 网络。

dot11_BSS_type_independent :为independent BSS网络

dot11_BSS_type_any :是 infrastructure 或者 independent BSS网络

 

infrastructure BSS

中控型基本服务集 (BSS)是一个包含了一个接入点和一些站点的 802.11 网络。这个接入点将信息送入目标站点或者一个固定网络。

independent BSS

IBSS(Independent Basic Service Set) 独立基本服务集 。是一种无线拓扑结构,IEEE802.11标准的模式

bool SearchNet(){       if (!OpenWLANService())    {        return false;    }    if (!WLANNetwork())    {        return false;    }     for(nInterfaceNumber = 0; nInterfaceNumber < (int)pInterfaceList->dwNumberOfItems; nInterfaceNumber++)    {        /*获取网卡信息*/        pInterface = (PWLAN_INTERFACE_INFO)&pInterfaceList->InterfaceInfo[nInterfaceNumber];        /*获得网络信息列表*/        dwResult = WlanGetAvailableNetworkList(hClient    //客户端的会话句柄, &pInterface->InterfaceGuid    //要搜索的接口的GUID, 0x00    //控制list中返回的网络的类型,XP SP2和SP3为零, NULL, &pNetList    //指向返回的可用网络的 WLAN_AVAILABLE_NETWORK_LIST 的指针);        if(ERROR_SUCCESS != dwResult)        {            switch (dwResult)            {            case ERROR_INVALID_PARAMETER:    //参数四不为空,或其他参数为空                wprintf(L"Para is NULL\n");                break;            case ERROR_INVALID_HANDLE:                wprintf(L"Failed to INVALID HANDLE \n");                break;             case ERROR_NOT_ENOUGH_MEMORY:                wprintf(L"Failed to allocate memory \n");                break;            case ERROR_NDIS_DOT11_POWER_STATE_INVALID:    //广播关闭无法搜索                wprintf(L"The radio for the interface is turned off \n");                break;            default:                dwResult = GetLastError();                wprintf(L"WlanGetAvailableNetworkList Fail: %wd\n", dwResult);                break;            }return false;        }        wprintf(L"WlanGetAvailableNetworkList Number %wd\n", pNetList->dwNumberOfItems);    //输出网络数量        /*连接网络*/bool resultSearch = true;        for(nNetNumber = 0; nNetNumber < pNetList->dwNumberOfItems; nNetNumber++)        {            /*获取网络信息,去重复*/            pNet = (PWLAN_AVAILABLE_NETWORK)&pNetList->Network[nNetNumber];           if (strcmp(target.c_str(),(char*)pNet->dot11Ssid.ucSSID) || !resultSearch){continue;}resultSearch = false;if (!SetProfile()){return false;}if (!WLANConnect()){return false;}     }        /*释放网络信息列表*/        if (NULL != pNetList)        {            WlanFreeMemory(pNetList);            pNetList = NULL;        }    }    /*释放网卡信息列表*/    if(NULL != pInterfaceList)    {        WlanFreeMemory(pInterfaceList);        pInterfaceList = NULL;    }       printf("SUCESS\n");    return true;}


 

第四步:设置用户文件Profile

bool SetProfile(){ string szProfileXML("");  //Profile XML流wscProfileXML = NULL;/*组合参数XML码流*/     string szTemp("");// char p[1024];    /*头*/    szProfileXML += string("<?xml version=\"1.0\"?><WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\"><name>");    /*name,一般与SSID相同*/szTemp = string((char*)pNet->dot11Ssid.ucSSID);    //配置文件名    szProfileXML += szTemp;    /*SSIDConfig*/    szProfileXML += string("</name><SSIDConfig><SSID><name>");szProfileXML += szTemp;    //已搜索到的网络对应的SSIDszProfileXML += string("</name></SSID></SSIDConfig>");/*connectionType*/szProfileXML += string("<connectionType>");switch(pNet->dot11BssType)    //网络类型    {        case dot11_BSS_type_infrastructure:            szProfileXML += "ESS";            break;        case dot11_BSS_type_independent:            szProfileXML += "IBSS";            break;        case dot11_BSS_type_any:            szProfileXML += "Any";            break;        default:            wprintf(L"Unknown BSS type");            return false;    }/*MSM*/szProfileXML += string("</connectionType><MSM><security><authEncryption><authentication>");switch( pNet->dot11DefaultAuthAlgorithm)    //网络加密方式    {        case DOT11_AUTH_ALGO_80211_OPEN:            szProfileXML += "open";wprintf(L"Open 802.11 authentication\n");            break;        case DOT11_AUTH_ALGO_80211_SHARED_KEY:szProfileXML += "shared";            wprintf(L"Shared 802.11 authentication");            break;        case DOT11_AUTH_ALGO_WPA:szProfileXML += "WPA";            wprintf(L"WPA-Enterprise 802.11 authentication\n");            break;        case DOT11_AUTH_ALGO_WPA_PSK:szProfileXML += "WPAPSK";            wprintf(L"WPA-Personal 802.11 authentication\n");            break;        case DOT11_AUTH_ALGO_WPA_NONE:szProfileXML += "none";            wprintf(L"WPA-NONE,not exist in MSDN\n");            break;        case DOT11_AUTH_ALGO_RSNA:szProfileXML += "WPA2";            wprintf(L"WPA2-Enterprise 802.11 authentication\n");            break;        case DOT11_AUTH_ALGO_RSNA_PSK:szProfileXML += "WPA2PSK";            wprintf(L"WPA2-Personal 802.11 authentication\n");            break;        default:           wprintf(L"Unknown authentication");   return false;    }szProfileXML += string("</authentication><encryption>");/*sprintf(p, "%d", pNet->dot11DefaultCipherAlgorithm);szProfileXML += string(p);*/switch(pNet->dot11DefaultCipherAlgorithm)    {        case DOT11_CIPHER_ALGO_NONE:            szProfileXML += "none";            break;        case DOT11_CIPHER_ALGO_WEP40:            szProfileXML += "WEP";            break;        case DOT11_CIPHER_ALGO_TKIP:            szProfileXML += "TKIP";            break;        case DOT11_CIPHER_ALGO_CCMP:            szProfileXML += "AES";            break;        case DOT11_CIPHER_ALGO_WEP104:            szProfileXML += "WEP";            break;                case DOT11_CIPHER_ALGO_WEP:            szProfileXML += "WEP";            break;  case DOT11_CIPHER_ALGO_WPA_USE_GROUP:wprintf(L"USE-GROUP not exist in MSDN");        default:            wprintf(L"Unknown encryption");return false;    }//szProfileXML += string("</encryption><useOneX>false</useOneX></authEncryption></security></MSM>");        //如果加密方式为WEP,keyType必须改为networkKeyszProfileXML += string("</encryption></authEncryption><sharedKey><keyType>passPhrase</keyType><protected>false</protected><keyMaterial>");szProfileXML += targetKey;/*尾*/szProfileXML += string("</keyMaterial></sharedKey></security></MSM></WLANProfile>");/*XML码流转换成双字节*/wscProfileXML = StringToLPCWSTR(szProfileXML);if(NULL == wscProfileXML){wprintf(L"Change wscProfileXML fail\n");return false;} /*设置网络参数*/    dwResult = WlanSetProfile(hClient, &pInterface->InterfaceGuid,         0x00    //设置用户文件类型, wscProfileXML    //用户文件内容, NULL    //在XP SP1和SP2下必须为NULL, FALSE    //是否覆盖已存在的用户文件, NULL    //在XP SP1和SP2下必须为NULL, &dwReasonCode);    if(ERROR_SUCCESS != dwResult)    {        switch (dwResult)        {        case ERROR_INVALID_PARAMETER:    //参数一、二、四、八为空或在XP SP1和SP2下参数三不为0            wprintf(L"Para is NULL\n");            break;        case ERROR_NO_MATCH:    //网络接口不支持的加密类型            wprintf(L"NIC NOT SUPPORT\n");            break;         case ERROR_NOT_ENOUGH_MEMORY:    //没有足够的内存空间            wprintf(L"Failed to allocate memory \n");            break;        case ERROR_BAD_PROFILE:    //用户文件格式错误            wprintf(L"The profile specified by strProfileXml is not valid \n");            break;        case ERROR_ALREADY_EXISTS:    //设置的用户文件已存在            wprintf(L"strProfileXml specifies a network that already exists \n");            break;        case ERROR_ACCESS_DENIED:    //用户没有权限设置用户文件            wprintf(L"The caller does not set the profile. \n");            break;        default:            dwResult = GetLastError();            wprintf(L"WlanSetProfile Fail: %wd\n", dwResult);             break;        }if (dwResult != 183){return false;}    }return true;}

第五步:连接一个指定的网络

WLAN_CONNECTION_PARAMETERS

  在使用WlanConnect 这个函数的时候,这个结构体需要作为参数来设定连接属性。

    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;
bool WLANConnect(){pConnPara = (PWLAN_CONNECTION_PARAMETERS)calloc(1, sizeof(WLAN_CONNECTION_PARAMETERS));    /*设置网络连接参数*/    if(NULL == pConnPara)    {        wprintf(L"pConnPara fail\n");    }pConnPara->wlanConnectionMode = (WLAN_CONNECTION_MODE)0; //XP SP2,SP3 must be 0pConnPara->strProfile = StringToLPCWSTR(target);    //指定的用户文件pConnPara->pDot11Ssid = &pNet->dot11Ssid;    //指定的SSIDpConnPara->pDesiredBssidList = NULL; //XP SP2,SP3 must be NULLpConnPara->dot11BssType = pNet->dot11BssType;    //网络类型pConnPara->dwFlags = 0x00000000; //XP SP2,SP3 must be 0       dwResult = WlanConnect(hClient    //客户端句柄, &pInterface->InterfaceGuid    //连接使用的接口的GUID, pConnPara    //指向结构体 WLAN_CONNECTION_PARAMETERS ,其中指定了连接类型,模式,网络概况,SSID 等其他参数。, NULL);    if(ERROR_SUCCESS != dwResult)    {        switch (dwResult)        {        case ERROR_INVALID_PARAMETER:            wprintf(L"Para is NULL\n");            break;        case ERROR_INVALID_HANDLE:            wprintf(L"Failed to INVALID HANDLE \n");            break;         case ERROR_ACCESS_DENIED:            wprintf(L"The caller does not have sufficient permissions. \n");            break;        default:            dwResult = GetLastError();            wprintf(L"WlanConnect Fail: %wd\n", dwResult);            break;        }return false;    }return true;}


第六步:断开网络连接

bool WLANDisconnect(){     dwResult = WlanDisconnect(hClient, &pInterface->InterfaceGuid, NULL);    if(ERROR_SUCCESS != dwResult)    {        switch (dwResult)        {        case ERROR_INVALID_PARAMETER:    //参数一、二为空            wprintf(L"Para is NULL\n");            break;        case ERROR_INVALID_HANDLE:            wprintf(L"Failed to INVALID HANDLE \n");            break;         case ERROR_NOT_ENOUGH_MEMORY:            wprintf(L"Failed to allocate memory \n");            break;        case ERROR_ACCESS_DENIED:            wprintf(L"The caller does not have sufficient permissions. \n");            break;        default:            dwResult = GetLastError();            wprintf(L"WlanConnect Fail: %wd\n", dwResult);            break;        }if (pProfileXml != NULL) {WlanFreeMemory(pProfileXml);//所有API用到的参数,都要使用API提供的函数去释放pProfileXml = NULL;}        free(pConnPara);return false;    }return true;}

第七步:关闭与服务器间的连接

bool CloseWLANService(){ if(NULL != hClient)     {        dwResult = WlanCloseHandle(hClient    //要关闭的连接的客户端句柄, NULL);        if(ERROR_SUCCESS != dwResult)        {            switch (dwResult)            {            case ERROR_INVALID_PARAMETER:    //参数一为空或参数二不为空                wprintf(L"Para is NULL\n");                break;            case ERROR_INVALID_HANDLE:                wprintf(L"Failed to INVALID HANDLE \n");                break;             default:                dwResult = GetLastError();                wprintf(L"WlanCloseHandle Fail: %wd\n", dwResult);                break;            }return false;        }        hClient = NULL;      } return true;}


附加:

查询网卡连接状态,每次查询都必须使用WlanEnumInterfaces获得新的网卡列表。

    PWLAN_INTERFACE_INFO_LIST pIfList = NULL;    PWLAN_INTERFACE_INFO pIfInfo = NULL;    dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList);     if (dwResult != ERROR_SUCCESS)  {        wprintf(L"WlanEnumInterfaces failed with error: %u\n", dwResult);        // FormatMessage can be used to find out why the function failed        return 1;    }    pIfInfo = (WLAN_INTERFACE_INFO *) &pIfList->InterfaceInfo[0];    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"First node in 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 to associate with a network\n");                break;            case wlan_interface_state_discovering:                wprintf(L"Auto configuration is 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;    }

CSDN源码:

WLAN控制台程序

WLAN图形界面操作程序

PUDN源码:

WLAN控制台程序

WLAN图形界面操作程序