zoukankan      html  css  js  c++  java
  • wince下实现wifi无线网络的连接和配置(WLAN)

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

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

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

    调用WZC函数需要包含的文件和库如下:

    1. #include <eaputil.h>
    2. #include <pm.h>
    3. #include <wzcsapi.h>
    4. #include <iphlpapi.h>
    5. #pragma comment(lib,"Iphlpapi.lib")
    6. #pragma comment(lib,"Wzcsapi.lib")
    7. #pragma comment(lib,"cclib.lib")

    存放SSID的基本信息的数据结构:
    1. /*SSID基本信息*/
    2. typedef struct tag_SsidInfo
    3. {
    4. wstring sSsid;
    5. int nRssi;
    6. NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
    7. ULONG ulPrivacy;
    8. NDIS_802_11_AUTHENTICATION_MODE AuthenticationMode;
    9. int iKeyIndex;
    10. wstring pKey;
    11. int iEapType;
    12. }SsidInfo;

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

    1.取得无线网卡

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

    2.从无线网卡取得无线网络信息
    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(1, (TEXT("Param Error.\n")));
    13. return FALSE;
    14. }
    15. szWiFiCard = pCard;
    16. *pOutFlags = 0;
    17. // 初始化无线网卡信息
    18. ZeroMemory(pIntf, sizeof(INTF_ENTRY_EX));
    19. // 设置 GUID 号
    20. pIntf->wszGuid = szWiFiCard;
    21. // 查询无线网卡信息
    22. DWORD dwStatus = WZCQueryInterfaceEx(NULL, INTF_ALL, pIntf, pOutFlags);
    23. if (dwStatus != ERROR_SUCCESS)
    24. {
    25. //RETAILMSG(1, (TEXT("WZCQueryInterfaceEx() error 0x%08X\n"), dwStatus));
    26. return FALSE;
    27. }
    28. return TRUE;
    29. }

    3.解析这些信息,得到需要的无线网参数,ssid,信号强度,加密方式等等


    1. void GetWirelseeListSSID(const PRAW_DATA prdBSSIDList,vector<SsidInfo> &SsidList)
    2. {
    3. SsidInfo tempInfo;
    4. WCHAR tSsid[MAX_PATH];
    5. if (prdBSSIDList == NULL || prdBSSIDList->dwDataLen == 0)
    6. {
    7. // RETAILMSG(DBG_MSG, (TEXT("<null> entry.\n")));
    8. return;
    9. }
    10. else
    11. {
    12. PWZC_802_11_CONFIG_LIST pConfigList = (PWZC_802_11_CONFIG_LIST)prdBSSIDList->pData;
    13. //RETAILMSG(DBG_MSG, (TEXT("[%d] entries.\n"), pConfigList->NumberOfItems));
    14. int i;
    15. // 枚举所有无线AP
    16. for (i = 0; i < pConfigList->NumberOfItems; i++)
    17. {
    18. PWZC_WLAN_CONFIG pConfig = &(pConfigList->Config[i]);
    19. RAW_DATA rdBuffer;
    20. rdBuffer.dwDataLen = pConfig->Ssid.SsidLength;
    21. rdBuffer.pData = pConfig->Ssid.Ssid;
    22. // 将 SSID 的 ASCII 码转化成字符串
    23. memset(tSsid,0,sizeof(tSsid));
    24. PrintSSID(&rdBuffer, tSsid);
    25. tempInfo.sSsid=wstring(tSsid);
    26. tempInfo.nRssi=(int)pConfig->Rssi;
    27. tempInfo.InfrastructureMode=pConfig->InfrastructureMode;
    28. tempInfo.AuthenticationMode=pConfig->AuthenticationMode;
    29. tempInfo.ulPrivacy=pConfig->Privacy;
    30. if (WifiCallBack)
    31. {
    32. WifiCallBack(tempInfo);
    33. }
    34. SsidList.push_back(tempInfo);
    35. }
    36. }
    37. }
    取得无线网的SSID名称
    1. void PrintSSID
    2. // some RAW_DATA is a SSID, this function is for printing SSID
    3. (
    4. PRAW_DATA prdSSID, // RAW SSID data
    5. WCHAR* tSsid
    6. )
    7. {
    8. if (prdSSID == NULL || prdSSID->dwDataLen == 0)
    9. wprintf(L"<NULL>");
    10. else
    11. {
    12. WCHAR szSsid[33];
    13. MultiByteToWideChar(CP_ACP,0,(LPCSTR)prdSSID->pData,-1,tSsid,MAX_PATH*2);
    14. }
    15. } // PrintSSID()

    4.根据上面得到的信息,加上用户输入的密码,生成的信息交给WINDOWS 的首选网络列表
    1. BOOL 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)
    2. //pCard: 无线网卡 GUID;pSSID: 无线AP SSID;bAdhoc: 是否点对点的 WIFI 连接;ulPrivacy: 加密模式(WEP/WPA....) ;
    3. //ndisMode: 认证模式(Open/Share);iKeyIndex: 密钥索引(1-4);pKey: 密码;iEapType: 802.11 认证模式
    4. {
    5. ResetPreferredList(pCard);
    6. BOOL bRet = FALSE;
    7. if (!pSSID)
    8. {
    9. return FALSE;
    10. }
    11. else
    12. {
    13. WZC_WLAN_CONFIG wzcConfig;
    14. ZeroMemory(&wzcConfig, sizeof(WZC_WLAN_CONFIG));
    15. wzcConfig.Length = sizeof(WZC_WLAN_CONFIG);
    16. wzcConfig.dwCtlFlags = 0;
    17. wzcConfig.Ssid.SsidLength = _tcslen(pSSID);
    18. for (UINT i = 0; i < wzcConfig.Ssid.SsidLength; i++)
    19. {
    20. wzcConfig.Ssid.Ssid[i] = (CHAR)pSSID[i];
    21. }
    22. wzcConfig.InfrastructureMode = infr;
    23. wzcConfig.AuthenticationMode = ndisMode;
    24. wzcConfig.Privacy = ulPrivacy;
    25. if (pKey == NULL || _tcslen(pKey) == 0)
    26. {
    27. // 对密钥进行转换
    28. bRet = InterpretEncryptionKeyValue(wzcConfig, 0, NULL, TRUE);
    29. wzcConfig.EapolParams.dwEapType = iEapType;
    30. wzcConfig.EapolParams.dwEapType =EAP_TYPE_TLS;
    31. wzcConfig.EapolParams.dwEapFlags = EAPOL_ENABLED;
    32. wzcConfig.EapolParams.bEnable8021x = TRUE;
    33. wzcConfig.EapolParams.dwAuthDataLen = 0;
    34. wzcConfig.EapolParams.pbAuthData = 0;
    35. }
    36. else
    37. {
    38. // RETAILMSG(DBG_MSG, (TEXT("WirelessConnect iKeyIndex = %d.\n"), iKeyIndex));
    39. bRet = InterpretEncryptionKeyValue(wzcConfig, iKeyIndex, pKey, FALSE);
    40. }
    41. // 连接到指定的无线AP,并将该AP添加到首先无线AP中
    42. AddToPreferredNetworkList(pCard, wzcConfig, pSSID);
    43. }
    44. return bRet;
    45. }

    5.加入WINDOWS的首选网络列表
    1. void AddToPreferredNetworkList
    2. // adding to the [Preferred Networks]
    3. // [Preferred Networks] is a list of SSIDs in preference order.
    4. // WZC continuously scans available SSIDs and attempt to connect to the most preferable SSID.
    5. (
    6. IN WCHAR *szWiFiCard,
    7. IN WZC_WLAN_CONFIG& wzcConfig1,
    8. IN WCHAR *szSsidToConnect
    9. )
    10. {
    11. DWORD dwOutFlags = 0;
    12. INTF_ENTRY_EX Intf;
    13. memset(&Intf, 0x00, sizeof(INTF_ENTRY_EX));
    14. Intf.wszGuid = szWiFiCard;
    15. DWORD dwStatus = WZCQueryInterfaceEx(
    16. NULL,
    17. INTF_ALL,
    18. &Intf,
    19. &dwOutFlags);
    20. if(dwStatus)
    21. {
    22. wprintf(L"WZCQueryInterfaceEx() error dwStatus=0x%0X, dwOutFlags=0x%0X", dwStatus, dwOutFlags);
    23. WZCDeleteIntfObjEx(&Intf);
    24. return;
    25. }
    26. WZC_802_11_CONFIG_LIST *pConfigList = (PWZC_802_11_CONFIG_LIST)Intf.rdStSSIDList.pData;
    27. if(!pConfigList) // empty [Preferred Networks] list case
    28. {
    29. DWORD dwDataLen = sizeof(WZC_802_11_CONFIG_LIST);
    30. WZC_802_11_CONFIG_LIST *pNewConfigList = (WZC_802_11_CONFIG_LIST *)LocalAlloc(LPTR, dwDataLen);
    31. pNewConfigList->NumberOfItems = 1;
    32. pNewConfigList->Index = 0;
    33. memcpy(pNewConfigList->Config, &wzcConfig1, sizeof(wzcConfig1));
    34. Intf.rdStSSIDList.pData = (BYTE*)pNewConfigList;
    35. Intf.rdStSSIDList.dwDataLen = dwDataLen;
    36. }
    37. else
    38. {
    39. ULONG uiNumberOfItems = pConfigList->NumberOfItems;
    40. for(UINT i=0; i<uiNumberOfItems; i++)
    41. {
    42. if(memcmp(&wzcConfig1.Ssid, &pConfigList->Config[i].Ssid, sizeof(NDIS_802_11_SSID)) == 0)
    43. {
    44. wprintf(L"%s is already in the [Preferred Networks] list", szSsidToConnect);
    45. WZCDeleteIntfObjEx(&Intf);
    46. return;
    47. }
    48. }
    49. wprintf(L"SSID List has [%d] entries.\n", uiNumberOfItems);
    50. wprintf(L"adding %s to the top of [Preferred Networks]\n", szSsidToConnect); // this will be the most preferable SSID
    51. DWORD dwDataLen = sizeof(WZC_802_11_CONFIG_LIST) + (uiNumberOfItems+1)*sizeof(WZC_WLAN_CONFIG);
    52. WZC_802_11_CONFIG_LIST *pNewConfigList = (WZC_802_11_CONFIG_LIST *)LocalAlloc(LPTR, dwDataLen);
    53. pNewConfigList->NumberOfItems = uiNumberOfItems + 1;
    54. pNewConfigList->Index = 0;
    55. memcpy(pNewConfigList->Config, &wzcConfig1, sizeof(wzcConfig1));
    56. if(pConfigList->NumberOfItems)
    57. {
    58. pNewConfigList->Index = pConfigList->Index;
    59. memcpy(pNewConfigList->Config+1, pConfigList->Config, (uiNumberOfItems)*sizeof(WZC_WLAN_CONFIG));
    60. LocalFree(pConfigList);
    61. pConfigList = NULL;
    62. }
    63. Intf.rdStSSIDList.pData = (BYTE*)pNewConfigList;
    64. Intf.rdStSSIDList.dwDataLen = dwDataLen;
    65. }
    66. dwStatus = WZCSetInterfaceEx(NULL, INTF_PREFLIST, &Intf, &dwOutFlags);
    67. if(dwStatus)
    68. wprintf(L"WZCSetInterfaceEx() error dwStatus=0x%0X, dwOutFlags=0x%0X", dwStatus, dwOutFlags);
    69. WZCDeleteIntfObjEx(&Intf);
    70. } // AddToPreferredNetworkList()

    6.重置WINDOWS的首选网络列表
    1. void ResetPreferredList
    2. // reset the [Preferred Networks], so wireless will be disconnected
    3. // wzctool -reset cisco1
    4. // reset CISCO1 adapter.
    5. // wzctool -reset
    6. // reset the first wireless adapter found in the system
    7. (
    8. PTCHAR pCard
    9. )
    10. {
    11. WCHAR *szWiFiCard = NULL;
    12. szWiFiCard = pCard;
    13. DWORD dwInFlags = 0;
    14. INTF_ENTRY_EX Intf;
    15. memset(&Intf, 0x00, sizeof(INTF_ENTRY_EX));
    16. Intf.wszGuid = szWiFiCard;
    17. DWORD dwStatus = WZCSetInterfaceEx(NULL, INTF_PREFLIST, &Intf, &dwInFlags);
    18. if(dwStatus)
    19. wprintf(L"WZCSetInterfaceEx() error dwStatus=0x%0X, dwOutFlags=0x%0X", dwStatus, dwInFlags);
    20. else
    21. wprintf(L"now, WZC resets [Preferred Networks]\n");
    22. } // ResetPreferredList()

    7.判断网卡是否连接到了无线网络
    1. BOOL IsWifiConnected(PTCHAR pCard,DWORD * pAdd)
    2. {
    3. BOOL bHasDefaultRoute = FALSE;
    4. ULONG wifiindex =0;
    5. if(NO_ERROR == GetAdapterIndex(pCard,&wifiindex))
    6. {
    7. DWORD dwTableSize = 0;
    8. GetIpAddrTable(NULL, &dwTableSize, FALSE);
    9. if (dwTableSize)
    10. {
    11. MIB_IPADDRTABLE* pft;
    12. pft = (MIB_IPADDRTABLE*)malloc(dwTableSize);
    13. if (pft)
    14. {
    15. if (GetIpAddrTable(pft, &dwTableSize, TRUE) == NO_ERROR)
    16. {
    17. for (ulong nIndex = 0; nIndex < pft->dwNumEntries; nIndex++)
    18. {
    19. if (pft->table[nIndex].dwIndex == wifiindex)
    20. {
    21. printf("get wifi index\n");
    22. printf("wifi add=%x\n",pft->table[nIndex].dwAddr);
    23. if (0!=pft->table[nIndex].dwAddr)
    24. {
    25. bHasDefaultRoute = TRUE;
    26. if (pAdd)
    27. {
    28. *pAdd = pft->table[nIndex].dwAddr;
    29. }
    30. }
    31. break;
    32. }
    33. }
    34. }
    35. free(pft);
    36. }
    37. }
    38. }
    39. return bHasDefaultRoute;
    40. }

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



  • 相关阅读:
    ZeptoLab Code Rush 2015
    UVa 10048 Audiophobia【Floyd】
    POJ 1847 Tram【Floyd】
    UVa 247 Calling Circles【传递闭包】
    UVa 1395 Slim Span【最小生成树】
    HDU 4006 The kth great number【优先队列】
    UVa 674 Coin Change【记忆化搜索】
    UVa 10285 Longest Run on a Snowboard【记忆化搜索】
    【NOIP2016提高A组模拟9.28】求导
    【NOIP2012模拟10.9】电费结算
  • 原文地址:https://www.cnblogs.com/liang123/p/6325648.html
Copyright © 2011-2022 走看看