在 Windows CE 下自带有无线网卡的配置和连接程序,这篇文章就来谈一下如何用那么可以利用微软自带的WZC函数来重新编写一个独立于系统的WIFI连接程序.
下面是一整套通过WZC函数连接无线网的程序,我自己测试后保证在系统下是可以运行.大家可以参考一下。
一、非常重要的库文件。
#include <eaputil.h>
#include <pm.h>
#include <wzcsapi.h>
#include <iphlpapi.h>
#pragma comment(lib,"Iphlpapi.lib")
#pragma comment(lib,"Wzcsapi.lib")
#pragma comment(lib,"cclib.lib")
二、枚举系统中可用的无线网络设备
- 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了。