设为首页 收藏本站
查看: 1271|回复: 0

[经验分享] WinCE 5.0 WIFI 无线网卡的配置和建立连接(转)

[复制链接]

尚未签到

发表于 2015-10-1 07:23:43 | 显示全部楼层 |阅读模式
  From:http://blog.iyunv.com/xajhuang/archive/2008/12/02/3419512.aspx
  在 Windows CE 下自带有无线网卡的配置和连接程序,可是我的系统剪裁掉了资源管理器和任务栏,导致自带的无线网卡配置程序不能再使用了,只好自力更生。
  我的环境是 S3C2440 + WinCE 5.0 + VNUWCL5(威盛无线网卡)及驱动程序。使用 Automatic Configuration Functions API
  一、枚举系统中可用的无线网络设备
  下面的函数可以枚举出系统中所有可用的无线网卡设备的GUID,为了简化,我选择第一块可用的无线网卡来操作      






BOOL GetFirstWirelessCard(PTCHAR pCard)
{
    if (!pCard)
    {
        return FALSE;
    }
    INTFS_KEY_TABLE IntfsTable;
    IntfsTable.dwNumIntfs = 0;
    IntfsTable.pIntfs = NULL;
    _tcscpy(pCard, TEXT(""));
    // 枚举系统中可用的无线网卡
    DWORD dwStatus = WZCEnumInterfaces(NULL, &IntfsTable);
    if (dwStatus != ERROR_SUCCESS)
    {
        RETAILMSG(DBG_MSG, (TEXT("WZCEnumInterfaces() error 0x%08X\n"),dwStatus));
        return FALSE;
    }
    // 判断无线网卡的数量,可以根据无线网卡数量来枚举出所有可用的无线网卡
    if (!IntfsTable.dwNumIntfs)
    {
        RETAILMSG(DBG_MSG, (TEXT("System has no wireless card.\n")));
        return FALSE;
    }
    _tcscpy(pCard, IntfsTable.pIntfs[0].wszGuid);
    LocalFree(IntfsTable.pIntfs);
    return TRUE;
}
  
   二、获取无线网络信息
  获取到了系统可用的无线网卡后,我们就可以利用它的 GUID 号来进行进一步的操作了,首先要做的事情就是得到该无线网卡的信息以及该无线网卡扫描到的 WIFI 网关信息。
  以下函数可以获取到该无线网卡及扫描的到的无线 AP 信息






//////////////////////////////////////////////////////////////////////////
// pCard: 无线网卡GUID
// pIntf: 无线网卡配置信息结果体
// pOutFlags: 网卡配置信息掩码标志
//////////////////////////////////////////////////////////////////////////
BOOL GetWirelessCardInfo(PTCHAR pCard, PINTF_ENTRY_EX pIntf, PDWORD pOutFlags)
{
    TCHAR *szWiFiCard = NULL;
    // 参数校验
    if (!pCard || !pIntf || !pOutFlags)
    {
        RETAILMSG(DBG_MSG, (TEXT("Param Error.\n")));
        return FALSE;
    }        
    szWiFiCard = pCard;
    *pOutFlags = 0;
    // 初始化无线网卡信息
    ZeroMemory(pIntf, sizeof(INTF_ENTRY_EX));
    // 设置GUID 号
    pIntf->wszGuid = szWiFiCard;
    // 查询无线网卡信息
    DWORD dwStatus = WZCQueryInterfaceEx(NULL, INTF_ALL, pIntf, pOutFlags);
    if (dwStatus != ERROR_SUCCESS)
    {
        RETAILMSG(DBG_MSG, (TEXT("WZCQueryInterfaceEx() error 0x%08X\n"), dwStatus));
        return FALSE;
    }
    return TRUE;
}
  
  三、判断连接状态
  我们可以通过无线网卡的状态来判断当前无线网卡是否已经和无线AP建立了连接






BOOL IsAssociated(const INTF_ENTRY_EX Intf, const DWORD dwOutFlags)
{   
    if (dwOutFlags & INTF_BSSID)
    {
        PRAW_DATA prdMAC = (PRAW_DATA)(&Intf.rdBSSID);
        // 判断BSSID 的MAC 地址是否有效来判断是否和无线AP建立了连接
        if (prdMAC == NULL || prdMAC->dwDataLen == 0 ||  
            (!prdMAC->pData[0] && !prdMAC->pData[1] && !prdMAC->pData[2] &
            !prdMAC->pData[3] && !prdMAC->pData[4] && !prdMAC->pData[5]))
        {
            RETAILMSG(DBG_MSG, (TEXT("(This wifi card is not associated to any)\n")));
            return FALSE;
        }
        else
        {
            RETAILMSG(DBG_MSG, (TEXT("(This wifi card is associated state)\n")));
            return TRUE;
        }
    }
    else
    {
        return FALSE;
    }   
}
  

  四、获取无线AP信息
  获取了无线网卡的信息后,可以通过无线网卡枚举出当前所有可用的无线AP的SSID名称以及加密模式等等所有可用信息,一下函数可以实现该功能






void GetWirelseeListSSID(const PRAW_DATA prdBSSIDList, HWND hListCtlWnd)
{
    if (prdBSSIDList == NULL || prdBSSIDList->dwDataLen  == 0)
    {
        RETAILMSG(DBG_MSG, (TEXT("<null> entry.\n")));
    }
    else
    {
        PWZC_802_11_CONFIG_LIST pConfigList = (PWZC_802_11_CONFIG_LIST)prdBSSIDList->pData;
        //RETAILMSG(DBG_MSG, (TEXT("[%d] entries.\n"), pConfigList->NumberOfItems));

        uint i;
        // 枚举所有无线AP
        for (i = 0; i < pConfigList->NumberOfItems; i++)
        {
            PWZC_WLAN_CONFIG pConfig = &(pConfigList->Config);
            RAW_DATA rdBuffer;
            rdBuffer.dwDataLen = pConfig->Ssid.SsidLength;
            rdBuffer.pData = pConfig->Ssid.Ssid;
            TCHAR tSsid[MAX_PATH];
            // 将SSID 的ASCII 码转化成字符串
            PrintSSID(&rdBuffer, tSsid);
            if (hListCtlWnd)
            {                    
                if (ListBox_FindString(hListCtlWnd, 0, tSsid) == LB_ERR)
                {
                    ListBox_AddString(hListCtlWnd, tSsid);
                }               
            }
            //RETAILMSG(DBG_MSG, (TEXT("\n")));  
        }
    }
}
  

  五、连接到指定的无线AP






//////////////////////////////////////////////////////////////////////////
// pCard: 无线网卡GUID
// pSSID: 无线AP SSID号
// bAdhoc: 是否点对点的WIFI 连接
// ulPrivacy: 加密模式(WEP/WPA....)
// ndisMode: 认证模式(Open/Share)
// iKeyIndex: 密钥索引(1-4)
// pKey: 密码
// iEapType: 802.11 认证模式
//////////////////////////////////////////////////////////////////////////
BOOL WirelessConnect(PTCHAR pCard, PTCHAR pSSID, BOOL bAdhoc, ULONG ulPrivacy, NDIS_802_11_AUTHENTICATION_MODE ndisMode, int iKeyIndex, PTCHAR pKey, int iEapType)
{
    BOOL bRet = FALSE;
    if (!pSSID)
    {
        RETAILMSG(DBG_MSG, (TEXT("Param Error.\n")));
        return FALSE;
    }
    else
    {
        WZC_WLAN_CONFIG wzcConfig;
        ZeroMemory(&wzcConfig, sizeof(WZC_WLAN_CONFIG));
        wzcConfig.Length = sizeof(WZC_WLAN_CONFIG);
        wzcConfig.dwCtlFlags = 0;
        wzcConfig.Ssid.SsidLength = _tcslen(pSSID);
        for (UINT i = 0; i < wzcConfig.Ssid.SsidLength; i++)
        {
            wzcConfig.Ssid.Ssid = (CHAR)pSSID;
        }
        if (bAdhoc)
        {
            wzcConfig.InfrastructureMode = Ndis802_11IBSS;
        }
        else
        {
            wzcConfig.InfrastructureMode = Ndis802_11Infrastructure;
        }
        wzcConfig.AuthenticationMode = ndisMode;
        wzcConfig.Privacy = ulPrivacy;
        if (pKey == NULL || _tcslen(pKey) == 0)
        {
            // 对密钥进行转换
            bRet = InterpretEncryptionKeyValue(wzcConfig, 0, NULL, TRUE);
            wzcConfig.EapolParams.dwEapType = iEapType;
            wzcConfig.EapolParams.dwEapFlags = EAPOL_ENABLED;
            wzcConfig.EapolParams.bEnable8021x  = TRUE;
            wzcConfig.EapolParams.dwAuthDataLen = 0;
            wzcConfig.EapolParams.pbAuthData = 0;
        }
        else
        {
            RETAILMSG(DBG_MSG, (TEXT("WirelessConnect iKeyIndex = %d.\n"), iKeyIndex));              
            bRet = InterpretEncryptionKeyValue(wzcConfig, iKeyIndex, pKey, FALSE);
        }
        // 连接到指定的无线AP,并将该AP添加到首先无线AP中
        AddToPreferredNetworkList(pCard, wzcConfig, pSSID);      
    }
    return bRet;
}
  

  六、密钥转换
  输入的密钥需要通过加密方式进行一定的转化,以下函数可以完成改功能






static void EncryptWepKMaterial(IN OUT WZC_WLAN_CONFIG* pwzcConfig)
{
    BYTE chFakeKeyMaterial[] = { 0x56, 0x09, 0x08, 0x98, 0x4D, 0x08, 0x11, 0x66, 0x42, 0x03, 0x01, 0x67, 0x66 };
    for (int i = 0; i < WZCCTL_MAX_WEPK_MATERIAL; i++)
        pwzcConfig->KeyMaterial ^= chFakeKeyMaterial[(7*i)%13];
}
BOOL InterpretEncryptionKeyValue(IN OUT WZC_WLAN_CONFIG& wzcConfig, IN int iKeyIndex, IN PTCHAR pKey, IN BOOL bNeed8021X)
{   
    if(wzcConfig.Privacy == Ndis802_11WEPEnabled)
    {        
        if(!bNeed8021X && pKey)      
        {            
            wzcConfig.KeyIndex = iKeyIndex;
            wzcConfig.KeyLength = _tcslen(pKey);
            if((wzcConfig.KeyLength == 5) || (wzcConfig.KeyLength == 13))
            {
                for(UINT i=0; i<wzcConfig.KeyLength; i++)
                    wzcConfig.KeyMaterial = (UCHAR)pKey;
            }
            else
            {
                if((pKey[0] != TEXT('0')) || (pKey[1] != TEXT('x')))
                {                    
                    RETAILMSG(DBG_MSG, (TEXT("Invalid key value.\n")));  
                    return FALSE;
                }
                pKey += 2;
                wzcConfig.KeyLength = wcslen(pKey);
                if((wzcConfig.KeyLength != 10) && (wzcConfig.KeyLength != 26))
                {
                    RETAILMSG(DBG_MSG, (TEXT("Invalid key value.\n")));  
                    return FALSE;
                }
                wzcConfig.KeyLength >>= 1;
                for(UINT i=0; i<wzcConfig.KeyLength; i++)
                {
                    wzcConfig.KeyMaterial = (HEX(pKey[2 * i]) << 4) | HEX(pKey[2 * i + 1]);
                }                    
            }
            EncryptWepKMaterial(&wzcConfig);
            wzcConfig.dwCtlFlags |= WZCCTL_WEPK_PRESENT;
        }
    }
    else if(wzcConfig.Privacy == Ndis802_11Encryption2Enabled
        || wzcConfig.Privacy == Ndis802_11Encryption3Enabled)
    {        
        if(!bNeed8021X)      
        {
            wzcConfig.KeyLength = wcslen(pKey);
            if((wzcConfig.KeyLength < 8) || (wzcConfig.KeyLength > 63))
            {
                RETAILMSG(DBG_MSG, (TEXT("WPA-PSK/TKIP key should be 8-63 char long string.\n")));   
                return FALSE;
            }
            char szEncryptionKeyValue8[64]; // longest key is 63
            memset(szEncryptionKeyValue8, 0, sizeof(szEncryptionKeyValue8));
            WideCharToMultiByte(CP_ACP,
                0,
                pKey,
                wzcConfig.KeyLength + 1,
                szEncryptionKeyValue8,
                wzcConfig.KeyLength + 1,
                NULL,
                NULL);
            WZCPassword2Key(&wzcConfig, szEncryptionKeyValue8);
            EncryptWepKMaterial(&wzcConfig);
            wzcConfig.dwCtlFlags |= WZCCTL_WEPK_XFORMAT
                | WZCCTL_WEPK_PRESENT
                | WZCCTL_ONEX_ENABLED;
        }
        wzcConfig.EapolParams.dwEapFlags = EAPOL_ENABLED;
        wzcConfig.EapolParams.dwEapType = DEFAULT_EAP_TYPE;
        wzcConfig.EapolParams.bEnable8021x = TRUE;
        wzcConfig.WPAMCastCipher = Ndis802_11Encryption2Enabled;
    }
    return TRUE;
}
  
  通过以上操作,完全可以连接到可用的无线AP了,再加上些适当的UI程序,完全可以用来替代 Windows CE 自带的无线配置程序了,我再连接中放置了一个简单的而完整的测试程序,相信大家看了以后都知道怎么操作无线网卡了
  http://download.iyunv.com/source/927575

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-121075-1-1.html 上篇帖子: (转帖)Android系列之Wifi定位 下篇帖子: Marvell w8782 sdio wifi AP模式设置
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表