無線LAN強度の取得

CEネタのついでに無線LAN強度の取得。
CE4.0以降(NDIS5.1対応)ならNIDS経由でいけます。


まずはinclude

#include <winioctl.h>
#include <ntddndis.h>
#include <nuiouser.h>

NDISオープン

HANDLE hNdis = ::CreateFile( NDISUIO_DEVICE_NAME, GENERIC_ALL, 0, NULL, OPEN_EXISTING,
                             FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
                             (HANDLE)INVALID_HANDLE_VALUE );

デバイス名取得

UCHAR                  cbQueryBuffer[ 1024 ];
PNDISUIO_QUERY_BINDING pQueryBinding;
DWORD                  dwBytesReturned = 0;

pQueryBinding = (PNDISUIO_QUERY_BINDING)&cbQueryBuffer[ 0 ];
pQueryBinding->BindingIndex = 0;

if ( ::DeviceIoControl( hNdis,
                        IOCTL_NDISUIO_QUERY_BINDING,
                        (LPVOID)&cbQueryBuffer[ 0 ],
                        sizeof(NDISUIO_QUERY_BINDING),
                        (LPVOID)&cbQueryBuffer[ 0 ],
                        sizeof(cbQueryBuffer),
                        &dwBytesReturned,
                        NULL ) == TRUE )
{
    TCHAR* pDeviceName = (TCHAR*)( cbQueryBuffer + pQueryBinding->DeviceNameOffset );
}

メディア接続検知

NIC_STATISTICS nicStatistics = { 0 };
DWORD          dwBytesReturned = 0;
BOOL bConnected = FALSE;

nicStatistics.ptcDeviceName = pDeviceName;

if ( ::DeviceIoControl( hNdis,
                        IOCTL_NDISUIO_NIC_STATISTICS,
                        NULL,
                        0,
                        &nicStatistics,
                        sizeof(NIC_STATISTICS),
                        &dwBytesReturned,
                        NULL ) == TRUE )
{
    bConnected = ( nicStatistics.MediaState == MEDIA_STATE_CONNECTED );
}

信号強度取得

// example.
// < -90 : No Signal
// < -81 : Very Low
// < -71 : Low
// < -67 : Good
// < -57 : Very Good
// ...   : Excellent

NDISUIO_QUERY_OID ndisQueryOid = { 0 };
DWORD             dwBytesReturned = 0;
int nDb = 0;

ndisQueryOid.Oid = OID_802_11_RSSI;
ndisQueryOid.ptcDeviceName = pDeviceName;

if ( ::DeviceIoControl( hNdis,
                        IOCTL_NDISUIO_QUERY_OID_VALUE,
                        (LPVOID)&ndisQueryOid,
                        sizeof(ndisQueryOid),
                        (LPVOID)&ndisQueryOid,
                        sizeof(ndisQueryOid),
                        &dwBytesReturned,
                        NULL ) == TRUE )
{
    ::CopyMemory( &nDb, &ndisQueryOid.Data[ 0 ], sizeof(ULONG) );
}

その他
OID_802_11_SSID、OID_802_11_BSSID_LIST_SCANとか…。


店舗系のハンディで無線LANを使っているようなシステムの場合、これを使って携帯みたいなアンテナアイコンを表示していたりします(・∀・)