Commit a08eb896 authored by Matthew Tran's avatar Matthew Tran Committed by Alexandre Julliard

hid: Fix HidP_(Get|Set)(Scaled)UsageValue with usage ranges and arrays.

parent 7f6e8387
......@@ -1806,11 +1806,8 @@ static void test_hidp( HANDLE file, HANDLE async_file, int report_id, BOOL polle
report[17] = 0xa5;
status = HidP_SetUsageValue( HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_HATSWITCH,
8, preparsed_data, report, caps.InputReportByteLength );
todo_wine
ok( status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#lx\n", status );
todo_wine
ok( report[16] == (char)8, "got value %#x\n", report[16] );
todo_wine
ok( report[17] == (char)0, "got value %#x\n", report[17] );
status = HidP_GetUsageValueArray( HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, buffer,
......@@ -1832,9 +1829,7 @@ static void test_hidp( HANDLE file, HANDLE async_file, int report_id, BOOL polle
report[17] = 0xff;
status = HidP_GetUsageValue( HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_HATSWITCH,
&value, preparsed_data, report, caps.InputReportByteLength );
todo_wine
ok( status == HIDP_STATUS_SUCCESS, "HidP_GetUsageValue returned %#lx\n", status );
todo_wine
ok( value == 0xffff, "got value %ld\n", value );
value = -128;
......@@ -2317,14 +2312,11 @@ static void test_hidp( HANDLE file, HANDLE async_file, int report_id, BOOL polle
{
status = HidP_SetUsageValue( HidP_Feature, HID_USAGE_PAGE_ORDINAL, generic_output_list, i + 1,
i, preparsed_data, report, caps.FeatureReportByteLength );
todo_wine
ok( status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#lx\n", status );
status = HidP_GetUsageValue( HidP_Feature, HID_USAGE_PAGE_ORDINAL, generic_output_list, i + 1,
&value, preparsed_data, report, caps.FeatureReportByteLength );
todo_wine
ok( status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#lx\n", status );
todo_wine
ok( value == i, "got value %#lx, expected %#x\n", value, i );
status = HidP_SetUsageValueArray( HidP_Feature, HID_USAGE_PAGE_ORDINAL, generic_output_list, i + 1, (void *)&value,
......@@ -2340,19 +2332,15 @@ static void test_hidp( HANDLE file, HANDLE async_file, int report_id, BOOL polle
{
status = HidP_SetScaledUsageValue( HidP_Feature, HID_USAGE_PAGE_ORDINAL, generic_output_list, i + 1,
i * 16, preparsed_data, report, caps.FeatureReportByteLength );
todo_wine
ok( status == HIDP_STATUS_SUCCESS, "HidP_SetScaledUsageValue returned %#lx\n", status );
status = HidP_GetScaledUsageValue( HidP_Feature, HID_USAGE_PAGE_ORDINAL, generic_output_list, i + 1,
(LONG *)&value, preparsed_data, report, caps.FeatureReportByteLength );
todo_wine
ok( status == HIDP_STATUS_SUCCESS, "HidP_GetScaledUsageValue returned %#lx\n", status );
todo_wine
ok( value == i * 16, "got value %#lx, expected %#x\n", value, i * 16 );
buffer[i + 21] = i;
}
todo_wine
ok( !memcmp( buffer, report, sizeof(buffer) ), "unexpected report data\n" );
test_hidp_get_input( file, report_id, caps.InputReportByteLength, preparsed_data );
......
......@@ -224,6 +224,8 @@ NTSTATUS WINAPI HidP_GetCaps( PHIDP_PREPARSED_DATA preparsed_data, HIDP_CAPS *ca
struct usage_value_params
{
BOOL array;
USAGE usage;
void *value_buf;
USHORT value_len;
void *report_buf;
......@@ -238,15 +240,18 @@ static LONG sign_extend( ULONG value, const struct hid_value_caps *caps )
static NTSTATUS get_usage_value( const struct hid_value_caps *caps, void *user )
{
unsigned char *report_buf, start_bit = caps->start_bit;
ULONG bit_count = caps->bit_size, bit_offset = 0;
struct usage_value_params *params = user;
ULONG bit_count = caps->bit_size * caps->report_count;
unsigned char *report_buf;
if (params->array) bit_count *= caps->report_count;
else bit_offset = (params->usage - caps->usage_min) * caps->bit_size;
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 );
report_buf = (unsigned char *)params->report_buf + caps->start_byte + bit_offset / 8;
copy_bits( params->value_buf, report_buf, bit_count, -(start_bit + bit_offset % 8) );
return HIDP_STATUS_NULL;
}
......@@ -280,7 +285,7 @@ NTSTATUS WINAPI HidP_GetScaledUsageValue( HIDP_REPORT_TYPE report_type, USAGE us
USAGE usage, LONG *value, PHIDP_PREPARSED_DATA preparsed_data,
char *report_buf, ULONG report_len )
{
struct usage_value_params params = {.value_buf = value, .value_len = sizeof(*value), .report_buf = report_buf};
struct usage_value_params params = {.usage = usage, .value_buf = value, .value_len = sizeof(*value), .report_buf = report_buf};
struct hid_preparsed_data *preparsed = (struct hid_preparsed_data *)preparsed_data;
struct caps_filter filter = {.values = TRUE, .usage_page = usage_page, .collection = collection, .usage = usage };
USHORT count = 1;
......@@ -298,7 +303,7 @@ NTSTATUS WINAPI HidP_GetScaledUsageValue( HIDP_REPORT_TYPE report_type, USAGE us
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 )
{
struct usage_value_params params = {.value_buf = value, .value_len = sizeof(*value), .report_buf = report_buf};
struct usage_value_params params = {.usage = usage, .value_buf = value, .value_len = sizeof(*value), .report_buf = report_buf};
struct hid_preparsed_data *preparsed = (struct hid_preparsed_data *)preparsed_data;
struct caps_filter filter = {.values = TRUE, .usage_page = usage_page, .collection = collection, .usage = usage};
USHORT count = 1;
......@@ -316,7 +321,7 @@ NTSTATUS WINAPI HidP_GetUsageValueArray( HIDP_REPORT_TYPE report_type, USAGE usa
USAGE usage, char *value_buf, USHORT value_len,
PHIDP_PREPARSED_DATA preparsed_data, char *report_buf, ULONG report_len )
{
struct usage_value_params params = {.value_buf = value_buf, .value_len = value_len, .report_buf = report_buf};
struct usage_value_params params = {.array = TRUE, .usage = usage, .value_buf = value_buf, .value_len = value_len, .report_buf = report_buf};
struct hid_preparsed_data *preparsed = (struct hid_preparsed_data *)preparsed_data;
struct caps_filter filter = {.values = TRUE, .array = TRUE, .usage_page = usage_page, .collection = collection, .usage = usage};
USHORT count = 1;
......@@ -448,14 +453,17 @@ ULONG WINAPI HidP_MaxUsageListLength( HIDP_REPORT_TYPE report_type, USAGE usage_
static NTSTATUS set_usage_value( const struct hid_value_caps *caps, void *user )
{
unsigned char *report_buf, start_bit = caps->start_bit;
ULONG bit_count = caps->bit_size, bit_offset = 0;
struct usage_value_params *params = user;
ULONG bit_count = caps->bit_size * caps->report_count;
unsigned char *report_buf;
if (params->array) bit_count *= caps->report_count;
else bit_offset = (params->usage - caps->usage_min) * caps->bit_size;
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 );
report_buf = (unsigned char *)params->report_buf + caps->start_byte + bit_offset / 8;
copy_bits( report_buf, params->value_buf, bit_count, start_bit + bit_offset % 8 );
return HIDP_STATUS_NULL;
}
......@@ -491,7 +499,7 @@ NTSTATUS WINAPI HidP_SetScaledUsageValue( HIDP_REPORT_TYPE report_type, USAGE us
USAGE usage, LONG value, PHIDP_PREPARSED_DATA preparsed_data,
char *report_buf, ULONG report_len )
{
struct usage_value_params params = {.value_buf = &value, .value_len = sizeof(value), .report_buf = report_buf};
struct usage_value_params params = {.usage = usage, .value_buf = &value, .value_len = sizeof(value), .report_buf = report_buf};
struct hid_preparsed_data *preparsed = (struct hid_preparsed_data *)preparsed_data;
struct caps_filter filter = {.values = TRUE, .usage_page = usage_page, .collection = collection, .usage = usage };
USHORT count = 1;
......@@ -508,7 +516,7 @@ NTSTATUS WINAPI HidP_SetScaledUsageValue( HIDP_REPORT_TYPE report_type, USAGE us
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 )
{
struct usage_value_params params = {.value_buf = &value, .value_len = sizeof(value), .report_buf = report_buf};
struct usage_value_params params = {.usage = usage, .value_buf = &value, .value_len = sizeof(value), .report_buf = report_buf};
struct hid_preparsed_data *preparsed = (struct hid_preparsed_data *)preparsed_data;
struct caps_filter filter = {.values = TRUE, .usage_page = usage_page, .collection = collection, .usage = usage};
USHORT count = 1;
......@@ -526,7 +534,7 @@ NTSTATUS WINAPI HidP_SetUsageValueArray( HIDP_REPORT_TYPE report_type, USAGE usa
USAGE usage, char *value_buf, USHORT value_len,
PHIDP_PREPARSED_DATA preparsed_data, char *report_buf, ULONG report_len )
{
struct usage_value_params params = {.value_buf = value_buf, .value_len = value_len, .report_buf = report_buf};
struct usage_value_params params = {.array = TRUE, .usage = usage, .value_buf = value_buf, .value_len = value_len, .report_buf = report_buf};
struct hid_preparsed_data *preparsed = (struct hid_preparsed_data *)preparsed_data;
struct caps_filter filter = {.values = TRUE, .array = TRUE, .usage_page = usage_page, .collection = collection, .usage = usage};
USHORT count = 1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment