PDA 같은 경우에는 DeviceIoControl로 OID_802_11_BSSID_LIST를 쿼리를 하면 주변 ap BeaconPeriod, Rssi, Mac , SSID 같은 값을 찾을 수 있음
참조 키워드 : WinceWifi
http://read.pudn.com/downloads74/sourcecode/embed/266030/WifiDemo/Wifi.cpp__.htm
// accesspoints.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <commctrl.h>
#include <stdlib.h>
#include <ntddndis.h>
#include <nuiouser.h>
#include <winioctl.h>
#include "strconv.h"
int _tmain(int argc, _TCHAR* argv[])
{
if (argc < 2)
{
printf("Usage: accesspoints <adapter name> [delay in ms]\n");
printf(" <adapter name> name of the wireless adapter\n");
printf(" [delay in ms] delay between scan and list query\n");
return -1;
}
LPCTSTR pszAdapter = argv[1];
HANDLE hDevice = CreateFile(
NDISUIO_DEVICE_NAME, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
DWORD dwError = GetLastError();
printf("Function \"CreateFile\" failed (0x%08x).\n", dwError);
return -2;
}
DWORD dwBytesReturned = 0;
NDISUIO_QUERY_OID NDISUIOQueryOid = {0};
NDISUIOQueryOid.ptcDeviceName = (PTCHAR) pszAdapter;
NDISUIOQueryOid.Oid = OID_GEN_PHYSICAL_MEDIUM;
if (!DeviceIoControl(
hDevice, IOCTL_NDISUIO_QUERY_OID_VALUE,
&NDISUIOQueryOid, sizeof(NDISUIOQueryOid),
&NDISUIOQueryOid, sizeof(NDISUIOQueryOid),
&dwBytesReturned, NULL))
{
DWORD dwError = GetLastError();
CloseHandle(hDevice);
printf("Function \"DeviceIoControl\" (OID_GEN_PHYSICAL_MEDIUM) failed (0x%08x).\n",
dwError);
return -3;
}
if (*((PNDIS_PHYSICAL_MEDIUM) NDISUIOQueryOid.Data) != NdisPhysicalMediumWirelessLan)
{
CloseHandle(hDevice);
printf("Device \"%s\" is no wireless adapter.\n", CTtoA(pszAdapter));
return -4;
}
CTtoW deviceName(pszAdapter);
if (!DeviceIoControl(
hDevice, IOCTL_NDISUIO_OPEN_DEVICE,
(LPVOID)(LPCWSTR) deviceName,
deviceName.GetLength() * sizeof(WCHAR),
NULL, 0, &dwBytesReturned, NULL))
{
DWORD dwError = GetLastError();
CloseHandle(hDevice);
printf("Function \"DeviceIoControl\" (IOCTL_NDISUIO_OPEN_DEVICE) failed (0x%08x).\n",
dwError);
return -5;
}
NDISUIO_SET_OID NDISUIOSetOid = {0};
NDISUIOSetOid.ptcDeviceName = (PTCHAR) pszAdapter;
NDISUIOSetOid.Oid = OID_802_11_BSSID_LIST_SCAN;
if (!DeviceIoControl(
hDevice, IOCTL_NDISUIO_SET_OID_VALUE,
&NDISUIOSetOid, sizeof(NDISUIOSetOid),
NULL, 0,
&dwBytesReturned, NULL))
{
DWORD dwError = GetLastError();
CloseHandle(hDevice);
printf("Function \"DeviceIoControl\" (OID_802_11_BSSID_LIST_SCAN) failed (0x%08x).\n",
dwError);
return -6;
}
if (argc >= 3)
{
Sleep((DWORD)_ttoi(argv[2]));
}
for (int i = 1;; ++i)
{
const DWORD queryMemSize = sizeof(NDISUIO_QUERY_OID) + sizeof(NDIS_WLAN_BSSID_EX) * i;
PNDISUIO_QUERY_OID pNDISUIOQueryOid = (PNDISUIO_QUERY_OID) malloc(queryMemSize);
pNDISUIOQueryOid->ptcDeviceName = (PTCHAR) pszAdapter;
pNDISUIOQueryOid->Oid = OID_802_11_BSSID_LIST;
if (!DeviceIoControl(
hDevice, IOCTL_NDISUIO_QUERY_OID_VALUE,
pNDISUIOQueryOid, queryMemSize,
pNDISUIOQueryOid, queryMemSize,
&dwBytesReturned, NULL))
{
DWORD dwError = GetLastError();
free(pNDISUIOQueryOid);
if (dwError == ERROR_INVALID_USER_BUFFER ||
dwError == ERROR_INSUFFICIENT_BUFFER)
continue;
CloseHandle(hDevice);
printf("Function \"DeviceIoControl\" (OID_802_11_BSSID_LIST) failed (0x%08x).\n",
dwError);
return -7;
}
PNDIS_802_11_BSSID_LIST_EX pBssidList = (PNDIS_802_11_BSSID_LIST_EX) pNDISUIOQueryOid->Data;
const int accessPointsCnt = (int) pBssidList->NumberOfItems;
printf("Found %d access point(s).\n", accessPointsCnt);
PNDIS_WLAN_BSSID_EX pBssid = pBssidList->Bssid;
for (int j = 0; j < accessPointsCnt; ++j)
{
printf("\n");
printf("MacAddress : %02X-%02X-%02X-%02X-%02X-%02X\n",
pBssid->MacAddress[0], pBssid->MacAddress[1],
pBssid->MacAddress[2], pBssid->MacAddress[3],
pBssid->MacAddress[4], pBssid->MacAddress[5]);
char* pSSID = (char*) malloc(pBssid->Ssid.SsidLength + 1);
memcpy(pSSID, pBssid->Ssid.Ssid, pBssid->Ssid.SsidLength);
pSSID[pBssid->Ssid.SsidLength] = '\0';
printf("Ssid : %s\n", pSSID);
free(pSSID);
printf("Privacy : %s\n", pBssid->Privacy ? "Yes" : "No");
printf("Rssi : %ld dBm\n", pBssid->Rssi);
printf("NetworkTypeInUse : %s\n",
pBssid->NetworkTypeInUse == Ndis802_11FH ? "Ndis802_11FH" :
pBssid->NetworkTypeInUse == Ndis802_11DS ? "Ndis802_11DS" :
"<unknown>");
printf("BeaconPeriod : %lu Kusec\n", pBssid->Configuration.BeaconPeriod);
printf("ATIMWindow : %lu Kusec\n", pBssid->Configuration.ATIMWindow);
if (pBssid->NetworkTypeInUse == Ndis802_11DS)
{
printf("DSConfig : %lu kHz\n", pBssid->Configuration.DSConfig);
}
else if (pBssid->NetworkTypeInUse == Ndis802_11FH)
{
printf("HopPattern : %lu\n", pBssid->Configuration.FHConfig.HopPattern);
printf("HopSet : %lu\n", pBssid->Configuration.FHConfig.HopSet);
printf("DwellTime : %lu Kusec\n", pBssid->Configuration.FHConfig.DwellTime);
}
printf("InfrastructureMode: %s\n",
pBssid->InfrastructureMode == Ndis802_11IBSS ? "Ndis802_11IBSS" :
pBssid->InfrastructureMode == Ndis802_11Infrastructure ? "Ndis802_11Infrastructure" :
pBssid->InfrastructureMode == Ndis802_11AutoUnknown ? "Ndis802_11AutoUnknown" :
"<unknown>");
printf("SupportedRates : [0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x]\n",
pBssid->SupportedRates[0], pBssid->SupportedRates[1], pBssid->SupportedRates[2],
pBssid->SupportedRates[3], pBssid->SupportedRates[4], pBssid->SupportedRates[5],
pBssid->SupportedRates[6], pBssid->SupportedRates[7]);
printf(" BSSBasicRateSet (Mbps):");
for (int n = 0; n < 8; ++n)
{
if (pBssid->SupportedRates[n] & 0x80)
printf(" %.1f", (pBssid->SupportedRates[n] & 0x7f) * 0.5f);
}
printf("\n");
printf(" Others (Mbps):");
for (int n = 0; n < 8; ++n)
{
if (!(pBssid->SupportedRates[n] & 0x80))
printf(" %.1f", (pBssid->SupportedRates[n] & 0x7f) * 0.5f);
}
printf("\n");
if (pBssid->Length >= sizeof(NDIS_802_11_BSSID_LIST_EX) && pBssid->IELength > 0)
{
printf("IEs : [");
for (ULONG n = 0; n < pBssid->IELength; ++n)
{
printf("0x%02x", pBssid->IEs[n]);
if (n < pBssid->IELength - 1)
printf(", ");
}
printf("]\n");
}
pBssid = (PNDIS_WLAN_BSSID_EX) ((LPBYTE) pBssid + pBssid->Length);
}
free(pNDISUIOQueryOid);
CloseHandle(hDevice);
return accessPointsCnt;
}
}
코드 출처 : http://geekswithblogs.net/dastblog/archive/2006/11/30/100038.aspx
/*
* Tux Droid - Wifi channel retrieving for windows.
* Copyright (C) 2008 C2ME Sa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <winsock2.h>
#define NUMBEROFSSIDS 10
/**
* \name NDIS structures and defines.
* @{
*/
/** Device type physical netcard */
#define FILE_DEVICE_PHYSICAL_NETCARD 23
/** File access type any */
#define FILE_ANY_ACCESS 0
/** File access method out direct */
#define METHOD_OUT_DIRECT 2
/**
* This macro is used to create a unique system I/O control code (IOCTL).
*/
#define CTL_CODE(DeviceType, Function, Method, Access)( \
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
/** NDIS IOCTL */
#define _NDIS_CONTROL_CODE(request, method) \
CTL_CODE(FILE_DEVICE_PHYSICAL_NETCARD, request, method, FILE_ANY_ACCESS)
/** NDIS IOCTL Query global stats */
#define IOCTL_NDIS_QUERY_GLOBAL_STATS _NDIS_CONTROL_CODE(0, METHOD_OUT_DIRECT)
/** NDIS OID code for SSID */
#define OID_802_11_SSID 0x0D010102
/** NDIS OID code for BSSID list */
#define OID_802_11_BSSID_LIST 0x0D010217
/** NDIS OID code for BSSID list scan */
#define OID_802_11_BSSID_LIST_SCAN 0x0D01011A
/**
* \brief This enumerated type holds the network subtype values for the
* physical layer of used with a specific driver.
*/
typedef enum _NDIS_802_11_NETWORK_TYPE
{
Ndis802_11FH, /**< Indicates the physical layer of the frequency
hopping spread-spectrum radio. */
Ndis802_11DS, /**< Indicates the physical layer of the direct
sequencing spread-spectrum radio. */
Ndis802_11NetworkTypeMax /**< Specifies the upper bound. */
} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE;
/**
* \brief This data type is used to provide a received signal strength
* indication (RSSI).
*/
typedef LONG NDIS_802_11_RSSI;
/**
* \brief specifies the frequency-hopping configuration for an
* NDIS_802_11_CONFIGURATION structure.
* \param Length Specifies the length of the NDIS_802_11_CONFIGURATION_FH
* structure in bytes.
* \param HopPattern Specifies the hop pattern used to determine the hop
* sequence. As defined by the 802.11 standard, the layer
* management entity (LME) of the physical layer uses a hop
* pattern to determine the hop sequence.
* \param HopSet Specifies a set of patterns. The LME of the physical layer
* uses these patterns to determine the hop sequence.
* \param DwellTime Specifies the maximum period of time during which the
* transmitter should remain fixed on a channel. This interval
* is described in K탎ec (1024 탎ec).
*/
typedef struct _NDIS_802_11_CONFIGURATION_FH
{
ULONG Length;
ULONG HopPattern;
ULONG HopSet;
ULONG DwellTime;
} NDIS_802_11_CONFIGURATION_FH, *PNDIS_802_11_CONFIGURATION_FH;
/**
* \brief Structure to describe the configuration of a radio.
* \param Length Specifies the length of the NDIS_802_11_CONFIGURATION
* structure in bytes.
* \param BeaconPeriod Specifies the interval between beacon message
* transmissions. This value is specified in K탎ec
* (1024 탎ec).
* \param ATIMWindow Specifies the announcement traffic information message
* (ATIM) window in K탎ec (1024 탎ec). The ATIM window is
* a short time period immediately after the transmission
* of each beacon in an IBSS configuration. During the ATIM
* window, any station can indicate the need to transfer data
* to another station during the following data-transmission
* window.
* \param DSConfig Specifies the frequency of the selected channel in kHz.
* \param FHConfig Specifies the frequency-hopping configuration in an
* NDIS_802_11_CONFIGURATION_FH structure.
*/
typedef struct _NDIS_802_11_CONFIGURATION
{
ULONG Length;
ULONG BeaconPeriod;
ULONG ATIMWindow;
ULONG DSConfig;
NDIS_802_11_CONFIGURATION_FH FHConfig;
} NDIS_802_11_CONFIGURATION, *PNDIS_802_11_CONFIGURATION;
/**
* \brief This enumerated type holds specific infrastructure values for the
* miniport driver to set in an 802.11 NIC.
*/
typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE
{
Ndis802_11IBSS, /**< Specifies the independent basic service set (IBSS)
mode. This mode is also known as ad hoc mode. */
Ndis802_11Infrastructure, /**< Specifies the infrastructure mode. */
Ndis802_11AutoUnknown, /**< Specifies an automatic mode. In this mode,
the 802.11 NIC can switch between ad hoc and
infrastructure modes as required. */
Ndis802_11InfrastructureMax /**< Specifies the upper bound. */
} NDIS_802_11_NETWORK_INFRASTRUCTURE, *PNDIS_802_11_NETWORK_INFRASTRUCTURE;
/**
* \brief This enumerated type holds the 802.11 authentication mode value to
* invoke Open system or Shared Key authentication services.
*/
typedef enum _NDIS_802_11_AUTHENTICATION_MODE
{
Ndis802_11AuthModeOpen, /**< Specifies 802.11 open authentication mode.
There are no checks when accepting clients
in this mode. */
Ndis802_11AuthModeShared, /**< Specifies 802.11 shared authentication that
uses a pre-shared wired equivalent privacy
(WEP) key. */
Ndis802_11AuthModeAutoSwitch, /**< Specifies auto-switch mode. When using
auto-switch mode, the NIC tries 802.11
shared authentication mode first. If
shared mode fails, the NIC attempts to
use 802.11 open authentication mode. */
Ndis802_11AuthModeMax /**< Defines the upper bound. */
} NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE;
/**
* \brief This data type provides a way to handle the data rates associated
* with 802.11 delivery.
*/
typedef UCHAR NDIS_802_11_RATES[8];
/**
* \brief This data type holds the MAC address of the associated access point.
* The setting is useful when doing a site survey.
*/
typedef UCHAR NDIS_802_11_MAC_ADDRESS[6];
/**
* \brief OID_802_11_SSID uses this structure when it requests a miniport
* driver to set or return the NIC service set identifier (SSID) value.
* \param SsidLength Specifies the length of the Ssid member in octets.
* \param Ssid Specifies the SSID. An empty string (that is, a string with the
* first byte set to zero) requests the 802.11 NIC to associate
* with any available SSID.
*/
typedef struct _NDIS_802_11_SSID
{
ULONG SsidLength;
UCHAR Ssid[32];
} NDIS_802_11_SSID, *PNDIS_802_11_SSID;
/**
* \brief This structure contains an array of Basic Service Set (BSS) data used
* by NDIS_802_11_BSSID_LIST.
* \param Length Specifies the length of the NDIS_WLAN_BSSID structure.
* \param MacAddress Specifies a media access control (MAC) address. Each
* access point has a unique MAC address that is the same
* as the BSSID.
* \param Reserved Do not use. This member maintains the DWORD alignment of the
* structure.
* \param Ssid Specifies an SSID as defined in the NDIS_802_11_SSID structure.
* \param Privacy Specifies a WEP encryption requirement.
* \param Rssi Specifies the Received Signal Strength Indication (RSSI) in dBm.
* \param NetworkTypeInUse Specifies the network type as defined in the
* NDIS_802_11_NETWORK_TYPE enumeration.
* \param Configuration Specifies the radio parameter configuration as defined
* in the NDIS_802_11_CONFIGURATION structure.
* \param InfrastructureMode Specifies the infrastructure mode as defined in
* the NDIS_802_11_NETWORK_INFRASTRUCTURE
* enumeration.
* \param SupportedRates Specifies a set of supported rates defined in an
* NDIS_802_11_RATES array.
*/
typedef struct _NDIS_WLAN_BSSID
{
ULONG Length;
NDIS_802_11_MAC_ADDRESS MacAddress;
UCHAR Reserved[2];
NDIS_802_11_SSID Ssid;
ULONG Privacy;
NDIS_802_11_RSSI Rssi;
NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
NDIS_802_11_CONFIGURATION Configuration;
NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
NDIS_802_11_RATES SupportedRates;
} NDIS_WLAN_BSSID, *PNDIS_WLAN_BSSID;
/**
* \brief Structure used by OID_802_11_BSSID_LIST to request that a miniport
* driver return a list containing all basic service set identifiers
* (BSSIDs) and their attributes, as listed in the 802.11 NIC database.
* \param NumberOfItems Specifies the number of items contained in the Bssid
* array. This array must contain at least one item.
* \param Bssid Specifies an array of NDIS_WLAN_BSSID structures.
*/
typedef struct _NDIS_802_11_BSSID_LIST
{
ULONG NumberOfItems;
NDIS_WLAN_BSSID Bssid[1];
} NDIS_802_11_BSSID_LIST, *PNDIS_802_11_BSSID_LIST;
/** @} */
/** Static adaptors list for XP mode */
static int _adaptators_list[20];
/** Static adaptors list size for XP mode */
static int _adaptators_count = 0;
/**
* \brief Retrieve a key value from the registry.
* \param hKey HKEY.
* \param szPath Entry path.
* \param szKey Key name.
* \param szBuffer Buffer which will contains the key value.
* \param dwSize Buffer value size.
* \return The success of the key reading.
*/
static bool
registry_get_keyvalue(HKEY hKey, char *szPath, char *szKey, char *szBuffer,
DWORD dwSize)
{
HKEY rk = NULL;
if (RegOpenKeyEx(hKey, szPath, 0, KEY_READ, &rk) != ERROR_SUCCESS)
{
return false;
}
if (RegQueryValueEx(rk,
szKey,
NULL,
NULL,
(unsigned char *)szBuffer,
&dwSize) != ERROR_SUCCESS)
{
return false;
}
RegCloseKey(rk);
return true;
}
/**
* \brief Retrieve the adaptators index in an internal list.
*/
static void
retrieve_network_adaptators(void)
{
char szKey[128];
DWORD dwSize = 256;
HKEY rk = NULL;
int i = 0;
_adaptators_count = 0;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards",
0,
KEY_READ,
&rk) == ERROR_SUCCESS)
{
while (RegEnumKeyEx(rk,
i,
szKey,
&dwSize,
NULL,
NULL,
NULL,
NULL) == ERROR_SUCCESS)
{
_adaptators_list[_adaptators_count] = atoi(szKey);
_adaptators_count++;
dwSize = 256;
i++;
}
RegCloseKey(rk);
}
}
/**
* \brief Open a network adaptator.
* \param szAdapterName Adaptator service name.
* \return The adaptator handle.
*/
static HANDLE
open_adaptator(char *szAdapterName)
{
HANDLE hAdapter;
char szAdapter[MAX_PATH];
_snprintf(szAdapter, sizeof(szAdapter) - 1, "\\\\.\\%s", szAdapterName);
hAdapter = CreateFile(szAdapter,
GENERIC_READ,
FILE_SHARE_READ |
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
return hAdapter;
}
/**
* \brief Get the used channel in an adaptator.
* \param hAdapter Adaptator handle.
* \param requested_SSID SSID that you want in priority.
* \return The channel number or -1 if fail.
*/
static int
get_channel_from_adaptator(HANDLE hAdapter, char *requested_SSID)
{
ULONG dwBytes, dwOIDCode;
int i;
NDIS_802_11_BSSID_LIST *pList;
NDIS_802_11_SSID pBSsid;
int _channel = -1;
int _bestRssi = -200;
/* If no SSID specified then attempt to retrieve the current
* used SSID */
if (strcmp("", requested_SSID) == 0)
{
/* Zerofill the SSID structure */
memset(&pBSsid, 0, sizeof(NDIS_802_11_SSID));
/* Set OID code to SSID request */
dwOIDCode = OID_802_11_SSID;
/* Used SSID request */
DeviceIoControl(hAdapter,
IOCTL_NDIS_QUERY_GLOBAL_STATS,
&dwOIDCode,
sizeof(dwOIDCode),
&pBSsid,
sizeof(pBSsid),
&dwBytes,
NULL);
/* Set the prior SSID with the one used by the adaptator.
* If no SSID found the value is "" */
requested_SSID = pBSsid.Ssid;
}
/* Memory allocation for the network list */
pList = (NDIS_802_11_BSSID_LIST *)VirtualAlloc(NULL,
sizeof(NDIS_802_11_BSSID_LIST) * NUMBEROFSSIDS,
MEM_RESERVE |
MEM_COMMIT,
PAGE_READWRITE);
if (!pList)
{
/* Memory allocation failed then return -1 */
return _channel;
}
else
{
/* Set OID code to BSSID_LIST_SCAN request */
dwOIDCode = OID_802_11_BSSID_LIST_SCAN;
/* Wifi network scanning */
DeviceIoControl(hAdapter,
IOCTL_NDIS_QUERY_GLOBAL_STATS,
&dwOIDCode,
sizeof(dwOIDCode),
( ULONG *)NULL,
0,
&dwBytes,
NULL);
/* Leave to breath the device ;) */
Sleep(100);
/* Zerofill the BSSID list */
memset(pList, 0, sizeof(NDIS_802_11_BSSID_LIST) * NUMBEROFSSIDS);
/* Set OID code to BSSID_LIST request */
dwOIDCode = OID_802_11_BSSID_LIST;
/* Retrieve the wifi networks from the previous scanning */
if (!DeviceIoControl(hAdapter,
IOCTL_NDIS_QUERY_GLOBAL_STATS,
&dwOIDCode,
sizeof(dwOIDCode),
( ULONG *)pList,
sizeof(NDIS_802_11_BSSID_LIST) * NUMBEROFSSIDS,
&dwBytes,
NULL))
{
/* Scanning failed then return -1 */
return _channel;
}
}
/* Browse the BSSID list */
for (i = 0; i < (int)pList->NumberOfItems; i++)
{
NDIS_WLAN_BSSID *cpSsid = &pList->Bssid[0];
int temp = i;
/* Get the next BSSID structure pointer.
* ( This operation is need because the BSSID structure length
* is not constant )*/
while(temp != 0)
{
cpSsid=(NDIS_WLAN_BSSID *)((char*)cpSsid + cpSsid->Length);
temp--;
}
/* If the SSID of the current BSSID structure is the prior SSID
* then get its channel */
if (strcmp(requested_SSID, cpSsid->Ssid.Ssid) == 0)
{
/* Determine the channel from the radio frequency.
* Channel = (frequency - 2407000) / 5000 */
_channel = (cpSsid->Configuration.DSConfig - 2407000) / 5000;
break;
}
/* Determine the stronger network power to return its channel if
* no prior SSID is defined */
if (cpSsid->Rssi > _bestRssi)
{
_channel = (cpSsid->Configuration.DSConfig - 2407000) / 5000;
_bestRssi = cpSsid->Rssi;
}
}
/* Return the used channel */
return _channel;
}
/**
* \brief Get the currently used wifi channel.
* You can define a prior SSID name in the first argument.
* Return the current used channel or -1.
*/
int get_wifi_channel(char *requested_SSID)
{
int channel = -1;
DWORD dwVersion = 0;
DWORD dwMajorVersion = 0;
/* Get the Windows version. */
dwVersion = GetVersion();
dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
/* If the version is older than vista */
if (dwMajorVersion < 6)
{
char szAdapter[128], szServiceName[128];
HANDLE hAdapter;
int i;
retrieve_network_adaptators();
for (i = 0; i < _adaptators_count; i++)
{
_snprintf(szAdapter, sizeof(szAdapter) - 1,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards\\%d",
_adaptators_list[i]);
registry_get_keyvalue(HKEY_LOCAL_MACHINE,
szAdapter,
"ServiceName",
szServiceName,
sizeof(szServiceName) - 1);
hAdapter = open_adaptator(szServiceName);
if (hAdapter != INVALID_HANDLE_VALUE)
{
channel = get_channel_from_adaptator(hAdapter, requested_SSID);
if (channel != -1)
{
break;
}
}
}
}
/* Version is vista or more recently */
else
{
/*
* This way to retrieve the Wifi channel currently used is a bit tricky.
* Previously, an easiest code was written, but was parsing directly the
* strings.
* The major problem is that netsh return translated strings. So it's
* it's almost impossible to do it working for all languages !
*
* This maner search for string untralsted, like SSID or BSSID, and count
* the lines to retrieve the channel.
*/
FILE *pcmd;
char buff[80];
char connected_SSID[32];
char current_SSID[32];
/* If no SSID specified then attempt to retrieve the current
* used SSID */
if (strcmp("", requested_SSID) == 0)
{
pcmd = popen("netsh wlan show interface", "r");
if (pcmd != NULL)
{
while(fgets(buff, 80, pcmd))
{
/* Parse the string : Be sure to considere the SSID line,
* and not BSSID */
if ((strstr(buff, "SSID") != NULL) &&
(strstr(buff, "BSSID") == NULL))
{
sscanf(strrchr(buff, ':'), ": %s", &connected_SSID[0]);
/* Assign the active SSID */
requested_SSID = connected_SSID;
break;
}
}
fclose(pcmd);
}
}
/* Search the channel */
pcmd = popen("netsh wlan show network mode=BSSID", "r");
if (pcmd != NULL)
{
while(fgets(buff, 80, pcmd))
{
/* Search for the correct SSID */
if ((strstr(buff, "SSID") != NULL) &&
(strstr(buff, "BSSID") == NULL))
{
sscanf(strrchr(buff, ':'), ": %s", ¤t_SSID[0]);
/* If the current scanned SSID is the requested one,
* continue */
if (strcmp(current_SSID,requested_SSID) == 0)
{
break;
}
}
}
while (fgets(buff, 80, pcmd))
{
/* Search for BSSID */
if (strstr(buff, "BSSID") != NULL)
{
/* Dummy reads :
- Signal
- RF type
*/
fgets(buff, 80, pcmd);
fgets(buff, 80, pcmd);
/* Retrive the channel */
fgets(buff, 80, pcmd);
sscanf(strrchr(buff, ':'), ": %d", &channel);
break;
}
}
fclose(pcmd);
}
}
return channel;
}
/**
* \brief Program entry point.
* You can define a prior SSID name in the first argument.
* Return the current used channel or -1.
*/
int main(int argc, char *argv[])
{
char *requested_SSID = "";
/* Set SSID name to search */
if (argc > 1)
{
requested_SSID = argv[1];
}
printf("Wifi channel is : %d\n", get_wifi_channel(requested_SSID));
return get_wifi_channel(requested_SSID);
}
소스 출처 : http://svn.tuxisalive.com/software_suite_v2/software/tux_wifi_channel/