Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
v3: Minor changes, drop the controversial test fixups, let's ignore the spurious failures for now.
Tweak the silent logic as requested, squeeze in a few more tests.
The spurious w864 crash doesn't seem to be related to the patches, it happens there from time to time when the driver tests aren't executed and is probably caused by some invalid cleanup.
FWIW, when I force start_driver code to fail on Wine in the same way it's failing on this machine, I also get a winedevice crash after the test has exited, on a call to PsGetCurrentProcessId() in winetest_cleanup. I have no idea if it's the same kind of thing, but it looks fishy.
dlls/ntoskrnl.exe/tests/driver_hid.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/tests/driver_hid.c b/dlls/ntoskrnl.exe/tests/driver_hid.c index 44ec1b09526..0f626e6866c 100644 --- a/dlls/ntoskrnl.exe/tests/driver_hid.c +++ b/dlls/ntoskrnl.exe/tests/driver_hid.c @@ -103,6 +103,7 @@ static const unsigned char report_descriptor[] =
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; const ULONG out_size = stack->Parameters.DeviceIoControl.OutputBufferLength; @@ -175,11 +176,15 @@ static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device, IRP *irp) }
case IOCTL_HID_READ_REPORT: + { + ULONG expected_size = 2; ok(!in_size, "got input size %u\n", in_size); - todo_wine ok(out_size == 2, "got output size %u\n", out_size); + if (!test_failed) todo_wine ok(out_size == expected_size, "got output size %u\n", out_size); + if (out_size != expected_size) test_failed = TRUE;
ret = STATUS_NOT_IMPLEMENTED; break; + }
case IOCTL_HID_GET_STRING: ok(!in_size, "got input size %u\n", in_size);
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntoskrnl.exe/tests/driver_hid.c | 28 ++++---- dlls/ntoskrnl.exe/tests/pop_hid_macros.h | 83 +++++++++++++++++++++++ dlls/ntoskrnl.exe/tests/psh_hid_macros.h | 85 ++++++++++++++++++++++++ 3 files changed, 184 insertions(+), 12 deletions(-) create mode 100644 dlls/ntoskrnl.exe/tests/pop_hid_macros.h create mode 100644 dlls/ntoskrnl.exe/tests/psh_hid_macros.h
diff --git a/dlls/ntoskrnl.exe/tests/driver_hid.c b/dlls/ntoskrnl.exe/tests/driver_hid.c index 0f626e6866c..b34ba7f19ae 100644 --- a/dlls/ntoskrnl.exe/tests/driver_hid.c +++ b/dlls/ntoskrnl.exe/tests/driver_hid.c @@ -85,22 +85,26 @@ 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[] = { - 0x05, HID_USAGE_PAGE_GENERIC, - 0x09, HID_USAGE_GENERIC_JOYSTICK, - 0xa1, 0x01, /* application collection */ - 0x05, HID_USAGE_PAGE_GENERIC, - 0x09, HID_USAGE_GENERIC_X, - 0x09, HID_USAGE_GENERIC_Y, - 0x15, 0x80, /* logical minimum -128 */ - 0x25, 0x7f, /* logical maximum 127 */ - 0x75, 0x08, /* report size */ - 0x95, 0x02, /* report count */ - 0x81, 0x02, /* input, variable */ - 0xc0, /* end collection */ + 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), + END_COLLECTION, };
+#include "pop_hid_macros.h" + static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device, IRP *irp) { static BOOL test_failed; diff --git a/dlls/ntoskrnl.exe/tests/pop_hid_macros.h b/dlls/ntoskrnl.exe/tests/pop_hid_macros.h new file mode 100644 index 00000000000..767c26e8ecb --- /dev/null +++ b/dlls/ntoskrnl.exe/tests/pop_hid_macros.h @@ -0,0 +1,83 @@ +/* + * HID report helper macros. + * + * Copyright 2021 Rémi Bernon for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#undef Data +#undef Cnst +#undef Array +#undef Var +#undef Abs +#undef Rel +#undef NoWrap +#undef Wrap +#undef NonLin +#undef Lin +#undef NoPref +#undef Pref +#undef NoNull +#undef Null +#undef NonVol +#undef Vol +#undef Bits +#undef Buff + +#undef Physical +#undef Application +#undef Logical +#undef Report +#undef NamedArray +#undef UsageSwitch +#undef UsageModifier + +#undef SHORT_ITEM_0 +#undef SHORT_ITEM_1 +#undef SHORT_ITEM_2 +#undef SHORT_ITEM_4 + +#undef LONG_ITEM + +#undef INPUT +#undef OUTPUT +#undef FEATURE +#undef COLLECTION +#undef END_COLLECTION + +#undef USAGE_PAGE +#undef LOGICAL_MINIMUM +#undef LOGICAL_MAXIMUM +#undef PHYSICAL_MINIMUM +#undef PHYSICAL_MAXIMUM +#undef UNIT_EXPONENT +#undef UNIT +#undef REPORT_SIZE +#undef REPORT_ID +#undef REPORT_COUNT +#undef PUSH +#undef POP + +#undef USAGE +#undef USAGE_MINIMUM +#undef USAGE_MAXIMUM +#undef DESIGNATOR_INDEX +#undef DESIGNATOR_MINIMUM +#undef DESIGNATOR_MAXIMUM +#undef STRING_INDEX +#undef STRING_MINIMUM +#undef STRING_MAXIMUM +#undef DELIMITER diff --git a/dlls/ntoskrnl.exe/tests/psh_hid_macros.h b/dlls/ntoskrnl.exe/tests/psh_hid_macros.h new file mode 100644 index 00000000000..4623af20598 --- /dev/null +++ b/dlls/ntoskrnl.exe/tests/psh_hid_macros.h @@ -0,0 +1,85 @@ +/* + * HID report helper macros. + * + * Copyright 2021 Rémi Bernon for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <hidusage.h> + +#define Data 0 +#define Cnst 0x01 +#define Ary 0 +#define Var 0x02 +#define Abs 0 +#define Rel 0x04 +#define NoWrap 0 +#define Wrap 0x08 +#define NonLin 0 +#define Lin 0x10 +#define NoPref 0 +#define Pref 0x20 +#define NoNull 0 +#define Null 0x40 +#define NonVol 0 +#define Vol 0x80 +#define Bits 0 +#define Buff 0x100 + +#define Physical 0x00 +#define Application 0x01 +#define Logical 0x02 +#define Report 0x03 +#define NamedArray 0x04 +#define UsageSwitch 0x05 +#define UsageModifier 0x06 + +#define SHORT_ITEM_0(tag,type) (((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) + +#define LONG_ITEM(tag,size) SHORT_ITEM_2(0xf,0x3,((tag)<<8)|(size)) + +#define INPUT(n,data) SHORT_ITEM_##n(0x8,0,data) +#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 USAGE_PAGE(n,data) SHORT_ITEM_##n(0x0,1,data) +#define LOGICAL_MINIMUM(n,data) SHORT_ITEM_##n(0x1,1,data) +#define LOGICAL_MAXIMUM(n,data) SHORT_ITEM_##n(0x2,1,data) +#define PHYSICAL_MINIMUM(n,data) SHORT_ITEM_##n(0x3,1,data) +#define PHYSICAL_MAXIMUM(n,data) SHORT_ITEM_##n(0x4,1,data) +#define UNIT_EXPONENT(n,data) SHORT_ITEM_##n(0x5,1,data) +#define UNIT(n,data) SHORT_ITEM_##n(0x6,1,data) +#define REPORT_SIZE(n,data) SHORT_ITEM_##n(0x7,1,data) +#define REPORT_ID(n,data) SHORT_ITEM_##n(0x8,1,data) +#define REPORT_COUNT(n,data) SHORT_ITEM_##n(0x9,1,data) +#define PUSH(n,data) SHORT_ITEM_##n(0xa,1,data) +#define POP(n,data) SHORT_ITEM_##n(0xb,1,data) + +#define USAGE(n,data) SHORT_ITEM_##n(0x0,2,data) +#define USAGE_MINIMUM(n,data) SHORT_ITEM_##n(0x1,2,data) +#define USAGE_MAXIMUM(n,data) SHORT_ITEM_##n(0x2,2,data) +#define DESIGNATOR_INDEX(n,data) SHORT_ITEM_##n(0x3,2,data) +#define DESIGNATOR_MINIMUM(n,data) SHORT_ITEM_##n(0x4,2,data) +#define DESIGNATOR_MAXIMUM(n,data) SHORT_ITEM_##n(0x5,2,data) +#define STRING_INDEX(n,data) SHORT_ITEM_##n(0x6,2,data) +#define STRING_MINIMUM(n,data) SHORT_ITEM_##n(0x7,2,data) +#define STRING_MAXIMUM(n,data) SHORT_ITEM_##n(0x8,2,data) +#define DELIMITER(n,data) SHORT_ITEM_##n(0x9,2,data)
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=91876
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
ntoskrnl.exe: ntoskrnl.c:1234: Test failed: got 0 bus arrival messages ntoskrnl.c:1250: Test failed: got 0 bus arrival messages
=== debiant2 (32 bit French report) ===
ntoskrnl.exe: ntoskrnl: Timeout
=== debiant2 (32 bit Hebrew:Israel report) ===
ntoskrnl.exe: ntoskrnl: Timeout
On 6/4/21 11:26 AM, Marvin wrote:
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=91876
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
ntoskrnl.exe: ntoskrnl.c:1234: Test failed: got 0 bus arrival messages ntoskrnl.c:1250: Test failed: got 0 bus arrival messages
=== debiant2 (32 bit French report) ===
ntoskrnl.exe: ntoskrnl: Timeout
=== debiant2 (32 bit Hebrew:Israel report) ===
ntoskrnl.exe: ntoskrnl: Timeout
Looks like another sort of spurious failure... The HID tests weren't even executed yet.
I think there's also a bunch of uninitialized memory uses, but I don't know if it's related.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntoskrnl.exe/tests/driver_hid.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/tests/driver_hid.c b/dlls/ntoskrnl.exe/tests/driver_hid.c index b34ba7f19ae..1fe644250f7 100644 --- a/dlls/ntoskrnl.exe/tests/driver_hid.c +++ b/dlls/ntoskrnl.exe/tests/driver_hid.c @@ -100,6 +100,27 @@ static const unsigned char report_descriptor[] = 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, };
@@ -181,7 +202,7 @@ static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device, IRP *irp)
case IOCTL_HID_READ_REPORT: { - ULONG expected_size = 2; + ULONG expected_size = 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 (out_size != expected_size) test_failed = TRUE;
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=91877
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
ntoskrnl.exe: ntoskrnl.c:1234: Test failed: got 0 bus arrival messages ntoskrnl.c:1250: Test failed: got 0 bus arrival messages
=== w1064_tsign (64 bit report) ===
ntoskrnl.exe: driver.c:272: Test failed: Got unexpected test_load_image_notify_count 0.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntoskrnl.exe/tests/Makefile.in | 2 +- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 299 ++++++++++++++++++++++++++++ 2 files changed, 300 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..f8f56c13342 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,19 +1498,150 @@ static void test_pnp_driver(struct testsign_context *ctx) SetCurrentDirectoryA(cwd); }
+#define check_hidp_caps(a, b) check_hidp_caps_(__LINE__, a, b) +static void check_hidp_caps_(int line, HIDP_CAPS *caps, const HIDP_CAPS *exp) +{ + ok_(__FILE__, line)(caps->Usage == exp->Usage, "unexpected caps Usage %x, expected %x\n", caps->Usage, exp->Usage); + ok_(__FILE__, line)(caps->UsagePage == exp->UsagePage, "unexpected caps UsagePage %x, expected %x\n", caps->UsagePage, exp->UsagePage); + ok_(__FILE__, line)(caps->InputReportByteLength == exp->InputReportByteLength, "unexpected caps InputReportByteLength %d, expected %d\n", caps->InputReportByteLength, exp->InputReportByteLength); + ok_(__FILE__, line)(caps->OutputReportByteLength == exp->OutputReportByteLength, "unexpected caps OutputReportByteLength %d, expected %d\n", caps->OutputReportByteLength, exp->OutputReportByteLength); + ok_(__FILE__, line)(caps->FeatureReportByteLength == exp->FeatureReportByteLength, "unexpected caps FeatureReportByteLength %d, expected %d\n", caps->FeatureReportByteLength, exp->FeatureReportByteLength); + ok_(__FILE__, line)(caps->NumberLinkCollectionNodes == exp->NumberLinkCollectionNodes, "unexpected caps NumberLinkCollectionNodes %d, expected %d\n", caps->NumberLinkCollectionNodes, exp->NumberLinkCollectionNodes); + ok_(__FILE__, line)(caps->NumberInputButtonCaps == exp->NumberInputButtonCaps, "unexpected caps NumberInputButtonCaps %d, expected %d\n", caps->NumberInputButtonCaps, exp->NumberInputButtonCaps); + ok_(__FILE__, line)(caps->NumberInputValueCaps == exp->NumberInputValueCaps, "unexpected caps NumberInputValueCaps %d, expected %d\n", caps->NumberInputValueCaps, exp->NumberInputValueCaps); + ok_(__FILE__, line)(caps->NumberInputDataIndices == exp->NumberInputDataIndices, "unexpected caps NumberInputDataIndices %d, expected %d\n", caps->NumberInputDataIndices, exp->NumberInputDataIndices); + ok_(__FILE__, line)(caps->NumberOutputButtonCaps == exp->NumberOutputButtonCaps, "unexpected caps NumberOutputButtonCaps %d, expected %d\n", caps->NumberOutputButtonCaps, exp->NumberOutputButtonCaps); + ok_(__FILE__, line)(caps->NumberOutputValueCaps == exp->NumberOutputValueCaps, "unexpected caps NumberOutputValueCaps %d, expected %d\n", caps->NumberOutputValueCaps, exp->NumberOutputValueCaps); + ok_(__FILE__, line)(caps->NumberOutputDataIndices == exp->NumberOutputDataIndices, "unexpected caps NumberOutputDataIndices %d, expected %d\n", caps->NumberOutputDataIndices, exp->NumberOutputDataIndices); + ok_(__FILE__, line)(caps->NumberFeatureButtonCaps == exp->NumberFeatureButtonCaps, "unexpected caps NumberFeatureButtonCaps %d, expected %d\n", caps->NumberFeatureButtonCaps, exp->NumberFeatureButtonCaps); + ok_(__FILE__, line)(caps->NumberFeatureValueCaps == exp->NumberFeatureValueCaps, "unexpected caps NumberFeatureValueCaps %d, expected %d\n", caps->NumberFeatureValueCaps, exp->NumberFeatureValueCaps); + ok_(__FILE__, line)(caps->NumberFeatureDataIndices == exp->NumberFeatureDataIndices, "unexpected caps NumberFeatureDataIndices %d, expected %d\n", caps->NumberFeatureDataIndices, exp->NumberFeatureDataIndices); +} + +#define check_hidp_button_caps(a, b) check_hidp_button_caps_(__LINE__, a, b) +static void check_hidp_button_caps_(int line, HIDP_BUTTON_CAPS *caps, const HIDP_BUTTON_CAPS *exp) +{ + ok_(__FILE__, line)(caps->UsagePage == exp->UsagePage, "unexpected button caps UsagePage %x, expected %x\n", caps->UsagePage, exp->UsagePage); + ok_(__FILE__, line)(caps->ReportID == exp->ReportID, "unexpected button caps ReportID %d, expected %d\n", caps->ReportID, exp->ReportID); + ok_(__FILE__, line)(caps->IsAlias == exp->IsAlias, "unexpected button caps IsAlias %d, expected %d\n", caps->IsAlias, exp->IsAlias); + ok_(__FILE__, line)(caps->BitField == exp->BitField, "unexpected button caps BitField %d, expected %d\n", caps->BitField, exp->BitField); + ok_(__FILE__, line)(caps->LinkCollection == exp->LinkCollection, "unexpected button caps LinkCollection %d, expected %d\n", caps->LinkCollection, exp->LinkCollection); + ok_(__FILE__, line)(caps->LinkUsage == exp->LinkUsage, "unexpected button caps LinkUsage %x, expected %x\n", caps->LinkUsage, exp->LinkUsage); + ok_(__FILE__, line)(caps->LinkUsagePage == exp->LinkUsagePage, "unexpected button caps LinkUsagePage %x, expected %x\n", caps->LinkUsagePage, exp->LinkUsagePage); + ok_(__FILE__, line)(caps->IsRange == exp->IsRange, "unexpected button caps IsRange %d, expected %d\n", caps->IsRange, exp->IsRange); + ok_(__FILE__, line)(caps->IsStringRange == exp->IsStringRange, "unexpected button caps IsStringRange %d, expected %d\n", caps->IsStringRange, exp->IsStringRange); + ok_(__FILE__, line)(caps->IsDesignatorRange == exp->IsDesignatorRange, "unexpected button caps IsDesignatorRange %d, expected %d\n", caps->IsDesignatorRange, exp->IsDesignatorRange); + ok_(__FILE__, line)(caps->IsAbsolute == exp->IsAbsolute, "unexpected button caps IsAbsolute %d, expected %d\n", caps->IsAbsolute, exp->IsAbsolute); + + if (!caps->IsRange && !exp->IsRange) + { + ok_(__FILE__, line)(caps->NotRange.Usage == exp->NotRange.Usage, "unexpected button caps NotRange.Usage %d, expected %d\n", caps->NotRange.Usage, exp->NotRange.Usage); + ok_(__FILE__, line)(caps->NotRange.DataIndex == exp->NotRange.DataIndex, "unexpected button caps NotRange.DataIndex %d, expected %d\n", caps->NotRange.DataIndex, exp->NotRange.DataIndex); + } + else if (caps->IsRange && exp->IsRange) + { + ok_(__FILE__, line)(caps->Range.UsageMin == exp->Range.UsageMin, "unexpected button caps Range.UsageMin %d, expected %d\n", caps->Range.UsageMin, exp->Range.UsageMin); + ok_(__FILE__, line)(caps->Range.UsageMax == exp->Range.UsageMax, "unexpected button caps Range.UsageMax %d, expected %d\n", caps->Range.UsageMax, exp->Range.UsageMax); + ok_(__FILE__, line)(caps->Range.DataIndexMin == exp->Range.DataIndexMin, "unexpected button caps Range.DataIndexMin %d, expected %d\n", caps->Range.DataIndexMin, exp->Range.DataIndexMin); + ok_(__FILE__, line)(caps->Range.DataIndexMax == exp->Range.DataIndexMax, "unexpected button caps Range.DataIndexMax %d, expected %d\n", caps->Range.DataIndexMax, exp->Range.DataIndexMax); + } + + if (!caps->IsRange && !exp->IsRange) + ok_(__FILE__, line)(caps->NotRange.StringIndex == exp->NotRange.StringIndex, "unexpected button caps NotRange.StringIndex %d, expected %d\n", caps->NotRange.StringIndex, exp->NotRange.StringIndex); + else if (caps->IsStringRange && exp->IsStringRange) + { + ok_(__FILE__, line)(caps->Range.StringMin == exp->Range.StringMin, "unexpected button caps Range.StringMin %d, expected %d\n", caps->Range.StringMin, exp->Range.StringMin); + ok_(__FILE__, line)(caps->Range.StringMax == exp->Range.StringMax, "unexpected button caps Range.StringMax %d, expected %d\n", caps->Range.StringMax, exp->Range.StringMax); + } + + if (!caps->IsDesignatorRange && !exp->IsDesignatorRange) + ok_(__FILE__, line)(caps->NotRange.DesignatorIndex == exp->NotRange.DesignatorIndex, "unexpected button caps NotRange.DesignatorIndex %d, expected %d\n", caps->NotRange.DesignatorIndex, exp->NotRange.DesignatorIndex); + else if (caps->IsDesignatorRange && exp->IsDesignatorRange) + { + ok_(__FILE__, line)(caps->Range.DesignatorMin == exp->Range.DesignatorMin, "unexpected button caps Range.DesignatorMin %d, expected %d\n", caps->Range.DesignatorMin, exp->Range.DesignatorMin); + ok_(__FILE__, line)(caps->Range.DesignatorMax == exp->Range.DesignatorMax, "unexpected button caps Range.DesignatorMax %d, expected %d\n", caps->Range.DesignatorMax, exp->Range.DesignatorMax); + } +} + +#define check_hidp_value_caps(a, b) check_hidp_value_caps_(__LINE__, a, b) +static void check_hidp_value_caps_(int line, HIDP_VALUE_CAPS *caps, const HIDP_VALUE_CAPS *exp) +{ + ok_(__FILE__, line)(caps->UsagePage == exp->UsagePage, "unexpected value caps UsagePage %x, expected %x\n", caps->UsagePage, exp->UsagePage); + ok_(__FILE__, line)(caps->ReportID == exp->ReportID, "unexpected value caps ReportID %d, expected %d\n", caps->ReportID, exp->ReportID); + ok_(__FILE__, line)(caps->IsAlias == exp->IsAlias, "unexpected value caps IsAlias %d, expected %d\n", caps->IsAlias, exp->IsAlias); + ok_(__FILE__, line)(caps->BitField == exp->BitField, "unexpected value caps BitField %d, expected %d\n", caps->BitField, exp->BitField); + ok_(__FILE__, line)(caps->LinkCollection == exp->LinkCollection, "unexpected value caps LinkCollection %d, expected %d\n", caps->LinkCollection, exp->LinkCollection); + ok_(__FILE__, line)(caps->LinkUsage == exp->LinkUsage, "unexpected value caps LinkUsage %x, expected %x\n", caps->LinkUsage, exp->LinkUsage); + ok_(__FILE__, line)(caps->LinkUsagePage == exp->LinkUsagePage, "unexpected value caps LinkUsagePage %x, expected %x\n", caps->LinkUsagePage, exp->LinkUsagePage); + ok_(__FILE__, line)(caps->IsRange == exp->IsRange, "unexpected value caps IsRange %d, expected %d\n", caps->IsRange, exp->IsRange); + ok_(__FILE__, line)(caps->IsStringRange == exp->IsStringRange, "unexpected value caps IsStringRange %d, expected %d\n", caps->IsStringRange, exp->IsStringRange); + ok_(__FILE__, line)(caps->IsDesignatorRange == exp->IsDesignatorRange, "unexpected value caps IsDesignatorRange %d, expected %d\n", caps->IsDesignatorRange, exp->IsDesignatorRange); + ok_(__FILE__, line)(caps->IsAbsolute == exp->IsAbsolute, "unexpected value caps IsAbsolute %d, expected %d\n", caps->IsAbsolute, exp->IsAbsolute); + + ok_(__FILE__, line)(caps->HasNull == exp->HasNull, "unexpected value caps HasNull %d, expected %d\n", caps->HasNull, exp->HasNull); + ok_(__FILE__, line)(caps->BitSize == exp->BitSize, "unexpected value caps BitSize %d, expected %d\n", caps->BitSize, exp->BitSize); + ok_(__FILE__, line)(caps->ReportCount == exp->ReportCount, "unexpected value caps ReportCount %d, expected %d\n", caps->ReportCount, exp->ReportCount); + ok_(__FILE__, line)(caps->UnitsExp == exp->UnitsExp, "unexpected value caps UnitsExp %d, expected %d\n", caps->UnitsExp, exp->UnitsExp); + ok_(__FILE__, line)(caps->Units == exp->Units, "unexpected value caps Units %d, expected %d\n", caps->Units, exp->Units); + ok_(__FILE__, line)(caps->LogicalMin == exp->LogicalMin, "unexpected value caps LogicalMin %d, expected %d\n", caps->LogicalMin, -exp->LogicalMin); + ok_(__FILE__, line)(caps->LogicalMax == exp->LogicalMax, "unexpected value caps LogicalMax %d, expected %d\n", caps->LogicalMax, exp->LogicalMax); + ok_(__FILE__, line)(caps->PhysicalMin == exp->PhysicalMin, "unexpected value caps PhysicalMin %d, expected %d\n", caps->PhysicalMin, exp->PhysicalMin); + ok_(__FILE__, line)(caps->PhysicalMax == exp->PhysicalMax, "unexpected value caps PhysicalMax %d, expected %d\n", caps->PhysicalMax, exp->PhysicalMax); + + if (!caps->IsRange && !exp->IsRange) + { + ok_(__FILE__, line)(caps->NotRange.Usage == exp->NotRange.Usage, "unexpected value caps NotRange.Usage %d, expected %d\n", caps->NotRange.Usage, exp->NotRange.Usage); + ok_(__FILE__, line)(caps->NotRange.DataIndex == exp->NotRange.DataIndex, "unexpected value caps NotRange.DataIndex %d, expected %d\n", caps->NotRange.DataIndex, exp->NotRange.DataIndex); + } + else if (caps->IsRange && exp->IsRange) + { + ok_(__FILE__, line)(caps->Range.UsageMin == exp->Range.UsageMin, "unexpected value caps Range.UsageMin %d, expected %d\n", caps->Range.UsageMin, exp->Range.UsageMin); + ok_(__FILE__, line)(caps->Range.UsageMax == exp->Range.UsageMax, "unexpected value caps Range.UsageMax %d, expected %d\n", caps->Range.UsageMax, exp->Range.UsageMax); + ok_(__FILE__, line)(caps->Range.DataIndexMin == exp->Range.DataIndexMin, "unexpected value caps Range.DataIndexMin %d, expected %d\n", caps->Range.DataIndexMin, exp->Range.DataIndexMin); + ok_(__FILE__, line)(caps->Range.DataIndexMax == exp->Range.DataIndexMax, "unexpected value caps Range.DataIndexMax %d, expected %d\n", caps->Range.DataIndexMax, exp->Range.DataIndexMax); + } + + if (!caps->IsRange && !exp->IsRange) + ok_(__FILE__, line)(caps->NotRange.StringIndex == exp->NotRange.StringIndex, "unexpected value caps NotRange.StringIndex %d, expected %d\n", caps->NotRange.StringIndex, exp->NotRange.StringIndex); + else if (caps->IsStringRange && exp->IsStringRange) + { + ok_(__FILE__, line)(caps->Range.StringMin == exp->Range.StringMin, "unexpected value caps Range.StringMin %d, expected %d\n", caps->Range.StringMin, exp->Range.StringMin); + ok_(__FILE__, line)(caps->Range.StringMax == exp->Range.StringMax, "unexpected value caps Range.StringMax %d, expected %d\n", caps->Range.StringMax, exp->Range.StringMax); + } + + if (!caps->IsDesignatorRange && !exp->IsDesignatorRange) + ok_(__FILE__, line)(caps->NotRange.DesignatorIndex == exp->NotRange.DesignatorIndex, "unexpected value caps NotRange.DesignatorIndex %d, expected %d\n", caps->NotRange.DesignatorIndex, exp->NotRange.DesignatorIndex); + else if (caps->IsDesignatorRange && exp->IsDesignatorRange) + { + ok_(__FILE__, line)(caps->Range.DesignatorMin == exp->Range.DesignatorMin, "unexpected value caps Range.DesignatorMin %d, expected %d\n", caps->Range.DesignatorMin, exp->Range.DesignatorMin); + ok_(__FILE__, line)(caps->Range.DesignatorMax == exp->Range.DesignatorMax, "unexpected value caps Range.DesignatorMax %d, expected %d\n", caps->Range.DesignatorMax, exp->Range.DesignatorMax); + } +} + static void test_hid_device(void) { + static const HIDP_CAPS expect_hidp_caps = + { + HID_USAGE_GENERIC_JOYSTICK, HID_USAGE_PAGE_GENERIC, 5, 0, 0, + {0}, 1, 1, 3, 11, 0, 0, 0, 0, 0, 0 + }; + 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)}; + PHIDP_PREPARSED_DATA preparsed_data; + HIDP_BUTTON_CAPS button_caps[16]; + HIDP_VALUE_CAPS value_caps[16]; BOOL ret, found = FALSE; OBJECT_ATTRIBUTES attr; UNICODE_STRING string; IO_STATUS_BLOCK io; NTSTATUS status; + HIDP_CAPS caps; unsigned int i; HDEVINFO set; + USHORT count; HANDLE file;
set = SetupDiGetClassDevsA(&GUID_DEVINTERFACE_HID, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); @@ -1541,6 +1674,172 @@ 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());
+ 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); + + ok(button_caps[0].UsagePage == HID_USAGE_PAGE_BUTTON, "unexpected button caps UsagePage %x, expected %x\n", button_caps[0].UsagePage, HID_USAGE_PAGE_BUTTON); + ok(button_caps[0].ReportID == 0, "unexpected button caps ReportID %d, expected %d\n", button_caps[0].ReportID, 0); + ok(!button_caps[0].IsAlias, "unexpected button caps IsAlias %d, expected %d\n", button_caps[0].IsAlias, 0); + todo_wine ok(button_caps[0].BitField == 2, "unexpected button caps BitField %d, expected %d\n", button_caps[0].BitField, 2); + ok(button_caps[0].LinkCollection == 0, "unexpected button caps LinkCollection %d, expected %d\n", button_caps[0].LinkCollection, 0); + ok(button_caps[0].LinkUsage == HID_USAGE_GENERIC_JOYSTICK, "unexpected button caps LinkUsage %x, expected %x\n", button_caps[0].LinkUsage, HID_USAGE_GENERIC_JOYSTICK); + ok(button_caps[0].LinkUsagePage == HID_USAGE_PAGE_GENERIC, "unexpected button caps LinkUsagePage %x, expected %x\n", button_caps[0].LinkUsagePage, HID_USAGE_PAGE_GENERIC); + ok(button_caps[0].IsRange, "unexpected button caps IsRange %d, expected %d\n", button_caps[0].IsRange, 1); + ok(!button_caps[0].IsStringRange, "unexpected button caps IsStringRange %d, expected %d\n", button_caps[0].IsStringRange, 0); + ok(!button_caps[0].IsDesignatorRange, "unexpected button caps IsDesignatorRange %d, expected %d\n", button_caps[0].IsDesignatorRange, 0); + ok(button_caps[0].IsAbsolute, "unexpected button caps IsAbsolute %d, expected %d\n", button_caps[0].IsAbsolute, 1); + ok(button_caps[0].Range.UsageMin == 1, "unexpected button caps Range.UsageMin %d, expected %d\n", button_caps[0].Range.UsageMin, 1); + ok(button_caps[0].Range.UsageMax == 8, "unexpected button caps Range.UsageMax %d, expected %d\n", button_caps[0].Range.UsageMax, 8); + ok(button_caps[0].Range.StringMin == 0, "unexpected button caps Range.StringMin %d, expected %d\n", button_caps[0].Range.StringMin, 0); + ok(button_caps[0].Range.StringMax == 0, "unexpected button caps Range.StringMax %d, expected %d\n", button_caps[0].Range.StringMax, 0); + ok(button_caps[0].Range.DesignatorMin == 0, "unexpected button caps Range.DesignatorMin %d, expected %d\n", button_caps[0].Range.DesignatorMin, 0); + ok(button_caps[0].Range.DesignatorMax == 0, "unexpected button caps Range.DesignatorMax %d, expected %d\n", button_caps[0].Range.DesignatorMax, 0); + ok(button_caps[0].Range.DataIndexMin == 2, "unexpected button caps Range.DataIndexMin %d, expected %d\n", button_caps[0].Range.DataIndexMin, 2); + ok(button_caps[0].Range.DataIndexMax == 9, "unexpected button caps Range.DataIndexMax %d, expected %d\n", button_caps[0].Range.DataIndexMax, 9); + + 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_GetValueCaps 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_GetValueCaps 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_GetValueCaps 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); + + ok(value_caps[0].UsagePage == HID_USAGE_PAGE_GENERIC, "unexpected value caps UsagePage %x, expected %x\n", value_caps[0].UsagePage, HID_USAGE_PAGE_GENERIC); + ok(value_caps[0].ReportID == 0, "unexpected value caps ReportID %d, expected %d\n", value_caps[0].ReportID, 0); + ok(value_caps[0].IsAlias == 0, "unexpected value caps IsAlias %d, expected %d\n", value_caps[0].IsAlias, 0); + todo_wine ok(value_caps[0].BitField == 2, "unexpected value caps BitField %d, expected %d\n", value_caps[0].BitField, 2); + ok(value_caps[0].LinkCollection == 0, "unexpected value caps LinkCollection %d, expected %d\n", value_caps[0].LinkCollection, 0); + ok(value_caps[0].LinkUsage == HID_USAGE_GENERIC_JOYSTICK, "unexpected value caps LinkUsage %x, expected %x\n", value_caps[0].LinkUsage, HID_USAGE_GENERIC_JOYSTICK); + ok(value_caps[0].LinkUsagePage == HID_USAGE_PAGE_GENERIC, "unexpected value caps LinkUsagePage %x, expected %x\n", value_caps[0].LinkUsagePage, HID_USAGE_PAGE_GENERIC); + ok(!value_caps[0].IsRange, "unexpected value caps IsRange %d, expected %d\n", value_caps[0].IsRange, 0); + ok(!value_caps[0].IsStringRange, "unexpected value caps IsStringRange %d, expected %d\n", value_caps[0].IsStringRange, 0); + ok(!value_caps[0].IsDesignatorRange, "unexpected value caps IsDesignatorRange %d, expected %d\n", value_caps[0].IsDesignatorRange, 0); + ok(value_caps[0].IsAbsolute, "unexpected value caps IsAbsolute %d, expected %d\n", value_caps[0].IsAbsolute, 1); + ok(value_caps[0].HasNull == 0, "unexpected value caps HasNull %d, expected %d\n", value_caps[0].HasNull, 0); + ok(value_caps[0].BitSize == 8, "unexpected value caps BitSize %d, expected %d\n", value_caps[0].BitSize, 8); + ok(value_caps[0].ReportCount == 1, "unexpected value caps ReportCount %d, expected %d\n", value_caps[0].ReportCount, 1); + ok(value_caps[0].UnitsExp == 0, "unexpected value caps UnitsExp %d, expected %d\n", value_caps[0].UnitsExp, 0); + ok(value_caps[0].Units == 0, "unexpected value caps Units %d, expected %d\n", value_caps[0].Units, 0); + ok(value_caps[0].LogicalMin == -128, "unexpected value caps LogicalMin %d, expected %d\n", value_caps[0].LogicalMin, -128); + ok(value_caps[0].LogicalMax == 127, "unexpected value caps LogicalMax %d, expected %d\n", value_caps[0].LogicalMax, 127); + ok(value_caps[0].PhysicalMin == 0, "unexpected value caps PhysicalMin %d, expected %d\n", value_caps[0].PhysicalMin, 0); + ok(value_caps[0].PhysicalMax == 0, "unexpected value caps PhysicalMax %d, expected %d\n", value_caps[0].PhysicalMax, 0); + todo_wine ok(value_caps[0].NotRange.Usage == HID_USAGE_GENERIC_Y, "unexpected value caps NotRange.Usage %d, expected %d\n", value_caps[0].NotRange.Usage, HID_USAGE_GENERIC_Y); + ok(value_caps[0].NotRange.StringIndex == 0, "unexpected value caps NotRange.StringIndex %d, expected %d\n", value_caps[0].NotRange.StringIndex, 0); + ok(value_caps[0].NotRange.DesignatorIndex == 0, "unexpected value caps NotRange.DesignatorIndex %d, expected %d\n", value_caps[0].NotRange.DesignatorIndex, 0); + ok(value_caps[0].NotRange.DataIndex == 0, "unexpected value caps NotRange.DataIndex %d, expected %d\n", value_caps[0].NotRange.DataIndex, 0); + + todo_wine ok(value_caps[1].NotRange.Usage == HID_USAGE_GENERIC_X, "unexpected value caps NotRange.Usage %d, expected %d\n", value_caps[1].NotRange.Usage, HID_USAGE_GENERIC_X); + ok(value_caps[2].NotRange.Usage == HID_USAGE_GENERIC_HATSWITCH, "unexpected value caps NotRange.Usage %d, expected %d\n", value_caps[2].NotRange.Usage, HID_USAGE_GENERIC_HATSWITCH); + + 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);
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=91878
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 ntoskrnl.c:1253: Test failed: got 0 bus removal messages ntoskrnl.c:1278: Test failed: got 0 child arrival messages ntoskrnl.c:1285: Test failed: failed to get device, error 0x103 ntoskrnl.c:1286: Test failed: wrong class {4d36e97d-e325-11ce-bfc1-08002be10318} ntoskrnl.c:1289: Test failed: failed to get device ID, error 0x57 ntoskrnl.c:1290: Test failed: got ID "\x05" ntoskrnl.c:1294: Test failed: got error 0x57 ntoskrnl.c:1311: Test failed: got error 0x57 ntoskrnl.c:1316: Test failed: got error 0x57 ntoskrnl.c:1320: Test failed: got error 0x57 ntoskrnl.c:1321: Test failed: got type 3 ntoskrnl.c:1322: Test failed: got size 0 ntoskrnl.c:1327: Test failed: got error 0x57 ntoskrnl.c:1328: Test failed: got type 3 ntoskrnl.c:1329: Test failed: got size 0 ntoskrnl.c:1334: Test failed: got error 0x57 ntoskrnl.c:1361: Test failed: got 0 child arrival messages ntoskrnl.c:1362: Test failed: got 0 child removal messages ntoskrnl.c:1365: Test failed: got 0 ntoskrnl.c:1464: Test failed: failed to get device list, error 0xd ntoskrnl.c:294: Test failed: expected SERVICE_STOPPED, got 4 ntoskrnl.c:1910: Test failed: failed to install device, error 0x430 ntoskrnl.c:1671: Test failed: didn't find device ntoskrnl.c:1675: Test failed: got error 2 ntoskrnl.c:1678: Test failed: HidD_GetPreparsedData failed with error 6 ntoskrnl.c:1684: Test failed: HidP_GetCaps returned 0xc0110001 ntoskrnl.c:1685: Test failed: unexpected caps Usage eb20, expected 4 ntoskrnl.c:1685: Test failed: unexpected caps UsagePage 22, expected 1 ntoskrnl.c:1685: Test failed: unexpected caps InputReportByteLength 52963, expected 5 ntoskrnl.c:1685: Test failed: unexpected caps OutputReportByteLength 30663, expected 0 ntoskrnl.c:1685: Test failed: unexpected caps NumberLinkCollectionNodes 60196, expected 1 ntoskrnl.c:1685: Test failed: unexpected caps NumberInputButtonCaps 34, expected 1 ntoskrnl.c:1685: Test failed: unexpected caps NumberInputValueCaps 53041, expected 3 ntoskrnl.c:1685: Test failed: unexpected caps NumberInputDataIndices 30663, expected 11 ntoskrnl.c:1685: Test failed: unexpected caps NumberOutputButtonCaps 1204, expected 0 ntoskrnl.c:1685: Test failed: unexpected caps NumberFeatureValueCaps 250, expected 0 ntoskrnl.c:1689: Test failed: HidP_GetButtonCaps returned 0xc0110001 ntoskrnl.c:1691: Test failed: HidP_GetButtonCaps returned 0xc0110001 ntoskrnl.c:1694: Test failed: HidP_GetButtonCaps returned 0xc0110001 ntoskrnl.c:1695: Test failed: HidP_GetButtonCaps returned count 0, expected 34 ntoskrnl.c:1700: Test failed: HidP_GetButtonCaps returned 0xc0110001 ntoskrnl.c:1701: Test failed: HidP_GetButtonCaps returned count 16, expected 34 ntoskrnl.c:1703: Test failed: unexpected button caps UsagePage 0, expected 9 ntoskrnl.c:1706: Test failed: unexpected button caps BitField 26912, expected 2 ntoskrnl.c:1707: Test failed: unexpected button caps LinkCollection 8307, expected 0 ntoskrnl.c:1708: Test failed: unexpected button caps LinkUsage 6f6e, expected 4 ntoskrnl.c:1709: Test failed: unexpected button caps LinkUsagePage 0, expected 1 ntoskrnl.c:1710: Test failed: unexpected button caps IsRange 0, expected 1 ntoskrnl.c:1713: Test failed: unexpected button caps IsAbsolute 0, expected 1 ntoskrnl.c:1714: Test failed: unexpected button caps Range.UsageMin 62852, expected 1 ntoskrnl.c:1715: Test failed: unexpected button caps Range.UsageMax 34, expected 8 ntoskrnl.c:1716: Test failed: unexpected button caps Range.StringMin 62856, expected 0 ntoskrnl.c:1717: Test failed: unexpected button caps Range.StringMax 34, expected 0 ntoskrnl.c:1718: Test failed: unexpected button caps Range.DesignatorMin 62848, expected 0 ntoskrnl.c:1719: Test failed: unexpected button caps Range.DesignatorMax 34, expected 0 ntoskrnl.c:1720: Test failed: unexpected button caps Range.DataIndexMin 63104, expected 2 ntoskrnl.c:1721: Test failed: unexpected button caps Range.DataIndexMax 34, expected 9 ntoskrnl.c:1725: Test failed: HidP_GetSpecificButtonCaps returned 0xc0110001 ntoskrnl.c:1727: Test failed: HidP_GetSpecificButtonCaps returned 0xc0110001 ntoskrnl.c:1730: Test failed: HidP_GetSpecificButtonCaps returned 0xc0110001 ntoskrnl.c:1731: Test failed: HidP_GetSpecificButtonCaps returned count 0, expected 34 ntoskrnl.c:1737: Test failed: HidP_GetSpecificButtonCaps returned 0xc0110001 ntoskrnl.c:1738: Test failed: HidP_GetSpecificButtonCaps returned count 15, expected 34 ntoskrnl.c:1739: Test failed: unexpected button caps UsagePage f6ac, expected 0 ntoskrnl.c:1739: Test failed: unexpected button caps ReportID 34, expected 0 ntoskrnl.c:1739: Test failed: unexpected button caps BitField 63132, expected 26912 ntoskrnl.c:1739: Test failed: unexpected button caps LinkCollection 34, expected 8307 ntoskrnl.c:1739: Test failed: unexpected button caps LinkUsage 18, expected 6f6e ntoskrnl.c:1739: Test failed: unexpected button caps IsRange 3, expected 0 ntoskrnl.c:1739: Test failed: unexpected button caps NotRange.DesignatorIndex 3, expected 62848 ntoskrnl.c:1742: Test failed: HidP_GetSpecificButtonCaps returned 0xc0110001 ntoskrnl.c:1743: Test failed: HidP_GetSpecificButtonCaps returned count 15, expected 1 ntoskrnl.c:1744: Test failed: unexpected button caps UsagePage f6ac, expected 0 ntoskrnl.c:1744: Test failed: unexpected button caps ReportID 34, expected 0 ntoskrnl.c:1744: Test failed: unexpected button caps BitField 63132, expected 26912 ntoskrnl.c:1744: Test failed: unexpected button caps LinkCollection 34, expected 8307 ntoskrnl.c:1744: Test failed: unexpected button caps LinkUsage 18, expected 6f6e ntoskrnl.c:1744: Test failed: unexpected button caps IsRange 3, expected 0 ntoskrnl.c:1744: Test failed: unexpected button caps NotRange.DesignatorIndex 3, expected 62848 ntoskrnl.c:1748: Test failed: HidP_GetSpecificButtonCaps returned 0xc0110001 ntoskrnl.c:1749: Test failed: HidP_GetValueCaps returned count 48879, expected 0 ntoskrnl.c:1752: Test failed: HidP_GetSpecificButtonCaps returned 0xc0110001 ntoskrnl.c:1753: Test failed: HidP_GetValueCaps returned count 48879, expected 0 ntoskrnl.c:1756: Test failed: HidP_GetSpecificButtonCaps returned 0xc0110001 ntoskrnl.c:1757: Test failed: HidP_GetValueCaps returned count 48879, expected 0 ntoskrnl.c:1761: Test failed: HidP_GetValueCaps returned 0xc0110001 ntoskrnl.c:1763: Test failed: HidP_GetValueCaps returned 0xc0110001 ntoskrnl.c:1766: Test failed: HidP_GetValueCaps returned 0xc0110001 ntoskrnl.c:1767: Test failed: HidP_GetValueCaps returned count 0, expected 53041 ntoskrnl.c:1772: Test failed: HidP_GetValueCaps returned 0xc0110001 ntoskrnl.c:1773: Test failed: HidP_GetValueCaps returned count 16, expected 53041 ntoskrnl.c:1775: Test failed: unexpected value caps UsagePage 43, expected 1 ntoskrnl.c:1776: Test failed: unexpected value caps ReportID 58, expected 0 ntoskrnl.c:1778: Test failed: unexpected value caps BitField 92, expected 2 ntoskrnl.c:1779: Test failed: unexpected value caps LinkCollection 85, expected 0 ntoskrnl.c:1780: Test failed: unexpected value caps LinkUsage 73, expected 4 ntoskrnl.c:1781: Test failed: unexpected value caps LinkUsagePage 65, expected 1 ntoskrnl.c:1782: Test failed: unexpected value caps IsRange 114, expected 0 ntoskrnl.c:1784: Test failed: unexpected value caps IsDesignatorRange 115, expected 0 ntoskrnl.c:1785: Test failed: unexpected value caps IsAbsolute 0, expected 1 ntoskrnl.c:1786: Test failed: unexpected value caps HasNull 92, expected 0 ntoskrnl.c:1787: Test failed: unexpected value caps BitSize 119, expected 8 ntoskrnl.c:1788: Test failed: unexpected value caps ReportCount 105, expected 1 ntoskrnl.c:1789: Test failed: unexpected value caps UnitsExp 6029428, expected 0 ntoskrnl.c:1790: Test failed: unexpected value caps Units 7340097, expected 0 ntoskrnl.c:1791: Test failed: unexpected value caps LogicalMin 4456560, expected -128 ntoskrnl.c:1792: Test failed: unexpected value caps LogicalMax 7602273, expected 127 ntoskrnl.c:1793: Test failed: unexpected value caps PhysicalMin 6029409, expected 0 ntoskrnl.c:1794: Test failed: unexpected value caps PhysicalMax 7274572, expected 0 ntoskrnl.c:1795: Test failed: unexpected value caps NotRange.Usage 99, expected 49 ntoskrnl.c:1796: Test failed: unexpected value caps NotRange.StringIndex 108, expected 0 ntoskrnl.c:1797: Test failed: unexpected value caps NotRange.DesignatorIndex 84, expected 0 ntoskrnl.c:1798: Test failed: unexpected value caps NotRange.DataIndex 109, expected 0 ntoskrnl.c:1800: Test failed: unexpected value caps NotRange.Usage 0, expected 48 ntoskrnl.c:1801: Test failed: unexpected value caps NotRange.Usage 8168, expected 57 ntoskrnl.c:1805: Test failed: HidP_GetSpecificValueCaps returned 0xc0110001 ntoskrnl.c:1807: Test failed: HidP_GetSpecificValueCaps returned 0xc0110001 ntoskrnl.c:1810: Test failed: HidP_GetSpecificValueCaps returned 0xc0110001 ntoskrnl.c:1811: Test failed: HidP_GetSpecificValueCaps returned count 0, expected 53041 ntoskrnl.c:1817: Test failed: HidP_GetSpecificValueCaps returned 0xc0110001 ntoskrnl.c:1818: Test failed: HidP_GetSpecificValueCaps returned count 13, expected 53041 ntoskrnl.c:1819: Test failed: unexpected value caps UsagePage eec5, expected 43 ntoskrnl.c:1819: Test failed: unexpected value caps ReportID 199, expected 58 ntoskrnl.c:1819: Test failed: unexpected value caps IsAlias 119, expected 0 ntoskrnl.c:1819: Test failed: unexpected value caps BitField 8168, expected 92 ntoskrnl.c:1819: Test failed: unexpected value caps LinkCollection 48, expected 85 ntoskrnl.c:1819: Test failed: unexpected value caps LinkUsage 1fe0, expected 73 ntoskrnl.c:1819: Test failed: unexpected value caps LinkUsagePage 30, expected 65 ntoskrnl.c:1819: Test failed: unexpected value caps IsRange 0, expected 114 ntoskrnl.c:1819: Test failed: unexpected value caps IsDesignatorRange 44, expected 115 ntoskrnl.c:1819: Test failed: unexpected value caps HasNull 72, expected 92 ntoskrnl.c:1819: Test failed: unexpected value caps BitSize 30663, expected 119 ntoskrnl.c:1819: Test failed: unexpected value caps ReportCount 4072, expected 105 ntoskrnl.c:1819: Test failed: unexpected value caps UnitsExp 2292412, expected 6029428 ntoskrnl.c:1819: Test failed: unexpected value caps Units 3149232, expected 7340097 ntoskrnl.c:1819: Test failed: unexpected value caps LogicalMin 2883584, expected -4456560 ntoskrnl.c:1819: Test failed: unexpected value caps LogicalMax 0, expected 7602273 ntoskrnl.c:1819: Test failed: unexpected value caps PhysicalMin 3632, expected 6029409 ntoskrnl.c:1819: Test failed: unexpected value caps PhysicalMax 582, expected 7274572 ntoskrnl.c:1819: Test failed: unexpected value caps Range.DesignatorMin 454, expected 84 ntoskrnl.c:1819: Test failed: unexpected value caps Range.DesignatorMax 0, expected 101 ntoskrnl.c:1820: Test failed: unexpected value caps UsagePage 2970, expected 5c ntoskrnl.c:1820: Test failed: unexpected value caps ReportID 44, expected 100 ntoskrnl.c:1820: Test failed: unexpected value caps BitField 582, expected 114 ntoskrnl.c:1820: Test failed: unexpected value caps LinkCollection 0, expected 105 ntoskrnl.c:1820: Test failed: unexpected value caps LinkUsage 89, expected 46 ntoskrnl.c:1820: Test failed: unexpected value caps LinkUsagePage 0, expected 44 ntoskrnl.c:1820: Test failed: unexpected value caps IsRange 176, expected 56 ntoskrnl.c:1820: Test failed: unexpected value caps IsStringRange 13, expected 0 ntoskrnl.c:1820: Test failed: unexpected value caps IsDesignatorRange 48, expected 51 ntoskrnl.c:1820: Test failed: unexpected value caps HasNull 0, expected 46 ntoskrnl.c:1820: Test failed: unexpected value caps BitSize 44, expected 116 ntoskrnl.c:1820: Test failed: unexpected value caps ReportCount 8160, expected 109 ntoskrnl.c:1820: Test failed: unexpected value caps UnitsExp 2883780, expected 5736736 ntoskrnl.c:1820: Test failed: unexpected value caps Units 0, expected 1310738 ntoskrnl.c:1820: Test failed: unexpected value caps LogicalMin 445, expected -3149240 ntoskrnl.c:1820: Test failed: unexpected value caps LogicalMax 2292680, expected 2293368 ntoskrnl.c:1820: Test failed: unexpected value caps PhysicalMin 137, expected 0 ntoskrnl.c:1820: Test failed: unexpected value caps PhysicalMax 2883584, expected 0 ntoskrnl.c:1820: Test failed: unexpected value caps Range.UsageMin 3504, expected 0 ntoskrnl.c:1820: Test failed: unexpected value caps Range.UsageMax 48, expected 0 ntoskrnl.c:1820: Test failed: unexpected value caps Range.DataIndexMin 23475, expected 0 ntoskrnl.c:1820: Test failed: unexpected value caps Range.DataIndexMax 30663, expected 520 ntoskrnl.c:1820: Test failed: unexpected value caps Range.DesignatorMin 23428, expected 64564 ntoskrnl.c:1820: Test failed: unexpected value caps Range.DesignatorMax 30663, expected 34 ntoskrnl.c:1821: Test failed: unexpected value caps UsagePage 8fa4, expected fa2c ntoskrnl.c:1821: Test failed: unexpected value caps ReportID 237, expected 34 ntoskrnl.c:1821: Test failed: unexpected value caps IsAlias 119, expected 0 ntoskrnl.c:1821: Test failed: unexpected value caps BitField 25523, expected 0 ntoskrnl.c:1821: Test failed: unexpected value caps LinkCollection 65, expected 0 ntoskrnl.c:1821: Test failed: unexpected value caps LinkUsage 2acc, expected 0 ntoskrnl.c:1821: Test failed: unexpected value caps LinkUsagePage 2c, expected 77c2 ntoskrnl.c:1821: Test failed: unexpected value caps IsDesignatorRange 44, expected 55 ntoskrnl.c:1821: Test failed: unexpected value caps IsAbsolute 0, expected 114 ntoskrnl.c:1821: Test failed: unexpected value caps HasNull 112, expected 8 ntoskrnl.c:1821: Test failed: unexpected value caps BitSize 44, expected 34 ntoskrnl.c:1821: Test failed: unexpected value caps ReportCount 10608, expected 35296 ntoskrnl.c:1821: Test failed: unexpected value caps UnitsExp 0, expected 2292312 ntoskrnl.c:1821: Test failed: unexpected value caps Units 11141134, expected 2009540728 ntoskrnl.c:1821: Test failed: unexpected value caps LogicalMin 4, expected -2010089628 ntoskrnl.c:1821: Test failed: unexpected value caps LogicalMax 445, expected 2010089628 ntoskrnl.c:1821: Test failed: unexpected value caps PhysicalMin 0, expected 2883584 ntoskrnl.c:1821: Test failed: unexpected value caps PhysicalMax 2894192, expected 2883584 ntoskrnl.c:1821: Test failed: unexpected value caps NotRange.Usage 36864, expected 8168 ntoskrnl.c:1821: Test failed: unexpected value caps NotRange.DataIndex 0, expected 64136 ntoskrnl.c:1821: Test failed: unexpected value caps NotRange.StringIndex 3512, expected 0 ntoskrnl.c:1821: Test failed: unexpected value caps Range.DesignatorMin 64688, expected 8168 ntoskrnl.c:1821: Test failed: unexpected value caps Range.DesignatorMax 34, expected 48 ntoskrnl.c:1825: Test failed: HidP_GetSpecificValueCaps returned 0xc0110001 ntoskrnl.c:1827: Test failed: unexpected value caps UsagePage eec5, expected fa2c ntoskrnl.c:1827: Test failed: unexpected value caps ReportID 199, expected 34 ntoskrnl.c:1827: Test failed: unexpected value caps IsAlias 119, expected 0 ntoskrnl.c:1827: Test failed: unexpected value caps BitField 8168, expected 0 ntoskrnl.c:1827: Test failed: unexpected value caps LinkCollection 48, expected 0 ntoskrnl.c:1827: Test failed: unexpected value caps LinkUsage 1fe0, expected 0 ntoskrnl.c:1827: Test failed: unexpected value caps LinkUsagePage 30, expected 77c2 ntoskrnl.c:1827: Test failed: unexpected value caps IsDesignatorRange 44, expected 55 ntoskrnl.c:1827: Test failed: unexpected value caps IsAbsolute 0, expected 114 ntoskrnl.c:1827: Test failed: unexpected value caps HasNull 72, expected 8 ntoskrnl.c:1827: Test failed: unexpected value caps BitSize 30663, expected 34 ntoskrnl.c:1827: Test failed: unexpected value caps ReportCount 4072, expected 35296 ntoskrnl.c:1827: Test failed: unexpected value caps UnitsExp 2292412, expected 2292312 ntoskrnl.c:1827: Test failed: unexpected value caps Units 3149232, expected 2009540728 ntoskrnl.c:1827: Test failed: unexpected value caps LogicalMin 2883584, expected -2010089628 ntoskrnl.c:1827: Test failed: unexpected value caps LogicalMax 0, expected 2010089628 ntoskrnl.c:1827: Test failed: unexpected value caps PhysicalMin 3632, expected 2883584 ntoskrnl.c:1827: Test failed: unexpected value caps PhysicalMax 582, expected 2883584 ntoskrnl.c:1827: Test failed: unexpected value caps NotRange.Usage 0, expected 8168 ntoskrnl.c:1827: Test failed: unexpected value caps NotRange.DataIndex 196, expected 64136 ntoskrnl.c:1827: Test failed: unexpected value caps Range.DesignatorMin 454, expected 8168 ntoskrnl.c:1827: Test failed: unexpected value caps Range.DesignatorMax 0, expected 48 ntoskrnl.c:1831: Test failed: HidP_GetSpecificValueCaps returned 0xc0110001 ntoskrnl.c:1832: Test failed: HidP_GetSpecificValueCaps returned count 57005, expected 0 ntoskrnl.c:1835: Test failed: HidP_GetSpecificValueCaps returned 0xc0110001 ntoskrnl.c:1836: Test failed: HidP_GetSpecificValueCaps returned count 57005, expected 0 ntoskrnl.c:1839: Test failed: HidP_GetSpecificValueCaps returned 0xc0110001 ntoskrnl.c:1840: Test failed: HidP_GetSpecificValueCaps returned count 57005, expected 0 ntoskrnl.c:1848: Test failed: got 0xc0000034 ntoskrnl.c:294: Test failed: expected SERVICE_STOPPED, got 4
=== w864 (64 bit report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl crashed (c0000374)
On 6/4/21 4:12 AM, Rémi Bernon wrote:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/ntoskrnl.exe/tests/Makefile.in | 2 +- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 299 ++++++++++++++++++++++++++++ 2 files changed, 300 insertions(+), 1 deletion(-)
First of all: nice. This is exactly the reason I wanted to add actual HID tests.
The patch looks mostly good to me, but I do have some nitpicks, inlined below.
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..f8f56c13342 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,19 +1498,150 @@ static void test_pnp_driver(struct testsign_context *ctx) SetCurrentDirectoryA(cwd); }
+#define check_hidp_caps(a, b) check_hidp_caps_(__LINE__, a, b) +static void check_hidp_caps_(int line, HIDP_CAPS *caps, const HIDP_CAPS *exp) +{
- ok_(__FILE__, line)(caps->Usage == exp->Usage, "unexpected caps Usage %x, expected %x\n", caps->Usage, exp->Usage);
- ok_(__FILE__, line)(caps->UsagePage == exp->UsagePage, "unexpected caps UsagePage %x, expected %x\n", caps->UsagePage, exp->UsagePage);
- ok_(__FILE__, line)(caps->InputReportByteLength == exp->InputReportByteLength, "unexpected caps InputReportByteLength %d, expected %d\n", caps->InputReportByteLength, exp->InputReportByteLength);
- ok_(__FILE__, line)(caps->OutputReportByteLength == exp->OutputReportByteLength, "unexpected caps OutputReportByteLength %d, expected %d\n", caps->OutputReportByteLength, exp->OutputReportByteLength);
- ok_(__FILE__, line)(caps->FeatureReportByteLength == exp->FeatureReportByteLength, "unexpected caps FeatureReportByteLength %d, expected %d\n", caps->FeatureReportByteLength, exp->FeatureReportByteLength);
- ok_(__FILE__, line)(caps->NumberLinkCollectionNodes == exp->NumberLinkCollectionNodes, "unexpected caps NumberLinkCollectionNodes %d, expected %d\n", caps->NumberLinkCollectionNodes, exp->NumberLinkCollectionNodes);
- ok_(__FILE__, line)(caps->NumberInputButtonCaps == exp->NumberInputButtonCaps, "unexpected caps NumberInputButtonCaps %d, expected %d\n", caps->NumberInputButtonCaps, exp->NumberInputButtonCaps);
- ok_(__FILE__, line)(caps->NumberInputValueCaps == exp->NumberInputValueCaps, "unexpected caps NumberInputValueCaps %d, expected %d\n", caps->NumberInputValueCaps, exp->NumberInputValueCaps);
- ok_(__FILE__, line)(caps->NumberInputDataIndices == exp->NumberInputDataIndices, "unexpected caps NumberInputDataIndices %d, expected %d\n", caps->NumberInputDataIndices, exp->NumberInputDataIndices);
- ok_(__FILE__, line)(caps->NumberOutputButtonCaps == exp->NumberOutputButtonCaps, "unexpected caps NumberOutputButtonCaps %d, expected %d\n", caps->NumberOutputButtonCaps, exp->NumberOutputButtonCaps);
- ok_(__FILE__, line)(caps->NumberOutputValueCaps == exp->NumberOutputValueCaps, "unexpected caps NumberOutputValueCaps %d, expected %d\n", caps->NumberOutputValueCaps, exp->NumberOutputValueCaps);
- ok_(__FILE__, line)(caps->NumberOutputDataIndices == exp->NumberOutputDataIndices, "unexpected caps NumberOutputDataIndices %d, expected %d\n", caps->NumberOutputDataIndices, exp->NumberOutputDataIndices);
- ok_(__FILE__, line)(caps->NumberFeatureButtonCaps == exp->NumberFeatureButtonCaps, "unexpected caps NumberFeatureButtonCaps %d, expected %d\n", caps->NumberFeatureButtonCaps, exp->NumberFeatureButtonCaps);
- ok_(__FILE__, line)(caps->NumberFeatureValueCaps == exp->NumberFeatureValueCaps, "unexpected caps NumberFeatureValueCaps %d, expected %d\n", caps->NumberFeatureValueCaps, exp->NumberFeatureValueCaps);
- ok_(__FILE__, line)(caps->NumberFeatureDataIndices == exp->NumberFeatureDataIndices, "unexpected caps NumberFeatureDataIndices %d, expected %d\n", caps->NumberFeatureDataIndices, exp->NumberFeatureDataIndices);
+}
These are some *really* long lines, and same with the ones below.
I guess it's always nice to see what exactly differs, but maybe it's more worthwhile just to use memcmp()? I don't feel strongly about it, though.
+#define check_hidp_button_caps(a, b) check_hidp_button_caps_(__LINE__, a, b) +static void check_hidp_button_caps_(int line, HIDP_BUTTON_CAPS *caps, const HIDP_BUTTON_CAPS *exp) +{
- ok_(__FILE__, line)(caps->UsagePage == exp->UsagePage, "unexpected button caps UsagePage %x, expected %x\n", caps->UsagePage, exp->UsagePage);
- ok_(__FILE__, line)(caps->ReportID == exp->ReportID, "unexpected button caps ReportID %d, expected %d\n", caps->ReportID, exp->ReportID);
- ok_(__FILE__, line)(caps->IsAlias == exp->IsAlias, "unexpected button caps IsAlias %d, expected %d\n", caps->IsAlias, exp->IsAlias);
- ok_(__FILE__, line)(caps->BitField == exp->BitField, "unexpected button caps BitField %d, expected %d\n", caps->BitField, exp->BitField);
- ok_(__FILE__, line)(caps->LinkCollection == exp->LinkCollection, "unexpected button caps LinkCollection %d, expected %d\n", caps->LinkCollection, exp->LinkCollection);
- ok_(__FILE__, line)(caps->LinkUsage == exp->LinkUsage, "unexpected button caps LinkUsage %x, expected %x\n", caps->LinkUsage, exp->LinkUsage);
- ok_(__FILE__, line)(caps->LinkUsagePage == exp->LinkUsagePage, "unexpected button caps LinkUsagePage %x, expected %x\n", caps->LinkUsagePage, exp->LinkUsagePage);
- ok_(__FILE__, line)(caps->IsRange == exp->IsRange, "unexpected button caps IsRange %d, expected %d\n", caps->IsRange, exp->IsRange);
- ok_(__FILE__, line)(caps->IsStringRange == exp->IsStringRange, "unexpected button caps IsStringRange %d, expected %d\n", caps->IsStringRange, exp->IsStringRange);
- ok_(__FILE__, line)(caps->IsDesignatorRange == exp->IsDesignatorRange, "unexpected button caps IsDesignatorRange %d, expected %d\n", caps->IsDesignatorRange, exp->IsDesignatorRange);
- ok_(__FILE__, line)(caps->IsAbsolute == exp->IsAbsolute, "unexpected button caps IsAbsolute %d, expected %d\n", caps->IsAbsolute, exp->IsAbsolute);
- if (!caps->IsRange && !exp->IsRange)
- {
ok_(__FILE__, line)(caps->NotRange.Usage == exp->NotRange.Usage, "unexpected button caps NotRange.Usage %d, expected %d\n", caps->NotRange.Usage, exp->NotRange.Usage);
ok_(__FILE__, line)(caps->NotRange.DataIndex == exp->NotRange.DataIndex, "unexpected button caps NotRange.DataIndex %d, expected %d\n", caps->NotRange.DataIndex, exp->NotRange.DataIndex);
- }
- else if (caps->IsRange && exp->IsRange)
- {
ok_(__FILE__, line)(caps->Range.UsageMin == exp->Range.UsageMin, "unexpected button caps Range.UsageMin %d, expected %d\n", caps->Range.UsageMin, exp->Range.UsageMin);
ok_(__FILE__, line)(caps->Range.UsageMax == exp->Range.UsageMax, "unexpected button caps Range.UsageMax %d, expected %d\n", caps->Range.UsageMax, exp->Range.UsageMax);
ok_(__FILE__, line)(caps->Range.DataIndexMin == exp->Range.DataIndexMin, "unexpected button caps Range.DataIndexMin %d, expected %d\n", caps->Range.DataIndexMin, exp->Range.DataIndexMin);
ok_(__FILE__, line)(caps->Range.DataIndexMax == exp->Range.DataIndexMax, "unexpected button caps Range.DataIndexMax %d, expected %d\n", caps->Range.DataIndexMax, exp->Range.DataIndexMax);
- }
- if (!caps->IsRange && !exp->IsRange)
ok_(__FILE__, line)(caps->NotRange.StringIndex == exp->NotRange.StringIndex, "unexpected button caps NotRange.StringIndex %d, expected %d\n", caps->NotRange.StringIndex, exp->NotRange.StringIndex);
- else if (caps->IsStringRange && exp->IsStringRange)
- {
ok_(__FILE__, line)(caps->Range.StringMin == exp->Range.StringMin, "unexpected button caps Range.StringMin %d, expected %d\n", caps->Range.StringMin, exp->Range.StringMin);
ok_(__FILE__, line)(caps->Range.StringMax == exp->Range.StringMax, "unexpected button caps Range.StringMax %d, expected %d\n", caps->Range.StringMax, exp->Range.StringMax);
- }
- if (!caps->IsDesignatorRange && !exp->IsDesignatorRange)
ok_(__FILE__, line)(caps->NotRange.DesignatorIndex == exp->NotRange.DesignatorIndex, "unexpected button caps NotRange.DesignatorIndex %d, expected %d\n", caps->NotRange.DesignatorIndex, exp->NotRange.DesignatorIndex);
- else if (caps->IsDesignatorRange && exp->IsDesignatorRange)
- {
ok_(__FILE__, line)(caps->Range.DesignatorMin == exp->Range.DesignatorMin, "unexpected button caps Range.DesignatorMin %d, expected %d\n", caps->Range.DesignatorMin, exp->Range.DesignatorMin);
ok_(__FILE__, line)(caps->Range.DesignatorMax == exp->Range.DesignatorMax, "unexpected button caps Range.DesignatorMax %d, expected %d\n", caps->Range.DesignatorMax, exp->Range.DesignatorMax);
- }
+}
+#define check_hidp_value_caps(a, b) check_hidp_value_caps_(__LINE__, a, b) +static void check_hidp_value_caps_(int line, HIDP_VALUE_CAPS *caps, const HIDP_VALUE_CAPS *exp) +{
- ok_(__FILE__, line)(caps->UsagePage == exp->UsagePage, "unexpected value caps UsagePage %x, expected %x\n", caps->UsagePage, exp->UsagePage);
- ok_(__FILE__, line)(caps->ReportID == exp->ReportID, "unexpected value caps ReportID %d, expected %d\n", caps->ReportID, exp->ReportID);
- ok_(__FILE__, line)(caps->IsAlias == exp->IsAlias, "unexpected value caps IsAlias %d, expected %d\n", caps->IsAlias, exp->IsAlias);
- ok_(__FILE__, line)(caps->BitField == exp->BitField, "unexpected value caps BitField %d, expected %d\n", caps->BitField, exp->BitField);
- ok_(__FILE__, line)(caps->LinkCollection == exp->LinkCollection, "unexpected value caps LinkCollection %d, expected %d\n", caps->LinkCollection, exp->LinkCollection);
- ok_(__FILE__, line)(caps->LinkUsage == exp->LinkUsage, "unexpected value caps LinkUsage %x, expected %x\n", caps->LinkUsage, exp->LinkUsage);
- ok_(__FILE__, line)(caps->LinkUsagePage == exp->LinkUsagePage, "unexpected value caps LinkUsagePage %x, expected %x\n", caps->LinkUsagePage, exp->LinkUsagePage);
- ok_(__FILE__, line)(caps->IsRange == exp->IsRange, "unexpected value caps IsRange %d, expected %d\n", caps->IsRange, exp->IsRange);
- ok_(__FILE__, line)(caps->IsStringRange == exp->IsStringRange, "unexpected value caps IsStringRange %d, expected %d\n", caps->IsStringRange, exp->IsStringRange);
- ok_(__FILE__, line)(caps->IsDesignatorRange == exp->IsDesignatorRange, "unexpected value caps IsDesignatorRange %d, expected %d\n", caps->IsDesignatorRange, exp->IsDesignatorRange);
- ok_(__FILE__, line)(caps->IsAbsolute == exp->IsAbsolute, "unexpected value caps IsAbsolute %d, expected %d\n", caps->IsAbsolute, exp->IsAbsolute);
- ok_(__FILE__, line)(caps->HasNull == exp->HasNull, "unexpected value caps HasNull %d, expected %d\n", caps->HasNull, exp->HasNull);
- ok_(__FILE__, line)(caps->BitSize == exp->BitSize, "unexpected value caps BitSize %d, expected %d\n", caps->BitSize, exp->BitSize);
- ok_(__FILE__, line)(caps->ReportCount == exp->ReportCount, "unexpected value caps ReportCount %d, expected %d\n", caps->ReportCount, exp->ReportCount);
- ok_(__FILE__, line)(caps->UnitsExp == exp->UnitsExp, "unexpected value caps UnitsExp %d, expected %d\n", caps->UnitsExp, exp->UnitsExp);
- ok_(__FILE__, line)(caps->Units == exp->Units, "unexpected value caps Units %d, expected %d\n", caps->Units, exp->Units);
- ok_(__FILE__, line)(caps->LogicalMin == exp->LogicalMin, "unexpected value caps LogicalMin %d, expected %d\n", caps->LogicalMin, -exp->LogicalMin);
- ok_(__FILE__, line)(caps->LogicalMax == exp->LogicalMax, "unexpected value caps LogicalMax %d, expected %d\n", caps->LogicalMax, exp->LogicalMax);
- ok_(__FILE__, line)(caps->PhysicalMin == exp->PhysicalMin, "unexpected value caps PhysicalMin %d, expected %d\n", caps->PhysicalMin, exp->PhysicalMin);
- ok_(__FILE__, line)(caps->PhysicalMax == exp->PhysicalMax, "unexpected value caps PhysicalMax %d, expected %d\n", caps->PhysicalMax, exp->PhysicalMax);
- if (!caps->IsRange && !exp->IsRange)
- {
ok_(__FILE__, line)(caps->NotRange.Usage == exp->NotRange.Usage, "unexpected value caps NotRange.Usage %d, expected %d\n", caps->NotRange.Usage, exp->NotRange.Usage);
ok_(__FILE__, line)(caps->NotRange.DataIndex == exp->NotRange.DataIndex, "unexpected value caps NotRange.DataIndex %d, expected %d\n", caps->NotRange.DataIndex, exp->NotRange.DataIndex);
- }
- else if (caps->IsRange && exp->IsRange)
- {
ok_(__FILE__, line)(caps->Range.UsageMin == exp->Range.UsageMin, "unexpected value caps Range.UsageMin %d, expected %d\n", caps->Range.UsageMin, exp->Range.UsageMin);
ok_(__FILE__, line)(caps->Range.UsageMax == exp->Range.UsageMax, "unexpected value caps Range.UsageMax %d, expected %d\n", caps->Range.UsageMax, exp->Range.UsageMax);
ok_(__FILE__, line)(caps->Range.DataIndexMin == exp->Range.DataIndexMin, "unexpected value caps Range.DataIndexMin %d, expected %d\n", caps->Range.DataIndexMin, exp->Range.DataIndexMin);
ok_(__FILE__, line)(caps->Range.DataIndexMax == exp->Range.DataIndexMax, "unexpected value caps Range.DataIndexMax %d, expected %d\n", caps->Range.DataIndexMax, exp->Range.DataIndexMax);
- }
- if (!caps->IsRange && !exp->IsRange)
ok_(__FILE__, line)(caps->NotRange.StringIndex == exp->NotRange.StringIndex, "unexpected value caps NotRange.StringIndex %d, expected %d\n", caps->NotRange.StringIndex, exp->NotRange.StringIndex);
- else if (caps->IsStringRange && exp->IsStringRange)
- {
ok_(__FILE__, line)(caps->Range.StringMin == exp->Range.StringMin, "unexpected value caps Range.StringMin %d, expected %d\n", caps->Range.StringMin, exp->Range.StringMin);
ok_(__FILE__, line)(caps->Range.StringMax == exp->Range.StringMax, "unexpected value caps Range.StringMax %d, expected %d\n", caps->Range.StringMax, exp->Range.StringMax);
- }
- if (!caps->IsDesignatorRange && !exp->IsDesignatorRange)
ok_(__FILE__, line)(caps->NotRange.DesignatorIndex == exp->NotRange.DesignatorIndex, "unexpected value caps NotRange.DesignatorIndex %d, expected %d\n", caps->NotRange.DesignatorIndex, exp->NotRange.DesignatorIndex);
- else if (caps->IsDesignatorRange && exp->IsDesignatorRange)
- {
ok_(__FILE__, line)(caps->Range.DesignatorMin == exp->Range.DesignatorMin, "unexpected value caps Range.DesignatorMin %d, expected %d\n", caps->Range.DesignatorMin, exp->Range.DesignatorMin);
ok_(__FILE__, line)(caps->Range.DesignatorMax == exp->Range.DesignatorMax, "unexpected value caps Range.DesignatorMax %d, expected %d\n", caps->Range.DesignatorMax, exp->Range.DesignatorMax);
- }
+}
- static void test_hid_device(void) {
- static const HIDP_CAPS expect_hidp_caps =
- {
HID_USAGE_GENERIC_JOYSTICK, HID_USAGE_PAGE_GENERIC, 5, 0, 0,
{0}, 1, 1, 3, 11, 0, 0, 0, 0, 0, 0
- };
This is of course hard to read as-is. I'm a strong proponent of using a designated initializer here.
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)};
- PHIDP_PREPARSED_DATA preparsed_data;
- HIDP_BUTTON_CAPS button_caps[16];
- HIDP_VALUE_CAPS value_caps[16]; BOOL ret, found = FALSE; OBJECT_ATTRIBUTES attr; UNICODE_STRING string; IO_STATUS_BLOCK io; NTSTATUS status;
- HIDP_CAPS caps; unsigned int i; HDEVINFO set;
- USHORT count; HANDLE file;
Maybe it'd be nice to split out the hid.dll tests into a separate function? You can tell just from the variable declarations that this one is kind of huge.
set = SetupDiGetClassDevsA(&GUID_DEVINTERFACE_HID, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
@@ -1541,6 +1674,172 @@ 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());
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);
ok(button_caps[0].UsagePage == HID_USAGE_PAGE_BUTTON, "unexpected button caps UsagePage %x, expected %x\n", button_caps[0].UsagePage, HID_USAGE_PAGE_BUTTON);
ok(button_caps[0].ReportID == 0, "unexpected button caps ReportID %d, expected %d\n", button_caps[0].ReportID, 0);
ok(!button_caps[0].IsAlias, "unexpected button caps IsAlias %d, expected %d\n", button_caps[0].IsAlias, 0);
todo_wine ok(button_caps[0].BitField == 2, "unexpected button caps BitField %d, expected %d\n", button_caps[0].BitField, 2);
ok(button_caps[0].LinkCollection == 0, "unexpected button caps LinkCollection %d, expected %d\n", button_caps[0].LinkCollection, 0);
ok(button_caps[0].LinkUsage == HID_USAGE_GENERIC_JOYSTICK, "unexpected button caps LinkUsage %x, expected %x\n", button_caps[0].LinkUsage, HID_USAGE_GENERIC_JOYSTICK);
ok(button_caps[0].LinkUsagePage == HID_USAGE_PAGE_GENERIC, "unexpected button caps LinkUsagePage %x, expected %x\n", button_caps[0].LinkUsagePage, HID_USAGE_PAGE_GENERIC);
ok(button_caps[0].IsRange, "unexpected button caps IsRange %d, expected %d\n", button_caps[0].IsRange, 1);
ok(!button_caps[0].IsStringRange, "unexpected button caps IsStringRange %d, expected %d\n", button_caps[0].IsStringRange, 0);
ok(!button_caps[0].IsDesignatorRange, "unexpected button caps IsDesignatorRange %d, expected %d\n", button_caps[0].IsDesignatorRange, 0);
ok(button_caps[0].IsAbsolute, "unexpected button caps IsAbsolute %d, expected %d\n", button_caps[0].IsAbsolute, 1);
ok(button_caps[0].Range.UsageMin == 1, "unexpected button caps Range.UsageMin %d, expected %d\n", button_caps[0].Range.UsageMin, 1);
ok(button_caps[0].Range.UsageMax == 8, "unexpected button caps Range.UsageMax %d, expected %d\n", button_caps[0].Range.UsageMax, 8);
ok(button_caps[0].Range.StringMin == 0, "unexpected button caps Range.StringMin %d, expected %d\n", button_caps[0].Range.StringMin, 0);
ok(button_caps[0].Range.StringMax == 0, "unexpected button caps Range.StringMax %d, expected %d\n", button_caps[0].Range.StringMax, 0);
ok(button_caps[0].Range.DesignatorMin == 0, "unexpected button caps Range.DesignatorMin %d, expected %d\n", button_caps[0].Range.DesignatorMin, 0);
ok(button_caps[0].Range.DesignatorMax == 0, "unexpected button caps Range.DesignatorMax %d, expected %d\n", button_caps[0].Range.DesignatorMax, 0);
ok(button_caps[0].Range.DataIndexMin == 2, "unexpected button caps Range.DataIndexMin %d, expected %d\n", button_caps[0].Range.DataIndexMin, 2);
ok(button_caps[0].Range.DataIndexMax == 9, "unexpected button caps Range.DataIndexMax %d, expected %d\n", button_caps[0].Range.DataIndexMax, 9);
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_GetValueCaps 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_GetValueCaps 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_GetValueCaps 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);
ok(value_caps[0].UsagePage == HID_USAGE_PAGE_GENERIC, "unexpected value caps UsagePage %x, expected %x\n", value_caps[0].UsagePage, HID_USAGE_PAGE_GENERIC);
ok(value_caps[0].ReportID == 0, "unexpected value caps ReportID %d, expected %d\n", value_caps[0].ReportID, 0);
ok(value_caps[0].IsAlias == 0, "unexpected value caps IsAlias %d, expected %d\n", value_caps[0].IsAlias, 0);
todo_wine ok(value_caps[0].BitField == 2, "unexpected value caps BitField %d, expected %d\n", value_caps[0].BitField, 2);
ok(value_caps[0].LinkCollection == 0, "unexpected value caps LinkCollection %d, expected %d\n", value_caps[0].LinkCollection, 0);
ok(value_caps[0].LinkUsage == HID_USAGE_GENERIC_JOYSTICK, "unexpected value caps LinkUsage %x, expected %x\n", value_caps[0].LinkUsage, HID_USAGE_GENERIC_JOYSTICK);
ok(value_caps[0].LinkUsagePage == HID_USAGE_PAGE_GENERIC, "unexpected value caps LinkUsagePage %x, expected %x\n", value_caps[0].LinkUsagePage, HID_USAGE_PAGE_GENERIC);
ok(!value_caps[0].IsRange, "unexpected value caps IsRange %d, expected %d\n", value_caps[0].IsRange, 0);
ok(!value_caps[0].IsStringRange, "unexpected value caps IsStringRange %d, expected %d\n", value_caps[0].IsStringRange, 0);
ok(!value_caps[0].IsDesignatorRange, "unexpected value caps IsDesignatorRange %d, expected %d\n", value_caps[0].IsDesignatorRange, 0);
ok(value_caps[0].IsAbsolute, "unexpected value caps IsAbsolute %d, expected %d\n", value_caps[0].IsAbsolute, 1);
ok(value_caps[0].HasNull == 0, "unexpected value caps HasNull %d, expected %d\n", value_caps[0].HasNull, 0);
ok(value_caps[0].BitSize == 8, "unexpected value caps BitSize %d, expected %d\n", value_caps[0].BitSize, 8);
ok(value_caps[0].ReportCount == 1, "unexpected value caps ReportCount %d, expected %d\n", value_caps[0].ReportCount, 1);
ok(value_caps[0].UnitsExp == 0, "unexpected value caps UnitsExp %d, expected %d\n", value_caps[0].UnitsExp, 0);
ok(value_caps[0].Units == 0, "unexpected value caps Units %d, expected %d\n", value_caps[0].Units, 0);
ok(value_caps[0].LogicalMin == -128, "unexpected value caps LogicalMin %d, expected %d\n", value_caps[0].LogicalMin, -128);
ok(value_caps[0].LogicalMax == 127, "unexpected value caps LogicalMax %d, expected %d\n", value_caps[0].LogicalMax, 127);
ok(value_caps[0].PhysicalMin == 0, "unexpected value caps PhysicalMin %d, expected %d\n", value_caps[0].PhysicalMin, 0);
ok(value_caps[0].PhysicalMax == 0, "unexpected value caps PhysicalMax %d, expected %d\n", value_caps[0].PhysicalMax, 0);
todo_wine ok(value_caps[0].NotRange.Usage == HID_USAGE_GENERIC_Y, "unexpected value caps NotRange.Usage %d, expected %d\n", value_caps[0].NotRange.Usage, HID_USAGE_GENERIC_Y);
ok(value_caps[0].NotRange.StringIndex == 0, "unexpected value caps NotRange.StringIndex %d, expected %d\n", value_caps[0].NotRange.StringIndex, 0);
ok(value_caps[0].NotRange.DesignatorIndex == 0, "unexpected value caps NotRange.DesignatorIndex %d, expected %d\n", value_caps[0].NotRange.DesignatorIndex, 0);
ok(value_caps[0].NotRange.DataIndex == 0, "unexpected value caps NotRange.DataIndex %d, expected %d\n", value_caps[0].NotRange.DataIndex, 0);
todo_wine ok(value_caps[1].NotRange.Usage == HID_USAGE_GENERIC_X, "unexpected value caps NotRange.Usage %d, expected %d\n", value_caps[1].NotRange.Usage, HID_USAGE_GENERIC_X);
ok(value_caps[2].NotRange.Usage == HID_USAGE_GENERIC_HATSWITCH, "unexpected value caps NotRange.Usage %d, expected %d\n", value_caps[2].NotRange.Usage, HID_USAGE_GENERIC_HATSWITCH);
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);
RtlInitUnicodeString(&string, L"\??\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}");
On 6/8/21 10:59 PM, Zebediah Figura (she/her) wrote:
exp->NumberFeatureDataIndices, "unexpected caps NumberFeatureDataIndices %d, expected %d\n", caps->NumberFeatureDataIndices, exp->NumberFeatureDataIndices); +}
These are some *really* long lines, and same with the ones below.
I guess it's always nice to see what exactly differs, but maybe it's more worthwhile just to use memcmp()? I don't feel strongly about it, though.
I think memcmp is fine up to the moment where the test breaks. To debug the issue it's nice to see what didn't match without having to write those long lines yourself (same for debugstr BTW, I'd love to have more helpers to dump the various Win32 structs readily available).
And for instance I don't like the report memcmp very much, because it doesn't tell you at all what's wrong with HidP_InitializeReportForID.
This only needs to be written once and (hopefully) nobody will have to look at it again. But then you can use it to check that both struct match and have precise info when they don't.
I would have like to be able to put individual todo_wine to replace the additional tests for the partially matching structs, but it was not convenient, so instead I'm just going to replace all the checks with a single call to these functions when the todo_wine are fixed.
I can wrap the lines though ;)
On 6/8/21 4:10 PM, Rémi Bernon wrote:
On 6/8/21 10:59 PM, Zebediah Figura (she/her) wrote:
exp->NumberFeatureDataIndices, "unexpected caps NumberFeatureDataIndices %d, expected %d\n", caps->NumberFeatureDataIndices, exp->NumberFeatureDataIndices); +}
These are some *really* long lines, and same with the ones below.
I guess it's always nice to see what exactly differs, but maybe it's more worthwhile just to use memcmp()? I don't feel strongly about it, though.
I think memcmp is fine up to the moment where the test breaks. To debug the issue it's nice to see what didn't match without having to write those long lines yourself (same for debugstr BTW, I'd love to have more helpers to dump the various Win32 structs readily available).
And for instance I don't like the report memcmp very much, because it doesn't tell you at all what's wrong with HidP_InitializeReportForID.
This only needs to be written once and (hopefully) nobody will have to look at it again. But then you can use it to check that both struct match and have precise info when they don't.
I would have like to be able to put individual todo_wine to replace the additional tests for the partially matching structs, but it was not convenient, so instead I'm just going to replace all the checks with a single call to these functions when the todo_wine are fixed.
Yeah, though on the other hand that's one reason it's nice to use memcmp - either they match or they don't.
Just a bit of extra 2¢: in DirectShow I ended up using memcmp() to match AM_MEDIA_TYPE. If a test breaks, which is not infrequently, I temporarily add strmbase_dump_media_type() to check the difference. Actually I've considered adding an automatic helper like that to compare_media_types() everywhere, though it'd be nice to have a debugstr_* type helper instead so that I don't have to turn on +strmbase to use it.
It may be a nice approach in general to structure things like
static bool compare_some_struct(const SOME_STRUCT *s, const SOME_STRUCT *expect) { if (!memcmp(s, expect, sizeof(*SOME_STRUCT))) return true; trace("Expected: %s\n", debugstr_some_struct(expect)); trace("Received: %s\n", debugstr_some_struct(s)); }
...
{ ok(compare_some_struct(&s, &expect), "Structures didn't match.\n"); }
Just brainstorming, but some apparent advantages:
* easy to read,
* easy to reuse debugstr_some_struct() in other places, including implementation (granted, we may need to copy code around, but that's still code sharing ultimately. Personally I'd like to see Wine be more amenable to adding internal helpers, though.)
* less risk of making copy-paste errors or accidentally skipping elements,
* makes dealing with todo_wine easier, including partial todo_wine,
* no need to do the __LINE__ hack.
One thing that would be nice to have, while we're at it, is a debugstr_bytes() helper; maybe also debugstr_ints(). That'd be nice in general, but could also serve as a poor man's debugstr_some_struct().
Maybe I'll start workshopping some of these; apparently 2021 is the year that I improve our testing infrastructure...
I can wrap the lines though ;)
That would be nice ;-)
On 6/8/21 11:27 PM, Zebediah Figura (she/her) wrote:
On 6/8/21 4:10 PM, Rémi Bernon wrote:
On 6/8/21 10:59 PM, Zebediah Figura (she/her) wrote:
exp->NumberFeatureDataIndices, "unexpected caps NumberFeatureDataIndices %d, expected %d\n", caps->NumberFeatureDataIndices, exp->NumberFeatureDataIndices); +}
These are some *really* long lines, and same with the ones below.
I guess it's always nice to see what exactly differs, but maybe it's more worthwhile just to use memcmp()? I don't feel strongly about it, though.
I think memcmp is fine up to the moment where the test breaks. To debug the issue it's nice to see what didn't match without having to write those long lines yourself (same for debugstr BTW, I'd love to have more helpers to dump the various Win32 structs readily available).
And for instance I don't like the report memcmp very much, because it doesn't tell you at all what's wrong with HidP_InitializeReportForID.
This only needs to be written once and (hopefully) nobody will have to look at it again. But then you can use it to check that both struct match and have precise info when they don't.
I would have like to be able to put individual todo_wine to replace the additional tests for the partially matching structs, but it was not convenient, so instead I'm just going to replace all the checks with a single call to these functions when the todo_wine are fixed.
Yeah, though on the other hand that's one reason it's nice to use memcmp
- either they match or they don't.
Just a bit of extra 2¢: in DirectShow I ended up using memcmp() to match AM_MEDIA_TYPE. If a test breaks, which is not infrequently, I temporarily add strmbase_dump_media_type() to check the difference. Actually I've considered adding an automatic helper like that to compare_media_types() everywhere, though it'd be nice to have a debugstr_* type helper instead so that I don't have to turn on +strmbase to use it.
It may be a nice approach in general to structure things like
static bool compare_some_struct(const SOME_STRUCT *s, const SOME_STRUCT *expect) { if (!memcmp(s, expect, sizeof(*SOME_STRUCT))) return true; trace("Expected: %s\n", debugstr_some_struct(expect)); trace("Received: %s\n", debugstr_some_struct(s)); }
...
{ ok(compare_some_struct(&s, &expect), "Structures didn't match.\n"); }
I don't have good opinion of trace-ing failures, I find that it quickly gets cut, and in general the traces you were interested it are after the cut.
On 6/8/21 4:33 PM, Rémi Bernon wrote:
On 6/8/21 11:27 PM, Zebediah Figura (she/her) wrote:
On 6/8/21 4:10 PM, Rémi Bernon wrote:
On 6/8/21 10:59 PM, Zebediah Figura (she/her) wrote:
exp->NumberFeatureDataIndices, "unexpected caps NumberFeatureDataIndices %d, expected %d\n", caps->NumberFeatureDataIndices, exp->NumberFeatureDataIndices); +}
These are some *really* long lines, and same with the ones below.
I guess it's always nice to see what exactly differs, but maybe it's more worthwhile just to use memcmp()? I don't feel strongly about it, though.
I think memcmp is fine up to the moment where the test breaks. To debug the issue it's nice to see what didn't match without having to write those long lines yourself (same for debugstr BTW, I'd love to have more helpers to dump the various Win32 structs readily available).
And for instance I don't like the report memcmp very much, because it doesn't tell you at all what's wrong with HidP_InitializeReportForID.
This only needs to be written once and (hopefully) nobody will have to look at it again. But then you can use it to check that both struct match and have precise info when they don't.
I would have like to be able to put individual todo_wine to replace the additional tests for the partially matching structs, but it was not convenient, so instead I'm just going to replace all the checks with a single call to these functions when the todo_wine are fixed.
Yeah, though on the other hand that's one reason it's nice to use memcmp - either they match or they don't.
Just a bit of extra 2¢: in DirectShow I ended up using memcmp() to match AM_MEDIA_TYPE. If a test breaks, which is not infrequently, I temporarily add strmbase_dump_media_type() to check the difference. Actually I've considered adding an automatic helper like that to compare_media_types() everywhere, though it'd be nice to have a debugstr_* type helper instead so that I don't have to turn on +strmbase to use it.
It may be a nice approach in general to structure things like
static bool compare_some_struct(const SOME_STRUCT *s, const SOME_STRUCT *expect) { if (!memcmp(s, expect, sizeof(*SOME_STRUCT))) return true; trace("Expected: %s\n", debugstr_some_struct(expect)); trace("Received: %s\n", debugstr_some_struct(s)); }
...
{ ok(compare_some_struct(&s, &expect), "Structures didn't match.\n"); }
I don't have good opinion of trace-ing failures, I find that it quickly gets cut, and in general the traces you were interested it are after the cut.
Sorry, I'm not sure I understand what you mean by this; can you please clarify?
On 6/8/21 11:35 PM, Zebediah Figura (she/her) wrote:
On 6/8/21 4:33 PM, Rémi Bernon wrote:
On 6/8/21 11:27 PM, Zebediah Figura (she/her) wrote:
On 6/8/21 4:10 PM, Rémi Bernon wrote:
On 6/8/21 10:59 PM, Zebediah Figura (she/her) wrote:
exp->NumberFeatureDataIndices, "unexpected caps NumberFeatureDataIndices %d, expected %d\n", caps->NumberFeatureDataIndices, exp->NumberFeatureDataIndices); +}
These are some *really* long lines, and same with the ones below.
I guess it's always nice to see what exactly differs, but maybe it's more worthwhile just to use memcmp()? I don't feel strongly about it, though.
I think memcmp is fine up to the moment where the test breaks. To debug the issue it's nice to see what didn't match without having to write those long lines yourself (same for debugstr BTW, I'd love to have more helpers to dump the various Win32 structs readily available).
And for instance I don't like the report memcmp very much, because it doesn't tell you at all what's wrong with HidP_InitializeReportForID.
This only needs to be written once and (hopefully) nobody will have to look at it again. But then you can use it to check that both struct match and have precise info when they don't.
I would have like to be able to put individual todo_wine to replace the additional tests for the partially matching structs, but it was not convenient, so instead I'm just going to replace all the checks with a single call to these functions when the todo_wine are fixed.
Yeah, though on the other hand that's one reason it's nice to use memcmp - either they match or they don't.
Just a bit of extra 2¢: in DirectShow I ended up using memcmp() to match AM_MEDIA_TYPE. If a test breaks, which is not infrequently, I temporarily add strmbase_dump_media_type() to check the difference. Actually I've considered adding an automatic helper like that to compare_media_types() everywhere, though it'd be nice to have a debugstr_* type helper instead so that I don't have to turn on +strmbase to use it.
It may be a nice approach in general to structure things like
static bool compare_some_struct(const SOME_STRUCT *s, const SOME_STRUCT *expect) { if (!memcmp(s, expect, sizeof(*SOME_STRUCT))) return true; trace("Expected: %s\n", debugstr_some_struct(expect)); trace("Received: %s\n", debugstr_some_struct(s)); }
...
{ ok(compare_some_struct(&s, &expect), "Structures didn't match.\n"); }
I don't have good opinion of trace-ing failures, I find that it quickly gets cut, and in general the traces you were interested it are after the cut.
Sorry, I'm not sure I understand what you mean by this; can you please clarify?
Eh sorry for my bad english, I mean that traces are muted after a being printed too many times, and it happens too often when I needed the traces.
On 6/8/21 4:37 PM, Rémi Bernon wrote:
On 6/8/21 11:35 PM, Zebediah Figura (she/her) wrote:
On 6/8/21 4:33 PM, Rémi Bernon wrote:
On 6/8/21 11:27 PM, Zebediah Figura (she/her) wrote:
On 6/8/21 4:10 PM, Rémi Bernon wrote:
On 6/8/21 10:59 PM, Zebediah Figura (she/her) wrote:
> exp->NumberFeatureDataIndices, "unexpected caps > NumberFeatureDataIndices %d, expected %d\n", > caps->NumberFeatureDataIndices, exp->NumberFeatureDataIndices); > +}
These are some *really* long lines, and same with the ones below.
I guess it's always nice to see what exactly differs, but maybe it's more worthwhile just to use memcmp()? I don't feel strongly about it, though.
I think memcmp is fine up to the moment where the test breaks. To debug the issue it's nice to see what didn't match without having to write those long lines yourself (same for debugstr BTW, I'd love to have more helpers to dump the various Win32 structs readily available).
And for instance I don't like the report memcmp very much, because it doesn't tell you at all what's wrong with HidP_InitializeReportForID.
This only needs to be written once and (hopefully) nobody will have to look at it again. But then you can use it to check that both struct match and have precise info when they don't.
I would have like to be able to put individual todo_wine to replace the additional tests for the partially matching structs, but it was not convenient, so instead I'm just going to replace all the checks with a single call to these functions when the todo_wine are fixed.
Yeah, though on the other hand that's one reason it's nice to use memcmp - either they match or they don't.
Just a bit of extra 2¢: in DirectShow I ended up using memcmp() to match AM_MEDIA_TYPE. If a test breaks, which is not infrequently, I temporarily add strmbase_dump_media_type() to check the difference. Actually I've considered adding an automatic helper like that to compare_media_types() everywhere, though it'd be nice to have a debugstr_* type helper instead so that I don't have to turn on +strmbase to use it.
It may be a nice approach in general to structure things like
static bool compare_some_struct(const SOME_STRUCT *s, const SOME_STRUCT *expect) { if (!memcmp(s, expect, sizeof(*SOME_STRUCT))) return true; trace("Expected: %s\n", debugstr_some_struct(expect)); trace("Received: %s\n", debugstr_some_struct(s)); }
...
{ ok(compare_some_struct(&s, &expect), "Structures didn't match.\n"); }
I don't have good opinion of trace-ing failures, I find that it quickly gets cut, and in general the traces you were interested it are after the cut.
Sorry, I'm not sure I understand what you mean by this; can you please clarify?
Eh sorry for my bad english, I mean that traces are muted after a being printed too many times, and it happens too often when I needed the traces.
Yes, I find the choice of defaults is a bit unfortunate, I'd rather see muting off by default, and enabled only for things like the testbot where we really care about report length.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/hid/hidp.c | 3 +++ dlls/ntoskrnl.exe/tests/ntoskrnl.c | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+)
diff --git a/dlls/hid/hidp.c b/dlls/hid/hidp.c index c4d162695a9..fd2ac86da32 100644 --- a/dlls/hid/hidp.c +++ b/dlls/hid/hidp.c @@ -1002,6 +1002,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;
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index f8f56c13342..099f747ff86 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -1630,10 +1630,12 @@ static void test_hid_device(void) SP_DEVICE_INTERFACE_DETAIL_DATA_A *iface_detail = (void *)buffer; SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}; SP_DEVINFO_DATA device = {sizeof(device)}; + HIDP_LINK_COLLECTION_NODE collections[16]; PHIDP_PREPARSED_DATA preparsed_data; HIDP_BUTTON_CAPS button_caps[16]; HIDP_VALUE_CAPS value_caps[16]; BOOL ret, found = FALSE; + DWORD collection_count; OBJECT_ATTRIBUTES attr; UNICODE_STRING string; IO_STATUS_BLOCK io; @@ -1684,6 +1686,26 @@ static void test_hid_device(void) 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, "HidP_GetLinkCollectionNodes returned count %d, 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, "HidP_GetLinkCollectionNodes returned count %d, expected %d\n", collection_count, caps.NumberLinkCollectionNodes); + + ok(collections[0].LinkUsage == HID_USAGE_GENERIC_JOYSTICK, "unexpected collection LinkUsage %x, expected %x\n", collections[0].LinkUsage, HID_USAGE_GENERIC_JOYSTICK); + ok(collections[0].LinkUsagePage == HID_USAGE_PAGE_GENERIC, "unexpected collection LinkUsagePage %x, expected %x\n", collections[0].LinkUsagePage, HID_USAGE_PAGE_GENERIC); + ok(collections[0].Parent == 0, "unexpected collection Parent %d, expected %d\n", collections[0].Parent, 0); + ok(collections[0].NumberOfChildren == 0, "unexpected collection NumberOfChildren %d, expected %d\n", collections[0].NumberOfChildren, 0); + ok(collections[0].NextSibling == 0, "unexpected collection NextSibling %d, expected %d\n", collections[0].NextSibling, 0); + ok(collections[0].FirstChild == 0, "unexpected collection FirstChild %d, expected %d\n", collections[0].FirstChild, 0); + ok(collections[0].CollectionType == 1, "unexpected collection CollectionType %d, expected %d\n", collections[0].CollectionType, 1); + ok(collections[0].IsAlias == 0, "unexpected collection IsAlias %d, expected %d\n", collections[0].IsAlias, 0); + 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);
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=91879
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)
On 6/4/21 4:12 AM, Rémi Bernon wrote:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/hid/hidp.c | 3 +++ dlls/ntoskrnl.exe/tests/ntoskrnl.c | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+)
diff --git a/dlls/hid/hidp.c b/dlls/hid/hidp.c index c4d162695a9..fd2ac86da32 100644 --- a/dlls/hid/hidp.c +++ b/dlls/hid/hidp.c @@ -1002,6 +1002,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;
It's not a huge deal, but it does bother me when a patch nominally against the tests modifies the implementation...
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index f8f56c13342..099f747ff86 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -1630,10 +1630,12 @@ static void test_hid_device(void) SP_DEVICE_INTERFACE_DETAIL_DATA_A *iface_detail = (void *)buffer; SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}; SP_DEVINFO_DATA device = {sizeof(device)};
- HIDP_LINK_COLLECTION_NODE collections[16]; PHIDP_PREPARSED_DATA preparsed_data; HIDP_BUTTON_CAPS button_caps[16]; HIDP_VALUE_CAPS value_caps[16]; BOOL ret, found = FALSE;
- DWORD collection_count; OBJECT_ATTRIBUTES attr; UNICODE_STRING string; IO_STATUS_BLOCK io;
@@ -1684,6 +1686,26 @@ static void test_hid_device(void) 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, "HidP_GetLinkCollectionNodes returned count %d, 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, "HidP_GetLinkCollectionNodes returned count %d, expected %d\n", collection_count, caps.NumberLinkCollectionNodes);
- ok(collections[0].LinkUsage == HID_USAGE_GENERIC_JOYSTICK, "unexpected collection LinkUsage %x, expected %x\n", collections[0].LinkUsage, HID_USAGE_GENERIC_JOYSTICK);
- ok(collections[0].LinkUsagePage == HID_USAGE_PAGE_GENERIC, "unexpected collection LinkUsagePage %x, expected %x\n", collections[0].LinkUsagePage, HID_USAGE_PAGE_GENERIC);
- ok(collections[0].Parent == 0, "unexpected collection Parent %d, expected %d\n", collections[0].Parent, 0);
- ok(collections[0].NumberOfChildren == 0, "unexpected collection NumberOfChildren %d, expected %d\n", collections[0].NumberOfChildren, 0);
- ok(collections[0].NextSibling == 0, "unexpected collection NextSibling %d, expected %d\n", collections[0].NextSibling, 0);
- ok(collections[0].FirstChild == 0, "unexpected collection FirstChild %d, expected %d\n", collections[0].FirstChild, 0);
- ok(collections[0].CollectionType == 1, "unexpected collection CollectionType %d, expected %d\n", collections[0].CollectionType, 1);
- ok(collections[0].IsAlias == 0, "unexpected collection IsAlias %d, expected %d\n", collections[0].IsAlias, 0);
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);
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index 099f747ff86..bd7dc2093e9 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -1626,7 +1626,7 @@ static void test_hid_device(void) {0}, 1, 1, 3, 11, 0, 0, 0, 0, 0, 0 };
- char buffer[200]; + char buffer[200], report[200]; SP_DEVICE_INTERFACE_DETAIL_DATA_A *iface_detail = (void *)buffer; SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}; SP_DEVINFO_DATA device = {sizeof(device)}; @@ -1861,6 +1861,24 @@ static void test_hid_device(void) 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);
+ 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, 5); + buffer[0] = 0; + 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=91880
Your paranoid android.
=== w864 (64 bit report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl crashed (c0000374)
On 6/4/21 4:12 AM, Rémi Bernon wrote:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/ntoskrnl.exe/tests/ntoskrnl.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index 099f747ff86..bd7dc2093e9 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -1626,7 +1626,7 @@ static void test_hid_device(void) {0}, 1, 1, 3, 11, 0, 0, 0, 0, 0, 0 };
- char buffer[200];
- char buffer[200], report[200]; SP_DEVICE_INTERFACE_DETAIL_DATA_A *iface_detail = (void *)buffer; SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}; SP_DEVINFO_DATA device = {sizeof(device)};
@@ -1861,6 +1861,24 @@ static void test_hid_device(void) 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);
- 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, 5);
- buffer[0] = 0;
This statement is redundant; is there a copy-paste error here?
- ok(!memcmp(buffer, report, sizeof(buffer)), "unexpected report data\n");
HidD_FreePreparsedData(preparsed_data); CloseHandle(file);
On 6/8/21 10:50 PM, Zebediah Figura (she/her) wrote:
+ 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, 5); + buffer[0] = 0;
This statement is redundant; is there a copy-paste error here?
I was doing some tests with report IDs, and I'm going to add tests with it, it's probably some left over code from a version with an ID which I then set to 0.
I've got additional patches that will change that part again, so this patch can just be ignored and I'll make another version that better fits with the later changes.
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=91875
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
ntoskrnl.exe: driver.c:272: Test failed: Got unexpected test_load_image_notify_count 0. ntoskrnl.c:1234: Test failed: got 0 bus arrival messages ntoskrnl.c:1250: Test failed: got 0 bus arrival messages
=== w8 (32 bit report) ===
ntoskrnl.exe: driver.c:272: Test failed: Got unexpected test_load_image_notify_count 0.
On 6/4/21 11:12 AM, Rémi Bernon wrote:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
v3: Minor changes, drop the controversial test fixups, let's ignore the spurious failures for now.
Tweak the silent logic as requested, squeeze in a few more tests. The spurious w864 crash doesn't seem to be related to the patches, it happens there from time to time when the driver tests aren't executed and is probably caused by some invalid cleanup. FWIW, when I force start_driver code to fail on Wine in the same way it's failing on this machine, I also get a winedevice crash after the test has exited, on a call to PsGetCurrentProcessId() in winetest_cleanup. I have no idea if it's the same kind of thing, but it looks fishy.
dlls/ntoskrnl.exe/tests/driver_hid.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/tests/driver_hid.c b/dlls/ntoskrnl.exe/tests/driver_hid.c index 44ec1b09526..0f626e6866c 100644 --- a/dlls/ntoskrnl.exe/tests/driver_hid.c +++ b/dlls/ntoskrnl.exe/tests/driver_hid.c @@ -103,6 +103,7 @@ static const unsigned char report_descriptor[] =
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; const ULONG out_size = stack->Parameters.DeviceIoControl.OutputBufferLength;
@@ -175,11 +176,15 @@ static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device, IRP *irp) }
case IOCTL_HID_READ_REPORT:
{
ULONG expected_size = 2; ok(!in_size, "got input size %u\n", in_size);
todo_wine ok(out_size == 2, "got output size %u\n", out_size);
if (!test_failed) todo_wine ok(out_size == expected_size, "got output size %u\n", out_size);
if (out_size != expected_size) test_failed = TRUE; ret = STATUS_NOT_IMPLEMENTED; break;
} case IOCTL_HID_GET_STRING: ok(!in_size, "got input size %u\n", in_size);
Hi!
Should I do something different for this series? I don't think the failures here are related to the additional tests.
Would it be better maybe to share the hid macros with PARENTSRC or move them to some public wine include?
Then it's not very convenient that the tests have to live in ntoskrnl.exe, and hid/hidclass.sys changes won't trigger any test run unless they touch some todo_wine.
The only other way I could think of to test HidP functions separately would be to dump PHIDP_PREPARSED_DATA blobs somehow and add them to hid/hidclass.sys tests, and it doesn't seem very robust.
Cheers,