4 * Copyright 2021 RĂ©mi Bernon for CodeWeavers
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 WIN32_NO_STATUS
32 #include <ddk/hidpddi.h>
35 #include "wine/list.h"
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(hid
);
40 /* Flags that are defined in the document
41 "Device Class Definition for Human Interface Devices" */
44 INPUT_DATA_CONST
= 0x01, /* Data (0) | Constant (1) */
45 INPUT_ARRAY_VAR
= 0x02, /* Array (0) | Variable (1) */
46 INPUT_ABS_REL
= 0x04, /* Absolute (0) | Relative (1) */
47 INPUT_WRAP
= 0x08, /* No Wrap (0) | Wrap (1) */
48 INPUT_LINEAR
= 0x10, /* Linear (0) | Non Linear (1) */
49 INPUT_PREFSTATE
= 0x20, /* Preferred State (0) | No Preferred (1) */
50 INPUT_NULL
= 0x40, /* No Null position (0) | Null state(1) */
51 INPUT_VOLATILE
= 0x80, /* Non Volatile (0) | Volatile (1) */
52 INPUT_BITFIELD
= 0x100 /* Bit Field (0) | Buffered Bytes (1) */
65 TAG_MAIN_INPUT
= 0x08,
66 TAG_MAIN_OUTPUT
= 0x09,
67 TAG_MAIN_FEATURE
= 0x0B,
68 TAG_MAIN_COLLECTION
= 0x0A,
69 TAG_MAIN_END_COLLECTION
= 0x0C
74 TAG_GLOBAL_USAGE_PAGE
= 0x0,
75 TAG_GLOBAL_LOGICAL_MINIMUM
,
76 TAG_GLOBAL_LOGICAL_MAXIMUM
,
77 TAG_GLOBAL_PHYSICAL_MINIMUM
,
78 TAG_GLOBAL_PHYSICAL_MAXIMUM
,
79 TAG_GLOBAL_UNIT_EXPONENT
,
81 TAG_GLOBAL_REPORT_SIZE
,
83 TAG_GLOBAL_REPORT_COUNT
,
90 TAG_LOCAL_USAGE
= 0x0,
91 TAG_LOCAL_USAGE_MINIMUM
,
92 TAG_LOCAL_USAGE_MAXIMUM
,
93 TAG_LOCAL_DESIGNATOR_INDEX
,
94 TAG_LOCAL_DESIGNATOR_MINIMUM
,
95 TAG_LOCAL_DESIGNATOR_MAXIMUM
,
96 TAG_LOCAL_STRING_INDEX
= 0x7,
97 TAG_LOCAL_STRING_MINIMUM
,
98 TAG_LOCAL_STRING_MAXIMUM
,
102 static inline const char *debugstr_hid_value_caps( struct hid_value_caps
*caps
)
104 if (!caps
) return "(null)";
105 return wine_dbg_sprintf( "RId %d, Usg %02x:%02x-%02x Dat %02x-%02x, Str %d-%d, Des %d-%d, "
106 "Bits %02lx Flags %#lx, LCol %d LUsg %02x:%02x, BitSz %d, RCnt %d, Unit %lx E%+ld, Log %+ld-%+ld, Phy %+ld-%+ld",
107 caps
->report_id
, caps
->usage_page
, caps
->usage_min
, caps
->usage_max
, caps
->data_index_min
, caps
->data_index_max
,
108 caps
->string_min
, caps
->string_max
, caps
->designator_min
, caps
->designator_max
, caps
->bit_field
, caps
->flags
,
109 caps
->link_collection
, caps
->link_usage_page
, caps
->link_usage
, caps
->bit_size
, caps
->report_count
,
110 caps
->units
, caps
->units_exp
, caps
->logical_min
, caps
->logical_max
, caps
->physical_min
, caps
->physical_max
);
113 static inline const char *debugstr_hid_collection_node( struct hid_collection_node
*node
)
115 if (!node
) return "(null)";
116 return wine_dbg_sprintf( "Usg %02x:%02x, Parent %u, Next %u, NbChild %u, Child %u, Type %02lx",
117 node
->usage_page
, node
->usage
, node
->parent
, node
->next_sibling
,
118 node
->number_of_children
, node
->first_child
, node
->collection_type
);
121 static void debug_print_preparsed( struct hid_preparsed_data
*data
)
127 TRACE( "usage %02x:%02x input %u-(%u)-%u, report len %u output %u-(%u)-%u, report len %u "
128 "feature %u-(%u)-%u, report len %u collections %u\n", data
->usage_page
, data
->usage
,
129 data
->input_caps_start
, data
->input_caps_count
, data
->input_caps_end
, data
->input_report_byte_length
,
130 data
->output_caps_start
, data
->output_caps_count
, data
->output_caps_end
, data
->output_report_byte_length
,
131 data
->feature_caps_start
, data
->feature_caps_count
, data
->feature_caps_end
, data
->feature_report_byte_length
,
132 data
->number_link_collection_nodes
);
133 end
= data
->input_caps_end
- data
->input_caps_start
;
134 for (i
= 0; i
< end
; i
++) TRACE( "input %d: %s\n", i
, debugstr_hid_value_caps( HID_INPUT_VALUE_CAPS( data
) + i
) );
135 end
= data
->output_caps_end
- data
->output_caps_start
;
136 for (i
= 0; i
< end
; i
++) TRACE( "output %d: %s\n", i
, debugstr_hid_value_caps( HID_OUTPUT_VALUE_CAPS( data
) + i
) );
137 end
= data
->feature_caps_end
- data
->feature_caps_start
;
138 for (i
= 0; i
< end
; i
++) TRACE( "feature %d: %s\n", i
, debugstr_hid_value_caps( HID_FEATURE_VALUE_CAPS( data
) + i
) );
139 end
= data
->number_link_collection_nodes
;
140 for (i
= 0; i
< end
; i
++) TRACE( "collection %d: %s\n", i
, debugstr_hid_collection_node( HID_COLLECTION_NODES( data
) + i
) );
144 struct hid_parser_state
148 USHORT input_report_byte_length
;
149 USHORT output_report_byte_length
;
150 USHORT feature_report_byte_length
;
151 USHORT number_link_collection_nodes
;
153 USAGE usages_page
[256];
154 USAGE usages_min
[256];
155 USAGE usages_max
[256];
158 struct hid_value_caps items
;
160 struct hid_value_caps
*stack
;
163 DWORD collection_idx
;
165 struct hid_value_caps
*collections
;
166 DWORD collections_size
;
168 struct hid_value_caps
*values
[3];
169 ULONG values_size
[3];
171 ULONG bit_size
[3][256];
172 USHORT byte_length
[3];
173 USHORT caps_count
[3];
174 USHORT empty_caps
[3];
175 USHORT data_count
[3];
178 static BOOL
array_reserve( struct hid_value_caps
**array
, DWORD
*array_size
, DWORD index
)
180 if (index
< *array_size
) return TRUE
;
181 if ((*array_size
= *array_size
? (*array_size
* 3 / 2) : 32) <= index
) return FALSE
;
182 if (!(*array
= realloc( *array
, *array_size
* sizeof(**array
) ))) return FALSE
;
186 static void copy_global_items( struct hid_value_caps
*dst
, const struct hid_value_caps
*src
)
188 dst
->usage_page
= src
->usage_page
;
189 dst
->logical_min
= src
->logical_min
;
190 dst
->logical_max
= src
->logical_max
;
191 dst
->physical_min
= src
->physical_min
;
192 dst
->physical_max
= src
->physical_max
;
193 dst
->units_exp
= src
->units_exp
;
194 dst
->units
= src
->units
;
195 dst
->bit_size
= src
->bit_size
;
196 dst
->report_id
= src
->report_id
;
197 dst
->report_count
= src
->report_count
;
200 static void copy_collection_items( struct hid_value_caps
*dst
, const struct hid_value_caps
*src
)
202 dst
->link_collection
= src
->link_collection
;
203 dst
->link_usage_page
= src
->link_usage_page
;
204 dst
->link_usage
= src
->link_usage
;
207 static void reset_local_items( struct hid_parser_state
*state
)
209 struct hid_value_caps tmp
;
210 copy_global_items( &tmp
, &state
->items
);
211 copy_collection_items( &tmp
, &state
->items
);
212 memset( &state
->items
, 0, sizeof(state
->items
) );
213 copy_global_items( &state
->items
, &tmp
);
214 copy_collection_items( &state
->items
, &tmp
);
215 memset( &state
->usages_page
, 0, sizeof(state
->usages_page
) );
216 memset( &state
->usages_min
, 0, sizeof(state
->usages_min
) );
217 memset( &state
->usages_max
, 0, sizeof(state
->usages_max
) );
218 state
->usages_size
= 0;
221 static BOOL
parse_global_push( struct hid_parser_state
*state
)
223 if (!array_reserve( &state
->stack
, &state
->stack_size
, state
->global_idx
))
225 ERR( "HID parser stack overflow!\n" );
229 copy_global_items( state
->stack
+ state
->global_idx
, &state
->items
);
234 static BOOL
parse_global_pop( struct hid_parser_state
*state
)
236 if (!state
->global_idx
)
238 ERR( "HID parser global stack underflow!\n" );
243 copy_global_items( &state
->items
, state
->stack
+ state
->global_idx
);
247 static BOOL
parse_local_usage( struct hid_parser_state
*state
, USAGE usage_page
, USAGE usage
)
249 if (!usage_page
) usage_page
= state
->items
.usage_page
;
250 if (state
->items
.flags
& HID_VALUE_CAPS_IS_RANGE
) state
->usages_size
= 0;
251 state
->usages_page
[state
->usages_size
] = usage_page
;
252 state
->usages_min
[state
->usages_size
] = usage
;
253 state
->usages_max
[state
->usages_size
] = usage
;
254 state
->items
.usage_min
= usage
;
255 state
->items
.usage_max
= usage
;
256 state
->items
.flags
&= ~HID_VALUE_CAPS_IS_RANGE
;
257 if (state
->usages_size
++ == 255) ERR( "HID parser usages stack overflow!\n" );
258 return state
->usages_size
<= 255;
261 static void parse_local_usage_min( struct hid_parser_state
*state
, USAGE usage_page
, USAGE usage
)
263 if (!usage_page
) usage_page
= state
->items
.usage_page
;
264 if (!(state
->items
.flags
& HID_VALUE_CAPS_IS_RANGE
)) state
->usages_max
[0] = 0;
265 state
->usages_page
[0] = usage_page
;
266 state
->usages_min
[0] = usage
;
267 state
->items
.usage_min
= usage
;
268 state
->items
.flags
|= HID_VALUE_CAPS_IS_RANGE
;
269 state
->usages_size
= 1;
272 static void parse_local_usage_max( struct hid_parser_state
*state
, USAGE usage_page
, USAGE usage
)
274 if (!usage_page
) usage_page
= state
->items
.usage_page
;
275 if (!(state
->items
.flags
& HID_VALUE_CAPS_IS_RANGE
)) state
->usages_min
[0] = 0;
276 state
->usages_page
[0] = usage_page
;
277 state
->usages_max
[0] = usage
;
278 state
->items
.usage_max
= usage
;
279 state
->items
.flags
|= HID_VALUE_CAPS_IS_RANGE
;
280 state
->usages_size
= 1;
283 static BOOL
parse_new_collection( struct hid_parser_state
*state
)
285 if (!array_reserve( &state
->stack
, &state
->stack_size
, state
->collection_idx
))
287 ERR( "HID parser stack overflow!\n" );
291 if (!array_reserve( &state
->collections
, &state
->collections_size
, state
->number_link_collection_nodes
))
293 ERR( "HID parser collections overflow!\n" );
297 copy_collection_items( state
->stack
+ state
->collection_idx
, &state
->items
);
298 state
->collection_idx
++;
300 state
->items
.usage_min
= state
->usages_min
[0];
301 state
->items
.usage_max
= state
->usages_max
[0];
303 state
->collections
[state
->number_link_collection_nodes
] = state
->items
;
304 state
->items
.link_collection
= state
->number_link_collection_nodes
;
305 state
->items
.link_usage_page
= state
->items
.usage_page
;
306 state
->items
.link_usage
= state
->items
.usage_min
;
307 if (!state
->number_link_collection_nodes
)
309 state
->usage_page
= state
->items
.usage_page
;
310 state
->usage
= state
->items
.usage_min
;
312 state
->number_link_collection_nodes
++;
314 reset_local_items( state
);
318 static BOOL
parse_end_collection( struct hid_parser_state
*state
)
320 if (!state
->collection_idx
)
322 ERR( "HID parser collection stack underflow!\n" );
326 state
->collection_idx
--;
327 copy_collection_items( &state
->items
, state
->stack
+ state
->collection_idx
);
328 reset_local_items( state
);
332 static void add_new_value_caps( struct hid_parser_state
*state
, struct hid_value_caps
*values
,
333 LONG i
, ULONG start_bit
)
335 DWORD count
, usages_size
= max( 1, state
->usages_size
);
337 state
->items
.start_byte
= start_bit
/ 8;
338 state
->items
.start_bit
= start_bit
% 8;
339 state
->items
.total_bits
= state
->items
.report_count
* state
->items
.bit_size
;
340 state
->items
.end_byte
= (start_bit
+ state
->items
.total_bits
+ 7) / 8;
341 state
->items
.usage_page
= state
->usages_page
[usages_size
- 1 - i
];
342 state
->items
.usage_min
= state
->usages_min
[usages_size
- 1 - i
];
343 state
->items
.usage_max
= state
->usages_max
[usages_size
- 1 - i
];
344 if (!state
->items
.usage_max
&& !state
->items
.usage_min
) count
= -1;
345 else count
= state
->items
.usage_max
- state
->items
.usage_min
;
346 state
->items
.data_index_min
= state
->items
.data_index_max
+ 1;
347 state
->items
.data_index_max
= state
->items
.data_index_min
+ count
;
348 values
[i
] = state
->items
;
350 if (values
[i
].flags
& HID_VALUE_CAPS_IS_BUTTON
)
352 if (!HID_VALUE_CAPS_IS_ARRAY( values
+ i
)) values
[i
].logical_min
= 0;
353 else values
[i
].logical_min
= values
[i
].logical_max
;
354 values
[i
].logical_max
= 0;
355 values
[i
].physical_min
= 0;
356 values
[i
].physical_max
= 0;
360 static BOOL
parse_new_value_caps( struct hid_parser_state
*state
, HIDP_REPORT_TYPE type
)
362 struct hid_value_caps
*values
;
363 USAGE usage_page
= state
->items
.usage_page
;
364 USHORT report_count
= state
->items
.report_count
;
365 DWORD i
, usages_size
= max( 1, state
->usages_size
);
366 USHORT
*byte_length
= &state
->byte_length
[type
];
367 ULONG start_bit
, *bit_size
= &state
->bit_size
[type
][state
->items
.report_id
];
370 if (!*bit_size
) *bit_size
= 8;
371 *bit_size
+= state
->items
.bit_size
* state
->items
.report_count
;
372 *byte_length
= max( *byte_length
, (*bit_size
+ 7) / 8 );
373 start_bit
= *bit_size
;
375 if (!state
->items
.report_count
)
377 state
->empty_caps
[type
] += usages_size
;
378 reset_local_items( state
);
382 if (!array_reserve( &state
->values
[type
], &state
->values_size
[type
],
383 state
->caps_count
[type
] + usages_size
))
385 ERR( "HID parser values overflow!\n" );
388 values
= state
->values
[type
] + state
->caps_count
[type
];
390 if (!(is_array
= HID_VALUE_CAPS_IS_ARRAY( &state
->items
))) state
->items
.report_count
-= usages_size
- 1;
391 else start_bit
-= state
->items
.report_count
* state
->items
.bit_size
;
393 if (!(state
->items
.bit_field
& INPUT_ABS_REL
)) state
->items
.flags
|= HID_VALUE_CAPS_IS_ABSOLUTE
;
394 if (state
->items
.bit_field
& INPUT_DATA_CONST
) state
->items
.flags
|= HID_VALUE_CAPS_IS_CONSTANT
;
395 if (state
->items
.bit_size
== 1 || is_array
) state
->items
.flags
|= HID_VALUE_CAPS_IS_BUTTON
;
397 if (is_array
) state
->items
.null_value
= state
->items
.logical_min
;
398 else if (!(state
->items
.bit_field
& INPUT_NULL
)) state
->items
.null_value
= 0;
399 else state
->items
.null_value
= 1;
401 state
->items
.data_index_max
= state
->data_count
[type
] - 1;
402 for (i
= 0; i
< usages_size
; ++i
)
404 if (!is_array
) start_bit
-= state
->items
.report_count
* state
->items
.bit_size
;
405 else if (i
) state
->items
.flags
|= HID_VALUE_CAPS_ARRAY_HAS_MORE
;
406 else state
->items
.flags
&= ~HID_VALUE_CAPS_ARRAY_HAS_MORE
;
407 add_new_value_caps( state
, values
, is_array
? usages_size
- i
- 1 : i
, start_bit
);
408 if (!is_array
) state
->items
.report_count
= 1;
410 state
->caps_count
[type
] += usages_size
;
411 state
->data_count
[type
] = state
->items
.data_index_max
+ 1;
413 state
->items
.usage_page
= usage_page
;
414 state
->items
.report_count
= report_count
;
415 reset_local_items( state
);
419 static void free_parser_state( struct hid_parser_state
*state
)
421 if (state
->global_idx
) ERR( "%lu unpopped device caps on the stack\n", state
->global_idx
);
422 if (state
->collection_idx
) ERR( "%lu unpopped device collection on the stack\n", state
->collection_idx
);
423 free( state
->stack
);
424 free( state
->collections
);
425 free( state
->values
[HidP_Input
] );
426 free( state
->values
[HidP_Output
] );
427 free( state
->values
[HidP_Feature
] );
431 static struct hid_preparsed_data
*build_preparsed_data( struct hid_parser_state
*state
, POOL_TYPE pool_type
)
433 struct hid_collection_node
*nodes
;
434 struct hid_preparsed_data
*data
;
435 struct hid_value_caps
*caps
;
436 DWORD i
, size
, caps_size
;
438 caps_size
= state
->caps_count
[HidP_Input
] + state
->caps_count
[HidP_Output
] +
439 state
->caps_count
[HidP_Feature
];
440 caps_size
+= state
->empty_caps
[HidP_Input
] + state
->empty_caps
[HidP_Output
] +
441 state
->empty_caps
[HidP_Feature
];
442 caps_size
*= sizeof(struct hid_value_caps
);
444 size
= caps_size
+ FIELD_OFFSET(struct hid_preparsed_data
, value_caps
[0]) +
445 state
->number_link_collection_nodes
* sizeof(struct hid_collection_node
);
446 if (!(data
= ExAllocatePool( pool_type
, size
))) return NULL
;
447 memset( data
, 0, size
);
449 memcpy( data
->magic
, "HidP KDR", 8 );
450 data
->usage
= state
->usage
;
451 data
->usage_page
= state
->usage_page
;
452 data
->input_caps_start
= 0;
453 data
->input_caps_count
= state
->caps_count
[HidP_Input
] + state
->empty_caps
[HidP_Input
];
454 data
->input_caps_end
= data
->input_caps_start
+ state
->caps_count
[HidP_Input
];
455 data
->input_report_byte_length
= state
->byte_length
[HidP_Input
];
456 data
->output_caps_start
= data
->input_caps_end
;
457 data
->output_caps_count
= state
->caps_count
[HidP_Output
] + state
->empty_caps
[HidP_Output
];
458 data
->output_caps_end
= data
->output_caps_start
+ state
->caps_count
[HidP_Output
];
459 data
->output_report_byte_length
= state
->byte_length
[HidP_Output
];
460 data
->feature_caps_start
= data
->output_caps_end
;
461 data
->feature_caps_count
= state
->caps_count
[HidP_Feature
] + state
->empty_caps
[HidP_Feature
];
462 data
->feature_caps_end
= data
->feature_caps_start
+ state
->caps_count
[HidP_Feature
];
463 data
->feature_report_byte_length
= state
->byte_length
[HidP_Feature
];
464 data
->caps_size
= caps_size
;
465 data
->number_link_collection_nodes
= state
->number_link_collection_nodes
;
467 caps
= HID_INPUT_VALUE_CAPS( data
);
468 memcpy( caps
, state
->values
[0], state
->caps_count
[HidP_Input
] * sizeof(*caps
) );
469 caps
= HID_OUTPUT_VALUE_CAPS( data
);
470 memcpy( caps
, state
->values
[1], state
->caps_count
[HidP_Output
] * sizeof(*caps
) );
471 caps
= HID_FEATURE_VALUE_CAPS( data
);
472 memcpy( caps
, state
->values
[2], state
->caps_count
[HidP_Feature
] * sizeof(*caps
) );
474 nodes
= HID_COLLECTION_NODES( data
);
475 for (i
= 0; i
< data
->number_link_collection_nodes
; ++i
)
477 nodes
[i
].usage_page
= state
->collections
[i
].usage_page
;
478 nodes
[i
].usage
= state
->collections
[i
].usage_min
;
479 nodes
[i
].parent
= state
->collections
[i
].link_collection
;
480 nodes
[i
].collection_type
= state
->collections
[i
].bit_field
;
481 nodes
[i
].first_child
= 0;
482 nodes
[i
].next_sibling
= 0;
483 nodes
[i
].number_of_children
= 0;
487 nodes
[i
].next_sibling
= nodes
[nodes
[i
].parent
].first_child
;
488 nodes
[nodes
[i
].parent
].first_child
= i
;
489 nodes
[nodes
[i
].parent
].number_of_children
++;
496 struct hid_preparsed_data
*parse_descriptor( BYTE
*descriptor
, unsigned int length
, POOL_TYPE pool_type
)
498 struct hid_preparsed_data
*data
= NULL
;
499 struct hid_parser_state
*state
;
507 TRACE( "descriptor %p, length %u:\n", descriptor
, length
);
508 for (i
= 0; i
< length
;)
511 do { TRACE( " %02x", descriptor
[i
] ); } while (++i
% 16 && i
< length
);
516 if (!(state
= calloc( 1, sizeof(*state
) ))) return NULL
;
518 for (ptr
= descriptor
, end
= descriptor
+ length
; ptr
!= end
; ptr
+= size
+ 1)
520 size
= (*ptr
& 0x03);
521 if (size
== 3) size
= 4;
522 if (ptr
+ size
> end
)
524 ERR( "Need %d bytes to read item value\n", size
);
528 if (size
== 0) signed_value
= value
= 0;
529 else if (size
== 1) signed_value
= (INT8
)(value
= *(UINT8
*)(ptr
+ 1));
530 else if (size
== 2) signed_value
= (INT16
)(value
= *(UINT16
*)(ptr
+ 1));
531 else if (size
== 4) signed_value
= (INT32
)(value
= *(UINT32
*)(ptr
+ 1));
534 ERR( "Unexpected item value size %d.\n", size
);
538 state
->items
.bit_field
= value
;
540 #define SHORT_ITEM( tag, type ) (((tag) << 4) | ((type) << 2))
541 switch (*ptr
& SHORT_ITEM( 0xf, 0x3 ))
543 case SHORT_ITEM( TAG_MAIN_INPUT
, TAG_TYPE_MAIN
):
544 if (!parse_new_value_caps( state
, HidP_Input
)) goto done
;
546 case SHORT_ITEM( TAG_MAIN_OUTPUT
, TAG_TYPE_MAIN
):
547 if (!parse_new_value_caps( state
, HidP_Output
)) goto done
;
549 case SHORT_ITEM( TAG_MAIN_FEATURE
, TAG_TYPE_MAIN
):
550 if (!parse_new_value_caps( state
, HidP_Feature
)) goto done
;
552 case SHORT_ITEM( TAG_MAIN_COLLECTION
, TAG_TYPE_MAIN
):
553 if (!parse_new_collection( state
)) goto done
;
555 case SHORT_ITEM( TAG_MAIN_END_COLLECTION
, TAG_TYPE_MAIN
):
556 if (!parse_end_collection( state
)) goto done
;
559 case SHORT_ITEM( TAG_GLOBAL_USAGE_PAGE
, TAG_TYPE_GLOBAL
):
560 state
->items
.usage_page
= value
;
562 case SHORT_ITEM( TAG_GLOBAL_LOGICAL_MINIMUM
, TAG_TYPE_GLOBAL
):
563 state
->items
.logical_min
= signed_value
;
565 case SHORT_ITEM( TAG_GLOBAL_LOGICAL_MAXIMUM
, TAG_TYPE_GLOBAL
):
566 state
->items
.logical_max
= signed_value
;
568 case SHORT_ITEM( TAG_GLOBAL_PHYSICAL_MINIMUM
, TAG_TYPE_GLOBAL
):
569 state
->items
.physical_min
= signed_value
;
571 case SHORT_ITEM( TAG_GLOBAL_PHYSICAL_MAXIMUM
, TAG_TYPE_GLOBAL
):
572 state
->items
.physical_max
= signed_value
;
574 case SHORT_ITEM( TAG_GLOBAL_UNIT_EXPONENT
, TAG_TYPE_GLOBAL
):
575 state
->items
.units_exp
= signed_value
;
577 case SHORT_ITEM( TAG_GLOBAL_UNIT
, TAG_TYPE_GLOBAL
):
578 state
->items
.units
= signed_value
;
580 case SHORT_ITEM( TAG_GLOBAL_REPORT_SIZE
, TAG_TYPE_GLOBAL
):
581 state
->items
.bit_size
= value
;
583 case SHORT_ITEM( TAG_GLOBAL_REPORT_ID
, TAG_TYPE_GLOBAL
):
584 state
->items
.report_id
= value
;
586 case SHORT_ITEM( TAG_GLOBAL_REPORT_COUNT
, TAG_TYPE_GLOBAL
):
587 state
->items
.report_count
= value
;
589 case SHORT_ITEM( TAG_GLOBAL_PUSH
, TAG_TYPE_GLOBAL
):
590 if (!parse_global_push( state
)) goto done
;
592 case SHORT_ITEM( TAG_GLOBAL_POP
, TAG_TYPE_GLOBAL
):
593 if (!parse_global_pop( state
)) goto done
;
596 case SHORT_ITEM( TAG_LOCAL_USAGE
, TAG_TYPE_LOCAL
):
597 if (!parse_local_usage( state
, value
>> 16, value
& 0xffff )) goto done
;
599 case SHORT_ITEM( TAG_LOCAL_USAGE_MINIMUM
, TAG_TYPE_LOCAL
):
600 parse_local_usage_min( state
, value
>> 16, value
& 0xffff );
602 case SHORT_ITEM( TAG_LOCAL_USAGE_MAXIMUM
, TAG_TYPE_LOCAL
):
603 parse_local_usage_max( state
, value
>> 16, value
& 0xffff );
605 case SHORT_ITEM( TAG_LOCAL_DESIGNATOR_INDEX
, TAG_TYPE_LOCAL
):
606 state
->items
.designator_min
= state
->items
.designator_max
= value
;
607 state
->items
.flags
&= ~HID_VALUE_CAPS_IS_DESIGNATOR_RANGE
;
609 case SHORT_ITEM( TAG_LOCAL_DESIGNATOR_MINIMUM
, TAG_TYPE_LOCAL
):
610 state
->items
.designator_min
= value
;
611 state
->items
.flags
|= HID_VALUE_CAPS_IS_DESIGNATOR_RANGE
;
613 case SHORT_ITEM( TAG_LOCAL_DESIGNATOR_MAXIMUM
, TAG_TYPE_LOCAL
):
614 state
->items
.designator_max
= value
;
615 state
->items
.flags
|= HID_VALUE_CAPS_IS_DESIGNATOR_RANGE
;
617 case SHORT_ITEM( TAG_LOCAL_STRING_INDEX
, TAG_TYPE_LOCAL
):
618 state
->items
.string_min
= state
->items
.string_max
= value
;
619 state
->items
.flags
&= ~HID_VALUE_CAPS_IS_STRING_RANGE
;
621 case SHORT_ITEM( TAG_LOCAL_STRING_MINIMUM
, TAG_TYPE_LOCAL
):
622 state
->items
.string_min
= value
;
623 state
->items
.flags
|= HID_VALUE_CAPS_IS_STRING_RANGE
;
625 case SHORT_ITEM( TAG_LOCAL_STRING_MAXIMUM
, TAG_TYPE_LOCAL
):
626 state
->items
.string_max
= value
;
627 state
->items
.flags
|= HID_VALUE_CAPS_IS_STRING_RANGE
;
629 case SHORT_ITEM( TAG_LOCAL_DELIMITER
, TAG_TYPE_LOCAL
):
630 FIXME( "delimiter %d not implemented!\n", value
);
634 FIXME( "item type %x not implemented!\n", *ptr
);
640 if ((data
= build_preparsed_data( state
, pool_type
))) debug_print_preparsed( data
);
643 free_parser_state( state
);
647 NTSTATUS WINAPI
HidP_GetCollectionDescription( PHIDP_REPORT_DESCRIPTOR report_desc
, ULONG report_desc_len
,
648 POOL_TYPE pool_type
, HIDP_DEVICE_DESC
*device_desc
)
650 ULONG i
, len
, report_count
= 0, input_len
[256] = {0}, output_len
[256] = {0}, feature_len
[256] = {0};
651 struct hid_value_caps
*caps
, *caps_end
;
652 struct hid_preparsed_data
*preparsed
;
654 TRACE( "report_desc %p, report_desc_len %lu, pool_type %u, device_desc %p.\n",
655 report_desc
, report_desc_len
, pool_type
, device_desc
);
657 memset( device_desc
, 0, sizeof(*device_desc
) );
659 if (!(preparsed
= parse_descriptor( report_desc
, report_desc_len
, pool_type
)))
660 return HIDP_STATUS_INTERNAL_ERROR
;
662 if (!(device_desc
->CollectionDesc
= ExAllocatePool( pool_type
, sizeof(*device_desc
->CollectionDesc
) )))
665 return STATUS_NO_MEMORY
;
668 len
= preparsed
->caps_size
+ FIELD_OFFSET(struct hid_preparsed_data
, value_caps
[0]) +
669 preparsed
->number_link_collection_nodes
* sizeof(struct hid_collection_node
);
671 device_desc
->CollectionDescLength
= 1;
672 device_desc
->CollectionDesc
[0].UsagePage
= preparsed
->usage_page
;
673 device_desc
->CollectionDesc
[0].Usage
= preparsed
->usage
;
674 device_desc
->CollectionDesc
[0].CollectionNumber
= 1;
675 device_desc
->CollectionDesc
[0].InputLength
= preparsed
->input_report_byte_length
;
676 device_desc
->CollectionDesc
[0].OutputLength
= preparsed
->output_report_byte_length
;
677 device_desc
->CollectionDesc
[0].FeatureLength
= preparsed
->feature_report_byte_length
;
678 device_desc
->CollectionDesc
[0].PreparsedDataLength
= len
;
679 device_desc
->CollectionDesc
[0].PreparsedData
= (PHIDP_PREPARSED_DATA
)preparsed
;
681 caps
= HID_INPUT_VALUE_CAPS( preparsed
);
682 caps_end
= caps
+ preparsed
->input_caps_end
- preparsed
->input_caps_start
;
683 for (; caps
!= caps_end
; ++caps
)
685 len
= caps
->start_byte
* 8 + caps
->start_bit
+ caps
->bit_size
* caps
->report_count
;
686 if (!input_len
[caps
->report_id
]) report_count
++;
687 input_len
[caps
->report_id
] = max(input_len
[caps
->report_id
], len
);
690 caps
= HID_OUTPUT_VALUE_CAPS( preparsed
);
691 caps_end
= caps
+ preparsed
->output_caps_end
- preparsed
->output_caps_start
;
692 for (; caps
!= caps_end
; ++caps
)
694 len
= caps
->start_byte
* 8 + caps
->start_bit
+ caps
->bit_size
* caps
->report_count
;
695 if (!input_len
[caps
->report_id
] && !output_len
[caps
->report_id
]) report_count
++;
696 output_len
[caps
->report_id
] = max(output_len
[caps
->report_id
], len
);
699 caps
= HID_FEATURE_VALUE_CAPS( preparsed
);
700 caps_end
= caps
+ preparsed
->feature_caps_end
- preparsed
->feature_caps_start
;
701 for (; caps
!= caps_end
; ++caps
)
703 len
= caps
->start_byte
* 8 + caps
->start_bit
+ caps
->bit_size
* caps
->report_count
;
704 if (!input_len
[caps
->report_id
] && !output_len
[caps
->report_id
] && !feature_len
[caps
->report_id
]) report_count
++;
705 feature_len
[caps
->report_id
] = max(feature_len
[caps
->report_id
], len
);
708 if (!(device_desc
->ReportIDs
= ExAllocatePool( pool_type
, sizeof(*device_desc
->ReportIDs
) * report_count
)))
711 ExFreePool( device_desc
->CollectionDesc
);
712 return STATUS_NO_MEMORY
;
715 for (i
= 0, report_count
= 0; i
< 256; ++i
)
717 if (!input_len
[i
] && !output_len
[i
] && !feature_len
[i
]) continue;
718 device_desc
->ReportIDs
[report_count
].ReportID
= i
;
719 device_desc
->ReportIDs
[report_count
].CollectionNumber
= 1;
720 device_desc
->ReportIDs
[report_count
].InputLength
= (input_len
[i
] + 7) / 8;
721 device_desc
->ReportIDs
[report_count
].OutputLength
= (output_len
[i
] + 7) / 8;
722 device_desc
->ReportIDs
[report_count
].FeatureLength
= (feature_len
[i
] + 7) / 8;
725 device_desc
->ReportIDsLength
= report_count
;
727 return HIDP_STATUS_SUCCESS
;
730 void WINAPI
HidP_FreeCollectionDescription( HIDP_DEVICE_DESC
*device_desc
)
732 TRACE( "device_desc %p.\n", device_desc
);
734 ExFreePool( device_desc
->CollectionDesc
);
735 ExFreePool( device_desc
->ReportIDs
);