mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-21 17:59:34 +00:00
Bug 985970. On Windows, initiate a scan of nearby wireless networks before collecting AP data. r=jimm
This commit is contained in:
parent
6372a893b2
commit
703335c64e
@ -42,6 +42,8 @@ elif CONFIG['OS_ARCH'] == 'FreeBSD':
|
||||
elif CONFIG['OS_ARCH'] == 'WINNT':
|
||||
UNIFIED_SOURCES += [
|
||||
'nsWifiScannerWin.cpp',
|
||||
'win_wifiScanner.cpp',
|
||||
'win_wlanLibrary.cpp',
|
||||
]
|
||||
elif CONFIG['OS_ARCH'] == 'SunOS':
|
||||
CXXFLAGS += CONFIG['GLIB_CFLAGS']
|
||||
|
@ -21,6 +21,10 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
class WinWifiScanner;
|
||||
#endif
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
extern PRLogModuleInfo *gWifiMonitorLog;
|
||||
#endif
|
||||
@ -71,6 +75,9 @@ class nsWifiMonitor MOZ_FINAL : nsIRunnable, nsIWifiMonitor, nsIObserver
|
||||
|
||||
mozilla::ReentrantMonitor mReentrantMonitor;
|
||||
|
||||
#ifdef XP_WIN
|
||||
nsAutoPtr<WinWifiScanner> mWinWifiScanner;
|
||||
#endif
|
||||
};
|
||||
#else
|
||||
#include "nsIWifi.h"
|
||||
|
@ -2,42 +2,39 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
#include "windows.h"
|
||||
#include "wlanapi.h"
|
||||
|
||||
#include "stdlib.h"
|
||||
|
||||
#include "nsWifiMonitor.h"
|
||||
#include "nsWifiAccessPoint.h"
|
||||
|
||||
#include "nsServiceManagerUtils.h"
|
||||
// moz headers (alphabetical)
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIMutableArray.h"
|
||||
|
||||
#define DOT11_BSS_TYPE_UNUSED static_cast<DOT11_BSS_TYPE>(0)
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsWifiAccessPoint.h"
|
||||
#include "win_wifiScanner.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
/**
|
||||
* `nsWifiMonitor` is declared in the cross-platform nsWifiMonitor.h and
|
||||
* is mostly defined in the cross-platform nsWifiMonitor.cpp. This function
|
||||
* is implemented in various platform-specific files but the implementation
|
||||
* is almost identical in each file. We relegate the Windows-specific
|
||||
* work to the `WinWifiScanner` class and deal with non-Windows-specific
|
||||
* issues like calling listeners here. Hopefully this file can be merged
|
||||
* with the other implementations of `nsWifiMonitor::DoScan` since a lot
|
||||
* of the code is identical
|
||||
*/
|
||||
nsresult
|
||||
nsWifiMonitor::DoScan()
|
||||
{
|
||||
HINSTANCE wlan_library = LoadLibrary("Wlanapi.dll");
|
||||
if (!wlan_library)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
decltype(::WlanOpenHandle)* WlanOpenHandle = (decltype(::WlanOpenHandle)*) GetProcAddress(wlan_library, "WlanOpenHandle");
|
||||
decltype(::WlanEnumInterfaces)* WlanEnumInterfaces = (decltype(::WlanEnumInterfaces)*) GetProcAddress(wlan_library, "WlanEnumInterfaces");
|
||||
decltype(::WlanGetNetworkBssList)* WlanGetNetworkBssList = (decltype(::WlanGetNetworkBssList)*) GetProcAddress(wlan_library, "WlanGetNetworkBssList");
|
||||
decltype(::WlanFreeMemory)* WlanFreeMemory = (decltype(::WlanFreeMemory)*) GetProcAddress(wlan_library, "WlanFreeMemory");
|
||||
decltype(::WlanCloseHandle)* WlanCloseHandle = (decltype(::WlanCloseHandle)*) GetProcAddress(wlan_library, "WlanCloseHandle");
|
||||
|
||||
if (!WlanOpenHandle ||
|
||||
!WlanEnumInterfaces ||
|
||||
!WlanGetNetworkBssList ||
|
||||
!WlanFreeMemory ||
|
||||
!WlanCloseHandle)
|
||||
return NS_ERROR_FAILURE;
|
||||
if (!mWinWifiScanner) {
|
||||
mWinWifiScanner = new WinWifiScanner();
|
||||
if (!mWinWifiScanner) {
|
||||
// TODO: Probably return OOM error
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// Regularly get the access point data.
|
||||
|
||||
@ -46,77 +43,15 @@ nsWifiMonitor::DoScan()
|
||||
|
||||
do {
|
||||
accessPoints.Clear();
|
||||
|
||||
// Get the handle to the WLAN API.
|
||||
DWORD negotiated_version;
|
||||
HANDLE wlan_handle = nullptr;
|
||||
// We could be executing on either Windows XP or Windows Vista, so use the
|
||||
// lower version of the client WLAN API. It seems that the negotiated version
|
||||
// is the Vista version irrespective of what we pass!
|
||||
static const int kXpWlanClientVersion = 1;
|
||||
if ((*WlanOpenHandle)(kXpWlanClientVersion,
|
||||
nullptr,
|
||||
&negotiated_version,
|
||||
&wlan_handle) != ERROR_SUCCESS) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
nsresult rv = mWinWifiScanner->GetAccessPointsFromWLAN(accessPoints);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// try again later.
|
||||
if (!wlan_handle)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Get the list of interfaces. WlanEnumInterfaces allocates interface_list.
|
||||
WLAN_INTERFACE_INFO_LIST *interface_list = nullptr;
|
||||
if ((*WlanEnumInterfaces)(wlan_handle, nullptr, &interface_list) != ERROR_SUCCESS) {
|
||||
// try again later
|
||||
(*WlanCloseHandle)(wlan_handle, nullptr);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Go through the list of interfaces and get the data for each.
|
||||
for (int i = 0; i < static_cast<int>(interface_list->dwNumberOfItems); ++i) {
|
||||
|
||||
WLAN_BSS_LIST *bss_list;
|
||||
HRESULT rv = (*WlanGetNetworkBssList)(wlan_handle,
|
||||
&interface_list->InterfaceInfo[i].InterfaceGuid,
|
||||
nullptr, // Use all SSIDs.
|
||||
DOT11_BSS_TYPE_UNUSED,
|
||||
false, // bSecurityEnabled - unused
|
||||
nullptr, // reserved
|
||||
&bss_list);
|
||||
if (rv != ERROR_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int j = 0; j < static_cast<int>(bss_list->dwNumberOfItems); ++j) {
|
||||
|
||||
nsWifiAccessPoint* ap = new nsWifiAccessPoint();
|
||||
if (!ap)
|
||||
continue;
|
||||
|
||||
const WLAN_BSS_ENTRY bss_entry = bss_list->wlanBssEntries[j];
|
||||
|
||||
ap->setMac(bss_entry.dot11Bssid);
|
||||
ap->setSignal(bss_entry.lRssi);
|
||||
ap->setSSID((char*) bss_entry.dot11Ssid.ucSSID,
|
||||
bss_entry.dot11Ssid.uSSIDLength);
|
||||
|
||||
accessPoints.AppendObject(ap);
|
||||
}
|
||||
(*WlanFreeMemory)(bss_list);
|
||||
}
|
||||
|
||||
// Free interface_list.
|
||||
(*WlanFreeMemory)(interface_list);
|
||||
|
||||
// Close the handle.
|
||||
(*WlanCloseHandle)(wlan_handle, nullptr);
|
||||
|
||||
|
||||
bool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
|
||||
ReplaceArray(lastAccessPoints, accessPoints);
|
||||
|
||||
nsresult rv = CallWifiListeners(lastAccessPoints, accessPointsChanged);
|
||||
rv = CallWifiListeners(lastAccessPoints, accessPointsChanged);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// wait for some reasonable amount of time. pref?
|
||||
|
192
netwerk/wifi/win_wifiScanner.cpp
Normal file
192
netwerk/wifi/win_wifiScanner.cpp
Normal file
@ -0,0 +1,192 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "win_wifiScanner.h"
|
||||
|
||||
// Moz headers (alphabetical)
|
||||
#include "win_wlanLibrary.h"
|
||||
|
||||
#define DOT11_BSS_TYPE_UNUSED static_cast<DOT11_BSS_TYPE>(0)
|
||||
|
||||
class InterfaceScanCallbackData {
|
||||
public:
|
||||
InterfaceScanCallbackData(uint32_t numInterfaces)
|
||||
: mCurrentlyScanningInterfaces(numInterfaces)
|
||||
{
|
||||
mAllInterfacesDoneScanningEvent =
|
||||
::CreateEvent(nullptr, // null security
|
||||
TRUE, // manual reset event
|
||||
FALSE, // initially nonsignaled
|
||||
nullptr); // not named
|
||||
MOZ_ASSERT(NULL != mAllInterfacesDoneScanningEvent);
|
||||
}
|
||||
|
||||
~InterfaceScanCallbackData()
|
||||
{
|
||||
::CloseHandle(mAllInterfacesDoneScanningEvent);
|
||||
}
|
||||
|
||||
void
|
||||
OnInterfaceScanComplete()
|
||||
{
|
||||
uint32_t val = ::InterlockedDecrement(&mCurrentlyScanningInterfaces);
|
||||
if (!val) {
|
||||
::SetEvent(mAllInterfacesDoneScanningEvent);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WaitForAllInterfacesToFinishScanning(uint32_t msToWait)
|
||||
{
|
||||
::WaitForSingleObject(mAllInterfacesDoneScanningEvent,
|
||||
msToWait);
|
||||
}
|
||||
|
||||
private:
|
||||
volatile uint32_t mCurrentlyScanningInterfaces;
|
||||
HANDLE mAllInterfacesDoneScanningEvent;
|
||||
};
|
||||
|
||||
static void
|
||||
OnScanComplete(PWLAN_NOTIFICATION_DATA data, PVOID context)
|
||||
{
|
||||
if (WLAN_NOTIFICATION_SOURCE_ACM != data->NotificationSource) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (wlan_notification_acm_scan_complete != data->NotificationCode &&
|
||||
wlan_notification_acm_scan_fail != data->NotificationCode) {
|
||||
return;
|
||||
}
|
||||
|
||||
InterfaceScanCallbackData* cbData =
|
||||
reinterpret_cast<InterfaceScanCallbackData*>(context);
|
||||
cbData->OnInterfaceScanComplete();
|
||||
}
|
||||
|
||||
WinWifiScanner::WinWifiScanner()
|
||||
{
|
||||
// NOTE: We assume that, if we were unable to load the WLAN library when
|
||||
// we initially tried, we will not be able to load it in the future.
|
||||
// Technically, on Windows XP SP2, a user could install the redistributable
|
||||
// and make our assumption incorrect. We opt to avoid making a bunch of
|
||||
// spurious LoadLibrary calls in the common case rather than load the
|
||||
// WLAN API in the edge case.
|
||||
mWlanLibrary = WinWLANLibrary::Load();
|
||||
MOZ_ASSERT(mWlanLibrary);
|
||||
}
|
||||
|
||||
WinWifiScanner::~WinWifiScanner()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
WinWifiScanner::GetAccessPointsFromWLAN(nsCOMArray<nsWifiAccessPoint> &accessPoints)
|
||||
{
|
||||
accessPoints.Clear();
|
||||
|
||||
// NOTE: We do not try to load the WLAN library if we previously failed
|
||||
// to load it. See the note in WinWifiScanner constructor
|
||||
if (!mWlanLibrary) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// Get the list of interfaces. WlanEnumInterfaces allocates interface_list.
|
||||
WLAN_INTERFACE_INFO_LIST *interface_list = nullptr;
|
||||
if (ERROR_SUCCESS !=
|
||||
(*mWlanLibrary->GetWlanEnumInterfacesPtr())(mWlanLibrary->GetWLANHandle(),
|
||||
nullptr,
|
||||
&interface_list)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// This ensures we call WlanFreeMemory on interface_list
|
||||
ScopedWLANObject scopedInterfaceList(mWlanLibrary, interface_list);
|
||||
|
||||
if (!interface_list->dwNumberOfItems) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
InterfaceScanCallbackData cbData(interface_list->dwNumberOfItems);
|
||||
|
||||
DWORD wlanNotifySource;
|
||||
if (ERROR_SUCCESS !=
|
||||
(*mWlanLibrary->GetWlanRegisterNotificationPtr())(
|
||||
mWlanLibrary->GetWLANHandle(),
|
||||
WLAN_NOTIFICATION_SOURCE_ACM,
|
||||
TRUE,
|
||||
(WLAN_NOTIFICATION_CALLBACK)OnScanComplete,
|
||||
&cbData,
|
||||
NULL,
|
||||
&wlanNotifySource)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Go through the list of interfaces and call `WlanScan` on each
|
||||
for (unsigned int i = 0; i < interface_list->dwNumberOfItems; ++i) {
|
||||
if (ERROR_SUCCESS !=
|
||||
(*mWlanLibrary->GetWlanScanPtr())(
|
||||
mWlanLibrary->GetWLANHandle(),
|
||||
&interface_list->InterfaceInfo[i].InterfaceGuid,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL)) {
|
||||
cbData.OnInterfaceScanComplete();
|
||||
}
|
||||
}
|
||||
|
||||
// From the MSDN documentation:
|
||||
// "Wireless network drivers that meet Windows logo requirements are
|
||||
// required to complete a WlanScan function request in 4 seconds"
|
||||
cbData.WaitForAllInterfacesToFinishScanning(5000);
|
||||
|
||||
// Unregister for the notifications. The documentation mentions that,
|
||||
// if a callback is currently running, this will wait for the callback
|
||||
// to complete.
|
||||
(*mWlanLibrary->GetWlanRegisterNotificationPtr())(
|
||||
mWlanLibrary->GetWLANHandle(),
|
||||
WLAN_NOTIFICATION_SOURCE_NONE,
|
||||
TRUE,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&wlanNotifySource);
|
||||
|
||||
// Go through the list of interfaces and get the data for each.
|
||||
for (uint32_t i = 0; i < interface_list->dwNumberOfItems; ++i) {
|
||||
WLAN_BSS_LIST *bss_list;
|
||||
if (ERROR_SUCCESS !=
|
||||
(*mWlanLibrary->GetWlanGetNetworkBssListPtr())(
|
||||
mWlanLibrary->GetWLANHandle(),
|
||||
&interface_list->InterfaceInfo[i].InterfaceGuid,
|
||||
nullptr, // Use all SSIDs.
|
||||
DOT11_BSS_TYPE_UNUSED,
|
||||
false, // bSecurityEnabled - unused
|
||||
nullptr, // reserved
|
||||
&bss_list)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// This ensures we call WlanFreeMemory on bss_list
|
||||
ScopedWLANObject scopedBssList(mWlanLibrary, bss_list);
|
||||
|
||||
// Store each discovered access point in our outparam
|
||||
for (int j = 0; j < static_cast<int>(bss_list->dwNumberOfItems); ++j) {
|
||||
nsWifiAccessPoint* ap = new nsWifiAccessPoint();
|
||||
if (!ap) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const WLAN_BSS_ENTRY bss_entry = bss_list->wlanBssEntries[j];
|
||||
ap->setMac(bss_entry.dot11Bssid);
|
||||
ap->setSignal(bss_entry.lRssi);
|
||||
ap->setSSID(reinterpret_cast<char const*>(bss_entry.dot11Ssid.ucSSID),
|
||||
bss_entry.dot11Ssid.uSSIDLength);
|
||||
|
||||
accessPoints.AppendObject(ap);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
32
netwerk/wifi/win_wifiScanner.h
Normal file
32
netwerk/wifi/win_wifiScanner.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
// Moz headers (alphabetical)
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCOMArray.h"
|
||||
|
||||
class nsWifiAccessPoint;
|
||||
class WinWLANLibrary;
|
||||
|
||||
class WinWifiScanner {
|
||||
public:
|
||||
WinWifiScanner();
|
||||
~WinWifiScanner();
|
||||
|
||||
/**
|
||||
* GetAccessPointsFromWLAN
|
||||
*
|
||||
* Scans the available wireless interfaces for nearby access points and
|
||||
* populates the supplied collection with them
|
||||
*
|
||||
* @param accessPoints The collection to populate with available APs
|
||||
* @return NS_OK on success, failure codes on failure
|
||||
*/
|
||||
nsresult GetAccessPointsFromWLAN(nsCOMArray<nsWifiAccessPoint> &accessPoints);
|
||||
|
||||
private:
|
||||
nsAutoPtr<WinWLANLibrary> mWlanLibrary;
|
||||
};
|
155
netwerk/wifi/win_wlanLibrary.cpp
Normal file
155
netwerk/wifi/win_wlanLibrary.cpp
Normal file
@ -0,0 +1,155 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "win_wlanLibrary.h"
|
||||
|
||||
// Moz headers (alphabetical)
|
||||
|
||||
|
||||
|
||||
WinWLANLibrary*
|
||||
WinWLANLibrary::Load()
|
||||
{
|
||||
WinWLANLibrary *ret = new WinWLANLibrary();
|
||||
if (!ret) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!ret->Initialize()) {
|
||||
delete ret;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
WinWLANLibrary::WinWLANLibrary()
|
||||
: mWlanLibrary(nullptr),
|
||||
mWlanHandle(nullptr),
|
||||
mWlanEnumInterfacesPtr(nullptr),
|
||||
mWlanGetNetworkBssListPtr(nullptr),
|
||||
mWlanFreeMemoryPtr(nullptr),
|
||||
mWlanCloseHandlePtr(nullptr),
|
||||
mWlanOpenHandlePtr(nullptr),
|
||||
mWlanRegisterNotificationPtr(nullptr),
|
||||
mWlanScanPtr(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
HANDLE
|
||||
WinWLANLibrary::GetWLANHandle() const
|
||||
{
|
||||
return mWlanHandle;
|
||||
}
|
||||
|
||||
decltype(::WlanEnumInterfaces)*
|
||||
WinWLANLibrary::GetWlanEnumInterfacesPtr() const
|
||||
{
|
||||
return mWlanEnumInterfacesPtr;
|
||||
}
|
||||
|
||||
decltype(::WlanGetNetworkBssList)*
|
||||
WinWLANLibrary::GetWlanGetNetworkBssListPtr() const
|
||||
{
|
||||
return mWlanGetNetworkBssListPtr;
|
||||
}
|
||||
|
||||
decltype(::WlanFreeMemory)*
|
||||
WinWLANLibrary::GetWlanFreeMemoryPtr() const
|
||||
{
|
||||
return mWlanFreeMemoryPtr;
|
||||
}
|
||||
|
||||
decltype(::WlanCloseHandle)*
|
||||
WinWLANLibrary::GetWlanCloseHandlePtr() const
|
||||
{
|
||||
return mWlanCloseHandlePtr;
|
||||
}
|
||||
|
||||
decltype(::WlanOpenHandle)*
|
||||
WinWLANLibrary::GetWlanOpenHandlePtr() const
|
||||
{
|
||||
return mWlanOpenHandlePtr;
|
||||
}
|
||||
|
||||
decltype(::WlanRegisterNotification)*
|
||||
WinWLANLibrary::GetWlanRegisterNotificationPtr() const
|
||||
{
|
||||
return mWlanRegisterNotificationPtr;
|
||||
}
|
||||
|
||||
decltype(::WlanScan)*
|
||||
WinWLANLibrary::GetWlanScanPtr() const
|
||||
{
|
||||
return mWlanScanPtr;
|
||||
}
|
||||
|
||||
bool
|
||||
WinWLANLibrary::Initialize()
|
||||
{
|
||||
mWlanLibrary = LoadLibrary("Wlanapi.dll");
|
||||
if (!mWlanLibrary) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mWlanOpenHandlePtr =
|
||||
(decltype(::WlanOpenHandle)*) GetProcAddress(mWlanLibrary,
|
||||
"WlanOpenHandle");
|
||||
mWlanEnumInterfacesPtr =
|
||||
(decltype(::WlanEnumInterfaces)*) GetProcAddress(mWlanLibrary,
|
||||
"WlanEnumInterfaces");
|
||||
mWlanRegisterNotificationPtr =
|
||||
(decltype(::WlanRegisterNotification)*) GetProcAddress(mWlanLibrary,
|
||||
"WlanRegisterNotification");
|
||||
mWlanScanPtr =
|
||||
(decltype(::WlanScan)*) GetProcAddress(mWlanLibrary, "WlanScan");
|
||||
|
||||
mWlanFreeMemoryPtr =
|
||||
(decltype(::WlanFreeMemory)*) GetProcAddress(mWlanLibrary,
|
||||
"WlanFreeMemory");
|
||||
mWlanCloseHandlePtr =
|
||||
(decltype(::WlanCloseHandle)*) GetProcAddress(mWlanLibrary,
|
||||
"WlanCloseHandle");
|
||||
mWlanGetNetworkBssListPtr =
|
||||
(decltype(::WlanGetNetworkBssList)*) GetProcAddress(mWlanLibrary,
|
||||
"WlanGetNetworkBssList");
|
||||
|
||||
if (!mWlanOpenHandlePtr ||
|
||||
!mWlanEnumInterfacesPtr ||
|
||||
!mWlanRegisterNotificationPtr ||
|
||||
!mWlanGetNetworkBssListPtr ||
|
||||
!mWlanScanPtr ||
|
||||
!mWlanFreeMemoryPtr ||
|
||||
!mWlanCloseHandlePtr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the handle to the WLAN API.
|
||||
DWORD negotiated_version;
|
||||
// We could be executing on either Windows XP or Windows Vista, so use the
|
||||
// lower version of the client WLAN API. It seems that the negotiated version
|
||||
// is the Vista version irrespective of what we pass!
|
||||
static const int kXpWlanClientVersion = 1;
|
||||
if (ERROR_SUCCESS !=
|
||||
(*mWlanOpenHandlePtr)(kXpWlanClientVersion,
|
||||
nullptr,
|
||||
&negotiated_version,
|
||||
&mWlanHandle)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
WinWLANLibrary::~WinWLANLibrary()
|
||||
{
|
||||
if (mWlanLibrary) {
|
||||
if (mWlanHandle) {
|
||||
(*mWlanCloseHandlePtr)(mWlanLibrary, mWlanHandle);
|
||||
mWlanHandle = nullptr;
|
||||
}
|
||||
::FreeLibrary(mWlanLibrary);
|
||||
mWlanLibrary = nullptr;
|
||||
}
|
||||
}
|
59
netwerk/wifi/win_wlanLibrary.h
Normal file
59
netwerk/wifi/win_wlanLibrary.h
Normal file
@ -0,0 +1,59 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
// Moz headers (alphabetical)
|
||||
|
||||
// System headers (alphabetical)
|
||||
#include <windows.h> // HINSTANCE, HANDLE
|
||||
#include <wlanapi.h> // Wlan* functions
|
||||
|
||||
|
||||
class WinWLANLibrary {
|
||||
public:
|
||||
static WinWLANLibrary* Load();
|
||||
~WinWLANLibrary();
|
||||
|
||||
HANDLE GetWLANHandle() const;
|
||||
decltype(::WlanEnumInterfaces)* GetWlanEnumInterfacesPtr() const;
|
||||
decltype(::WlanGetNetworkBssList)* GetWlanGetNetworkBssListPtr() const;
|
||||
decltype(::WlanFreeMemory)* GetWlanFreeMemoryPtr() const;
|
||||
decltype(::WlanCloseHandle)* GetWlanCloseHandlePtr() const;
|
||||
decltype(::WlanOpenHandle)* GetWlanOpenHandlePtr() const;
|
||||
decltype(::WlanRegisterNotification)* GetWlanRegisterNotificationPtr() const;
|
||||
decltype(::WlanScan)* GetWlanScanPtr() const;
|
||||
|
||||
private:
|
||||
WinWLANLibrary();
|
||||
bool Initialize();
|
||||
|
||||
HMODULE mWlanLibrary;
|
||||
HANDLE mWlanHandle;
|
||||
decltype(::WlanEnumInterfaces)* mWlanEnumInterfacesPtr;
|
||||
decltype(::WlanGetNetworkBssList)* mWlanGetNetworkBssListPtr;
|
||||
decltype(::WlanFreeMemory)* mWlanFreeMemoryPtr;
|
||||
decltype(::WlanCloseHandle)* mWlanCloseHandlePtr;
|
||||
decltype(::WlanOpenHandle)* mWlanOpenHandlePtr;
|
||||
decltype(::WlanRegisterNotification)* mWlanRegisterNotificationPtr;
|
||||
decltype(::WlanScan)* mWlanScanPtr;
|
||||
};
|
||||
|
||||
class ScopedWLANObject {
|
||||
public:
|
||||
ScopedWLANObject(WinWLANLibrary* library, void* object)
|
||||
: mObject(object),
|
||||
mLibrary(library)
|
||||
{
|
||||
}
|
||||
|
||||
~ScopedWLANObject()
|
||||
{
|
||||
(*(mLibrary->GetWlanFreeMemoryPtr()))(mObject);
|
||||
}
|
||||
|
||||
private:
|
||||
WinWLANLibrary *mLibrary;
|
||||
void *mObject;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user