hidparse.sys: Split struct hid_value_caps start_bit into start_byte / start_bit.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Rémi Bernon 2021-09-17 09:18:54 +02:00 committed by Alexandre Julliard
parent 5030f4cf26
commit 6fa0d12724
3 changed files with 57 additions and 25 deletions

View file

@ -192,10 +192,13 @@ static NTSTATUS get_scaled_usage_value( const struct hid_value_caps *caps, void
struct usage_value_params *params = user;
ULONG unsigned_value = 0, bit_count = caps->bit_size * caps->report_count;
LONG signed_value, *value = params->value_buf;
unsigned char *report_buf;
if ((bit_count + 7) / 8 > sizeof(unsigned_value)) return HIDP_STATUS_BUFFER_TOO_SMALL;
if (sizeof(LONG) > params->value_len) return HIDP_STATUS_BUFFER_TOO_SMALL;
copy_bits( (unsigned char *)&unsigned_value, params->report_buf, bit_count, -caps->start_bit );
report_buf = (unsigned char *)params->report_buf + caps->start_byte;
copy_bits( (unsigned char *)&unsigned_value, report_buf, bit_count, -caps->start_bit );
signed_value = sign_extend( unsigned_value, caps );
if (caps->logical_min > caps->logical_max || caps->physical_min > caps->physical_max)
@ -232,9 +235,14 @@ static NTSTATUS get_usage_value( const struct hid_value_caps *caps, void *user )
{
struct usage_value_params *params = user;
ULONG bit_count = caps->bit_size * caps->report_count;
unsigned char *report_buf;
if ((bit_count + 7) / 8 > params->value_len) return HIDP_STATUS_BUFFER_TOO_SMALL;
memset( params->value_buf, 0, params->value_len );
copy_bits( params->value_buf, params->report_buf, bit_count, -caps->start_bit );
report_buf = (unsigned char *)params->report_buf + caps->start_byte;
copy_bits( params->value_buf, report_buf, bit_count, -caps->start_bit );
return HIDP_STATUS_NULL;
}
@ -285,14 +293,17 @@ struct get_usage_params
static NTSTATUS get_usage( const struct hid_value_caps *caps, void *user )
{
struct get_usage_params *params = user;
unsigned char *report_buf;
ULONG bit, last;
BYTE index;
report_buf = (unsigned char *)params->report_buf + caps->start_byte;
if (HID_VALUE_CAPS_IS_ARRAY( caps ))
{
for (bit = caps->start_bit, last = bit + caps->report_count * caps->bit_size - 1; bit <= last; bit += 8)
{
if (!(index = params->report_buf[bit / 8])) continue;
if (!(index = report_buf[bit / 8])) continue;
if (params->usages < params->usages_end) *params->usages = caps->usage_min + index - caps->start_index;
params->usages++;
}
@ -301,7 +312,7 @@ static NTSTATUS get_usage( const struct hid_value_caps *caps, void *user )
for (bit = caps->start_bit, last = bit + caps->usage_max - caps->usage_min; bit <= last; ++bit)
{
if (!(params->report_buf[bit / 8] & (1 << (bit % 8)))) continue;
if (!(report_buf[bit / 8] & (1 << (bit % 8)))) continue;
if (params->usages < params->usages_end) *params->usages = caps->usage_min + bit - caps->start_bit;
params->usages++;
}
@ -384,6 +395,7 @@ static NTSTATUS set_scaled_usage_value( const struct hid_value_caps *caps, void
{
ULONG bit_count = caps->bit_size * caps->report_count;
struct usage_value_params *params = user;
unsigned char *report_buf;
LONG value, log_range, phy_range;
if (caps->logical_min > caps->logical_max) return HIDP_STATUS_BAD_LOG_PHY_VALUES;
@ -404,7 +416,8 @@ static NTSTATUS set_scaled_usage_value( const struct hid_value_caps *caps, void
value = caps->logical_min + value;
}
copy_bits( params->report_buf, (unsigned char *)&value, bit_count, caps->start_bit );
report_buf = (unsigned char *)params->report_buf + caps->start_byte;
copy_bits( report_buf, (unsigned char *)&value, bit_count, caps->start_bit );
return HIDP_STATUS_NULL;
}
@ -431,8 +444,13 @@ static NTSTATUS set_usage_value( const struct hid_value_caps *caps, void *user )
{
struct usage_value_params *params = user;
ULONG bit_count = caps->bit_size * caps->report_count;
unsigned char *report_buf;
if ((bit_count + 7) / 8 > params->value_len) return HIDP_STATUS_BUFFER_TOO_SMALL;
copy_bits( params->report_buf, params->value_buf, bit_count, caps->start_bit );
report_buf = (unsigned char *)params->report_buf + caps->start_byte;
copy_bits( report_buf, params->value_buf, bit_count, caps->start_bit );
return HIDP_STATUS_NULL;
}
@ -481,14 +499,17 @@ struct set_usage_params
static NTSTATUS set_usage( const struct hid_value_caps *caps, void *user )
{
struct set_usage_params *params = user;
unsigned char *report_buf;
ULONG bit, last;
report_buf = (unsigned char *)params->report_buf + caps->start_byte;
if (HID_VALUE_CAPS_IS_ARRAY( caps ))
{
for (bit = caps->start_bit, last = bit + caps->report_count * caps->bit_size - 1; bit <= last; bit += 8)
{
if (params->report_buf[bit / 8]) continue;
params->report_buf[bit / 8] = caps->start_index + params->usage - caps->usage_min;
if (report_buf[bit / 8]) continue;
report_buf[bit / 8] = caps->start_index + params->usage - caps->usage_min;
break;
}
@ -497,7 +518,7 @@ static NTSTATUS set_usage( const struct hid_value_caps *caps, void *user )
}
bit = caps->start_bit + params->usage - caps->usage_min;
params->report_buf[bit / 8] |= (1 << (bit % 8));
report_buf[bit / 8] |= (1 << (bit % 8));
return HIDP_STATUS_NULL;
}
@ -538,15 +559,18 @@ struct unset_usage_params
static NTSTATUS unset_usage( const struct hid_value_caps *caps, void *user )
{
struct unset_usage_params *params = user;
unsigned char *report_buf;
ULONG bit, index, last;
report_buf = (unsigned char *)params->report_buf + caps->start_byte;
if (HID_VALUE_CAPS_IS_ARRAY( caps ))
{
for (bit = caps->start_bit, last = bit + caps->report_count * caps->bit_size - 1; bit <= last; bit += 8)
{
index = caps->start_index + params->usage - caps->usage_min;
if (params->report_buf[bit / 8] != index) continue;
params->report_buf[bit / 8] = 0;
if (report_buf[bit / 8] != index) continue;
report_buf[bit / 8] = 0;
params->found = TRUE;
break;
}
@ -555,8 +579,8 @@ static NTSTATUS unset_usage( const struct hid_value_caps *caps, void *user )
}
bit = caps->start_bit + params->usage - caps->usage_min;
if (params->report_buf[bit / 8] & (1 << (bit % 8))) params->found = TRUE;
params->report_buf[bit / 8] &= ~(1 << (bit % 8));
if (report_buf[bit / 8] & (1 << (bit % 8))) params->found = TRUE;
report_buf[bit / 8] &= ~(1 << (bit % 8));
return HIDP_STATUS_NULL;
}
@ -726,14 +750,17 @@ struct get_usage_and_page_params
static NTSTATUS get_usage_and_page( const struct hid_value_caps *caps, void *user )
{
struct get_usage_and_page_params *params = user;
unsigned char *report_buf;
ULONG bit, last;
BYTE index;
report_buf = (unsigned char *)params->report_buf + caps->start_byte;
if (HID_VALUE_CAPS_IS_ARRAY( caps ))
{
for (bit = caps->start_bit, last = bit + caps->report_count * caps->bit_size - 1; bit <= last; bit += 8)
{
if (!(index = params->report_buf[bit / 8])) continue;
if (!(index = report_buf[bit / 8])) continue;
if (params->usages < params->usages_end)
{
params->usages->UsagePage = caps->usage_page;
@ -746,7 +773,7 @@ static NTSTATUS get_usage_and_page( const struct hid_value_caps *caps, void *use
for (bit = caps->start_bit, last = bit + caps->usage_max - caps->usage_min; bit <= last; bit++)
{
if (!(params->report_buf[bit / 8] & (1 << (bit % 8)))) continue;
if (!(report_buf[bit / 8] & (1 << (bit % 8)))) continue;
if (params->usages < params->usages_end)
{
params->usages->UsagePage = caps->usage_page;
@ -813,11 +840,13 @@ static NTSTATUS find_all_data( const struct hid_value_caps *caps, void *user )
struct find_all_data_params *params = user;
HIDP_DATA *data = params->data, *data_end = params->data_end;
ULONG bit, last, bit_count = caps->bit_size * caps->report_count;
char *report_buf = params->report_buf;
unsigned char *report_buf;
BYTE index;
if (!caps->bit_size) return HIDP_STATUS_SUCCESS;
report_buf = (unsigned char *)params->report_buf + caps->start_byte;
if (HID_VALUE_CAPS_IS_ARRAY( caps ))
{
for (bit = caps->start_bit, last = bit + caps->report_count * caps->bit_size - 1; bit <= last; bit += 8)
@ -851,7 +880,7 @@ static NTSTATUS find_all_data( const struct hid_value_caps *caps, void *user )
data->DataIndex = caps->data_index_min;
data->RawValue = 0;
if ((bit_count + 7) / 8 > sizeof(data->RawValue)) return HIDP_STATUS_BUFFER_TOO_SMALL;
copy_bits( (void *)&data->RawValue, (void *)report_buf, bit_count, -caps->start_bit );
copy_bits( (void *)&data->RawValue, report_buf, bit_count, -caps->start_bit );
}
data++;
}

View file

@ -333,13 +333,13 @@ static BOOL parse_new_value_caps( struct hid_parser_state *state, HIDP_REPORT_TY
USHORT *byte_size = state->byte_size[type];
USHORT *value_idx = state->value_idx[type];
USHORT *data_idx = state->data_idx[type];
ULONG *bit_size = &state->bit_size[type][state->items.report_id];
ULONG start_bit, *bit_size = &state->bit_size[type][state->items.report_id];
BOOL is_array;
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 );
state->items.start_bit = *bit_size;
start_bit = *bit_size;
if (!state->items.report_count)
{
@ -356,11 +356,13 @@ static BOOL parse_new_value_caps( struct hid_parser_state *state, HIDP_REPORT_TY
state->items.start_index = usages_size;
if (!(is_array = HID_VALUE_CAPS_IS_ARRAY( &state->items ))) state->items.report_count -= usages_size - 1;
else state->items.start_bit -= state->items.report_count * state->items.bit_size;
else start_bit -= state->items.report_count * state->items.bit_size;
while (usages_size--)
{
if (!is_array) state->items.start_bit -= state->items.report_count * state->items.bit_size;
if (!is_array) start_bit -= state->items.report_count * state->items.bit_size;
state->items.start_byte = start_bit / 8;
state->items.start_bit = start_bit % 8;
state->items.usage_page = state->usages_page[usages_size];
state->items.usage_min = state->usages_min[usages_size];
state->items.usage_max = state->usages_max[usages_size];
@ -652,7 +654,7 @@ NTSTATUS WINAPI HidP_GetCollectionDescription( PHIDP_REPORT_DESCRIPTOR report_de
caps_end = caps + preparsed->value_caps_count[HidP_Input];
for (; caps != caps_end; ++caps)
{
len = caps->start_bit + caps->bit_size * caps->report_count;
len = caps->start_byte * 8 + caps->start_bit + caps->bit_size * caps->report_count;
if (!input_len[caps->report_id]) report_count++;
input_len[caps->report_id] = max(input_len[caps->report_id], len);
}
@ -661,7 +663,7 @@ NTSTATUS WINAPI HidP_GetCollectionDescription( PHIDP_REPORT_DESCRIPTOR report_de
caps_end = caps + preparsed->value_caps_count[HidP_Output];
for (; caps != caps_end; ++caps)
{
len = caps->start_bit + caps->bit_size * caps->report_count;
len = caps->start_byte * 8 + caps->start_bit + caps->bit_size * caps->report_count;
if (!input_len[caps->report_id] && !output_len[caps->report_id]) report_count++;
output_len[caps->report_id] = max(output_len[caps->report_id], len);
}
@ -670,7 +672,7 @@ NTSTATUS WINAPI HidP_GetCollectionDescription( PHIDP_REPORT_DESCRIPTOR report_de
caps_end = caps + preparsed->value_caps_count[HidP_Feature];
for (; caps != caps_end; ++caps)
{
len = caps->start_bit + caps->bit_size * caps->report_count;
len = caps->start_byte * 8 + caps->start_bit + caps->bit_size * caps->report_count;
if (!input_len[caps->report_id] && !output_len[caps->report_id] && !feature_len[caps->report_id]) report_count++;
feature_len[caps->report_id] = max(feature_len[caps->report_id], len);
}

View file

@ -52,7 +52,8 @@ struct hid_value_caps
USHORT bit_field;
USHORT bit_size;
USHORT report_count;
ULONG start_bit;
UCHAR start_bit;
USHORT start_byte;
ULONG start_index;
LONG logical_min;
LONG logical_max;