From: "Rémi Bernon" Subject: [PATCH 6/6] hidclass.sys: Compute report sizes during parsing. Message-Id: <20210618073940.3507834-6-rbernon@codeweavers.com> Date: Fri, 18 Jun 2021 09:39:40 +0200 In-Reply-To: <20210618073940.3507834-1-rbernon@codeweavers.com> References: <20210618073940.3507834-1-rbernon@codeweavers.com> Signed-off-by: Rémi Bernon --- dlls/hidclass.sys/descriptor.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/dlls/hidclass.sys/descriptor.c b/dlls/hidclass.sys/descriptor.c index 26edb102034..9bde61c4289 100644 --- a/dlls/hidclass.sys/descriptor.c +++ b/dlls/hidclass.sys/descriptor.c @@ -286,6 +286,9 @@ struct hid_parser_state struct hid_value_caps *collections; DWORD collections_size; + + ULONG bit_size[3][256]; + USHORT *byte_size[3]; /* pointers to caps */ }; static BOOL array_reserve( struct hid_value_caps **array, DWORD *array_size, DWORD index ) @@ -441,6 +444,8 @@ static BOOL parse_end_collection( struct hid_parser_state *state ) static BOOL parse_new_value_caps( struct hid_parser_state *state, HIDP_REPORT_TYPE type, struct collection *collection ) { + USHORT *byte_size = state->byte_size[type]; + ULONG *bit_size = &state->bit_size[type][state->items.report_id]; struct feature *feature; int j; @@ -460,10 +465,22 @@ static BOOL parse_new_value_caps( struct hid_parser_state *state, HIDP_REPORT_TY } } + if (!*bit_size) *bit_size = 8; + *bit_size += state->items.bit_size * state->items.report_count; + *byte_size = max( *byte_size, (*bit_size + 7) / 8 ); + reset_local_items( state ); return TRUE; } +static void init_parser_state( struct hid_parser_state *state ) +{ + memset( state, 0, sizeof(*state) ); + state->byte_size[HidP_Input] = &state->caps.InputReportByteLength; + state->byte_size[HidP_Output] = &state->caps.OutputReportByteLength; + state->byte_size[HidP_Feature] = &state->caps.FeatureReportByteLength; +} + static void free_parser_state( struct hid_parser_state *state ) { if (state->global_idx) ERR( "%u unpopped device caps on the stack\n", state->global_idx ); @@ -744,20 +761,14 @@ static void preparse_collection(const struct collection *root, const struct coll case HidP_Input: build_elements(report, elem, f, &data->caps.NumberInputDataIndices); count_elements(f, &data->caps.NumberInputButtonCaps, &data->caps.NumberInputValueCaps); - data->caps.InputReportByteLength = - max(data->caps.InputReportByteLength, (report->bitSize + 7) / 8); break; case HidP_Output: build_elements(report, elem, f, &data->caps.NumberOutputDataIndices); count_elements(f, &data->caps.NumberOutputButtonCaps, &data->caps.NumberOutputValueCaps); - data->caps.OutputReportByteLength = - max(data->caps.OutputReportByteLength, (report->bitSize + 7) / 8); break; case HidP_Feature: build_elements(report, elem, f, &data->caps.NumberFeatureDataIndices); count_elements(f, &data->caps.NumberFeatureButtonCaps, &data->caps.NumberFeatureValueCaps); - data->caps.FeatureReportByteLength = - max(data->caps.FeatureReportByteLength, (report->bitSize + 7) / 8); break; } } @@ -862,6 +873,7 @@ WINE_HIDP_PREPARSED_DATA* ParseDescriptor(BYTE *descriptor, unsigned int length) } list_init(&base->features); list_init(&base->collections); + init_parser_state( state ); if (parse_descriptor( descriptor, 0, length, base, state ) < 0) { -- 2.31.0