migrate substitution keywords to SVN
[reactos.git] / reactos / lib / hid / hid.c
1 /*
2 * ReactOS Hid User Library
3 * Copyright (C) 2004 ReactOS Team
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 /* $Id$
20 *
21 * PROJECT: ReactOS Hid User Library
22 * FILE: lib/hid/hid.c
23 * PURPOSE: ReactOS Hid User Library
24 *
25 * UPDATE HISTORY:
26 * 07/12/2004 Created
27 */
28 #include <windows.h>
29 #include <ddk/hidusage.h>
30 #include <ddk/hidclass.h>
31 #include <ddk/hidpi.h>
32 #include "internal.h"
33
34 HINSTANCE hDllInstance;
35
36 /* device interface GUID for HIDClass devices */
37 const GUID HidClassGuid = {0x4D1E55B2, 0xF16F, 0x11CF, {0x88,0xCB,0x00,0x11,0x11,0x00,0x00,0x30}};
38
39 BOOL STDCALL
40 DllMain(HINSTANCE hinstDLL,
41 DWORD dwReason,
42 LPVOID lpvReserved)
43 {
44 switch(dwReason)
45 {
46 case DLL_PROCESS_ATTACH:
47 hDllInstance = hinstDLL;
48 break;
49
50 case DLL_THREAD_ATTACH:
51 break;
52
53 case DLL_THREAD_DETACH:
54 break;
55
56 case DLL_PROCESS_DETACH:
57 break;
58 }
59 return TRUE;
60 }
61
62
63 /*
64 * HidD_FlushQueue EXPORTED
65 *
66 * @implemented
67 */
68 HIDAPI
69 BOOLEAN DDKAPI
70 HidD_FlushQueue(IN HANDLE HidDeviceObject)
71 {
72 DWORD RetLen;
73 return DeviceIoControl(HidDeviceObject, IOCTL_HID_FLUSH_QUEUE,
74 NULL, 0,
75 NULL, 0,
76 &RetLen, NULL);
77 }
78
79
80 /*
81 * HidD_FreePreparsedData EXPORTED
82 *
83 * @implemented
84 */
85 HIDAPI
86 BOOLEAN DDKAPI
87 HidD_FreePreparsedData(IN PHIDP_PREPARSED_DATA PreparsedData)
88 {
89 return (LocalFree((HLOCAL)PreparsedData) == NULL);
90 }
91
92
93 /*
94 * HidD_GetAttributes EXPORTED
95 *
96 * @implemented
97 */
98 HIDAPI
99 BOOLEAN DDKAPI
100 HidD_GetAttributes(IN HANDLE HidDeviceObject,
101 OUT PHIDD_ATTRIBUTES Attributes)
102 {
103 HID_COLLECTION_INFORMATION hci;
104 DWORD RetLen;
105
106 if(!DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_COLLECTION_INFORMATION,
107 NULL, 0,
108 &hci, sizeof(HID_COLLECTION_INFORMATION),
109 &RetLen, NULL))
110 {
111 return FALSE;
112 }
113
114 /* copy the fields */
115 Attributes->Size = sizeof(HIDD_ATTRIBUTES);
116 Attributes->VendorID = hci.VendorID;
117 Attributes->ProductID = hci.ProductID;
118 Attributes->VersionNumber = hci.VersionNumber;
119
120 return TRUE;
121 }
122
123
124 /*
125 * HidP_GetButtonCaps EXPORTED
126 *
127 * @implemented
128 */
129 HIDAPI
130 NTSTATUS DDKAPI
131 HidP_GetButtonCaps(IN HIDP_REPORT_TYPE ReportType,
132 OUT PHIDP_BUTTON_CAPS ButtonCaps,
133 IN OUT PULONG ButtonCapsLength,
134 IN PHIDP_PREPARSED_DATA PreparsedData)
135 {
136 return HidP_GetSpecificButtonCaps(ReportType, 0, 0, 0, ButtonCaps,
137 ButtonCapsLength, PreparsedData);
138 }
139
140
141 /*
142 * HidD_GetFeature EXPORTED
143 *
144 * @implemented
145 */
146 HIDAPI
147 BOOLEAN DDKAPI
148 HidD_GetFeature(IN HANDLE HidDeviceObject,
149 OUT PVOID ReportBuffer,
150 IN ULONG ReportBufferLength)
151 {
152 DWORD RetLen;
153 return DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_FEATURE,
154 NULL, 0,
155 ReportBuffer, ReportBufferLength,
156 &RetLen, NULL);
157 }
158
159
160 /*
161 * HidD_GetHidGuid EXPORTED
162 *
163 * @implemented
164 */
165 HIDAPI
166 VOID DDKAPI
167 HidD_GetHidGuid(OUT LPGUID HidGuid)
168 {
169 *HidGuid = HidClassGuid;
170 }
171
172
173 /*
174 * HidD_GetInputReport EXPORTED
175 *
176 * @implemented
177 */
178 HIDAPI
179 BOOLEAN DDKAPI
180 HidD_GetInputReport(IN HANDLE HidDeviceObject,
181 IN OUT PVOID ReportBuffer,
182 IN ULONG ReportBufferLength)
183 {
184 DWORD RetLen;
185 return DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_INPUT_REPORT,
186 NULL, 0,
187 ReportBuffer, ReportBufferLength,
188 &RetLen, NULL);
189 }
190
191
192 /*
193 * HidD_GetManufacturerString EXPORTED
194 *
195 * @implemented
196 */
197 HIDAPI
198 BOOLEAN DDKAPI
199 HidD_GetManufacturerString(IN HANDLE HidDeviceObject,
200 OUT PVOID Buffer,
201 IN ULONG BufferLength)
202 {
203 DWORD RetLen;
204 return DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_MANUFACTURER_STRING,
205 NULL, 0,
206 Buffer, BufferLength,
207 &RetLen, NULL);
208 }
209
210
211 /*
212 * HidD_GetNumInputBuffers EXPORTED
213 *
214 * @implemented
215 */
216 HIDAPI
217 BOOLEAN DDKAPI
218 HidD_GetNumInputBuffers(IN HANDLE HidDeviceObject,
219 OUT PULONG NumberBuffers)
220 {
221 DWORD RetLen;
222 return DeviceIoControl(HidDeviceObject, IOCTL_GET_NUM_DEVICE_INPUT_BUFFERS,
223 NULL, 0,
224 NumberBuffers, sizeof(ULONG),
225 &RetLen, NULL);
226 }
227
228
229 /*
230 * HidD_GetPhysicalDescriptor EXPORTED
231 *
232 * @implemented
233 */
234 HIDAPI
235 BOOLEAN DDKAPI
236 HidD_GetPhysicalDescriptor(IN HANDLE HidDeviceObject,
237 OUT PVOID Buffer,
238 IN ULONG BufferLength)
239 {
240 DWORD RetLen;
241 return DeviceIoControl(HidDeviceObject, IOCTL_GET_PHYSICAL_DESCRIPTOR,
242 NULL, 0,
243 Buffer, BufferLength,
244 &RetLen, NULL);
245 }
246
247
248 /*
249 * HidD_GetPreparsedData EXPORTED
250 *
251 * @implemented
252 */
253 HIDAPI
254 BOOLEAN DDKAPI
255 HidD_GetPreparsedData(IN HANDLE HidDeviceObject,
256 OUT PHIDP_PREPARSED_DATA *PreparsedData)
257 {
258 HID_COLLECTION_INFORMATION hci;
259 DWORD RetLen;
260 BOOL Ret;
261
262 if(PreparsedData == NULL)
263 {
264 return FALSE;
265 }
266
267 if(!DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_COLLECTION_INFORMATION,
268 NULL, 0,
269 &hci, sizeof(HID_COLLECTION_INFORMATION),
270 &RetLen, NULL))
271 {
272 return FALSE;
273 }
274
275 *PreparsedData = LocalAlloc(LHND, hci.DescriptorSize);
276 if(*PreparsedData == NULL)
277 {
278 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
279 return FALSE;
280 }
281
282 Ret = DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_COLLECTION_DESCRIPTOR,
283 NULL, 0,
284 *PreparsedData, hci.DescriptorSize,
285 &RetLen, NULL);
286
287 if(!Ret)
288 {
289 /* FIXME - Free the buffer in case we failed to get the descriptor? */
290 LocalFree((HLOCAL)*PreparsedData);
291 }
292 #if 0
293 else
294 {
295 /* should we truncate the memory in case RetLen < hci.DescriptorSize? */
296 }
297 #endif
298
299 return Ret;
300 }
301
302
303 /*
304 * HidD_GetProductString EXPORTED
305 *
306 * @implemented
307 */
308 HIDAPI
309 BOOLEAN DDKAPI
310 HidD_GetProductString(IN HANDLE HidDeviceObject,
311 OUT PVOID Buffer,
312 IN ULONG BufferLength)
313 {
314 DWORD RetLen;
315 return DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_PRODUCT_STRING,
316 NULL, 0,
317 Buffer, BufferLength,
318 &RetLen, NULL);
319 }
320
321
322 /*
323 * HidD_GetSerialNumberString EXPORTED
324 *
325 * @implemented
326 */
327 HIDAPI
328 BOOLEAN DDKAPI
329 HidD_GetSerialNumberString(IN HANDLE HidDeviceObject,
330 OUT PVOID Buffer,
331 IN ULONG BufferLength)
332 {
333 DWORD RetLen;
334 return DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_SERIALNUMBER_STRING,
335 NULL, 0,
336 Buffer, BufferLength,
337 &RetLen, NULL);
338 }
339
340
341 /*
342 * HidP_GetValueCaps EXPORTED
343 *
344 * @implemented
345 */
346 HIDAPI
347 NTSTATUS DDKAPI
348 HidP_GetValueCaps(IN HIDP_REPORT_TYPE ReportType,
349 OUT PHIDP_VALUE_CAPS ValueCaps,
350 IN OUT PULONG ValueCapsLength,
351 IN PHIDP_PREPARSED_DATA PreparsedData)
352 {
353 return HidP_GetSpecificValueCaps(ReportType, 0, 0, 0, ValueCaps,
354 ValueCapsLength, PreparsedData);
355 }
356
357
358 /*
359 * HidD_Hello EXPORTED
360 *
361 * Undocumented easter egg function. It fills the buffer with "Hello\n"
362 * and returns number of bytes filled in (lstrlen(Buffer) + 1 == 7)
363 *
364 * Bugs: - doesn't check Buffer for NULL
365 * - always returns 7 even if BufferLength < 7 but doesn't produce a buffer overflow
366 *
367 * @implemented
368 */
369 HIDAPI
370 ULONG DDKAPI
371 HidD_Hello(OUT PCHAR Buffer,
372 IN ULONG BufferLength)
373 {
374 const PCHAR HelloString = "Hello\n";
375 ULONG StrSize = (lstrlenA(HelloString) + 1) * sizeof(CHAR);
376
377 if(BufferLength > 0)
378 {
379 memcpy(Buffer, HelloString, min(StrSize, BufferLength));
380 }
381
382 return StrSize;
383 }
384
385
386 /*
387 * HidD_SetFeature EXPORTED
388 *
389 * @implemented
390 */
391 HIDAPI
392 BOOLEAN DDKAPI
393 HidD_SetFeature(IN HANDLE HidDeviceObject,
394 IN PVOID ReportBuffer,
395 IN ULONG ReportBufferLength)
396 {
397 DWORD RetLen;
398 return DeviceIoControl(HidDeviceObject, IOCTL_HID_SET_FEATURE,
399 ReportBuffer, ReportBufferLength,
400 NULL, 0,
401 &RetLen, NULL);
402 }
403
404
405 /*
406 * HidD_SetNumInputBuffers EXPORTED
407 *
408 * @implemented
409 */
410 HIDAPI
411 BOOLEAN DDKAPI
412 HidD_SetNumInputBuffers(IN HANDLE HidDeviceObject,
413 IN ULONG NumberBuffers)
414 {
415 DWORD RetLen;
416 return DeviceIoControl(HidDeviceObject, IOCTL_SET_NUM_DEVICE_INPUT_BUFFERS,
417 &NumberBuffers, sizeof(ULONG),
418 NULL, 0,
419 &RetLen, NULL);
420 }
421
422
423 /*
424 * HidD_SetOutputReport EXPORTED
425 *
426 * @implemented
427 */
428 HIDAPI
429 BOOLEAN DDKAPI
430 HidD_SetOutputReport(IN HANDLE HidDeviceObject,
431 IN PVOID ReportBuffer,
432 IN ULONG ReportBufferLength)
433 {
434 DWORD RetLen;
435 return DeviceIoControl(HidDeviceObject, IOCTL_HID_SET_OUTPUT_REPORT,
436 ReportBuffer, ReportBufferLength,
437 NULL, 0,
438 &RetLen, NULL);
439 }
440
441 /* EOF */