[PATCH 4/7] hidparse.sys: Make internal HID structures compatible with native.

Rémi Bernon rbernon at codeweavers.com
Wed Sep 22 03:08:32 CDT 2021


Or compatible enough ast least.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/dinput8/tests/hid.c | 14 ++++++++--
 dlls/hid/hidp.c          |  6 ++--
 dlls/hidparse.sys/main.c |  8 ++++--
 dlls/user32/rawinput.c   |  6 +++-
 include/wine/hid.h       | 59 ++++++++++++++++++++++------------------
 5 files changed, 57 insertions(+), 36 deletions(-)

diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c
index b4aad6b7d5a..2694391bc4e 100644
--- a/dlls/dinput8/tests/hid.c
+++ b/dlls/dinput8/tests/hid.c
@@ -3116,7 +3116,6 @@ static void test_hidp_kdr(void)
     ok( ret, "HidD_GetPreparsedData failed with error %u\n", GetLastError() );
 
     kdr = (struct hidp_kdr *)preparsed_data;
-    todo_wine
     ok( !strncmp( kdr->magic, expect_kdr.magic, 8 ), "got %s expected %s\n",
         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_report_byte_length );
         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_end );
         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", 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 );
             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", report_count );
             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], "%#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", link_collection );
             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", designator_min );
             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 );
+            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 );
+            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", unknown );
+            todo_wine_if( !(kdr->caps[i].bit_field & 2) )
             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 );
+            todo_wine_if( kdr->caps[i].flags & HIDP_KDR_CAPS_IS_BUTTON )
             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], "%#x", units );
             check_member( kdr->caps[i], expect_caps[i], "%#x", units_exp );
diff --git a/dlls/hid/hidp.c b/dlls/hid/hidp.c
index 4abc867fe0f..90dc3211e45 100644
--- a/dlls/hid/hidp.c
+++ b/dlls/hid/hidp.c
@@ -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,
                                       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)
     {
@@ -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 );
 
-    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->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 );
 
-    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;
     if (capacity < count) return HIDP_STATUS_BUFFER_TOO_SMALL;
diff --git a/dlls/hidparse.sys/main.c b/dlls/hidparse.sys/main.c
index 02a1c2d58d0..19c756d9002 100644
--- a/dlls/hidparse.sys/main.c
+++ b/dlls/hidparse.sys/main.c
@@ -415,8 +415,7 @@ static struct hid_preparsed_data *build_preparsed_data( struct hid_parser_state
     if (!(data = ExAllocatePool( pool_type, size ))) return NULL;
     memset( data, 0, size );
 
-    data->magic = HID_MAGIC;
-    data->size = size;
+    memcpy( data->magic, "HidP KDR", 8 );
     data->usage = state->usage;
     data->usage_page = state->usage_page;
     data->input_caps_start = 0;
@@ -635,6 +634,9 @@ NTSTATUS WINAPI HidP_GetCollectionDescription( PHIDP_REPORT_DESCRIPTOR report_de
         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->CollectionDesc[0].UsagePage = preparsed->usage_page;
     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].OutputLength = preparsed->output_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;
 
     caps = HID_INPUT_VALUE_CAPS( preparsed );
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index 39f8c622fee..3a316024656 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -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)
 {
+    struct hid_preparsed_data *preparsed;
     RID_DEVICE_INFO info;
     struct device *device;
     DWORD len, data_len;
@@ -751,7 +752,10 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT
         break;
 
     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)
             memcpy(data, device->data, len);
         *data_size = len;
diff --git a/include/wine/hid.h b/include/wine/hid.h
index a74b7eed02b..1d489a24c88 100644
--- a/include/wine/hid.h
+++ b/include/wine/hid.h
@@ -44,31 +44,36 @@ struct hid_collection_node
 
 struct hid_value_caps
 {
-    USAGE   usage_page;
-    USAGE   usage_min;
-    USAGE   usage_max;
-    USHORT  data_index_min;
-    USHORT  data_index_max;
-    USHORT  string_min;
-    USHORT  string_max;
-    USHORT  designator_min;
-    USHORT  designator_max;
-    ULONG   flags;
-    UCHAR   report_id;
-    USHORT  link_collection;
-    USAGE   link_usage_page;
-    USAGE   link_usage;
-    USHORT  bit_field;
-    USHORT  bit_size;
-    USHORT  report_count;
-    UCHAR   start_bit;
-    USHORT  start_byte;
-    LONG    logical_min;
-    LONG    logical_max;
-    LONG    physical_min;
-    LONG    physical_max;
-    ULONG   units;
-    ULONG   units_exp;
+    USHORT usage_page;
+    UCHAR report_id;
+    UCHAR start_bit;
+    USHORT bit_size;
+    USHORT report_count;
+    USHORT start_byte;
+    USHORT total_bits;
+    ULONG bit_field;
+    USHORT end_byte;
+    USHORT link_collection;
+    USAGE link_usage_page;
+    USAGE link_usage;
+    ULONG flags;
+    ULONG padding[8];
+    USAGE usage_min;
+    USAGE usage_max;
+    USHORT string_min;
+    USHORT string_max;
+    USHORT designator_min;
+    USHORT designator_max;
+    USHORT data_index_min;
+    USHORT data_index_max;
+    USHORT null_value;
+    USHORT unknown;
+    LONG logical_min;
+    LONG logical_max;
+    LONG physical_min;
+    LONG physical_max;
+    LONG units;
+    LONG units_exp;
 };
 
 /* named array continues on next caps */
@@ -85,10 +90,10 @@ struct hid_value_caps
 
 struct hid_preparsed_data
 {
-    DWORD magic;
-    DWORD size;
+    char magic[8];
     USAGE usage;
     USAGE usage_page;
+    USHORT unknown[2];
     USHORT input_caps_start;
     USHORT input_caps_count;
     USHORT input_caps_end;
-- 
2.33.0




More information about the wine-devel mailing list