[PATCH 3/7] ntoskrnl.exe/tests: Add tests with and without report IDs.

Rémi Bernon rbernon at codeweavers.com
Fri Jun 11 05:43:55 CDT 2021


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/ntoskrnl.exe/tests/driver_hid.c | 97 ++++++++++++++++------------
 dlls/ntoskrnl.exe/tests/ntoskrnl.c   | 54 ++++++++++++----
 2 files changed, 97 insertions(+), 54 deletions(-)

diff --git a/dlls/ntoskrnl.exe/tests/driver_hid.c b/dlls/ntoskrnl.exe/tests/driver_hid.c
index 1fe644250f7..7260adeb172 100644
--- a/dlls/ntoskrnl.exe/tests/driver_hid.c
+++ b/dlls/ntoskrnl.exe/tests/driver_hid.c
@@ -40,6 +40,7 @@
 static UNICODE_STRING control_symlink;
 
 static unsigned int got_start_device;
+static unsigned int report_id;
 
 static NTSTATUS WINAPI driver_pnp(DEVICE_OBJECT *device, IRP *irp)
 {
@@ -85,49 +86,54 @@ static NTSTATUS WINAPI driver_power(DEVICE_OBJECT *device, IRP *irp)
     return PoCallDriver(ext->NextDeviceObject, irp);
 }
 
-#include "psh_hid_macros.h"
-
-static const unsigned char report_descriptor[] =
+static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device, IRP *irp)
 {
-    USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC),
-    USAGE(1, HID_USAGE_GENERIC_JOYSTICK),
-    COLLECTION(1, Application),
-        USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC),
-        USAGE(1, HID_USAGE_GENERIC_X),
-        USAGE(1, HID_USAGE_GENERIC_Y),
-        LOGICAL_MINIMUM(1, -128),
-        LOGICAL_MAXIMUM(1, 127),
-        REPORT_SIZE(1, 8),
-        REPORT_COUNT(1, 2),
-        INPUT(1, Data|Var|Abs),
-
-        USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON),
-        USAGE_MINIMUM(1, 1),
-        USAGE_MAXIMUM(1, 8),
-        LOGICAL_MINIMUM(1, 0),
-        LOGICAL_MAXIMUM(1, 1),
-        PHYSICAL_MINIMUM(1, 0),
-        PHYSICAL_MAXIMUM(1, 1),
-        REPORT_COUNT(1, 8),
-        REPORT_SIZE(1, 1),
-        INPUT(1, Data|Var|Abs),
-
+#include "psh_hid_macros.h"
+/* Replace REPORT_ID with USAGE_PAGE when id is 0 */
+#define REPORT_ID_OR_USAGE_PAGE(size, id) SHORT_ITEM_1((id ? 8 : 0), 1, id)
+    const unsigned char report_descriptor[] =
+    {
         USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC),
-        USAGE(1, HID_USAGE_GENERIC_HATSWITCH),
-        LOGICAL_MINIMUM(1, 1),
-        LOGICAL_MAXIMUM(1, 8),
-        PHYSICAL_MINIMUM(1, 0),
-        PHYSICAL_MAXIMUM(1, 8),
-        REPORT_SIZE(1, 4),
-        REPORT_COUNT(1, 2),
-        INPUT(1, Data|Var|Abs),
-    END_COLLECTION,
-};
-
+        USAGE(1, HID_USAGE_GENERIC_JOYSTICK),
+        COLLECTION(1, Application),
+            USAGE(1, HID_USAGE_GENERIC_JOYSTICK),
+            COLLECTION(1, Logical),
+                REPORT_ID_OR_USAGE_PAGE(1, report_id),
+                USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC),
+                USAGE(1, HID_USAGE_GENERIC_X),
+                USAGE(1, HID_USAGE_GENERIC_Y),
+                LOGICAL_MINIMUM(1, -128),
+                LOGICAL_MAXIMUM(1, 127),
+                REPORT_SIZE(1, 8),
+                REPORT_COUNT(1, 2),
+                INPUT(1, Data|Var|Abs),
+
+                USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON),
+                USAGE_MINIMUM(1, 1),
+                USAGE_MAXIMUM(1, 8),
+                LOGICAL_MINIMUM(1, 0),
+                LOGICAL_MAXIMUM(1, 1),
+                PHYSICAL_MINIMUM(1, 0),
+                PHYSICAL_MAXIMUM(1, 1),
+                REPORT_COUNT(1, 8),
+                REPORT_SIZE(1, 1),
+                INPUT(1, Data|Var|Abs),
+
+                USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC),
+                USAGE(1, HID_USAGE_GENERIC_HATSWITCH),
+                LOGICAL_MINIMUM(1, 1),
+                LOGICAL_MAXIMUM(1, 8),
+                PHYSICAL_MINIMUM(1, 0),
+                PHYSICAL_MAXIMUM(1, 8),
+                REPORT_SIZE(1, 4),
+                REPORT_COUNT(1, 2),
+                INPUT(1, Data|Var|Abs),
+            END_COLLECTION,
+        END_COLLECTION,
+    };
+#undef REPORT_ID_OR_USAGE_PAGE
 #include "pop_hid_macros.h"
 
-static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device, IRP *irp)
-{
     static BOOL test_failed;
     IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp);
     const ULONG in_size = stack->Parameters.DeviceIoControl.InputBufferLength;
@@ -202,9 +208,13 @@ static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device, IRP *irp)
 
         case IOCTL_HID_READ_REPORT:
         {
-            ULONG expected_size = 4;
+            ULONG expected_size = report_id ? 5 : 4;
             ok(!in_size, "got input size %u\n", in_size);
-            if (!test_failed) todo_wine ok(out_size == expected_size, "got output size %u\n", out_size);
+            if (!test_failed)
+            {
+                todo_wine_if(!report_id)
+                ok(out_size == expected_size, "got output size %u\n", out_size);
+            }
             if (out_size != expected_size) test_failed = TRUE;
 
             ret = STATUS_NOT_IMPLEMENTED;
@@ -284,11 +294,16 @@ NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *registry)
         .DriverObject = driver,
         .RegistryPath = registry,
     };
+    WCHAR buffer[MAX_PATH];
     NTSTATUS ret;
 
     if ((ret = winetest_init()))
         return ret;
 
+    memset(buffer, 0, sizeof(buffer));
+    lstrcpynW(buffer, registry->Buffer, min(MAX_PATH, registry->Length / sizeof(WCHAR) + 1));
+    if (wcsstr(buffer, L"winetest_hid_report_id")) report_id = 1;
+
     driver->DriverExtension->AddDevice = driver_add_device;
     driver->DriverUnload = driver_unload;
     driver->MajorFunction[IRP_MJ_PNP] = driver_pnp;
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
index 90d68149c1f..6afc07ef62e 100644
--- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
@@ -1639,25 +1639,27 @@ static inline void check_hidp_value_caps_(int line, HIDP_VALUE_CAPS *caps, const
     }
 }
 
-static void test_hidp(HANDLE file)
+static void test_hidp(HANDLE file, int report_id)
 {
-    static const HIDP_CAPS expect_hidp_caps =
+    const HIDP_CAPS expect_hidp_caps =
     {
         .Usage = HID_USAGE_GENERIC_JOYSTICK,
         .UsagePage = HID_USAGE_PAGE_GENERIC,
         .InputReportByteLength = 5,
-        .NumberLinkCollectionNodes = 1,
+        .NumberLinkCollectionNodes = 2,
         .NumberInputButtonCaps = 1,
         .NumberInputValueCaps = 3,
         .NumberInputDataIndices = 11,
     };
-    static const HIDP_BUTTON_CAPS expect_button_caps[] =
+    const HIDP_BUTTON_CAPS expect_button_caps[] =
     {
         {
             .UsagePage = HID_USAGE_PAGE_BUTTON,
+            .ReportID = report_id,
             .BitField = 2,
             .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
             .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
+            .LinkCollection = 1,
             .IsRange = TRUE,
             .IsAbsolute = TRUE,
             .Range.UsageMin = 1,
@@ -1666,13 +1668,15 @@ static void test_hidp(HANDLE file)
             .Range.DataIndexMax = 9,
         },
     };
-    static const HIDP_VALUE_CAPS expect_value_caps[] =
+    const HIDP_VALUE_CAPS expect_value_caps[] =
     {
         {
             .UsagePage = HID_USAGE_PAGE_GENERIC,
+            .ReportID = report_id,
             .BitField = 2,
             .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
             .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
+            .LinkCollection = 1,
             .IsAbsolute = TRUE,
             .BitSize = 8,
             .ReportCount = 1,
@@ -1682,9 +1686,11 @@ static void test_hidp(HANDLE file)
         },
         {
             .UsagePage = HID_USAGE_PAGE_GENERIC,
+            .ReportID = report_id,
             .BitField = 2,
             .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
             .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
+            .LinkCollection = 1,
             .IsAbsolute = TRUE,
             .BitSize = 8,
             .ReportCount = 1,
@@ -1695,9 +1701,11 @@ static void test_hidp(HANDLE file)
         },
         {
             .UsagePage = HID_USAGE_PAGE_GENERIC,
+            .ReportID = report_id,
             .BitField = 2,
             .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
             .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
+            .LinkCollection = 1,
             .IsAbsolute = TRUE,
             .BitSize = 4,
             .ReportCount = 2,
@@ -1714,6 +1722,13 @@ static void test_hidp(HANDLE file)
             .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
             .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
             .CollectionType = 1,
+            .NumberOfChildren = 1,
+            .FirstChild = 1,
+        },
+        {
+            .LinkUsage = HID_USAGE_GENERIC_JOYSTICK,
+            .LinkUsagePage = HID_USAGE_PAGE_GENERIC,
+            .CollectionType = 2,
         },
     };
 
@@ -1961,34 +1976,45 @@ static void test_hidp(HANDLE file)
     ok(status == HIDP_STATUS_INVALID_REPORT_LENGTH, "HidP_InitializeReportForID returned %#x\n", status);
     status = HidP_InitializeReportForID(HidP_Input, 0, preparsed_data, report, caps.InputReportByteLength + 1);
     ok(status == HIDP_STATUS_INVALID_REPORT_LENGTH, "HidP_InitializeReportForID returned %#x\n", status);
+    status = HidP_InitializeReportForID(HidP_Input, 1 - report_id, preparsed_data, report, caps.InputReportByteLength);
+    todo_wine_if(!report_id)
+    ok(status == HIDP_STATUS_REPORT_DOES_NOT_EXIST, "HidP_InitializeReportForID returned %#x\n", status);
 
     memset(report, 0xcd, sizeof(report));
-    status = HidP_InitializeReportForID(HidP_Input, 0, preparsed_data, report, caps.InputReportByteLength);
+    status = HidP_InitializeReportForID(HidP_Input, report_id, preparsed_data, report, caps.InputReportByteLength);
+    todo_wine_if(report_id)
     ok(status == HIDP_STATUS_SUCCESS, "HidP_InitializeReportForID returned %#x\n", status);
 
     memset(buffer, 0xcd, sizeof(buffer));
     memset(buffer, 0, caps.InputReportByteLength);
+    buffer[0] = report_id;
+    todo_wine_if(report_id)
     ok(!memcmp(buffer, report, sizeof(buffer)), "unexpected report data\n");
 
     HidD_FreePreparsedData(preparsed_data);
     CloseHandle(file);
 }
 
-static void test_hid_device(void)
+static void test_hid_device(char const *service_name)
 {
     char buffer[200];
     SP_DEVICE_INTERFACE_DETAIL_DATA_A *iface_detail = (void *)buffer;
     SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)};
     SP_DEVINFO_DATA device = {sizeof(device)};
+    unsigned int i, report_id;
     BOOL ret, found = FALSE;
     OBJECT_ATTRIBUTES attr;
     UNICODE_STRING string;
     IO_STATUS_BLOCK io;
     NTSTATUS status;
-    unsigned int i;
     HDEVINFO set;
     HANDLE file;
 
+    if (!strcmp(service_name, "winetest_hid_report_ids")) report_id = 1;
+    else report_id = 0;
+
+    winetest_push_context("report %d", report_id);
+
     set = SetupDiGetClassDevsA(&GUID_DEVINTERFACE_HID, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
     ok(set != INVALID_HANDLE_VALUE, "failed to get device list, error %#x\n", GetLastError());
 
@@ -2019,7 +2045,7 @@ static void test_hid_device(void)
             FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
     ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
 
-    test_hidp(file);
+    test_hidp(file, report_id);
 
     CloseHandle(file);
 
@@ -2027,12 +2053,13 @@ static void test_hid_device(void)
     InitializeObjectAttributes(&attr, &string, OBJ_CASE_INSENSITIVE, NULL, NULL);
     status = NtOpenFile(&file, SYNCHRONIZE, &attr, &io, 0, FILE_SYNCHRONOUS_IO_NONALERT);
     todo_wine ok(status == STATUS_UNSUCCESSFUL, "got %#x\n", status);
+
+    winetest_pop_context();
 }
 
-static void test_hid_driver(struct testsign_context *ctx)
+static void test_hid_driver(struct testsign_context *ctx, char const *service_name)
 {
     static const char hardware_id[] = "test_hardware_id\0";
-    static const char service_name[] = "winetest_hid";
     char path[MAX_PATH], dest[MAX_PATH], *filepart;
     SP_DEVINFO_DATA device = {sizeof(device)};
     char cwd[MAX_PATH], tempdir[MAX_PATH];
@@ -2094,7 +2121,7 @@ static void test_hid_driver(struct testsign_context *ctx)
 
     /* Tests. */
 
-    test_hid_device();
+    test_hid_device(service_name);
 
     /* Clean up. */
 
@@ -2225,7 +2252,8 @@ START_TEST(ntoskrnl)
     test_pnp_driver(&ctx);
 
     subtest("driver_hid");
-    test_hid_driver(&ctx);
+    test_hid_driver(&ctx, "winetest_hid");
+    test_hid_driver(&ctx, "winetest_hid_report_ids");
 
 out:
     testsign_cleanup(&ctx);
-- 
2.31.0




More information about the wine-devel mailing list