From: Rémi Bernon rbernon@codeweavers.com
--- dlls/hid/hidp.c | 80 +++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 42 deletions(-)
diff --git a/dlls/hid/hidp.c b/dlls/hid/hidp.c index a1c5805c19f..bf5a6259484 100644 --- a/dlls/hid/hidp.c +++ b/dlls/hid/hidp.c @@ -236,18 +236,33 @@ static LONG sign_extend( ULONG value, const struct hid_value_caps *caps ) return value - ((value & sign) << 1); }
-static NTSTATUS get_scaled_usage_value( const struct hid_value_caps *caps, void *user ) +static NTSTATUS get_usage_value( const struct hid_value_caps *caps, void *user ) { 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; + ULONG bit_count = caps->bit_size * caps->report_count; 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; + if ((bit_count + 7) / 8 > params->value_len) return HIDP_STATUS_BUFFER_TOO_SMALL; + memset( params->value_buf, 0, params->value_len );
report_buf = (unsigned char *)params->report_buf + caps->start_byte; - copy_bits( (unsigned char *)&unsigned_value, report_buf, bit_count, -caps->start_bit ); + copy_bits( params->value_buf, report_buf, bit_count, -caps->start_bit ); + + return HIDP_STATUS_NULL; +} + +static NTSTATUS get_scaled_usage_value( const struct hid_value_caps *caps, void *user ) +{ + struct usage_value_params *params = user; + LONG signed_value, *value = params->value_buf; + ULONG unsigned_value = 0; + NTSTATUS status; + + params->value_buf = &unsigned_value; + params->value_len = sizeof(unsigned_value); + if ((status = get_usage_value( caps, params )) != HIDP_STATUS_NULL) return status; + + if (sizeof(LONG) > params->value_len) return HIDP_STATUS_BUFFER_TOO_SMALL; signed_value = sign_extend( unsigned_value, caps );
if (caps->logical_min > caps->logical_max || caps->physical_min > caps->physical_max) @@ -280,21 +295,6 @@ NTSTATUS WINAPI HidP_GetScaledUsageValue( HIDP_REPORT_TYPE report_type, USAGE us return enum_value_caps( preparsed, report_type, report_len, &filter, get_scaled_usage_value, ¶ms, &count ); }
-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 ); - - 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; -} - NTSTATUS WINAPI HidP_GetUsageValue( HIDP_REPORT_TYPE report_type, USAGE usage_page, USHORT collection, USAGE usage, ULONG *value, PHIDP_PREPARSED_DATA preparsed_data, char *report_buf, ULONG report_len ) { @@ -446,17 +446,28 @@ ULONG WINAPI HidP_MaxUsageListLength( HIDP_REPORT_TYPE report_type, USAGE usage_ return count; }
-static NTSTATUS set_scaled_usage_value( const struct hid_value_caps *caps, void *user ) +static NTSTATUS set_usage_value( const struct hid_value_caps *caps, void *user ) { - ULONG bit_count = caps->bit_size * caps->report_count; 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; + + 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; +} + +static NTSTATUS set_scaled_usage_value( const struct hid_value_caps *caps, void *user ) +{ + struct usage_value_params *params = user; LONG value, log_range, phy_range;
if (caps->logical_min > caps->logical_max) return HIDP_STATUS_BAD_LOG_PHY_VALUES; if (caps->physical_min > caps->physical_max) return HIDP_STATUS_BAD_LOG_PHY_VALUES;
- if ((bit_count + 7) / 8 > sizeof(value)) return HIDP_STATUS_BUFFER_TOO_SMALL; if (sizeof(LONG) > params->value_len) return HIDP_STATUS_BUFFER_TOO_SMALL; value = *(LONG *)params->value_buf;
@@ -471,10 +482,9 @@ static NTSTATUS set_scaled_usage_value( const struct hid_value_caps *caps, void value = caps->logical_min + value; }
- 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; + params->value_buf = &value; + params->value_len = sizeof(value); + return set_usage_value( caps, params ); }
NTSTATUS WINAPI HidP_SetScaledUsageValue( HIDP_REPORT_TYPE report_type, USAGE usage_page, USHORT collection, @@ -495,20 +505,6 @@ NTSTATUS WINAPI HidP_SetScaledUsageValue( HIDP_REPORT_TYPE report_type, USAGE us return enum_value_caps( preparsed, report_type, report_len, &filter, set_scaled_usage_value, ¶ms, &count ); }
-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; - - 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; -} - NTSTATUS WINAPI HidP_SetUsageValue( HIDP_REPORT_TYPE report_type, USAGE usage_page, USHORT collection, USAGE usage, ULONG value, PHIDP_PREPARSED_DATA preparsed_data, char *report_buf, ULONG report_len ) {