Index: net/base/net_util_win.cc |
diff --git a/net/base/net_util_win.cc b/net/base/net_util_win.cc |
index cac92e39d54bbb391814190d1faf0ed440c61848..ebe3523dd7fc6ea54500bfb117d40f612a6cd050 100644 |
--- a/net/base/net_util_win.cc |
+++ b/net/base/net_util_win.cc |
@@ -22,67 +22,13 @@ |
#include "net/base/escape.h" |
#include "net/base/ip_endpoint.h" |
#include "net/base/net_errors.h" |
+#include "net/base/net_util_win.h" |
#include "url/gurl.h" |
namespace net { |
namespace { |
-struct WlanApi { |
- typedef DWORD (WINAPI *WlanOpenHandleFunc)( |
- DWORD, VOID*, DWORD*, HANDLE*); |
- typedef DWORD (WINAPI *WlanEnumInterfacesFunc)( |
- HANDLE, VOID*, WLAN_INTERFACE_INFO_LIST**); |
- typedef DWORD (WINAPI *WlanQueryInterfaceFunc)( |
- HANDLE, const GUID*, WLAN_INTF_OPCODE, VOID*, DWORD*, VOID**, |
- WLAN_OPCODE_VALUE_TYPE*); |
- typedef VOID (WINAPI *WlanFreeMemoryFunc)(VOID*); |
- typedef DWORD (WINAPI *WlanCloseHandleFunc)(HANDLE, VOID*); |
- |
- WlanApi() : initialized(false) { |
- // Use an absolute path to load the DLL to avoid DLL preloading attacks. |
- static const wchar_t* const kDLL = L"%WINDIR%\\system32\\wlanapi.dll"; |
- wchar_t path[MAX_PATH] = {0}; |
- ExpandEnvironmentStrings(kDLL, path, arraysize(path)); |
- module = ::LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); |
- if (!module) |
- return; |
- |
- open_handle_func = reinterpret_cast<WlanOpenHandleFunc>( |
- ::GetProcAddress(module, "WlanOpenHandle")); |
- enum_interfaces_func = reinterpret_cast<WlanEnumInterfacesFunc>( |
- ::GetProcAddress(module, "WlanEnumInterfaces")); |
- query_interface_func = reinterpret_cast<WlanQueryInterfaceFunc>( |
- ::GetProcAddress(module, "WlanQueryInterface")); |
- free_memory_func = reinterpret_cast<WlanFreeMemoryFunc>( |
- ::GetProcAddress(module, "WlanFreeMemory")); |
- close_handle_func = reinterpret_cast<WlanCloseHandleFunc>( |
- ::GetProcAddress(module, "WlanCloseHandle")); |
- initialized = open_handle_func && enum_interfaces_func && |
- query_interface_func && free_memory_func && |
- close_handle_func; |
- } |
- |
- template <typename T> |
- DWORD OpenHandle(DWORD client_version, DWORD* cur_version, T* handle) const { |
- HANDLE temp_handle; |
- DWORD result = open_handle_func(client_version, NULL, cur_version, |
- &temp_handle); |
- if (result != ERROR_SUCCESS) |
- return result; |
- handle->Set(temp_handle); |
- return ERROR_SUCCESS; |
- } |
- |
- HMODULE module; |
- WlanOpenHandleFunc open_handle_func; |
- WlanEnumInterfacesFunc enum_interfaces_func; |
- WlanQueryInterfaceFunc query_interface_func; |
- WlanFreeMemoryFunc free_memory_func; |
- WlanCloseHandleFunc close_handle_func; |
- bool initialized; |
-}; |
- |
// Converts Windows defined types to NetworkInterfaceType. |
NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(DWORD ifType) { |
// Bail out for pre-Vista versions of Windows which are documented to give |
@@ -104,6 +50,43 @@ NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(DWORD ifType) { |
} // namespace |
+namespace internal { |
+ |
+base::LazyInstance<WlanApi>::Leaky lazy_wlanapi = |
+ LAZY_INSTANCE_INITIALIZER; |
+ |
+WlanApi& WlanApi::GetInstance() { |
+ return lazy_wlanapi.Get(); |
+} |
+ |
+WlanApi::WlanApi() : initialized(false) { |
+ // Use an absolute path to load the DLL to avoid DLL preloading attacks. |
+ static const wchar_t* const kDLL = L"%WINDIR%\\system32\\wlanapi.dll"; |
+ wchar_t path[MAX_PATH] = {0}; |
+ ExpandEnvironmentStrings(kDLL, path, arraysize(path)); |
+ module = ::LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); |
+ if (!module) |
+ return; |
+ |
+ open_handle_func = reinterpret_cast<WlanOpenHandleFunc>( |
+ ::GetProcAddress(module, "WlanOpenHandle")); |
+ enum_interfaces_func = reinterpret_cast<WlanEnumInterfacesFunc>( |
+ ::GetProcAddress(module, "WlanEnumInterfaces")); |
+ query_interface_func = reinterpret_cast<WlanQueryInterfaceFunc>( |
+ ::GetProcAddress(module, "WlanQueryInterface")); |
+ set_interface_func = reinterpret_cast<WlanSetInterfaceFunc>( |
+ ::GetProcAddress(module, "WlanSetInterface")); |
+ free_memory_func = reinterpret_cast<WlanFreeMemoryFunc>( |
+ ::GetProcAddress(module, "WlanFreeMemory")); |
+ close_handle_func = reinterpret_cast<WlanCloseHandleFunc>( |
+ ::GetProcAddress(module, "WlanCloseHandle")); |
+ initialized = open_handle_func && enum_interfaces_func && |
+ query_interface_func && set_interface_func && |
+ free_memory_func && close_handle_func; |
+} |
+ |
+} // namespace internal |
+ |
bool GetNetworkList(NetworkInterfaceList* networks, int policy) { |
// GetAdaptersAddresses() may require IO operations. |
base::ThreadRestrictions::AssertIOAllowed(); |
@@ -216,39 +199,11 @@ bool GetNetworkList(NetworkInterfaceList* networks, int policy) { |
} |
WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { |
- static base::LazyInstance<WlanApi>::Leaky lazy_wlanapi = |
- LAZY_INSTANCE_INITIALIZER; |
- |
- struct WlanApiHandleTraits { |
- typedef HANDLE Handle; |
- |
- static bool CloseHandle(HANDLE handle) { |
- return lazy_wlanapi.Get().close_handle_func(handle, NULL) == |
- ERROR_SUCCESS; |
- } |
- static bool IsHandleValid(HANDLE handle) { |
- return base::win::HandleTraits::IsHandleValid(handle); |
- } |
- static HANDLE NullHandle() { |
- return base::win::HandleTraits::NullHandle(); |
- } |
- }; |
- |
- typedef base::win::GenericScopedHandle< |
- WlanApiHandleTraits, |
- base::win::DummyVerifierTraits> WlanHandle; |
- |
- struct WlanApiDeleter { |
- inline void operator()(void* ptr) const { |
- lazy_wlanapi.Get().free_memory_func(ptr); |
- } |
- }; |
- |
- const WlanApi& wlanapi = lazy_wlanapi.Get(); |
+ const internal::WlanApi& wlanapi = internal::WlanApi::GetInstance(); |
if (!wlanapi.initialized) |
return WIFI_PHY_LAYER_PROTOCOL_NONE; |
- WlanHandle client; |
+ internal::WlanHandle client; |
DWORD cur_version = 0; |
const DWORD kMaxClientVersion = 2; |
DWORD result = wlanapi.OpenHandle(kMaxClientVersion, &cur_version, &client); |
@@ -259,7 +214,7 @@ WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { |
result = wlanapi.enum_interfaces_func(client, NULL, &interface_list_ptr); |
if (result != ERROR_SUCCESS) |
return WIFI_PHY_LAYER_PROTOCOL_NONE; |
- scoped_ptr<WLAN_INTERFACE_INFO_LIST, WlanApiDeleter> interface_list( |
+ scoped_ptr<WLAN_INTERFACE_INFO_LIST, internal::WlanApiDeleter> interface_list( |
interface_list_ptr); |
// Assume at most one connected wifi interface. |
@@ -283,7 +238,7 @@ WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { |
&conn_info_size, reinterpret_cast<VOID**>(&conn_info_ptr), &op_code); |
if (result != ERROR_SUCCESS) |
return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; |
- scoped_ptr<WLAN_CONNECTION_ATTRIBUTES, WlanApiDeleter> conn_info( |
+ scoped_ptr<WLAN_CONNECTION_ATTRIBUTES, internal::WlanApiDeleter> conn_info( |
conn_info_ptr); |
switch (conn_info->wlanAssociationAttributes.dot11PhyType) { |
@@ -306,4 +261,59 @@ WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { |
} |
} |
+// Note: There is no need to explicitly set the options back |
+// as the OS will automatically set them back when the WlanHandle |
+// is closed. |
+class WifiOptionSetter : public ScopedWifiOptions { |
+ public: |
+ WifiOptionSetter(int options) { |
+ const internal::WlanApi& wlanapi = internal::WlanApi::GetInstance(); |
+ if (!wlanapi.initialized) |
+ return; |
+ |
+ DWORD cur_version = 0; |
+ const DWORD kMaxClientVersion = 2; |
+ DWORD result = wlanapi.OpenHandle( |
+ kMaxClientVersion, &cur_version, &client_); |
+ if (result != ERROR_SUCCESS) |
+ return; |
+ |
+ WLAN_INTERFACE_INFO_LIST* interface_list_ptr = NULL; |
+ result = wlanapi.enum_interfaces_func(client_, NULL, &interface_list_ptr); |
+ if (result != ERROR_SUCCESS) |
+ return; |
+ scoped_ptr<WLAN_INTERFACE_INFO_LIST, internal::WlanApiDeleter> |
+ interface_list(interface_list_ptr); |
+ |
+ for (unsigned i = 0; i < interface_list->dwNumberOfItems; ++i) { |
+ WLAN_INTERFACE_INFO* info = &interface_list->InterfaceInfo[i]; |
+ if (options & WIFI_OPTIONS_DISABLE_SCAN) { |
+ BOOL data = false; |
+ wlanapi.set_interface_func(client_, |
+ &info->InterfaceGuid, |
+ wlan_intf_opcode_background_scan_enabled, |
+ sizeof(data), |
+ &data, |
+ NULL); |
+ } |
+ if (options & WIFI_OPTIONS_MEDIA_STREAMING_MODE) { |
+ BOOL data = true; |
+ wlanapi.set_interface_func(client_, |
+ &info->InterfaceGuid, |
+ wlan_intf_opcode_media_streaming_mode, |
+ sizeof(data), |
+ &data, |
+ NULL); |
+ } |
+ } |
+ } |
+ |
+ private: |
+ internal::WlanHandle client_; |
+}; |
+ |
+scoped_ptr<ScopedWifiOptions> SetWifiOptions(int options) { |
+ return scoped_ptr<ScopedWifiOptions>(new WifiOptionSetter(options)); |
+} |
+ |
} // namespace net |