win32 wifi连接

首先,获取所有可用的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 notifications
FALSE, 
NULL,
NULL, // context data
NULL, 
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 一般已经过加密处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值