netwerk/wifi/nsWifiScannerWin.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/netwerk/wifi/nsWifiScannerWin.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,131 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +
     1.9 +#include "windows.h"
    1.10 +#include "wlanapi.h"
    1.11 +
    1.12 +#include "stdlib.h"
    1.13 +
    1.14 +#include "nsWifiMonitor.h"
    1.15 +#include "nsWifiAccessPoint.h"
    1.16 +
    1.17 +#include "nsServiceManagerUtils.h"
    1.18 +#include "nsComponentManagerUtils.h"
    1.19 +#include "nsIMutableArray.h"
    1.20 +
    1.21 +#define DOT11_BSS_TYPE_UNUSED static_cast<DOT11_BSS_TYPE>(0)
    1.22 +
    1.23 +using namespace mozilla;
    1.24 +
    1.25 +nsresult
    1.26 +nsWifiMonitor::DoScan()
    1.27 +{
    1.28 +    HINSTANCE wlan_library = LoadLibrary("Wlanapi.dll");
    1.29 +    if (!wlan_library)
    1.30 +      return NS_ERROR_NOT_AVAILABLE;
    1.31 +
    1.32 +    decltype(::WlanOpenHandle)* WlanOpenHandle = (decltype(::WlanOpenHandle)*) GetProcAddress(wlan_library, "WlanOpenHandle");
    1.33 +    decltype(::WlanEnumInterfaces)* WlanEnumInterfaces = (decltype(::WlanEnumInterfaces)*) GetProcAddress(wlan_library, "WlanEnumInterfaces");
    1.34 +    decltype(::WlanGetNetworkBssList)* WlanGetNetworkBssList = (decltype(::WlanGetNetworkBssList)*) GetProcAddress(wlan_library, "WlanGetNetworkBssList");
    1.35 +    decltype(::WlanFreeMemory)* WlanFreeMemory = (decltype(::WlanFreeMemory)*) GetProcAddress(wlan_library, "WlanFreeMemory");
    1.36 +    decltype(::WlanCloseHandle)* WlanCloseHandle = (decltype(::WlanCloseHandle)*) GetProcAddress(wlan_library, "WlanCloseHandle");
    1.37 +
    1.38 +    if (!WlanOpenHandle ||
    1.39 +        !WlanEnumInterfaces ||
    1.40 +        !WlanGetNetworkBssList ||
    1.41 +        !WlanFreeMemory ||
    1.42 +        !WlanCloseHandle)
    1.43 +      return NS_ERROR_FAILURE;
    1.44 +
    1.45 +    // Regularly get the access point data.
    1.46 +
    1.47 +    nsCOMArray<nsWifiAccessPoint> lastAccessPoints;
    1.48 +    nsCOMArray<nsWifiAccessPoint> accessPoints;
    1.49 +
    1.50 +    do {
    1.51 +      accessPoints.Clear();
    1.52 +
    1.53 +      // Get the handle to the WLAN API.
    1.54 +      DWORD negotiated_version;
    1.55 +      HANDLE wlan_handle = nullptr;
    1.56 +      // We could be executing on either Windows XP or Windows Vista, so use the
    1.57 +      // lower version of the client WLAN API. It seems that the negotiated version
    1.58 +      // is the Vista version irrespective of what we pass!
    1.59 +      static const int kXpWlanClientVersion = 1;
    1.60 +      if ((*WlanOpenHandle)(kXpWlanClientVersion,
    1.61 +                            nullptr,
    1.62 +                            &negotiated_version,
    1.63 +                            &wlan_handle) != ERROR_SUCCESS) {
    1.64 +        return NS_ERROR_NOT_AVAILABLE;
    1.65 +      }
    1.66 +
    1.67 +      // try again later.
    1.68 +      if (!wlan_handle)
    1.69 +        return NS_ERROR_FAILURE;
    1.70 +
    1.71 +      // Get the list of interfaces. WlanEnumInterfaces allocates interface_list.
    1.72 +      WLAN_INTERFACE_INFO_LIST *interface_list = nullptr;
    1.73 +      if ((*WlanEnumInterfaces)(wlan_handle, nullptr, &interface_list) != ERROR_SUCCESS) {
    1.74 +        // try again later
    1.75 +        (*WlanCloseHandle)(wlan_handle, nullptr);
    1.76 +        return NS_ERROR_FAILURE;
    1.77 +      }
    1.78 +
    1.79 +      // Go through the list of interfaces and get the data for each.
    1.80 +      for (int i = 0; i < static_cast<int>(interface_list->dwNumberOfItems); ++i) {
    1.81 +
    1.82 +        WLAN_BSS_LIST *bss_list;
    1.83 +        HRESULT rv = (*WlanGetNetworkBssList)(wlan_handle,
    1.84 +                                              &interface_list->InterfaceInfo[i].InterfaceGuid,
    1.85 +                                              nullptr,  // Use all SSIDs.
    1.86 +                                              DOT11_BSS_TYPE_UNUSED,
    1.87 +                                              false,    // bSecurityEnabled - unused
    1.88 +                                              nullptr,  // reserved
    1.89 +                                              &bss_list);
    1.90 +        if (rv != ERROR_SUCCESS) {
    1.91 +          continue;
    1.92 +        }
    1.93 +
    1.94 +        for (int j = 0; j < static_cast<int>(bss_list->dwNumberOfItems); ++j) {
    1.95 +
    1.96 +          nsWifiAccessPoint* ap = new nsWifiAccessPoint();
    1.97 +          if (!ap)
    1.98 +            continue;
    1.99 +
   1.100 +          const WLAN_BSS_ENTRY bss_entry = bss_list->wlanBssEntries[j];
   1.101 +
   1.102 +          ap->setMac(bss_entry.dot11Bssid);
   1.103 +          ap->setSignal(bss_entry.lRssi);
   1.104 +          ap->setSSID((char*) bss_entry.dot11Ssid.ucSSID,
   1.105 +                      bss_entry.dot11Ssid.uSSIDLength);
   1.106 +
   1.107 +          accessPoints.AppendObject(ap);
   1.108 +        }
   1.109 +        (*WlanFreeMemory)(bss_list);
   1.110 +      }
   1.111 +
   1.112 +      // Free interface_list.
   1.113 +      (*WlanFreeMemory)(interface_list);
   1.114 +
   1.115 +      // Close the handle.
   1.116 +      (*WlanCloseHandle)(wlan_handle, nullptr);
   1.117 +
   1.118 +
   1.119 +      bool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
   1.120 +      ReplaceArray(lastAccessPoints, accessPoints);
   1.121 +
   1.122 +      nsresult rv = CallWifiListeners(lastAccessPoints, accessPointsChanged);
   1.123 +      NS_ENSURE_SUCCESS(rv, rv);
   1.124 +
   1.125 +      // wait for some reasonable amount of time.  pref?
   1.126 +      LOG(("waiting on monitor\n"));
   1.127 +
   1.128 +      ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   1.129 +      mon.Wait(PR_SecondsToInterval(60));
   1.130 +    }
   1.131 +    while (mKeepGoing);
   1.132 +
   1.133 +    return NS_OK;
   1.134 +}

mercurial