Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(422)

Side by Side Diff: device/hid/hid_connection_win.cc

Issue 143883005: HID backend (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@hid-impl-base
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "device/hid/hid_connection_win.h"
6
7 #include <cstring>
8
9 #include "base/threading/thread_restrictions.h"
10 #include "device/hid/hid_service.h"
11 #include "device/hid/hid_service_win.h"
12 #include "net/base/io_buffer.h"
13
14 #if defined(OS_WIN)
15
16 #define INITGUID
17
18 #include <windows.h>
19 #include <hidclass.h>
20
21 extern "C" {
22
23 #include <hidsdi.h>
24
25 }
26
27 #include <setupapi.h>
28 #include <winioctl.h>
29 #include "base/win/scoped_handle.h"
30
31 #endif // defined(OS_WIN)
32
33 namespace device {
34
35 AsyncTransfer::AsyncTransfer(HANDLE file,
36 scoped_refptr<net::IOBuffer> buffer,
37 const HidIOCallback& callback,
38 bool is_read)
39 : file_(file),
40 buffer_(buffer),
41 callback_(callback),
42 actual_size_(0),
43 is_read_(is_read) {
44 memset(&overlapped_, 0, sizeof(OVERLAPPED));
45 event_.Set(CreateEvent(NULL, FALSE, FALSE, NULL));
46 overlapped_.hEvent = event_.Get();
47 }
48
49 AsyncTransfer::~AsyncTransfer() {
50 }
51
52 void AsyncTransfer::StartWatching(BOOL result_from_winapi) {
53 if (!result_from_winapi) {
54 if (GetLastError() == ERROR_IO_PENDING) {
55 if (watcher_.StartWatching(event_.Get(), this)) {
56 AddRef();
57 } else {
58 callback_.Run(false, NULL, 0);
59 }
60 } else {
61 PLOG(ERROR) << "HidConnectionWin::Read";
62 callback_.Run(false, NULL, 0);
63 }
64 } else {
65 AddRef();
66 OnObjectSignaled(overlapped_.hEvent);
67 }
68 }
69
70 OVERLAPPED* AsyncTransfer::GetOverlappedPtr() {
71 return &overlapped_;
72 }
73
74 DWORD* AsyncTransfer::GetActualSizePtr() {
75 return &actual_size_;
76 }
77
78 void AsyncTransfer::OnObjectSignaled(HANDLE object) {
79 DCHECK_EQ(object, event_.Get());
80 BOOL result = GetOverlappedResult(file_,&overlapped_, &actual_size_, FALSE);
81
82 // For input transfers, if the first byte is zero, we need to remove it.
83 if (is_read_ && buffer_->data()[0] == 0) {
84 actual_size_--;
85 memmove(buffer_->data(), buffer_->data() + 1, actual_size_);
86 }
87 callback_.Run(result != 0, buffer_, (size_t)actual_size_);
88 Release();
89 }
90
91 HidConnectionWin::HidConnectionWin(HidDeviceInfo device_info)
92 : HidConnection(device_info),
93 available_(false) {
94 file_.Set(CreateFileA(device_info.device_id.c_str(),
95 GENERIC_WRITE | GENERIC_READ,
96 FILE_SHARE_READ,
97 NULL,
98 OPEN_EXISTING,
99 FILE_FLAG_OVERLAPPED,
100 NULL));
101 available_ = file_.Get() != INVALID_HANDLE_VALUE;
102 }
103
104 HidConnectionWin::~HidConnectionWin() {}
105
106 void HidConnectionWin::Read(const HidIOCallback& callback) {
107 size_t report_size = device_info_.input_report_size;
108 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(report_size));
109 scoped_refptr<AsyncTransfer> aync_transfer(
110 new AsyncTransfer(file_, buffer, callback, true));
111
112 aync_transfer->StartWatching(ReadFile(file_.Get(),
113 buffer->data(),
114 report_size,
115 aync_transfer->GetActualSizePtr(),
116 aync_transfer->GetOverlappedPtr()));
117 }
118
119 void HidConnectionWin::Write(scoped_refptr<net::IOBuffer> buffer,
120 size_t size,
121 const HidIOCallback& callback) {
122 size_t report_size = device_info_.output_report_size;
123 if (size < report_size) {
124 scoped_refptr<net::IOBuffer> expanded_buffer(
125 new net::IOBuffer(report_size));
126 memset(expanded_buffer->data(), 0, report_size);
127 memcpy(expanded_buffer->data(), buffer->data(), size);
128 size = report_size;
129 buffer = expanded_buffer;
130 }
131
132 scoped_refptr<AsyncTransfer> aync_transfer(
133 new AsyncTransfer(file_, NULL, callback, false));
134
135 aync_transfer->StartWatching(WriteFile(file_,
136 buffer->data(),
137 size,
138 aync_transfer->GetActualSizePtr(),
139 aync_transfer->GetOverlappedPtr()));
140 }
141
142 void HidConnectionWin::GetFeatureReport(const HidIOCallback& callback) {
143 size_t report_size = device_info_.feature_report_size;
144 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(report_size));
145 scoped_refptr<AsyncTransfer> aync_transfer(
146 new AsyncTransfer(file_, buffer, callback, true));
147
148 aync_transfer->
149 StartWatching(DeviceIoControl(file_,
150 IOCTL_HID_GET_FEATURE,
151 NULL, 0,
152 buffer->data(), report_size,
153 aync_transfer->GetActualSizePtr(),
154 aync_transfer->GetOverlappedPtr()));
155 }
156
157 void HidConnectionWin::SendFeatureReport(scoped_refptr<net::IOBuffer> buffer,
158 size_t size,
159 const HidIOCallback& callback) {
160 size_t report_size = device_info_.feature_report_size;
161 if (size < report_size) {
162 scoped_refptr<net::IOBuffer> expanded_buffer(
163 new net::IOBuffer(report_size));
164 memset(expanded_buffer->data(), 0, report_size);
165 memcpy(expanded_buffer->data(), buffer->data(), size);
166 size = report_size;
167 buffer = expanded_buffer;
168 }
169
170 scoped_refptr<AsyncTransfer> aync_transfer(
171 new AsyncTransfer(file_, NULL, callback, false));
172
173 aync_transfer->
174 StartWatching(DeviceIoControl(file_,
175 IOCTL_HID_SET_FEATURE,
176 buffer->data(), report_size,
177 NULL, 0,
178 aync_transfer->GetActualSizePtr(),
179 aync_transfer->GetOverlappedPtr()));
180 }
181
182 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698