现在的位置: 首页 > 综合 > 正文

WinCE 5.0 WIFI 无线网卡的配置和建立连接

2013年04月30日 ⁄ 综合 ⁄ 共 9438字 ⁄ 字号 评论关闭

WinCE 5.0 WIFI 无线网卡的配置和建立连接 

        在 Windows CE 下自带有无线网卡的配置和连接程序,可是我的系统剪裁掉了资源管理器和任务栏,导致自带的无线网卡配置程序不能再使用了,只好自力更生。

        我的环境是 S3C2440 + WinCE 5.0 + VNUWCL5(威盛无线网卡)及驱动程序。使用 Automatic Configuration Functions API

        一、枚举系统中可用的无线网络设备

                下面的函数可以枚举出系统中所有可用的无线网卡设备的GUID,为了简化,我选择第一块可用的无线网卡来操作       

  1. BOOL
     GetFirstWirelessCard(
    PTCHAR
     pCard)
  2. {
  3.     
    if
     (!pCard)
  4.     {
  5.         
    return
     FALSE;
  6.     }
  7.     INTFS_KEY_TABLE IntfsTable;
  8.     IntfsTable.dwNumIntfs = 0;
  9.     IntfsTable.pIntfs = NULL;
  10.     _tcscpy(pCard, TEXT(
    ""
    ));
  11.     
    // 枚举系统中可用的无线网卡
  12.     
    DWORD
     dwStatus = WZCEnumInterfaces(NULL, &IntfsTable);
  13.     
    if
     (dwStatus != ERROR_SUCCESS)
  14.     {
  15.         RETAILMSG(DBG_MSG, (TEXT(
    "WZCEnumInterfaces() error 0x%08X/n"
    ),dwStatus));
  16.         
    return
     FALSE;
  17.     }
  18.     
    // 判断无线网卡的数量,可以根据无线网卡数量来枚举出所有可用的无线网卡
  19.     
    if
     (!IntfsTable.dwNumIntfs)
  20.     {
  21.         RETAILMSG(DBG_MSG, (TEXT(
    "System has no wireless card./n"
    )));
  22.         
    return
     FALSE;
  23.     }
  24.     _tcscpy(pCard, IntfsTable.pIntfs[0].wszGuid);
  25.     LocalFree(IntfsTable.pIntfs);
  26.     
    return
     TRUE;
  27. }

        二、获取无线网络信息

        获取到了系统可用的无线网卡后,我们就可以利用它的 GUID 号来进行进一步的操作了,首先要做的事情就是得到该无线网卡的信息以及该无线网卡扫描到的 WIFI 网关信息。

        以下函数可以获取到该无线网卡及扫描的到的无线 AP 信息

  1. //////////////////////////////////////////////////////////////////////////
  2. // pCard: 无线网卡 GUID
  3. // pIntf: 无线网卡配置信息结果体
  4. // pOutFlags: 网卡配置信息掩码标志
  5. //////////////////////////////////////////////////////////////////////////
  6. BOOL
     GetWirelessCardInfo(
    PTCHAR
     pCard, PINTF_ENTRY_EX pIntf, PDWORD pOutFlags)
  7. {
  8.     
    TCHAR
     *szWiFiCard = NULL;
  9.     
    // 参数校验
  10.     
    if
     (!pCard || !pIntf || !pOutFlags)
  11.     {
  12.         RETAILMSG(DBG_MSG, (TEXT(
    "Param Error./n"
    )));
  13.         
    return
     FALSE;
  14.     }       
  15.     szWiFiCard = pCard;
  16.     
  17.     *pOutFlags = 0;
  18.     
  19.     
    // 初始化无线网卡信息
  20.     ZeroMemory(pIntf, 
    sizeof
    (INTF_ENTRY_EX));
  21.     
  22.     
    // 设置 GUID 号
  23.     pIntf->wszGuid = szWiFiCard;
  24.     
    // 查询无线网卡信息
  25.     
    DWORD
     dwStatus = WZCQueryInterfaceEx(NULL, INTF_ALL, pIntf, pOutFlags);
  26.     
    if
     (dwStatus != ERROR_SUCCESS)
  27.     {
  28.         RETAILMSG(DBG_MSG, (TEXT(
    "WZCQueryInterfaceEx() error 0x%08X/n"
    ), dwStatus));
  29.         
    return
     FALSE;
  30.     }
  31.     
  32.     
    return
     TRUE;
  33. }

        三、判断连接状态

        我们可以通过无线网卡的状态来判断当前无线网卡是否已经和无线AP建立了连接

  1. BOOL
     IsAssociated(
    const
     INTF_ENTRY_EX Intf, 
    const
     
    DWORD
     dwOutFlags)
  2. {   
  3.     
    if
     (dwOutFlags & INTF_BSSID)
  4.     {
  5.         PRAW_DATA prdMAC = (PRAW_DATA)(&Intf.rdBSSID);
  6.         
  7.         
    // 判断 BSSID 的 MAC 地址是否有效来判断是否和无线AP建立了连接
  8.         
    if
     (prdMAC == NULL || prdMAC->dwDataLen == 0 || 
  9.             (!prdMAC->pData[0] && !prdMAC->pData[1] && !prdMAC->pData[2] &
  10.             !prdMAC->pData[3] && !prdMAC->pData[4] && !prdMAC->pData[5]))
  11.         {
  12.             RETAILMSG(DBG_MSG, (TEXT(
    "(This wifi card is not associated to any)/n"
    )));
  13.             
    return
     FALSE;
  14.         }
  15.         
    else
  16.         {
  17.             RETAILMSG(DBG_MSG, (TEXT(
    "(This wifi card is associated state)/n"
    )));
  18.             
    return
     TRUE;
  19.         }
  20.     }
  21.     
    else
  22.     {
  23.         
    return
     FALSE;
  24.     }   
  25. }

        四、获取无线AP信息

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

  1. void
     GetWirelseeListSSID(
    const
     PRAW_DATA prdBSSIDList, 
    HWND
     hListCtlWnd)
  2. {
  3.     
    if
     (prdBSSIDList == NULL || prdBSSIDList->dwDataLen  == 0)
  4.     {
  5.         RETAILMSG(DBG_MSG, (TEXT(
    "<null> entry./n"
    )));
  6.     }
  7.     
    else
  8.     {
  9.         PWZC_802_11_CONFIG_LIST pConfigList = (PWZC_802_11_CONFIG_LIST)prdBSSIDList->pData;
  10.         
    //RETAILMSG(DBG_MSG, (TEXT("[%d] entries./n"), pConfigList->NumberOfItems));
  11.         uint i;
  12.         
  13.         
    // 枚举所有无线AP
  14.         
    for
     (i = 0; i < pConfigList->NumberOfItems; i++)
  15.         {
  16.             PWZC_WLAN_CONFIG pConfig = &(pConfigList->Config[i]);
  17.             
  18.             RAW_DATA rdBuffer;
  19.             rdBuffer.dwDataLen = pConfig->Ssid.SsidLength;
  20.             rdBuffer.pData = pConfig->Ssid.Ssid;
  21.             
    TCHAR
     tSsid[MAX_PATH];
  22.             
  23.             
    // 将 SSID 的 ASCII 码转化成字符串
  24.             PrintSSID(&rdBuffer, tSsid);
  25.             
    if
     (hListCtlWnd)
  26.             {                   
  27.                 
    if
     (ListBox_FindString(hListCtlWnd, 0, tSsid) == LB_ERR)
  28.                 {
  29.                     ListBox_AddString(hListCtlWnd, tSsid);
  30.                 }               
  31.             }
  32.             
    //RETAILMSG(DBG_MSG, (TEXT("/n"))); 
  33.         }
  34.     }
  35. }

        五、连接到指定的无线AP

  1. //////////////////////////////////////////////////////////////////////////
  2. // pCard: 无线网卡 GUID
  3. // pSSID: 无线AP SSID号
  4. // bAdhoc: 是否点对点的 WIFI 连接
  5. // ulPrivacy: 加密模式(WEP/WPA....)
  6. // ndisMode: 认证模式(Open/Share)
  7. // iKeyIndex: 密钥索引(1-4)
  8. // pKey: 密码
  9. // iEapType: 802.11 认证模式
  10. //////////////////////////////////////////////////////////////////////////
  11. BOOL
     WirelessConnect(
    PTCHAR
     pCard, 
    PTCHAR
     pSSID, 
    BOOL
     bAdhoc, 
    ULONG
     ulPrivacy, NDIS_802_11_AUTHENTICATION_MODE ndisMode, 
    int
     iKeyIndex, 
    PTCHAR
     pKey, 
    int
     iEapType)
  12. {
  13.     
    BOOL
     bRet = FALSE;
  14.     
  15.     
    if
     (!pSSID)
  16.     {
  17.         RETAILMSG(DBG_MSG, (TEXT(
    "Param Error./n"
    )));
  18.         
    return
     FALSE;
  19.     }
  20.     
    else
  21.     {
  22.         WZC_WLAN_CONFIG wzcConfig;
  23.         ZeroMemory(&wzcConfig, 
    sizeof
    (WZC_WLAN_CONFIG));
  24.         wzcConfig.Length = 
    sizeof
    (WZC_WLAN_CONFIG);
  25.         wzcConfig.dwCtlFlags = 0;
  26.         wzcConfig.Ssid.SsidLength = _tcslen(pSSID);
  27.         
    for
     (
    UINT
     i = 0; i < wzcConfig.Ssid.SsidLength; i++)
  28.         {
  29.             wzcConfig.Ssid.Ssid[i] = (
    CHAR
    )pSSID[i];
  30.         }
  31.         
  32.         
    if
     (bAdhoc)
  33.         {
  34.             wzcConfig.InfrastructureMode = Ndis802_11IBSS;
  35.         }
  36.         
    else
  37.         {
  38.             wzcConfig.InfrastructureMode = Ndis802_11Infrastructure;
  39.         }
  40.         
  41.         wzcConfig.AuthenticationMode = ndisMode;
  42.         wzcConfig.Privacy = ulPrivacy;
  43.         
  44.         
    if
     (pKey == NULL || _tcslen(pKey) == 0)
  45.         {
  46.             
    // 对密钥进行转换
  47.             bRet = InterpretEncryptionKeyValue(wzcConfig, 0, NULL, TRUE);
  48.             wzcConfig.EapolParams.dwEapType = iEapType;
  49.             wzcConfig.EapolParams.dwEapFlags = EAPOL_ENABLED;
  50.             wzcConfig.EapolParams.bEnable8021x  = TRUE;
  51.             wzcConfig.EapolParams.dwAuthDataLen = 0;
  52.             wzcConfig.EapolParams.pbAuthData = 0;
  53.         }
  54.         
    else
  55.         {
  56.             RETAILMSG(DBG_MSG, (TEXT(
    "WirelessConnect iKeyIndex = %d./n"
    ), iKeyIndex));             
  57.             bRet = InterpretEncryptionKeyValue(wzcConfig, iKeyIndex, pKey, FALSE);
  58.         }
  59.         
    // 连接到指定的无线AP,并将该AP添加到首先无线AP中
  60.         AddToPreferredNetworkList(pCard, wzcConfig, pSSID);     
  61.     }
  62.     
    return
     bRet;
  63. }

        六、密钥转换

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

    

  1. static
     
    void
     EncryptWepKMaterial(IN OUT WZC_WLAN_CONFIG* pwzcConfig)
  2. {
  3.     BYTE chFakeKeyMaterial[] = { 0x56, 0x09, 0x08, 0x98, 0x4D, 0x08, 0x11, 0x66, 0x42, 0x03, 0x01, 0x67, 0x66 };
  4.     
    for
     (
    int
     i = 0; i < WZCCTL_MAX_WEPK_MATERIAL; i++)
  5.         pwzcConfig->KeyMaterial[i] ^= chFakeKeyMaterial[(7*i)%13];
  6. }
  7. BOOL InterpretEncryptionKeyValue(IN OUT WZC_WLAN_CONFIG& wzcConfig, IN 
    int
     iKeyIndex, IN PTCHAR pKey, IN BOOL bNeed8021X)
  8. {   
  9.     
    if
    (wzcConfig.Privacy == Ndis802_11WEPEnabled)
  10.     {       
  11.         
    if
    (!bNeed8021X && pKey)     
  12.         {           
  13.             wzcConfig.KeyIndex = iKeyIndex;
  14.             wzcConfig.KeyLength = _tcslen(pKey);
  15.             
  16.             
    if
    ((wzcConfig.KeyLength == 5) || (wzcConfig.KeyLength == 13))
  17.             {
  18.                 
    for
    (UINT i=0; i<wzcConfig.KeyLength; i++)
  19.                     wzcConfig.KeyMaterial[i] = (UCHAR)pKey[i];
  20.             }
  21.             
    else
  22.             {
  23.                 
    if
    ((pKey[0] != TEXT(
    '0'
    )) || (pKey[1] != TEXT(
    'x'
    )))
  24.                 {                   
  25.                     RETAILMSG(DBG_MSG, (TEXT(
    "Invalid key value./n"
    ))); 
  26.                     
    return
     FALSE;
  27.                 }
  28.                 pKey += 2;
  29.                 wzcConfig.KeyLength = wcslen(pKey);
  30.                 
    if
    ((wzcConfig.KeyLength != 10) && (wzcConfig.KeyLength != 26))
  31.                 {
  32.                     RETAILMSG(DBG_MSG, (TEXT(
    "Invalid key value./n"
    ))); 
  33.                     
    return
     FALSE;
  34.                 }
  35.                 wzcConfig.KeyLength >>= 1;
  36.                 
    for
    (UINT i=0; i<wzcConfig.KeyLength; i++)
  37.                 {
  38.                     wzcConfig.KeyMaterial[i] = (HEX(pKey[2 * i]) << 4) | HEX(pKey[2 * i + 1]);
  39.                 }                   
  40.             }
  41.             EncryptWepKMaterial(&wzcConfig);
  42.             wzcConfig.dwCtlFlags |= WZCCTL_WEPK_PRESENT;
  43.         }
  44.     }
  45.     
    else
     
    if
    (wzcConfig.Privacy == Ndis802_11Encryption2Enabled
  46.         || wzcConfig.Privacy == Ndis802_11Encryption3Enabled)
  47.     {       
  48.         
    if
    (!bNeed8021X)     
  49.         {
  50.             wzcConfig.KeyLength = wcslen(pKey);
  51.             
    if
    ((wzcConfig.KeyLength < 8) || (wzcConfig.KeyLength > 63))
  52.             {
  53.                 RETAILMSG(DBG_MSG, (TEXT(
    "WPA-PSK/TKIP key should be 8-63 char long string./n"
    )));  
  54.                 
    return
     FALSE;
  55.             }
  56.             
    char
     szEncryptionKeyValue8[64]; 
    // longest key is 63
  57.             memset(szEncryptionKeyValue8, 0, 
    sizeof
    (szEncryptionKeyValue8));
  58.             WideCharToMultiByte(CP_ACP,
  59.                 0,
  60.                 pKey,
  61.                 wzcConfig.KeyLength + 1,
  62.                 szEncryptionKeyValue8,
  63.                 wzcConfig.KeyLength + 1,
  64.                 NULL,
  65.                 NULL);
  66.             WZCPassword2Key(&wzcConfig, szEncryptionKeyValue8);
  67.             EncryptWepKMaterial(&wzcConfig);
  68.             wzcConfig.dwCtlFlags |= WZCCTL_WEPK_XFORMAT
  69.                 | WZCCTL_WEPK_PRESENT
  70.                 | WZCCTL_ONEX_ENABLED;
  71.         }
  72.         wzcConfig.EapolParams.dwEapFlags = EAPOL_ENABLED;
  73.         wzcConfig.EapolParams.dwEapType = DEFAULT_EAP_TYPE;
  74.         wzcConfig.EapolParams.bEnable8021x = TRUE;
  75.         wzcConfig.WPAMCastCipher = Ndis802_11Encryption2Enabled;
  76.     }
  77.     
    return
     TRUE;
  78. }

        通过以上操作,完全可以连接到可用的无线AP了,再加上些适当的UI程序,完全可以用来替代 Windows CE 自带的无线配置程序了,我再连接中放置了一个简单的而完整的测试程序,相信大家看了以后都知道怎么操作无线网卡了。

http://download.csdn.net/source/927575


抱歉!评论已关闭.