在 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 信息
- 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));
-
-
- 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);
-
-
- 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;
-
- uint i;
-
-
- for (i = 0; i < pConfigList->NumberOfItems; i++)
- {
- PWZC_WLAN_CONFIG pConfig = &(pConfigList->Config[i]);
-
- RAW_DATA rdBuffer;
- rdBuffer.dwDataLen = pConfig->Ssid.SsidLength;
- rdBuffer.pData = pConfig->Ssid.Ssid;
- TCHAR tSsid[MAX_PATH];
-
-
- PrintSSID(&rdBuffer, tSsid);
- if (hListCtlWnd)
- {
- if (ListBox_FindString(hListCtlWnd, 0, tSsid) == LB_ERR)
- {
- ListBox_AddString(hListCtlWnd, tSsid);
- }
- }
-
- }
- }
- }
五、连接到指定的无线AP
- 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[i] = (CHAR)pSSID[i];
- }
-
- 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);
- }
-
- 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[i] ^= 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[i] = (UCHAR)pKey[i];
- }
- 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[i] = (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];
- 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.csdn.net/source/927575