汁ごはん このページをアンテナに追加 RSSフィード

2009年01月13日 (火曜日)

アクセスポイント情報の取得

以前、Wireless LAN APIを使ってNIC一覧の取得を行うプログラムを書きました。今回は、そのNICからみえるアクセスポイントの一覧の取得機能を追加してみます。

#include <windows.h>
#include <iostream>
#include <string>
#include <Wlanapi.h>
#pragma comment(lib, "wlanapi.lib")

bool displayESSID(HANDLE handle, GUID *guid)
{
	unsigned i;
	WLAN_AVAILABLE_NETWORK_LIST *networkList;
	
	if(WlanGetAvailableNetworkList(handle, guid, 0, NULL, &networkList) != ERROR_SUCCESS)
		return false;
	
	for(i = 0; i < networkList->dwNumberOfItems; ++i) {
		WLAN_AVAILABLE_NETWORK *nw = &networkList->Network[i];
		DOT11_SSID *ssid = &nw->dot11Ssid;
		std::cout << "  " << std::string((char *)ssid->ucSSID, (size_t)ssid->uSSIDLength);
		std::cout << " " << nw->wlanSignalQuality << std::endl;
	}
	
	WlanFreeMemory(networkList);
	return true;
}

int main(void)
{
	unsigned i;
	DWORD err, ver;
	HANDLE hClient;
	WLAN_INTERFACE_INFO_LIST *ifList;

	if((err = WlanOpenHandle(WLAN_API_MAKE_VERSION(1, 0), NULL, &ver, &hClient)) != ERROR_SUCCESS) {
		std::cerr << "error: WlanOpenHandle()" << std::endl;
		return 1;
	}

	// get interface list
	WlanEnumInterfaces(hClient, NULL, &ifList);
	std::cout << ifList->dwNumberOfItems << " interfaces found" << std::endl;
	for(i = 0; i < ifList->dwNumberOfItems; ++i) {
		WLAN_INTERFACE_INFO wii = ifList->InterfaceInfo[i];
		std::wcout << wii.strInterfaceDescription << std::endl;
		displayESSID(hClient, &wii.InterfaceGuid);
	}

	WlanFreeMemory(ifList);
	WlanCloseHandle(hClient, NULL);
	return 0;
}

アクセスポイントの一覧を取得するAPIはWlanGetAvailableNetworkList()です。NICのGUIDを第1引数に与える必要があるので、レジストリを調べて指定するか、あるいはWlanEnumInterfaces()で取得してきます。今回は後者のAPIから取得する方法を使いました。

WlanGetAvailableNetworkList()を呼ぶと、WLAN_AVAILABLE_NETWORK_LIST構造体にアクセスポイント一覧が詰め込まれて返って来ます。メモリ確保はAPI側でやってもらえるのですが、解放は自前でWlanFreeMemory()を呼ぶ必要があります。

具体的にどういうデータが取れるのかは、_WLAN_AVAILABLE_NETWORK | Microsoft Docsを参照して下さい。ここでは、ESSIDを取得する為にメンバ変数dot11Ssidを、信号強度を取得する為にメンバ変数wlanSignalQualityを利用しています。

2009年01月11日 (日曜日)

Wireless LAN API - 目次

あらまし

Wireless LAN APIで検索されている方が多いので、少し書いてみようかと思います。やっぱりLinuxよりもWindowsの方が需要あるようで。

Windows XP SP3以降からWireless LAN API, あるいはNative WiFi Support for Windows XPと呼ばれるWi-Fiの為のAPIが用意されました。これを使うと、難しい事をしなくてもWi-Fiデバイスプログラムから操作できるようになります。

Wireless LAN APIで出来る事は、基本的にネットワークの接続・切断に絞られています。その他にNIC一覧の取得や、NICから見えているSSIDの一覧の取得なども出来ますが、基本的に接続・切断に必要最低限の機能がついているという感じです。

受信信号強度や各NICの状態を得る為には、Wireless LAN APIではなく、WMI (Windows Management Instrumentation)を使った状態取得をする必要があります。これについては、各所にサンプルコードや解説が載っていますので、そちらをご覧ください。

だいたいのプログラミングの様子は、以前書いた「Wireless LAN APIを使ってみた - 汁ごはん」にありますので、そちらを参照された方が素早く感覚をつかめるかもしれません。

参考リンク

2008年05月18日 (日曜日)

Wireless LAN APIを使ってみた

Windows XP SP3から標準搭載される予定の、Wireless LAN APIを使ってみています。Windows XP SP3でなくても、SP2ならばKB918997インストールすれば使えます。

まず、Windows側で無線LANを管理していないといけないので、サードパーティ製ツールで接続管理をしている場合は、Windows側で管理するようにします。

それから、Windows Zero Configurationを有効にする必要がありますので、起動していなかったらサービスを見つけて立ち上げましょう。

とりあえず、Wireless LANNIC一覧を取得するコードを書いてみました。

#include <windows.h>
#include <iostream>
#include <Wlanapi.h>
#pragma comment(lib, "wlanapi.lib")

int main(void)
{
	unsigned i;
	DWORD err, ver;
	HANDLE hClient;
	WLAN_INTERFACE_INFO_LIST *ifList;

	if((err = WlanOpenHandle(WLAN_API_MAKE_VERSION(1, 0), NULL, &ver, &hClient)) != ERROR_SUCCESS) {
		std::cerr << "error: WlanOpenHandle()" << std::endl;
		return 1;
	}

	// get interface list
	WlanEnumInterfaces(hClient, NULL, &ifList);
	std::cout << ifList->dwNumberOfItems << " interfaces found" << std::endl;
	for(i = 0; i < ifList->dwNumberOfItems; ++i) {
		WLAN_INTERFACE_INFO wii = ifList->InterfaceInfo[i];
		std::wcout << wii.strInterfaceDescription << std::endl;
	}

	WlanFreeMemory(ifList);
	WlanCloseHandle(hClient, NULL);
	return 0;
}