在windows ce下wifi连接上无线ap后,如何获取它的ip地址

liuxing320 2010-02-25 09:16:51
在windows ce下wifi能够连接上无线路由器,我这边用的工具是微软提供的wzc工具,但是连接上无线路由后,不知道如何获取它的ip地址。wzc里面的函数也不知道用哪个,通常的做法是wifi设备端发送dhcp包给无线路由器,但是dhcp包不知道如何发送,应该使用哪些api函数?
也是就在这段代码后:
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;
}
二、获取无线网络信息

//////////////////////////////////////////////////////////////////////////
// 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;
}
三、判断连接状态

我们可以通过无线网卡的状态来判断当前无线网卡是否已经和无线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;
}
}
四、获取无线AP信息

获取了无线网卡的信息后,可以通过无线网卡枚举出当前所有可用的无线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;

//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")));
}
}
}
五、连接到指定的无线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;
}
六、密钥转换
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;
}
通过这6个函数连接上无线ap后,不知道如何获取它的IP地址,如果直接用winsock函数来获取IP地址,会得到一串乱码。现在还不明白是不是连接上了已经分配了一个IP地址,还是说一定要发送dhcp包给连接上的这个无线ap来请求IP地址。
...全文
1763 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
dragoniye 2011-11-18
  • 打赏
  • 举报
回复
mark下,lz代码不错
善古 2011-03-30
  • 打赏
  • 举报
回复
大侠你好,请问以上方法,在windowsXP下是否也同样可以使用呢?
[Quote=引用 2 楼 suwyhoho 的回复:]
DWORD GetAdaptersInfo(
PIP_ADAPTER_INFO pAdapterInfo,
PULONG pOutBufLen
);

typedef struct _IP_ADAPTER_INFO {
struct _IP_ADAPTER_INFO* Next;
DWORD ComboIndex;
Char AdapterName[MAX_AD……
[/Quote]
善古 2011-03-30
  • 打赏
  • 举报
回复
请问以上方法,在windowsXP下是否也同样可以使用呢?
chenyqzyf 2011-02-28
  • 打赏
  • 举报
回复
用动态库iphlapi.dll
liuxing320 2010-03-03
  • 打赏
  • 举报
回复
根据1楼和2楼的提示,做了一下尝试:
我发现在Iphlpapi.h中有很多关于网卡信息的函数和ARP发包的函数,1楼和2楼多谢了
在调用DWORD GetAdaptersInfo( PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen );时我们会加入Iphlpapi.h和库文件Iphlpapi.lib;但是我加入了这两个文件后,编译的时候会报错,好像是和wzcsapi.lib冲突了,具体错误如下:
BUILD: [01:0000000076:ERRORE] iphlpapi.lib(iphlpapi.obj) : error LNK2005: DllEntry already defined in wzcsapi.lib(wzcsapi.obj)
这两个库之间存在重叠部分。如果你去掉iphlpapi.lib,那么GetAdaptersInfo函数就无法识别,如果你去掉wzcsapi.lib,则关于wzc自动配置的部分函数就无法识别。请问一下有什么方法可以解决这个问题
suwyhoho 2010-03-01
  • 打赏
  • 举报
回复
DWORD GetAdaptersInfo(
PIP_ADAPTER_INFO pAdapterInfo,
PULONG pOutBufLen
);

typedef struct _IP_ADAPTER_INFO {
struct _IP_ADAPTER_INFO* Next;
DWORD ComboIndex;
Char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];
char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];
UINT AddressLength;
BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];
DWORD Index;
UINT Type;
UINT DhcpEnabled;
PIP_ADDR_STRING CurrentIpAddress;
IP_ADDR_STRING IpAddressList;
IP_ADDR_STRING GatewayList;
IP_ADDR_STRING DhcpServer;
BOOL HaveWins;
IP_ADDR_STRING PrimaryWinsServer;
IP_ADDR_STRING SecondaryWinsServer;
time_t LeaseObtained;
time_t LeaseExpires;
} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;

IP_ADDR_STRING IpAddressList就是当前设备的IP
yzbsd 2010-03-01
  • 打赏
  • 举报
回复
可以尝试读取注册表数据,自动分配以后,注册表里面应该可以找到该信息

19,504

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
  • 嵌入开发(WinCE)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧