Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntoskrnl.exe/tests/driver_hid.c | 124 +++++++++++- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 246 ++++++++++++++++++++--- dlls/ntoskrnl.exe/tests/psh_hid_macros.h | 4 +- dlls/winebus.sys/psh_hid_macros.h | 4 +- 4 files changed, 339 insertions(+), 39 deletions(-)
diff --git a/dlls/ntoskrnl.exe/tests/driver_hid.c b/dlls/ntoskrnl.exe/tests/driver_hid.c index 7260adeb172..6a5aeb05fbd 100644 --- a/dlls/ntoskrnl.exe/tests/driver_hid.c +++ b/dlls/ntoskrnl.exe/tests/driver_hid.c @@ -90,7 +90,7 @@ 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) +#define REPORT_ID_OR_USAGE_PAGE(size, id, off) SHORT_ITEM_1((id ? 8 : 0), 1, (id + off)) const unsigned char report_descriptor[] = { USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC), @@ -98,7 +98,7 @@ static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device, IRP *irp) COLLECTION(1, Application), USAGE(1, HID_USAGE_GENERIC_JOYSTICK), COLLECTION(1, Logical), - REPORT_ID_OR_USAGE_PAGE(1, report_id), + REPORT_ID_OR_USAGE_PAGE(1, report_id, 0), USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC), USAGE(1, HID_USAGE_GENERIC_X), USAGE(1, HID_USAGE_GENERIC_Y), @@ -113,22 +113,132 @@ static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device, IRP *irp) 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_MINIMUM(1, 0x18), + USAGE_MAXIMUM(1, 0x1f), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 1), + REPORT_COUNT(1, 8), + REPORT_SIZE(1, 1), + INPUT(1, Cnst|Var|Abs), + REPORT_COUNT(1, 8), + REPORT_SIZE(1, 1), + INPUT(1, Cnst|Var|Abs), + /* needs to be 8 bit aligned as next has Buff */ + + USAGE_MINIMUM(4, (HID_USAGE_PAGE_KEYBOARD<<16)|0x8), + USAGE_MAXIMUM(4, (HID_USAGE_PAGE_KEYBOARD<<16)|0xf), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 8), + REPORT_COUNT(1, 2), + REPORT_SIZE(1, 8), + INPUT(2, Data|Ary|Rel|Wrap|Lin|Pref|Null|Vol|Buff), + + /* needs to be 8 bit aligned as previous has Buff */ + USAGE(1, 0x20), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 1), + REPORT_COUNT(1, 8), + REPORT_SIZE(1, 1), + INPUT(1, Data|Var|Abs), + USAGE_MINIMUM(1, 0x21), + USAGE_MAXIMUM(1, 0x22), + REPORT_COUNT(1, 2), + REPORT_SIZE(1, 0), + INPUT(1, Data|Var|Abs), + USAGE(1, 0x23), + REPORT_COUNT(1, 0), + 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, + + USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC), + USAGE(1, HID_USAGE_GENERIC_JOYSTICK), + COLLECTION(1, Report), + REPORT_ID_OR_USAGE_PAGE(1, report_id, 1), + USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON), + USAGE_MINIMUM(1, 9), + USAGE_MAXIMUM(1, 10), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 1), + REPORT_COUNT(1, 8), + REPORT_SIZE(1, 1), + INPUT(1, Data|Var|Abs), + END_COLLECTION, + + USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS), + USAGE(1, HID_USAGE_HAPTICS_SIMPLE_CONTROLLER), + COLLECTION(1, Logical), + REPORT_ID_OR_USAGE_PAGE(1, report_id, 0), + USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS), + + USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_LIST), + COLLECTION(1, NamedArray), + USAGE_PAGE(1, HID_USAGE_PAGE_ORDINAL), + USAGE(1, 3), /* HID_USAGE_HAPTICS_WAVEFORM_RUMBLE */ + USAGE(1, 4), /* HID_USAGE_HAPTICS_WAVEFORM_BUZZ */ + LOGICAL_MINIMUM(2, 0x0000), + LOGICAL_MAXIMUM(2, 0xffff), + REPORT_COUNT(1, 2), + REPORT_SIZE(1, 16), + FEATURE(1, Data|Var|Abs|Null), + END_COLLECTION, + + USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS), + USAGE(1, HID_USAGE_HAPTICS_DURATION_LIST), + COLLECTION(1, NamedArray), + USAGE_PAGE(1, HID_USAGE_PAGE_ORDINAL), + USAGE(1, 3), /* 0 (HID_USAGE_HAPTICS_WAVEFORM_RUMBLE) */ + USAGE(1, 4), /* 0 (HID_USAGE_HAPTICS_WAVEFORM_BUZZ) */ + LOGICAL_MINIMUM(2, 0x0000), + LOGICAL_MAXIMUM(2, 0xffff), + REPORT_COUNT(1, 2), + REPORT_SIZE(1, 16), + FEATURE(1, Data|Var|Abs|Null), + END_COLLECTION, + + USAGE_PAGE(2, HID_USAGE_PAGE_HAPTICS), + USAGE(1, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME), + UNIT(2, 0x1001), /* seconds */ + UNIT_EXPONENT(1, -3), /* 10^-3 */ + LOGICAL_MINIMUM(2, 0x8000), + LOGICAL_MAXIMUM(2, 0x7fff), + PHYSICAL_MINIMUM(4, 0x00000000), + PHYSICAL_MAXIMUM(4, 0xffffffff), + REPORT_SIZE(1, 32), + REPORT_COUNT(1, 1), + FEATURE(1, Data|Var|Abs), + /* reset global items */ + UNIT(1, 0), /* None */ + UNIT_EXPONENT(1, 0), + END_COLLECTION, + + USAGE_PAGE(1, HID_USAGE_PAGE_GENERIC), + USAGE(1, HID_USAGE_GENERIC_JOYSTICK), + COLLECTION(1, Report), + REPORT_ID_OR_USAGE_PAGE(1, report_id, 1), + USAGE_PAGE(1, HID_USAGE_PAGE_BUTTON), + USAGE_MINIMUM(1, 9), + USAGE_MAXIMUM(1, 10), + LOGICAL_MINIMUM(1, 0), + LOGICAL_MAXIMUM(1, 1), + PHYSICAL_MINIMUM(1, 0), + PHYSICAL_MAXIMUM(1, 1), + REPORT_COUNT(1, 8), + REPORT_SIZE(1, 1), + FEATURE(1, Data|Var|Abs), + END_COLLECTION, END_COLLECTION, }; #undef REPORT_ID_OR_USAGE_PAGE @@ -208,7 +318,7 @@ static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device, IRP *irp)
case IOCTL_HID_READ_REPORT: { - ULONG expected_size = report_id ? 5 : 4; + ULONG expected_size = 10; ok(!in_size, "got input size %u\n", in_size); if (!test_failed) { diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index 6afc07ef62e..c1427258971 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -1641,15 +1641,36 @@ static inline void check_hidp_value_caps_(int line, HIDP_VALUE_CAPS *caps, const
static void test_hidp(HANDLE file, int report_id) { - 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 = 2, - .NumberInputButtonCaps = 1, - .NumberInputValueCaps = 3, - .NumberInputDataIndices = 11, + /* without report id */ + { + .Usage = HID_USAGE_GENERIC_JOYSTICK, + .UsagePage = HID_USAGE_PAGE_GENERIC, + .InputReportByteLength = 11, + .FeatureReportByteLength = 14, + .NumberLinkCollectionNodes = 7, + .NumberInputButtonCaps = 5, + .NumberInputValueCaps = 4, + .NumberInputDataIndices = 32, + .NumberFeatureButtonCaps = 1, + .NumberFeatureValueCaps = 5, + .NumberFeatureDataIndices = 7, + }, + /* with report id */ + { + .Usage = HID_USAGE_GENERIC_JOYSTICK, + .UsagePage = HID_USAGE_PAGE_GENERIC, + .InputReportByteLength = 10, + .FeatureReportByteLength = 13, + .NumberLinkCollectionNodes = 7, + .NumberInputButtonCaps = 5, + .NumberInputValueCaps = 4, + .NumberInputDataIndices = 32, + .NumberFeatureButtonCaps = 1, + .NumberFeatureValueCaps = 5, + .NumberFeatureDataIndices = 7, + }, }; const HIDP_BUTTON_CAPS expect_button_caps[] = { @@ -1667,6 +1688,48 @@ static void test_hidp(HANDLE file, int report_id) .Range.DataIndexMin = 2, .Range.DataIndexMax = 9, }, + { + .UsagePage = HID_USAGE_PAGE_BUTTON, + .ReportID = report_id, + .BitField = 3, + .LinkCollection = 1, + .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, + .LinkUsagePage = HID_USAGE_PAGE_GENERIC, + .IsRange = TRUE, + .IsAbsolute = TRUE, + .Range.UsageMin = 0x18, + .Range.UsageMax = 0x1f, + .Range.DataIndexMin = 10, + .Range.DataIndexMax = 17, + }, + { + .UsagePage = HID_USAGE_PAGE_KEYBOARD, + .ReportID = report_id, + .BitField = 0x1fc, + .LinkCollection = 1, + .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, + .LinkUsagePage = HID_USAGE_PAGE_GENERIC, + .IsRange = TRUE, + .IsAbsolute = FALSE, + .Range.UsageMin = 0x8, + .Range.UsageMax = 0xf, + .Range.DataIndexMin = 18, + .Range.DataIndexMax = 25, + }, + { + .UsagePage = HID_USAGE_PAGE_BUTTON, + .ReportID = report_id, + .BitField = 2, + .LinkCollection = 1, + .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, + .LinkUsagePage = HID_USAGE_PAGE_GENERIC, + .IsRange = FALSE, + .IsAbsolute = TRUE, + .NotRange.Usage = 0x20, + .NotRange.Reserved1 = 0x20, + .NotRange.DataIndex = 26, + .NotRange.Reserved4 = 26, + }, }; const HIDP_VALUE_CAPS expect_value_caps[] = { @@ -1683,6 +1746,7 @@ static void test_hidp(HANDLE file, int report_id) .LogicalMin = -128, .LogicalMax = 127, .NotRange.Usage = HID_USAGE_GENERIC_Y, + .NotRange.Reserved1 = HID_USAGE_GENERIC_Y, }, { .UsagePage = HID_USAGE_PAGE_GENERIC, @@ -1697,7 +1761,25 @@ static void test_hidp(HANDLE file, int report_id) .LogicalMin = -128, .LogicalMax = 127, .NotRange.Usage = HID_USAGE_GENERIC_X, + .NotRange.Reserved1 = HID_USAGE_GENERIC_X, .NotRange.DataIndex = 1, + .NotRange.Reserved4 = 1, + }, + { + .UsagePage = HID_USAGE_PAGE_BUTTON, + .ReportID = report_id, + .BitField = 2, + .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, + .LinkUsagePage = HID_USAGE_PAGE_GENERIC, + .LinkCollection = 1, + .IsAbsolute = TRUE, + .ReportCount = 1, + .LogicalMax = 1, + .IsRange = TRUE, + .Range.UsageMin = 0x21, + .Range.UsageMax = 0x22, + .Range.DataIndexMin = 27, + .Range.DataIndexMax = 28, }, { .UsagePage = HID_USAGE_PAGE_GENERIC, @@ -1711,9 +1793,10 @@ static void test_hidp(HANDLE file, int report_id) .ReportCount = 2, .LogicalMin = 1, .LogicalMax = 8, - .PhysicalMax = 8, .NotRange.Usage = HID_USAGE_GENERIC_HATSWITCH, - .NotRange.DataIndex = 10, + .NotRange.Reserved1 = HID_USAGE_GENERIC_HATSWITCH, + .NotRange.DataIndex = 29, + .NotRange.Reserved4 = 29, }, }; static const HIDP_LINK_COLLECTION_NODE expect_collections[] = @@ -1722,8 +1805,8 @@ static void test_hidp(HANDLE file, int report_id) .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, .LinkUsagePage = HID_USAGE_PAGE_GENERIC, .CollectionType = 1, - .NumberOfChildren = 1, - .FirstChild = 1, + .NumberOfChildren = 4, + .FirstChild = 6, }, { .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, @@ -1752,7 +1835,25 @@ static void test_hidp(HANDLE file, int report_id) ok(status == HIDP_STATUS_INVALID_PREPARSED_DATA, "HidP_GetCaps returned %#x\n", status); status = HidP_GetCaps(preparsed_data, &caps); ok(status == HIDP_STATUS_SUCCESS, "HidP_GetCaps returned %#x\n", status); - check_hidp_caps(&caps, &expect_hidp_caps); + check_member(caps, expect_hidp_caps[report_id], "%04x", Usage); + check_member(caps, expect_hidp_caps[report_id], "%04x", UsagePage); + check_member(caps, expect_hidp_caps[report_id], "%d", InputReportByteLength); + check_member(caps, expect_hidp_caps[report_id], "%d", OutputReportByteLength); + check_member(caps, expect_hidp_caps[report_id], "%d", FeatureReportByteLength); + check_member(caps, expect_hidp_caps[report_id], "%d", NumberLinkCollectionNodes); + todo_wine + check_member(caps, expect_hidp_caps[report_id], "%d", NumberInputButtonCaps); + todo_wine + check_member(caps, expect_hidp_caps[report_id], "%d", NumberInputValueCaps); + todo_wine + check_member(caps, expect_hidp_caps[report_id], "%d", NumberInputDataIndices); + check_member(caps, expect_hidp_caps[report_id], "%d", NumberOutputButtonCaps); + check_member(caps, expect_hidp_caps[report_id], "%d", NumberOutputValueCaps); + check_member(caps, expect_hidp_caps[report_id], "%d", NumberOutputDataIndices); + check_member(caps, expect_hidp_caps[report_id], "%d", NumberFeatureButtonCaps); + check_member(caps, expect_hidp_caps[report_id], "%d", NumberFeatureValueCaps); + todo_wine + check_member(caps, expect_hidp_caps[report_id], "%d", NumberFeatureDataIndices);
collection_count = 0; status = HidP_GetLinkCollectionNodes(collections, &collection_count, preparsed_data); @@ -1771,7 +1872,16 @@ static void test_hidp(HANDLE file, int report_id) for (i = 0; i < ARRAY_SIZE(expect_collections); ++i) { winetest_push_context("collections[%d]", i); - check_hidp_link_collection_node(collections + i, expect_collections + i); + check_member(collections[i], expect_collections[i], "%04x", LinkUsage); + check_member(collections[i], expect_collections[i], "%04x", LinkUsagePage); + check_member(collections[i], expect_collections[i], "%d", Parent); + check_member(collections[i], expect_collections[i], "%d", NumberOfChildren); + todo_wine_if(i == 1) + check_member(collections[i], expect_collections[i], "%d", NextSibling); + todo_wine_if(i == 0) + check_member(collections[i], expect_collections[i], "%d", FirstChild); + check_member(collections[i], expect_collections[i], "%d", CollectionType); + check_member(collections[i], expect_collections[i], "%d", IsAlias); winetest_pop_context(); }
@@ -1791,6 +1901,7 @@ static void test_hidp(HANDLE file, int report_id) count = ARRAY_SIZE(button_caps); status = HidP_GetButtonCaps(HidP_Input, button_caps, &count, (PHIDP_PREPARSED_DATA)buffer); ok(status == HIDP_STATUS_INVALID_PREPARSED_DATA, "HidP_GetButtonCaps returned %#x\n", status); + memset(button_caps, 0, sizeof(button_caps)); status = HidP_GetButtonCaps(HidP_Input, button_caps, &count, preparsed_data); ok(status == HIDP_STATUS_SUCCESS, "HidP_GetButtonCaps returned %#x\n", status); ok(count == caps.NumberInputButtonCaps, "HidP_GetButtonCaps returned count %d, expected %d\n", @@ -1799,25 +1910,36 @@ static void test_hidp(HANDLE file, int report_id) for (i = 0; i < ARRAY_SIZE(expect_button_caps); ++i) { winetest_push_context("button_caps[%d]", i); + todo_wine_if(i >= 2) check_member(button_caps[i], expect_button_caps[i], "%04x", UsagePage); + todo_wine_if(i >= 2 && report_id) check_member(button_caps[i], expect_button_caps[i], "%d", ReportID); check_member(button_caps[i], expect_button_caps[i], "%d", IsAlias); todo_wine check_member(button_caps[i], expect_button_caps[i], "%d", BitField); + todo_wine_if(i >= 2) check_member(button_caps[i], expect_button_caps[i], "%d", LinkCollection); + todo_wine_if(i >= 3) check_member(button_caps[i], expect_button_caps[i], "%04x", LinkUsage); + todo_wine_if(i >= 3) check_member(button_caps[i], expect_button_caps[i], "%04x", LinkUsagePage); + todo_wine_if(i == 1) check_member(button_caps[i], expect_button_caps[i], "%d", IsRange); check_member(button_caps[i], expect_button_caps[i], "%d", IsStringRange); check_member(button_caps[i], expect_button_caps[i], "%d", IsDesignatorRange); + todo_wine_if(i >= 2) check_member(button_caps[i], expect_button_caps[i], "%d", IsAbsolute); + todo_wine_if(i >= 1) check_member(button_caps[i], expect_button_caps[i], "%04x", Range.UsageMin); + todo_wine_if(i >= 1) check_member(button_caps[i], expect_button_caps[i], "%04x", Range.UsageMax); check_member(button_caps[i], expect_button_caps[i], "%d", Range.StringMin); check_member(button_caps[i], expect_button_caps[i], "%d", Range.StringMax); check_member(button_caps[i], expect_button_caps[i], "%d", Range.DesignatorMin); check_member(button_caps[i], expect_button_caps[i], "%d", Range.DesignatorMax); + todo_wine_if(i >= 1) check_member(button_caps[i], expect_button_caps[i], "%d", Range.DataIndexMin); + todo_wine_if(i >= 1) check_member(button_caps[i], expect_button_caps[i], "%d", Range.DataIndexMax); winetest_pop_context(); } @@ -1891,6 +2013,7 @@ static void test_hidp(HANDLE file, int report_id) for (i = 0; i < ARRAY_SIZE(expect_value_caps); ++i) { winetest_push_context("value_caps[%d]", i); + todo_wine_if(i == 3) check_member(value_caps[i], expect_value_caps[i], "%04x", UsagePage); check_member(value_caps[i], expect_value_caps[i], "%d", ReportID); check_member(value_caps[i], expect_value_caps[i], "%d", IsAlias); @@ -1899,28 +2022,42 @@ static void test_hidp(HANDLE file, int report_id) check_member(value_caps[i], expect_value_caps[i], "%d", LinkCollection); check_member(value_caps[i], expect_value_caps[i], "%04x", LinkUsage); check_member(value_caps[i], expect_value_caps[i], "%04x", LinkUsagePage); + todo_wine_if(i == 3) check_member(value_caps[i], expect_value_caps[i], "%d", IsRange); check_member(value_caps[i], expect_value_caps[i], "%d", IsStringRange); check_member(value_caps[i], expect_value_caps[i], "%d", IsDesignatorRange); + todo_wine_if(i == 2) check_member(value_caps[i], expect_value_caps[i], "%d", IsAbsolute); + todo_wine_if(i == 2) check_member(value_caps[i], expect_value_caps[i], "%d", HasNull); + todo_wine_if(i >= 2) check_member(value_caps[i], expect_value_caps[i], "%d", BitSize); + todo_wine_if(i == 2) check_member(value_caps[i], expect_value_caps[i], "%d", ReportCount); check_member(value_caps[i], expect_value_caps[i], "%d", UnitsExp); check_member(value_caps[i], expect_value_caps[i], "%d", Units); + todo_wine_if(i >= 3) check_member(value_caps[i], expect_value_caps[i], "%d", LogicalMin); + todo_wine_if(i >= 2) check_member(value_caps[i], expect_value_caps[i], "%d", LogicalMax); check_member(value_caps[i], expect_value_caps[i], "%d", PhysicalMin); check_member(value_caps[i], expect_value_caps[i], "%d", PhysicalMax); - todo_wine_if(i != 2) - check_member(value_caps[i], expect_value_caps[i], "%04x", NotRange.Usage); - check_member(value_caps[i], expect_value_caps[i], "%d", NotRange.StringIndex); - check_member(value_caps[i], expect_value_caps[i], "%d", NotRange.DesignatorIndex); - check_member(value_caps[i], expect_value_caps[i], "%d", NotRange.DataIndex); + todo_wine + check_member(value_caps[i], expect_value_caps[i], "%04x", Range.UsageMin); + todo_wine + check_member(value_caps[i], expect_value_caps[i], "%04x", Range.UsageMax); + check_member(value_caps[i], expect_value_caps[i], "%d", Range.StringMin); + check_member(value_caps[i], expect_value_caps[i], "%d", Range.StringMax); + check_member(value_caps[i], expect_value_caps[i], "%d", Range.DesignatorMin); + check_member(value_caps[i], expect_value_caps[i], "%d", Range.DesignatorMax); + todo_wine_if(i >= 2) + check_member(value_caps[i], expect_value_caps[i], "%d", Range.DataIndexMin); + todo_wine_if(i >= 2) + check_member(value_caps[i], expect_value_caps[i], "%d", Range.DataIndexMax); winetest_pop_context(); }
- count = ARRAY_SIZE(value_caps) - 3; + count = ARRAY_SIZE(value_caps) - 4; status = HidP_GetSpecificValueCaps(HidP_Output, 0, 0, 0, value_caps, &count, preparsed_data); todo_wine ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetSpecificValueCaps returned %#x\n", status); @@ -1933,24 +2070,61 @@ static void test_hidp(HANDLE file, int report_id) todo_wine ok(count == caps.NumberInputValueCaps, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count, caps.NumberInputValueCaps); - count = ARRAY_SIZE(value_caps) - 3; - status = HidP_GetSpecificValueCaps(HidP_Input, 0, 0, 0, value_caps + 3, &count, (PHIDP_PREPARSED_DATA)buffer); + count = ARRAY_SIZE(value_caps) - 4; + status = HidP_GetSpecificValueCaps(HidP_Input, 0, 0, 0, value_caps + 4, &count, (PHIDP_PREPARSED_DATA)buffer); ok(status == HIDP_STATUS_INVALID_PREPARSED_DATA, "HidP_GetSpecificValueCaps returned %#x\n", status);
- status = HidP_GetSpecificValueCaps(HidP_Input, 0, 0, 0, value_caps + 3, &count, preparsed_data); + status = HidP_GetSpecificValueCaps(HidP_Input, 0, 0, 0, value_caps + 4, &count, preparsed_data); ok(status == HIDP_STATUS_SUCCESS, "HidP_GetSpecificValueCaps returned %#x\n", status); ok(count == caps.NumberInputValueCaps, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count, caps.NumberInputValueCaps); - check_hidp_value_caps(&value_caps[3], &value_caps[0]); - check_hidp_value_caps(&value_caps[4], &value_caps[1]); - check_hidp_value_caps(&value_caps[5], &value_caps[2]); + check_hidp_value_caps(&value_caps[4], &value_caps[0]); + check_hidp_value_caps(&value_caps[5], &value_caps[1]); + check_hidp_value_caps(&value_caps[6], &value_caps[2]); + check_hidp_value_caps(&value_caps[7], &value_caps[3]);
count = 1; status = HidP_GetSpecificValueCaps(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_HATSWITCH, - value_caps + 3, &count, preparsed_data); + value_caps + 4, &count, preparsed_data); ok(status == HIDP_STATUS_SUCCESS, "HidP_GetSpecificValueCaps returned %#x\n", status); ok(count == 1, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count, 1); - check_hidp_value_caps(&value_caps[3], &value_caps[2]); + + todo_wine + check_member(value_caps[4], value_caps[3], "%04x", UsagePage); + check_member(value_caps[4], value_caps[3], "%d", ReportID); + check_member(value_caps[4], value_caps[3], "%d", IsAlias); + check_member(value_caps[4], value_caps[3], "%d", BitField); + check_member(value_caps[4], value_caps[3], "%d", LinkCollection); + check_member(value_caps[4], value_caps[3], "%04x", LinkUsage); + check_member(value_caps[4], value_caps[3], "%04x", LinkUsagePage); + todo_wine + check_member(value_caps[4], value_caps[3], "%d", IsRange); + check_member(value_caps[4], value_caps[3], "%d", IsStringRange); + check_member(value_caps[4], value_caps[3], "%d", IsDesignatorRange); + check_member(value_caps[4], value_caps[3], "%d", IsAbsolute); + check_member(value_caps[4], value_caps[3], "%d", HasNull); + todo_wine + check_member(value_caps[4], value_caps[3], "%d", BitSize); + check_member(value_caps[4], value_caps[3], "%d", ReportCount); + check_member(value_caps[4], value_caps[3], "%d", UnitsExp); + check_member(value_caps[4], value_caps[3], "%d", Units); + todo_wine + check_member(value_caps[4], value_caps[3], "%d", LogicalMin); + todo_wine + check_member(value_caps[4], value_caps[3], "%d", LogicalMax); + check_member(value_caps[4], value_caps[3], "%d", PhysicalMin); + check_member(value_caps[4], value_caps[3], "%d", PhysicalMax); + todo_wine + check_member(value_caps[4], value_caps[3], "%04x", Range.UsageMin); + check_member(value_caps[4], value_caps[3], "%04x", Range.UsageMax); + check_member(value_caps[4], value_caps[3], "%d", Range.StringMin); + check_member(value_caps[4], value_caps[3], "%d", Range.StringMax); + check_member(value_caps[4], value_caps[3], "%d", Range.DesignatorMin); + check_member(value_caps[4], value_caps[3], "%d", Range.DesignatorMax); + todo_wine + check_member(value_caps[4], value_caps[3], "%d", Range.DataIndexMin); + todo_wine + check_member(value_caps[4], value_caps[3], "%d", Range.DataIndexMax);
count = 0xdead; status = HidP_GetSpecificValueCaps(HidP_Input, 0xfffe, 0, 0, value_caps, &count, preparsed_data); @@ -1991,6 +2165,22 @@ static void test_hidp(HANDLE file, int report_id) todo_wine_if(report_id) ok(!memcmp(buffer, report, sizeof(buffer)), "unexpected report data\n");
+ memset(report, 0xcd, sizeof(report)); + status = HidP_InitializeReportForID(HidP_Feature, 3, preparsed_data, report, caps.FeatureReportByteLength); + 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_Feature, report_id, preparsed_data, report, caps.FeatureReportByteLength); + 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.FeatureReportByteLength); + 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); } diff --git a/dlls/ntoskrnl.exe/tests/psh_hid_macros.h b/dlls/ntoskrnl.exe/tests/psh_hid_macros.h index 4623af20598..ad5cfa34fea 100644 --- a/dlls/ntoskrnl.exe/tests/psh_hid_macros.h +++ b/dlls/ntoskrnl.exe/tests/psh_hid_macros.h @@ -47,7 +47,7 @@ #define UsageSwitch 0x05 #define UsageModifier 0x06
-#define SHORT_ITEM_0(tag,type) (((tag)<<4)|((type)<<2)|0) +#define SHORT_ITEM_0(tag,type,data) (((tag)<<4)|((type)<<2)|0) #define SHORT_ITEM_1(tag,type,data) (((tag)<<4)|((type)<<2)|1),((data)&0xff) #define SHORT_ITEM_2(tag,type,data) (((tag)<<4)|((type)<<2)|2),((data)&0xff),(((data)>>8)&0xff) #define SHORT_ITEM_4(tag,type,data) (((tag)<<4)|((type)<<2)|3),((data)&0xff),(((data)>>8)&0xff),(((data)>>16)&0xff),(((data)>>24)&0xff) @@ -58,7 +58,7 @@ #define OUTPUT(n,data) SHORT_ITEM_##n(0x9,0,data) #define FEATURE(n,data) SHORT_ITEM_##n(0xb,0,data) #define COLLECTION(n,data) SHORT_ITEM_##n(0xa,0,data) -#define END_COLLECTION SHORT_ITEM_0(0xc,0) +#define END_COLLECTION SHORT_ITEM_0(0xc,0,0)
#define USAGE_PAGE(n,data) SHORT_ITEM_##n(0x0,1,data) #define LOGICAL_MINIMUM(n,data) SHORT_ITEM_##n(0x1,1,data) diff --git a/dlls/winebus.sys/psh_hid_macros.h b/dlls/winebus.sys/psh_hid_macros.h index 4623af20598..ad5cfa34fea 100644 --- a/dlls/winebus.sys/psh_hid_macros.h +++ b/dlls/winebus.sys/psh_hid_macros.h @@ -47,7 +47,7 @@ #define UsageSwitch 0x05 #define UsageModifier 0x06
-#define SHORT_ITEM_0(tag,type) (((tag)<<4)|((type)<<2)|0) +#define SHORT_ITEM_0(tag,type,data) (((tag)<<4)|((type)<<2)|0) #define SHORT_ITEM_1(tag,type,data) (((tag)<<4)|((type)<<2)|1),((data)&0xff) #define SHORT_ITEM_2(tag,type,data) (((tag)<<4)|((type)<<2)|2),((data)&0xff),(((data)>>8)&0xff) #define SHORT_ITEM_4(tag,type,data) (((tag)<<4)|((type)<<2)|3),((data)&0xff),(((data)>>8)&0xff),(((data)>>16)&0xff),(((data)>>24)&0xff) @@ -58,7 +58,7 @@ #define OUTPUT(n,data) SHORT_ITEM_##n(0x9,0,data) #define FEATURE(n,data) SHORT_ITEM_##n(0xb,0,data) #define COLLECTION(n,data) SHORT_ITEM_##n(0xa,0,data) -#define END_COLLECTION SHORT_ITEM_0(0xc,0) +#define END_COLLECTION SHORT_ITEM_0(0xc,0,0)
#define USAGE_PAGE(n,data) SHORT_ITEM_##n(0x0,1,data) #define LOGICAL_MINIMUM(n,data) SHORT_ITEM_##n(0x1,1,data)