[PATCH 1/5] hidparse.sys: Split struct hid_value_caps start_bit into start_byte / start_bit.
Rémi Bernon
rbernon at codeweavers.com
Fri Sep 17 02:18:54 CDT 2021
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
This is the first part of a series to make Wine internal HID structures
compatible (enough) with native.
dlls/hid/hidp.c | 63 +++++++++++++++++++++++++++++-----------
dlls/hidparse.sys/main.c | 16 +++++-----
include/wine/hid.h | 3 +-
3 files changed, 57 insertions(+), 25 deletions(-)
diff --git a/dlls/hid/hidp.c b/dlls/hid/hidp.c
index cd9de2148c2..a94e7b637ae 100644
--- a/dlls/hid/hidp.c
+++ b/dlls/hid/hidp.c
@@ -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++;
}
diff --git a/dlls/hidparse.sys/main.c b/dlls/hidparse.sys/main.c
index 3a57c338165..b7326f9fe4a 100644
--- a/dlls/hidparse.sys/main.c
+++ b/dlls/hidparse.sys/main.c
@@ -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);
}
diff --git a/include/wine/hid.h b/include/wine/hid.h
index e76676ac8c2..8e33745ddc4 100644
--- a/include/wine/hid.h
+++ b/include/wine/hid.h
@@ -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;
--
2.33.0
More information about the wine-devel
mailing list