在WINCE 6.0平台上进行测试,WINCE4.0以上平台亦支持,扩展API需WINCE 6.0以上平台
在WINCE上获取无线网卡信息,主要分为两种方式一种是通过NIC_STATISTICS结构体从网卡驱动中获取相关信息,另一种是通过WINCE提供的Wireless Automatic Configuration driver (WZCSVC)去查询。
一、DeviceIoControl方式
typedef struct {
ULONG Size;
PTCHAR ptcDeviceName;
ULONG DeviceState;
ULONG MediaType;
ULONG MediaState;
ULONG PhysicalMediaType;
ULONG LinkSpeed;
ULONGLONG PacketsSent;
ULONGLONG PacketsReceived;
ULONG InitTime;
ULONG ConnectTime;
ULONGLONG BytesSent;
ULONGLONG BytesReceived;
ULONGLONG DirectedBytesReceived;
ULONGLONG DirectedPacketsReceived;
ULONG PacketsReceiveErrors;
ULONG PacketsSendErrors;
ULONG ResetCount;
ULONG MediaSenseConnectCount;
ULONG MediaSenseDisconnectCount;
} NIC_STATISTICS, *PNIC_STATISTICS;
-
Size
-
NIC_STATISTICS结构体大小.
-
ptcDeviceName
-
查询设备名.
DeviceState
-
设备状态,同查询OID_GEN_MEDIA_IN_USE结果.
State
Value
DEVICE_STATE_CONNECTED
1
DEVICE_STATE_DISCONNECTED
0
- MediaType MediaType的有效值。
-
NdisMediumxxx
Description
NdisMedium802_3
Specifies an Ethernet (802.3) medium.
NdisMedium802_5
Not supported for NDISUIO. Specifies a Token Ring (802.5) medium.
NdisMediumWan
Not supported for NDISUIO. Specifies a WAN.
NdisMediumDix
Not supported for NDISUIO. Specifies DEC/Intel/Xerox (DIX) Ethernet medium.
NdisMediumWirelessWan
Not supported for NDISUIO. Specifies various types of wireless medium.
NdisMediumIrda
Not supported for NDISUIO. Specifies an infrared (IrDA) medium.
NdisMediumBpc
Not supported for NDISUIO. Specifies a broadcast architecture medium.
NdisMediumCoWan
Not supported for NDISUIO. Specifies a connection-oriented WAN medium, which is not supported.
NdisMedium1394
Not supported for NDISUIO. Specifies an IEEE 1394 medium.
NdisMediumMax
Not supported for NDISUIO. Specifies an upper bound.
- MediaState
-
网络适配器的连接状态,同查询OID_GEN_MEDIA_CONNECT_STATUS结果。.
Media state
Value
MEDIA_STATE_CONNECTED
0
MEDIA_STATE_DISCONNECTED
1
MEDIA_STATE_UNKNOWN
-1
- PhysicalMediaType
网络适配器支持的媒介,同查询OID_GEN_PHYSICAL_MEDIUM结果。
LinkSpeed
网络适配器的速度上限,同查询OID_GEN_LINK_SPEED结果。
-
PacketsSent
-
发送包数量。
-
PacketsReceived
-
接收包数量。
-
InitTime
-
驱动初始化时间,单位毫秒。
-
ConnectTime
-
连接网络时间,单位秒。
-
BytesSent
-
发送字节数。
-
BytesReceived
-
接收字节数。
-
DirectedBytesReceived
-
直接接收字节数。
-
DirectedPacketsReceived
-
直接接收包的数量。
-
PacketsReceiveErrors
-
接收包错误数。
-
PacketsSendErrors
-
发送包错误数。
-
ResetCount
-
返回端口适配器重置次数。
-
MediaSenseConnectCount
-
返回端口适配器状连接次数。
-
MediaSenseDisconnectCount
-
返回端口适配器断开连接次数。
#include <windows.h>
#include <commctrl.h>
#include <winioctl.h>
#include <ntddndis.h>
#include <nuiouser.h>
//查询的无线网卡名称
#define NETCARD_NAME _T("VNUWLC41");
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwBufReadSize = 0;
NIC_STATISTICS stNicStatistics = {0};
HANDLE hFile = CreateFile(NDISUIO_DEVICE_NAME,
(GENERIC_READ|GENERIC_WRITE),
(FILE_SHARE_READ|FILE_SHARE_WRITE),
0,
OPEN_EXISTING,
0,
0);
if (hFile != INVALID_HANDLE_VALUE)
{
stNicStatistics.ptcDeviceName = NETCARD_NAME;
BOOL bRetIO = DeviceIoControl(hFile,
IOCTL_NDISUIO_NIC_STATISTICS,
NULL,
0,
&stNicStatistics,
sizeof(NIC_STATISTICS),
&dwBufReadSize,
NULL);
if(bRetIO)
{
printf("Size:%d\
ptcDeviceName:%s\
DeviceState:%d\n\
MediaType:%d\n\
MediaState:%d\n\
PhysicalMediaType:%d\n\
LinkSpeed:%d\n\
PacketsSent:%d\n\
PacketsReceived:%d\n\
InitTime:%d\n\
ConnectTime:%d\n\
BytesSent:%d\n\
BytesReceived:%d\n\
DirectedBytesReceived:%d\n\
DirectedPacketsReceived:%d\n\
PacketsReceiveErrors:%d\n\
PacketsSendErrors:%d\n\
ResetCount:%d\n\
MediaSenseConnectCount:%d\n\
MediaSenseDisconnectCount:%d\n",
stNicStatistics.Size, //结构体大小
stNicStatistics.ptcDeviceName, //设备名
stNicStatistics.DeviceState, //设备状态
stNicStatistics.MediaType,
stNicStatistics.MediaState, //设备连接网络的状态
stNicStatistics.PhysicalMediaType,
stNicStatistics.LinkSpeed, //速度上线
stNicStatistics.PacketsSent, //发送包数量
stNicStatistics.PacketsReceived, //接收包数量
stNicStatistics.InitTime, //驱动初始化时间
stNicStatistics.ConnectTime, //连接网络时间
stNicStatistics.BytesSent, //发送字节数
stNicStatistics.BytesReceived, //接收字节数
stNicStatistics.DirectedBytesReceived, //直接接收字节数
stNicStatistics.DirectedPacketsReceived, //直接接收包数量
stNicStatistics.PacketsReceiveErrors, //接收包错误数量
stNicStatistics.PacketsSendErrors, //发送包错误数量
stNicStatistics.ResetCount, //重置次数
stNicStatistics.MediaSenseConnectCount, //连接次数
stNicStatistics.MediaSenseDisconnectCount); //断开连接次数
if(MEDIA_STATE_CONNECTED == stNicStatistics.MediaState)
{
printf("WIFI connected!");
}
}
}
getchar();
return 0;
}
二、WZC方式
该方式来自WINCE下wzctool的源码
void
DoQuery
// Query the WiFi card and print out the info available for the interface.
// wzctool -q cisco1
// query cisco1 adapter parameters.
// wzctool -q
// find wireless card, and query for that adapter.
(
IN int argc, // number of args
IN WCHAR* argv[] // arg array
)
{
WCHAR *szWiFiCard = NULL;
if(GetOption(argc, argv, L"q", &szWiFiCard) < 0)
{
GetFirstWirelessNetworkCard();
if(!*g_WirelessCard1) // wifi card not found
return;
szWiFiCard = g_WirelessCard1;
}
INTF_ENTRY_EX Intf;
DWORD dwOutFlags;
memset(&Intf, 0x00, sizeof(INTF_ENTRY_EX));
Intf.wszGuid = szWiFiCard;
DWORD dwStatus = WZCQueryInterfaceEx(
NULL,
INTF_ALL,
&Intf,
&dwOutFlags);
if (dwStatus != ERROR_SUCCESS)
{
wprintf(L"WZCQueryInterfaceEx() error 0x%08X\n", dwStatus);
getchar();
return;
}
wprintf(L"WZCQueryInterfaceEx() for %s\n", szWiFiCard);
wprintf(L"In flags used = [0x%08X]\n", INTF_ALL);
wprintf(L"Returned out flags = [0x%08X]\n", dwOutFlags);
// GUID (in CE, GUID=instance name)
wprintf(L"wzcGuid = [%s]\n", Intf.wszGuid);
// Description
wprintf(L"wzcDescr = [%s]\n", Intf.wszDescr);
// Print BSSID. BSSID is the MAC address of the AP I am connected.
if (dwOutFlags & INTF_BSSID)
{
wprintf(L"BSSID = ");
PrintMacAddress(&Intf.rdBSSID);
PRAW_DATA prdMAC = &Intf.rdBSSID;
if (
prdMAC == NULL ||
(prdMAC->dwDataLen == 0) ||
(prdMAC->dwDataLen != 6) ||
( !prdMAC->pData[0] &&
!prdMAC->pData[1] &&
!prdMAC->pData[2] &&
!prdMAC->pData[3] &&
!prdMAC->pData[4] &&
!prdMAC->pData[5] )
)
wprintf(L" (this wifi card is not associated to any)\n");
else
wprintf(L" (this wifi card is associated state)\n");
}
else
wprintf(L"BSSID = <unknown> (not connected)\n");
// Media Type
if (dwOutFlags & INTF_NDISMEDIA)
wprintf(L"Media Type = [%d]\n", Intf.ulMediaType);
else
wprintf(L"Media Type = <unknown>\n");
// Configuration Mode
if (dwOutFlags & INTF_ALL_FLAGS)
{
wprintf(L"Configuration Mode = [%08X]\n", Intf.dwCtlFlags);
if(Intf.dwCtlFlags & INTFCTL_ENABLED)
wprintf(L" zero conf enabled for this interface\n");
if(Intf.dwCtlFlags & INTFCTL_FALLBACK)
wprintf(L" attempt to connect to visible non-preferred networks also\n");
if(Intf.dwCtlFlags & INTFCTL_OIDSSUPP)
wprintf(L" 802.11 OIDs are supported by the driver/firmware\n");
if(Intf.dwCtlFlags & INTFCTL_VOLATILE)
wprintf(L" the service parameters are volatile\n");
if(Intf.dwCtlFlags & INTFCTL_POLICY)
wprintf(L" the service parameters policy enforced\n");
}
else
wprintf(L"Configuration Mode = <unknown>\n");
// Print Infrastructure Mode
if (dwOutFlags & INTF_INFRAMODE)
{
wprintf(L"Infrastructure Mode = [%d] ", Intf.nInfraMode);
if(Intf.nInfraMode == Ndis802_11IBSS)
wprintf(L"IBSS net (adhoc net)\n");
else if(Intf.nInfraMode == Ndis802_11Infrastructure)
wprintf(L"Infrastructure net (connected to an Access Point)\n");
else
wprintf(L"Ndis802_11AutoUnknown\n");
}
else
wprintf(L"Infrastructure Mode = <unknown>\n");
// Print Authentication Mode
if (dwOutFlags & INTF_AUTHMODE)
{
wprintf(L"Authentication Mode = [%d] ", Intf.nAuthMode);
if((DWORD)Intf.nAuthMode < Ndis802_11AuthModeMax)
wprintf(L"%s\n", g_szAuthenticationMode[Intf.nAuthMode]);
else
wprintf(L"<unknown>\n");
}
else
wprintf(L"Authentication Mode = <unknown>\n");
wprintf(L"rdNicCapabilities = %d bytes\n", Intf.rdNicCapabilities.dwDataLen);
getchar();
if (Intf.rdNicCapabilities.dwDataLen)
{
PINTF_80211_CAPABILITY pCapability = (PINTF_80211_CAPABILITY)Intf.rdNicCapabilities.pData;
DWORD i;
wprintf (L" dwNumOfPMKIDs : [%d]\n", pCapability->dwNumOfPMKIDs);
wprintf (L" dwNumOfAuthEncryptPairs : [%d]\n", pCapability->dwNumOfAuthEncryptPairs);
for (i = 0 ; i < pCapability->dwNumOfAuthEncryptPairs ; i++)
{
wprintf (L" Pair[%d]\n", i+1);
wprintf (L" AuthmodeSupported [%s]\n",
g_szAuthenticationMode[pCapability->AuthEncryptPair[i].AuthModeSupported]);
wprintf (L" EncryptStatusSupported [%s]\n",
g_szcPrivacyMode[pCapability->AuthEncryptPair[i].EncryptStatusSupported]);
}
}
#ifdef UNDER_CE
wprintf(L"rdPMKCache = %u bytes\n", Intf.rdPMKCache.dwDataLen);
if (Intf.rdPMKCache.dwDataLen)
{
PNDIS_802_11_PMKID pCache = (PNDIS_802_11_PMKID)Intf.rdPMKCache.pData;
DWORD i;
wprintf (L" BSSIDInfoCount : [%u]\n", pCache->BSSIDInfoCount);
for (i = 0 ; i < pCache->BSSIDInfoCount; i++)
{
PBYTE pMac = &pCache->BSSIDInfo[i].BSSID[0];
PBYTE pId = &pCache->BSSIDInfo[i].PMKID[0];
wprintf (L" BSSID=%02X%02X%02X%02X%02X%02X PMKID=%02X%02X..%02X%02X\n",
pMac[0], pMac[1], pMac[2], pMac[3], pMac[4], pMac[5],
pId[0], pId[1], pId[14], pId[15]);
}
}
#endif
// Print WEP status
if (dwOutFlags & INTF_WEPSTATUS)
{
wprintf(L"WEP Status = [%d] ", Intf.nWepStatus);
WCHAR* szWepStatus[] =
{
L"Ndis802_11WEPEnabled",
L"Ndis802_11WEPDisabled",
L"Ndis802_11WEPKeyAbsent",
L"Ndis802_11WEPNotSupported"
};
if(Intf.nWepStatus < 4)
wprintf(L"%s\n", szWepStatus[Intf.nWepStatus]);
else
wprintf(L"<unknown value>\n");
}
else
wprintf(L"WEP Status = <unknown>\n");
// Print SSID status
if (dwOutFlags & INTF_SSID)
{
wprintf(L"SSID = ");
PrintSSID(&Intf.rdSSID);
wprintf(L"\n");
}
else
wprintf(L"SSID = <unknown>\n");
if (dwOutFlags & INTF_CAPABILITIES)
{
wprintf(L"Capabilities =\n");
if(Intf.dwCapabilities & INTFCAP_SSN)
wprintf(L" WPA/TKIP capable\n");
if(Intf.dwCapabilities & INTFCAP_80211I)
wprintf(L" WPA2/AES capable\n");
}
wprintf(L"\n");
wprintf(L"[Available Networks] SSID List ");
PrintConfigList(&Intf.rdBSSIDList);
wprintf(L"\n");
wprintf(L"[Preferred Networks] SSID List ");
PrintConfigList(&Intf.rdStSSIDList);
wprintf(L"\n");
wprintf(L"rdCtrlData length = %d bytes\n", Intf.rdCtrlData.dwDataLen);
//
// Free memory block that WZC allocated.
// WZCQueryInterfaceEx() always should be followed by this WZCDeleteIntfObj().
// Note that the wzcGuid is ** NOT ** freed by WZCDeleteIntfObj()
//
WZCDeleteIntfObjEx(&Intf);
//
// Get context information.
//
wprintf(L"\n");
wprintf(L"parameter setting in Zero Config\n");
WZC_CONTEXT WzcContext;
dwStatus = WZCQueryContext(NULL, 0x00, &WzcContext, NULL);
if (dwStatus != ERROR_SUCCESS)
wprintf(L"!!! Failed WZCQueryContext. Err = [0x%08X] !!!\n", dwStatus);
else
{
wprintf(L"tmTr = %d mili-seconds (Scan time out)\n", WzcContext.tmTr);
wprintf(L"tmTp = %d mili-seconds (Association time out)\n", WzcContext.tmTp);
wprintf(L"tmTc = %d mili-seconds (Periodic scan when connected)\n", WzcContext.tmTc);
wprintf(L"tmTf = %d mili-seconds (Periodic scan when disconnected)\n", WzcContext.tmTf);
}
} // DoQuery()
三、获取无线信号强度
参照WINCE无线网卡操作界面NETUI中获取无线的方法
#include <windows.h>
#include <commctrl.h>
#include <winioctl.h>
#include <ntddndis.h>
#include <nuiouser.h>
#define NETCARD_NAME _T("TIWLNAPI1")
int _tmain(int argc, _TCHAR* argv[])
{
NATIVEWIFI_STATISTICS NwifiStatistics = {0};
DWORD dwBytesWritten = 0;
DWORD dwBytesReturned = 0;
BOOL fRetVal = FALSE;
PNDISUIO_QUERY_OID pQueryOid = NULL;
UCHAR QueryBuffer[sizeof(NDISUIO_QUERY_OID)+sizeof(DWORD)];
HANDLE hFile = CreateFile(NDISUIO_DEVICE_NAME,
(GENERIC_READ|GENERIC_WRITE),
(FILE_SHARE_READ|FILE_SHARE_WRITE),
0,
OPEN_EXISTING,
0,
0);
NwifiStatistics.ptcDeviceName = NETCARD_NAME;
while (hFile != INVALID_HANDLE_VALUE)
{
pQueryOid = (PNDISUIO_QUERY_OID)&QueryBuffer[0];
pQueryOid->ptcDeviceName = NETCARD_NAME;
pQueryOid->Oid = OID_802_11_RSSI;
fRetVal = DeviceIoControl(
hFile,
IOCTL_NDISUIO_QUERY_OID_VALUE,
(LPVOID) pQueryOid,
sizeof(NDISUIO_QUERY_OID) + sizeof(DWORD),
(LPVOID) pQueryOid,
sizeof(NDISUIO_QUERY_OID) + sizeof(DWORD),
&dwBytesReturned,
NULL);
if(fRetVal == TRUE)
{
// example.
// < -90 : No Signal
// < -81 : Very Low
// < -71 : Low
// < -67 : Good
// < -57 : Very Good
// ... : Excellent
printf("Wifi signal strength:%d\n", *(DWORD *)&pQueryOid->Data);
}
else
{
printf("ERROR:%d\n", GetLastError());
}
Sleep(500);
}
return 0;
}
PS:WINCE连接网络后,信号强度不在变化,即使信号强度变化也是由于短暂的断开并重新连接操作。
WZCTOOL源码下载:
http://download.csdn.net/detail/berial_sin/6487227