Index: net/base/net_util_win.cc |
diff --git a/net/base/net_util_win.cc b/net/base/net_util_win.cc |
index 5b101aede6b8c4654f29aa487be27b63835d35aa..f2d2fa414ea1ae01aeeb4085ee207fead7b039ce 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" |
rvargas (doing something else)
2013/02/11 21:14:44
not good.
Note that I failed to mention the other
szym
2013/02/11 22:51:19
Done.
|
#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"))); |
+ 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; |
rvargas (doing something else)
2013/02/11 21:14:44
This should be a GenericScopedHandle with a custom
szym
2013/02/11 22:51:19
Done.
|
+ DWORD cur_version = 0; |
+ DWORD result = open_handle_func(2 /* max_client */, NULL, &cur_version, |
+ &client); |
+ if (result != ERROR_SUCCESS) |
+ return WIFI_PHY_MODE_NONE; |
+ base::ScopedClosureRunner close_handle( |
+ base::Bind(base::IgnoreResult(close_handle_func), client, (VOID*)NULL)); |
+ |
+ WLAN_INTERFACE_INFO_LIST* interface_list = NULL; |
rvargas (doing something else)
2013/02/11 21:14:44
scoped_ptr with custom Deleter
szym
2013/02/11 22:51:19
Done, although there does not seem to be something
|
+ 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)); |
+ |
+ if (interface_list->dwNumberOfItems == 0) |
+ return WIFI_PHY_MODE_NONE; |
+ |
+ // Assume one wifi interface. |
+ WLAN_INTERFACE_INFO& info = interface_list->InterfaceInfo[0]; |
+ if (info.isState != wlan_interface_state_connected) |
+ return WIFI_PHY_MODE_NONE; |
rvargas (doing something else)
2013/02/11 21:14:44
look at the next interface?
szym
2013/02/11 22:51:19
Done.
|
+ |
+ WLAN_CONNECTION_ATTRIBUTES* conn_info = NULL; |
rvargas (doing something else)
2013/02/11 21:14:44
same here
szym
2013/02/11 22:51:19
Done.
|
+ 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); |
rvargas (doing something else)
2013/02/11 21:14:44
c++ cast (Doesn't this work without a cast?)
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 |