2025-11-28 00:35:46 +09:00

2697 lines
74 KiB
C++

/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
wlsample.cpp
Abstract:
Sample code for WLAN APIs
Date:
11/08/2005 created
08/22/2006 modified
Environment:
User mode only
--*/
// define this flag for COM
#define _WIN32_DCOM
#include <windows.h>
#include <conio.h>
#include <objbase.h>
#include <rpcsal.h>
#include <objbase.h>
#include <msxml6.h>
#include <atlbase.h>
#include <iostream>
#include <iomanip>
// headers needed to use WLAN APIs
#include <wlanapi.h>
using namespace std;
// get win32 error from HRESULT
#define WIN32_FROM_HRESULT(hr) \
(SUCCEEDED(hr) ? ERROR_SUCCESS : \
(HRESULT_FACILITY(hr) == FACILITY_WIN32 ? HRESULT_CODE(hr) : (hr)))
//
// Utility functions
//
// get interface state string
LPWSTR
GetInterfaceStateString(
__in WLAN_INTERFACE_STATE wlanInterfaceState
)
{
LPWSTR strRetCode;
switch(wlanInterfaceState)
{
case wlan_interface_state_not_ready:
strRetCode = L"\"not ready\"";
break;
case wlan_interface_state_connected:
strRetCode = L"\"connected\"";
break;
case wlan_interface_state_ad_hoc_network_formed:
strRetCode = L"\"ad hoc network formed\"";
break;
case wlan_interface_state_disconnecting:
strRetCode = L"\"disconnecting\"";
break;
case wlan_interface_state_disconnected:
strRetCode = L"\"disconnected\"";
break;
case wlan_interface_state_associating:
strRetCode = L"\"associating\"";
break;
case wlan_interface_state_discovering:
strRetCode = L"\"discovering\"";
break;
case wlan_interface_state_authenticating:
strRetCode = L"\"authenticating\"";
break;
default:
strRetCode = L"\"invalid interface state\"";
}
return strRetCode;
}
// get ACM notification string
LPWSTR
GetAcmNotificationString(
__in DWORD acmNotif
)
{
LPWSTR strRetCode;
switch(acmNotif)
{
case wlan_notification_acm_autoconf_enabled:
strRetCode = L"\"autoconf enabled\"";
break;
case wlan_notification_acm_autoconf_disabled:
strRetCode = L"\"autoconf disabled\"";
break;
case wlan_notification_acm_background_scan_enabled:
strRetCode = L"\"background scan enabled\"";
break;
case wlan_notification_acm_background_scan_disabled:
strRetCode = L"\"background scan disabled\"";
break;
case wlan_notification_acm_power_setting_change:
strRetCode = L"\"power setting change\"";
break;
case wlan_notification_acm_scan_complete:
strRetCode = L"\"scan complete\"";
break;
case wlan_notification_acm_scan_fail:
strRetCode = L"\"scan fail\"";
break;
case wlan_notification_acm_connection_start:
strRetCode = L"\"connection start\"";
break;
case wlan_notification_acm_connection_complete:
strRetCode = L"\"connection complete\"";
break;
case wlan_notification_acm_connection_attempt_fail:
strRetCode = L"\"connection fail\"";
break;
case wlan_notification_acm_filter_list_change:
strRetCode = L"\"filter list change\"";
break;
case wlan_notification_acm_interface_arrival:
strRetCode = L"\"interface arrival\"";
break;
case wlan_notification_acm_interface_removal:
strRetCode = L"\"interface removal\"";
break;
case wlan_notification_acm_profile_change:
strRetCode = L"\"profile change\"";
break;
case wlan_notification_acm_profiles_exhausted:
strRetCode = L"\"profiles exhausted\"";
break;
case wlan_notification_acm_network_not_available:
strRetCode = L"\"network not available\"";
break;
case wlan_notification_acm_network_available:
strRetCode = L"\"network available\"";
break;
case wlan_notification_acm_disconnecting:
strRetCode = L"\"disconnecting\"";
break;
case wlan_notification_acm_disconnected:
strRetCode = L"\"disconnected\"";
break;
case wlan_notification_acm_adhoc_network_state_change:
strRetCode = L"\"ad hoc network state changes\"";
break;
default:
strRetCode = L"\"unknown ACM notification\"";
}
return strRetCode;
}
// get MSMM notification string
LPWSTR
GetMsmNotificationString(
__in DWORD msmNotif
)
{
LPWSTR strRetCode;
switch(msmNotif)
{
case wlan_notification_msm_associating:
strRetCode = L"\"associating\"";
break;
case wlan_notification_msm_associated:
strRetCode = L"\"associated\"";
break;
case wlan_notification_msm_authenticating:
strRetCode = L"\"authenticating\"";
break;
case wlan_notification_msm_connected:
strRetCode = L"\"connected\"";
break;
case wlan_notification_msm_roaming_start:
strRetCode = L"\"roaming start\"";
break;
case wlan_notification_msm_roaming_end:
strRetCode = L"\"roaming end\"";
break;
case wlan_notification_msm_radio_state_change:
strRetCode = L"\"radio state change\"";
break;
case wlan_notification_msm_signal_quality_change:
strRetCode = L"\"signal quality change\"";
break;
case wlan_notification_msm_disassociating:
strRetCode = L"\"disassociating\"";
break;
case wlan_notification_msm_disconnected:
strRetCode = L"\"disconnected\"";
break;
case wlan_notification_msm_peer_join:
strRetCode = L"\"a peer joins the ad hoc network\"";
break;
case wlan_notification_msm_peer_leave:
strRetCode = L"\"a peer leaves the ad hoc network\"";
break;
case wlan_notification_msm_adapter_removal:
strRetCode = L"\"adapter is in a bad state\"";
break;
default:
strRetCode = L"\"unknown MSM notification\"";
}
return strRetCode;
}
// get connection mode string
LPWSTR
GetConnectionModeString(
__in WLAN_CONNECTION_MODE wlanConnMode
)
{
LPWSTR strRetCode;
switch(wlanConnMode)
{
case wlan_connection_mode_profile:
strRetCode = L"\"manual connection with a profile\"";
break;
case wlan_connection_mode_temporary_profile:
strRetCode = L"\"manual connection with a temporary profile\"";
break;
case wlan_connection_mode_discovery_secure:
strRetCode = L"\"connection to a secure network without a profile\"";
break;
case wlan_connection_mode_discovery_unsecure:
strRetCode = L"\"connection to an unsecure network without a profile\"";
break;
case wlan_connection_mode_auto:
strRetCode = L"\"automatic connection with a profile\"";
break;
default:
strRetCode = L"\"invalid connection mode\"";
}
return strRetCode;
}
// get PHY type string
LPWSTR
GetPhyTypeString(
__in ULONG uDot11PhyType
)
{
LPWSTR strRetCode;
switch(uDot11PhyType)
{
case dot11_phy_type_dsss:
strRetCode = L"\"DSSS\"";
break;
case dot11_phy_type_erp:
strRetCode = L"\"802.11g\"";
break;
case dot11_phy_type_fhss:
strRetCode = L"\"FHSS\"";
break;
case dot11_phy_type_hrdsss:
strRetCode = L"\"802.11b\"";
break;
case dot11_phy_type_irbaseband:
strRetCode = L"\"IR-base band\"";
break;
case dot11_phy_type_ofdm:
strRetCode = L"\"802.11a\"";
break;
case dot11_phy_type_any:
strRetCode = L"\"any\"";
break;
default:
strRetCode = L"\"Unknown PHY type\"";
}
return strRetCode;
}
// get BSS type string
LPWSTR
GetBssTypeString(
__in DOT11_BSS_TYPE dot11BssType
)
{
LPWSTR strRetCode;
switch(dot11BssType)
{
case dot11_BSS_type_infrastructure:
strRetCode = L"\"Infrastructure\"";
break;
case dot11_BSS_type_independent:
strRetCode = L"\"Ad hoc\"";
break;
case dot11_BSS_type_any:
strRetCode = L"\"Any\"";
break;
default:
strRetCode = L"\"Unknown BSS type\"";
}
return strRetCode;
}
// get radio state string
LPWSTR
GetRadioStateString(
__in DOT11_RADIO_STATE radioState
)
{
LPWSTR strRetCode;
switch(radioState)
{
case dot11_radio_state_on:
strRetCode = L"\"on\"";
break;
case dot11_radio_state_off:
strRetCode = L"\"off\"";
break;
default:
strRetCode = L"\"unknown state\"";
}
return strRetCode;
}
// get auth algorithm string
LPWSTR
GetAuthAlgoString(
__in DOT11_AUTH_ALGORITHM dot11AuthAlgo
)
{
LPWSTR strRetCode = L"\"Unknown algorithm\"";
switch(dot11AuthAlgo)
{
case DOT11_AUTH_ALGO_80211_OPEN:
strRetCode = L"\"Open\"";
break;
case DOT11_AUTH_ALGO_80211_SHARED_KEY:
strRetCode = L"\"Shared\"";
break;
case DOT11_AUTH_ALGO_WPA:
strRetCode = L"\"WPA-Enterprise\"";
break;
case DOT11_AUTH_ALGO_WPA_PSK:
strRetCode = L"\"WPA-Personal\"";
break;
case DOT11_AUTH_ALGO_WPA_NONE:
strRetCode = L"\"WPA-NONE\"";
break;
case DOT11_AUTH_ALGO_RSNA:
strRetCode = L"\"WPA2-Enterprise\"";
break;
case DOT11_AUTH_ALGO_RSNA_PSK:
strRetCode = L"\"WPA2-Personal\"";
break;
default:
if (dot11AuthAlgo & DOT11_AUTH_ALGO_IHV_START)
{
strRetCode = L"\"Vendor-specific algorithm\"";
}
}
return strRetCode;
}
// get cipher algorithm string
LPWSTR
GetCipherAlgoString(
__in DOT11_CIPHER_ALGORITHM dot11CipherAlgo
)
{
LPWSTR strRetCode = L"\"Unknown algorithm\"";
switch(dot11CipherAlgo)
{
case DOT11_CIPHER_ALGO_NONE:
strRetCode = L"\"None\"";
break;
case DOT11_CIPHER_ALGO_WEP40:
strRetCode = L"\"WEP40\"";
break;
case DOT11_CIPHER_ALGO_TKIP:
strRetCode = L"\"TKIP\"";
break;
case DOT11_CIPHER_ALGO_CCMP:
strRetCode = L"\"AES\"";
break;
case DOT11_CIPHER_ALGO_WEP104:
strRetCode = L"\"WEP104\"";
break;
case DOT11_CIPHER_ALGO_WPA_USE_GROUP:
strRetCode = L"\"USE-GROUP\"";
break;
case DOT11_CIPHER_ALGO_WEP:
strRetCode = L"\"WEP\"";
break;
default:
if (dot11CipherAlgo & DOT11_CIPHER_ALGO_IHV_START)
{
strRetCode = L"\"Vendor-specific algorithm\"";
}
}
return strRetCode;
}
// get SSID from the WCHAR string
DWORD
StringWToSsid(
__in LPCWSTR strSsid,
__out PDOT11_SSID pSsid
)
{
DWORD dwRetCode = ERROR_SUCCESS;
BYTE pbSsid[DOT11_SSID_MAX_LENGTH + 1] = {0};
if (strSsid == NULL || pSsid == NULL)
{
dwRetCode = ERROR_INVALID_PARAMETER;
}
else
{
pSsid->uSSIDLength = WideCharToMultiByte (CP_ACP,
0,
strSsid,
-1,
(LPSTR)pbSsid,
sizeof(pbSsid),
NULL,
NULL);
pSsid->uSSIDLength--;
memcpy(&pSsid->ucSSID, pbSsid, pSsid->uSSIDLength);
}
return dwRetCode;
}
// copy SSID to a null-terminated WCHAR string
// count is the number of WCHAR in the buffer.
LPWSTR
SsidToStringW(
__out_ecount(count) LPWSTR buf,
__in ULONG count,
__in PDOT11_SSID pSsid
)
{
ULONG bytes, i;
bytes = min( count-1, pSsid->uSSIDLength);
for( i=0; i<bytes; i++)
mbtowc( &buf[i], (const char *)&pSsid->ucSSID[i], 1);
buf[bytes] = '\0';
return buf;
}
// the max lenght of the reason string in characters
#define WLSAMPLE_REASON_STRING_LEN 256
// print the reason string
VOID
PrintReason(
__in WLAN_REASON_CODE reason
)
{
WCHAR strReason[WLSAMPLE_REASON_STRING_LEN];
if (WlanReasonCodeToString(
reason,
WLSAMPLE_REASON_STRING_LEN,
strReason,
NULL // reserved
) == ERROR_SUCCESS)
{
wcout << L" The reason is \"" << strReason << L"\"." << endl;
}
else
{
wcout << L" The reason code is " << reason << L"." << endl;
}
}
// print the basic information of a visible wireless network
VOID PrintNetworkInfo(
__in PWLAN_AVAILABLE_NETWORK pNetwork
)
{
WCHAR strSsid[DOT11_SSID_MAX_LENGTH+1];
if (pNetwork != NULL)
{
// SSID
wcout << L"SSID: " << SsidToStringW(strSsid, sizeof(strSsid)/sizeof(WCHAR), &pNetwork->dot11Ssid) << endl;
// whether security is enabled
if (pNetwork->bSecurityEnabled)
{
wcout << L"\tSecurity enabled." << endl;
}
else
{
wcout << L"\tSecurity not enabled." << endl;
}
// number of BSSIDs
wcout << L"\tContains " << pNetwork->uNumberOfBssids << L" BSSIDs." << endl;
// whether have a profile for this SSID
if (pNetwork->dwFlags & WLAN_AVAILABLE_NETWORK_HAS_PROFILE)
{
wcout << L"\tHas a matching profile: " << pNetwork->strProfileName << L"." <<endl;
}
// whether it is connected
if (pNetwork->dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED)
{
wcout << L"\tCurrently connected." << endl;
}
// whether it is connectable
if (!pNetwork->bNetworkConnectable)
{
// the reason that it is not connectable
wcout << L"\tThe network is not connectable. ";
PrintReason(pNetwork->wlanNotConnectableReason);
}
else
{
wcout << L"\tThe network is connectable." << endl;
}
// BSS type
wcout << L"\tBSS type: " << GetBssTypeString(pNetwork->dot11BssType) << endl;
// Signal quality
wcout << L"\tSignal quality: " << pNetwork->wlanSignalQuality << L"%" << endl;
// Default auth algorithm
wcout << L"\tDefault authentication algorithm: " << GetAuthAlgoString(pNetwork->dot11DefaultAuthAlgorithm) << endl;
// Default cipher algorithm
wcout << L"\tDefault cipher algorithm: " << GetCipherAlgoString(pNetwork->dot11DefaultCipherAlgorithm) << endl;
}
}
// print BSS info
VOID
PrintBssInfo(
__in PWLAN_BSS_ENTRY pBss
)
{
WCHAR strSsid[DOT11_SSID_MAX_LENGTH+1];
UINT i;
PBYTE pIe = NULL;
if (pBss != NULL)
{
// MAC address
wcout << L"MAC address: ";
for (i = 0; i < 6; i++)
{
wcout << setw(2) << setfill(L'0') << hex << (UINT)pBss->dot11Bssid[i] <<L" ";
}
wcout << endl;
// SSID
wcout << L"\tSSID: " << SsidToStringW(strSsid, sizeof(strSsid)/sizeof(WCHAR), &pBss->dot11Ssid) << endl;
// Beacon period
wcout << L"\tBeacon period: " << dec << pBss->usBeaconPeriod << L" TU" << endl;
// IE
wcout << L"\tIE";
i = 0;
pIe = (PBYTE)(pBss) + pBss->ulIeOffset;
// print 8 byte per line
while (i < pBss->ulIeSize)
{
if (i % 8 == 0)
{
wcout << endl << L"\t\t";
}
wcout << setw(2) << setfill(L'0') << hex << (UINT)pIe[i] << L" ";
i++;
}
wcout << endl;
}
}
#define WLAN_INVALID_COUNTER (ULONGLONG)-1
// print the counter value in driver statistics
VOID
PrintCounterValue(
__in ULONGLONG value
)
{
if (value == WLAN_INVALID_COUNTER)
wcout << L" cannot be obtained" << endl;
else
// wcout cannot handle ULONGLONG
wcout << (UINT)value << endl;
}
// print the error message
VOID
PrintErrorMsg(
__in LPWSTR strCommand,
__in DWORD dwError
)
{
if (strCommand != NULL)
{
if (dwError == ERROR_SUCCESS)
{
wcout << L"Command \"" << strCommand << L"\" completed successfully." << endl;
}
else if (dwError == ERROR_INVALID_PARAMETER)
{
wcout << L"The parameter for \"" << strCommand << L"\" is not correct. ";
wcout << L"Please use \"help " << strCommand << L"\" to check the usage of the command." << endl;
}
else if (dwError == ERROR_BAD_PROFILE)
{
wcout << L"The given profile is not valid." << endl;
}
else if (dwError == ERROR_NOT_SUPPORTED)
{
wcout << L"Command \"" << strCommand << L"\" is not supported." << endl;
}
else
{
wcout << L"Got error " << dwError << L" for command \"" << strCommand << L"\"" << endl;
}
}
}
// open a WLAN client handle and check version
DWORD
OpenHandleAndCheckVersion(
PHANDLE phClient
)
{
DWORD dwError = ERROR_SUCCESS;
DWORD dwServiceVersion;
HANDLE hClient = NULL;
__try
{
*phClient = NULL;
// open a handle to the service
if ((dwError = WlanOpenHandle(
WLAN_API_VERSION,
NULL, // reserved
&dwServiceVersion,
&hClient
)) != ERROR_SUCCESS)
{
__leave;
}
// check service version
if (WLAN_API_VERSION_MAJOR(dwServiceVersion) < WLAN_API_VERSION_MAJOR(WLAN_API_VERSION_2_0))
{
// No-op, because the version check is for demonstration purpose only.
// You can add your own logic here.
}
*phClient = hClient;
// set hClient to NULL so it will not be closed
hClient = NULL;
}
__finally
{
if (hClient != NULL)
{
// clean up
WlanCloseHandle(
hClient,
NULL // reserved
);
}
}
return dwError;
}
//
// Functions that demonstrate how to use WLAN APIs
//
// Notification callback function
VOID WINAPI
NotificationCallback(
__in PWLAN_NOTIFICATION_DATA pNotifData,
__in_opt PVOID pContext // this parameter is not used
)
{
WCHAR strSsid[DOT11_SSID_MAX_LENGTH+1];
PWLAN_CONNECTION_NOTIFICATION_DATA pConnNotifData = NULL;
if (pNotifData != NULL)
{
switch(pNotifData->NotificationSource)
{
case WLAN_NOTIFICATION_SOURCE_ACM:
wcout << L"Got notification " << GetAcmNotificationString(pNotifData->NotificationCode) << L" from ACM." << endl;
// print some notifications as examples
switch(pNotifData->NotificationCode)
{
case wlan_notification_acm_connection_complete:
if (pNotifData->dwDataSize < sizeof(WLAN_CONNECTION_NOTIFICATION_DATA))
{
break;
}
pConnNotifData = (PWLAN_CONNECTION_NOTIFICATION_DATA)pNotifData->pData;
if (pConnNotifData->wlanReasonCode == WLAN_REASON_CODE_SUCCESS)
{
wcout << L"The connection succeeded." << endl;
if (pConnNotifData->wlanConnectionMode == wlan_connection_mode_discovery_secure ||
pConnNotifData->wlanConnectionMode == wlan_connection_mode_discovery_unsecure)
{
// the temporary profile generated for discovery
wcout << L"The profile used for this connection is as follows:" << endl;
wcout << pConnNotifData->strProfileXml << endl;
}
}
else
{
wcout << L"The connection failed.";
PrintReason(pConnNotifData->wlanReasonCode);
}
break;
case wlan_notification_acm_connection_start:
if (pNotifData->dwDataSize != sizeof(WLAN_CONNECTION_NOTIFICATION_DATA))
{
break;
}
pConnNotifData = (PWLAN_CONNECTION_NOTIFICATION_DATA)pNotifData->pData;
// print out some connection information
wcout << L"\tCurrently connecting to " << SsidToStringW(strSsid, sizeof(strSsid)/sizeof(WCHAR), &pConnNotifData->dot11Ssid);
wcout << L" using profile " << pConnNotifData->strProfileName;
wcout << L", connection mode is " << GetConnectionModeString(pConnNotifData->wlanConnectionMode);
wcout << L", BSS type is " << GetBssTypeString(pConnNotifData->dot11BssType) << endl;
break;
}
break;
case WLAN_NOTIFICATION_SOURCE_MSM:
wcout << L"Got notification " << GetMsmNotificationString(pNotifData->NotificationCode) << L" from MSM." << endl;
break;
}
}
}
// Register for notification
VOID
RegisterNotification(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
DWORD dwError = ERROR_SUCCESS;
HANDLE hClient = NULL;
DWORD dwPrevNotifType = 0;
__try
{
if (argc != 1)
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// open a handle to the service
if ((dwError = OpenHandleAndCheckVersion(
&hClient
)) != ERROR_SUCCESS)
{
__leave;
}
// register for ACM and MSM notifications
if ((dwError = WlanRegisterNotification(
hClient,
WLAN_NOTIFICATION_SOURCE_ACM | WLAN_NOTIFICATION_SOURCE_MSM,
FALSE, // do not ignore duplications
NotificationCallback,
NULL, // no callback context is needed
NULL, // reserved
&dwPrevNotifType
)) != ERROR_SUCCESS)
{
__leave;
}
wcout << L"ACM and MSM notifications are successfully registered. Press any key to exit." << endl;
// wait for the user to press a key
_getch();
// unregister notifications
if ((dwError = WlanRegisterNotification(
hClient,
WLAN_NOTIFICATION_SOURCE_NONE,
FALSE, // do not ignore duplications
NULL, // no callback function is needed
NULL, // no callback context is needed
NULL, // reserved
&dwPrevNotifType
)) == ERROR_SUCCESS)
{
wcout << L"ACM and MSM notifications are successfully unregistered." << endl;
}
else
{
wcout << L"Error " << dwError << L" occurs when unresiger ACM and MSM notifications." << endl;
}
}
__finally
{
// clean up
if (hClient != NULL)
{
WlanCloseHandle(
hClient,
NULL // reserved
);
}
}
PrintErrorMsg(argv[0], dwError);
}
// set profile
VOID
SetProfile(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
DWORD dwError;
HRESULT hr;
HANDLE hClient = NULL;
GUID guidIntf;
CComPtr<IXMLDOMDocument2> pXmlDoc;
CComBSTR bstrXml;
VARIANT_BOOL vbSuccess;
DWORD dwReason;
// __try and __leave cannot be used here because of COM object
do
{
if (argc != 3)
{
dwError = ERROR_INVALID_PARAMETER;
break;
}
// get the interface GUID
if (UuidFromString((RPC_WSTR)argv[1], &guidIntf) != RPC_S_OK)
{
wcerr << L"Invalid GUID " << argv[1] << endl;
dwError = ERROR_INVALID_PARAMETER;
break;
}
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (hr != S_OK)
{
dwError = WIN32_FROM_HRESULT(hr);
break;
}
// create a COM object to read the XML file
hr = CoCreateInstance(
CLSID_DOMDocument60,
NULL,
CLSCTX_INPROC_SERVER,
IID_IXMLDOMDocument2,
(void**)&pXmlDoc
);
if (hr != S_OK)
{
dwError = WIN32_FROM_HRESULT(hr);
break;
}
// load the file into the COM object
hr = pXmlDoc->load((CComVariant)argv[2], &vbSuccess);
if (hr != S_OK || vbSuccess != VARIANT_TRUE)
{
dwError = ERROR_BAD_PROFILE;
break;
}
// get XML string out from the file
hr = pXmlDoc->get_xml(&bstrXml);
if (hr != S_OK)
{
dwError = ERROR_BAD_PROFILE;
break;
}
// open handle
if ((dwError = OpenHandleAndCheckVersion(
&hClient
)) != ERROR_SUCCESS)
{
break;
}
// set profile
dwError = WlanSetProfile(
hClient,
&guidIntf,
0, // no flags for the profile
bstrXml,
NULL, // use the default ACL
TRUE, // overwrite a profile if it already exists
NULL, // reserved
&dwReason
);
if (dwError == ERROR_BAD_PROFILE)
{
wcout << L"The profile is bad.";
PrintReason(dwReason);
}
} while (FALSE);
// clean up
if (hClient != NULL)
{
WlanCloseHandle(
hClient,
NULL // reserved
);
}
PrintErrorMsg(argv[0], dwError);
}
// get profile
VOID
GetProfile(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
DWORD dwError = ERROR_SUCCESS;
HANDLE hClient = NULL;
PWSTR strXml;
GUID guidIntf;
__try
{
if (argc != 3)
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// get the interface GUID
if (UuidFromString((RPC_WSTR)argv[1], &guidIntf) != RPC_S_OK)
{
wcerr << L"Invalid GUID " << argv[1] << endl;
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// open handle
if ((dwError = OpenHandleAndCheckVersion(
&hClient
)) != ERROR_SUCCESS)
{
__leave;
}
// get profile
if ((dwError = WlanGetProfile(
hClient,
&guidIntf,
argv[2], // profile name
NULL, // reserved
&strXml, // XML string of the profile
NULL, // not interested in the profile flags
NULL // don't care about ACL
)) == ERROR_SUCCESS)
{
wcout << L"The return profile xml is: " << endl << strXml << endl;
WlanFreeMemory(strXml);
}
}
__finally
{
// clean up
if (hClient != NULL)
{
WlanCloseHandle(
hClient,
NULL // reserved
);
}
}
PrintErrorMsg(argv[0], dwError);
}
// delete profile
VOID
DeleteProfile(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
DWORD dwError = ERROR_SUCCESS;
HANDLE hClient = NULL;
GUID guidIntf;
__try
{
if (argc != 3)
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// get the interface GUID
if (UuidFromString((RPC_WSTR)argv[1], &guidIntf) != RPC_S_OK)
{
wcerr << L"Invalid GUID " << argv[1] << endl;
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// open handle
if ((dwError = OpenHandleAndCheckVersion(
&hClient
)) != ERROR_SUCCESS)
{
__leave;
}
// delete profile
dwError = WlanDeleteProfile(
hClient,
&guidIntf,
argv[2], // profile name
NULL // reserved
);
}
__finally
{
// clean up
if (hClient != NULL)
{
WlanCloseHandle(
hClient,
NULL // reserved
);
}
}
PrintErrorMsg(argv[0], dwError);
}
// set profile list
VOID
SetProfileList(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
DWORD dwError = ERROR_SUCCESS;
HANDLE hClient = NULL;
GUID guidIntf;
__try
{
if (argc < 3)
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// get the interface GUID
if (UuidFromString((RPC_WSTR)argv[1], &guidIntf) != RPC_S_OK)
{
wcerr << L"Invalid GUID " << argv[1] << endl;
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// open handle
if ((dwError = OpenHandleAndCheckVersion(
&hClient
)) != ERROR_SUCCESS)
{
__leave;
}
// set profile list
dwError = WlanSetProfileList(
hClient,
&guidIntf,
argc - 2, // number of profiles
(LPCWSTR *)(argv + 2), // the list of profiles name following the command and the interface GUID
NULL // reserved
);
}
__finally
{
// clean up
if (hClient != NULL)
{
WlanCloseHandle(
hClient,
NULL // reserved
);
}
}
PrintErrorMsg(argv[0], dwError);
}
// get the list of profiles
VOID
GetProfileList(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
DWORD dwError = ERROR_SUCCESS;
HANDLE hClient = NULL;
GUID guidIntf;
PWLAN_PROFILE_INFO_LIST pProfileList = NULL;
PWLAN_PROFILE_INFO pInfo = NULL;
UINT i;
__try
{
if (argc != 2)
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// get the interface GUID
if (UuidFromString((RPC_WSTR)argv[1], &guidIntf) != RPC_S_OK)
{
wcerr << L"Invalid GUID " << argv[1] << endl;
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// open handle
if ((dwError = OpenHandleAndCheckVersion(
&hClient
)) != ERROR_SUCCESS)
{
__leave;
}
// get profile list
if ((dwError = WlanGetProfileList(
hClient,
&guidIntf,
NULL, // reserved
&pProfileList
)) != ERROR_SUCCESS)
{
__leave;
}
wcout << L"There are " << pProfileList->dwNumberOfItems << L" profiles on the interface." << endl;
// print out profiles
for (i = 0; i < pProfileList->dwNumberOfItems; i++)
{
pInfo = &pProfileList->ProfileInfo[i];
wcout << L"\t\"" << pInfo->strProfileName << L"\"" << endl;
}
}
__finally
{
// clean up
if (pProfileList != NULL)
{
WlanFreeMemory(pProfileList);
}
if (hClient != NULL)
{
WlanCloseHandle(
hClient,
NULL // reserved
);
}
}
PrintErrorMsg(argv[0], dwError);
}
// enumerate wireless interfaces
VOID
EnumInterface(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
DWORD dwError = ERROR_SUCCESS;
HANDLE hClient = NULL;
PWLAN_INTERFACE_INFO_LIST pIntfList = NULL;
RPC_WSTR strGuid = NULL;
UINT i = 0;
__try
{
if (argc != 1)
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// open handle
if ((dwError = OpenHandleAndCheckVersion(
&hClient
)) != ERROR_SUCCESS)
{
__leave;
}
// enumerate wireless interfaces
if ((dwError = WlanEnumInterfaces(
hClient,
NULL, // reserved
&pIntfList
)) != ERROR_SUCCESS)
{
__leave;
}
wcout << L"There are " << pIntfList->dwNumberOfItems << L" interfaces in the system." << endl;
// print out interface information
for (i = 0; i < pIntfList->dwNumberOfItems; i++)
{
wcout << L"Interface " << i << L":" << endl;
if (UuidToStringW(&pIntfList->InterfaceInfo[i].InterfaceGuid, &strGuid) == RPC_S_OK)
{
wcout << L"\tGUID: " << (LPWSTR)strGuid << endl;
RpcStringFreeW(&strGuid);
}
wcout << L"\t" << pIntfList->InterfaceInfo[i].strInterfaceDescription << endl;
wcout << L"\tState: " << GetInterfaceStateString(pIntfList->InterfaceInfo[i].isState) << endl;
wcout << endl;
}
}
__finally
{
// clean up
if (pIntfList != NULL)
{
WlanFreeMemory(pIntfList);
}
if (hClient != NULL)
{
WlanCloseHandle(
hClient,
NULL // reserved
);
}
}
PrintErrorMsg(argv[0], dwError);
}
// get interface capability and supported auth/cipher
VOID
GetInterfaceCapability(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
DWORD dwError = ERROR_SUCCESS;
HANDLE hClient = NULL;
GUID guidIntf;
PWLAN_INTERFACE_CAPABILITY pCapability = NULL;
PWLAN_AUTH_CIPHER_PAIR_LIST pSupportedAuthCipherList = NULL;
DWORD dwDataSize;
UINT i;
__try
{
if (argc != 2)
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// get the interface GUID
if (UuidFromString((RPC_WSTR)argv[1], &guidIntf) != RPC_S_OK)
{
wcerr << L"Invalid GUID " << argv[1] << endl;
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// open handle
if ((dwError = OpenHandleAndCheckVersion(
&hClient
)) != ERROR_SUCCESS)
{
__leave;
}
if (( dwError = WlanGetInterfaceCapability(
hClient,
&guidIntf,
NULL, // reserved
&pCapability
)) != ERROR_SUCCESS)
{
__leave;
}
// print interface capability information
if (pCapability->interfaceType == wlan_interface_type_emulated_802_11)
{
wcout << L"Emulated 802.11 NIC." << endl;
}
else if (pCapability->interfaceType == wlan_interface_type_native_802_11)
{
wcout << L"Native 802.11 NIC." << endl;
}
else
{
wcout << L"Unknown NIC." << endl;
}
// print supported PHY type
wcout << L"Supports " << pCapability->dwNumberOfSupportedPhys << L" PHY types:" << endl;
for (i = 0; i < pCapability->dwNumberOfSupportedPhys; i++)
{
wcout << L"\t" << GetPhyTypeString(pCapability->dot11PhyTypes[i]) << endl;
}
// query supported auth/cipher for infrastructure
if ((dwError = WlanQueryInterface(
hClient,
&guidIntf,
wlan_intf_opcode_supported_infrastructure_auth_cipher_pairs,
NULL, // reserved
&dwDataSize,
(PVOID *)&(pSupportedAuthCipherList),
NULL // not interesed in the type of the opcode value
)) != ERROR_SUCCESS)
{
__leave;
}
// print auth/cipher algorithms
wcout << L"Supported auth cipher pairs (infrastructure):" << endl;
for (i = 0; i < pSupportedAuthCipherList->dwNumberOfItems; i++)
{
wcout << L"\t";
wcout << GetAuthAlgoString(pSupportedAuthCipherList->pAuthCipherPairList[i].AuthAlgoId);
wcout << L" and ";
wcout << GetCipherAlgoString(pSupportedAuthCipherList->pAuthCipherPairList[i].CipherAlgoId) << endl;
}
WlanFreeMemory(pSupportedAuthCipherList);
pSupportedAuthCipherList = NULL;
// query supported auth/cipher for ad hoc
if ((dwError = WlanQueryInterface(
hClient,
&guidIntf,
wlan_intf_opcode_supported_adhoc_auth_cipher_pairs,
NULL, // reserved
&dwDataSize,
(PVOID *)&(pSupportedAuthCipherList),
NULL // not interesed in the type of the opcode value
)) != ERROR_SUCCESS)
{
__leave;
}
// print auth/cipher algorithms
wcout << L"Supported auth cipher pairs (ad hoc):" << endl;
for (i = 0; i < pSupportedAuthCipherList->dwNumberOfItems; i++)
{
wcout << L"\t";
wcout << GetAuthAlgoString(pSupportedAuthCipherList->pAuthCipherPairList[i].AuthAlgoId);
wcout << L" and ";
wcout << GetCipherAlgoString(pSupportedAuthCipherList->pAuthCipherPairList[i].CipherAlgoId) << endl;
}
WlanFreeMemory(pSupportedAuthCipherList);
pSupportedAuthCipherList = NULL;
}
__finally
{
// clean up
if (hClient != NULL)
{
WlanCloseHandle(
hClient,
NULL // reserved
);
}
}
PrintErrorMsg(argv[0], dwError);
}
// set the radio state
VOID
SetRadioState(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
DWORD dwError = ERROR_SUCCESS;
HANDLE hClient = NULL;
GUID guidIntf;
PWLAN_INTERFACE_CAPABILITY pInterfaceCapability = NULL;
DWORD i;
WLAN_PHY_RADIO_STATE wlanPhyRadioState;
__try
{
if (argc != 3)
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
if (_wcsicmp(argv[2], L"on") == 0)
{
wlanPhyRadioState.dot11SoftwareRadioState = dot11_radio_state_on;
}
else if (_wcsicmp(argv[2], L"off") == 0)
{
wlanPhyRadioState.dot11SoftwareRadioState = dot11_radio_state_off;
}
else
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// get the interface GUID
if (UuidFromString((RPC_WSTR)argv[1], &guidIntf) != RPC_S_OK)
{
wcerr << L"Invalid GUID " << argv[1] << endl;
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// open handle
if ((dwError = OpenHandleAndCheckVersion(
&hClient
)) != ERROR_SUCCESS)
{
__leave;
}
// get interface capability, which includes the supported PHYs
if ((dwError = WlanGetInterfaceCapability(
hClient,
&guidIntf,
NULL, // reserved
&pInterfaceCapability
)) != ERROR_SUCCESS)
{
__leave;
}
// set radio state on every PHY
for (i = 0; i < pInterfaceCapability->dwNumberOfSupportedPhys; i++)
{
// set radio state on every PHY
wlanPhyRadioState.dwPhyIndex = i;
if ((dwError = WlanSetInterface(
hClient,
&guidIntf,
wlan_intf_opcode_radio_state,
sizeof(wlanPhyRadioState),
(PBYTE)&wlanPhyRadioState,
NULL // reserved
)) != ERROR_SUCCESS)
{
// rollback is nice to have, but not required
__leave;
}
}
}
__finally
{
// clean up
if (hClient != NULL)
{
WlanCloseHandle(
hClient,
NULL // reserved
);
}
if (pInterfaceCapability != NULL)
{
WlanFreeMemory(pInterfaceCapability);
}
}
PrintErrorMsg(argv[0], dwError);
}
// query basic interface information
VOID
QueryInterface(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
DWORD dwError = ERROR_SUCCESS;
HANDLE hClient = NULL;
GUID guidIntf;
WLAN_INTERFACE_STATE isState;
PWLAN_CONNECTION_ATTRIBUTES pCurrentNetwork = NULL;
WCHAR strSsid[DOT11_SSID_MAX_LENGTH+1];
WLAN_RADIO_STATE wlanRadioState;
PVOID pData = NULL;
DWORD dwDataSize = 0;
UINT i;
__try
{
if (argc != 2)
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// get the interface GUID
if (UuidFromString((RPC_WSTR)argv[1], &guidIntf) != RPC_S_OK)
{
wcerr << L"Invalid GUID " << argv[1] << endl;
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// open handle
if ((dwError = OpenHandleAndCheckVersion(
&hClient
)) != ERROR_SUCCESS)
{
__leave;
}
// query radio state information
// this opcode is not supported in XP
if ((dwError = WlanQueryInterface(
hClient,
&guidIntf,
wlan_intf_opcode_radio_state,
NULL, // reserved
&dwDataSize,
&pData,
NULL // not interesed in the type of the opcode value
)) != ERROR_SUCCESS &&
dwError != ERROR_NOT_SUPPORTED)
{
__leave;
}
if (dwError == ERROR_SUCCESS)
{
if (dwDataSize != sizeof(WLAN_RADIO_STATE))
{
dwError = ERROR_INVALID_DATA;
__leave;
}
wlanRadioState = *((PWLAN_RADIO_STATE)pData);
// print radio state
for (i = 0; i < wlanRadioState.dwNumberOfPhys; i++)
{
wcout << L"PHY " << wlanRadioState.PhyRadioState[i].dwPhyIndex << L": " << endl;
wcout << L"\tSoftware radio state is " << GetRadioStateString(wlanRadioState.PhyRadioState[i].dot11SoftwareRadioState) << L"." << endl;
wcout << L"\tHardware radio state is " << GetRadioStateString(wlanRadioState.PhyRadioState[i].dot11HardwareRadioState) << L"." << endl;
}
WlanFreeMemory(pData);
pData = NULL;
}
else
{
// not supported in XP
// print message
wcout << L"Querying radio state is not supported." << endl;
}
// query interface state
if ((dwError = WlanQueryInterface(
hClient,
&guidIntf,
wlan_intf_opcode_interface_state,
NULL, // reserved
&dwDataSize,
&pData,
NULL // not interesed in the type of the opcode value
)) != ERROR_SUCCESS)
{
__leave;
}
if (dwDataSize != sizeof(WLAN_INTERFACE_STATE))
{
dwError = ERROR_INVALID_DATA;
__leave;
}
isState = *((PWLAN_INTERFACE_STATE)pData);
// print interface state
wcout << L"Interface state: " << GetInterfaceStateString(isState) << L"." << endl;
WlanFreeMemory(pData);
pData = NULL;
// query the current connection
if ((dwError = WlanQueryInterface(
hClient,
&guidIntf,
wlan_intf_opcode_current_connection,
NULL, // reserved
&dwDataSize,
&pData,
NULL // not interesed in the type of the opcode value
)) == ERROR_SUCCESS &&
dwDataSize == sizeof(WLAN_CONNECTION_ATTRIBUTES)
)
{
pCurrentNetwork = (PWLAN_CONNECTION_ATTRIBUTES)pData;
}
// we don't treat ERROR_INVALID_STATE as an error for querying the interface
if (dwError == ERROR_INVALID_STATE)
{
dwError = ERROR_SUCCESS;
}
if (pCurrentNetwork == NULL)
{
// no connection information
__leave;
}
// print current connection information
if (pCurrentNetwork->isState == wlan_interface_state_connected)
wcout << L"Currently connected to ";
else if (pCurrentNetwork->isState == wlan_interface_state_ad_hoc_network_formed)
wcout << L"Currently formed ";
else if (pCurrentNetwork->isState == wlan_interface_state_associating ||
pCurrentNetwork->isState == wlan_interface_state_discovering ||
pCurrentNetwork->isState == wlan_interface_state_authenticating
)
wcout << L"Currently connecting to ";
wcout << SsidToStringW(strSsid, sizeof(strSsid)/sizeof(WCHAR), &pCurrentNetwork->wlanAssociationAttributes.dot11Ssid);
wcout << L" using profile " << pCurrentNetwork->strProfileName;
wcout << L", connection mode is " << GetConnectionModeString(pCurrentNetwork->wlanConnectionMode);
wcout << L", BSS type is " << GetBssTypeString(pCurrentNetwork->wlanAssociationAttributes.dot11BssType) << L"." << endl;
wcout << L"Current PHY type: ";
wcout << GetPhyTypeString(pCurrentNetwork->wlanAssociationAttributes.dot11PhyType) << endl;
}
__finally
{
if (pData != NULL)
{
WlanFreeMemory(pData);
}
// clean up
if (hClient != NULL)
{
WlanCloseHandle(
hClient,
NULL // reserved
);
}
}
PrintErrorMsg(argv[0], dwError);
}
// scan
VOID
Scan(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
DWORD dwError = ERROR_SUCCESS;
HANDLE hClient = NULL;
GUID guidIntf;
__try
{
if (argc != 2)
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// get the interface GUID
if (UuidFromString((RPC_WSTR)argv[1], &guidIntf) != RPC_S_OK)
{
wcerr << L"Invalid GUID " << argv[1] << endl;
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// open handle
if ((dwError = OpenHandleAndCheckVersion(
&hClient
)) != ERROR_SUCCESS)
{
__leave;
}
// scan
dwError = WlanScan(
hClient,
&guidIntf,
NULL, // don't perform additional probe for a specific SSID
NULL, // no IE data for the additional probe
NULL // reserved
);
}
__finally
{
// clean up
if (hClient != NULL)
{
WlanCloseHandle(
hClient,
NULL // reserved
);
}
}
PrintErrorMsg(argv[0], dwError);
}
// get the list of visible wireless networks
VOID
GetVisibleNetworkList(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
DWORD dwError = ERROR_SUCCESS;
HANDLE hClient = NULL;
GUID guidIntf;
PWLAN_AVAILABLE_NETWORK_LIST pVList = NULL;
UINT i;
__try
{
if (argc != 2)
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// get the interface GUID
if (UuidFromString((RPC_WSTR)argv[1], &guidIntf) != RPC_S_OK)
{
wcerr << L"Invalid GUID " << argv[1] << endl;
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// open handle
if ((dwError = OpenHandleAndCheckVersion(
&hClient
)) != ERROR_SUCCESS)
{
__leave;
}
if ((dwError = WlanGetAvailableNetworkList(
hClient,
&guidIntf,
0, // only show visible networks
NULL, // reserved
&pVList
)) != ERROR_SUCCESS)
{
__leave;
}
// print all visible networks
wcout << L"Total " << pVList->dwNumberOfItems << L" networks are visible." << endl;
for (i = 0; i < pVList->dwNumberOfItems; i++)
{
wcout << L"Network " <<i << L":" << endl;
PrintNetworkInfo(&pVList->Network[i]);
wcout << endl;
}
WlanFreeMemory(pVList);
}
__finally
{
// clean up
if (hClient != NULL)
{
WlanCloseHandle(
hClient,
NULL // reserved
);
}
}
PrintErrorMsg(argv[0], dwError);
}
// get driver statistics
VOID
GetDriverStatistics(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
DWORD dwError = ERROR_SUCCESS;
HANDLE hClient = NULL;
GUID guidIntf;
PVOID pData = NULL;
DWORD dwSize;
PWLAN_STATISTICS pStatistics;
UINT i;
__try
{
if (argc != 2)
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// get the interface GUID
if (UuidFromString((RPC_WSTR)argv[1], &guidIntf) != RPC_S_OK)
{
wcerr << L"Invalid GUID " << argv[1] << endl;
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// open handle
if ((dwError = OpenHandleAndCheckVersion(
&hClient
)) != ERROR_SUCCESS)
{
__leave;
}
if ((dwError = WlanQueryInterface(
hClient,
&guidIntf,
wlan_intf_opcode_statistics,
NULL, // reserved
&dwSize,
&pData,
NULL // not interesed in the type of the opcode value
)) != ERROR_SUCCESS)
{
__leave;
}
pStatistics = (PWLAN_STATISTICS)pData;
// print statistics information
wcout << L"Four way handshake failures: \t";
PrintCounterValue(pStatistics->ullFourWayHandshakeFailures);
wcout << L"TKIP Counter Measures invoked: \t";
PrintCounterValue(pStatistics->ullTKIPCounterMeasuresInvoked);
// frame statistics
wcout << L"Unicast counters\n";
wcout << L"\tTransmitted frame count: \t";
PrintCounterValue(pStatistics->MacUcastCounters.ullTransmittedFrameCount);
wcout << L"\tReceived frame count: \t";
PrintCounterValue(pStatistics->MacUcastCounters.ullReceivedFrameCount);
wcout << L"\tWEP excluded count: \t";
PrintCounterValue(pStatistics->MacUcastCounters.ullWEPExcludedCount);
// frame statistics
wcout << L"Multicast counters\n";
wcout << L"\tTransmitted frame count: \t";
PrintCounterValue(pStatistics->MacMcastCounters.ullTransmittedFrameCount);
wcout << L"\tReceived frame count: \t";
PrintCounterValue(pStatistics->MacMcastCounters.ullReceivedFrameCount);
wcout << L"\tWEP excluded count: \t";
PrintCounterValue(pStatistics->MacMcastCounters.ullWEPExcludedCount);
for (i = 0; i < pStatistics->dwNumberOfPhys; i++)
{
wcout << L"PHY " << i << endl;
wcout << L"\tTransmitted frame count: \t";
PrintCounterValue(pStatistics->PhyCounters[i].ullTransmittedFrameCount);
wcout << L"\tMulticast transmitted frame count: \t";
PrintCounterValue(pStatistics->PhyCounters[i].ullMulticastTransmittedFrameCount);
wcout << L"\tReceived frame count: \t";
PrintCounterValue(pStatistics->PhyCounters[i].ullReceivedFrameCount);
wcout << L"\tMulticast received frame count: \t";
PrintCounterValue(pStatistics->PhyCounters[i].ullMulticastReceivedFrameCount);
}
WlanFreeMemory(pData);
}
__finally
{
// clean up
if (hClient != NULL)
{
WlanCloseHandle(
hClient,
NULL // reserved
);
}
}
PrintErrorMsg(argv[0], dwError);
}
// get BSS list
VOID
GetBssList(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
DWORD dwError = ERROR_SUCCESS;
HANDLE hClient = NULL;
GUID guidIntf;
DOT11_SSID dot11Ssid = {0};
PDOT11_SSID pDot11Ssid = NULL;
DOT11_BSS_TYPE dot11BssType = dot11_BSS_type_any;
BOOL bSecurityEnabled = TRUE;
PWLAN_BSS_LIST pWlanBssList = NULL;
UINT i;
__try
{
if (argc != 2 && argc != 5)
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// get the interface GUID
if (UuidFromString((RPC_WSTR)argv[1], &guidIntf) != RPC_S_OK)
{
wcerr << L"Invalid GUID " << argv[1] << endl;
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
if (argc == 5)
{
// get SSID
if ((dwError = StringWToSsid(argv[2], &dot11Ssid)) != ERROR_SUCCESS)
{
__leave;
}
pDot11Ssid = &dot11Ssid;
// get BSS type
if (_wcsicmp(argv[3],L"adhoc") == 0 || _wcsicmp(argv[3], L"a") == 0)
dot11BssType = dot11_BSS_type_independent;
else if (_wcsicmp(argv[3], L"infrastructure") == 0 || _wcsicmp(argv[3], L"i") == 0)
dot11BssType = dot11_BSS_type_infrastructure;
else
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// get whether security enabled or not
if (_wcsicmp(argv[4], L"secure") == 0 || _wcsicmp(argv[4], L"s") == 0)
bSecurityEnabled = TRUE;
else if (_wcsicmp(argv[4], L"unsecure") == 0 || _wcsicmp(argv[4], L"u") == 0)
bSecurityEnabled = FALSE;
else
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
}
// open handle
if ((dwError = OpenHandleAndCheckVersion(
&hClient
)) != ERROR_SUCCESS)
{
__leave;
}
if ((dwError = WlanGetNetworkBssList(
hClient,
&guidIntf,
pDot11Ssid,
dot11BssType,
bSecurityEnabled,
NULL, // reserved
&pWlanBssList
)) != ERROR_SUCCESS)
{
__leave;
}
for (i = 0; i < pWlanBssList->dwNumberOfItems; i++)
{
PrintBssInfo(&pWlanBssList->wlanBssEntries[i]);
}
WlanFreeMemory(pWlanBssList);
}
__finally
{
// clean up
if (hClient != NULL)
{
WlanCloseHandle(
hClient,
NULL // reserved
);
}
}
PrintErrorMsg(argv[0], dwError);
}
// connect to a network using a saved profile
VOID
Connect(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
DWORD dwError = ERROR_SUCCESS;
HANDLE hClient = NULL;
GUID guidIntf;
DOT11_SSID dot11Ssid = {0};
WLAN_CONNECTION_PARAMETERS wlanConnPara;
__try
{
if (argc != 5)
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// get the interface GUID
if (UuidFromString((RPC_WSTR)argv[1], &guidIntf) != RPC_S_OK)
{
wcerr << L"Invalid GUID " << argv[1] << endl;
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// get SSID
if ((dwError = StringWToSsid(argv[2], &dot11Ssid)) != ERROR_SUCCESS)
{
__leave;
}
// set the connection mode (connecting using a profile)
wlanConnPara.wlanConnectionMode = wlan_connection_mode_profile;
// set the profile name
wlanConnPara.strProfile = argv[4];
// set the SSID
wlanConnPara.pDot11Ssid = &dot11Ssid;
// get BSS type
if (_wcsicmp(argv[3],L"adhoc") == 0 || _wcsicmp(argv[3], L"a") == 0)
wlanConnPara.dot11BssType = dot11_BSS_type_independent;
else if (_wcsicmp(argv[3], L"infrastructure") == 0 || _wcsicmp(argv[3], L"i") == 0)
wlanConnPara.dot11BssType = dot11_BSS_type_infrastructure;
else
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// the desired BSSID list is empty
wlanConnPara.pDesiredBssidList = NULL;
// no connection flags
wlanConnPara.dwFlags = 0;
// open handle
if ((dwError = OpenHandleAndCheckVersion(
&hClient
)) != ERROR_SUCCESS)
{
__leave;
}
dwError = WlanConnect(
hClient,
&guidIntf,
&wlanConnPara,
NULL // reserved
);
}
__finally
{
// clean up
if (hClient != NULL)
{
WlanCloseHandle(
hClient,
NULL // reserved
);
}
}
PrintErrorMsg(argv[0], dwError);
}
// discovery a network without using a saved profile
VOID
Discover(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
DWORD dwError = ERROR_SUCCESS;
HANDLE hClient = NULL;
GUID guidIntf;
DOT11_SSID dot11Ssid = {0};
WLAN_CONNECTION_PARAMETERS wlanConnPara;
__try
{
if (argc != 5)
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// get the interface GUID
if (UuidFromString((RPC_WSTR)argv[1], &guidIntf) != RPC_S_OK)
{
wcerr << L"Invalid GUID " << argv[1] << endl;
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// get SSID
if ((dwError = StringWToSsid(argv[2], &dot11Ssid)) != ERROR_SUCCESS)
{
__leave;
}
// profile is ignored for discovery
wlanConnPara.strProfile = NULL;
// set the SSID
wlanConnPara.pDot11Ssid = &dot11Ssid;
// get BSS type
if (_wcsicmp(argv[3],L"adhoc") == 0 || _wcsicmp(argv[3], L"a") == 0)
wlanConnPara.dot11BssType = dot11_BSS_type_independent;
else if (_wcsicmp(argv[3], L"infrastructure") == 0 || _wcsicmp(argv[3], L"i") == 0)
wlanConnPara.dot11BssType = dot11_BSS_type_infrastructure;
else
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// get whether security enabled or not
if (_wcsicmp(argv[4], L"secure") == 0 || _wcsicmp(argv[4], L"s") == 0)
wlanConnPara.wlanConnectionMode = wlan_connection_mode_discovery_secure;
else if (_wcsicmp(argv[4], L"unsecure") == 0 || _wcsicmp(argv[4], L"u") == 0)
wlanConnPara.wlanConnectionMode = wlan_connection_mode_discovery_unsecure;
else
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// the desired BSSID list is empty
wlanConnPara.pDesiredBssidList = NULL;
// no connection flags
wlanConnPara.dwFlags = 0;
// open handle
if ((dwError = OpenHandleAndCheckVersion(
&hClient
)) != ERROR_SUCCESS)
{
__leave;
}
dwError = WlanConnect(
hClient,
&guidIntf,
&wlanConnPara,
NULL // reserved
);
}
__finally
{
// clean up
if (hClient != NULL)
{
WlanCloseHandle(
hClient,
NULL // reserved
);
}
}
PrintErrorMsg(argv[0], dwError);
}
// disconnect from the current network
VOID
Disconnect(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
DWORD dwError = ERROR_SUCCESS;
HANDLE hClient = NULL;
GUID guidIntf;
__try
{
if (argc != 2)
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// get the interface GUID
if (UuidFromString((RPC_WSTR)argv[1], &guidIntf) != RPC_S_OK)
{
wcerr << L"Invalid GUID " << argv[1] << endl;
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// open handle
if ((dwError = OpenHandleAndCheckVersion(
&hClient
)) != ERROR_SUCCESS)
{
__leave;
}
dwError = WlanDisconnect(
hClient,
&guidIntf,
NULL // reserved
);
}
__finally
{
// clean up
if (hClient != NULL)
{
WlanCloseHandle(
hClient,
NULL // reserved
);
}
}
PrintErrorMsg(argv[0], dwError);
}
// save a temporary profile
// a temporary profile can be generated by the service for discovery
// or passed with WlanConnect when the connection mode is wlan_connection_mode_temporary_profile
VOID
SaveTemporaryProfile(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
DWORD dwError = ERROR_SUCCESS;
HANDLE hClient = NULL;
GUID guidIntf;
DWORD dwFlags = 0;
__try
{
if (argc != 3)
{
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// get the interface GUID
if (UuidFromString((RPC_WSTR)argv[1], &guidIntf) != RPC_S_OK)
{
wcerr << L"Invalid GUID " << argv[1] << endl;
dwError = ERROR_INVALID_PARAMETER;
__leave;
}
// open handle
if ((dwError = OpenHandleAndCheckVersion(
&hClient
)) != ERROR_SUCCESS)
{
__leave;
}
dwError = WlanSaveTemporaryProfile(
hClient,
&guidIntf,
argv[2], // profile name
NULL, // use default ACL
0, // no profile flags
TRUE, // overwrite the existing profile
NULL // reserved
);
}
__finally
{
// clean up
if (hClient != NULL)
{
WlanCloseHandle(
hClient,
NULL // reserved
);
}
}
PrintErrorMsg(argv[0], dwError);
}
// show help messages
VOID
Help(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
);
typedef VOID (*WLSAMPLE_FUNCTION) (int argc, LPWSTR argv[]);
typedef struct _WLSAMPLE_COMMAND {
LPWSTR strCommandName; // command name
LPWSTR strShortHand; // a shorthand for the command
WLSAMPLE_FUNCTION Func; // pointer to the function
LPWSTR strHelpMessage; // help message
LPWSTR strParameters; // parameters for the command
BOOL bRemarks; // whether have remarks for the command
LPWSTR strRemarks; // remarks
} WLSAMPLE_COMMAND, *PWLSAMPLE_COMMAND;
WLSAMPLE_COMMAND g_Commands[] = {
// interface related commands
{
L"EnumInterface",
L"ei",
EnumInterface,
L"Enumerate wireless interfaces and print the basic interface information.",
L"",
FALSE,
L""
},
{
L"GetInterfaceCapability",
L"gic",
GetInterfaceCapability,
L"Get the capability of an interface.",
L"<interface GUID>",
TRUE,
L"Use EnumInterface (ei) command to get the GUID of an interface."
},
{
L"QueryInterface",
L"qi",
QueryInterface,
L"Query the basic information of an interface.",
L"<interface GUID>",
TRUE,
L"Use EnumInterface (ei) command to get the GUID of an interface."
},
{
L"SetRadioState",
L"srs",
SetRadioState,
L"Set the software radio state.",
L"<interface GUID> <on|off>",
TRUE,
L"Use EnumInterface (ei) command to get the GUID of an interface."
},
{
L"GetDriverStatistics",
L"gds",
GetDriverStatistics,
L"Get driver statistics." ,
L"<interface GUID>",
TRUE,
L"Use EnumInterface (ei) command to get the GUID of an interface."
},
// scan related commands
{
L"Scan",
L"scan",
Scan,
L"Scan for available wireless networks.",
L"<interface GUID>",
TRUE,
L"Use EnumInterface (ei) command to get the GUID of an interface."
},
{
L"GetBssList",
L"gbs",
GetBssList,
L"Get the list of BSS." ,
L"<interface GUID> [<SSID> <infrastructure(i)|adhoc(a)> <secure(s)|unsecure(u)>]",
TRUE,
L"Use EnumInterface (ei) command to get the GUID of an interface."
},
{
L"GetVisibleNetworkList",
L"gvl",
GetVisibleNetworkList,
L"Get the list of visible wireless networks.",
L"<interface GUID>",
TRUE,
L"Use EnumInterface (ei) command to get the GUID of an interface."
},
// profile releated commands
{
L"SetProfile",
L"sp",
SetProfile,
L"Save a profile.",
L"<interface GUID> <profile XML file name>",
TRUE,
L"Use EnumInterface (ei) command to get the GUID of an interface."
},
{
L"SaveTempProfile",
L"stp",
SaveTemporaryProfile,
L"Save the temporary profile used for the current connection.",
L"<interface GUID> <profile name>",
TRUE,
L"Use EnumInterface (ei) command to get the GUID of an interface."
},
{
L"GetProfile",
L"gp",
GetProfile,
L"Get the content of a saved profile.",
L"<interface GUID> <profile name>",
TRUE,
L"Use EnumInterface (ei) command to get the GUID of an interface."
},
{
L"DeleteProfile",
L"dp",
DeleteProfile,
L"Delete a saved profile.",
L"<interface GUID> <profile name>",
TRUE,
L"Use EnumInterface (ei) command to get the GUID of an interface."
},
{
L"SetProfileList",
L"spl",
SetProfileList,
L"Set the preference order of saved profiles. The list must contain all profiles.",
L"<interface GUID> <profile name>+",
TRUE,
L"Use EnumInterface (ei) command to get the GUID of an interface."
},
{
L"GetProfileList",
L"gpl",
GetProfileList,
L"Get the list of saved profiles, in the preference order." ,
L"<interface GUID>",
TRUE,
L"Use EnumInterface (ei) command to get the GUID of an interface."
},
// connection related commands
{
L"Connect",
L"conn",
Connect,
L"Connect to a wireless network using a saved profile.",
L"<interface GUID> <SSID> <infrastructure(i)|adhoc(a)> <profile name>",
TRUE,
L"Use EnumInterface (ei) command to get the GUID of an interface."
},
{
L"Disconnect",
L"dc",
Disconnect,
L"Disconnect from the current network.",
L"<interface GUID>",
TRUE,
L"Use EnumInterface (ei) command to get the GUID of an interface."
},
{
L"Discover",
L"disc",
Discover,
L"Connect to a network without a saved profile. The WLAN service will discover the settings for connection.",
L"<interface GUID> <SSID> <infrastructure(i)|adhoc(a)> <secure(s)|unsecure(u)>",
TRUE,
L"Use EnumInterface (ei) command to get the GUID of an interface."
},
// other commands
{
L"RegisterNotif",
L"r",
RegisterNotification,
L"Register ACM and MSM notifications.",
L"",
FALSE,
L""
},
{
L"help",
L"?",
Help,
L"Print this help message.",
L"[<command>]",
FALSE,
L""
}
};
// show help messages
VOID
Help(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
UINT i;
if (argc == 1)
{
// show all commands
wcout << L"This is a sample showing how to use WLAN APIs to manager wireless networks." << endl;
wcout << L"The following commands are available. Use \"help xyz\" to show the description of command xyz." << endl;
for (i=0; i < sizeof(g_Commands)/sizeof(WLSAMPLE_COMMAND); i++)
{
wcout << L"\t"<< g_Commands[i].strCommandName;
wcout << L"(" << g_Commands[i].strShortHand << L")" << endl;
}
}
else if (argc == 2)
{
// show the description of a command
for (i=0; i < sizeof(g_Commands)/sizeof(WLSAMPLE_COMMAND); i++)
{
if (_wcsicmp(argv[1], g_Commands[i].strCommandName) == 0 ||
_wcsicmp(argv[1], g_Commands[i].strShortHand) == 0)
{
wcout << L"Command: " << g_Commands[i].strCommandName;
wcout << L"(" << g_Commands[i].strShortHand << L")" << endl;
wcout << L"Description: " << g_Commands[i].strHelpMessage << endl;
wcout << L"Usage: " << g_Commands[i].strCommandName;
wcout << L"(" << g_Commands[i].strShortHand << L") ";
wcout << g_Commands[i].strParameters << endl;
if (g_Commands[i].bRemarks)
{
wcout << L"Remarks: " << g_Commands[i].strRemarks << endl;
}
break;
}
}
}
else
{
PrintErrorMsg(argv[0], ERROR_INVALID_PARAMETER);
}
}
// command is stored in the global variable
void
ExecuteCommand(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
UINT i = 0;
for (i=0; i < sizeof(g_Commands)/sizeof(WLSAMPLE_COMMAND); i++)
{
// find the command and call the function
if (_wcsicmp(argv[0], g_Commands[i].strCommandName) == 0 ||
_wcsicmp(argv[0], g_Commands[i].strShortHand) == 0)
{
g_Commands[i].Func(argc, argv);
break;
}
}
if (i == sizeof(g_Commands)/sizeof(WLSAMPLE_COMMAND))
{
wcerr << L"Invalid command " << argv[0] << L"!" << endl;
}
}
// the main program
int _cdecl
wmain(
__in int argc,
__in_ecount(argc) LPWSTR argv[]
)
{
DWORD dwRetCode = ERROR_SUCCESS;
if (argc <= 1)
{
wcout << L"Please type \"" << argv[0] << L" ?\" for help." << endl;
dwRetCode = ERROR_INVALID_PARAMETER;
}
else
{
// don't pass in the first parameter
ExecuteCommand(argc-1, argv+1);
}
return dwRetCode;
}