一汁三菜

自分が楽しいと思うこと、マラソン、旅行、その他日々の記録をしたい。

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

以前、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を利用しています。