[SHELL32]
[reactos.git] / reactos / dll / win32 / hid / hid.c
1 /*
2 * ReactOS Hid User Library
3 * Copyright (C) 2004-2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19 /*
20 * PROJECT: ReactOS Hid User Library
21 * FILE: lib/hid/hid.c
22 * PURPOSE: ReactOS Hid User Library
23 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
24 *
25 * UPDATE HISTORY:
26 * 07/12/2004 Created
27 */
28
29 #include "precomp.h"
30
31 #include <winbase.h>
32
33 #define NDEBUG
34 #include <debug.h>
35
36 HINSTANCE hDllInstance;
37
38 /* device interface GUID for HIDClass devices */
39 const GUID HidClassGuid = {0x4D1E55B2, 0xF16F, 0x11CF, {0x88,0xCB,0x00,0x11,0x11,0x00,0x00,0x30}};
40
41 BOOL WINAPI
42 DllMain(HINSTANCE hinstDLL,
43 DWORD dwReason,
44 LPVOID lpvReserved)
45 {
46 switch(dwReason)
47 {
48 case DLL_PROCESS_ATTACH:
49 hDllInstance = hinstDLL;
50 break;
51
52 case DLL_THREAD_ATTACH:
53 break;
54
55 case DLL_THREAD_DETACH:
56 break;
57
58 case DLL_PROCESS_DETACH:
59 break;
60 }
61 return TRUE;
62 }
63
64
65 /*
66 * HidD_FlushQueue EXPORTED
67 *
68 * @implemented
69 */
70 HIDAPI
71 BOOLEAN WINAPI
72 HidD_FlushQueue(IN HANDLE HidDeviceObject)
73 {
74 DWORD RetLen;
75 return DeviceIoControl(HidDeviceObject, IOCTL_HID_FLUSH_QUEUE,
76 NULL, 0,
77 NULL, 0,
78 &RetLen, NULL) != 0;
79 }
80
81
82 /*
83 * HidD_FreePreparsedData EXPORTED
84 *
85 * @implemented
86 */
87 HIDAPI
88 BOOLEAN WINAPI
89 HidD_FreePreparsedData(IN PHIDP_PREPARSED_DATA PreparsedData)
90 {
91 return (LocalFree((HLOCAL)PreparsedData) == NULL);
92 }
93
94
95 /*
96 * HidD_GetAttributes EXPORTED
97 *
98 * @implemented
99 */
100 HIDAPI
101 BOOLEAN WINAPI
102 HidD_GetAttributes(IN HANDLE HidDeviceObject,
103 OUT PHIDD_ATTRIBUTES Attributes)
104 {
105 HID_COLLECTION_INFORMATION hci;
106 DWORD RetLen;
107
108 if(!DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_COLLECTION_INFORMATION,
109 NULL, 0,
110 &hci, sizeof(HID_COLLECTION_INFORMATION),
111 &RetLen, NULL))
112 {
113 return FALSE;
114 }
115
116 /* copy the fields */
117 Attributes->Size = sizeof(HIDD_ATTRIBUTES);
118 Attributes->VendorID = hci.VendorID;
119 Attributes->ProductID = hci.ProductID;
120 Attributes->VersionNumber = hci.VersionNumber;
121
122 return TRUE;
123 }
124
125
126 /*
127 * HidP_GetButtonCaps EXPORTED
128 *
129 * @implemented
130 */
131 HIDAPI
132 NTSTATUS WINAPI
133 HidP_GetButtonCaps(IN HIDP_REPORT_TYPE ReportType,
134 OUT PHIDP_BUTTON_CAPS ButtonCaps,
135 IN OUT PUSHORT ButtonCapsLength,
136 IN PHIDP_PREPARSED_DATA PreparsedData)
137 {
138 return HidP_GetSpecificButtonCaps(ReportType, 0, 0, 0, ButtonCaps,
139 ButtonCapsLength, PreparsedData);
140 }
141
142
143 /*
144 * HidD_GetFeature EXPORTED
145 *
146 * @implemented
147 */
148 HIDAPI
149 BOOLEAN WINAPI
150 HidD_GetFeature(IN HANDLE HidDeviceObject,
151 OUT PVOID ReportBuffer,
152 IN ULONG ReportBufferLength)
153 {
154 DWORD RetLen;
155 return DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_FEATURE,
156 NULL, 0,
157 ReportBuffer, ReportBufferLength,
158 &RetLen, NULL) != 0;
159 }
160
161
162 /*
163 * HidD_GetHidGuid EXPORTED
164 *
165 * @implemented
166 */
167 HIDAPI
168 VOID WINAPI
169 HidD_GetHidGuid(OUT LPGUID HidGuid)
170 {
171 *HidGuid = HidClassGuid;
172 }
173
174
175 /*
176 * HidD_GetInputReport EXPORTED
177 *
178 * @implemented
179 */
180 HIDAPI
181 BOOLEAN WINAPI
182 HidD_GetInputReport(IN HANDLE HidDeviceObject,
183 IN OUT PVOID ReportBuffer,
184 IN ULONG ReportBufferLength)
185 {
186 DWORD RetLen;
187 return DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_INPUT_REPORT,
188 NULL, 0,
189 ReportBuffer, ReportBufferLength,
190 &RetLen, NULL) != 0;
191 }
192
193
194 /*
195 * HidD_GetManufacturerString EXPORTED
196 *
197 * @implemented
198 */
199 HIDAPI
200 BOOLEAN WINAPI
201 HidD_GetManufacturerString(IN HANDLE HidDeviceObject,
202 OUT PVOID Buffer,
203 IN ULONG BufferLength)
204 {
205 DWORD RetLen;
206 return DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_MANUFACTURER_STRING,
207 NULL, 0,
208 Buffer, BufferLength,
209 &RetLen, NULL) != 0;
210 }
211
212
213 /*
214 * HidD_GetNumInputBuffers EXPORTED
215 *
216 * @implemented
217 */
218 HIDAPI
219 BOOLEAN WINAPI
220 HidD_GetNumInputBuffers(IN HANDLE HidDeviceObject,
221 OUT PULONG NumberBuffers)
222 {
223 DWORD RetLen;
224 return DeviceIoControl(HidDeviceObject, IOCTL_GET_NUM_DEVICE_INPUT_BUFFERS,
225 NULL, 0,
226 NumberBuffers, sizeof(ULONG),
227 &RetLen, NULL) != 0;
228 }
229
230
231 /*
232 * HidD_GetPhysicalDescriptor EXPORTED
233 *
234 * @implemented
235 */
236 HIDAPI
237 BOOLEAN WINAPI
238 HidD_GetPhysicalDescriptor(IN HANDLE HidDeviceObject,
239 OUT PVOID Buffer,
240 IN ULONG BufferLength)
241 {
242 DWORD RetLen;
243 return DeviceIoControl(HidDeviceObject, IOCTL_GET_PHYSICAL_DESCRIPTOR,
244 NULL, 0,
245 Buffer, BufferLength,
246 &RetLen, NULL) != 0;
247 }
248
249
250 /*
251 * HidD_GetPreparsedData EXPORTED
252 *
253 * @implemented
254 */
255 HIDAPI
256 BOOLEAN WINAPI
257 HidD_GetPreparsedData(IN HANDLE HidDeviceObject,
258 OUT PHIDP_PREPARSED_DATA *PreparsedData)
259 {
260 HID_COLLECTION_INFORMATION hci;
261 DWORD RetLen;
262 BOOLEAN Ret;
263
264 if(PreparsedData == NULL)
265 {
266 return FALSE;
267 }
268
269 if(!DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_COLLECTION_INFORMATION,
270 NULL, 0,
271 &hci, sizeof(HID_COLLECTION_INFORMATION),
272 &RetLen, NULL))
273 {
274 return FALSE;
275 }
276
277 *PreparsedData = LocalAlloc(LHND, hci.DescriptorSize);
278 if(*PreparsedData == NULL)
279 {
280 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
281 return FALSE;
282 }
283
284 Ret = DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_COLLECTION_DESCRIPTOR,
285 NULL, 0,
286 *PreparsedData, hci.DescriptorSize,
287 &RetLen, NULL) != 0;
288
289 if(!Ret)
290 {
291 /* FIXME - Free the buffer in case we failed to get the descriptor? */
292 LocalFree((HLOCAL)*PreparsedData);
293 }
294 #if 0
295 else
296 {
297 /* should we truncate the memory in case RetLen < hci.DescriptorSize? */
298 }
299 #endif
300
301 return Ret;
302 }
303
304
305 /*
306 * HidD_GetProductString EXPORTED
307 *
308 * @implemented
309 */
310 HIDAPI
311 BOOLEAN WINAPI
312 HidD_GetProductString(IN HANDLE HidDeviceObject,
313 OUT PVOID Buffer,
314 IN ULONG BufferLength)
315 {
316 DWORD RetLen;
317 return DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_PRODUCT_STRING,
318 NULL, 0,
319 Buffer, BufferLength,
320 &RetLen, NULL) != 0;
321 }
322
323
324 /*
325 * HidD_GetSerialNumberString EXPORTED
326 *
327 * @implemented
328 */
329 HIDAPI
330 BOOLEAN WINAPI
331 HidD_GetSerialNumberString(IN HANDLE HidDeviceObject,
332 OUT PVOID Buffer,
333 IN ULONG BufferLength)
334 {
335 DWORD RetLen;
336 return DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_SERIALNUMBER_STRING,
337 NULL, 0,
338 Buffer, BufferLength,
339 &RetLen, NULL) != 0;
340 }
341
342
343 /*
344 * HidP_GetValueCaps EXPORTED
345 *
346 * @implemented
347 */
348 HIDAPI
349 NTSTATUS WINAPI
350 HidP_GetValueCaps(IN HIDP_REPORT_TYPE ReportType,
351 OUT PHIDP_VALUE_CAPS ValueCaps,
352 IN OUT PUSHORT ValueCapsLength,
353 IN PHIDP_PREPARSED_DATA PreparsedData)
354 {
355 return HidP_GetSpecificValueCaps(ReportType, 0, 0, 0, ValueCaps,
356 ValueCapsLength, PreparsedData);
357 }
358
359
360 /*
361 * HidD_Hello EXPORTED
362 *
363 * Undocumented easter egg function. It fills the buffer with "Hello\n"
364 * and returns number of bytes filled in (lstrlen(Buffer) + 1 == 7)
365 *
366 * Bugs: - doesn't check Buffer for NULL
367 * - always returns 7 even if BufferLength < 7 but doesn't produce a buffer overflow
368 *
369 * @implemented
370 */
371 HIDAPI
372 ULONG WINAPI
373 HidD_Hello(OUT PCHAR Buffer,
374 IN ULONG BufferLength)
375 {
376 const CHAR HelloString[] = "Hello\n";
377
378 if(BufferLength > 0)
379 {
380 memcpy(Buffer, HelloString, min(sizeof(HelloString), BufferLength));
381 }
382
383 return sizeof(HelloString);
384 }
385
386
387 /*
388 * HidD_SetFeature EXPORTED
389 *
390 * @implemented
391 */
392 HIDAPI
393 BOOLEAN WINAPI
394 HidD_SetFeature(IN HANDLE HidDeviceObject,
395 IN PVOID ReportBuffer,
396 IN ULONG ReportBufferLength)
397 {
398 DWORD RetLen;
399 return DeviceIoControl(HidDeviceObject, IOCTL_HID_SET_FEATURE,
400 ReportBuffer, ReportBufferLength,
401 NULL, 0,
402 &RetLen, NULL) != 0;
403 }
404
405
406 /*
407 * HidD_SetNumInputBuffers EXPORTED
408 *
409 * @implemented
410 */
411 HIDAPI
412 BOOLEAN WINAPI
413 HidD_SetNumInputBuffers(IN HANDLE HidDeviceObject,
414 IN ULONG NumberBuffers)
415 {
416 DWORD RetLen;
417 return DeviceIoControl(HidDeviceObject, IOCTL_SET_NUM_DEVICE_INPUT_BUFFERS,
418 &NumberBuffers, sizeof(ULONG),
419 NULL, 0,
420 &RetLen, NULL) != 0;
421 }
422
423
424 /*
425 * HidD_SetOutputReport EXPORTED
426 *
427 * @implemented
428 */
429 HIDAPI
430 BOOLEAN WINAPI
431 HidD_SetOutputReport(IN HANDLE HidDeviceObject,
432 IN PVOID ReportBuffer,
433 IN ULONG ReportBufferLength)
434 {
435 DWORD RetLen;
436 return DeviceIoControl(HidDeviceObject, IOCTL_HID_SET_OUTPUT_REPORT,
437 ReportBuffer, ReportBufferLength,
438 NULL, 0,
439 &RetLen, NULL) != 0;
440 }
441
442 /*
443 * HidD_GetIndexedString EXPORTED
444 *
445 * @implemented
446 */
447 HIDAPI
448 BOOLEAN WINAPI
449 HidD_GetIndexedString(IN HANDLE HidDeviceObject,
450 IN ULONG StringIndex,
451 OUT PVOID Buffer,
452 IN ULONG BufferLength)
453 {
454 DWORD RetLen;
455 return DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_INDEXED_STRING,
456 &StringIndex, sizeof(ULONG),
457 Buffer, BufferLength,
458 &RetLen, NULL) != 0;
459 }
460
461 /*
462 * HidD_GetMsGenreDescriptor EXPORTED
463 *
464 * @implemented
465 */
466 HIDAPI
467 BOOLEAN WINAPI
468 HidD_GetMsGenreDescriptor(IN HANDLE HidDeviceObject,
469 OUT PVOID Buffer,
470 IN ULONG BufferLength)
471 {
472 DWORD RetLen;
473 return DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_MS_GENRE_DESCRIPTOR,
474 0, 0,
475 Buffer, BufferLength,
476 &RetLen, NULL) != 0;
477 }
478
479 /*
480 * HidD_GetConfiguration EXPORTED
481 *
482 * @implemented
483 */
484 HIDAPI
485 BOOLEAN WINAPI
486 HidD_GetConfiguration(IN HANDLE HidDeviceObject,
487 OUT PHIDD_CONFIGURATION Configuration,
488 IN ULONG ConfigurationLength)
489 {
490
491 // magic cookie
492 Configuration->cookie = (PVOID)HidD_GetConfiguration;
493
494 return DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_DRIVER_CONFIG,
495 0, 0,
496 &Configuration->size, ConfigurationLength - sizeof(ULONG),
497 (PULONG)&Configuration->cookie, NULL) != 0;
498 }
499
500 /*
501 * HidD_SetConfiguration EXPORTED
502 *
503 * @implemented
504 */
505 HIDAPI
506 BOOLEAN WINAPI
507 HidD_SetConfiguration(IN HANDLE HidDeviceObject,
508 IN PHIDD_CONFIGURATION Configuration,
509 IN ULONG ConfigurationLength)
510 {
511 BOOLEAN Ret = FALSE;
512
513 if (Configuration->cookie == (PVOID)HidD_GetConfiguration)
514 {
515 Ret = DeviceIoControl(HidDeviceObject, IOCTL_HID_SET_DRIVER_CONFIG,
516 0, 0,
517 (PVOID)&Configuration->size, ConfigurationLength - sizeof(ULONG),
518 (PULONG)&Configuration->cookie, NULL) != 0;
519 }
520 else
521 {
522 SetLastError(ERROR_INVALID_PARAMETER);
523 }
524
525 return Ret;
526 }
527
528 /*
529 * HidP_GetUsagesEx EXPORTED
530 *
531 * @implemented
532 */
533 HIDAPI
534 NTSTATUS WINAPI
535 HidP_GetUsagesEx(IN HIDP_REPORT_TYPE ReportType,
536 IN USHORT LinkCollection,
537 OUT PUSAGE_AND_PAGE ButtonList,
538 IN OUT ULONG *UsageLength,
539 IN PHIDP_PREPARSED_DATA PreparsedData,
540 IN PCHAR Report,
541 IN ULONG ReportLength)
542 {
543 return HidP_GetUsages(ReportType, ButtonList->UsagePage, LinkCollection, &ButtonList->Usage, UsageLength, PreparsedData, Report, ReportLength);
544 }
545
546
547 /* EOF */