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/