OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/base/net_util.h" | 5 #include "net/base/net_util.h" |
6 | 6 |
7 #include <iphlpapi.h> | 7 #include <iphlpapi.h> |
| 8 #include <wlanapi.h> |
8 | 9 |
9 #include <algorithm> | 10 #include <algorithm> |
10 | 11 |
11 #include "base/file_path.h" | 12 #include "base/file_path.h" |
| 13 #include "base/lazy_instance.h" |
12 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
13 #include "base/string_piece.h" | 15 #include "base/string_piece.h" |
14 #include "base/string_util.h" | 16 #include "base/string_util.h" |
15 #include "base/sys_string_conversions.h" | 17 #include "base/sys_string_conversions.h" |
16 #include "base/threading/thread_restrictions.h" | 18 #include "base/threading/thread_restrictions.h" |
17 #include "base/utf_string_conversions.h" | 19 #include "base/utf_string_conversions.h" |
| 20 #include "base/win/scoped_handle.h" |
18 #include "googleurl/src/gurl.h" | 21 #include "googleurl/src/gurl.h" |
19 #include "net/base/escape.h" | 22 #include "net/base/escape.h" |
20 #include "net/base/ip_endpoint.h" | 23 #include "net/base/ip_endpoint.h" |
21 #include "net/base/net_errors.h" | 24 #include "net/base/net_errors.h" |
22 | 25 |
23 namespace net { | 26 namespace net { |
24 | 27 |
25 bool FileURLToFilePath(const GURL& url, base::FilePath* file_path) { | 28 bool FileURLToFilePath(const GURL& url, base::FilePath* file_path) { |
26 *file_path = base::FilePath(); | 29 *file_path = base::FilePath(); |
27 std::wstring& file_path_str = const_cast<std::wstring&>(file_path->value()); | 30 std::wstring& file_path_str = const_cast<std::wstring&>(file_path->value()); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 std::string name = adapter->AdapterName; | 123 std::string name = adapter->AdapterName; |
121 networks->push_back(NetworkInterface(name, endpoint.address())); | 124 networks->push_back(NetworkInterface(name, endpoint.address())); |
122 } | 125 } |
123 } | 126 } |
124 } | 127 } |
125 } | 128 } |
126 | 129 |
127 return true; | 130 return true; |
128 } | 131 } |
129 | 132 |
| 133 WifiPhyMode GetWifiPhyMode() { |
| 134 struct WlanApi { |
| 135 typedef DWORD (WINAPI *WlanOpenHandleFunc)( |
| 136 DWORD, VOID*, DWORD*, HANDLE*); |
| 137 typedef DWORD (WINAPI *WlanEnumInterfacesFunc)( |
| 138 HANDLE, VOID*, WLAN_INTERFACE_INFO_LIST **); |
| 139 typedef DWORD (WINAPI *WlanQueryInterfaceFunc)( |
| 140 HANDLE, const GUID *, WLAN_INTF_OPCODE, VOID*, DWORD*, VOID**, |
| 141 WLAN_OPCODE_VALUE_TYPE*); |
| 142 typedef VOID (WINAPI *WlanFreeMemoryFunc)(VOID*); |
| 143 typedef DWORD (WINAPI *WlanCloseHandleFunc)(HANDLE, VOID*); |
| 144 |
| 145 WlanApi() : initialized(false) { |
| 146 // Use an absolute path to load the DLL to avoid DLL preloading attacks. |
| 147 static const wchar_t* const kDLL = L"%WINDIR%\\system32\\wlanapi.dll"; |
| 148 wchar_t path[MAX_PATH] = {0}; |
| 149 ExpandEnvironmentStrings(kDLL, path, arraysize(path)); |
| 150 module = ::LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); |
| 151 if (!module) |
| 152 return; |
| 153 |
| 154 open_handle_func = reinterpret_cast<WlanOpenHandleFunc>( |
| 155 ::GetProcAddress(module, "WlanOpenHandle")); |
| 156 enum_interfaces_func = reinterpret_cast<WlanEnumInterfacesFunc>( |
| 157 ::GetProcAddress(module, "WlanEnumInterfaces")); |
| 158 query_interface_func = reinterpret_cast<WlanQueryInterfaceFunc>( |
| 159 ::GetProcAddress(module, "WlanQueryInterface")); |
| 160 free_memory_func = reinterpret_cast<WlanFreeMemoryFunc>( |
| 161 ::GetProcAddress(module, "WlanFreeMemory")); |
| 162 close_handle_func = reinterpret_cast<WlanCloseHandleFunc>( |
| 163 ::GetProcAddress(module, "WlanCloseHandle")); |
| 164 initialized = open_handle_func && enum_interfaces_func && |
| 165 query_interface_func && free_memory_func && |
| 166 close_handle_func; |
| 167 } |
| 168 |
| 169 HMODULE module; |
| 170 WlanOpenHandleFunc open_handle_func; |
| 171 WlanEnumInterfacesFunc enum_interfaces_func; |
| 172 WlanQueryInterfaceFunc query_interface_func; |
| 173 WlanFreeMemoryFunc free_memory_func; |
| 174 WlanCloseHandleFunc close_handle_func; |
| 175 bool initialized; |
| 176 }; |
| 177 |
| 178 static base::LazyInstance<WlanApi>::Leaky lazy_wlanapi = |
| 179 LAZY_INSTANCE_INITIALIZER; |
| 180 |
| 181 struct WlanApiHandleTraits { |
| 182 typedef HANDLE Handle; |
| 183 |
| 184 static bool CloseHandle(HANDLE handle) { |
| 185 return lazy_wlanapi.Get().close_handle_func(handle, NULL) == |
| 186 ERROR_SUCCESS; |
| 187 } |
| 188 static bool IsHandleValid(HANDLE handle) { |
| 189 return base::win::HandleTraits::IsHandleValid(handle); |
| 190 } |
| 191 static HANDLE NullHandle() { |
| 192 return base::win::HandleTraits::NullHandle(); |
| 193 } |
| 194 }; |
| 195 |
| 196 typedef base::win::GenericScopedHandle<WlanApiHandleTraits, |
| 197 base::win::VerifierTraits> WlanHandle; |
| 198 |
| 199 struct WlanApiDeleter { |
| 200 inline void operator()(void* ptr) const { |
| 201 lazy_wlanapi.Get().free_memory_func(ptr); |
| 202 } |
| 203 }; |
| 204 |
| 205 const WlanApi& wlanapi = lazy_wlanapi.Get(); |
| 206 if (!wlanapi.initialized) |
| 207 return WIFI_PHY_MODE_NONE; |
| 208 |
| 209 WlanHandle client; |
| 210 DWORD cur_version = 0; |
| 211 const DWORD kMaxClientVersion = 2; |
| 212 DWORD result = wlanapi.open_handle_func(kMaxClientVersion, NULL, &cur_version, |
| 213 client.Receive()); |
| 214 if (result != ERROR_SUCCESS) |
| 215 return WIFI_PHY_MODE_NONE; |
| 216 |
| 217 WLAN_INTERFACE_INFO_LIST* interface_list_ptr = NULL; |
| 218 result = wlanapi.enum_interfaces_func(client, NULL, &interface_list_ptr); |
| 219 if (result != ERROR_SUCCESS) |
| 220 return WIFI_PHY_MODE_NONE; |
| 221 scoped_ptr<WLAN_INTERFACE_INFO_LIST, WlanApiDeleter> interface_list( |
| 222 interface_list_ptr); |
| 223 |
| 224 // Assume at most one connected wifi interface. |
| 225 WLAN_INTERFACE_INFO* info = NULL; |
| 226 for (unsigned i = 0; i < interface_list->dwNumberOfItems; ++i) { |
| 227 if (interface_list->InterfaceInfo[i].isState == |
| 228 wlan_interface_state_connected) { |
| 229 info = &interface_list->InterfaceInfo[i]; |
| 230 break; |
| 231 } |
| 232 } |
| 233 |
| 234 if (info == NULL) |
| 235 return WIFI_PHY_MODE_NONE; |
| 236 |
| 237 WLAN_CONNECTION_ATTRIBUTES* conn_info_ptr; |
| 238 DWORD conn_info_size = 0; |
| 239 WLAN_OPCODE_VALUE_TYPE op_code; |
| 240 result = wlanapi.query_interface_func( |
| 241 client, &info->InterfaceGuid, wlan_intf_opcode_current_connection, NULL, |
| 242 &conn_info_size, reinterpret_cast<VOID**>(&conn_info_ptr), &op_code); |
| 243 if (result != ERROR_SUCCESS) |
| 244 return WIFI_PHY_MODE_UNKNOWN; |
| 245 scoped_ptr<WLAN_CONNECTION_ATTRIBUTES, WlanApiDeleter> conn_info( |
| 246 conn_info_ptr); |
| 247 |
| 248 switch (conn_info->wlanAssociationAttributes.dot11PhyType) { |
| 249 case dot11_phy_type_fhss: |
| 250 return WIFI_PHY_MODE_ANCIENT; |
| 251 case dot11_phy_type_dsss: |
| 252 return WIFI_PHY_MODE_B; |
| 253 case dot11_phy_type_irbaseband: |
| 254 return WIFI_PHY_MODE_ANCIENT; |
| 255 case dot11_phy_type_ofdm: |
| 256 return WIFI_PHY_MODE_A; |
| 257 case dot11_phy_type_hrdsss: |
| 258 return WIFI_PHY_MODE_B; |
| 259 case dot11_phy_type_erp: |
| 260 return WIFI_PHY_MODE_G; |
| 261 case dot11_phy_type_ht: |
| 262 return WIFI_PHY_MODE_N; |
| 263 default: |
| 264 return WIFI_PHY_MODE_UNKNOWN; |
| 265 } |
| 266 } |
| 267 |
130 } // namespace net | 268 } // namespace net |
OLD | NEW |