Chromium Code Reviews| 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..254ed84f3efb0c262de9f7755ff0d434fc4521af 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,40 @@ NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(DWORD ifType) { |
| } // namespace |
| + |
| +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; |
| +} |
| + |
| bool GetNetworkList(NetworkInterfaceList* networks, int policy) { |
| // GetAdaptersAddresses() may require IO operations. |
| base::ThreadRestrictions::AssertIOAllowed(); |
| @@ -174,7 +154,8 @@ bool GetNetworkList(NetworkInterfaceList* networks, int policy) { |
| IPNumberMatchesPrefix(endpoint.address(), |
| network_endpoint.address(), |
| prefix->PrefixLength)) { |
| - net_prefix = std::max<size_t>(net_prefix, prefix->PrefixLength); |
| + net_prefix = std::max<size_t>(net_prefix, |
| + prefix->PrefixLength); |
|
pauljensen
2014/09/23 14:03:55
unnecessary change?
hubbe
2014/09/23 17:37:50
Done.
|
| } |
| } |
| } |
| @@ -216,35 +197,7 @@ 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 WlanApi& wlanapi = WlanApi::GetInstance(); |
| if (!wlanapi.initialized) |
| return WIFI_PHY_LAYER_PROTOCOL_NONE; |
| @@ -306,4 +259,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. |
|
pauljensen
2014/09/23 14:03:55
I couldn't find any documentation for this. Have
hubbe
2014/09/23 17:37:49
It's very poorly documented, but the documentation
|
| +class WifiOptionSetter : public ScopedWifiOptions { |
| + public: |
| + WifiOptionSetter(int options) { |
| + const WlanApi& wlanapi = 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, 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: |
| + WlanHandle client_; |
| +}; |
| + |
| +scoped_ptr<ScopedWifiOptions> SetWifiOptions(int options) { |
| + return scoped_ptr<ScopedWifiOptions>(new WifiOptionSetter(options)); |
| +} |
| + |
| } // namespace net |