| 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
|
|
|