[PATCH 4/5] hid: Build link collection nodes in HidP_GetLinkCollectionNodes.

Rémi Bernon rbernon at codeweavers.com
Mon Jun 28 02:22:00 CDT 2021


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/hid/hidp.c                | 44 ++++++++++++++++++----------------
 dlls/hidclass.sys/descriptor.c | 29 ++++------------------
 include/wine/hid.h             | 14 +----------
 3 files changed, 30 insertions(+), 57 deletions(-)

diff --git a/dlls/hid/hidp.c b/dlls/hid/hidp.c
index 94dc4212067..750dbce9f26 100644
--- a/dlls/hid/hidp.c
+++ b/dlls/hid/hidp.c
@@ -721,33 +721,37 @@ NTSTATUS WINAPI HidP_GetData( HIDP_REPORT_TYPE report_type, HIDP_DATA *data, ULO
     return HIDP_STATUS_SUCCESS;
 }
 
-NTSTATUS WINAPI HidP_GetLinkCollectionNodes(HIDP_LINK_COLLECTION_NODE *LinkCollectionNode,
-    ULONG *LinkCollectionNodeLength, PHIDP_PREPARSED_DATA PreparsedData)
+NTSTATUS WINAPI HidP_GetLinkCollectionNodes( HIDP_LINK_COLLECTION_NODE *nodes, ULONG *nodes_len, PHIDP_PREPARSED_DATA preparsed_data )
 {
-    WINE_HIDP_PREPARSED_DATA *data = (WINE_HIDP_PREPARSED_DATA*)PreparsedData;
-    WINE_HID_LINK_COLLECTION_NODE *nodes = HID_NODES(data);
-    ULONG i;
+    WINE_HIDP_PREPARSED_DATA *preparsed = (WINE_HIDP_PREPARSED_DATA *)preparsed_data;
+    struct hid_value_caps *caps = HID_COLLECTION_VALUE_CAPS( preparsed );
+    ULONG i, count, capacity = *nodes_len;
 
-    TRACE("(%p, %p, %p)\n", LinkCollectionNode, LinkCollectionNodeLength, PreparsedData);
+    TRACE( "nodes %p, nodes_len %p, preparsed_data %p.\n", nodes, nodes_len, preparsed_data );
 
-    if (data->magic != HID_MAGIC)
-        return HIDP_STATUS_INVALID_PREPARSED_DATA;
+    if (preparsed->magic != HID_MAGIC) return HIDP_STATUS_INVALID_PREPARSED_DATA;
 
-    if (*LinkCollectionNodeLength < data->caps.NumberLinkCollectionNodes)
-        return HIDP_STATUS_BUFFER_TOO_SMALL;
+    if (capacity < preparsed->caps.NumberLinkCollectionNodes) return HIDP_STATUS_BUFFER_TOO_SMALL;
+    count = *nodes_len = preparsed->caps.NumberLinkCollectionNodes;
 
-    for (i = 0; i < data->caps.NumberLinkCollectionNodes; ++i)
+    for (i = 0; i < count; ++i)
     {
-        LinkCollectionNode[i].LinkUsage = nodes[i].LinkUsage;
-        LinkCollectionNode[i].LinkUsagePage = nodes[i].LinkUsagePage;
-        LinkCollectionNode[i].Parent = nodes[i].Parent;
-        LinkCollectionNode[i].NumberOfChildren = nodes[i].NumberOfChildren;
-        LinkCollectionNode[i].NextSibling = nodes[i].NextSibling;
-        LinkCollectionNode[i].FirstChild = nodes[i].FirstChild;
-        LinkCollectionNode[i].CollectionType = nodes[i].CollectionType;
-        LinkCollectionNode[i].IsAlias = nodes[i].IsAlias;
+        nodes[i].LinkUsagePage = caps[i].usage_page;
+        nodes[i].LinkUsage = caps[i].usage_min;
+        nodes[i].Parent = caps[i].link_collection;
+        nodes[i].CollectionType = caps[i].bit_field;
+        nodes[i].IsAlias = 0;
+        nodes[i].FirstChild = 0;
+        nodes[i].NextSibling = 0;
+        nodes[i].NumberOfChildren = 0;
+
+        if (i > 0)
+        {
+            nodes[i].NextSibling = nodes[nodes[i].Parent].FirstChild;
+            nodes[nodes[i].Parent].FirstChild = i;
+            nodes[nodes[i].Parent].NumberOfChildren++;
+        }
     }
-    *LinkCollectionNodeLength = data->caps.NumberLinkCollectionNodes;
 
     return HIDP_STATUS_SUCCESS;
 }
diff --git a/dlls/hidclass.sys/descriptor.c b/dlls/hidclass.sys/descriptor.c
index 3b4455a0b88..986912990a7 100644
--- a/dlls/hidclass.sys/descriptor.c
+++ b/dlls/hidclass.sys/descriptor.c
@@ -834,7 +834,6 @@ static void preparse_collection(const struct collection *root, const struct coll
 static WINE_HIDP_PREPARSED_DATA *build_preparsed_data( struct collection *base_collection,
                                                        struct hid_parser_state *state )
 {
-    WINE_HID_LINK_COLLECTION_NODE *nodes;
     WINE_HIDP_PREPARSED_DATA *data;
     struct hid_value_caps *caps;
     unsigned int report_count;
@@ -843,7 +842,6 @@ static WINE_HIDP_PREPARSED_DATA *build_preparsed_data( struct collection *base_c
 
     struct preparse_ctx ctx;
     unsigned int element_off;
-    unsigned int nodes_offset;
 
     memset(&ctx, 0, sizeof(ctx));
     create_preparse_ctx(base_collection, &ctx);
@@ -853,10 +851,8 @@ static WINE_HIDP_PREPARSED_DATA *build_preparsed_data( struct collection *base_c
     element_off = FIELD_OFFSET(WINE_HIDP_PREPARSED_DATA, reports[report_count]);
     size = element_off + (ctx.elem_count * sizeof(WINE_HID_ELEMENT));
 
-    nodes_offset = size;
-    size += state->caps.NumberLinkCollectionNodes * sizeof(WINE_HID_LINK_COLLECTION_NODE);
-
-    caps_len = state->caps.NumberInputValueCaps + state->caps.NumberOutputValueCaps + state->caps.NumberFeatureValueCaps;
+    caps_len = state->caps.NumberInputValueCaps + state->caps.NumberOutputValueCaps +
+               state->caps.NumberFeatureValueCaps + state->caps.NumberLinkCollectionNodes;
     caps_off = size;
     size += caps_len * sizeof(*caps);
 
@@ -866,7 +862,6 @@ static WINE_HIDP_PREPARSED_DATA *build_preparsed_data( struct collection *base_c
     data->caps = state->caps;
     data->new_caps = state->caps;
     data->elementOffset = element_off;
-    data->nodesOffset = nodes_offset;
 
     data->value_caps_offset = caps_off;
     data->value_caps_count[HidP_Input] = state->caps.NumberInputValueCaps;
@@ -878,23 +873,6 @@ static WINE_HIDP_PREPARSED_DATA *build_preparsed_data( struct collection *base_c
     data->caps.NumberFeatureValueCaps = data->caps.NumberFeatureButtonCaps = data->caps.NumberFeatureDataIndices = 0;
     preparse_collection(base_collection, base_collection, data, &ctx);
 
-    nodes = HID_NODES( data );
-    for (i = 0; i < data->caps.NumberLinkCollectionNodes; ++i)
-    {
-        nodes[i].LinkUsagePage = state->collections[i].usage_page;
-        nodes[i].LinkUsage = state->collections[i].usage_min;
-        nodes[i].Parent = state->collections[i].link_collection;
-        nodes[i].CollectionType = state->collections[i].bit_field;
-        nodes[i].IsAlias = 0;
-
-        if (i > 0)
-        {
-            nodes[i].NextSibling = nodes[nodes[i].Parent].FirstChild;
-            nodes[nodes[i].Parent].FirstChild = i;
-            nodes[nodes[i].Parent].NumberOfChildren++;
-        }
-    }
-
     /* fixup value vs button vs filler counts */
 
     caps = HID_INPUT_VALUE_CAPS( data );
@@ -929,6 +907,9 @@ static WINE_HIDP_PREPARSED_DATA *build_preparsed_data( struct collection *base_c
     data->new_caps.NumberFeatureButtonCaps = button;
     data->new_caps.NumberFeatureValueCaps -= filler + button;
 
+    caps = HID_COLLECTION_VALUE_CAPS( data );
+    memcpy( caps, state->collections, data->new_caps.NumberLinkCollectionNodes * sizeof(*caps) );
+
     return data;
 }
 
diff --git a/include/wine/hid.h b/include/wine/hid.h
index 8d1d6d4d104..b15b26474a0 100644
--- a/include/wine/hid.h
+++ b/include/wine/hid.h
@@ -81,17 +81,6 @@ typedef struct __WINE_HID_REPORT
     DWORD elementIdx;
 } WINE_HID_REPORT;
 
-typedef struct __WINE_HID_LINK_COLLECTION_NODE {
-    USAGE  LinkUsage;
-    USAGE  LinkUsagePage;
-    USHORT Parent;
-    USHORT NumberOfChildren;
-    USHORT NextSibling;
-    USHORT FirstChild;
-    BYTE   CollectionType;
-    BYTE   IsAlias;
-} WINE_HID_LINK_COLLECTION_NODE;
-
 typedef struct __WINE_HIDP_PREPARSED_DATA
 {
     DWORD magic;
@@ -100,7 +89,6 @@ typedef struct __WINE_HIDP_PREPARSED_DATA
     HIDP_CAPS new_caps;
 
     DWORD elementOffset;
-    DWORD nodesOffset;
     DWORD reportCount[3];
     BYTE reportIdx[3][256];
 
@@ -113,10 +101,10 @@ typedef struct __WINE_HIDP_PREPARSED_DATA
 #define HID_OUTPUT_REPORTS(d) ((d)->reports + (d)->reportCount[0])
 #define HID_FEATURE_REPORTS(d) ((d)->reports + (d)->reportCount[0] + (d)->reportCount[1])
 #define HID_ELEMS(d) ((WINE_HID_ELEMENT*)((BYTE*)(d) + (d)->elementOffset))
-#define HID_NODES(d) ((WINE_HID_LINK_COLLECTION_NODE*)((BYTE*)(d) + (d)->nodesOffset))
 
 #define HID_INPUT_VALUE_CAPS(d) ((struct hid_value_caps*)((char *)(d) + (d)->value_caps_offset))
 #define HID_OUTPUT_VALUE_CAPS(d) (HID_INPUT_VALUE_CAPS(d) + (d)->value_caps_count[0])
 #define HID_FEATURE_VALUE_CAPS(d) (HID_OUTPUT_VALUE_CAPS(d) + (d)->value_caps_count[1])
+#define HID_COLLECTION_VALUE_CAPS(d) (HID_FEATURE_VALUE_CAPS(d) + (d)->value_caps_count[2])
 
 #endif /* __WINE_PARSE_H */
-- 
2.32.0




More information about the wine-devel mailing list