hidparse.sys: Make internal HID structures compatible with native.

Or compatible enough ast least.

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-22 10:08:32 +02:00 committed by Alexandre Julliard
parent 75e74b3a73
commit e1e82148f8
5 changed files with 57 additions and 36 deletions

View file

@ -3116,7 +3116,6 @@ static void test_hidp_kdr(void)
ok( ret, "HidD_GetPreparsedData failed with error %u\n", GetLastError() ); ok( ret, "HidD_GetPreparsedData failed with error %u\n", GetLastError() );
kdr = (struct hidp_kdr *)preparsed_data; kdr = (struct hidp_kdr *)preparsed_data;
todo_wine
ok( !strncmp( kdr->magic, expect_kdr.magic, 8 ), "got %s expected %s\n", ok( !strncmp( kdr->magic, expect_kdr.magic, 8 ), "got %s expected %s\n",
debugstr_an(kdr->magic, 8), debugstr_an(expect_kdr.magic, 8) ); debugstr_an(kdr->magic, 8), debugstr_an(expect_kdr.magic, 8) );
@ -3135,13 +3134,15 @@ static void test_hidp_kdr(void)
check_member( *kdr, expect_kdr, "%d", output_caps_end ); check_member( *kdr, expect_kdr, "%d", output_caps_end );
check_member( *kdr, expect_kdr, "%d", output_report_byte_length ); check_member( *kdr, expect_kdr, "%d", output_report_byte_length );
check_member( *kdr, expect_kdr, "%d", feature_caps_start ); check_member( *kdr, expect_kdr, "%d", feature_caps_start );
todo_wine
check_member( *kdr, expect_kdr, "%d", feature_caps_count ); check_member( *kdr, expect_kdr, "%d", feature_caps_count );
check_member( *kdr, expect_kdr, "%d", feature_caps_end ); check_member( *kdr, expect_kdr, "%d", feature_caps_end );
check_member( *kdr, expect_kdr, "%d", feature_report_byte_length ); check_member( *kdr, expect_kdr, "%d", feature_report_byte_length );
todo_wine
check_member( *kdr, expect_kdr, "%d", caps_size ); check_member( *kdr, expect_kdr, "%d", caps_size );
check_member( *kdr, expect_kdr, "%d", number_link_collection_nodes ); check_member( *kdr, expect_kdr, "%d", number_link_collection_nodes );
for (i = 0; i < ARRAY_SIZE(expect_caps); ++i) for (i = 0; i < min( ARRAY_SIZE(expect_caps), kdr->caps_size / sizeof(struct hidp_kdr_caps) ); ++i)
{ {
winetest_push_context( "caps[%d]", i ); winetest_push_context( "caps[%d]", i );
check_member( kdr->caps[i], expect_caps[i], "%04x", usage_page ); check_member( kdr->caps[i], expect_caps[i], "%04x", usage_page );
@ -3150,8 +3151,10 @@ static void test_hidp_kdr(void)
check_member( kdr->caps[i], expect_caps[i], "%d", bit_size ); check_member( kdr->caps[i], expect_caps[i], "%d", bit_size );
check_member( kdr->caps[i], expect_caps[i], "%d", report_count ); check_member( kdr->caps[i], expect_caps[i], "%d", report_count );
check_member( kdr->caps[i], expect_caps[i], "%d", start_byte ); check_member( kdr->caps[i], expect_caps[i], "%d", start_byte );
todo_wine
check_member( kdr->caps[i], expect_caps[i], "%d", total_bits ); check_member( kdr->caps[i], expect_caps[i], "%d", total_bits );
check_member( kdr->caps[i], expect_caps[i], "%#x", bit_field ); check_member( kdr->caps[i], expect_caps[i], "%#x", bit_field );
todo_wine_if( expect_caps[i].end_byte )
check_member( kdr->caps[i], expect_caps[i], "%d", end_byte ); check_member( kdr->caps[i], expect_caps[i], "%d", end_byte );
check_member( kdr->caps[i], expect_caps[i], "%d", link_collection ); check_member( kdr->caps[i], expect_caps[i], "%d", link_collection );
check_member( kdr->caps[i], expect_caps[i], "%04x", link_usage_page ); check_member( kdr->caps[i], expect_caps[i], "%04x", link_usage_page );
@ -3171,13 +3174,20 @@ static void test_hidp_kdr(void)
check_member( kdr->caps[i], expect_caps[i], "%d", string_max ); check_member( kdr->caps[i], expect_caps[i], "%d", string_max );
check_member( kdr->caps[i], expect_caps[i], "%d", designator_min ); check_member( kdr->caps[i], expect_caps[i], "%d", designator_min );
check_member( kdr->caps[i], expect_caps[i], "%d", designator_max ); check_member( kdr->caps[i], expect_caps[i], "%d", designator_max );
todo_wine_if( !(kdr->caps[i].bit_field & 2) && !(kdr->caps[i].flags & HIDP_KDR_CAPS_IS_RANGE) )
check_member( kdr->caps[i], expect_caps[i], "%#x", data_index_min ); check_member( kdr->caps[i], expect_caps[i], "%#x", data_index_min );
todo_wine_if( !(kdr->caps[i].bit_field & 2) && !(kdr->caps[i].flags & HIDP_KDR_CAPS_IS_RANGE) )
check_member( kdr->caps[i], expect_caps[i], "%#x", data_index_max ); check_member( kdr->caps[i], expect_caps[i], "%#x", data_index_max );
todo_wine_if( expect_caps[i].null_value )
check_member( kdr->caps[i], expect_caps[i], "%d", null_value ); check_member( kdr->caps[i], expect_caps[i], "%d", null_value );
check_member( kdr->caps[i], expect_caps[i], "%d", unknown ); check_member( kdr->caps[i], expect_caps[i], "%d", unknown );
todo_wine_if( !(kdr->caps[i].bit_field & 2) )
check_member( kdr->caps[i], expect_caps[i], "%d", logical_min ); check_member( kdr->caps[i], expect_caps[i], "%d", logical_min );
todo_wine_if( kdr->caps[i].flags & HIDP_KDR_CAPS_IS_BUTTON )
check_member( kdr->caps[i], expect_caps[i], "%d", logical_max ); check_member( kdr->caps[i], expect_caps[i], "%d", logical_max );
todo_wine_if( kdr->caps[i].flags & HIDP_KDR_CAPS_IS_BUTTON )
check_member( kdr->caps[i], expect_caps[i], "%d", physical_min ); check_member( kdr->caps[i], expect_caps[i], "%d", physical_min );
todo_wine_if( kdr->caps[i].flags & HIDP_KDR_CAPS_IS_BUTTON )
check_member( kdr->caps[i], expect_caps[i], "%d", physical_max ); check_member( kdr->caps[i], expect_caps[i], "%d", physical_max );
check_member( kdr->caps[i], expect_caps[i], "%#x", units ); check_member( kdr->caps[i], expect_caps[i], "%#x", units );
check_member( kdr->caps[i], expect_caps[i], "%#x", units_exp ); check_member( kdr->caps[i], expect_caps[i], "%#x", units_exp );

View file

@ -39,7 +39,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(hidp);
static NTSTATUS get_value_caps_range( struct hid_preparsed_data *preparsed, HIDP_REPORT_TYPE report_type, ULONG report_len, static NTSTATUS get_value_caps_range( struct hid_preparsed_data *preparsed, HIDP_REPORT_TYPE report_type, ULONG report_len,
const struct hid_value_caps **caps, const struct hid_value_caps **caps_end ) const struct hid_value_caps **caps, const struct hid_value_caps **caps_end )
{ {
if (!preparsed || preparsed->magic != HID_MAGIC) return HIDP_STATUS_INVALID_PREPARSED_DATA; if (!preparsed || memcmp( preparsed->magic, "HidP KDR", 8 )) return HIDP_STATUS_INVALID_PREPARSED_DATA;
switch (report_type) switch (report_type)
{ {
@ -171,7 +171,7 @@ NTSTATUS WINAPI HidP_GetCaps( PHIDP_PREPARSED_DATA preparsed_data, HIDP_CAPS *ca
TRACE( "preparsed_data %p, caps %p.\n", preparsed_data, caps ); TRACE( "preparsed_data %p, caps %p.\n", preparsed_data, caps );
if (!preparsed || preparsed->magic != HID_MAGIC) return HIDP_STATUS_INVALID_PREPARSED_DATA; if (!preparsed || memcmp( preparsed->magic, "HidP KDR", 8 )) return HIDP_STATUS_INVALID_PREPARSED_DATA;
caps->Usage = preparsed->usage; caps->Usage = preparsed->usage;
caps->UsagePage = preparsed->usage_page; caps->UsagePage = preparsed->usage_page;
@ -1002,7 +1002,7 @@ NTSTATUS WINAPI HidP_GetLinkCollectionNodes( HIDP_LINK_COLLECTION_NODE *nodes, U
TRACE( "nodes %p, nodes_len %p, preparsed_data %p.\n", nodes, nodes_len, preparsed_data ); TRACE( "nodes %p, nodes_len %p, preparsed_data %p.\n", nodes, nodes_len, preparsed_data );
if (!preparsed || preparsed->magic != HID_MAGIC) return HIDP_STATUS_INVALID_PREPARSED_DATA; if (!preparsed || memcmp( preparsed->magic, "HidP KDR", 8 )) return HIDP_STATUS_INVALID_PREPARSED_DATA;
count = *nodes_len = preparsed->number_link_collection_nodes; count = *nodes_len = preparsed->number_link_collection_nodes;
if (capacity < count) return HIDP_STATUS_BUFFER_TOO_SMALL; if (capacity < count) return HIDP_STATUS_BUFFER_TOO_SMALL;

View file

@ -415,8 +415,7 @@ static struct hid_preparsed_data *build_preparsed_data( struct hid_parser_state
if (!(data = ExAllocatePool( pool_type, size ))) return NULL; if (!(data = ExAllocatePool( pool_type, size ))) return NULL;
memset( data, 0, size ); memset( data, 0, size );
data->magic = HID_MAGIC; memcpy( data->magic, "HidP KDR", 8 );
data->size = size;
data->usage = state->usage; data->usage = state->usage;
data->usage_page = state->usage_page; data->usage_page = state->usage_page;
data->input_caps_start = 0; data->input_caps_start = 0;
@ -635,6 +634,9 @@ NTSTATUS WINAPI HidP_GetCollectionDescription( PHIDP_REPORT_DESCRIPTOR report_de
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
} }
len = preparsed->caps_size + FIELD_OFFSET(struct hid_preparsed_data, value_caps[0]) +
preparsed->number_link_collection_nodes * sizeof(struct hid_collection_node);
device_desc->CollectionDescLength = 1; device_desc->CollectionDescLength = 1;
device_desc->CollectionDesc[0].UsagePage = preparsed->usage_page; device_desc->CollectionDesc[0].UsagePage = preparsed->usage_page;
device_desc->CollectionDesc[0].Usage = preparsed->usage; device_desc->CollectionDesc[0].Usage = preparsed->usage;
@ -642,7 +644,7 @@ NTSTATUS WINAPI HidP_GetCollectionDescription( PHIDP_REPORT_DESCRIPTOR report_de
device_desc->CollectionDesc[0].InputLength = preparsed->input_report_byte_length; device_desc->CollectionDesc[0].InputLength = preparsed->input_report_byte_length;
device_desc->CollectionDesc[0].OutputLength = preparsed->output_report_byte_length; device_desc->CollectionDesc[0].OutputLength = preparsed->output_report_byte_length;
device_desc->CollectionDesc[0].FeatureLength = preparsed->feature_report_byte_length; device_desc->CollectionDesc[0].FeatureLength = preparsed->feature_report_byte_length;
device_desc->CollectionDesc[0].PreparsedDataLength = preparsed->size; device_desc->CollectionDesc[0].PreparsedDataLength = len;
device_desc->CollectionDesc[0].PreparsedData = (PHIDP_PREPARSED_DATA)preparsed; device_desc->CollectionDesc[0].PreparsedData = (PHIDP_PREPARSED_DATA)preparsed;
caps = HID_INPUT_VALUE_CAPS( preparsed ); caps = HID_INPUT_VALUE_CAPS( preparsed );

View file

@ -717,6 +717,7 @@ UINT WINAPI GetRawInputDeviceInfoA(HANDLE device, UINT command, void *data, UINT
*/ */
UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT *data_size) UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT *data_size)
{ {
struct hid_preparsed_data *preparsed;
RID_DEVICE_INFO info; RID_DEVICE_INFO info;
struct device *device; struct device *device;
DWORD len, data_len; DWORD len, data_len;
@ -751,7 +752,10 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT
break; break;
case RIDI_PREPARSEDDATA: case RIDI_PREPARSEDDATA:
len = device->data ? ((struct hid_preparsed_data *)device->data)->size : 0; if (!(preparsed = (struct hid_preparsed_data *)device->data)) len = 0;
else len = preparsed->caps_size + FIELD_OFFSET(struct hid_preparsed_data, value_caps[0]) +
preparsed->number_link_collection_nodes * sizeof(struct hid_collection_node);
if (device->data && len <= data_len && data) if (device->data && len <= data_len && data)
memcpy(data, device->data, len); memcpy(data, device->data, len);
*data_size = len; *data_size = len;

View file

@ -44,31 +44,36 @@ struct hid_collection_node
struct hid_value_caps struct hid_value_caps
{ {
USAGE usage_page; USHORT usage_page;
USAGE usage_min; UCHAR report_id;
USAGE usage_max; UCHAR start_bit;
USHORT data_index_min; USHORT bit_size;
USHORT data_index_max; USHORT report_count;
USHORT string_min; USHORT start_byte;
USHORT string_max; USHORT total_bits;
USHORT designator_min; ULONG bit_field;
USHORT designator_max; USHORT end_byte;
ULONG flags; USHORT link_collection;
UCHAR report_id; USAGE link_usage_page;
USHORT link_collection; USAGE link_usage;
USAGE link_usage_page; ULONG flags;
USAGE link_usage; ULONG padding[8];
USHORT bit_field; USAGE usage_min;
USHORT bit_size; USAGE usage_max;
USHORT report_count; USHORT string_min;
UCHAR start_bit; USHORT string_max;
USHORT start_byte; USHORT designator_min;
LONG logical_min; USHORT designator_max;
LONG logical_max; USHORT data_index_min;
LONG physical_min; USHORT data_index_max;
LONG physical_max; USHORT null_value;
ULONG units; USHORT unknown;
ULONG units_exp; LONG logical_min;
LONG logical_max;
LONG physical_min;
LONG physical_max;
LONG units;
LONG units_exp;
}; };
/* named array continues on next caps */ /* named array continues on next caps */
@ -85,10 +90,10 @@ struct hid_value_caps
struct hid_preparsed_data struct hid_preparsed_data
{ {
DWORD magic; char magic[8];
DWORD size;
USAGE usage; USAGE usage;
USAGE usage_page; USAGE usage_page;
USHORT unknown[2];
USHORT input_caps_start; USHORT input_caps_start;
USHORT input_caps_count; USHORT input_caps_count;
USHORT input_caps_end; USHORT input_caps_end;