win32 wifi连接

来源:互联网 发布:lol 新手 知乎 编辑:程序博客网 时间:2024/05/18 01:15

首先,获取所有可用的wifi:
windows API提供WlanEnumInterfaces接口获取所有可用的wlan,详细的可以参看msdn下的例子程序,https://msdn.microsoft.com/en-us/library/windows/desktop/ms706749(v=vs.85).aspx

  if (pBssEntry->bSecurityEnabled)     wprintf(L"Yes\n"); else     wprintf(L"No\n");

这里表示当前wlan连接是否需要密码。

pBssEntry =(WLAN_AVAILABLE_NETWORK *)&pBssList->Network[j];if (pBssEntry->dot11Ssid.uSSIDLength == 0)    wifi.mName.Append(Empty);else {       for (k = 0; k < pBssEntry->dot11Ssid.uSSIDLength; k++)     {        //wprintf(L"%c", (int) pBssEntry->dot11Ssid.ucSSID[k]);        wsprintf(&buf[k],L"%c", (int) pBssEntry->dot11Ssid.ucSSID[k]);    }    wifi.mName.Append(buf);}

这里可以获取wlan的名称。

if (pBssEntry->wlanSignalQuality == 0)    iRSSI = -100;else if (pBssEntry->wlanSignalQuality == 100)       iRSSI = -50;else    iRSSI = -100 + (pBssEntry->wlanSignalQuality/2);    

这里获取wlan的信号强度。

连接之前先注册通告消息:

DWORD err = WlanRegisterNotification(    hClient,     WLAN_NOTIFICATION_SOURCE_ACM,//WLAN_NOTIFICATION_SOURCE_ALL, notifications    FALSE,     ConnectNotifyCallback,    this, // context data    NULL,     NULL     );

可以注册所有类型的通告消息,但是一般没有这个必要,注册自己想要的,这里注册的消息类型是WLAN_NOTIFICATION_SOURCE_ACM,ConnectNotifyCallback是回调函数,可以用来处理发送回来的消息。this为上下文参数,为一个对象,也就是消息由哪个对象处理。倒数第二个参数为保留参数,设为NULL;倒数第一个参数为前一个注册消息源,这里也为NULL。注册成功返回ERROR_SUCCESS。

一切完毕之后需要取消注册通告消息:

DWORD err = WlanRegisterNotification(hClient, WLAN_NOTIFICATION_SOURCE_NONE, // register all notificationsFALSE, NULL,NULL, // context dataNULL, NULL );

连接指定wlan:

void CWifiDialog::ConnectWlan(){    int index;    int err;    CString key;    GUID pInterfaceGuid = pIfInfo->InterfaceGuid;    TCHAR profile[2048] = {0};    index = mWifiList->GetCurSel();    pBssEntry =(WLAN_AVAILABLE_NETWORK *)&pBssList->Network[index];    WLAN_CONNECTION_PARAMETERS ConnPara;    if (need a key)    {      //这里可以由用户输入密码        key = GetKey();        wsprintf(profile, WPProfileKey, wifi.mName, wifi.mName, key);    }    else    {           //不需要密码        wsprintf(profile, WPProfileNoKey, wifi.mName, wifi.mName);    }    ConnPara.pDot11Ssid = &(pBssEntry->dot11Ssid);//pDot11Ssid; // SSID    ConnPara.dot11BssType = pBssEntry->dot11BssType; // BSS type    ConnPara.pDesiredBssidList = NULL; // no desired BSSID    ConnPara.strProfile = profile;//NULL; // no profile    ConnPara.wlanConnectionMode =  wlan_connection_mode_temporary_profile;//wlan_connection_mode_discovery_secure;    ConnPara.dwFlags = 0; // no connection flag    err = WlanConnect(hClient, &pInterfaceGuid, &ConnPara, NULL);     //WLAN_CONNECTION_ADHOC_JOIN_ONLY    if (err ==  ERROR_SUCCESS)    {       //TODO:如保存密码    }    else if (err == ERROR_INVALID_PARAMETER)    {    }    else if (err == ERROR_INVALID_HANDLE)    {    }    else if (err == ERROR_ACCESS_DENIED)    {    }    else    {        if (mWifis.at(index).mIsLocked)        {              ConnectWlan();        }        else        {            return;        }    }}

如果连接没有成功,重连。

连接状态监听:

void  OnConnect(PWLAN_NOTIFICATION_DATA data){       int err;    CString hint;    hint.Append(_T("连接"));    hint.Append(mWifis.at(mCurIndex).mName);    if (data->InterfaceGuid == pIfInfo->InterfaceGuid)    {           if (data->NotificationSource == WLAN_NOTIFICATION_SOURCE_ACM)        {            if (data->NotificationCode == wlan_notification_acm_connection_start)            {                hint.Append(_T("开始"));            }            else if(data->NotificationCode == wlan_notification_acm_connection_complete)            {                hint.Append(_T("成功"));            }            else if (data->NotificationCode == wlan_notification_acm_connection_attempt_fail)            {                   hint.Append(_T("失败"));            }            else if (data->NotificationCode ==  wlan_notification_acm_disconnected)            {            }        }    }}

if (data->InterfaceGuid == pIfInfo->InterfaceGuid)判断过滤通告消息。
NotificationSource == WLAN_NOTIFICATION_SOURCE_ACM 通知源是WLAN_NOTIFICATION_SOURCE_ACM ,其他源的不处理,接着处理通知码,wlan_notification_acm_disconnected表示断开一个连接,例如,连接另外一个wlan时,就需要断开当前连接(如果当前已经有连接),wlan_notification_acm_connection_start表示连接开始,wlan_notification_acm_connection_complete表示连接成功。

WLANProfile设置:
当进行wlan连接时,ConnPara.wlanConnectionMode 设置为 wlan_connection_mode_temporary_profile时需要设置WLANProfile,WLANProfile例子如下:

_T("<?xml version=\"1.0\" encoding=\"US-ASCII\"?>\                        <WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\">\                        <name>%s</name>\                        <SSIDConfig>\                        <SSID>\                        <name>%s</name>\                        </SSID>\                        </SSIDConfig>\                        <connectionType>ESS</connectionType>\                        <connectionMode>auto</connectionMode>\                        <autoSwitch>false</autoSwitch>\                        <MSM>\                        <security>\                            <authEncryption>\                                <authentication>WPA2PSK</authentication>\                                <encryption>AES</encryption>\                                <useOneX>false</useOneX>\                            </authEncryption>\                            <sharedKey>\                            <keyType>passPhrase</keyType>\                            <protected>false</protected>\                            <keyMaterial>%s</keyMaterial>\                            </sharedKey>\                        </security>\                        </MSM>\                        </WLANProfile>")

keyMaterial 出设置wlan密码,name处为wlan 的SSID。

可以使用命令: netsh wlan export profile %SSIDName% folder=D:\ 导出指定SSID的 wlan profile。不过导出的profile中keyMaterial 一般已经过加密处理。

0 0
原创粉丝点击