在 Windows CE 下自带有无线网卡的配置和连接程序,但是如果系统剪裁掉了资源管理器和任务栏,就会导致自带的无线网卡配置程序不能再使用了,那么可以利用微软自带的WZC函数来重新编写一个新工具。
所以设置WIFI,第一步就是要获取这个无线路由器的名称,WINCE 500提供了获取这个名字的API,叫WZCQueryInterfaceEx(),用这个函数需要升级PB补丁到最新版,不然就用WZCQueryInterface()。设置中主要用的函数都在wzctool.cpp 这个里面:GetFirstWirelessNetworkCard(),找你的无线网卡;InterpretEncryptionKeyValue(),这个是帮你转处理密码的函数;AddToPreferredNetworkList(),这个函数就是帮你连的无线上网的函数了,密码和网络名称都传给这个函数,然后调用它就连上去了。
详细列举说明如下:
(1)GetFirstWirelessCard
枚举系统中可用的无线网络设备,为了简化,选择第一块可用的无线网卡来操作.
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); //获得第一块网卡的GUID
LocalFree(IntfsTable.pIntfs);
return TRUE;
}
(2)GetWirelessCardInfo
获取到了系统可用的无线网卡后,我们就可以利用它的 GUID 号得到该无线网卡的信息以及该无线网卡扫描到的 WIFI 网关信息。
BOOL GetWirelessCardInfo(PTCHAR pCard, PINTF_ENTRY_EX pIntf, PDWORD pOutFlags) //pCard: 无线网卡 GUID
{ //pIntf: 无线网卡配置信息结果体;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;
}
(3)IsAssociated
我们可以通过无线网卡的状态来判断当前无线网卡是否已经和无线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;
}
}
(4)GetWirelseeListSSID
获取了无线网卡的信息后,可以通过无线网卡枚举出当前所有可用的无线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;
// 枚举所有无线AP
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];
// 将 SSID 的 ASCII 码转化成字符串
PrintSSID(&rdBuffer, tSsid);
if (hListCtlWnd)
{
if (ListBox_FindString(hListCtlWnd, 0, tSsid) == LB_ERR) //显示可用AP的SSID
{
ListBox_AddString(hListCtlWnd, tSsid);
}
}
}
}
}
(5)WirelessConnect
连接到指定的无线AP。
BOOL WirelessConnect(PTCHAR pCard, PTCHAR pSSID, BOOL bAdhoc, ULONG ulPrivacy, NDIS_802_11_AUTHENTICATION_MODE ndisMode, int iKeyIndex, PTCHAR pKey, int iEapType)
//pCard: 无线网卡 GUID;pSSID: 无线AP SSID;bAdhoc: 是否点对点的 WIFI 连接;ulPrivacy: 加密模式(WEP/WPA....) ;
//ndisMode: 认证模式(Open/Share);iKeyIndex: 密钥索引(1-4);pKey: 密码;iEapType: 802.11 认证模式
{
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);
}
// 连接到指定的无线AP,并将该AP添加到首先无线AP中
AddToPreferredNetworkList(pCard, wzcConfig, pSSID);
}
return bRet;
}
(6)InterpretEncryptionKeyValue,输入的密钥需要通过加密方式进行一定的转化,可以直接查找故该处省略。
通过以上操作,完全可以连接到可用的无线AP了,再加上些适当的UI程序,完全可以用来替代 Windows CE 自带的无线配置程序了。
参考原文:http://hi.baidu.com/coldfrost/blog/item/522dd117f3924a01c83d6d04.html
参考原文:http://www.cnblogs.com/Jade2009/archive/2009/01/04/1368201.html