netwerk/wifi/nsWifiScannerWin.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "windows.h"
     7 #include "wlanapi.h"
     9 #include "stdlib.h"
    11 #include "nsWifiMonitor.h"
    12 #include "nsWifiAccessPoint.h"
    14 #include "nsServiceManagerUtils.h"
    15 #include "nsComponentManagerUtils.h"
    16 #include "nsIMutableArray.h"
    18 #define DOT11_BSS_TYPE_UNUSED static_cast<DOT11_BSS_TYPE>(0)
    20 using namespace mozilla;
    22 nsresult
    23 nsWifiMonitor::DoScan()
    24 {
    25     HINSTANCE wlan_library = LoadLibrary("Wlanapi.dll");
    26     if (!wlan_library)
    27       return NS_ERROR_NOT_AVAILABLE;
    29     decltype(::WlanOpenHandle)* WlanOpenHandle = (decltype(::WlanOpenHandle)*) GetProcAddress(wlan_library, "WlanOpenHandle");
    30     decltype(::WlanEnumInterfaces)* WlanEnumInterfaces = (decltype(::WlanEnumInterfaces)*) GetProcAddress(wlan_library, "WlanEnumInterfaces");
    31     decltype(::WlanGetNetworkBssList)* WlanGetNetworkBssList = (decltype(::WlanGetNetworkBssList)*) GetProcAddress(wlan_library, "WlanGetNetworkBssList");
    32     decltype(::WlanFreeMemory)* WlanFreeMemory = (decltype(::WlanFreeMemory)*) GetProcAddress(wlan_library, "WlanFreeMemory");
    33     decltype(::WlanCloseHandle)* WlanCloseHandle = (decltype(::WlanCloseHandle)*) GetProcAddress(wlan_library, "WlanCloseHandle");
    35     if (!WlanOpenHandle ||
    36         !WlanEnumInterfaces ||
    37         !WlanGetNetworkBssList ||
    38         !WlanFreeMemory ||
    39         !WlanCloseHandle)
    40       return NS_ERROR_FAILURE;
    42     // Regularly get the access point data.
    44     nsCOMArray<nsWifiAccessPoint> lastAccessPoints;
    45     nsCOMArray<nsWifiAccessPoint> accessPoints;
    47     do {
    48       accessPoints.Clear();
    50       // Get the handle to the WLAN API.
    51       DWORD negotiated_version;
    52       HANDLE wlan_handle = nullptr;
    53       // We could be executing on either Windows XP or Windows Vista, so use the
    54       // lower version of the client WLAN API. It seems that the negotiated version
    55       // is the Vista version irrespective of what we pass!
    56       static const int kXpWlanClientVersion = 1;
    57       if ((*WlanOpenHandle)(kXpWlanClientVersion,
    58                             nullptr,
    59                             &negotiated_version,
    60                             &wlan_handle) != ERROR_SUCCESS) {
    61         return NS_ERROR_NOT_AVAILABLE;
    62       }
    64       // try again later.
    65       if (!wlan_handle)
    66         return NS_ERROR_FAILURE;
    68       // Get the list of interfaces. WlanEnumInterfaces allocates interface_list.
    69       WLAN_INTERFACE_INFO_LIST *interface_list = nullptr;
    70       if ((*WlanEnumInterfaces)(wlan_handle, nullptr, &interface_list) != ERROR_SUCCESS) {
    71         // try again later
    72         (*WlanCloseHandle)(wlan_handle, nullptr);
    73         return NS_ERROR_FAILURE;
    74       }
    76       // Go through the list of interfaces and get the data for each.
    77       for (int i = 0; i < static_cast<int>(interface_list->dwNumberOfItems); ++i) {
    79         WLAN_BSS_LIST *bss_list;
    80         HRESULT rv = (*WlanGetNetworkBssList)(wlan_handle,
    81                                               &interface_list->InterfaceInfo[i].InterfaceGuid,
    82                                               nullptr,  // Use all SSIDs.
    83                                               DOT11_BSS_TYPE_UNUSED,
    84                                               false,    // bSecurityEnabled - unused
    85                                               nullptr,  // reserved
    86                                               &bss_list);
    87         if (rv != ERROR_SUCCESS) {
    88           continue;
    89         }
    91         for (int j = 0; j < static_cast<int>(bss_list->dwNumberOfItems); ++j) {
    93           nsWifiAccessPoint* ap = new nsWifiAccessPoint();
    94           if (!ap)
    95             continue;
    97           const WLAN_BSS_ENTRY bss_entry = bss_list->wlanBssEntries[j];
    99           ap->setMac(bss_entry.dot11Bssid);
   100           ap->setSignal(bss_entry.lRssi);
   101           ap->setSSID((char*) bss_entry.dot11Ssid.ucSSID,
   102                       bss_entry.dot11Ssid.uSSIDLength);
   104           accessPoints.AppendObject(ap);
   105         }
   106         (*WlanFreeMemory)(bss_list);
   107       }
   109       // Free interface_list.
   110       (*WlanFreeMemory)(interface_list);
   112       // Close the handle.
   113       (*WlanCloseHandle)(wlan_handle, nullptr);
   116       bool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
   117       ReplaceArray(lastAccessPoints, accessPoints);
   119       nsresult rv = CallWifiListeners(lastAccessPoints, accessPointsChanged);
   120       NS_ENSURE_SUCCESS(rv, rv);
   122       // wait for some reasonable amount of time.  pref?
   123       LOG(("waiting on monitor\n"));
   125       ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   126       mon.Wait(PR_SecondsToInterval(60));
   127     }
   128     while (mKeepGoing);
   130     return NS_OK;
   131 }

mercurial