使用WZC函数在WINDOWS CE下搜索连接WIFI的具体实现与源码

在 Windows CE 下自带有无线网卡的配置和连接程序,但是如果系统剪裁掉了资源管理器和任务栏,或者再CE的很多应用中,,是不允许用户回到桌面去调用系统的连接程序的,这篇文章就来谈一下如何用那么可以利用微软自带的WZC函数来重新编写一个独立于系统的WIFI连接程序。

连接WIFI网络有这么几个步骤,第一步,要获取你自己的网卡,调用GetFirstWirelessNetworkCard()来实现。第二步,要获得当前环境中的无线网信息,调用GetWirelessCardInfo来取得这些信息,调用GetWirelseeListSSID来解析这些信息,接下来把取得的无线网SSID和自己输入的密码用AddToPreferredNetworkList()传到WINDOWS的首选无线网列表中,windows就会自动连接这个无线网络。

下面是一整套通过WZC函数连接无线网的程序,我自己测试后保证可以运行,如有需要全部源码或者动态库文件的,请留言或者留下邮箱

最近测试下面的代码时,发现连接没有密码的AP是会连接不上。已经修改。

调用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")

存放SSID的基本信息的数据结构

/*SSID基本信息*/ typedef struct tag_SsidInfo {wstring sSsid;int nRssi;NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;ULONG ulPrivacy;NDIS_802_11_AUTHENTICATION_MODE AuthenticationMode;int iKeyIndex;wstring pKey;int iEapType; }SsidInfo;

接下来看关键函数的具体实现:

1.取得无线网卡

BOOL Wifioption::GetFirstWirelessCard(PTCHAR pCard) {WifiCallBack=NULL;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(1, (TEXT("WZCEnumInterfaces() error 0x%08X\n"),dwStatus));return FALSE;}// 判断无线网卡的数量,可以根据无线网卡数量来枚举出所有可用的无线网卡if (!IntfsTable.dwNumIntfs){RETAILMSG(1, (TEXT("System has no wireless card.\n")));return FALSE;}_tcscpy(pCard, IntfsTable.pIntfs[0].wszGuid);LocalFree(IntfsTable.pIntfs);return TRUE; } 2.从无线网卡取得无线网络信息////////////////////////////////////////////////////////////////////////// // pCard: 无线网卡 GUID // pIntf: 无线网卡配置信息结果体 // pOutFlags: 网卡配置信息掩码标志 ////////////////////////////////////////////////////////////////////////// BOOL Wifioption::GetWirelessCardInfo(PTCHAR pCard, PINTF_ENTRY_EX pIntf, PDWORD pOutFlags) {TCHAR *szWiFiCard = NULL;// 参数校验if (!pCard || !pIntf || !pOutFlags){//RETAILMSG(1, (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(1, (TEXT("WZCQueryInterfaceEx() error 0x%08X\n"), dwStatus));return FALSE;}return TRUE; } 3.解析这些信息,得到需要的无线网参数,ssid,信号强度,加密方式等等void Wifioption::GetWirelseeListSSID(const PRAW_DATA prdBSSIDList,vector<SsidInfo> &SsidList){SsidInfo tempInfo;WCHAR tSsid[MAX_PATH];if (prdBSSIDList == NULL || prdBSSIDList->dwDataLen == 0){//RETAILMSG(DBG_MSG, (TEXT("<null> entry.\n")));return;}else{PWZC_802_11_CONFIG_LIST pConfigList = (PWZC_802_11_CONFIG_LIST)prdBSSIDList->pData;//RETAILMSG(DBG_MSG, (TEXT("[%d] entries.\n"), pConfigList->NumberOfItems));int i;// 枚举所有无线APfor (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;// 将 SSID 的 ASCII 码转化成字符串memset(tSsid,0,sizeof(tSsid));PrintSSID(&rdBuffer, tSsid);tempInfo.sSsid=wstring(tSsid);tempInfo.nRssi=(int)pConfig->Rssi;tempInfo.InfrastructureMode=pConfig->InfrastructureMode;tempInfo.AuthenticationMode=pConfig->AuthenticationMode;tempInfo.ulPrivacy=pConfig->Privacy;if (WifiCallBack){WifiCallBack(tempInfo);}SsidList.push_back(tempInfo);}}}void Wifioption::PrintSSID// some RAW_DATA is a SSID, this function is for printing SSID( PRAW_DATA prdSSID, // RAW SSID data WCHAR* tSsid ){if (prdSSID == NULL || prdSSID->dwDataLen == 0)wprintf(L"<NULL>");else{WCHAR szSsid[33];MultiByteToWideChar(CP_ACP,0,(LPCSTR)prdSSID->pData,-1,tSsid,MAX_PATH*2);}}//PrintSSID()4.根据上面得到的信息,加上用户输入的密码,生成的信息交给WINDOWS 的首选网络列表BOOL Wifioption::WirelessConnect(PTCHAR pCard, PTCHAR pSSID,NDIS_802_11_NETWORK_INFRASTRUCTURE infr, ULONG ulPrivacy, NDIS_802_11_AUTHENTICATION_MODE ndisMode, PTCHAR pKey,int iKeyIndex, int iEapType) //pCard: 无线网卡 GUID;pSSID: 无线AP SSID;bAdhoc: 是否点对点的 WIFI 连接;ulPrivacy: 加密模式(WEP/WPA….) ; //ndisMode: 认证模式(Open/Share);iKeyIndex: 密钥索引(1-4);pKey: 密码;iEapType: 802.11 认证模式 {ResetPreferredList(pCard);BOOL bRet = FALSE;if (!pSSID){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];}wzcConfig.InfrastructureMode = infr;wzcConfig.AuthenticationMode = ndisMode;wzcConfig.Privacy = ulPrivacy;if (pKey == NULL || _tcslen(pKey) == 0){// 对密钥进行转换/*bRet = InterpretEncryptionKeyValue(wzcConfig, 0, NULL, TRUE);wzcConfig.EapolParams.dwEapType = iEapType;wzcConfig.EapolParams.dwEapType =EAP_TYPE_TLS;wzcConfig.EapolParams.dwEapFlags = EAPOL_ENABLED;wzcConfig.EapolParams.bEnable8021x = TRUE;wzcConfig.EapolParams.dwAuthDataLen = 0;wzcConfig.EapolParams.pbAuthData = 0; */CRICH_MOON 修改于2012年12月14日 bRet = InterpretEncryptionKeyValue(wzcConfig, iKeyIndex, pKey, FALSE); } 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; }取得无线网的SSID名称void Wifioption::PrintSSID// some RAW_DATA is a SSID, this function is for printing SSID( PRAW_DATA prdSSID, // RAW SSID data WCHAR* tSsid ){if (prdSSID == NULL || prdSSID->dwDataLen == 0)wprintf(L"<NULL>");else{WCHAR szSsid[33];MultiByteToWideChar(CP_ACP,0,(LPCSTR)prdSSID->pData,-1,tSsid,MAX_PATH*2);}}//PrintSSID()松树亭亭玉立的耸立在周围小草小花的中间,

使用WZC函数在WINDOWS CE下搜索连接WIFI的具体实现与源码

相关文章:

你感兴趣的文章:

标签云: