[PATCH 5/5] hidclass.sys: Merge parse_descriptor and ParseDescriptor.

Rémi Bernon rbernon at codeweavers.com
Mon Aug 9 03:32:43 CDT 2021


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/hidclass.sys/descriptor.c | 91 +++++++++++++++-------------------
 dlls/hidclass.sys/hid.h        |  2 +-
 dlls/hidclass.sys/pnp.c        |  2 +-
 3 files changed, 43 insertions(+), 52 deletions(-)

diff --git a/dlls/hidclass.sys/descriptor.c b/dlls/hidclass.sys/descriptor.c
index 7375f3d3214..f8a26d87c9f 100644
--- a/dlls/hidclass.sys/descriptor.c
+++ b/dlls/hidclass.sys/descriptor.c
@@ -449,55 +449,68 @@ static WINE_HIDP_PREPARSED_DATA *build_preparsed_data( struct hid_parser_state *
     return data;
 }
 
-static int parse_descriptor( BYTE *descriptor, unsigned int index, unsigned int length,
-                             struct hid_parser_state *state )
+WINE_HIDP_PREPARSED_DATA *parse_descriptor( BYTE *descriptor, unsigned int length )
 {
-    int i;
-    UINT32 value;
+    WINE_HIDP_PREPARSED_DATA *data = NULL;
+    struct hid_parser_state *state;
+    UINT32 size, value;
     INT32 signed_value;
+    BYTE *ptr, *end;
+    int i;
 
-    for (i = index; i < length;)
+    if (TRACE_ON( hid ))
     {
-        BYTE item = descriptor[i++];
-        int size = item & 0x03;
+        TRACE( "descriptor %p, length %u:\n", descriptor, length );
+        for (i = 0; i < length;)
+        {
+            TRACE( "%08x ", i );
+            do { TRACE( " %02x", descriptor[i] ); } while (++i % 16 && i < length);
+            TRACE( "\n" );
+        }
+    }
+
+    if (!(state = calloc( 1, sizeof(*state) ))) return NULL;
+    init_parser_state( state );
 
+    for (ptr = descriptor, end = descriptor + length; ptr != end; ptr += size + 1)
+    {
+        size = (*ptr & 0x03);
         if (size == 3) size = 4;
-        if (length - i < size)
+        if (ptr + size > end)
         {
             ERR("Need %d bytes to read item value\n", size);
-            return -1;
+            goto done;
         }
 
         if (size == 0) signed_value = value = 0;
-        else if (size == 1) signed_value = (INT8)(value = *(UINT8 *)(descriptor + i));
-        else if (size == 2) signed_value = (INT16)(value = *(UINT16 *)(descriptor + i));
-        else if (size == 4) signed_value = (INT32)(value = *(UINT32 *)(descriptor + i));
+        else if (size == 1) signed_value = (INT8)(value = *(UINT8 *)(ptr + 1));
+        else if (size == 2) signed_value = (INT16)(value = *(UINT16 *)(ptr + 1));
+        else if (size == 4) signed_value = (INT32)(value = *(UINT32 *)(ptr + 1));
         else
         {
             ERR("Unexpected item value size %d.\n", size);
-            return -1;
+            goto done;
         }
-        i += size;
 
         state->items.bit_field = value;
 
 #define SHORT_ITEM(tag,type) (((tag)<<4)|((type)<<2))
-        switch (item & SHORT_ITEM(0xf,0x3))
+        switch (*ptr & SHORT_ITEM(0xf,0x3))
         {
         case SHORT_ITEM(TAG_MAIN_INPUT, TAG_TYPE_MAIN):
-            if (!parse_new_value_caps( state, HidP_Input )) return -1;
+            if (!parse_new_value_caps( state, HidP_Input )) goto done;
             break;
         case SHORT_ITEM(TAG_MAIN_OUTPUT, TAG_TYPE_MAIN):
-            if (!parse_new_value_caps( state, HidP_Output )) return -1;
+            if (!parse_new_value_caps( state, HidP_Output )) goto done;
             break;
         case SHORT_ITEM(TAG_MAIN_FEATURE, TAG_TYPE_MAIN):
-            if (!parse_new_value_caps( state, HidP_Feature )) return -1;
+            if (!parse_new_value_caps( state, HidP_Feature )) goto done;
             break;
         case SHORT_ITEM(TAG_MAIN_COLLECTION, TAG_TYPE_MAIN):
-            if (!parse_new_collection( state )) return -1;
+            if (!parse_new_collection( state )) goto done;
             break;
         case SHORT_ITEM(TAG_MAIN_END_COLLECTION, TAG_TYPE_MAIN):
-            if (!parse_end_collection( state )) return -1;
+            if (!parse_end_collection( state )) goto done;
             break;
 
         case SHORT_ITEM(TAG_GLOBAL_USAGE_PAGE, TAG_TYPE_GLOBAL):
@@ -531,14 +544,14 @@ static int parse_descriptor( BYTE *descriptor, unsigned int index, unsigned int
             state->items.report_count = value;
             break;
         case SHORT_ITEM(TAG_GLOBAL_PUSH, TAG_TYPE_GLOBAL):
-            if (!parse_global_push( state )) return -1;
+            if (!parse_global_push( state )) goto done;
             break;
         case SHORT_ITEM(TAG_GLOBAL_POP, TAG_TYPE_GLOBAL):
-            if (!parse_global_pop( state )) return -1;
+            if (!parse_global_pop( state )) goto done;
             break;
 
         case SHORT_ITEM(TAG_LOCAL_USAGE, TAG_TYPE_LOCAL):
-            if (!parse_local_usage( state, value >> 16, value & 0xffff )) return -1;
+            if (!parse_local_usage( state, value >> 16, value & 0xffff )) goto done;
             break;
         case SHORT_ITEM(TAG_LOCAL_USAGE_MINIMUM, TAG_TYPE_LOCAL):
             parse_local_usage_min( state, value >> 16, value & 0xffff );
@@ -572,40 +585,18 @@ static int parse_descriptor( BYTE *descriptor, unsigned int index, unsigned int
             break;
         case SHORT_ITEM(TAG_LOCAL_DELIMITER, TAG_TYPE_LOCAL):
             FIXME("delimiter %d not implemented!\n", value);
-            return -1;
+            goto done;
 
         default:
-            FIXME("item type %x not implemented!\n", item);
-            return -1;
+            FIXME( "item type %x not implemented!\n", *ptr );
+            goto done;
         }
 #undef SHORT_ITEM
     }
-    return i;
-}
-
-WINE_HIDP_PREPARSED_DATA* ParseDescriptor(BYTE *descriptor, unsigned int length)
-{
-    WINE_HIDP_PREPARSED_DATA *data = NULL;
-    struct hid_parser_state *state;
-    int i;
-
-    if (TRACE_ON(hid))
-    {
-        TRACE("descriptor %p, length %u:\n", descriptor, length);
-        for (i = 0; i < length;)
-        {
-            TRACE("%08x ", i);
-            do { TRACE(" %02x", descriptor[i]); } while (++i % 16 && i < length);
-            TRACE("\n");
-        }
-    }
-
-    if (!(state = calloc( 1, sizeof(*state) ))) return NULL;
-    init_parser_state( state );
 
-    if (parse_descriptor( descriptor, 0, length, state ) >= 0 && (data = build_preparsed_data( state )))
-        debug_print_preparsed( data );
+    if ((data = build_preparsed_data( state ))) debug_print_preparsed( data );
 
+done:
     free_parser_state( state );
     return data;
 }
diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h
index f0982d508e3..c00f014bb2c 100644
--- a/dlls/hidclass.sys/hid.h
+++ b/dlls/hidclass.sys/hid.h
@@ -123,4 +123,4 @@ NTSTATUS WINAPI pdo_create(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN;
 NTSTATUS WINAPI pdo_close(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN;
 
 /* Parsing HID Report Descriptors into preparsed data */
-WINE_HIDP_PREPARSED_DATA* ParseDescriptor(BYTE *descriptor, unsigned int length) DECLSPEC_HIDDEN;
+WINE_HIDP_PREPARSED_DATA *parse_descriptor( BYTE *descriptor, unsigned int length ) DECLSPEC_HIDDEN;
diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c
index e5a38dafc1c..d792e5d3ddd 100644
--- a/dlls/hidclass.sys/pnp.c
+++ b/dlls/hidclass.sys/pnp.c
@@ -251,7 +251,7 @@ static void create_child(minidriver *minidriver, DEVICE_OBJECT *fdo)
         return;
     }
 
-    pdo_ext->u.pdo.preparsed_data = ParseDescriptor(reportDescriptor, descriptor.DescriptorList[i].wReportLength);
+    pdo_ext->u.pdo.preparsed_data = parse_descriptor( reportDescriptor, descriptor.DescriptorList[i].wReportLength );
     free(reportDescriptor);
     if (!pdo_ext->u.pdo.preparsed_data)
     {
-- 
2.32.0




More information about the wine-devel mailing list