Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 // Windows Vista uses the Native Wifi (WLAN) API for accessing WiFi cards. See | 5 // Windows Vista uses the Native Wifi (WLAN) API for accessing WiFi cards. See |
| 6 // http://msdn.microsoft.com/en-us/library/ms705945(VS.85).aspx. Windows XP | 6 // http://msdn.microsoft.com/en-us/library/ms705945(VS.85).aspx. Windows XP |
| 7 // Service Pack 3 (and Windows XP Service Pack 2, if upgraded with a hot fix) | 7 // Service Pack 3 (and Windows XP Service Pack 2, if upgraded with a hot fix) |
| 8 // also support a limited version of the WLAN API. See | 8 // also support a limited version of the WLAN API. See |
| 9 // http://msdn.microsoft.com/en-us/library/bb204766.aspx. The WLAN API uses | 9 // http://msdn.microsoft.com/en-us/library/bb204766.aspx. The WLAN API uses |
| 10 // wlanapi.h, which is not part of the SDK used by Gears, so is replicated | 10 // wlanapi.h, which is not part of the SDK used by Gears, so is replicated |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 // not to work on XP SP3. So we use WLAN on Vista, and use NDIS directly | 21 // not to work on XP SP3. So we use WLAN on Vista, and use NDIS directly |
| 22 // otherwise. | 22 // otherwise. |
| 23 | 23 |
| 24 #include "device/geolocation/wifi_data_provider_win.h" | 24 #include "device/geolocation/wifi_data_provider_win.h" |
| 25 | 25 |
| 26 #include <windows.h> | 26 #include <windows.h> |
| 27 #include <winioctl.h> | 27 #include <winioctl.h> |
| 28 #include <wlanapi.h> | 28 #include <wlanapi.h> |
| 29 | 29 |
| 30 #include "base/memory/free_deleter.h" | 30 #include "base/memory/free_deleter.h" |
| 31 #include "base/memory/ptr_util.h" | |
| 31 #include "base/metrics/histogram_macros.h" | 32 #include "base/metrics/histogram_macros.h" |
| 32 #include "base/strings/utf_string_conversions.h" | 33 #include "base/strings/utf_string_conversions.h" |
| 33 #include "base/win/windows_version.h" | 34 #include "base/win/windows_version.h" |
| 34 #include "device/geolocation/wifi_data_provider_common.h" | 35 #include "device/geolocation/wifi_data_provider_common.h" |
| 35 #include "device/geolocation/wifi_data_provider_common_win.h" | 36 #include "device/geolocation/wifi_data_provider_common_win.h" |
| 36 #include "device/geolocation/wifi_data_provider_manager.h" | 37 #include "device/geolocation/wifi_data_provider_manager.h" |
| 37 | 38 |
| 38 // Taken from ndis.h for WinCE. | 39 // Taken from ndis.h for WinCE. |
| 39 #define NDIS_STATUS_INVALID_LENGTH ((NDIS_STATUS)0xC0010014L) | 40 #define NDIS_STATUS_INVALID_LENGTH ((NDIS_STATUS)0xC0010014L) |
| 40 #define NDIS_STATUS_BUFFER_TOO_SHORT ((NDIS_STATUS)0xC0010016L) | 41 #define NDIS_STATUS_BUFFER_TOO_SHORT ((NDIS_STATUS)0xC0010016L) |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 // WlanFreeMemory | 80 // WlanFreeMemory |
| 80 typedef VOID(WINAPI* WlanFreeMemoryFunction)(PVOID pMemory); | 81 typedef VOID(WINAPI* WlanFreeMemoryFunction)(PVOID pMemory); |
| 81 | 82 |
| 82 // WlanCloseHandle | 83 // WlanCloseHandle |
| 83 typedef DWORD(WINAPI* WlanCloseHandleFunction)(HANDLE hClientHandle, | 84 typedef DWORD(WINAPI* WlanCloseHandleFunction)(HANDLE hClientHandle, |
| 84 PVOID pReserved); | 85 PVOID pReserved); |
| 85 | 86 |
| 86 // Local classes and functions | 87 // Local classes and functions |
| 87 class WindowsWlanApi : public WifiDataProviderCommon::WlanApiInterface { | 88 class WindowsWlanApi : public WifiDataProviderCommon::WlanApiInterface { |
| 88 public: | 89 public: |
| 90 // Factory function. Will return NULL if this API is unavailable. | |
| 91 static std::unique_ptr<WindowsWlanApi> Create(); | |
| 92 | |
| 93 // Takes ownership of the library handle. | |
| 94 explicit WindowsWlanApi(HINSTANCE library); | |
| 89 ~WindowsWlanApi() override; | 95 ~WindowsWlanApi() override; |
| 90 // Factory function. Will return NULL if this API is unavailable. | |
| 91 static WindowsWlanApi* Create(); | |
| 92 | 96 |
| 93 // WlanApiInterface | 97 // WlanApiInterface |
| 94 bool GetAccessPointData(WifiData::AccessPointDataSet* data) override; | 98 bool GetAccessPointData(WifiData::AccessPointDataSet* data) override; |
| 95 | 99 |
| 96 private: | 100 private: |
| 97 // Takes ownership of the library handle. | |
| 98 explicit WindowsWlanApi(HINSTANCE library); | |
| 99 | |
| 100 // Loads the required functions from the DLL. | 101 // Loads the required functions from the DLL. |
| 101 void GetWLANFunctions(HINSTANCE wlan_library); | 102 void GetWLANFunctions(HINSTANCE wlan_library); |
| 102 int GetInterfaceDataWLAN(HANDLE wlan_handle, | 103 int GetInterfaceDataWLAN(HANDLE wlan_handle, |
| 103 const GUID& interface_id, | 104 const GUID& interface_id, |
| 104 WifiData::AccessPointDataSet* data); | 105 WifiData::AccessPointDataSet* data); |
| 105 | 106 |
| 106 // Logs number of detected wlan interfaces. | 107 // Logs number of detected wlan interfaces. |
| 107 static void LogWlanInterfaceCount(int count); | 108 static void LogWlanInterfaceCount(int count); |
| 108 | 109 |
| 109 // Handle to the wlanapi.dll library. | 110 // Handle to the wlanapi.dll library. |
| 110 HINSTANCE library_; | 111 HINSTANCE library_; |
| 111 | 112 |
| 112 // Function pointers for WLAN | 113 // Function pointers for WLAN |
| 113 WlanOpenHandleFunction WlanOpenHandle_function_; | 114 WlanOpenHandleFunction WlanOpenHandle_function_; |
| 114 WlanEnumInterfacesFunction WlanEnumInterfaces_function_; | 115 WlanEnumInterfacesFunction WlanEnumInterfaces_function_; |
| 115 WlanGetNetworkBssListFunction WlanGetNetworkBssList_function_; | 116 WlanGetNetworkBssListFunction WlanGetNetworkBssList_function_; |
| 116 WlanFreeMemoryFunction WlanFreeMemory_function_; | 117 WlanFreeMemoryFunction WlanFreeMemory_function_; |
| 117 WlanCloseHandleFunction WlanCloseHandle_function_; | 118 WlanCloseHandleFunction WlanCloseHandle_function_; |
| 118 }; | 119 }; |
| 119 | 120 |
| 120 class WindowsNdisApi : public WifiDataProviderCommon::WlanApiInterface { | 121 class WindowsNdisApi : public WifiDataProviderCommon::WlanApiInterface { |
| 121 public: | 122 public: |
| 123 static std::unique_ptr<WindowsNdisApi> Create(); | |
| 124 | |
| 125 // Swaps in content of the vector passed | |
| 126 explicit WindowsNdisApi(std::vector<base::string16>* interface_service_names); | |
| 122 ~WindowsNdisApi() override; | 127 ~WindowsNdisApi() override; |
| 123 static WindowsNdisApi* Create(); | |
| 124 | 128 |
| 125 // WlanApiInterface | 129 // WlanApiInterface |
| 126 bool GetAccessPointData(WifiData::AccessPointDataSet* data) override; | 130 bool GetAccessPointData(WifiData::AccessPointDataSet* data) override; |
| 127 | 131 |
| 128 private: | 132 private: |
| 129 static bool GetInterfacesNDIS( | 133 static bool GetInterfacesNDIS( |
| 130 std::vector<base::string16>* interface_service_names_out); | 134 std::vector<base::string16>* interface_service_names_out); |
| 131 | |
| 132 // Swaps in content of the vector passed | |
| 133 explicit WindowsNdisApi(std::vector<base::string16>* interface_service_names); | |
| 134 | |
| 135 bool GetInterfaceDataNDIS(HANDLE adapter_handle, | 135 bool GetInterfaceDataNDIS(HANDLE adapter_handle, |
| 136 WifiData::AccessPointDataSet* data); | 136 WifiData::AccessPointDataSet* data); |
| 137 // NDIS variables. | 137 // NDIS variables. |
| 138 std::vector<base::string16> interface_service_names_; | 138 std::vector<base::string16> interface_service_names_; |
| 139 | 139 |
| 140 // Remembers scan result buffer size across calls. | 140 // Remembers scan result buffer size across calls. |
| 141 int oid_buffer_size_; | 141 int oid_buffer_size_; |
| 142 }; | 142 }; |
| 143 | 143 |
| 144 // Extracts data for an access point and converts to Gears format. | 144 // Extracts data for an access point and converts to Gears format. |
| 145 bool GetNetworkData(const WLAN_BSS_ENTRY& bss_entry, | 145 bool GetNetworkData(const WLAN_BSS_ENTRY& bss_entry, |
| 146 AccessPointData* access_point_data); | 146 AccessPointData* access_point_data); |
| 147 bool UndefineDosDevice(const base::string16& device_name); | 147 bool UndefineDosDevice(const base::string16& device_name); |
| 148 bool DefineDosDeviceIfNotExists(const base::string16& device_name); | 148 bool DefineDosDeviceIfNotExists(const base::string16& device_name); |
| 149 HANDLE GetFileHandle(const base::string16& device_name); | 149 HANDLE GetFileHandle(const base::string16& device_name); |
| 150 // Makes the OID query and returns a Windows API error code. | 150 // Makes the OID query and returns a Windows API error code. |
| 151 int PerformQuery(HANDLE adapter_handle, | 151 int PerformQuery(HANDLE adapter_handle, |
| 152 BYTE* buffer, | 152 BYTE* buffer, |
| 153 DWORD buffer_size, | 153 DWORD buffer_size, |
| 154 DWORD* bytes_out); | 154 DWORD* bytes_out); |
| 155 bool ResizeBuffer(int requested_size, | 155 bool ResizeBuffer(int requested_size, |
| 156 std::unique_ptr<BYTE, base::FreeDeleter>* buffer); | 156 std::unique_ptr<BYTE, base::FreeDeleter>* buffer); |
| 157 // Gets the system directory and appends a trailing slash if not already | 157 // Gets the system directory and appends a trailing slash if not already |
| 158 // present. | 158 // present. |
| 159 bool GetSystemDirectory(base::string16* path); | 159 bool GetSystemDirectory(base::string16* path); |
| 160 } // namespace | 160 } // anonymous namespace |
| 161 | 161 |
| 162 WifiDataProvider* WifiDataProviderManager::DefaultFactoryFunction() { | 162 WifiDataProvider* WifiDataProviderManager::DefaultFactoryFunction() { |
| 163 return new WifiDataProviderWin(); | 163 return new WifiDataProviderWin(); |
| 164 } | 164 } |
| 165 | 165 |
| 166 WifiDataProviderWin::WifiDataProviderWin() {} | 166 WifiDataProviderWin::WifiDataProviderWin() {} |
| 167 | 167 |
| 168 WifiDataProviderWin::~WifiDataProviderWin() {} | 168 WifiDataProviderWin::~WifiDataProviderWin() {} |
| 169 | 169 |
| 170 WifiDataProviderCommon::WlanApiInterface* WifiDataProviderWin::NewWlanApi() { | 170 std::unique_ptr<WifiDataProviderCommon::WlanApiInterface> |
| 171 WifiDataProviderWin::CreateWlanApi() { | |
| 171 // Use the WLAN interface if we're on Vista and if it's available. Otherwise, | 172 // Use the WLAN interface if we're on Vista and if it's available. Otherwise, |
| 172 // use NDIS. | 173 // use NDIS. |
| 173 WlanApiInterface* api = WindowsWlanApi::Create(); | 174 std::unique_ptr<WlanApiInterface> api = WindowsWlanApi::Create(); |
| 174 if (api) { | 175 if (api) |
| 175 return api; | 176 return api; |
| 176 } | |
| 177 return WindowsNdisApi::Create(); | 177 return WindowsNdisApi::Create(); |
| 178 } | 178 } |
| 179 | 179 |
| 180 WifiPollingPolicy* WifiDataProviderWin::NewPollingPolicy() { | 180 std::unique_ptr<WifiPollingPolicy> WifiDataProviderWin::CreatePollingPolicy() { |
| 181 return new GenericWifiPollingPolicy< | 181 return base::MakeUnique<GenericWifiPollingPolicy< |
| 182 kDefaultPollingInterval, kNoChangePollingInterval, | 182 kDefaultPollingInterval, kNoChangePollingInterval, |
| 183 kTwoNoChangePollingInterval, kNoWifiPollingIntervalMilliseconds>; | 183 kTwoNoChangePollingInterval, kNoWifiPollingIntervalMilliseconds>>(); |
| 184 } | 184 } |
| 185 | 185 |
| 186 // Local classes and functions | 186 // Local classes and functions |
| 187 namespace { | 187 namespace { |
| 188 | 188 |
| 189 // WindowsWlanApi | 189 // WindowsWlanApi |
| 190 WindowsWlanApi::WindowsWlanApi(HINSTANCE library) : library_(library) { | 190 WindowsWlanApi::WindowsWlanApi(HINSTANCE library) : library_(library) { |
| 191 GetWLANFunctions(library_); | 191 GetWLANFunctions(library_); |
| 192 } | 192 } |
| 193 | 193 |
| 194 WindowsWlanApi::~WindowsWlanApi() { | 194 WindowsWlanApi::~WindowsWlanApi() { |
| 195 FreeLibrary(library_); | 195 FreeLibrary(library_); |
| 196 } | 196 } |
| 197 | 197 |
| 198 WindowsWlanApi* WindowsWlanApi::Create() { | 198 std::unique_ptr<WindowsWlanApi> WindowsWlanApi::Create() { |
| 199 if (base::win::GetVersion() < base::win::VERSION_VISTA) | 199 if (base::win::GetVersion() < base::win::VERSION_VISTA) |
| 200 return NULL; | 200 return nullptr; |
| 201 // We use an absolute path to load the DLL to avoid DLL preloading attacks. | 201 // We use an absolute path to load the DLL to avoid DLL preloading attacks. |
| 202 base::string16 system_directory; | 202 base::string16 system_directory; |
| 203 if (!GetSystemDirectory(&system_directory)) { | 203 if (!GetSystemDirectory(&system_directory)) |
| 204 return NULL; | 204 return nullptr; |
| 205 } | |
| 206 DCHECK(!system_directory.empty()); | 205 DCHECK(!system_directory.empty()); |
| 207 base::string16 dll_path = system_directory + L"wlanapi.dll"; | 206 base::string16 dll_path = system_directory + L"wlanapi.dll"; |
| 208 HINSTANCE library = | 207 HINSTANCE library = |
| 209 LoadLibraryEx(dll_path.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH); | 208 LoadLibraryEx(dll_path.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH); |
| 210 if (!library) { | 209 if (!library) |
| 211 return NULL; | 210 return nullptr; |
| 212 } | 211 return base::MakeUnique<WindowsWlanApi>(library); |
| 213 return new WindowsWlanApi(library); | |
| 214 } | 212 } |
| 215 | 213 |
| 216 void WindowsWlanApi::GetWLANFunctions(HINSTANCE wlan_library) { | 214 void WindowsWlanApi::GetWLANFunctions(HINSTANCE wlan_library) { |
| 217 DCHECK(wlan_library); | 215 DCHECK(wlan_library); |
| 218 WlanOpenHandle_function_ = reinterpret_cast<WlanOpenHandleFunction>( | 216 WlanOpenHandle_function_ = reinterpret_cast<WlanOpenHandleFunction>( |
| 219 GetProcAddress(wlan_library, "WlanOpenHandle")); | 217 GetProcAddress(wlan_library, "WlanOpenHandle")); |
| 220 WlanEnumInterfaces_function_ = reinterpret_cast<WlanEnumInterfacesFunction>( | 218 WlanEnumInterfaces_function_ = reinterpret_cast<WlanEnumInterfacesFunction>( |
| 221 GetProcAddress(wlan_library, "WlanEnumInterfaces")); | 219 GetProcAddress(wlan_library, "WlanEnumInterfaces")); |
| 222 WlanGetNetworkBssList_function_ = | 220 WlanGetNetworkBssList_function_ = |
| 223 reinterpret_cast<WlanGetNetworkBssListFunction>( | 221 reinterpret_cast<WlanGetNetworkBssListFunction>( |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 340 // WindowsNdisApi | 338 // WindowsNdisApi |
| 341 WindowsNdisApi::WindowsNdisApi( | 339 WindowsNdisApi::WindowsNdisApi( |
| 342 std::vector<base::string16>* interface_service_names) | 340 std::vector<base::string16>* interface_service_names) |
| 343 : oid_buffer_size_(kInitialBufferSize) { | 341 : oid_buffer_size_(kInitialBufferSize) { |
| 344 DCHECK(!interface_service_names->empty()); | 342 DCHECK(!interface_service_names->empty()); |
| 345 interface_service_names_.swap(*interface_service_names); | 343 interface_service_names_.swap(*interface_service_names); |
| 346 } | 344 } |
| 347 | 345 |
| 348 WindowsNdisApi::~WindowsNdisApi() {} | 346 WindowsNdisApi::~WindowsNdisApi() {} |
| 349 | 347 |
| 350 WindowsNdisApi* WindowsNdisApi::Create() { | 348 std::unique_ptr<WindowsNdisApi> WindowsNdisApi::Create() { |
| 351 std::vector<base::string16> interface_service_names; | 349 std::vector<base::string16> interface_service_names; |
| 352 if (GetInterfacesNDIS(&interface_service_names)) { | 350 if (GetInterfacesNDIS(&interface_service_names)) |
| 353 return new WindowsNdisApi(&interface_service_names); | 351 return base::MakeUnique<WindowsNdisApi>(&interface_service_names); |
| 354 } | 352 return nullptr; |
| 355 return NULL; | |
| 356 } | 353 } |
| 357 | 354 |
| 358 bool WindowsNdisApi::GetAccessPointData(WifiData::AccessPointDataSet* data) { | 355 bool WindowsNdisApi::GetAccessPointData(WifiData::AccessPointDataSet* data) { |
| 359 DCHECK(data); | 356 DCHECK(data); |
| 360 int interfaces_failed = 0; | 357 int interfaces_failed = 0; |
| 361 int interfaces_succeeded = 0; | 358 int interfaces_succeeded = 0; |
| 362 | 359 |
| 363 for (int i = 0; i < static_cast<int>(interface_service_names_.size()); ++i) { | 360 for (int i = 0; i < static_cast<int>(interface_service_names_.size()); ++i) { |
| 364 // First, check that we have a DOS device for this adapter. | 361 // First, check that we have a DOS device for this adapter. |
| 365 if (!DefineDosDeviceIfNotExists(interface_service_names_[i])) { | 362 if (!DefineDosDeviceIfNotExists(interface_service_names_[i])) |
| 366 continue; | 363 continue; |
| 367 } | |
| 368 | 364 |
| 369 // Get the handle to the device. This will fail if the named device is not | 365 // Get the handle to the device. This will fail if the named device is not |
| 370 // valid. | 366 // valid. |
| 371 HANDLE adapter_handle = GetFileHandle(interface_service_names_[i]); | 367 HANDLE adapter_handle = GetFileHandle(interface_service_names_[i]); |
| 372 if (adapter_handle == INVALID_HANDLE_VALUE) { | 368 if (adapter_handle == INVALID_HANDLE_VALUE) |
| 373 continue; | 369 continue; |
| 374 } | |
| 375 | 370 |
| 376 // Get the data. | 371 // Get the data. |
| 377 if (GetInterfaceDataNDIS(adapter_handle, data)) { | 372 if (GetInterfaceDataNDIS(adapter_handle, data)) |
| 378 ++interfaces_succeeded; | 373 ++interfaces_succeeded; |
| 379 } else { | 374 else |
| 380 ++interfaces_failed; | 375 ++interfaces_failed; |
| 381 } | |
| 382 | 376 |
| 383 // Clean up. | 377 // Clean up. |
| 384 CloseHandle(adapter_handle); | 378 CloseHandle(adapter_handle); |
| 385 UndefineDosDevice(interface_service_names_[i]); | 379 UndefineDosDevice(interface_service_names_[i]); |
| 386 } | 380 } |
| 387 | 381 |
| 388 // Return true if at least one interface succeeded, or at the very least none | 382 // Return true if at least one interface succeeded, or at the very least none |
| 389 // failed. | 383 // failed. |
| 390 return interfaces_succeeded > 0 || interfaces_failed == 0; | 384 return interfaces_succeeded > 0 || interfaces_failed == 0; |
| 391 } | 385 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 430 RegCloseKey(network_cards_key); | 424 RegCloseKey(network_cards_key); |
| 431 return true; | 425 return true; |
| 432 } | 426 } |
| 433 | 427 |
| 434 bool WindowsNdisApi::GetInterfaceDataNDIS(HANDLE adapter_handle, | 428 bool WindowsNdisApi::GetInterfaceDataNDIS(HANDLE adapter_handle, |
| 435 WifiData::AccessPointDataSet* data) { | 429 WifiData::AccessPointDataSet* data) { |
| 436 DCHECK(data); | 430 DCHECK(data); |
| 437 | 431 |
| 438 std::unique_ptr<BYTE, base::FreeDeleter> buffer( | 432 std::unique_ptr<BYTE, base::FreeDeleter> buffer( |
| 439 static_cast<BYTE*>(malloc(oid_buffer_size_))); | 433 static_cast<BYTE*>(malloc(oid_buffer_size_))); |
| 440 if (buffer == NULL) { | 434 if (buffer == NULL) |
|
Reilly Grant (use Gerrit)
2017/04/24 19:42:33
!buffer
mcasas
2017/04/24 19:47:35
Done.
| |
| 441 return false; | 435 return false; |
| 442 } | |
| 443 | 436 |
| 444 DWORD bytes_out; | 437 DWORD bytes_out; |
| 445 int result; | 438 int result; |
| 446 | 439 |
| 447 while (true) { | 440 while (true) { |
| 448 bytes_out = 0; | 441 bytes_out = 0; |
| 449 result = PerformQuery(adapter_handle, buffer.get(), oid_buffer_size_, | 442 result = PerformQuery(adapter_handle, buffer.get(), oid_buffer_size_, |
| 450 &bytes_out); | 443 &bytes_out); |
| 451 if (result == ERROR_GEN_FAILURE || // Returned by some Intel cards. | 444 if (result == ERROR_GEN_FAILURE || // Returned by some Intel cards. |
| 452 result == ERROR_INSUFFICIENT_BUFFER || result == ERROR_MORE_DATA || | 445 result == ERROR_INSUFFICIENT_BUFFER || result == ERROR_MORE_DATA || |
| 453 result == NDIS_STATUS_INVALID_LENGTH || | 446 result == NDIS_STATUS_INVALID_LENGTH || |
| 454 result == NDIS_STATUS_BUFFER_TOO_SHORT) { | 447 result == NDIS_STATUS_BUFFER_TOO_SHORT) { |
| 455 // The buffer we supplied is too small, so increase it. bytes_out should | 448 // The buffer we supplied is too small, so increase it. bytes_out should |
| 456 // provide the required buffer size, but this is not always the case. | 449 // provide the required buffer size, but this is not always the case. |
| 457 if (bytes_out > static_cast<DWORD>(oid_buffer_size_)) { | 450 if (bytes_out > static_cast<DWORD>(oid_buffer_size_)) |
| 458 oid_buffer_size_ = bytes_out; | 451 oid_buffer_size_ = bytes_out; |
| 459 } else { | 452 else |
| 460 oid_buffer_size_ *= 2; | 453 oid_buffer_size_ *= 2; |
| 461 } | 454 |
| 462 if (!ResizeBuffer(oid_buffer_size_, &buffer)) { | 455 if (!ResizeBuffer(oid_buffer_size_, &buffer)) { |
| 463 oid_buffer_size_ = kInitialBufferSize; // Reset for next time. | 456 oid_buffer_size_ = kInitialBufferSize; // Reset for next time. |
| 464 return false; | 457 return false; |
| 465 } | 458 } |
| 466 } else { | 459 } else { |
| 467 // The buffer is not too small. | 460 // The buffer is not too small. |
| 468 break; | 461 break; |
| 469 } | 462 } |
| 470 } | 463 } |
| 471 DCHECK(buffer.get()); | 464 DCHECK(buffer.get()); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 508 // We create a DOS device name for the device at \Device\<device_name>. | 501 // We create a DOS device name for the device at \Device\<device_name>. |
| 509 base::string16 target_path = L"\\Device\\" + device_name; | 502 base::string16 target_path = L"\\Device\\" + device_name; |
| 510 | 503 |
| 511 TCHAR target[kStringLength]; | 504 TCHAR target[kStringLength]; |
| 512 if (QueryDosDevice(device_name.c_str(), target, kStringLength) > 0 && | 505 if (QueryDosDevice(device_name.c_str(), target, kStringLength) > 0 && |
| 513 target_path.compare(target) == 0) { | 506 target_path.compare(target) == 0) { |
| 514 // Device already exists. | 507 // Device already exists. |
| 515 return true; | 508 return true; |
| 516 } | 509 } |
| 517 | 510 |
| 518 if (GetLastError() != ERROR_FILE_NOT_FOUND) { | 511 if (GetLastError() != ERROR_FILE_NOT_FOUND) |
| 519 return false; | 512 return false; |
| 520 } | |
| 521 | 513 |
| 522 if (!DefineDosDevice(DDD_RAW_TARGET_PATH, device_name.c_str(), | 514 if (!DefineDosDevice(DDD_RAW_TARGET_PATH, device_name.c_str(), |
| 523 target_path.c_str())) { | 515 target_path.c_str())) { |
| 524 return false; | 516 return false; |
| 525 } | 517 } |
| 526 | 518 |
| 527 // Check that the device is really there. | 519 // Check that the device is really there. |
| 528 return QueryDosDevice(device_name.c_str(), target, kStringLength) > 0 && | 520 return QueryDosDevice(device_name.c_str(), target, kStringLength) > 0 && |
| 529 target_path.compare(target) == 0; | 521 target_path.compare(target) == 0; |
| 530 } | 522 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 565 | 557 |
| 566 buffer->reset( | 558 buffer->reset( |
| 567 reinterpret_cast<BYTE*>(realloc(buffer->release(), requested_size))); | 559 reinterpret_cast<BYTE*>(realloc(buffer->release(), requested_size))); |
| 568 return buffer != NULL; | 560 return buffer != NULL; |
| 569 } | 561 } |
| 570 | 562 |
| 571 bool GetSystemDirectory(base::string16* path) { | 563 bool GetSystemDirectory(base::string16* path) { |
| 572 DCHECK(path); | 564 DCHECK(path); |
| 573 // Return value includes terminating NULL. | 565 // Return value includes terminating NULL. |
| 574 int buffer_size = ::GetSystemDirectory(NULL, 0); | 566 int buffer_size = ::GetSystemDirectory(NULL, 0); |
| 575 if (buffer_size == 0) { | 567 if (buffer_size == 0) |
| 576 return false; | 568 return false; |
| 577 } | |
| 578 std::unique_ptr<base::char16[]> buffer(new base::char16[buffer_size]); | 569 std::unique_ptr<base::char16[]> buffer(new base::char16[buffer_size]); |
| 579 | 570 |
| 580 // Return value excludes terminating NULL. | 571 // Return value excludes terminating NULL. |
| 581 int characters_written = ::GetSystemDirectory(buffer.get(), buffer_size); | 572 int characters_written = ::GetSystemDirectory(buffer.get(), buffer_size); |
| 582 if (characters_written == 0) { | 573 if (characters_written == 0) |
| 583 return false; | 574 return false; |
| 584 } | |
| 585 DCHECK_EQ(buffer_size - 1, characters_written); | 575 DCHECK_EQ(buffer_size - 1, characters_written); |
| 586 | 576 |
| 587 path->assign(buffer.get(), characters_written); | 577 path->assign(buffer.get(), characters_written); |
| 588 | 578 |
| 589 if (*path->rbegin() != L'\\') { | 579 if (*path->rbegin() != L'\\') |
| 590 path->append(L"\\"); | 580 path->append(L"\\"); |
| 591 } | |
| 592 DCHECK_EQ(L'\\', *path->rbegin()); | 581 DCHECK_EQ(L'\\', *path->rbegin()); |
| 593 return true; | 582 return true; |
| 594 } | 583 } |
| 595 } // namespace | 584 } // namespace |
| 596 | 585 |
| 597 } // namespace device | 586 } // namespace device |
| OLD | NEW |