4 * Copyright (C) 2015 Aric Stewart
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #define NONAMELESSUNION
27 #define WIN32_NO_STATUS
35 #include "ddk/hidpi.h"
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(hidp
);
41 static NTSTATUS
get_report_data(BYTE
*report
, INT reportLength
, INT startBit
, INT valueSize
, PULONG value
)
44 if ((startBit
+ valueSize
) / 8 > reportLength
)
45 return HIDP_STATUS_INVALID_REPORT_LENGTH
;
49 ULONG byte_index
= startBit
/ 8;
50 ULONG bit_index
= startBit
- (byte_index
* 8);
51 INT mask
= (1 << bit_index
);
52 *value
= (report
[byte_index
] & mask
);
56 ULONG byte_index
= startBit
/ 8;
58 ULONG remainingBits
= valueSize
;
60 ULONG begin_offset
= startBit
% 8;
63 if (remainingBits
>= 8)
65 BYTE mask
= 0xff << begin_offset
;
66 data
|= (report
[byte_index
] & mask
) << shift
;
68 remainingBits
-= (8-begin_offset
);
69 shift
+= (8-begin_offset
);
72 else if (remainingBits
> 0)
74 BYTE mask
= (0xff >> (8-remainingBits
)) << begin_offset
;
75 data
|= (report
[byte_index
] & mask
) << shift
;
81 return HIDP_STATUS_SUCCESS
;
84 NTSTATUS WINAPI
HidP_GetButtonCaps(HIDP_REPORT_TYPE ReportType
, PHIDP_BUTTON_CAPS ButtonCaps
,
85 PUSHORT ButtonCapsLength
, PHIDP_PREPARSED_DATA PreparsedData
)
87 PWINE_HIDP_PREPARSED_DATA data
= (PWINE_HIDP_PREPARSED_DATA
)PreparsedData
;
88 WINE_HID_REPORT
*report
= NULL
;
89 USHORT b_count
= 0, r_count
= 0;
92 TRACE("(%i, %p, %p, %p)\n",ReportType
, ButtonCaps
, ButtonCapsLength
, PreparsedData
);
94 if (data
->magic
!= HID_MAGIC
)
95 return HIDP_STATUS_INVALID_PREPARSED_DATA
;
100 b_count
= data
->caps
.NumberInputButtonCaps
;
101 r_count
= data
->dwInputReportCount
;
102 report
= HID_INPUT_REPORTS(data
);
105 b_count
= data
->caps
.NumberOutputButtonCaps
;
106 r_count
= data
->dwOutputReportCount
;
107 report
= HID_OUTPUT_REPORTS(data
);
110 b_count
= data
->caps
.NumberFeatureButtonCaps
;
111 r_count
= data
->dwFeatureReportCount
;
112 report
= HID_FEATURE_REPORTS(data
);
115 return HIDP_STATUS_INVALID_REPORT_TYPE
;
118 if (!r_count
|| !b_count
|| !report
)
120 *ButtonCapsLength
= 0;
121 return HIDP_STATUS_SUCCESS
;
124 b_count
= min(b_count
, *ButtonCapsLength
);
127 for (j
= 0; j
< r_count
&& u
< b_count
; j
++)
129 for (i
= 0; i
< report
->elementCount
&& u
< b_count
; i
++)
131 if (report
->Elements
[i
].ElementType
== ButtonElement
)
132 ButtonCaps
[u
++] = report
->Elements
[i
].caps
.button
;
134 report
= HID_NEXT_REPORT(data
, report
);
137 *ButtonCapsLength
= b_count
;
138 return HIDP_STATUS_SUCCESS
;
142 NTSTATUS WINAPI
HidP_GetCaps(PHIDP_PREPARSED_DATA PreparsedData
,
143 PHIDP_CAPS Capabilities
)
145 PWINE_HIDP_PREPARSED_DATA data
= (PWINE_HIDP_PREPARSED_DATA
)PreparsedData
;
147 TRACE("(%p, %p)\n",PreparsedData
, Capabilities
);
149 if (data
->magic
!= HID_MAGIC
)
150 return HIDP_STATUS_INVALID_PREPARSED_DATA
;
152 *Capabilities
= data
->caps
;
154 return HIDP_STATUS_SUCCESS
;
157 static NTSTATUS
find_value(HIDP_REPORT_TYPE ReportType
, USAGE UsagePage
, USHORT LinkCollection
,
158 USAGE Usage
, PHIDP_PREPARSED_DATA PreparsedData
, PCHAR Report
,
159 WINE_HID_ELEMENT
**element
)
161 PWINE_HIDP_PREPARSED_DATA data
= (PWINE_HIDP_PREPARSED_DATA
)PreparsedData
;
162 WINE_HID_REPORT
*report
= NULL
;
163 USHORT v_count
= 0, r_count
= 0;
166 TRACE("(%i, %x, %i, %i, %p, %p)\n", ReportType
, UsagePage
, LinkCollection
, Usage
,
167 PreparsedData
, Report
);
169 if (data
->magic
!= HID_MAGIC
)
170 return HIDP_STATUS_INVALID_PREPARSED_DATA
;
174 v_count
= data
->caps
.NumberInputValueCaps
;
175 r_count
= data
->dwInputReportCount
;
176 report
= HID_INPUT_REPORTS(data
);
179 v_count
= data
->caps
.NumberOutputValueCaps
;
180 r_count
= data
->dwOutputReportCount
;
181 report
= HID_OUTPUT_REPORTS(data
);
184 v_count
= data
->caps
.NumberFeatureValueCaps
;
185 r_count
= data
->dwFeatureReportCount
;
186 report
= HID_FEATURE_REPORTS(data
);
189 return HIDP_STATUS_INVALID_REPORT_TYPE
;
192 if (!r_count
|| !v_count
|| !report
)
193 return HIDP_STATUS_USAGE_NOT_FOUND
;
195 for (i
= 0; i
< r_count
; i
++)
197 if (!report
->reportID
|| report
->reportID
== Report
[0])
199 report
= HID_NEXT_REPORT(data
, report
);
203 return HIDP_STATUS_REPORT_DOES_NOT_EXIST
;
205 for (i
= 0; i
< report
->elementCount
; i
++)
207 if (report
->Elements
[i
].ElementType
== ValueElement
&&
208 report
->Elements
[i
].caps
.value
.UsagePage
== UsagePage
&&
209 report
->Elements
[i
].caps
.value
.u
.NotRange
.Usage
== Usage
)
211 *element
= &report
->Elements
[i
];
212 return HIDP_STATUS_SUCCESS
;
216 return HIDP_STATUS_USAGE_NOT_FOUND
;
219 NTSTATUS WINAPI
HidP_GetScaledUsageValue(HIDP_REPORT_TYPE ReportType
, USAGE UsagePage
,
220 USHORT LinkCollection
, USAGE Usage
, PLONG UsageValue
,
221 PHIDP_PREPARSED_DATA PreparsedData
, PCHAR Report
, ULONG ReportLength
)
224 WINE_HID_ELEMENT
*element
;
225 TRACE("(%i, %x, %i, %i, %p, %p, %p, %i)\n", ReportType
, UsagePage
, LinkCollection
, Usage
, UsageValue
,
226 PreparsedData
, Report
, ReportLength
);
228 rc
= find_value(ReportType
, UsagePage
, LinkCollection
, Usage
, PreparsedData
, Report
, &element
);
230 if (rc
== HIDP_STATUS_SUCCESS
)
233 rc
= get_report_data((BYTE
*)Report
, ReportLength
,
234 element
->valueStartBit
, element
->bitCount
, &rawValue
);
235 if (rc
!= HIDP_STATUS_SUCCESS
)
237 if (element
->caps
.value
.BitSize
== 16)
238 rawValue
= (short)rawValue
;
239 *UsageValue
= rawValue
;
246 NTSTATUS WINAPI
HidP_GetUsageValue(HIDP_REPORT_TYPE ReportType
, USAGE UsagePage
, USHORT LinkCollection
,
247 USAGE Usage
, PULONG UsageValue
, PHIDP_PREPARSED_DATA PreparsedData
,
248 PCHAR Report
, ULONG ReportLength
)
250 WINE_HID_ELEMENT
*element
;
253 TRACE("(%i, %x, %i, %i, %p, %p, %p, %i)\n", ReportType
, UsagePage
, LinkCollection
, Usage
, UsageValue
,
254 PreparsedData
, Report
, ReportLength
);
256 rc
= find_value(ReportType
, UsagePage
, LinkCollection
, Usage
, PreparsedData
, Report
, &element
);
258 if (rc
== HIDP_STATUS_SUCCESS
)
260 return get_report_data((BYTE
*)Report
, ReportLength
,
261 element
->valueStartBit
, element
->bitCount
, UsageValue
);
268 NTSTATUS WINAPI
HidP_GetUsages(HIDP_REPORT_TYPE ReportType
, USAGE UsagePage
, USHORT LinkCollection
,
269 PUSAGE UsageList
, PULONG UsageLength
, PHIDP_PREPARSED_DATA PreparsedData
,
270 PCHAR Report
, ULONG ReportLength
)
272 PWINE_HIDP_PREPARSED_DATA data
= (PWINE_HIDP_PREPARSED_DATA
)PreparsedData
;
273 WINE_HID_REPORT
*report
= NULL
;
275 USHORT b_count
= 0, r_count
= 0;
278 TRACE("(%i, %x, %i, %p, %p, %p, %p, %i)\n", ReportType
, UsagePage
, LinkCollection
, UsageList
,
279 UsageLength
, PreparsedData
, Report
, ReportLength
);
281 if (data
->magic
!= HID_MAGIC
)
284 return HIDP_STATUS_INVALID_PREPARSED_DATA
;
290 b_count
= data
->caps
.NumberInputButtonCaps
;
291 r_count
= data
->dwInputReportCount
;
292 report
= HID_INPUT_REPORTS(data
);
295 b_count
= data
->caps
.NumberOutputButtonCaps
;
296 r_count
= data
->dwOutputReportCount
;
297 report
= HID_OUTPUT_REPORTS(data
);
300 b_count
= data
->caps
.NumberFeatureButtonCaps
;
301 r_count
= data
->dwFeatureReportCount
;
302 report
= HID_FEATURE_REPORTS(data
);
305 return HIDP_STATUS_INVALID_REPORT_TYPE
;
308 if (!r_count
|| !b_count
|| !report
)
309 return HIDP_STATUS_USAGE_NOT_FOUND
;
311 for (i
= 0; i
< r_count
; i
++)
313 if (!report
->reportID
|| report
->reportID
== Report
[0])
315 report
= HID_NEXT_REPORT(data
, report
);
319 return HIDP_STATUS_REPORT_DOES_NOT_EXIST
;
322 for (i
= 0; i
< report
->elementCount
&& uCount
< *UsageLength
; i
++)
324 if (report
->Elements
[i
].ElementType
== ButtonElement
&&
325 report
->Elements
[i
].caps
.button
.UsagePage
== UsagePage
)
328 WINE_HID_ELEMENT
*element
= &report
->Elements
[i
];
329 for (k
=0; k
< element
->bitCount
; k
++)
332 NTSTATUS rc
= get_report_data((BYTE
*)Report
, ReportLength
,
333 element
->valueStartBit
+ k
, 1, &v
);
334 if (rc
!= HIDP_STATUS_SUCCESS
)
339 if (uCount
== *UsageLength
)
340 return HIDP_STATUS_BUFFER_TOO_SMALL
;
341 UsageList
[uCount
] = element
->caps
.button
.u
.Range
.UsageMin
+ k
;
348 *UsageLength
= uCount
;
351 return HIDP_STATUS_USAGE_NOT_FOUND
;
353 return HIDP_STATUS_SUCCESS
;
357 NTSTATUS WINAPI
HidP_GetValueCaps(HIDP_REPORT_TYPE ReportType
, PHIDP_VALUE_CAPS ValueCaps
,
358 PUSHORT ValueCapsLength
, PHIDP_PREPARSED_DATA PreparsedData
)
360 PWINE_HIDP_PREPARSED_DATA data
= (PWINE_HIDP_PREPARSED_DATA
)PreparsedData
;
361 WINE_HID_REPORT
*report
= NULL
;
362 USHORT v_count
= 0, r_count
= 0;
365 TRACE("(%i, %p, %p, %p)\n", ReportType
, ValueCaps
, ValueCapsLength
, PreparsedData
);
367 if (data
->magic
!= HID_MAGIC
)
368 return HIDP_STATUS_INVALID_PREPARSED_DATA
;
373 v_count
= data
->caps
.NumberInputValueCaps
;
374 r_count
= data
->dwInputReportCount
;
375 report
= HID_INPUT_REPORTS(data
);
378 v_count
= data
->caps
.NumberOutputValueCaps
;
379 r_count
= data
->dwOutputReportCount
;
380 report
= HID_OUTPUT_REPORTS(data
);
383 v_count
= data
->caps
.NumberFeatureValueCaps
;
384 r_count
= data
->dwFeatureReportCount
;
385 report
= HID_FEATURE_REPORTS(data
);
388 return HIDP_STATUS_INVALID_REPORT_TYPE
;
391 if (!r_count
|| !v_count
|| !report
)
393 *ValueCapsLength
= 0;
394 return HIDP_STATUS_SUCCESS
;
397 v_count
= min(v_count
, *ValueCapsLength
);
400 for (j
= 0; j
< r_count
&& u
< v_count
; j
++)
402 for (i
= 0; i
< report
->elementCount
&& u
< v_count
; i
++)
404 if (report
->Elements
[i
].ElementType
== ValueElement
)
405 ValueCaps
[u
++] = report
->Elements
[i
].caps
.value
;
407 report
= HID_NEXT_REPORT(data
, report
);
410 *ValueCapsLength
= v_count
;
411 return HIDP_STATUS_SUCCESS
;
414 NTSTATUS WINAPI
HidP_InitializeReportForID(HIDP_REPORT_TYPE ReportType
, UCHAR ReportID
,
415 PHIDP_PREPARSED_DATA PreparsedData
, PCHAR Report
,
419 PWINE_HIDP_PREPARSED_DATA data
= (PWINE_HIDP_PREPARSED_DATA
)PreparsedData
;
420 WINE_HID_REPORT
*report
= NULL
;
425 TRACE("(%i, %i, %p, %p, %i)\n",ReportType
, ReportID
, PreparsedData
, Report
, ReportLength
);
427 if (data
->magic
!= HID_MAGIC
)
428 return HIDP_STATUS_INVALID_PREPARSED_DATA
;
433 size
= data
->caps
.InputReportByteLength
;
434 report
= HID_INPUT_REPORTS(data
);
435 r_count
= data
->dwInputReportCount
;
438 size
= data
->caps
.OutputReportByteLength
;
439 report
= HID_OUTPUT_REPORTS(data
);
440 r_count
= data
->dwOutputReportCount
;
443 size
= data
->caps
.FeatureReportByteLength
;
444 report
= HID_FEATURE_REPORTS(data
);
445 r_count
= data
->dwFeatureReportCount
;
448 return HIDP_STATUS_INVALID_REPORT_TYPE
;
451 if (!r_count
|| !size
|| !report
)
452 return HIDP_STATUS_REPORT_DOES_NOT_EXIST
;
454 if (size
!= ReportLength
)
455 return HIDP_STATUS_INVALID_REPORT_LENGTH
;
457 ZeroMemory(Report
, size
);
459 for (i
= 0; i
< r_count
; i
++)
461 if (report
->reportID
== ReportID
)
464 if (report
->reportID
)
465 Report
[0] = ReportID
;
466 /* TODO: Handle null and default values */
468 report
= HID_NEXT_REPORT(data
, report
);
472 return HIDP_STATUS_REPORT_DOES_NOT_EXIST
;
474 return HIDP_STATUS_SUCCESS
;
477 ULONG WINAPI
HidP_MaxUsageListLength(HIDP_REPORT_TYPE ReportType
, USAGE UsagePage
, PHIDP_PREPARSED_DATA PreparsedData
)
479 PWINE_HIDP_PREPARSED_DATA data
= (PWINE_HIDP_PREPARSED_DATA
)PreparsedData
;
480 WINE_HID_REPORT
*report
= NULL
;
485 TRACE("(%i, %x, %p)\n", ReportType
, UsagePage
, PreparsedData
);
487 if (data
->magic
!= HID_MAGIC
)
493 report
= HID_INPUT_REPORTS(data
);
494 r_count
= data
->dwInputReportCount
;
497 report
= HID_OUTPUT_REPORTS(data
);
498 r_count
= data
->dwOutputReportCount
;
501 report
= HID_FEATURE_REPORTS(data
);
502 r_count
= data
->dwFeatureReportCount
;
505 return HIDP_STATUS_INVALID_REPORT_TYPE
;
508 if (!r_count
|| !report
)
511 for (i
= 0; i
< r_count
; i
++)
514 for (j
= 0; j
< report
->elementCount
; j
++)
516 if (report
->Elements
[j
].ElementType
== ButtonElement
&&
517 (UsagePage
== 0 || report
->Elements
[j
].caps
.button
.UsagePage
== UsagePage
))
519 if (report
->Elements
[j
].caps
.button
.IsRange
)
520 count
+= (report
->Elements
[j
].caps
.button
.u
.Range
.UsageMax
-
521 report
->Elements
[j
].caps
.button
.u
.Range
.UsageMin
) + 1;
526 report
= HID_NEXT_REPORT(data
, report
);
531 NTSTATUS WINAPI
HidP_TranslateUsagesToI8042ScanCodes(USAGE
*ChangedUsageList
,
532 ULONG UsageListLength
, HIDP_KEYBOARD_DIRECTION KeyAction
,
533 HIDP_KEYBOARD_MODIFIER_STATE
*ModifierState
,
534 PHIDP_INSERT_SCANCODES InsertCodesProcedure
, VOID
*InsertCodesContext
)
536 FIXME("stub: %p, %i, %i, %p, %p, %p\n", ChangedUsageList
, UsageListLength
,
537 KeyAction
, ModifierState
, InsertCodesProcedure
, InsertCodesContext
);
539 return STATUS_NOT_IMPLEMENTED
;
542 NTSTATUS WINAPI
HidP_GetSpecificButtonCaps(HIDP_REPORT_TYPE ReportType
,
543 USAGE UsagePage
, USHORT LinkCollection
, USAGE Usage
,
544 HIDP_BUTTON_CAPS
*ButtonCaps
, USHORT
*ButtonCapsLength
, PHIDP_PREPARSED_DATA PreparsedData
)
546 WINE_HIDP_PREPARSED_DATA
*data
= (WINE_HIDP_PREPARSED_DATA
*)PreparsedData
;
547 WINE_HID_REPORT
*report
= NULL
;
548 USHORT b_count
= 0, r_count
= 0;
551 TRACE("(%i, 0x%x, %i, 0x%x, %p %p %p)\n", ReportType
, UsagePage
, LinkCollection
,
552 Usage
, ButtonCaps
, ButtonCapsLength
, PreparsedData
);
554 if (data
->magic
!= HID_MAGIC
)
555 return HIDP_STATUS_INVALID_PREPARSED_DATA
;
560 b_count
= data
->caps
.NumberInputButtonCaps
;
561 r_count
= data
->dwInputReportCount
;
562 report
= HID_INPUT_REPORTS(data
);
565 b_count
= data
->caps
.NumberOutputButtonCaps
;
566 r_count
= data
->dwOutputReportCount
;
567 report
= HID_OUTPUT_REPORTS(data
);
570 b_count
= data
->caps
.NumberFeatureButtonCaps
;
571 r_count
= data
->dwFeatureReportCount
;
572 report
= HID_FEATURE_REPORTS(data
);
575 return HIDP_STATUS_INVALID_REPORT_TYPE
;
578 if (!r_count
|| !b_count
|| !report
)
580 *ButtonCapsLength
= 0;
581 return HIDP_STATUS_SUCCESS
;
584 b_count
= min(b_count
, *ButtonCapsLength
);
587 for (j
= 0; j
< r_count
&& u
< b_count
; j
++)
589 for (i
= 0; i
< report
->elementCount
&& u
< b_count
; i
++)
591 if (report
->Elements
[i
].ElementType
== ButtonElement
&&
592 (UsagePage
== 0 || UsagePage
== report
->Elements
[i
].caps
.button
.UsagePage
) &&
593 (LinkCollection
== 0 || LinkCollection
== report
->Elements
[i
].caps
.button
.LinkCollection
) &&
595 (!report
->Elements
[i
].caps
.button
.IsRange
&&
596 Usage
== report
->Elements
[i
].caps
.button
.u
.NotRange
.Usage
)) ||
597 (report
->Elements
[i
].caps
.button
.IsRange
&&
598 Usage
>=report
->Elements
[i
].caps
.button
.u
.Range
.UsageMin
&&
599 Usage
<= report
->Elements
[i
].caps
.button
.u
.Range
.UsageMax
)))
601 ButtonCaps
[u
++] = report
->Elements
[i
].caps
.button
;
604 report
= HID_NEXT_REPORT(data
, report
);
606 TRACE("Matched %i usages\n", u
);
608 *ButtonCapsLength
= u
;
610 return HIDP_STATUS_SUCCESS
;
614 NTSTATUS WINAPI
HidP_GetSpecificValueCaps(HIDP_REPORT_TYPE ReportType
,
615 USAGE UsagePage
, USHORT LinkCollection
, USAGE Usage
,
616 HIDP_VALUE_CAPS
*ValueCaps
, USHORT
*ValueCapsLength
, PHIDP_PREPARSED_DATA PreparsedData
)
618 WINE_HIDP_PREPARSED_DATA
*data
= (PWINE_HIDP_PREPARSED_DATA
)PreparsedData
;
619 WINE_HID_REPORT
*report
= NULL
;
620 USHORT v_count
= 0, r_count
= 0;
623 TRACE("(%i, 0x%x, %i, 0x%x, %p %p %p)\n", ReportType
, UsagePage
, LinkCollection
,
624 Usage
, ValueCaps
, ValueCapsLength
, PreparsedData
);
626 if (data
->magic
!= HID_MAGIC
)
627 return HIDP_STATUS_INVALID_PREPARSED_DATA
;
632 v_count
= data
->caps
.NumberInputValueCaps
;
633 r_count
= data
->dwInputReportCount
;
634 report
= HID_INPUT_REPORTS(data
);
637 v_count
= data
->caps
.NumberOutputValueCaps
;
638 r_count
= data
->dwOutputReportCount
;
639 report
= HID_OUTPUT_REPORTS(data
);
642 v_count
= data
->caps
.NumberFeatureValueCaps
;
643 r_count
= data
->dwFeatureReportCount
;
644 report
= HID_FEATURE_REPORTS(data
);
647 return HIDP_STATUS_INVALID_REPORT_TYPE
;
650 if (!r_count
|| !v_count
|| !report
)
652 *ValueCapsLength
= 0;
653 return HIDP_STATUS_SUCCESS
;
656 v_count
= min(v_count
, *ValueCapsLength
);
659 for (j
= 0; j
< r_count
&& u
< v_count
; j
++)
661 for (i
= 0; i
< report
->elementCount
&& u
< v_count
; i
++)
663 if (report
->Elements
[i
].ElementType
== ValueElement
&&
664 (UsagePage
== 0 || UsagePage
== report
->Elements
[i
].caps
.value
.UsagePage
) &&
665 (LinkCollection
== 0 || LinkCollection
== report
->Elements
[i
].caps
.value
.LinkCollection
) &&
666 (Usage
== 0 || Usage
== report
->Elements
[i
].caps
.value
.u
.NotRange
.Usage
))
668 ValueCaps
[u
++] = report
->Elements
[i
].caps
.value
;
671 report
= HID_NEXT_REPORT(data
, report
);
673 TRACE("Matched %i usages\n", u
);
675 *ValueCapsLength
= u
;
677 return HIDP_STATUS_SUCCESS
;
680 NTSTATUS WINAPI
HidP_GetUsagesEx(HIDP_REPORT_TYPE ReportType
, USHORT LinkCollection
, USAGE_AND_PAGE
*ButtonList
,
681 ULONG
*UsageLength
, PHIDP_PREPARSED_DATA PreparsedData
, CHAR
*Report
, ULONG ReportLength
)
683 WINE_HIDP_PREPARSED_DATA
*data
= (WINE_HIDP_PREPARSED_DATA
*)PreparsedData
;
684 WINE_HID_REPORT
*report
= NULL
;
685 USHORT b_count
= 0, r_count
= 0;
689 TRACE("(%i, %i, %p, %p(%i), %p, %p, %i)\n", ReportType
, LinkCollection
, ButtonList
,
690 UsageLength
, *UsageLength
, PreparsedData
, Report
, ReportLength
);
692 if (data
->magic
!= HID_MAGIC
)
693 return HIDP_STATUS_INVALID_PREPARSED_DATA
;
698 b_count
= data
->caps
.NumberInputButtonCaps
;
699 r_count
= data
->dwInputReportCount
;
700 report
= HID_INPUT_REPORTS(data
);
703 b_count
= data
->caps
.NumberOutputButtonCaps
;
704 r_count
= data
->dwOutputReportCount
;
705 report
= HID_OUTPUT_REPORTS(data
);
708 b_count
= data
->caps
.NumberFeatureButtonCaps
;
709 r_count
= data
->dwFeatureReportCount
;
710 report
= HID_FEATURE_REPORTS(data
);
713 return HIDP_STATUS_INVALID_REPORT_TYPE
;
716 if (!r_count
|| !b_count
|| !report
)
717 return HIDP_STATUS_USAGE_NOT_FOUND
;
719 for (i
= 0; i
< r_count
; i
++)
721 if (!report
->reportID
|| report
->reportID
== Report
[0])
723 report
= HID_NEXT_REPORT(data
, report
);
727 return HIDP_STATUS_REPORT_DOES_NOT_EXIST
;
729 for (i
= 0; i
< report
->elementCount
; i
++)
731 if (report
->Elements
[i
].ElementType
== ButtonElement
)
734 WINE_HID_ELEMENT
*element
= &report
->Elements
[i
];
735 for (k
=0; k
< element
->bitCount
; k
++)
738 NTSTATUS rc
= get_report_data((BYTE
*)Report
, ReportLength
,
739 element
->valueStartBit
+ k
, 1, &v
);
740 if (rc
!= HIDP_STATUS_SUCCESS
)
744 if (uCount
< *UsageLength
)
746 ButtonList
[uCount
].Usage
= element
->caps
.button
.u
.Range
.UsageMin
+ k
;
747 ButtonList
[uCount
].UsagePage
= element
->caps
.button
.UsagePage
;
755 TRACE("Returning %i usages\n", uCount
);
757 if (*UsageLength
< uCount
)
758 rc
= HIDP_STATUS_BUFFER_TOO_SMALL
;
760 rc
= HIDP_STATUS_SUCCESS
;
762 *UsageLength
= uCount
;
767 ULONG WINAPI
HidP_MaxDataListLength(HIDP_REPORT_TYPE ReportType
, PHIDP_PREPARSED_DATA PreparsedData
)
769 WINE_HIDP_PREPARSED_DATA
*data
= (WINE_HIDP_PREPARSED_DATA
*)PreparsedData
;
770 TRACE("(%i, %p)\n", ReportType
, PreparsedData
);
771 if (data
->magic
!= HID_MAGIC
)
777 return data
->caps
.NumberInputDataIndices
;
779 return data
->caps
.NumberOutputDataIndices
;
781 return data
->caps
.NumberFeatureDataIndices
;
787 NTSTATUS WINAPI
HidP_GetData(HIDP_REPORT_TYPE ReportType
, HIDP_DATA
*DataList
, ULONG
*DataLength
,
788 PHIDP_PREPARSED_DATA PreparsedData
,CHAR
*Report
, ULONG ReportLength
)
790 WINE_HIDP_PREPARSED_DATA
*data
= (WINE_HIDP_PREPARSED_DATA
*)PreparsedData
;
791 WINE_HID_REPORT
*report
= NULL
;
796 TRACE("(%i, %p, %p(%i), %p, %p, %i)\n", ReportType
, DataList
, DataLength
,
797 DataLength
?*DataLength
:0, PreparsedData
, Report
, ReportLength
);
799 if (data
->magic
!= HID_MAGIC
)
805 r_count
= data
->dwInputReportCount
;
806 report
= HID_INPUT_REPORTS(data
);
809 r_count
= data
->dwOutputReportCount
;
810 report
= HID_OUTPUT_REPORTS(data
);
813 r_count
= data
->dwFeatureReportCount
;
814 report
= HID_FEATURE_REPORTS(data
);
817 return HIDP_STATUS_INVALID_REPORT_TYPE
;
820 for (i
= 0; i
< r_count
; i
++)
822 if (!report
->reportID
|| report
->reportID
== Report
[0])
824 report
= HID_NEXT_REPORT(data
, report
);
828 return HIDP_STATUS_REPORT_DOES_NOT_EXIST
;
830 for (i
= 0; i
< report
->elementCount
; i
++)
832 WINE_HID_ELEMENT
*element
= &report
->Elements
[i
];
833 if (element
->ElementType
== ButtonElement
)
836 for (k
=0; k
< element
->bitCount
; k
++)
839 NTSTATUS rc
= get_report_data((BYTE
*)Report
, ReportLength
,
840 element
->valueStartBit
+ k
, 1, &v
);
841 if (rc
!= HIDP_STATUS_SUCCESS
)
845 if (uCount
< *DataLength
)
847 DataList
[uCount
].DataIndex
= element
->caps
.button
.u
.Range
.DataIndexMin
+ k
;
848 DataList
[uCount
].u
.On
= v
;
856 if (uCount
< *DataLength
)
859 NTSTATUS rc
= get_report_data((BYTE
*)Report
, ReportLength
,
860 element
->valueStartBit
, element
->bitCount
, &v
);
861 if (rc
!= HIDP_STATUS_SUCCESS
)
863 if (element
->caps
.value
.BitSize
== 16)
865 DataList
[uCount
].DataIndex
= element
->caps
.value
.u
.NotRange
.DataIndex
;
866 DataList
[uCount
].u
.RawValue
= v
;
872 if (*DataLength
< uCount
)
873 rc
= HIDP_STATUS_BUFFER_TOO_SMALL
;
875 rc
= HIDP_STATUS_SUCCESS
;
877 *DataLength
= uCount
;