WinCE 5.0 WIFI無線LANカードの構成と接続の確立

21436 ワード

From:http://blog.csdn.net/xajhuang/archive/2008/12/02/3419512.aspx
Windows CEでは無線LANカードの設定と接続プログラムを持っていますが、私のシステムは資源管理器とタスクバーを切断してしまいました.自分の持っている無線LANカードの配置プログラムがもう使えなくなり、自力更生を余儀なくされました.
私の環境はS 3 C 2440+WinCE 5.0+VNUWCL 5(威盛無線LANカード)とドライバです.Automatic Cofigration Fnctions APIを使用します.
一、列挙システムで利用可能な無線ネットワークデバイス
      以下の関数は、システム内のすべての利用可能な無線LANカードデバイスのGUIDを挙げてもいいです.簡略化のために、最初のブロックで利用できる無線LANカードを選択して操作します.      
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);

LocalFree(IntfsTable.pIntfs);

return TRUE;
}
codearara{color:black;background-white;line-height:18 px;border:1 px soliid\82824;4 f 81 bd;magin:0;width:atot!impotantntntnt;width:100%;overflow:atot:atot;tet;tet:atot;tet;tet;tet-alt-fttttttttttfrerererererereft;12 ftttttttttttttttttttttttttttttttttttttttttttttttttft;a Sans Mono」、courier、monopace、serif).codeara preライン-height:18 px;padding:0 0 0 0 12 px!impoport;magin:0 em;background-カラー:??bref!impotant).ラインwrap pre{white-space:pre-wrap;white-space;white-space;white-space;white-space;whit;white-space-space;whit;whit;white-space-space-space-space;whit;white;whit;whit;whit;white-space-space-eak:normal).codeara pre.alt{background-カラー:菗f 7 f 7 ff!impotant].codeara.lnum{color=ble 4 f 81 bd;line-height:18 px}
 二、無線ネットワーク情報の取得
        システムが使える無線LANカードを取得したら、そのGUID番号を利用してさらなる操作ができます.まずやるべきことは、無線LANカードの情報と無線LANカードがスキャンしたWIFIゲートウェイの情報を得ることです.
        以下の関数は、無線LANカードおよびスキャンされた無線AP情報を取得することができる.
////////////////////////////////////////////////////////////////////////// 
// pCard: GUID
// pIntf:
// pOutFlags:
//////////////////////////////////////////////////////////////////////////
BOOL GetWirelessCardInfo(PTCHAR pCard, PINTF_ENTRY_EX pIntf, PDWORD 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;
}
codearara{color:black;background-white;line-height:18 px;border:1 px soliid\82824;4 f 81 bd;magin:0;width:atot!impotantntntnt;width:100%;overflow:atot:atot;tet;tet:atot;tet;tet;tet-alt-fttttttttttfrerererererereft;12 ftttttttttttttttttttttttttttttttttttttttttttttttttft;a Sans Mono」、courier、monopace、serif).codeara preライン-height:18 px;padding:0 0 0 0 12 px!impoport;magin:0 em;background-カラー:??bref!impotant).ラインwrap pre{white-space:pre-wrap;white-space;white-space;white-space;white-space;whit;white-space-space;whit;whit;white-space-space-space-space;whit;white;whit;whit;whit;white-space-space-eak:normal).codeara pre.alt{background-カラー:菗f 7 f 7 ff!impotant].codeara.lnum{color=ble 4 f 81 bd;line-height:18 px}
三、接続状態を判断する
        無線LANカードの状態を通じて、現在の無線LANカードが無線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;
}
}
codearara{color:black;background-white;line-height:18 px;border:1 px soliid\82824;4 f 81 bd;magin:0;width:atot!impotantntntnt;width:100%;overflow:atot:atot;tet;tet:atot;tet;tet;tet-alt-fttttttttttfrerererererereft;12 ftttttttttttttttttttttttttttttttttttttttttttttttttft;a Sans Mono」、courier、monopace、serif).codeara preライン-height:18 px;padding:0 0 0 0 12 px!impoport;magin:0 em;background-カラー:??bref!impotant).ラインwrap pre{white-space:pre-wrap;white-space;white-space;white-space;white-space;whit;white-space-space;whit;whit;white-space-space-space-space;whit;white;whit;whit;whit;white-space-space-eak:normal).codeara pre.alt{background-カラー:菗f 7 f 7 ff!impotant].codeara.lnum{color=ble 4 f 81 bd;line-height:18 px}
四、無線AP情報の取得
        無線LANカードの情報を取得すると、現在利用可能な無線APのSSID名や暗号化モードなどすべての利用可能な情報を無線LANカードの枚数で挙げることができます.
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;

//RETAILMSG(DBG_MSG, (TEXT("[%d] entries./n"), pConfigList->NumberOfItems));

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)
{
ListBox_AddString(hListCtlWnd, tSsid);
}
}

//RETAILMSG(DBG_MSG, (TEXT("/n")));
}
}
}
codearara{color:black;background-white;line-height:18 px;border:1 px soliid\82824;4 f 81 bd;magin:0;width:atot!impotantntntnt;width:100%;overflow:atot:atot;tet;tet:atot;tet;tet;tet-alt-fttttttttttfrerererererereft;12 ftttttttttttttttttttttttttttttttttttttttttttttttttft;a Sans Mono」、courier、monopace、serif).codeara preライン-height:18 px;padding:0 0 0 0 12 px!impoport;magin:0 em;background-カラー:??bref!impotant).ラインwrap pre{white-space:pre-wrap;white-space;white-space;white-space;white-space;whit;white-space-space;whit;whit;white-space-space-space-space;whit;white;whit;whit;whit;white-space-space-eak:normal).codeara pre.alt{background-カラー:菗f 7 f 7 ff!impotant].codeara.lnum{color=ble 4 f 81 bd;line-height:18 px}
五、指定の無線APに接続する
////////////////////////////////////////////////////////////////////////// 
// pCard: GUID
// pSSID: AP SSID
// bAdhoc: WIFI
// ulPrivacy: (WEP/WPA....)
// ndisMode: (Open/Share)
// iKeyIndex: (1-4)
// pKey:
// iEapType: 802.11
//////////////////////////////////////////////////////////////////////////
BOOL WirelessConnect(PTCHAR pCard, PTCHAR pSSID, BOOL bAdhoc, ULONG ulPrivacy, NDIS_802_11_AUTHENTICATION_MODE ndisMode, int iKeyIndex, PTCHAR pKey, int iEapType)
{
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;
}
codearara{color:black;background-white;line-height:18 px;border:1 px soliid\82824;4 f 81 bd;magin:0;width:atot!impotantntntnt;width:100%;overflow:atot:atot;tet;tet:atot;tet;tet;tet-alt-fttttttttttfrerererererereft;12 ftttttttttttttttttttttttttttttttttttttttttttttttttft;a Sans Mono」、courier、monopace、serif).codeara preライン-height:18 px;padding:0 0 0 0 12 px!impoport;magin:0 em;background-カラー:??bref!impotant).ラインwrap pre{white-space:pre-wrap;white-space;white-space;white-space;white-space;whit;white-space-space;whit;whit;white-space-space-space-space;whit;white;whit;whit;whit;white-space-space-eak:normal).codeara pre.alt{background-カラー:菗f 7 f 7 ff!impotant].codeara.lnum{color=ble 4 f 81 bd;line-height:18 px}
六、鍵の変換
        入力された鍵は暗号化によって一定の変換が必要です.以下の関数で変更が可能です.
static void 
EncryptWepKMaterial(IN OUT WZC_WLAN_CONFIG* pwzcConfig) 
{
BYTE chFakeKeyMaterial[] = { 0x56, 0x09, 0x08, 0x98, 0x4D, 0x08, 0x11, 0x66, 0x42, 0x03, 0x01, 0x67, 0x66 };
for (int i = 0; i < WZCCTL_MAX_WEPK_MATERIAL; i++)
pwzcConfig->KeyMaterial[i] ^= chFakeKeyMaterial[(7*i)%13];
}

BOOL InterpretEncryptionKeyValue(IN OUT WZC_WLAN_CONFIG& wzcConfig, IN int iKeyIndex, IN PTCHAR pKey, IN BOOL bNeed8021X)
{
if (wzcConfig.Privacy == Ndis802_11WEPEnabled)
{
if (!bNeed8021X && pKey)
{
wzcConfig.KeyIndex = iKeyIndex;
wzcConfig.KeyLength = _tcslen(pKey);
if ((wzcConfig.KeyLength == 5) || (wzcConfig.KeyLength == 13))
{
for (UINT i=0; i<wzcConfig.KeyLength; i++)
wzcConfig.KeyMaterial[i] = (UCHAR)pKey[i];
}
else
{
if ((pKey[0] != TEXT('0' )) || (pKey[1] != TEXT('x' )))
{
RETAILMSG(DBG_MSG, (TEXT("Invalid key value./n" )));
return FALSE;
}

pKey += 2;
wzcConfig.KeyLength = wcslen(pKey);

if ((wzcConfig.KeyLength != 10) && (wzcConfig.KeyLength != 26))
{
RETAILMSG(DBG_MSG, (TEXT("Invalid key value./n" )));
return FALSE;
}

wzcConfig.KeyLength >>= 1;

for (UINT i=0; i<wzcConfig.KeyLength; i++)
{
wzcConfig.KeyMaterial[i] = (HEX(pKey[2 * i]) << 4) | HEX(pKey[2 * i + 1]);
}
}

EncryptWepKMaterial(&wzcConfig);

wzcConfig.dwCtlFlags |= WZCCTL_WEPK_PRESENT;
}
}
else if (wzcConfig.Privacy == Ndis802_11Encryption2Enabled
|| wzcConfig.Privacy == Ndis802_11Encryption3Enabled)
{
if (!bNeed8021X)
{
wzcConfig.KeyLength = wcslen(pKey);

if ((wzcConfig.KeyLength < 8) || (wzcConfig.KeyLength > 63))
{
RETAILMSG(DBG_MSG, (TEXT("WPA-PSK/TKIP key should be 8-63 char long string./n" )));
return FALSE;
}

char szEncryptionKeyValue8[64]; // longest key is 63
memset(szEncryptionKeyValue8, 0, sizeof (szEncryptionKeyValue8));

WideCharToMultiByte(CP_ACP,
0,
pKey,
wzcConfig.KeyLength + 1,
szEncryptionKeyValue8,
wzcConfig.KeyLength + 1,

NULL,
NULL);
WZCPassword2Key(&wzcConfig, szEncryptionKeyValue8);
EncryptWepKMaterial(&wzcConfig);

wzcConfig.dwCtlFlags |= WZCCTL_WEPK_XFORMAT
| WZCCTL_WEPK_PRESENT
| WZCCTL_ONEX_ENABLED;
}

wzcConfig.EapolParams.dwEapFlags = EAPOL_ENABLED;
wzcConfig.EapolParams.dwEapType = DEFAULT_EAP_TYPE;
wzcConfig.EapolParams.bEnable8021x = TRUE;
wzcConfig.WPAMCastCipher = Ndis802_11Encryption2Enabled;
}

return TRUE;
}
codearara{color:black;background-white;line-height:18 px;border:1 px soliid\82824;4 f 81 bd;magin:0;width:atot!impotantntntnt;width:100%;overflow:atot:atot;tet;tet:atot;tet;tet;tet-alt-fttttttttttfrerererererereft;12 ftttttttttttttttttttttttttttttttttttttttttttttttttft;a Sans Mono」、courier、monopace、serif).codeara preライン-height:18 px;padding:0 0 0 0 12 px!impoport;magin:0 em;background-カラー:??bref!impotant).ラインwrap pre{white-space:pre-wrap;white-space;white-space;white-space;white-space;whit;white-space-space;whit;whit;white-space-space-space-space;whit;white;whit;whit;whit;white-space-space-eak:normal).codeara pre.alt{background-カラー:菗f 7 f 7 ff!impotant].codeara.lnum{color=ble 4 f 81 bd;line-height:18 px}
      以上の操作によって、利用可能な無線APに接続できます.また、適切なUIプログラムを加えて、Windows CEが持っている無線配置プログラムに取って代わることができます.また接続中に簡単で完璧なテストプログラムが置いてあります.皆さんは見てから、無線LANカードの操作方法が分かります.
http://download.csdn.net/source/927575