ntoskrnl.exe/tests: Add tests with and without report IDs.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
b572cf3025
commit
731dd7de44
3 changed files with 116 additions and 56 deletions
|
@ -1436,7 +1436,7 @@
|
|||
@ stdcall -private ZwOpenEvent(ptr long ptr) NtOpenEvent
|
||||
@ stdcall ZwOpenFile(ptr long ptr ptr long long) NtOpenFile
|
||||
@ stdcall -private ZwOpenJobObject(ptr long ptr) NtOpenJobObject
|
||||
@ stdcall -private ZwOpenKey(ptr long ptr) NtOpenKey
|
||||
@ stdcall ZwOpenKey(ptr long ptr) NtOpenKey
|
||||
@ stdcall -private ZwOpenKeyEx(ptr long ptr long) NtOpenKeyEx
|
||||
@ stdcall -private ZwOpenKeyTransacted(ptr long ptr long) NtOpenKeyTransacted
|
||||
@ stdcall -private ZwOpenKeyTransactedEx(ptr long ptr long long) NtOpenKeyTransactedEx
|
||||
|
@ -1476,7 +1476,7 @@
|
|||
@ stdcall -private ZwQuerySystemInformation(long ptr long ptr) NtQuerySystemInformation
|
||||
@ stdcall -private ZwQuerySystemInformationEx(long ptr long ptr long ptr) NtQuerySystemInformationEx
|
||||
@ stdcall -private ZwQueryTimerResolution(ptr ptr ptr) NtQueryTimerResolution
|
||||
@ stdcall -private ZwQueryValueKey(long ptr long ptr long ptr) NtQueryValueKey
|
||||
@ stdcall ZwQueryValueKey(long ptr long ptr long ptr) NtQueryValueKey
|
||||
@ stdcall -private ZwQueryVirtualMemory(long ptr long ptr long ptr) NtQueryVirtualMemory
|
||||
@ stdcall -private ZwQueryVolumeInformationFile(long ptr ptr long long) NtQueryVolumeInformationFile
|
||||
@ stdcall -private ZwReadFile(long long ptr ptr ptr ptr long ptr ptr) NtReadFile
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
static UNICODE_STRING control_symlink;
|
||||
|
||||
static unsigned int got_start_device;
|
||||
static DWORD 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[] =
|
||||
{
|
||||
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),
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
#include "pop_hid_macros.h"
|
||||
|
||||
static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device, IRP *irp)
|
||||
{
|
||||
#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_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 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;
|
||||
|
@ -278,17 +288,33 @@ static void WINAPI driver_unload(DRIVER_OBJECT *driver)
|
|||
|
||||
NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *registry)
|
||||
{
|
||||
static const int info_size = offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data );
|
||||
char buffer[offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data ) + sizeof(DWORD)];
|
||||
HID_MINIDRIVER_REGISTRATION params =
|
||||
{
|
||||
.Revision = HID_REVISION,
|
||||
.DriverObject = driver,
|
||||
.RegistryPath = registry,
|
||||
};
|
||||
UNICODE_STRING name_str;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
NTSTATUS ret;
|
||||
HANDLE hkey;
|
||||
DWORD size;
|
||||
|
||||
if ((ret = winetest_init()))
|
||||
return ret;
|
||||
|
||||
InitializeObjectAttributes(&attr, registry, 0, NULL, NULL);
|
||||
ret = ZwOpenKey(&hkey, KEY_ALL_ACCESS, &attr);
|
||||
ok(!ret, "ZwOpenKey returned %#x\n", ret);
|
||||
|
||||
RtlInitUnicodeString(&name_str, L"ReportID");
|
||||
size = info_size + sizeof(report_id);
|
||||
ret = ZwQueryValueKey(hkey, &name_str, KeyValuePartialInformation, buffer, size, &size);
|
||||
ok(!ret, "ZwQueryValueKey returned %#x\n", ret);
|
||||
memcpy(&report_id, buffer + info_size, size - info_size);
|
||||
|
||||
driver->DriverExtension->AddDevice = driver_add_device;
|
||||
driver->DriverUnload = driver_unload;
|
||||
driver->MajorFunction[IRP_MJ_PNP] = driver_pnp;
|
||||
|
|
|
@ -1634,25 +1634,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,
|
||||
|
@ -1661,13 +1663,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,
|
||||
|
@ -1677,9 +1681,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,
|
||||
|
@ -1690,9 +1696,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,
|
||||
|
@ -1709,6 +1717,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,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -1956,20 +1971,26 @@ 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(DWORD report_id)
|
||||
{
|
||||
char buffer[200];
|
||||
SP_DEVICE_INTERFACE_DETAIL_DATA_A *iface_detail = (void *)buffer;
|
||||
|
@ -1984,6 +2005,8 @@ static void test_hid_device(void)
|
|||
HDEVINFO set;
|
||||
HANDLE file;
|
||||
|
||||
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());
|
||||
|
||||
|
@ -2014,7 +2037,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);
|
||||
|
||||
|
@ -2022,9 +2045,11 @@ 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, DWORD report_id)
|
||||
{
|
||||
static const char hardware_id[] = "test_hardware_id\0";
|
||||
char path[MAX_PATH], dest[MAX_PATH], *filepart;
|
||||
|
@ -2034,13 +2059,21 @@ static void test_hid_driver(struct testsign_context *ctx)
|
|||
SC_HANDLE manager, service;
|
||||
BOOL ret, need_reboot;
|
||||
HANDLE catalog, file;
|
||||
LSTATUS status;
|
||||
HDEVINFO set;
|
||||
HKEY hkey;
|
||||
FILE *f;
|
||||
|
||||
GetCurrentDirectoryA(ARRAY_SIZE(cwd), cwd);
|
||||
GetTempPathA(ARRAY_SIZE(tempdir), tempdir);
|
||||
SetCurrentDirectoryA(tempdir);
|
||||
|
||||
status = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Services\\winetest", 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL);
|
||||
ok(!status, "RegCreateKeyExW returned %#x\n", status);
|
||||
|
||||
status = RegSetValueExW(hkey, L"ReportID", 0, REG_DWORD, (void *)&report_id, sizeof(report_id));
|
||||
ok(!status, "RegSetValueExW returned %#x\n", status);
|
||||
|
||||
load_resource(L"driver_hid.dll", driver_filename);
|
||||
ret = MoveFileExW(driver_filename, L"winetest.sys", MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING);
|
||||
ok(ret, "failed to move file, error %u\n", GetLastError());
|
||||
|
@ -2088,7 +2121,7 @@ static void test_hid_driver(struct testsign_context *ctx)
|
|||
|
||||
/* Tests. */
|
||||
|
||||
test_hid_device();
|
||||
test_hid_device(report_id);
|
||||
|
||||
/* Clean up. */
|
||||
|
||||
|
@ -2219,7 +2252,8 @@ START_TEST(ntoskrnl)
|
|||
test_pnp_driver(&ctx);
|
||||
|
||||
subtest("driver_hid");
|
||||
test_hid_driver(&ctx);
|
||||
test_hid_driver(&ctx, 0);
|
||||
test_hid_driver(&ctx, 1);
|
||||
|
||||
out:
|
||||
testsign_cleanup(&ctx);
|
||||
|
|
Loading…
Add table
Reference in a new issue