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

Side by Side Diff: device/hid/hid_service_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_service_win.h"
6
7 #include <cstdlib>
8 #include <string>
9
10 #include "base/callback_helpers.h"
11 #include "base/lazy_instance.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/stl_util.h"
14 #include "base/strings/sys_string_conversions.h"
15 #include "device/hid/hid_connection.h"
16 #include "device/hid/hid_connection_win.h"
17 #include "device/hid/hid_service.h"
18 #include "net/base/io_buffer.h"
19
20 #if defined(OS_WIN)
21
22 #define INITGUID
23
24 #include <windows.h>
25 #include <hidclass.h>
26
27 extern "C" {
28
29 #include <hidsdi.h>
30
31 }
32
33 #include <setupapi.h>
34 #include <winioctl.h>
35 #include "base/win/scoped_handle.h"
36
37 #endif // defined(OS_WIN)
38
39 // Setup API is required to enumerate HID devices.
40 #pragma comment(lib, "setupapi.lib")
41 #pragma comment(lib, "hid.lib")
42
43 namespace device {
44 namespace {
45
46 base::LazyInstance<HidServiceWin> g_hid_service = LAZY_INSTANCE_INITIALIZER;
47
48 const char kHIDClass[] = "HIDClass";
49
50 } // namespace
51
52 HidServiceWin::HidServiceWin() {
53 initialized_ = Enumerate();
54 }
55 HidServiceWin::~HidServiceWin() {}
56
57 bool HidServiceWin::Enumerate() {
58 BOOL res;
59 HDEVINFO device_info_set;
60 SP_DEVINFO_DATA devinfo_data;
61 SP_DEVICE_INTERFACE_DATA device_interface_data;
62
63 memset(&devinfo_data, 0, sizeof(SP_DEVINFO_DATA));
64 devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA);
65 device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
66
67 device_info_set = SetupDiGetClassDevs(
68 &GUID_DEVINTERFACE_HID,
69 NULL,
70 NULL,
71 DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
72
73 if (device_info_set == INVALID_HANDLE_VALUE)
74 return false;
75
76 for (int device_index = 0;
77 SetupDiEnumDeviceInterfaces(device_info_set,
78 NULL,
79 &GUID_DEVINTERFACE_HID,
80 device_index,
81 &device_interface_data);
82 device_index++) {
83 DWORD required_size = 0;
84
85 // Determime the required size of detail struct.
86 SetupDiGetDeviceInterfaceDetailA(device_info_set,
87 &device_interface_data,
88 NULL,
89 0,
90 &required_size,
91 NULL);
92
93 scoped_ptr_malloc<SP_DEVICE_INTERFACE_DETAIL_DATA_A>
94 device_interface_detail_data(
95 reinterpret_cast<SP_DEVICE_INTERFACE_DETAIL_DATA_A*>(
96 malloc(required_size)));
97 device_interface_detail_data->cbSize =
98 sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
99
100 // Get the detailed data for this device.
101 res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
102 &device_interface_data,
103 device_interface_detail_data.get(),
104 required_size,
105 NULL,
106 NULL);
107 if (!res)
108 continue;
109
110 // Enumerate device info. Looking for Setup Class "HIDClass".
111 for (DWORD i = 0;
112 SetupDiEnumDeviceInfo(device_info_set, i, &devinfo_data);
113 i++) {
114 char class_name[256] = {0};
115 res = SetupDiGetDeviceRegistryPropertyA(device_info_set,
116 &devinfo_data,
117 SPDRP_CLASS,
118 NULL,
119 (PBYTE) class_name,
120 sizeof(class_name) - 1,
121 NULL);
122 if (!res)
123 break;
124 if (memcmp(class_name, kHIDClass, sizeof(kHIDClass)) == 0) {
125 char driver_name[256] = {0};
126 // Get bounded driver.
127 res = SetupDiGetDeviceRegistryPropertyA(device_info_set,
128 &devinfo_data,
129 SPDRP_DRIVER,
130 NULL,
131 (PBYTE) driver_name,
132 sizeof(driver_name) - 1,
133 NULL);
134 if (res) {
135 // Found the drive.
136 break;
137 }
138 }
139 }
140
141 if (!res)
142 continue;
143
144 PlatformDeviceAdd(device_interface_detail_data->DevicePath);
145 }
146
147 return true;
148 }
149
150 void HidServiceWin::PlatformDeviceAdd(std::string device_path) {
151 HidDeviceInfo device_info;
152 device_info.device_id = device_path;
153
154 // Try to open the device.
155 base::win::ScopedHandle device_handle(
156 CreateFileA(device_path.c_str(),
157 0,
158 FILE_SHARE_READ | FILE_SHARE_WRITE,
159 NULL,
160 OPEN_EXISTING,
161 FILE_FLAG_OVERLAPPED,
162 0));
163 if (!device_handle)
164 return;
165
166 // Get VID/PID pair.
167 HIDD_ATTRIBUTES attrib = {0};
168 attrib.Size = sizeof(HIDD_ATTRIBUTES);
169 if (!HidD_GetAttributes(device_handle.Get(), &attrib))
170 return;
171
172 device_info.vendor_id = attrib.VendorID;
173 device_info.product_id = attrib.ProductID;
174
175 for (ULONG i = 32;
176 HidD_SetNumInputBuffers(device_handle.Get(), i);
177 i <<= 1);
178
179 // Get usage and usage page (optional).
180 PHIDP_PREPARSED_DATA preparsed_data;
181 if (HidD_GetPreparsedData(device_handle.Get(), &preparsed_data) &&
182 preparsed_data) {
183 HIDP_CAPS capabilities;
184 if (HidP_GetCaps(preparsed_data, &capabilities) == HIDP_STATUS_SUCCESS) {
185 device_info.usage = capabilities.Usage;
186 device_info.usage_page = capabilities.UsagePage;
187 device_info.input_report_size = capabilities.InputReportByteLength;
188 device_info.output_report_size = capabilities.OutputReportByteLength;
189 device_info.feature_report_size = capabilities.FeatureReportByteLength;
190 }
191 HidD_FreePreparsedData(preparsed_data);
192 }
193
194 // Get the serial number
195 wchar_t str_property[512] = { 0 };
196 if (HidD_GetSerialNumberString(device_handle.Get(),
197 str_property,
198 sizeof(str_property))) {
199 device_info.serial_number = base::SysWideToUTF8(str_property);
200 }
201
202 if (HidD_GetProductString(device_handle.Get(),
203 str_property,
204 sizeof(str_property))) {
205 device_info.product_name = base::SysWideToUTF8(str_property);
206 }
207
208 HidService::DeviceAdd(device_info);
209 }
210
211 void HidServiceWin::PlatformDeviceRemove(std::string device_path) {
212 HidService::DeviceRemove(device_path);
213 }
214
215 void HidServiceWin::GetDevices(std::vector<HidDeviceInfo>* devices) {
216 Enumerate();
217 HidService::GetDevices(devices);
218 }
219
220 scoped_refptr<HidConnection> HidServiceWin::Connect(std::string device_id) {
221 if (!ContainsKey(devices_, device_id)) return NULL;
222 scoped_refptr<HidConnectionWin> connection(
223 new HidConnectionWin(devices_[device_id]));
224 if (!connection->available()) return NULL;
225 return connection;
226 }
227
228 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698