Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/hid/hidp.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/dlls/hid/hidp.c b/dlls/hid/hidp.c index a7003717a21..2933c2ff7ef 100644 --- a/dlls/hid/hidp.c +++ b/dlls/hid/hidp.c @@ -1001,6 +1001,9 @@ NTSTATUS WINAPI HidP_GetLinkCollectionNodes(HIDP_LINK_COLLECTION_NODE *LinkColle
TRACE("(%p, %p, %p)\n", LinkCollectionNode, LinkCollectionNodeLength, PreparsedData);
+ if (data->magic != HID_MAGIC) + return HIDP_STATUS_INVALID_PREPARSED_DATA; + if (*LinkCollectionNodeLength < data->caps.NumberLinkCollectionNodes) return HIDP_STATUS_BUFFER_TOO_SMALL;
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntoskrnl.exe/tests/Makefile.in | 2 +- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 218 ++++++++++++++++++++++++++++ 2 files changed, 219 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/tests/Makefile.in b/dlls/ntoskrnl.exe/tests/Makefile.in index 8c2115984c5..863fad30f63 100644 --- a/dlls/ntoskrnl.exe/tests/Makefile.in +++ b/dlls/ntoskrnl.exe/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = ntoskrnl.exe -IMPORTS = advapi32 crypt32 newdev setupapi user32 wintrust ws2_32 +IMPORTS = advapi32 crypt32 newdev setupapi user32 wintrust ws2_32 hid
driver_IMPORTS = winecrt0 ntoskrnl driver_EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -Wl,--subsystem,native diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index 5e2520a3e12..b61d9b33a6f 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -40,6 +40,8 @@ #include "initguid.h" #include "devguid.h" #include "ddk/hidclass.h" +#include "ddk/hidsdi.h" +#include "ddk/hidpi.h" #include "wine/test.h" #include "wine/heap.h" #include "wine/mssign.h" @@ -1496,6 +1498,220 @@ static void test_pnp_driver(struct testsign_context *ctx) SetCurrentDirectoryA(cwd); }
+#define check_member_(file, line, val, exp, fmt, member) \ + ok_(file, line)((val).member == (exp).member, \ + "got " #member " " fmt ", expected " fmt "\n", \ + (val).member, (exp).member) +#define check_member(val, exp, fmt, member) check_member_(__FILE__, __LINE__, val, exp, fmt, member) + +#define check_hidp_caps(a, b) check_hidp_caps_(__LINE__, a, b) +static inline void check_hidp_caps_(int line, HIDP_CAPS *caps, const HIDP_CAPS *exp) +{ + check_member_(__FILE__, line, *caps, *exp, "%04x", Usage); + check_member_(__FILE__, line, *caps, *exp, "%04x", UsagePage); + check_member_(__FILE__, line, *caps, *exp, "%d", InputReportByteLength); + check_member_(__FILE__, line, *caps, *exp, "%d", OutputReportByteLength); + check_member_(__FILE__, line, *caps, *exp, "%d", FeatureReportByteLength); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberLinkCollectionNodes); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberInputButtonCaps); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberInputValueCaps); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberInputDataIndices); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberOutputButtonCaps); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberOutputValueCaps); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberOutputDataIndices); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberFeatureButtonCaps); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberFeatureValueCaps); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberFeatureDataIndices); +} + +#define check_hidp_button_caps(a, b) check_hidp_button_caps_(__LINE__, a, b) +static inline void check_hidp_button_caps_(int line, HIDP_BUTTON_CAPS *caps, const HIDP_BUTTON_CAPS *exp) +{ + check_member_(__FILE__, line, *caps, *exp, "%04x", UsagePage); + check_member_(__FILE__, line, *caps, *exp, "%d", ReportID); + check_member_(__FILE__, line, *caps, *exp, "%d", IsAlias); + check_member_(__FILE__, line, *caps, *exp, "%d", BitField); + check_member_(__FILE__, line, *caps, *exp, "%d", LinkCollection); + check_member_(__FILE__, line, *caps, *exp, "%04x", LinkUsage); + check_member_(__FILE__, line, *caps, *exp, "%04x", LinkUsagePage); + check_member_(__FILE__, line, *caps, *exp, "%d", IsRange); + check_member_(__FILE__, line, *caps, *exp, "%d", IsStringRange); + check_member_(__FILE__, line, *caps, *exp, "%d", IsDesignatorRange); + check_member_(__FILE__, line, *caps, *exp, "%d", IsAbsolute); + + if (!caps->IsRange && !exp->IsRange) + { + check_member_(__FILE__, line, *caps, *exp, "%04x", NotRange.Usage); + check_member_(__FILE__, line, *caps, *exp, "%d", NotRange.DataIndex); + } + else if (caps->IsRange && exp->IsRange) + { + check_member_(__FILE__, line, *caps, *exp, "%04x", Range.UsageMin); + check_member_(__FILE__, line, *caps, *exp, "%04x", Range.UsageMax); + check_member_(__FILE__, line, *caps, *exp, "%d", Range.DataIndexMin); + check_member_(__FILE__, line, *caps, *exp, "%d", Range.DataIndexMax); + } + + if (!caps->IsRange && !exp->IsRange) + check_member_(__FILE__, line, *caps, *exp, "%d", NotRange.StringIndex); + else if (caps->IsStringRange && exp->IsStringRange) + { + check_member_(__FILE__, line, *caps, *exp, "%d", Range.StringMin); + check_member_(__FILE__, line, *caps, *exp, "%d", Range.StringMax); + } + + if (!caps->IsDesignatorRange && !exp->IsDesignatorRange) + check_member_(__FILE__, line, *caps, *exp, "%d", NotRange.DesignatorIndex); + else if (caps->IsDesignatorRange && exp->IsDesignatorRange) + { + check_member_(__FILE__, line, *caps, *exp, "%d", Range.DesignatorMin); + check_member_(__FILE__, line, *caps, *exp, "%d", Range.DesignatorMax); + } +} + +static void test_hidp(HANDLE file) +{ + static const HIDP_CAPS expect_hidp_caps = + { + .Usage = HID_USAGE_GENERIC_JOYSTICK, + .UsagePage = HID_USAGE_PAGE_GENERIC, + .InputReportByteLength = 5, + .NumberLinkCollectionNodes = 1, + .NumberInputButtonCaps = 1, + .NumberInputValueCaps = 3, + .NumberInputDataIndices = 11, + }; + static const HIDP_BUTTON_CAPS expect_button_caps[] = + { + { + .UsagePage = HID_USAGE_PAGE_BUTTON, + .BitField = 2, + .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, + .LinkUsagePage = HID_USAGE_PAGE_GENERIC, + .IsRange = TRUE, + .IsAbsolute = TRUE, + .Range.UsageMin = 1, + .Range.UsageMax = 8, + .Range.DataIndexMin = 2, + .Range.DataIndexMax = 9, + }, + }; + + PHIDP_PREPARSED_DATA preparsed_data; + HIDP_BUTTON_CAPS button_caps[16]; + char buffer[200]; + NTSTATUS status; + HIDP_CAPS caps; + unsigned int i; + USHORT count; + BOOL ret; + + ret = HidD_GetPreparsedData(file, &preparsed_data); + ok(ret, "HidD_GetPreparsedData failed with error %u\n", GetLastError()); + + memset(buffer, 0, sizeof(buffer)); + status = HidP_GetCaps((PHIDP_PREPARSED_DATA)buffer, &caps); + 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); + + count = ARRAY_SIZE(button_caps); + status = HidP_GetButtonCaps(HidP_Output, button_caps, &count, preparsed_data); + todo_wine + ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetButtonCaps returned %#x\n", status); + status = HidP_GetButtonCaps(HidP_Feature + 1, button_caps, &count, preparsed_data); + ok(status == HIDP_STATUS_INVALID_REPORT_TYPE, "HidP_GetButtonCaps returned %#x\n", status); + count = 0; + status = HidP_GetButtonCaps(HidP_Input, button_caps, &count, preparsed_data); + todo_wine + ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetButtonCaps returned %#x\n", status); + todo_wine + ok(count == caps.NumberInputButtonCaps, "HidP_GetButtonCaps returned count %d, expected %d\n", + count, caps.NumberInputButtonCaps); + 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); + 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", + count, caps.NumberInputButtonCaps); + + for (i = 0; i < ARRAY_SIZE(expect_button_caps); ++i) + { + winetest_push_context("button_caps[%d]", i); + check_member(button_caps[i], expect_button_caps[i], "%04x", UsagePage); + 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); + check_member(button_caps[i], expect_button_caps[i], "%d", LinkCollection); + check_member(button_caps[i], expect_button_caps[i], "%04x", LinkUsage); + check_member(button_caps[i], expect_button_caps[i], "%04x", LinkUsagePage); + 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); + check_member(button_caps[i], expect_button_caps[i], "%d", IsAbsolute); + check_member(button_caps[i], expect_button_caps[i], "%04x", Range.UsageMin); + 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); + check_member(button_caps[i], expect_button_caps[i], "%d", Range.DataIndexMin); + check_member(button_caps[i], expect_button_caps[i], "%d", Range.DataIndexMax); + winetest_pop_context(); + } + + count = ARRAY_SIZE(button_caps) - 1; + status = HidP_GetSpecificButtonCaps(HidP_Output, 0, 0, 0, button_caps, &count, preparsed_data); + todo_wine + ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetSpecificButtonCaps returned %#x\n", status); + status = HidP_GetSpecificButtonCaps(HidP_Feature + 1, 0, 0, 0, button_caps, &count, preparsed_data); + ok(status == HIDP_STATUS_INVALID_REPORT_TYPE, "HidP_GetSpecificButtonCaps returned %#x\n", status); + count = 0; + status = HidP_GetSpecificButtonCaps(HidP_Input, 0, 0, 0, button_caps, &count, preparsed_data); + todo_wine + ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetSpecificButtonCaps returned %#x\n", status); + todo_wine + ok(count == caps.NumberInputButtonCaps, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", + count, caps.NumberInputButtonCaps); + count = ARRAY_SIZE(button_caps) - 1; + status = HidP_GetSpecificButtonCaps(HidP_Input, 0, 0, 0, button_caps, &count, (PHIDP_PREPARSED_DATA)buffer); + ok(status == HIDP_STATUS_INVALID_PREPARSED_DATA, "HidP_GetSpecificButtonCaps returned %#x\n", status); + + status = HidP_GetSpecificButtonCaps(HidP_Input, 0, 0, 0, button_caps + 1, &count, preparsed_data); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetSpecificButtonCaps returned %#x\n", status); + ok(count == caps.NumberInputButtonCaps, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", + count, caps.NumberInputButtonCaps); + check_hidp_button_caps(&button_caps[1], &button_caps[0]); + + status = HidP_GetSpecificButtonCaps(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, 5, button_caps + 1, + &count, preparsed_data); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetSpecificButtonCaps returned %#x\n", status); + ok(count == 1, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count, 1); + check_hidp_button_caps(&button_caps[1], &button_caps[0]); + + count = 0xbeef; + status = HidP_GetSpecificButtonCaps(HidP_Input, 0xfffe, 0, 0, button_caps, &count, preparsed_data); + todo_wine + ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetSpecificButtonCaps returned %#x\n", status); + ok(count == 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count, 0); + count = 0xbeef; + status = HidP_GetSpecificButtonCaps(HidP_Input, 0, 0xfffe, 0, button_caps, &count, preparsed_data); + todo_wine + ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetSpecificButtonCaps returned %#x\n", status); + ok(count == 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count, 0); + count = 0xbeef; + status = HidP_GetSpecificButtonCaps(HidP_Input, 0, 0, 0xfffe, button_caps, &count, preparsed_data); + todo_wine + ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetSpecificButtonCaps returned %#x\n", status); + ok(count == 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count, 0); + + HidD_FreePreparsedData(preparsed_data); + CloseHandle(file); +} + static void test_hid_device(void) { char buffer[200]; @@ -1541,6 +1757,8 @@ 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); + CloseHandle(file);
RtlInitUnicodeString(&string, L"\??\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}");
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=92189
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
ntoskrnl.exe: ntoskrnl.c:1236: Test failed: got 0 bus arrival messages ntoskrnl.c:1252: Test failed: got 0 bus arrival messages
=== w7u_el (32 bit report) ===
ntoskrnl.exe: driver.c:759: Test failed: got 0
=== w864 (64 bit report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl crashed (c0000374)
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 199 +++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+)
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index b61d9b33a6f..c931f5a02d0 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -1569,6 +1569,61 @@ static inline void check_hidp_button_caps_(int line, HIDP_BUTTON_CAPS *caps, con } }
+#define check_hidp_value_caps(a, b) check_hidp_value_caps_(__LINE__, a, b) +static inline void check_hidp_value_caps_(int line, HIDP_VALUE_CAPS *caps, const HIDP_VALUE_CAPS *exp) +{ + check_member_(__FILE__, line, *caps, *exp, "%04x", UsagePage); + check_member_(__FILE__, line, *caps, *exp, "%d", ReportID); + check_member_(__FILE__, line, *caps, *exp, "%d", IsAlias); + check_member_(__FILE__, line, *caps, *exp, "%d", BitField); + check_member_(__FILE__, line, *caps, *exp, "%d", LinkCollection); + check_member_(__FILE__, line, *caps, *exp, "%d", LinkUsage); + check_member_(__FILE__, line, *caps, *exp, "%d", LinkUsagePage); + check_member_(__FILE__, line, *caps, *exp, "%d", IsRange); + check_member_(__FILE__, line, *caps, *exp, "%d", IsStringRange); + check_member_(__FILE__, line, *caps, *exp, "%d", IsDesignatorRange); + check_member_(__FILE__, line, *caps, *exp, "%d", IsAbsolute); + + check_member_(__FILE__, line, *caps, *exp, "%d", HasNull); + check_member_(__FILE__, line, *caps, *exp, "%d", BitSize); + check_member_(__FILE__, line, *caps, *exp, "%d", ReportCount); + check_member_(__FILE__, line, *caps, *exp, "%d", UnitsExp); + check_member_(__FILE__, line, *caps, *exp, "%d", Units); + check_member_(__FILE__, line, *caps, *exp, "%d", LogicalMin); + check_member_(__FILE__, line, *caps, *exp, "%d", LogicalMax); + check_member_(__FILE__, line, *caps, *exp, "%d", PhysicalMin); + check_member_(__FILE__, line, *caps, *exp, "%d", PhysicalMax); + + if (!caps->IsRange && !exp->IsRange) + { + check_member_(__FILE__, line, *caps, *exp, "%04x", NotRange.Usage); + check_member_(__FILE__, line, *caps, *exp, "%d", NotRange.DataIndex); + } + else if (caps->IsRange && exp->IsRange) + { + check_member_(__FILE__, line, *caps, *exp, "%04x", Range.UsageMin); + check_member_(__FILE__, line, *caps, *exp, "%04x", Range.UsageMax); + check_member_(__FILE__, line, *caps, *exp, "%d", Range.DataIndexMin); + check_member_(__FILE__, line, *caps, *exp, "%d", Range.DataIndexMax); + } + + if (!caps->IsRange && !exp->IsRange) + check_member_(__FILE__, line, *caps, *exp, "%d", NotRange.StringIndex); + else if (caps->IsStringRange && exp->IsStringRange) + { + check_member_(__FILE__, line, *caps, *exp, "%d", Range.StringMin); + check_member_(__FILE__, line, *caps, *exp, "%d", Range.StringMax); + } + + if (!caps->IsDesignatorRange && !exp->IsDesignatorRange) + check_member_(__FILE__, line, *caps, *exp, "%d", NotRange.DesignatorIndex); + else if (caps->IsDesignatorRange && exp->IsDesignatorRange) + { + check_member_(__FILE__, line, *caps, *exp, "%d", Range.DesignatorMin); + check_member_(__FILE__, line, *caps, *exp, "%d", Range.DesignatorMax); + } +} + static void test_hidp(HANDLE file) { static const HIDP_CAPS expect_hidp_caps = @@ -1596,9 +1651,52 @@ static void test_hidp(HANDLE file) .Range.DataIndexMax = 9, }, }; + static const HIDP_VALUE_CAPS expect_value_caps[] = + { + { + .UsagePage = HID_USAGE_PAGE_GENERIC, + .BitField = 2, + .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, + .LinkUsagePage = HID_USAGE_PAGE_GENERIC, + .IsAbsolute = TRUE, + .BitSize = 8, + .ReportCount = 1, + .LogicalMin = -128, + .LogicalMax = 127, + .NotRange.Usage = HID_USAGE_GENERIC_Y, + }, + { + .UsagePage = HID_USAGE_PAGE_GENERIC, + .BitField = 2, + .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, + .LinkUsagePage = HID_USAGE_PAGE_GENERIC, + .IsAbsolute = TRUE, + .BitSize = 8, + .ReportCount = 1, + .LogicalMin = -128, + .LogicalMax = 127, + .NotRange.Usage = HID_USAGE_GENERIC_X, + .NotRange.DataIndex = 1, + }, + { + .UsagePage = HID_USAGE_PAGE_GENERIC, + .BitField = 2, + .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, + .LinkUsagePage = HID_USAGE_PAGE_GENERIC, + .IsAbsolute = TRUE, + .BitSize = 4, + .ReportCount = 2, + .LogicalMin = 1, + .LogicalMax = 8, + .PhysicalMax = 8, + .NotRange.Usage = HID_USAGE_GENERIC_HATSWITCH, + .NotRange.DataIndex = 10, + }, + };
PHIDP_PREPARSED_DATA preparsed_data; HIDP_BUTTON_CAPS button_caps[16]; + HIDP_VALUE_CAPS value_caps[16]; char buffer[200]; NTSTATUS status; HIDP_CAPS caps; @@ -1708,6 +1806,107 @@ static void test_hidp(HANDLE file) ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetSpecificButtonCaps returned %#x\n", status); ok(count == 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count, 0);
+ count = ARRAY_SIZE(value_caps); + status = HidP_GetValueCaps(HidP_Output, value_caps, &count, preparsed_data); + todo_wine + ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetValueCaps returned %#x\n", status); + status = HidP_GetValueCaps(HidP_Feature + 1, value_caps, &count, preparsed_data); + ok(status == HIDP_STATUS_INVALID_REPORT_TYPE, "HidP_GetValueCaps returned %#x\n", status); + count = 0; + status = HidP_GetValueCaps(HidP_Input, value_caps, &count, preparsed_data); + todo_wine + ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetValueCaps returned %#x\n", status); + todo_wine + ok(count == caps.NumberInputValueCaps, "HidP_GetValueCaps returned count %d, expected %d\n", + count, caps.NumberInputValueCaps); + count = ARRAY_SIZE(value_caps); + status = HidP_GetValueCaps(HidP_Input, value_caps, &count, (PHIDP_PREPARSED_DATA)buffer); + ok(status == HIDP_STATUS_INVALID_PREPARSED_DATA, "HidP_GetValueCaps returned %#x\n", status); + status = HidP_GetValueCaps(HidP_Input, value_caps, &count, preparsed_data); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetValueCaps returned %#x\n", status); + ok(count == caps.NumberInputValueCaps, "HidP_GetValueCaps returned count %d, expected %d\n", + count, caps.NumberInputValueCaps); + + for (i = 0; i < ARRAY_SIZE(expect_value_caps); ++i) + { + winetest_push_context("value_caps[%d]", i); + 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); + todo_wine + check_member(value_caps[i], expect_value_caps[i], "%d", BitField); + 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); + 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); + check_member(value_caps[i], expect_value_caps[i], "%d", IsAbsolute); + check_member(value_caps[i], expect_value_caps[i], "%d", HasNull); + check_member(value_caps[i], expect_value_caps[i], "%d", BitSize); + 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); + check_member(value_caps[i], expect_value_caps[i], "%d", LogicalMin); + 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); + winetest_pop_context(); + } + + count = ARRAY_SIZE(value_caps) - 3; + 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); + status = HidP_GetSpecificValueCaps(HidP_Feature + 1, 0, 0, 0, value_caps, &count, preparsed_data); + ok(status == HIDP_STATUS_INVALID_REPORT_TYPE, "HidP_GetSpecificValueCaps returned %#x\n", status); + count = 0; + status = HidP_GetSpecificValueCaps(HidP_Input, 0, 0, 0, value_caps, &count, preparsed_data); + todo_wine + ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetSpecificValueCaps returned %#x\n", status); + 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); + 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); + 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]); + + count = 1; + status = HidP_GetSpecificValueCaps(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_HATSWITCH, + value_caps + 3, &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]); + + count = 0xdead; + status = HidP_GetSpecificValueCaps(HidP_Input, 0xfffe, 0, 0, value_caps, &count, preparsed_data); + todo_wine + ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetSpecificValueCaps returned %#x\n", status); + ok(count == 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count, 0); + count = 0xdead; + status = HidP_GetSpecificValueCaps(HidP_Input, 0, 0xfffe, 0, value_caps, &count, preparsed_data); + todo_wine + ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetSpecificValueCaps returned %#x\n", status); + ok(count == 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count, 0); + count = 0xdead; + status = HidP_GetSpecificValueCaps(HidP_Input, 0, 0, 0xfffe, value_caps, &count, preparsed_data); + todo_wine + ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetSpecificValueCaps returned %#x\n", status); + ok(count == 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count, 0); + HidD_FreePreparsedData(preparsed_data); CloseHandle(file); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=92190
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
ntoskrnl.exe: ntoskrnl.c:1236: Test failed: got 0 bus arrival messages ntoskrnl.c:1252: Test failed: got 0 bus arrival messages
=== w864 (64 bit report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl crashed (c0000374)
=== w1064_tsign (64 bit report) ===
ntoskrnl.exe: driver.c:272: Test failed: Got unexpected test_load_image_notify_count 0.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 45 ++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index c931f5a02d0..6a73493aa39 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -1524,6 +1524,20 @@ static inline void check_hidp_caps_(int line, HIDP_CAPS *caps, const HIDP_CAPS * check_member_(__FILE__, line, *caps, *exp, "%d", NumberFeatureDataIndices); }
+#define check_hidp_link_collection_node(a, b) check_hidp_link_collection_node_(__LINE__, a, b) +static inline void check_hidp_link_collection_node_(int line, HIDP_LINK_COLLECTION_NODE *node, + const HIDP_LINK_COLLECTION_NODE *exp) +{ + check_member_(__FILE__, line, *node, *exp, "%04x", LinkUsage); + check_member_(__FILE__, line, *node, *exp, "%04x", LinkUsagePage); + check_member_(__FILE__, line, *node, *exp, "%d", Parent); + check_member_(__FILE__, line, *node, *exp, "%d", NumberOfChildren); + check_member_(__FILE__, line, *node, *exp, "%d", NextSibling); + check_member_(__FILE__, line, *node, *exp, "%d", FirstChild); + check_member_(__FILE__, line, *node, *exp, "%d", CollectionType); + check_member_(__FILE__, line, *node, *exp, "%d", IsAlias); +} + #define check_hidp_button_caps(a, b) check_hidp_button_caps_(__LINE__, a, b) static inline void check_hidp_button_caps_(int line, HIDP_BUTTON_CAPS *caps, const HIDP_BUTTON_CAPS *exp) { @@ -1693,10 +1707,20 @@ static void test_hidp(HANDLE file) .NotRange.DataIndex = 10, }, }; + static const HIDP_LINK_COLLECTION_NODE expect_collections[] = + { + { + .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, + .LinkUsagePage = HID_USAGE_PAGE_GENERIC, + .CollectionType = 1, + }, + };
+ HIDP_LINK_COLLECTION_NODE collections[16]; PHIDP_PREPARSED_DATA preparsed_data; HIDP_BUTTON_CAPS button_caps[16]; HIDP_VALUE_CAPS value_caps[16]; + DWORD collection_count; char buffer[200]; NTSTATUS status; HIDP_CAPS caps; @@ -1714,6 +1738,27 @@ static void test_hidp(HANDLE file) ok(status == HIDP_STATUS_SUCCESS, "HidP_GetCaps returned %#x\n", status); check_hidp_caps(&caps, &expect_hidp_caps);
+ collection_count = 0; + status = HidP_GetLinkCollectionNodes(collections, &collection_count, preparsed_data); + ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetLinkCollectionNodes returned %#x\n", status); + todo_wine + ok(collection_count == caps.NumberLinkCollectionNodes, "got %d collection nodes, expected %d\n", + collection_count, caps.NumberLinkCollectionNodes); + collection_count = ARRAY_SIZE(collections); + status = HidP_GetLinkCollectionNodes(collections, &collection_count, (PHIDP_PREPARSED_DATA)buffer); + ok(status == HIDP_STATUS_INVALID_PREPARSED_DATA, "HidP_GetLinkCollectionNodes returned %#x\n", status); + status = HidP_GetLinkCollectionNodes(collections, &collection_count, preparsed_data); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetLinkCollectionNodes returned %#x\n", status); + ok(collection_count == caps.NumberLinkCollectionNodes, "got %d collection nodes, expected %d\n", + collection_count, caps.NumberLinkCollectionNodes); + + 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); + winetest_pop_context(); + } + count = ARRAY_SIZE(button_caps); status = HidP_GetButtonCaps(HidP_Output, button_caps, &count, preparsed_data); todo_wine
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=92191
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
ntoskrnl.exe: ntoskrnl.c:1236: Test failed: got 0 bus arrival messages ntoskrnl.c:1252: Test failed: got 0 bus arrival messages
=== debiant2 (32 bit German report) ===
ntoskrnl.exe: ntoskrnl: Timeout
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index 6a73493aa39..ff73e8eae18 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -1720,8 +1720,8 @@ static void test_hidp(HANDLE file) PHIDP_PREPARSED_DATA preparsed_data; HIDP_BUTTON_CAPS button_caps[16]; HIDP_VALUE_CAPS value_caps[16]; + char buffer[200], report[200]; DWORD collection_count; - char buffer[200]; NTSTATUS status; HIDP_CAPS caps; unsigned int i; @@ -1952,6 +1952,23 @@ static void test_hidp(HANDLE file) ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetSpecificValueCaps returned %#x\n", status); ok(count == 0, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count, 0);
+ status = HidP_InitializeReportForID(HidP_Input, 0, (PHIDP_PREPARSED_DATA)buffer, report, sizeof(report)); + ok(status == HIDP_STATUS_INVALID_PREPARSED_DATA, "HidP_InitializeReportForID returned %#x\n", status); + status = HidP_InitializeReportForID(HidP_Feature + 1, 0, preparsed_data, report, sizeof(report)); + ok(status == HIDP_STATUS_INVALID_REPORT_TYPE, "HidP_InitializeReportForID returned %#x\n", status); + status = HidP_InitializeReportForID(HidP_Input, 0, preparsed_data, report, sizeof(report)); + 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); + + memset(report, 0xcd, sizeof(report)); + status = HidP_InitializeReportForID(HidP_Input, 0, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_InitializeReportForID returned %#x\n", status); + + memset(buffer, 0xcd, sizeof(buffer)); + memset(buffer, 0, caps.InputReportByteLength); + ok(!memcmp(buffer, report, sizeof(buffer)), "unexpected report data\n"); + HidD_FreePreparsedData(preparsed_data); CloseHandle(file); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=92192
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
ntoskrnl.exe: ntoskrnl.c:1236: Test failed: got 0 bus arrival messages ntoskrnl.c:1252: Test failed: got 0 bus arrival messages
=== w864 (64 bit report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl crashed (c0000374)