15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright (c) 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "device/hid/hid_connection_win.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <cstring> 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h" 105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/files/file.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/message_loop/message_loop.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/win/object_watcher.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define INITGUID 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <windows.h> 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <hidclass.h> 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)extern "C" { 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <hidsdi.h> 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <setupapi.h> 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <winioctl.h> 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace device { 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)struct PendingHidTransfer : public base::RefCounted<PendingHidTransfer>, 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public base::win::ObjectWatcher::Delegate, 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public base::MessageLoop::DestructionObserver { 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci typedef base::Callback<void(PendingHidTransfer*, bool)> Callback; 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PendingHidTransfer(scoped_refptr<net::IOBuffer> buffer, 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const Callback& callback); 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void TakeResultFromWindowsAPI(BOOL result); 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OVERLAPPED* GetOverlapped() { return &overlapped_; } 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Implements base::win::ObjectWatcher::Delegate. 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnObjectSignaled(HANDLE object) OVERRIDE; 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Implements base::MessageLoop::DestructionObserver 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void WillDestroyCurrentMessageLoop() OVERRIDE; 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The buffer isn't used by this object but it's important that a reference 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // to it is held until the transfer completes. 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<net::IOBuffer> buffer_; 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Callback callback_; 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OVERLAPPED overlapped_; 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::win::ScopedHandle event_; 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::win::ObjectWatcher watcher_; 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) friend class base::RefCounted<PendingHidTransfer>; 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual ~PendingHidTransfer(); 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PendingHidTransfer); 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)PendingHidTransfer::PendingHidTransfer( 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<net::IOBuffer> buffer, 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const PendingHidTransfer::Callback& callback) 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : buffer_(buffer), 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_(callback), 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) event_(CreateEvent(NULL, FALSE, FALSE, NULL)) { 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memset(&overlapped_, 0, sizeof(OVERLAPPED)); 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) overlapped_.hEvent = event_.Get(); 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)PendingHidTransfer::~PendingHidTransfer() { 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::MessageLoop::current()->RemoveDestructionObserver(this); 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PendingHidTransfer::TakeResultFromWindowsAPI(BOOL result) { 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (result) { 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback_.Run(this, true); 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (GetLastError() == ERROR_IO_PENDING) { 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::MessageLoop::current()->AddDestructionObserver(this); 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddRef(); 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) watcher_.StartWatching(event_.Get(), this); 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VPLOG(1) << "HID transfer failed"; 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback_.Run(this, false); 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PendingHidTransfer::OnObjectSignaled(HANDLE event_handle) { 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback_.Run(this, true); 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Release(); 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PendingHidTransfer::WillDestroyCurrentMessageLoop() { 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) watcher_.StopWatching(); 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback_.Run(this, false); 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)HidConnectionWin::HidConnectionWin(const HidDeviceInfo& device_info) 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : HidConnection(device_info) { 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) file_.Set(CreateFileA(device_info.device_id.c_str(), 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GENERIC_WRITE | GENERIC_READ, 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FILE_SHARE_READ | FILE_SHARE_WRITE, 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL, 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OPEN_EXISTING, 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FILE_FLAG_OVERLAPPED, 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL)); 1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!file_.IsValid() && 1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu GetLastError() == base::File::FILE_ERROR_ACCESS_DENIED) { 1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu file_.Set(CreateFileA(device_info.device_id.c_str(), 1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu GENERIC_READ, 1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FILE_SHARE_READ, 1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NULL, 1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu OPEN_EXISTING, 1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FILE_FLAG_OVERLAPPED, 1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NULL)); 1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)HidConnectionWin::~HidConnectionWin() { 1221675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch} 1231675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch 1241675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdochvoid HidConnectionWin::PlatformClose() { 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CancelIo(file_.Get()); 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid HidConnectionWin::PlatformRead( 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const HidConnection::ReadCallback& callback) { 13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Windows will always include the report ID (including zero if report IDs 13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // are not in use) in the buffer. 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<net::IOBufferWithSize> buffer = 13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) new net::IOBufferWithSize(device_info().max_input_report_size + 1); 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<PendingHidTransfer> transfer(new PendingHidTransfer( 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer, 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&HidConnectionWin::OnReadComplete, this, buffer, callback))); 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transfers_.insert(transfer); 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) transfer->TakeResultFromWindowsAPI( 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ReadFile(file_.Get(), 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer->data(), 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static_cast<DWORD>(buffer->size()), 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NULL, 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) transfer->GetOverlapped())); 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid HidConnectionWin::PlatformWrite(scoped_refptr<net::IOBuffer> buffer, 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size_t size, 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const WriteCallback& callback) { 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The Windows API always wants either a report ID (if supported) or 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // zero at the front of every output report. 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<PendingHidTransfer> transfer(new PendingHidTransfer( 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer, base::Bind(&HidConnectionWin::OnWriteComplete, this, callback))); 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transfers_.insert(transfer); 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transfer->TakeResultFromWindowsAPI(WriteFile(file_.Get(), 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer->data(), 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static_cast<DWORD>(size), 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transfer->GetOverlapped())); 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid HidConnectionWin::PlatformGetFeatureReport(uint8_t report_id, 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ReadCallback& callback) { 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The first byte of the destination buffer is the report ID being requested. 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<net::IOBufferWithSize> buffer = 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new net::IOBufferWithSize(device_info().max_feature_report_size + 1); 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer->data()[0] = report_id; 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<PendingHidTransfer> transfer(new PendingHidTransfer( 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer, 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind( 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &HidConnectionWin::OnReadFeatureComplete, this, buffer, callback))); 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transfers_.insert(transfer); 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transfer->TakeResultFromWindowsAPI( 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DeviceIoControl(file_.Get(), 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IOCTL_HID_GET_FEATURE, 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL, 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 0, 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer->data(), 1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static_cast<DWORD>(buffer->size()), 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL, 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transfer->GetOverlapped())); 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 184116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HidConnectionWin::PlatformSendFeatureReport( 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<net::IOBuffer> buffer, 1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size_t size, 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const WriteCallback& callback) { 188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The Windows API always wants either a report ID (if supported) or 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // zero at the front of every output report. 1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<PendingHidTransfer> transfer(new PendingHidTransfer( 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer, base::Bind(&HidConnectionWin::OnWriteComplete, this, callback))); 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transfer->TakeResultFromWindowsAPI( 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DeviceIoControl(file_.Get(), 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IOCTL_HID_SET_FEATURE, 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffer->data(), 1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static_cast<DWORD>(size), 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL, 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 0, 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL, 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transfer->GetOverlapped())); 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid HidConnectionWin::OnReadComplete(scoped_refptr<net::IOBuffer> buffer, 2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ReadCallback& callback, 2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PendingHidTransfer* transfer, 2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool signaled) { 2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!signaled) { 2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(false, NULL, 0); 2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DWORD bytes_transferred; 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (GetOverlappedResult( 214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) file_, transfer->GetOverlapped(), &bytes_transferred, FALSE)) { 2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CompleteRead(buffer, bytes_transferred, callback); 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VPLOG(1) << "HID read failed"; 2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(false, NULL, 0); 2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid HidConnectionWin::OnReadFeatureComplete( 2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<net::IOBuffer> buffer, 2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ReadCallback& callback, 2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PendingHidTransfer* transfer, 2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool signaled) { 2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!signaled) { 2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(false, NULL, 0); 2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DWORD bytes_transferred; 2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (GetOverlappedResult( 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file_, transfer->GetOverlapped(), &bytes_transferred, FALSE)) { 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<net::IOBuffer> new_buffer( 2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new net::IOBuffer(bytes_transferred - 1)); 2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci memcpy(new_buffer->data(), buffer->data() + 1, bytes_transferred - 1); 2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CompleteRead(new_buffer, bytes_transferred, callback); 2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VPLOG(1) << "HID read failed"; 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(false, NULL, 0); 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid HidConnectionWin::OnWriteComplete(const WriteCallback& callback, 2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PendingHidTransfer* transfer, 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool signaled) { 2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!signaled) { 2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(false); 2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DWORD bytes_transferred; 2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (GetOverlappedResult( 2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file_, transfer->GetOverlapped(), &bytes_transferred, FALSE)) { 2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(true); 2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VPLOG(1) << "HID write failed"; 2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(false); 2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace device 264