OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/base/net_util.h" | 5 #include "net/base/net_util.h" |
6 | 6 |
7 #include <iphlpapi.h> | 7 #include <iphlpapi.h> |
8 #include <wlanapi.h> | 8 #include <wlanapi.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
11 | 11 |
12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
14 #include "base/memory/lifetime_interface.h" | |
14 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
15 #include "base/strings/string_piece.h" | 16 #include "base/strings/string_piece.h" |
16 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
17 #include "base/strings/sys_string_conversions.h" | 18 #include "base/strings/sys_string_conversions.h" |
18 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
19 #include "base/threading/thread_restrictions.h" | 20 #include "base/threading/thread_restrictions.h" |
20 #include "base/win/scoped_handle.h" | 21 #include "base/win/scoped_handle.h" |
21 #include "base/win/windows_version.h" | 22 #include "base/win/windows_version.h" |
22 #include "net/base/escape.h" | 23 #include "net/base/escape.h" |
23 #include "net/base/ip_endpoint.h" | 24 #include "net/base/ip_endpoint.h" |
24 #include "net/base/net_errors.h" | 25 #include "net/base/net_errors.h" |
25 #include "url/gurl.h" | 26 #include "url/gurl.h" |
26 | 27 |
27 namespace net { | 28 namespace net { |
28 | 29 |
29 namespace { | 30 namespace { |
30 | 31 |
31 struct WlanApi { | 32 struct WlanApi { |
32 typedef DWORD (WINAPI *WlanOpenHandleFunc)( | 33 typedef DWORD (WINAPI *WlanOpenHandleFunc)( |
33 DWORD, VOID*, DWORD*, HANDLE*); | 34 DWORD, VOID*, DWORD*, HANDLE*); |
34 typedef DWORD (WINAPI *WlanEnumInterfacesFunc)( | 35 typedef DWORD (WINAPI *WlanEnumInterfacesFunc)( |
35 HANDLE, VOID*, WLAN_INTERFACE_INFO_LIST**); | 36 HANDLE, VOID*, WLAN_INTERFACE_INFO_LIST**); |
36 typedef DWORD (WINAPI *WlanQueryInterfaceFunc)( | 37 typedef DWORD (WINAPI *WlanQueryInterfaceFunc)( |
37 HANDLE, const GUID*, WLAN_INTF_OPCODE, VOID*, DWORD*, VOID**, | 38 HANDLE, const GUID*, WLAN_INTF_OPCODE, VOID*, DWORD*, VOID**, |
38 WLAN_OPCODE_VALUE_TYPE*); | 39 WLAN_OPCODE_VALUE_TYPE*); |
40 typedef DWORD (WINAPI *WlanSetInterfaceFunc)( | |
41 HANDLE, const GUID*, WLAN_INTF_OPCODE, DWORD, const VOID*, VOID*); | |
39 typedef VOID (WINAPI *WlanFreeMemoryFunc)(VOID*); | 42 typedef VOID (WINAPI *WlanFreeMemoryFunc)(VOID*); |
40 typedef DWORD (WINAPI *WlanCloseHandleFunc)(HANDLE, VOID*); | 43 typedef DWORD (WINAPI *WlanCloseHandleFunc)(HANDLE, VOID*); |
41 | 44 |
42 WlanApi() : initialized(false) { | 45 WlanApi() : initialized(false) { |
43 // Use an absolute path to load the DLL to avoid DLL preloading attacks. | 46 // Use an absolute path to load the DLL to avoid DLL preloading attacks. |
44 static const wchar_t* const kDLL = L"%WINDIR%\\system32\\wlanapi.dll"; | 47 static const wchar_t* const kDLL = L"%WINDIR%\\system32\\wlanapi.dll"; |
45 wchar_t path[MAX_PATH] = {0}; | 48 wchar_t path[MAX_PATH] = {0}; |
46 ExpandEnvironmentStrings(kDLL, path, arraysize(path)); | 49 ExpandEnvironmentStrings(kDLL, path, arraysize(path)); |
47 module = ::LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); | 50 module = ::LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); |
48 if (!module) | 51 if (!module) |
49 return; | 52 return; |
50 | 53 |
51 open_handle_func = reinterpret_cast<WlanOpenHandleFunc>( | 54 open_handle_func = reinterpret_cast<WlanOpenHandleFunc>( |
52 ::GetProcAddress(module, "WlanOpenHandle")); | 55 ::GetProcAddress(module, "WlanOpenHandle")); |
53 enum_interfaces_func = reinterpret_cast<WlanEnumInterfacesFunc>( | 56 enum_interfaces_func = reinterpret_cast<WlanEnumInterfacesFunc>( |
54 ::GetProcAddress(module, "WlanEnumInterfaces")); | 57 ::GetProcAddress(module, "WlanEnumInterfaces")); |
55 query_interface_func = reinterpret_cast<WlanQueryInterfaceFunc>( | 58 query_interface_func = reinterpret_cast<WlanQueryInterfaceFunc>( |
56 ::GetProcAddress(module, "WlanQueryInterface")); | 59 ::GetProcAddress(module, "WlanQueryInterface")); |
60 set_interface_func = reinterpret_cast<WlanSetInterfaceFunc>( | |
61 ::GetProcAddress(module, "WlanSetInterface")); | |
57 free_memory_func = reinterpret_cast<WlanFreeMemoryFunc>( | 62 free_memory_func = reinterpret_cast<WlanFreeMemoryFunc>( |
58 ::GetProcAddress(module, "WlanFreeMemory")); | 63 ::GetProcAddress(module, "WlanFreeMemory")); |
59 close_handle_func = reinterpret_cast<WlanCloseHandleFunc>( | 64 close_handle_func = reinterpret_cast<WlanCloseHandleFunc>( |
60 ::GetProcAddress(module, "WlanCloseHandle")); | 65 ::GetProcAddress(module, "WlanCloseHandle")); |
61 initialized = open_handle_func && enum_interfaces_func && | 66 initialized = open_handle_func && enum_interfaces_func && |
62 query_interface_func && free_memory_func && | 67 query_interface_func && free_memory_func && |
63 close_handle_func; | 68 close_handle_func; |
64 } | 69 } |
65 | 70 |
66 template <typename T> | 71 template <typename T> |
67 DWORD OpenHandle(DWORD client_version, DWORD* cur_version, T* handle) const { | 72 DWORD OpenHandle(DWORD client_version, DWORD* cur_version, T* handle) const { |
68 HANDLE temp_handle; | 73 HANDLE temp_handle; |
69 DWORD result = open_handle_func(client_version, NULL, cur_version, | 74 DWORD result = open_handle_func(client_version, NULL, cur_version, |
70 &temp_handle); | 75 &temp_handle); |
71 if (result != ERROR_SUCCESS) | 76 if (result != ERROR_SUCCESS) |
72 return result; | 77 return result; |
73 handle->Set(temp_handle); | 78 handle->Set(temp_handle); |
74 return ERROR_SUCCESS; | 79 return ERROR_SUCCESS; |
75 } | 80 } |
76 | 81 |
77 HMODULE module; | 82 HMODULE module; |
78 WlanOpenHandleFunc open_handle_func; | 83 WlanOpenHandleFunc open_handle_func; |
79 WlanEnumInterfacesFunc enum_interfaces_func; | 84 WlanEnumInterfacesFunc enum_interfaces_func; |
80 WlanQueryInterfaceFunc query_interface_func; | 85 WlanQueryInterfaceFunc query_interface_func; |
86 WlanSetInterfaceFunc set_interface_func; | |
81 WlanFreeMemoryFunc free_memory_func; | 87 WlanFreeMemoryFunc free_memory_func; |
82 WlanCloseHandleFunc close_handle_func; | 88 WlanCloseHandleFunc close_handle_func; |
83 bool initialized; | 89 bool initialized; |
84 }; | 90 }; |
85 | 91 |
86 // Converts Windows defined types to NetworkInterfaceType. | 92 // Converts Windows defined types to NetworkInterfaceType. |
87 NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(DWORD ifType) { | 93 NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(DWORD ifType) { |
88 // Bail out for pre-Vista versions of Windows which are documented to give | 94 // Bail out for pre-Vista versions of Windows which are documented to give |
89 // inaccurate results like returning Ethernet for WiFi. | 95 // inaccurate results like returning Ethernet for WiFi. |
90 // http://msdn.microsoft.com/en-us/library/windows/desktop/aa366058.aspx | 96 // http://msdn.microsoft.com/en-us/library/windows/desktop/aa366058.aspx |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
208 } | 214 } |
209 } | 215 } |
210 } | 216 } |
211 | 217 |
212 if (ipv6_address.get()) { | 218 if (ipv6_address.get()) { |
213 networks->push_back(*(ipv6_address.get())); | 219 networks->push_back(*(ipv6_address.get())); |
214 } | 220 } |
215 return true; | 221 return true; |
216 } | 222 } |
217 | 223 |
218 WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { | 224 namespace { |
pauljensen
2014/09/16 15:01:18
I think moving this up into the anonymous namespac
hubbe
2014/09/16 21:06:50
Done.
| |
219 static base::LazyInstance<WlanApi>::Leaky lazy_wlanapi = | 225 base::LazyInstance<WlanApi>::Leaky lazy_wlanapi = |
220 LAZY_INSTANCE_INITIALIZER; | 226 LAZY_INSTANCE_INITIALIZER; |
221 | 227 |
222 struct WlanApiHandleTraits { | 228 struct WlanApiHandleTraits { |
223 typedef HANDLE Handle; | 229 typedef HANDLE Handle; |
224 | 230 |
225 static bool CloseHandle(HANDLE handle) { | 231 static bool CloseHandle(HANDLE handle) { |
226 return lazy_wlanapi.Get().close_handle_func(handle, NULL) == | 232 return lazy_wlanapi.Get().close_handle_func(handle, NULL) == |
227 ERROR_SUCCESS; | 233 ERROR_SUCCESS; |
228 } | 234 } |
229 static bool IsHandleValid(HANDLE handle) { | 235 static bool IsHandleValid(HANDLE handle) { |
230 return base::win::HandleTraits::IsHandleValid(handle); | 236 return base::win::HandleTraits::IsHandleValid(handle); |
231 } | 237 } |
232 static HANDLE NullHandle() { | 238 static HANDLE NullHandle() { |
233 return base::win::HandleTraits::NullHandle(); | 239 return base::win::HandleTraits::NullHandle(); |
234 } | 240 } |
235 }; | 241 }; |
236 | 242 |
237 typedef base::win::GenericScopedHandle< | 243 typedef base::win::GenericScopedHandle< |
238 WlanApiHandleTraits, | 244 WlanApiHandleTraits, |
239 base::win::DummyVerifierTraits> WlanHandle; | 245 base::win::DummyVerifierTraits> WlanHandle; |
240 | 246 |
241 struct WlanApiDeleter { | 247 struct WlanApiDeleter { |
242 inline void operator()(void* ptr) const { | 248 inline void operator()(void* ptr) const { |
243 lazy_wlanapi.Get().free_memory_func(ptr); | 249 lazy_wlanapi.Get().free_memory_func(ptr); |
244 } | 250 } |
245 }; | 251 }; |
252 }; | |
pauljensen
2014/09/16 15:01:18
// namespace
hubbe
2014/09/16 21:06:51
No longer relevant.
| |
246 | 253 |
254 WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { | |
247 const WlanApi& wlanapi = lazy_wlanapi.Get(); | 255 const WlanApi& wlanapi = lazy_wlanapi.Get(); |
248 if (!wlanapi.initialized) | 256 if (!wlanapi.initialized) |
249 return WIFI_PHY_LAYER_PROTOCOL_NONE; | 257 return WIFI_PHY_LAYER_PROTOCOL_NONE; |
250 | 258 |
251 WlanHandle client; | 259 WlanHandle client; |
252 DWORD cur_version = 0; | 260 DWORD cur_version = 0; |
253 const DWORD kMaxClientVersion = 2; | 261 const DWORD kMaxClientVersion = 2; |
254 DWORD result = wlanapi.OpenHandle(kMaxClientVersion, &cur_version, &client); | 262 DWORD result = wlanapi.OpenHandle(kMaxClientVersion, &cur_version, &client); |
255 if (result != ERROR_SUCCESS) | 263 if (result != ERROR_SUCCESS) |
256 return WIFI_PHY_LAYER_PROTOCOL_NONE; | 264 return WIFI_PHY_LAYER_PROTOCOL_NONE; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
299 return WIFI_PHY_LAYER_PROTOCOL_B; | 307 return WIFI_PHY_LAYER_PROTOCOL_B; |
300 case dot11_phy_type_erp: | 308 case dot11_phy_type_erp: |
301 return WIFI_PHY_LAYER_PROTOCOL_G; | 309 return WIFI_PHY_LAYER_PROTOCOL_G; |
302 case dot11_phy_type_ht: | 310 case dot11_phy_type_ht: |
303 return WIFI_PHY_LAYER_PROTOCOL_N; | 311 return WIFI_PHY_LAYER_PROTOCOL_N; |
304 default: | 312 default: |
305 return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; | 313 return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; |
306 } | 314 } |
307 } | 315 } |
308 | 316 |
317 class WifiOptionSetter : public base::LifetimeInterface { | |
318 public: | |
319 WifiOptionSetter(int options) { | |
pauljensen
2014/09/16 15:01:18
indent
hubbe
2014/09/16 21:06:50
Done (finally configured emacs on my windows box,
| |
320 const WlanApi& wlanapi = lazy_wlanapi.Get(); | |
321 if (!wlanapi.initialized) | |
322 return; | |
323 | |
324 DWORD cur_version = 0; | |
325 const DWORD kMaxClientVersion = 2; | |
pauljensen
2014/09/16 15:01:18
Please add a comment about where this 0 and 2 come
hubbe
2014/09/16 21:06:50
Gladly, but I don't know. I copied this from line
| |
326 DWORD result = wlanapi.OpenHandle( | |
327 kMaxClientVersion, &cur_version, &client_); | |
328 if (result != ERROR_SUCCESS) | |
329 return; | |
330 | |
331 WLAN_INTERFACE_INFO_LIST* interface_list_ptr = NULL; | |
332 result = wlanapi.enum_interfaces_func(client_, NULL, &interface_list_ptr); | |
333 if (result != ERROR_SUCCESS) | |
334 return; | |
335 scoped_ptr<WLAN_INTERFACE_INFO_LIST, WlanApiDeleter> interface_list( | |
336 interface_list_ptr); | |
337 | |
338 // Assume at most one connected wifi interface. | |
pauljensen
2014/09/16 15:01:18
"at most one"? This function appears to loop thro
hubbe
2014/09/16 21:06:50
Oops, removed.
| |
339 WLAN_INTERFACE_INFO* info = NULL; | |
340 for (unsigned i = 0; i < interface_list->dwNumberOfItems; ++i) { | |
341 if (options & WIFI_OPTIONS_DISABLE_SCAN) { | |
342 BOOL data = false; | |
343 wlanapi.set_interface_func(client_, | |
344 &info->InterfaceGuid, | |
345 wlan_intf_opcode_background_scan_enabled, | |
346 sizeof(data), | |
347 &data, | |
348 NULL); | |
349 } | |
350 if (options & WIFI_OPTIONS_MEDIA_STREAMING_MODE) { | |
351 BOOL data = true; | |
352 wlanapi.set_interface_func(client_, | |
353 &info->InterfaceGuid, | |
354 wlan_intf_opcode_media_streaming_mode, | |
355 sizeof(data), | |
356 &data, | |
357 NULL); | |
358 } | |
359 } | |
360 } | |
361 | |
pauljensen
2014/09/16 15:01:18
Maybe I'm missing something, but shouldn't there b
hubbe
2014/09/16 21:06:51
If I'm reading the documentation correctly, the OS
| |
362 private: | |
363 WlanHandle client_; | |
364 }; | |
365 | |
366 scoped_ptr<base::LifetimeInterface> SetWifiOptions(int options) { | |
367 return scoped_ptr<base::LifetimeInterface>( | |
368 new WifiOptionSetter(options)); | |
369 } | |
370 | |
309 } // namespace net | 371 } // namespace net |
OLD | NEW |