Commit 693959c4 authored by hubbe's avatar hubbe Committed by Commit bot

Cast: Allow extension to control wifi options on windows

This allows the cast extension to turn off wifi scan while
streaming is in progress, and also set the "media streaming mode"
further experimentation is need to see if these options are actually
useful.

BUG=410500

Review URL: https://codereview.chromium.org/566243005

Cr-Commit-Position: refs/heads/master@{#296253}
parent 37c07808
...@@ -106,6 +106,16 @@ CastTransportSenderImpl::CastTransportSenderImpl( ...@@ -106,6 +106,16 @@ CastTransportSenderImpl::CastTransportSenderImpl(
transport_->StartReceiving( transport_->StartReceiving(
base::Bind(&CastTransportSenderImpl::OnReceivedPacket, base::Bind(&CastTransportSenderImpl::OnReceivedPacket,
weak_factory_.GetWeakPtr())); weak_factory_.GetWeakPtr()));
int wifi_options = 0;
if (options->HasKey("disable_wifi_scan")) {
wifi_options |= net::WIFI_OPTIONS_DISABLE_SCAN;
}
if (options->HasKey("media_streaming_mode")) {
wifi_options |= net::WIFI_OPTIONS_MEDIA_STREAMING_MODE;
}
if (wifi_options) {
wifi_options_autoreset_ = net::SetWifiOptions(wifi_options);
}
} }
} }
......
...@@ -56,11 +56,14 @@ class CastTransportSenderImpl : public CastTransportSender { ...@@ -56,11 +56,14 @@ class CastTransportSenderImpl : public CastTransportSender {
// |raw_events_callback| is a null callback. // |raw_events_callback| is a null callback.
// |options| contains optional settings for the transport, possible // |options| contains optional settings for the transport, possible
// keys are: // keys are:
// "DSCP" (value doesn't matter) - turns DSCP on // "DSCP" (value ignored) - turns DSCP on
// "pacer_target_burst_size": int - specifies how many packets to send // "pacer_target_burst_size": int - specifies how many packets to send
// per 10 ms ideally. // per 10 ms ideally.
// "pacer_max_burst_size": int - specifies how many pakcets to send // "pacer_max_burst_size": int - specifies how many pakcets to send
// per 10 ms, max // per 10 ms, max
// "disable_wifi_scan" (value ignored) - disable wifi scans while streaming
// "media_streaming_mode" (value ignored) - turn media streaming mode on
// Note, these options may be ignored on some platforms.
CastTransportSenderImpl( CastTransportSenderImpl(
net::NetLog* net_log, net::NetLog* net_log,
base::TickClock* clock, base::TickClock* clock,
...@@ -165,6 +168,8 @@ class CastTransportSenderImpl : public CastTransportSender { ...@@ -165,6 +168,8 @@ class CastTransportSenderImpl : public CastTransportSender {
// audio packet. // audio packet.
int64 last_byte_acked_for_audio_; int64 last_byte_acked_for_audio_;
scoped_ptr<net::ScopedWifiOptions> wifi_options_autoreset_;
base::WeakPtrFactory<CastTransportSenderImpl> weak_factory_; base::WeakPtrFactory<CastTransportSenderImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(CastTransportSenderImpl); DISALLOW_COPY_AND_ASSIGN(CastTransportSenderImpl);
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/test/simple_test_tick_clock.h" #include "base/test/simple_test_tick_clock.h"
#include "base/values.h"
#include "media/cast/cast_config.h" #include "media/cast/cast_config.h"
#include "media/cast/net/cast_transport_config.h" #include "media/cast/net/cast_transport_config.h"
#include "media/cast/net/cast_transport_sender_impl.h" #include "media/cast/net/cast_transport_sender_impl.h"
...@@ -90,6 +91,27 @@ class CastTransportSenderImplTest : public ::testing::Test { ...@@ -90,6 +91,27 @@ class CastTransportSenderImplTest : public ::testing::Test {
task_runner_->RunTasks(); task_runner_->RunTasks();
} }
void InitWithOptions() {
scoped_ptr<base::DictionaryValue> options(
new base::DictionaryValue);
options->SetBoolean("DHCP", true);
options->SetBoolean("disable_wifi_scan", true);
options->SetBoolean("media_streaming_mode", true);
options->SetInteger("pacer_target_burst_size", 20);
options->SetInteger("pacer_max_burst_size", 100);
transport_sender_.reset(
new CastTransportSenderImpl(NULL,
&testing_clock_,
net::IPEndPoint(),
options.Pass(),
base::Bind(&UpdateCastTransportStatus),
BulkRawEventsCallback(),
base::TimeDelta(),
task_runner_,
&transport_));
task_runner_->RunTasks();
}
void InitWithLogging() { void InitWithLogging() {
transport_sender_.reset(new CastTransportSenderImpl( transport_sender_.reset(new CastTransportSenderImpl(
NULL, NULL,
...@@ -152,6 +174,12 @@ TEST_F(CastTransportSenderImplTest, InitWithLogging) { ...@@ -152,6 +174,12 @@ TEST_F(CastTransportSenderImplTest, InitWithLogging) {
EXPECT_EQ(5, num_times_callback_called_); EXPECT_EQ(5, num_times_callback_called_);
} }
TEST_F(CastTransportSenderImplTest, InitWithOptions) {
InitWithOptions();
task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50));
EXPECT_EQ(0, num_times_callback_called_);
}
TEST_F(CastTransportSenderImplTest, NacksCancelRetransmits) { TEST_F(CastTransportSenderImplTest, NacksCancelRetransmits) {
InitWithoutLogging(); InitWithoutLogging();
InitializeVideo(); InitializeVideo();
......
...@@ -1040,4 +1040,7 @@ unsigned MaskPrefixLength(const IPAddressNumber& mask) { ...@@ -1040,4 +1040,7 @@ unsigned MaskPrefixLength(const IPAddressNumber& mask) {
return CommonPrefixLength(mask, all_ones); return CommonPrefixLength(mask, all_ones);
} }
ScopedWifiOptions::~ScopedWifiOptions() {
}
} // namespace net } // namespace net
...@@ -518,6 +518,28 @@ enum WifiPHYLayerProtocol { ...@@ -518,6 +518,28 @@ enum WifiPHYLayerProtocol {
// Currently only available on OS_WIN. // Currently only available on OS_WIN.
NET_EXPORT WifiPHYLayerProtocol GetWifiPHYLayerProtocol(); NET_EXPORT WifiPHYLayerProtocol GetWifiPHYLayerProtocol();
enum WifiOptions {
// Disables background SSID scans.
WIFI_OPTIONS_DISABLE_SCAN = 1 << 0,
// Enables media streaming mode.
WIFI_OPTIONS_MEDIA_STREAMING_MODE = 1 << 1
};
class NET_EXPORT ScopedWifiOptions {
public:
ScopedWifiOptions() {}
virtual ~ScopedWifiOptions();
private:
DISALLOW_COPY_AND_ASSIGN(ScopedWifiOptions);
};
// Set temporary options on all wifi interfaces.
// |options| is an ORed bitfield of WifiOptions.
// Options are automatically disabled when the scoped pointer
// is freed. Currently only available on OS_WIN.
NET_EXPORT scoped_ptr<ScopedWifiOptions> SetWifiOptions(int options);
// Returns number of matching initial bits between the addresses |a1| and |a2|. // Returns number of matching initial bits between the addresses |a1| and |a2|.
unsigned CommonPrefixLength(const IPAddressNumber& a1, unsigned CommonPrefixLength(const IPAddressNumber& a1,
const IPAddressNumber& a2); const IPAddressNumber& a2);
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/string_tokenizer.h" #include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
...@@ -284,4 +285,9 @@ WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { ...@@ -284,4 +285,9 @@ WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN;
} }
scoped_ptr<ScopedWifiOptions> SetWifiOptions(int options) {
return scoped_ptr<ScopedWifiOptions>();
}
} // namespace net } // namespace net
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <iphlpapi.h> #include <iphlpapi.h>
#include <objbase.h> #include <objbase.h>
#include "base/win/windows_version.h" #include "base/win/windows_version.h"
#include "net/base/net_util_win.h"
#elif !defined(OS_ANDROID) #elif !defined(OS_ANDROID)
#include <net/if.h> #include <net/if.h>
#endif // OS_WIN #endif // OS_WIN
...@@ -790,6 +791,114 @@ TEST(NetUtilTest, GetNetworkList) { ...@@ -790,6 +791,114 @@ TEST(NetUtilTest, GetNetworkList) {
} }
} }
namespace {
#if defined(OS_WIN)
bool read_int_or_bool(DWORD data_size,
PVOID data) {
switch (data_size) {
case 1:
return !!*reinterpret_cast<uint8*>(data);
case 4:
return !!*reinterpret_cast<uint32*>(data);
default:
LOG(FATAL) << "That is not a type I know!";
return false;
}
}
int GetWifiOptions() {
const internal::WlanApi& wlanapi = internal::WlanApi::GetInstance();
if (!wlanapi.initialized)
return -1;
internal::WlanHandle client;
DWORD cur_version = 0;
const DWORD kMaxClientVersion = 2;
DWORD result = wlanapi.OpenHandle(
kMaxClientVersion, &cur_version, &client);
if (result != ERROR_SUCCESS)
return -1;
WLAN_INTERFACE_INFO_LIST* interface_list_ptr = NULL;
result = wlanapi.enum_interfaces_func(client, NULL, &interface_list_ptr);
if (result != ERROR_SUCCESS)
return -1;
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];
DWORD data_size;
PVOID data;
int options = 0;
result = wlanapi.query_interface_func(
client,
&info->InterfaceGuid,
wlan_intf_opcode_background_scan_enabled,
NULL,
&data_size,
&data,
NULL);
if (result != ERROR_SUCCESS)
continue;
if (!read_int_or_bool(data_size, data)) {
options |= WIFI_OPTIONS_DISABLE_SCAN;
}
internal::WlanApi::GetInstance().free_memory_func(data);
result = wlanapi.query_interface_func(
client,
&info->InterfaceGuid,
wlan_intf_opcode_media_streaming_mode,
NULL,
&data_size,
&data,
NULL);
if (result != ERROR_SUCCESS)
continue;
if (read_int_or_bool(data_size, data)) {
options |= WIFI_OPTIONS_MEDIA_STREAMING_MODE;
}
internal::WlanApi::GetInstance().free_memory_func(data);
// Just the the options from the first succesful
// interface.
return options;
}
// No wifi interface found.
return -1;
}
#else // OS_WIN
int GetWifiOptions() {
// Not supported.
return -1;
}
#endif // OS_WIN
void TryChangeWifiOptions(int options) {
int previous_options = GetWifiOptions();
scoped_ptr<ScopedWifiOptions> scoped_options = SetWifiOptions(options);
EXPECT_EQ(previous_options | options, GetWifiOptions());
scoped_options.reset();
EXPECT_EQ(previous_options, GetWifiOptions());
}
}; // namespace
// Test SetWifiOptions().
TEST(NetUtilTest, SetWifiOptionsTest) {
TryChangeWifiOptions(0);
TryChangeWifiOptions(WIFI_OPTIONS_DISABLE_SCAN);
TryChangeWifiOptions(WIFI_OPTIONS_MEDIA_STREAMING_MODE);
TryChangeWifiOptions(WIFI_OPTIONS_DISABLE_SCAN |
WIFI_OPTIONS_MEDIA_STREAMING_MODE);
}
struct NonUniqueNameTestData { struct NonUniqueNameTestData {
bool is_unique; bool is_unique;
const char* hostname; const char* hostname;
......
...@@ -22,67 +22,13 @@ ...@@ -22,67 +22,13 @@
#include "net/base/escape.h" #include "net/base/escape.h"
#include "net/base/ip_endpoint.h" #include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
#include "net/base/net_util_win.h"
#include "url/gurl.h" #include "url/gurl.h"
namespace net { namespace net {
namespace { 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. // Converts Windows defined types to NetworkInterfaceType.
NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(DWORD ifType) { NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(DWORD ifType) {
// Bail out for pre-Vista versions of Windows which are documented to give // Bail out for pre-Vista versions of Windows which are documented to give
...@@ -104,6 +50,43 @@ NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(DWORD ifType) { ...@@ -104,6 +50,43 @@ NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(DWORD ifType) {
} // namespace } // 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) { bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
// GetAdaptersAddresses() may require IO operations. // GetAdaptersAddresses() may require IO operations.
base::ThreadRestrictions::AssertIOAllowed(); base::ThreadRestrictions::AssertIOAllowed();
...@@ -221,39 +204,11 @@ bool GetNetworkList(NetworkInterfaceList* networks, int policy) { ...@@ -221,39 +204,11 @@ bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
} }
WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
static base::LazyInstance<WlanApi>::Leaky lazy_wlanapi = const internal::WlanApi& wlanapi = internal::WlanApi::GetInstance();
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();
if (!wlanapi.initialized) if (!wlanapi.initialized)
return WIFI_PHY_LAYER_PROTOCOL_NONE; return WIFI_PHY_LAYER_PROTOCOL_NONE;
WlanHandle client; internal::WlanHandle client;
DWORD cur_version = 0; DWORD cur_version = 0;
const DWORD kMaxClientVersion = 2; const DWORD kMaxClientVersion = 2;
DWORD result = wlanapi.OpenHandle(kMaxClientVersion, &cur_version, &client); DWORD result = wlanapi.OpenHandle(kMaxClientVersion, &cur_version, &client);
...@@ -264,7 +219,7 @@ WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { ...@@ -264,7 +219,7 @@ WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
result = wlanapi.enum_interfaces_func(client, NULL, &interface_list_ptr); result = wlanapi.enum_interfaces_func(client, NULL, &interface_list_ptr);
if (result != ERROR_SUCCESS) if (result != ERROR_SUCCESS)
return WIFI_PHY_LAYER_PROTOCOL_NONE; 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); interface_list_ptr);
// Assume at most one connected wifi interface. // Assume at most one connected wifi interface.
...@@ -288,7 +243,7 @@ WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { ...@@ -288,7 +243,7 @@ WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
&conn_info_size, reinterpret_cast<VOID**>(&conn_info_ptr), &op_code); &conn_info_size, reinterpret_cast<VOID**>(&conn_info_ptr), &op_code);
if (result != ERROR_SUCCESS) if (result != ERROR_SUCCESS)
return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; 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); conn_info_ptr);
switch (conn_info->wlanAssociationAttributes.dot11PhyType) { switch (conn_info->wlanAssociationAttributes.dot11PhyType) {
...@@ -311,4 +266,59 @@ WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { ...@@ -311,4 +266,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 } // namespace net
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_BASE_NET_UTIL_WIN_H_
#define NET_BASE_NET_UTIL_WIN_H_
// This file is only used to expose some of the internals
// of net_util_win.cc to tests.
#include <wlanapi.h>
#include "base/win/scoped_handle.h"
#include "net/base/net_export.h"
namespace net {
namespace internal {
struct NET_EXPORT 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 DWORD (WINAPI *WlanSetInterfaceFunc)(
HANDLE, const GUID*, WLAN_INTF_OPCODE, DWORD, const VOID*, VOID*);
typedef VOID (WINAPI *WlanFreeMemoryFunc)(VOID*);
typedef DWORD (WINAPI *WlanCloseHandleFunc)(HANDLE, VOID*);
WlanApi();
static WlanApi& GetInstance();
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;
WlanSetInterfaceFunc set_interface_func;
WlanFreeMemoryFunc free_memory_func;
WlanCloseHandleFunc close_handle_func;
bool initialized;
};
struct WlanApiHandleTraits {
typedef HANDLE Handle;
static bool CloseHandle(HANDLE handle) {
return WlanApi::GetInstance().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 {
WlanApi::GetInstance().free_memory_func(ptr);
}
};
} // namespace internal
} // namespace net
#endif // NET_BASE_NET_UTIL_WIN_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment