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 5debd7228110ee83cab0bc050fcc47122016c10c..0f5f8cafc729a0d467f829eb561c4fff5e3d6161 100644 |
| --- a/net/base/net_util_win.cc |
| +++ b/net/base/net_util_win.cc |
| @@ -5,11 +5,15 @@ |
| #include "net/base/net_util.h" |
| #include <iphlpapi.h> |
| +#include <wlanapi.h> |
| #include <algorithm> |
| +#include "base/bind.h" |
| +#include "base/bind_helpers.h" |
| #include "base/file_path.h" |
| #include "base/memory/scoped_ptr.h" |
| +#include "base/scoped_native_library.h" |
| #include "base/string_piece.h" |
| #include "base/string_util.h" |
| #include "base/sys_string_conversions.h" |
| @@ -127,4 +131,91 @@ bool GetNetworkList(NetworkInterfaceList* networks) { |
| return true; |
| } |
| +WifiPhyMode GetWifiPhyMode() { |
| + 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*); |
| + |
| + base::ScopedNativeLibrary wlanapi( |
| + FilePath(FILE_PATH_LITERAL("wlanapi.dll"))); |
|
Ryan Sleevi
2013/02/11 18:32:28
See rvargas' previous comments re: ScopedNativeLib
szym
2013/02/11 22:51:19
From my experiments, this takes a while, on Window
|
| + WlanOpenHandleFunc open_handle_func = reinterpret_cast<WlanOpenHandleFunc>( |
| + wlanapi.GetFunctionPointer("WlanOpenHandle")); |
| + WlanEnumInterfacesFunc enum_interfaces_func = |
| + reinterpret_cast<WlanEnumInterfacesFunc>( |
| + wlanapi.GetFunctionPointer("WlanEnumInterfaces")); |
| + WlanQueryInterfaceFunc query_interface_func = |
| + reinterpret_cast<WlanQueryInterfaceFunc>( |
| + wlanapi.GetFunctionPointer("WlanQueryInterface")); |
| + WlanFreeMemoryFunc free_memory_func = reinterpret_cast<WlanFreeMemoryFunc>( |
| + wlanapi.GetFunctionPointer("WlanFreeMemory")); |
| + WlanCloseHandleFunc close_handle_func = |
| + reinterpret_cast<WlanCloseHandleFunc>( |
| + wlanapi.GetFunctionPointer("WlanCloseHandle")); |
| + if (!(open_handle_func && enum_interfaces_func && query_interface_func && |
| + free_memory_func && close_handle_func)) { |
| + return WIFI_PHY_MODE_NONE; |
| + } |
| + |
| + HANDLE client = NULL; |
| + DWORD cur_version = 0; |
| + DWORD result = open_handle_func(2 /* max_client */, NULL, &cur_version, |
|
Ryan Sleevi
2013/02/11 18:32:28
Can you make this a meaningful constant?
const DW
szym
2013/02/11 22:51:19
Done.
|
| + &client); |
| + if (result != ERROR_SUCCESS) |
| + return WIFI_PHY_MODE_NONE; |
| + base::ScopedClosureRunner close_handle( |
| + base::Bind(base::IgnoreResult(close_handle_func), client, (VOID*)NULL)); |
|
Ryan Sleevi
2013/02/11 18:32:28
style nit: c-style casts are no good.
Other point
szym
2013/02/11 22:51:19
I didn't think HANDLE can be scoped_ptr'ed.
|
| + |
| + WLAN_INTERFACE_INFO_LIST* interface_list = NULL; |
| + result = enum_interfaces_func(client, NULL, &interface_list); |
| + if (result != ERROR_SUCCESS) |
| + return WIFI_PHY_MODE_NONE; |
| + base::ScopedClosureRunner free_interfaces( |
| + base::Bind(free_memory_func, interface_list)); |
|
Ryan Sleevi
2013/02/11 18:32:28
same here
|
| + |
| + if (interface_list->dwNumberOfItems == 0) |
| + return WIFI_PHY_MODE_NONE; |
| + |
| + // Assume one wifi interface. |
|
Ryan Sleevi
2013/02/11 18:32:28
Why?
Should we be treating the results as a colle
szym
2013/02/11 22:51:19
Yes. No. But I'd guesstimate this works for >95% o
|
| + WLAN_INTERFACE_INFO& info = interface_list->InterfaceInfo[0]; |
| + if (info.isState != wlan_interface_state_connected) |
| + return WIFI_PHY_MODE_NONE; |
| + |
| + WLAN_CONNECTION_ATTRIBUTES* conn_info = NULL; |
| + DWORD conn_info_size = 0; |
| + WLAN_OPCODE_VALUE_TYPE op_code; |
| + |
| + result = query_interface_func( |
| + client, &info.InterfaceGuid, wlan_intf_opcode_current_connection, NULL, |
| + &conn_info_size, (VOID**)&conn_info, &op_code); |
|
Ryan Sleevi
2013/02/11 18:32:28
style nit: wrong casts
szym
2013/02/11 22:51:19
Done.
|
| + if (result != ERROR_SUCCESS) |
| + return WIFI_PHY_MODE_UNKNOWN; |
| + base::ScopedClosureRunner free_conn_info( |
| + base::Bind(free_memory_func, conn_info)); |
| + |
| + switch (conn_info->wlanAssociationAttributes.dot11PhyType) { |
| + case dot11_phy_type_fhss: |
| + return WIFI_PHY_MODE_ANCIENT; |
| + case dot11_phy_type_dsss: |
| + return WIFI_PHY_MODE_B; |
| + case dot11_phy_type_irbaseband: |
| + return WIFI_PHY_MODE_ANCIENT; |
| + case dot11_phy_type_ofdm: |
| + return WIFI_PHY_MODE_A; |
| + case dot11_phy_type_hrdsss: |
| + return WIFI_PHY_MODE_B; |
| + case dot11_phy_type_erp: |
| + return WIFI_PHY_MODE_G; |
| + case dot11_phy_type_ht: |
| + return WIFI_PHY_MODE_N; |
| + default: |
| + return WIFI_PHY_MODE_UNKNOWN; |
| + } |
| +} |
| + |
| } // namespace net |