Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/hid/hid.spec | 2 +- dlls/hid/hidp.c | 8 ++++++++ include/ddk/hidpi.h | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/dlls/hid/hid.spec b/dlls/hid/hid.spec index b50e04d197f..b8e29fef16a 100644 --- a/dlls/hid/hid.spec +++ b/dlls/hid/hid.spec @@ -22,7 +22,7 @@ @ stdcall HidP_GetCaps(ptr ptr) @ stdcall HidP_GetData(long ptr ptr ptr ptr long) @ stub HidP_GetExtendedAttributes -@ stub HidP_GetLinkCollectionNodes +@ stdcall HidP_GetLinkCollectionNodes(ptr ptr ptr) @ stdcall HidP_GetScaledUsageValue(long long long long ptr ptr ptr long) @ stdcall HidP_GetSpecificButtonCaps(long long long long ptr ptr ptr) @ stdcall HidP_GetSpecificValueCaps(long long long long ptr ptr ptr) diff --git a/dlls/hid/hidp.c b/dlls/hid/hidp.c index 9d631912c85..5f18f57dd93 100644 --- a/dlls/hid/hidp.c +++ b/dlls/hid/hidp.c @@ -927,3 +927,11 @@ NTSTATUS WINAPI HidP_GetData(HIDP_REPORT_TYPE ReportType, HIDP_DATA *DataList, U
return rc; } + +NTSTATUS WINAPI HidP_GetLinkCollectionNodes(HIDP_LINK_COLLECTION_NODE *LinkCollectionNode, + ULONG *LinkCollectionNodeLength, PHIDP_PREPARSED_DATA PreparsedData) +{ + TRACE("stub (%p, %p, %p)\n", LinkCollectionNode, LinkCollectionNodeLength, PreparsedData); + + return STATUS_NOT_IMPLEMENTED; +} diff --git a/include/ddk/hidpi.h b/include/ddk/hidpi.h index 042c84dd1c5..51d61ea8541 100644 --- a/include/ddk/hidpi.h +++ b/include/ddk/hidpi.h @@ -175,6 +175,19 @@ typedef struct _HIDP_DATA { } DUMMYUNIONNAME; } HIDP_DATA, *PHIDP_DATA;
+typedef struct _HIDP_LINK_COLLECTION_NODE { + USAGE LinkUsage; + USAGE LinkUsagePage; + USHORT Parent; + USHORT NumberOfChildren; + USHORT NextSibling; + USHORT FirstChild; + ULONG CollectionType : 8; + ULONG IsAlias : 1; + ULONG Reserved : 23; + PVOID UserContext; +} HIDP_LINK_COLLECTION_NODE, *PHIDP_LINK_COLLECTION_NODE; + typedef BOOLEAN (NTAPI *PHIDP_INSERT_SCANCODES) (VOID *Context, CHAR *NewScanCodes, ULONG Length);
@@ -196,6 +209,7 @@ NTSTATUS WINAPI HidP_GetSpecificValueCaps(HIDP_REPORT_TYPE ReportType, USAGE Usa NTSTATUS WINAPI HidP_GetUsagesEx(HIDP_REPORT_TYPE ReportType, USHORT LinkCollection, USAGE_AND_PAGE *ButtonList, ULONG *UsageLength, PHIDP_PREPARSED_DATA PreparsedData, CHAR *Report, ULONG ReportLength); ULONG WINAPI HidP_MaxDataListLength(HIDP_REPORT_TYPE ReportType, PHIDP_PREPARSED_DATA PreparsedData); NTSTATUS WINAPI HidP_GetData(HIDP_REPORT_TYPE ReportType, HIDP_DATA *DataList, ULONG *DataLength, PHIDP_PREPARSED_DATA PreparsedData, CHAR *Report, ULONG ReportLength); +NTSTATUS WINAPI HidP_GetLinkCollectionNodes(HIDP_LINK_COLLECTION_NODE *LinkCollectionNode, ULONG *LinkCollectionNodeLength, PHIDP_PREPARSED_DATA PreparsedData);
#ifndef FACILITY_HID_ERROR_CODE #define FACILITY_HID_ERROR_CODE 0x11
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/hid/tests/device.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/dlls/hid/tests/device.c b/dlls/hid/tests/device.c index bb819cc83f2..ce90f18f0cd 100644 --- a/dlls/hid/tests/device.c +++ b/dlls/hid/tests/device.c @@ -232,6 +232,33 @@ static void process_data(HIDP_CAPS Caps, PHIDP_PREPARSED_DATA ppd, CHAR *data, D
HeapFree(GetProcessHeap(), 0, values); } + + todo_wine + ok(Caps.NumberLinkCollectionNodes > 0, "Expected at least one link collection\n"); + if (Caps.NumberLinkCollectionNodes) + { + HIDP_LINK_COLLECTION_NODE nodes[256]; + ULONG nodes_count = ARRAY_SIZE(nodes); + + status = HidP_GetLinkCollectionNodes(nodes, &nodes_count, ppd); + todo_wine + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetLinkCollectionNodes failed:%x\n", status); + + for (i = 0; i < nodes_count; ++i) + { + trace(" [%d] LinkUsage: %x LinkUsagePage: %x Parent: %x " + "NumberOfChildren: %x NextSibling: %x FirstChild: %x " + "CollectionType: %x IsAlias: %x UserContext: %p\n", + i, nodes[i].LinkUsage, nodes[i].LinkUsagePage, nodes[i].Parent, + nodes[i].NumberOfChildren, nodes[i].NextSibling, nodes[i].FirstChild, + nodes[i].CollectionType, nodes[i].IsAlias, nodes[i].UserContext); + } + + ok(nodes_count > 0, "Unexpected number of link collection nodes:%u.\n", nodes_count); + ok(nodes[0].LinkUsagePage == Caps.UsagePage, "Unexpected top collection usage page:%x\n", nodes[0].LinkUsagePage); + ok(nodes[0].LinkUsage == Caps.Usage, "Unexpected top collection usage:%x\n", nodes[0].LinkUsage); + ok(nodes[0].CollectionType == 1, "Unexpected top collection type:%x\n", nodes[0].CollectionType); + } }
static void test_read_device(void)
There should always be the top level collection, and some games expect that or crash.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/hid/hidp.c | 2 ++ dlls/hid/tests/device.c | 1 - dlls/hidclass.sys/descriptor.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/dlls/hid/hidp.c b/dlls/hid/hidp.c index 5f18f57dd93..9aef7711d0b 100644 --- a/dlls/hid/hidp.c +++ b/dlls/hid/hidp.c @@ -933,5 +933,7 @@ NTSTATUS WINAPI HidP_GetLinkCollectionNodes(HIDP_LINK_COLLECTION_NODE *LinkColle { TRACE("stub (%p, %p, %p)\n", LinkCollectionNode, LinkCollectionNodeLength, PreparsedData);
+ *LinkCollectionNodeLength = 0; + return STATUS_NOT_IMPLEMENTED; } diff --git a/dlls/hid/tests/device.c b/dlls/hid/tests/device.c index ce90f18f0cd..cdc1d94db1a 100644 --- a/dlls/hid/tests/device.c +++ b/dlls/hid/tests/device.c @@ -233,7 +233,6 @@ static void process_data(HIDP_CAPS Caps, PHIDP_PREPARSED_DATA ppd, CHAR *data, D HeapFree(GetProcessHeap(), 0, values); }
- todo_wine ok(Caps.NumberLinkCollectionNodes > 0, "Expected at least one link collection\n"); if (Caps.NumberLinkCollectionNodes) { diff --git a/dlls/hidclass.sys/descriptor.c b/dlls/hidclass.sys/descriptor.c index af1679d23b0..09455fb05b8 100644 --- a/dlls/hidclass.sys/descriptor.c +++ b/dlls/hidclass.sys/descriptor.c @@ -911,6 +911,7 @@ static WINE_HIDP_PREPARSED_DATA* build_PreparseData(struct collection *base_coll data->dwSize = size; data->caps.Usage = base_collection->caps.u.NotRange.Usage; data->caps.UsagePage = base_collection->caps.UsagePage; + data->caps.NumberLinkCollectionNodes = 1; data->elementOffset = element_off;
preparse_collection(base_collection, data, &ctx);
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
It may be better to reroder this before patch #3 where we advertise the top level collection presence, but then the todo_wine removal would be pointless here. Maybe squash both?
dlls/hid/hidp.c | 20 +++++++++++++++++--- dlls/hid/tests/device.c | 1 - 2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/dlls/hid/hidp.c b/dlls/hid/hidp.c index 9aef7711d0b..e00d40ed280 100644 --- a/dlls/hid/hidp.c +++ b/dlls/hid/hidp.c @@ -931,9 +931,23 @@ NTSTATUS WINAPI HidP_GetData(HIDP_REPORT_TYPE ReportType, HIDP_DATA *DataList, U NTSTATUS WINAPI HidP_GetLinkCollectionNodes(HIDP_LINK_COLLECTION_NODE *LinkCollectionNode, ULONG *LinkCollectionNodeLength, PHIDP_PREPARSED_DATA PreparsedData) { - TRACE("stub (%p, %p, %p)\n", LinkCollectionNode, LinkCollectionNodeLength, PreparsedData); + WINE_HIDP_PREPARSED_DATA *data = (WINE_HIDP_PREPARSED_DATA*)PreparsedData;
- *LinkCollectionNodeLength = 0; + TRACE("(%p, %p, %p)\n", LinkCollectionNode, LinkCollectionNodeLength, PreparsedData);
- return STATUS_NOT_IMPLEMENTED; + if (data->caps.NumberLinkCollectionNodes > 1) + FIXME("Unsupported number of link collections!\n"); + + *LinkCollectionNodeLength = 1; + LinkCollectionNode[0].LinkUsage = data->caps.Usage; + LinkCollectionNode[0].LinkUsagePage = data->caps.UsagePage; + LinkCollectionNode[0].Parent = 0; + LinkCollectionNode[0].NumberOfChildren = 0; + LinkCollectionNode[0].NextSibling = 0; + LinkCollectionNode[0].FirstChild = 0; + LinkCollectionNode[0].CollectionType = 1; + LinkCollectionNode[0].IsAlias = 0; + LinkCollectionNode[0].UserContext = 0; + + return STATUS_SUCCESS; } diff --git a/dlls/hid/tests/device.c b/dlls/hid/tests/device.c index cdc1d94db1a..79530c63416 100644 --- a/dlls/hid/tests/device.c +++ b/dlls/hid/tests/device.c @@ -240,7 +240,6 @@ static void process_data(HIDP_CAPS Caps, PHIDP_PREPARSED_DATA ppd, CHAR *data, D ULONG nodes_count = ARRAY_SIZE(nodes);
status = HidP_GetLinkCollectionNodes(nodes, &nodes_count, ppd); - todo_wine ok(status == HIDP_STATUS_SUCCESS, "HidP_GetLinkCollectionNodes failed:%x\n", status);
for (i = 0; i < nodes_count; ++i)
On 2/7/20 7:25 PM, Rémi Bernon wrote:
- return STATUS_SUCCESS;
This should be HIDP_STATUS_SUCCESS ofc. -- Rémi Bernon rbernon@codeweavers.com
We discussed a bit, but it would be nice if you could investigate how hard it would be to have a real implementation of this based on the HID descriptor.
If that ends up being way to hard then something like this could be acceptable for a first pass stub. But I would like to see some A fixme message somewhere.
-aric
On 2/7/20 12:50 PM, Rémi Bernon wrote:
On 2/7/20 7:25 PM, Rémi Bernon wrote:
+ return STATUS_SUCCESS;
This should be HIDP_STATUS_SUCCESS ofc.
Rémi Bernon rbernon@codeweavers.com