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. }



  • 相关阅读:
    Hibernate 5.x 生成 SessionFactory 源码跟踪分析
    编译iftop
    Too many open files
    ffmpeg指定网卡
    abrt-hook-ccpp使用CPU太多
    ffplay播放时显示信息的意义
    Windows换行符和Linux换行符的替换
    directshow在WIN10下的一个BUG
    使用mirrordriver截屏
    mac xmind 激活
  • 原文地址:https://www.cnblogs.com/LoongEmbedded/p/5298663.html
Copyright © 2011-2022 走看看