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

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

mercurial