WIFI之四:WINCE 500上WIFI工具的编写

来源:互联网 发布:ubuntu恢复删除的文件 编辑:程序博客网 时间:2024/05/02 02:38
 在 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