diff options
author | alph <alph@chromium.org> | 2015-11-18 09:35:06 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-18 17:35:50 +0000 |
commit | 221127798bff4a91906781f6e862a9258cd8b9f8 (patch) | |
tree | 4e5bf8b618f523211027c52455b1ecc1e76ef786 | |
parent | db3c40ee764db0693a2014753f5b462b416d1883 (diff) | |
download | chromium_src-221127798bff4a91906781f6e862a9258cd8b9f8.zip chromium_src-221127798bff4a91906781f6e862a9258cd8b9f8.tar.gz chromium_src-221127798bff4a91906781f6e862a9258cd8b9f8.tar.bz2 |
Revert of Reland: Add code to deal with serial device disconnection detection on Windows (patchset #16 id:300001 of https://codereview.chromium.org/1439443002/ )
Reason for revert:
Broke Win GN build http://build.chromium.org/p/chromium.win/builders/Win%20x64%20GN%20%28dbg%29/builds/13710
Original issue's description:
> Add code to deal with serial device disconnection
> detection on Windows.
>
> This patch added code to deal with serial device
> disconnection detection problem on Windows. It gets the
> COM port information from the device path and compare
> the COM port information with the port information that
> serial io handler holds. If they match, cancel read for
> that port.
>
> BUG=361606
>
> Committed: https://crrev.com/195a0f202c1b89540d4a385d881cd483abe757fa
> Cr-Commit-Position: refs/heads/master@{#360193}
>
> Committed: https://crrev.com/8d09d9564ea10012d55ed634c0c2835efbd8d01f
> Cr-Commit-Position: refs/heads/master@{#360347}
TBR=reillyg@chromium.org,grt@chromium.org,thestig@chromium.org,juncai@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=361606
Review URL: https://codereview.chromium.org/1460743002
Cr-Commit-Position: refs/heads/master@{#360356}
-rw-r--r-- | device/core/BUILD.gn | 2 | ||||
-rw-r--r-- | device/core/core.gyp | 2 | ||||
-rw-r--r-- | device/core/device_info_query_win.cc | 66 | ||||
-rw-r--r-- | device/core/device_info_query_win.h | 49 | ||||
-rw-r--r-- | device/serial/BUILD.gn | 1 | ||||
-rw-r--r-- | device/serial/serial.gyp | 1 | ||||
-rw-r--r-- | device/serial/serial_io_handler.cc | 1 | ||||
-rw-r--r-- | device/serial/serial_io_handler.h | 12 | ||||
-rw-r--r-- | device/serial/serial_io_handler_win.cc | 103 | ||||
-rw-r--r-- | device/serial/serial_io_handler_win.h | 8 | ||||
-rw-r--r-- | device/usb/usb.gyp | 1 | ||||
-rw-r--r-- | device/usb/usb_service_impl.cc | 80 |
12 files changed, 74 insertions, 252 deletions
diff --git a/device/core/BUILD.gn b/device/core/BUILD.gn index 6f55190..e85acb6 100644 --- a/device/core/BUILD.gn +++ b/device/core/BUILD.gn @@ -8,8 +8,6 @@ component("core") { sources = [ "device_client.cc", "device_client.h", - "device_info_query_win.cc", - "device_info_query_win.h", "device_monitor_win.cc", "device_monitor_win.h", ] diff --git a/device/core/core.gyp b/device/core/core.gyp index 6002a5f..d27073d 100644 --- a/device/core/core.gyp +++ b/device/core/core.gyp @@ -19,8 +19,6 @@ 'sources': [ 'device_client.cc', 'device_client.h', - 'device_info_query_win.cc', - 'device_info_query_win.h', 'device_monitor_win.cc', 'device_monitor_win.h', ], diff --git a/device/core/device_info_query_win.cc b/device/core/device_info_query_win.cc deleted file mode 100644 index 4d62b32..0000000 --- a/device/core/device_info_query_win.cc +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2015 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. - -#include "device/core/device_info_query_win.h" - -#include <string.h> - -#include "base/strings/string_util.h" - -namespace device { - -DeviceInfoQueryWin::DeviceInfoQueryWin() - : device_info_list_(SetupDiCreateDeviceInfoList(nullptr, nullptr)) { - memset(&device_info_data_, 0, sizeof(device_info_data_)); -} - -DeviceInfoQueryWin::~DeviceInfoQueryWin() { - if (device_info_list_valid()) { - // Release |device_info_data_| only when it is valid. - if (device_info_data_.cbSize != 0) - SetupDiDeleteDeviceInfo(device_info_list_, &device_info_data_); - SetupDiDestroyDeviceInfoList(device_info_list_); - } -} - -bool DeviceInfoQueryWin::AddDevice(const char* device_path) { - return SetupDiOpenDeviceInterfaceA(device_info_list_, device_path, 0, - nullptr) != FALSE; -} - -bool DeviceInfoQueryWin::GetDeviceInfo() { - DCHECK_EQ(0U, device_info_data_.cbSize); - device_info_data_.cbSize = sizeof(device_info_data_); - if (!SetupDiEnumDeviceInfo(device_info_list_, 0, &device_info_data_)) { - // Clear cbSize to maintain the invariant. - device_info_data_.cbSize = 0; - return false; - } - return true; -} - -bool DeviceInfoQueryWin::GetDeviceStringProperty(DWORD property, - std::string* property_buffer) { - DWORD property_reg_data_type; - const size_t property_buffer_length = 512; - if (!SetupDiGetDeviceRegistryPropertyA( - device_info_list_, &device_info_data_, property, - &property_reg_data_type, - reinterpret_cast<PBYTE>( - base::WriteInto(property_buffer, property_buffer_length)), - static_cast<DWORD>(property_buffer_length), nullptr)) - return false; - - if (property_reg_data_type != REG_SZ) - return false; - - // Shrink |property_buffer| down to its correct size. - size_t eos = property_buffer->find('\0'); - if (eos != std::string::npos) - property_buffer->resize(eos); - - return true; -} - -} // namespace device diff --git a/device/core/device_info_query_win.h b/device/core/device_info_query_win.h deleted file mode 100644 index 2e399e4..0000000 --- a/device/core/device_info_query_win.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2015 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 DEVICE_CORE_DEVICE_INFO_QUERY_WIN_H_ -#define DEVICE_CORE_DEVICE_INFO_QUERY_WIN_H_ - -#include <windows.h> -#include <setupapi.h> - -#include <string> - -#include "base/macros.h" -#include "device/core/device_core_export.h" - -namespace device { - -// Wraps HDEVINFO and SP_DEVINFO_DATA into a class that can automatically -// release them. Provides interfaces that can add a device using its -// device path, get device info and get device string property. -class DEVICE_CORE_EXPORT DeviceInfoQueryWin { - public: - DeviceInfoQueryWin(); - ~DeviceInfoQueryWin(); - - // Add a device to |device_info_list_| using its |device_path| so that - // its device info can be retrieved. - bool AddDevice(const char* device_path); - // Get the device info and store it into |device_info_data_|, this function - // should be called at most once. - bool GetDeviceInfo(); - // Get device string property and store it into |property_buffer|. - bool GetDeviceStringProperty(DWORD property, std::string* property_buffer); - - bool device_info_list_valid() { - return device_info_list_ != INVALID_HANDLE_VALUE; - } - - private: - HDEVINFO device_info_list_ = INVALID_HANDLE_VALUE; - // When device_info_data_.cbSize != 0, |device_info_data_| is valid. - SP_DEVINFO_DATA device_info_data_; - - DISALLOW_COPY_AND_ASSIGN(DeviceInfoQueryWin); -}; - -} // namespace device - -#endif // DEVICE_CORE_DEVICE_INFO_QUERY_WIN_H_ diff --git a/device/serial/BUILD.gn b/device/serial/BUILD.gn index f66cedf..1ee6c5f 100644 --- a/device/serial/BUILD.gn +++ b/device/serial/BUILD.gn @@ -45,7 +45,6 @@ static_library("serial") { public_deps = [ ":serial_mojo", "//base", - "//device/core", ] deps = [ "//mojo/public/cpp/system", diff --git a/device/serial/serial.gyp b/device/serial/serial.gyp index 0e56df1..de18133 100644 --- a/device/serial/serial.gyp +++ b/device/serial/serial.gyp @@ -50,7 +50,6 @@ '../../net/net.gyp:net', '../../third_party/mojo/mojo_public.gyp:mojo_cpp_bindings', '../../third_party/re2/re2.gyp:re2', - '../core/core.gyp:device_core', ], 'export_dependent_settings': [ 'device_serial_mojo', diff --git a/device/serial/serial_io_handler.cc b/device/serial/serial_io_handler.cc index 1cfb1cd..452f91c 100644 --- a/device/serial/serial_io_handler.cc +++ b/device/serial/serial_io_handler.cc @@ -44,7 +44,6 @@ void SerialIoHandler::Open(const std::string& port, DCHECK(file_thread_task_runner_.get()); DCHECK(ui_thread_task_runner_.get()); MergeConnectionOptions(options); - port_ = port; #if defined(OS_CHROMEOS) chromeos::PermissionBrokerClient* client = diff --git a/device/serial/serial_io_handler.h b/device/serial/serial_io_handler.h index 63e6c90..81d7028 100644 --- a/device/serial/serial_io_handler.h +++ b/device/serial/serial_io_handler.h @@ -190,16 +190,6 @@ class SerialIoHandler : public base::NonThreadSafe, // Possibly fixes up a serial port path name in a platform-specific manner. static std::string MaybeFixUpPortName(const std::string& port_name); - base::SingleThreadTaskRunner* file_thread_task_runner() const { - return file_thread_task_runner_.get(); - } - - base::SingleThreadTaskRunner* ui_thread_task_runner() const { - return ui_thread_task_runner_.get(); - } - - const std::string& port() const { return port_; } - private: friend class base::RefCounted<SerialIoHandler>; @@ -239,8 +229,6 @@ class SerialIoHandler : public base::NonThreadSafe, // On Chrome OS, PermissionBrokerClient should be called on the UI thread. scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner_; - std::string port_; - DISALLOW_COPY_AND_ASSIGN(SerialIoHandler); }; diff --git a/device/serial/serial_io_handler_win.cc b/device/serial/serial_io_handler_win.cc index 2a1e752..56fe93b 100644 --- a/device/serial/serial_io_handler_win.cc +++ b/device/serial/serial_io_handler_win.cc @@ -2,17 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "device/serial/serial_io_handler_win.h" - #include <windows.h> -#include <setupapi.h> -#include "base/bind.h" -#include "base/scoped_observer.h" -#include "base/threading/thread_checker.h" -#include "device/core/device_info_query_win.h" -#include "device/core/device_monitor_win.h" -#include "third_party/re2/re2/re2.h" +#include "device/serial/serial_io_handler_win.h" namespace device { @@ -138,12 +130,6 @@ serial::StopBits StopBitsConstantToEnum(int stop_bits) { } } -// Searches for the COM port in the device's friendly name, assigns its value to -// com_port, and returns whether the operation was successful. -bool GetCOMPort(const std::string friendly_name, std::string* com_port) { - return RE2::PartialMatch(friendly_name, ".* \\((COM[0-9]+)\\)", com_port); -} - } // namespace // static @@ -153,81 +139,6 @@ scoped_refptr<SerialIoHandler> SerialIoHandler::Create( return new SerialIoHandlerWin(file_thread_task_runner, ui_thread_task_runner); } -class SerialIoHandlerWin::UiThreadHelper : public DeviceMonitorWin::Observer { - public: - UiThreadHelper( - base::WeakPtr<SerialIoHandlerWin> io_handler, - scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner) - : device_observer_(this), - io_handler_(io_handler), - io_thread_task_runner_(io_thread_task_runner) {} - - ~UiThreadHelper() { DCHECK(thread_checker_.CalledOnValidThread()); } - - static void Start(UiThreadHelper* self) { - self->thread_checker_.DetachFromThread(); - DeviceMonitorWin* device_monitor = DeviceMonitorWin::GetForAllInterfaces(); - if (device_monitor) - self->device_observer_.Add(device_monitor); - } - - private: - // DeviceMonitorWin::Observer - void OnDeviceRemoved(const GUID& class_guid, - const std::string& device_path) override { - DCHECK(thread_checker_.CalledOnValidThread()); - io_thread_task_runner_->PostTask( - FROM_HERE, base::Bind(&SerialIoHandlerWin::OnDeviceRemoved, io_handler_, - device_path)); - } - - base::ThreadChecker thread_checker_; - ScopedObserver<DeviceMonitorWin, DeviceMonitorWin::Observer> device_observer_; - - // This weak pointer is only valid when checked on this task runner. - base::WeakPtr<SerialIoHandlerWin> io_handler_; - scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_; - - DISALLOW_COPY_AND_ASSIGN(UiThreadHelper); -}; - -void SerialIoHandlerWin::OnDeviceRemoved(const std::string& device_path) { - DCHECK(CalledOnValidThread()); - - DeviceInfoQueryWin device_info_query; - if (!device_info_query.device_info_list_valid()) { - DVPLOG(1) << "Failed to create a device information set"; - return; - } - - // This will add the device so we can query driver info. - if (!device_info_query.AddDevice(device_path.c_str())) { - DVPLOG(1) << "Failed to get device interface data for " << device_path; - return; - } - - if (!device_info_query.GetDeviceInfo()) { - DVPLOG(1) << "Failed to get device info for " << device_path; - return; - } - - std::string friendly_name; - if (!device_info_query.GetDeviceStringProperty(SPDRP_FRIENDLYNAME, - &friendly_name)) { - DVPLOG(1) << "Failed to get device service property"; - return; - } - - std::string com_port; - if (!GetCOMPort(friendly_name, &com_port)) { - DVPLOG(1) << "Failed to get port name from \"" << friendly_name << "\"."; - return; - } - - if (port() == com_port) - CancelRead(serial::RECEIVE_ERROR_DISCONNECTED); -} - bool SerialIoHandlerWin::PostOpen() { DCHECK(!comm_context_); DCHECK(!read_context_); @@ -248,13 +159,6 @@ bool SerialIoHandlerWin::PostOpen() { write_context_->handler = this; memset(&write_context_->overlapped, 0, sizeof(write_context_->overlapped)); - scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner = - base::ThreadTaskRunnerHandle::Get(); - helper_ = - new UiThreadHelper(weak_factory_.GetWeakPtr(), io_thread_task_runner); - ui_thread_task_runner()->PostTask( - FROM_HERE, base::Bind(&UiThreadHelper::Start, helper_)); - // A ReadIntervalTimeout of MAXDWORD will cause async reads to complete // immediately with any data that's available, even if there is none. // This is OK because we never issue a read request until WaitCommEvent @@ -367,11 +271,10 @@ SerialIoHandlerWin::SerialIoHandlerWin( scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner) : SerialIoHandler(file_thread_task_runner, ui_thread_task_runner), event_mask_(0), - is_comm_pending_(false), - weak_factory_(this) {} + is_comm_pending_(false) { +} SerialIoHandlerWin::~SerialIoHandlerWin() { - ui_thread_task_runner()->DeleteSoon(FROM_HERE, helper_); } void SerialIoHandlerWin::OnIOCompleted( diff --git a/device/serial/serial_io_handler_win.h b/device/serial/serial_io_handler_win.h index 831eab6..7f438b5 100644 --- a/device/serial/serial_io_handler_win.h +++ b/device/serial/serial_io_handler_win.h @@ -32,7 +32,6 @@ class SerialIoHandlerWin : public SerialIoHandler, bool PostOpen() override; private: - class UiThreadHelper; friend class SerialIoHandler; explicit SerialIoHandlerWin( @@ -45,8 +44,6 @@ class SerialIoHandlerWin : public SerialIoHandler, DWORD bytes_transfered, DWORD error) override; - void OnDeviceRemoved(const std::string& device_path); - // Context used for asynchronous WaitCommEvent calls. scoped_ptr<base::MessageLoopForIO::IOContext> comm_context_; @@ -64,11 +61,6 @@ class SerialIoHandlerWin : public SerialIoHandler, // after a corresponding WaitCommEvent has completed. bool is_comm_pending_; - // The helper lives on the UI thread and holds a weak reference back to the - // handler that owns it. - UiThreadHelper* helper_ = nullptr; - base::WeakPtrFactory<SerialIoHandlerWin> weak_factory_; - DISALLOW_COPY_AND_ASSIGN(SerialIoHandlerWin); }; diff --git a/device/usb/usb.gyp b/device/usb/usb.gyp index 453ba1a..c7bf776 100644 --- a/device/usb/usb.gyp +++ b/device/usb/usb.gyp @@ -14,7 +14,6 @@ '../../components/components.gyp:device_event_log_component', '../../net/net.gyp:net', '../../third_party/libusb/libusb.gyp:libusb', - '../core/core.gyp:device_core', ], 'include_dirs': [ '../..', diff --git a/device/usb/usb_service_impl.cc b/device/usb/usb_service_impl.cc index 9770007..dd5cc90 100644 --- a/device/usb/usb_service_impl.cc +++ b/device/usb/usb_service_impl.cc @@ -27,7 +27,6 @@ #include <usbiodef.h> #include "base/strings/string_util.h" -#include "device/core/device_info_query_win.h" #endif // OS_WIN #if defined(USE_UDEV) @@ -54,33 +53,96 @@ const int kControlTransferTimeout = 60000; // 1 minute #if defined(OS_WIN) +// Wrapper around a HDEVINFO that automatically destroys it. +class ScopedDeviceInfoList { + public: + explicit ScopedDeviceInfoList(HDEVINFO handle) : handle_(handle) {} + + ~ScopedDeviceInfoList() { + if (valid()) { + SetupDiDestroyDeviceInfoList(handle_); + } + } + + bool valid() { return handle_ != INVALID_HANDLE_VALUE; } + + HDEVINFO get() { return handle_; } + + private: + HDEVINFO handle_; + + DISALLOW_COPY_AND_ASSIGN(ScopedDeviceInfoList); +}; + +// Wrapper around an SP_DEVINFO_DATA that initializes it properly and +// automatically deletes it. +class ScopedDeviceInfo { + public: + ScopedDeviceInfo() { + memset(&dev_info_data_, 0, sizeof(dev_info_data_)); + dev_info_data_.cbSize = sizeof(dev_info_data_); + } + + ~ScopedDeviceInfo() { + if (dev_info_set_ != INVALID_HANDLE_VALUE) { + SetupDiDeleteDeviceInfo(dev_info_set_, &dev_info_data_); + } + } + + // Once the SP_DEVINFO_DATA has been populated it must be freed using the + // HDEVINFO it was created from. + void set_valid(HDEVINFO dev_info_set) { + DCHECK(dev_info_set_ == INVALID_HANDLE_VALUE); + DCHECK(dev_info_set != INVALID_HANDLE_VALUE); + dev_info_set_ = dev_info_set; + } + + PSP_DEVINFO_DATA get() { return &dev_info_data_; } + + private: + HDEVINFO dev_info_set_ = INVALID_HANDLE_VALUE; + SP_DEVINFO_DATA dev_info_data_; +}; + bool IsWinUsbInterface(const std::string& device_path) { - DeviceInfoQueryWin device_info_query; - if (!device_info_query.device_info_list_valid()) { + ScopedDeviceInfoList dev_info_list(SetupDiCreateDeviceInfoList(NULL, NULL)); + if (!dev_info_list.valid()) { USB_PLOG(ERROR) << "Failed to create a device information set"; return false; } - // This will add the device so we can query driver info. - if (!device_info_query.AddDevice(device_path.c_str())) { + // This will add the device to |dev_info_list| so we can query driver info. + if (!SetupDiOpenDeviceInterfaceA(dev_info_list.get(), device_path.c_str(), 0, + NULL)) { USB_PLOG(ERROR) << "Failed to get device interface data for " << device_path; return false; } - if (!device_info_query.GetDeviceInfo()) { + ScopedDeviceInfo dev_info; + if (!SetupDiEnumDeviceInfo(dev_info_list.get(), 0, dev_info.get())) { USB_PLOG(ERROR) << "Failed to get device info for " << device_path; return false; } + dev_info.set_valid(dev_info_list.get()); - std::string buffer; - if (!device_info_query.GetDeviceStringProperty(SPDRP_SERVICE, &buffer)) { + DWORD reg_data_type; + BYTE buffer[256]; + if (!SetupDiGetDeviceRegistryPropertyA(dev_info_list.get(), dev_info.get(), + SPDRP_SERVICE, ®_data_type, + &buffer[0], sizeof buffer, NULL)) { USB_PLOG(ERROR) << "Failed to get device service property"; return false; } + if (reg_data_type != REG_SZ) { + USB_LOG(ERROR) << "Unexpected data type for driver service: " + << reg_data_type; + return false; + } USB_LOG(DEBUG) << "Driver for " << device_path << " is " << buffer << "."; - if (base::StartsWith(buffer, "WinUSB", base::CompareCase::INSENSITIVE_ASCII)) + if (base::StartsWith(reinterpret_cast<const char*>(buffer), "WinUSB", + base::CompareCase::INSENSITIVE_ASCII)) return true; return false; } |