Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
The idea for this series is to have the driver-based HID test live in dlls/hid/tests instead of ntoskrnl.exe, as it probably should.
The driver_hid source and the other driver test utility, however, aren't moved. I think it would be inconvenient to duplicate the driver test utility code, but moreover because I intend to make driver_hid much more flexible and to share it in other modules tests if possible.
The actual driver test cases will be entirely controlled from the test executables instead of being hardcoded in the driver, and we'll then be able to use it to create virtual devices and test them from the user side.
For APIs such as DInput, it will allow us to have test cases without requiring actual devices, and even better, test cases with controlled input, or specific device features, such as force-feedback.
dlls/ntoskrnl.exe/tests/driver_tests.h | 565 ++++++++++++++++++++++ dlls/ntoskrnl.exe/tests/ntoskrnl.c | 630 +------------------------ 2 files changed, 583 insertions(+), 612 deletions(-) create mode 100644 dlls/ntoskrnl.exe/tests/driver_tests.h
diff --git a/dlls/ntoskrnl.exe/tests/driver_tests.h b/dlls/ntoskrnl.exe/tests/driver_tests.h new file mode 100644 index 00000000000..dee183154e8 --- /dev/null +++ b/dlls/ntoskrnl.exe/tests/driver_tests.h @@ -0,0 +1,565 @@ +/* + * ntoskrnl.exe testing framework + * + * Copyright 2015 Sebastian Lackner + * Copyright 2015 Michael Müller + * Copyright 2015 Christian Costa + * Copyright 2020-2021 Zebediah Figura 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 <stdarg.h> +#include <stddef.h> +#include <time.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winioctl.h" +#include "winternl.h" +#include "winuser.h" +#include "winnls.h" +#include "winsvc.h" +#include "winreg.h" +#include "wincrypt.h" + +#include "mscat.h" +#include "newdev.h" +#include "ntsecapi.h" +#include "objbase.h" +#include "setupapi.h" + +#include "wine/mssign.h" +#include "wine/test.h" + +#include "driver.h" + +static HANDLE test_data_mapping; +static struct test_data *test_data; + +static HRESULT (WINAPI *pSignerSign)(SIGNER_SUBJECT_INFO *subject, SIGNER_CERT *cert, + SIGNER_SIGNATURE_INFO *signature, SIGNER_PROVIDER_INFO *provider, + const WCHAR *timestamp, CRYPT_ATTRIBUTES *attr, void *sip_data); + +#define load_resource (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : load_resource_ +static void load_resource_(const WCHAR *name, WCHAR *filename) +{ + static WCHAR path[MAX_PATH]; + DWORD written; + HANDLE file; + HRSRC res; + void *ptr; + + GetTempPathW(ARRAY_SIZE(path), path); + GetTempFileNameW(path, name, 0, filename); + + file = CreateFileW(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + winetest_ok(file != INVALID_HANDLE_VALUE, "failed to create %s, error %u\n", debugstr_w(filename), GetLastError()); + + res = FindResourceW(NULL, name, L"TESTDLL"); + winetest_ok( res != 0, "couldn't find resource\n" ); + ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res )); + WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL ); + winetest_ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" ); + CloseHandle( file ); +} + +struct testsign_context +{ + HCRYPTPROV provider; + const CERT_CONTEXT *cert, *root_cert, *publisher_cert; + HCERTSTORE root_store, publisher_store; +}; + +static BOOL testsign_create_cert(struct testsign_context *ctx) +{ + BYTE encoded_name[100], encoded_key_id[200], public_key_info_buffer[1000]; + WCHAR container_name[26]; + BYTE hash_buffer[16], cert_buffer[1000], provider_nameA[100], serial[16]; + CERT_PUBLIC_KEY_INFO *public_key_info = (CERT_PUBLIC_KEY_INFO *)public_key_info_buffer; + CRYPT_KEY_PROV_INFO provider_info = {0}; + CRYPT_ALGORITHM_IDENTIFIER algid = {0}; + CERT_AUTHORITY_KEY_ID_INFO key_info; + CERT_INFO cert_info = {0}; + WCHAR provider_nameW[100]; + CERT_EXTENSION extension; + HCRYPTKEY key; + DWORD size; + BOOL ret; + + memset(ctx, 0, sizeof(*ctx)); + + srand(time(NULL)); + swprintf(container_name, ARRAY_SIZE(container_name), L"wine_testsign%u", rand()); + + ret = CryptAcquireContextW(&ctx->provider, container_name, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET); + winetest_ok(ret, "Failed to create container, error %#x\n", GetLastError()); + + ret = CryptGenKey(ctx->provider, AT_SIGNATURE, CRYPT_EXPORTABLE, &key); + winetest_ok(ret, "Failed to create key, error %#x\n", GetLastError()); + ret = CryptDestroyKey(key); + winetest_ok(ret, "Failed to destroy key, error %#x\n", GetLastError()); + ret = CryptGetUserKey(ctx->provider, AT_SIGNATURE, &key); + winetest_ok(ret, "Failed to get user key, error %#x\n", GetLastError()); + ret = CryptDestroyKey(key); + winetest_ok(ret, "Failed to destroy key, error %#x\n", GetLastError()); + + size = sizeof(encoded_name); + ret = CertStrToNameA(X509_ASN_ENCODING, "CN=winetest_cert", CERT_X500_NAME_STR, NULL, encoded_name, &size, NULL); + winetest_ok(ret, "Failed to convert name, error %#x\n", GetLastError()); + key_info.CertIssuer.cbData = size; + key_info.CertIssuer.pbData = encoded_name; + + size = sizeof(public_key_info_buffer); + ret = CryptExportPublicKeyInfo(ctx->provider, AT_SIGNATURE, X509_ASN_ENCODING, public_key_info, &size); + winetest_ok(ret, "Failed to export public key, error %#x\n", GetLastError()); + cert_info.SubjectPublicKeyInfo = *public_key_info; + + size = sizeof(hash_buffer); + ret = CryptHashPublicKeyInfo(ctx->provider, CALG_MD5, 0, X509_ASN_ENCODING, public_key_info, hash_buffer, &size); + winetest_ok(ret, "Failed to hash public key, error %#x\n", GetLastError()); + + key_info.KeyId.cbData = size; + key_info.KeyId.pbData = hash_buffer; + + RtlGenRandom(serial, sizeof(serial)); + key_info.CertSerialNumber.cbData = sizeof(serial); + key_info.CertSerialNumber.pbData = serial; + + size = sizeof(encoded_key_id); + ret = CryptEncodeObject(X509_ASN_ENCODING, X509_AUTHORITY_KEY_ID, &key_info, encoded_key_id, &size); + winetest_ok(ret, "Failed to convert name, error %#x\n", GetLastError()); + + extension.pszObjId = (char *)szOID_AUTHORITY_KEY_IDENTIFIER; + extension.fCritical = TRUE; + extension.Value.cbData = size; + extension.Value.pbData = encoded_key_id; + + cert_info.dwVersion = CERT_V3; + cert_info.SerialNumber = key_info.CertSerialNumber; + cert_info.SignatureAlgorithm.pszObjId = (char *)szOID_RSA_SHA1RSA; + cert_info.Issuer = key_info.CertIssuer; + GetSystemTimeAsFileTime(&cert_info.NotBefore); + GetSystemTimeAsFileTime(&cert_info.NotAfter); + cert_info.NotAfter.dwHighDateTime += 1; + cert_info.Subject = key_info.CertIssuer; + cert_info.cExtension = 1; + cert_info.rgExtension = &extension; + algid.pszObjId = (char *)szOID_RSA_SHA1RSA; + size = sizeof(cert_buffer); + ret = CryptSignAndEncodeCertificate(ctx->provider, AT_SIGNATURE, X509_ASN_ENCODING, + X509_CERT_TO_BE_SIGNED, &cert_info, &algid, NULL, cert_buffer, &size); + winetest_ok(ret, "Failed to create certificate, error %#x\n", GetLastError()); + + ctx->cert = CertCreateCertificateContext(X509_ASN_ENCODING, cert_buffer, size); + winetest_ok(!!ctx->cert, "Failed to create context, error %#x\n", GetLastError()); + + size = sizeof(provider_nameA); + ret = CryptGetProvParam(ctx->provider, PP_NAME, provider_nameA, &size, 0); + winetest_ok(ret, "Failed to get prov param, error %#x\n", GetLastError()); + MultiByteToWideChar(CP_ACP, 0, (char *)provider_nameA, -1, provider_nameW, ARRAY_SIZE(provider_nameW)); + + provider_info.pwszContainerName = (WCHAR *)container_name; + provider_info.pwszProvName = provider_nameW; + provider_info.dwProvType = PROV_RSA_FULL; + provider_info.dwKeySpec = AT_SIGNATURE; + ret = CertSetCertificateContextProperty(ctx->cert, CERT_KEY_PROV_INFO_PROP_ID, 0, &provider_info); + winetest_ok(ret, "Failed to set provider info, error %#x\n", GetLastError()); + + ctx->root_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_A, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, "root"); + if (!ctx->root_store && GetLastError() == ERROR_ACCESS_DENIED) + { + skip("Failed to open root store.\n"); + + ret = CertFreeCertificateContext(ctx->cert); + winetest_ok(ret, "Failed to free certificate, error %u\n", GetLastError()); + ret = CryptReleaseContext(ctx->provider, 0); + winetest_ok(ret, "failed to release context, error %u\n", GetLastError()); + + return FALSE; + } + winetest_ok(!!ctx->root_store, "Failed to open store, error %u\n", GetLastError()); + ret = CertAddCertificateContextToStore(ctx->root_store, ctx->cert, CERT_STORE_ADD_ALWAYS, &ctx->root_cert); + if (!ret && GetLastError() == ERROR_ACCESS_DENIED) + { + skip("Failed to add self-signed certificate to store.\n"); + + ret = CertFreeCertificateContext(ctx->cert); + winetest_ok(ret, "Failed to free certificate, error %u\n", GetLastError()); + ret = CertCloseStore(ctx->root_store, CERT_CLOSE_STORE_CHECK_FLAG); + winetest_ok(ret, "Failed to close store, error %u\n", GetLastError()); + ret = CryptReleaseContext(ctx->provider, 0); + winetest_ok(ret, "failed to release context, error %u\n", GetLastError()); + + return FALSE; + } + winetest_ok(ret, "Failed to add certificate, error %u\n", GetLastError()); + + ctx->publisher_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_A, 0, 0, + CERT_SYSTEM_STORE_LOCAL_MACHINE, "trustedpublisher"); + winetest_ok(!!ctx->publisher_store, "Failed to open store, error %u\n", GetLastError()); + ret = CertAddCertificateContextToStore(ctx->publisher_store, ctx->cert, + CERT_STORE_ADD_ALWAYS, &ctx->publisher_cert); + winetest_ok(ret, "Failed to add certificate, error %u\n", GetLastError()); + + return TRUE; +} + +static void testsign_cleanup(struct testsign_context *ctx) +{ + BOOL ret; + + ret = CertFreeCertificateContext(ctx->cert); + winetest_ok(ret, "Failed to free certificate, error %u\n", GetLastError()); + + ret = CertDeleteCertificateFromStore(ctx->root_cert); + winetest_ok(ret, "Failed to remove certificate, error %u\n", GetLastError()); + ret = CertCloseStore(ctx->root_store, CERT_CLOSE_STORE_CHECK_FLAG); + winetest_ok(ret, "Failed to close store, error %u\n", GetLastError()); + + ret = CertDeleteCertificateFromStore(ctx->publisher_cert); + winetest_ok(ret, "Failed to remove certificate, error %u\n", GetLastError()); + ret = CertCloseStore(ctx->publisher_store, CERT_CLOSE_STORE_CHECK_FLAG); + winetest_ok(ret, "Failed to close store, error %u\n", GetLastError()); + + ret = CryptReleaseContext(ctx->provider, 0); + winetest_ok(ret, "failed to release context, error %u\n", GetLastError()); +} + +#define testsign_sign (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : testsign_sign_ +static void testsign_sign_(struct testsign_context *ctx, const WCHAR *filename) +{ + SIGNER_ATTR_AUTHCODE authcode = {sizeof(authcode)}; + SIGNER_SIGNATURE_INFO signature = {sizeof(signature)}; + SIGNER_SUBJECT_INFO subject = {sizeof(subject)}; + SIGNER_CERT_STORE_INFO store = {sizeof(store)}; + SIGNER_CERT cert_info = {sizeof(cert_info)}; + SIGNER_FILE_INFO file = {sizeof(file)}; + DWORD index = 0; + HRESULT hr; + + subject.dwSubjectChoice = 1; + subject.pdwIndex = &index; + subject.pSignerFileInfo = &file; + file.pwszFileName = (WCHAR *)filename; + cert_info.dwCertChoice = 2; + cert_info.pCertStoreInfo = &store; + store.pSigningCert = ctx->cert; + store.dwCertPolicy = 0; + signature.algidHash = CALG_SHA_256; + signature.dwAttrChoice = SIGNER_AUTHCODE_ATTR; + signature.pAttrAuthcode = &authcode; + authcode.pwszName = L""; + authcode.pwszInfo = L""; + hr = pSignerSign(&subject, &cert_info, &signature, NULL, NULL, NULL, NULL); + todo_wine winetest_ok(hr == S_OK || broken(hr == NTE_BAD_ALGID) /* < 7 */, "Failed to sign, hr %#x\n", hr); +} + +#define unload_driver (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : unload_driver_ +static void unload_driver_(SC_HANDLE service) +{ + SERVICE_STATUS status; + + ControlService(service, SERVICE_CONTROL_STOP, &status); + while (status.dwCurrentState == SERVICE_STOP_PENDING) + { + BOOL ret; + Sleep(100); + ret = QueryServiceStatus(service, &status); + winetest_ok(ret, "QueryServiceStatus failed: %u\n", GetLastError()); + } + winetest_ok(status.dwCurrentState == SERVICE_STOPPED, + "expected SERVICE_STOPPED, got %d\n", status.dwCurrentState); + + DeleteService(service); + CloseServiceHandle(service); +} + +static HANDLE okfile; + +static void cat_okfile(void) +{ + char buffer[512]; + DWORD size; + + SetFilePointer(okfile, 0, NULL, FILE_BEGIN); + + do + { + ReadFile(okfile, buffer, sizeof(buffer), &size, NULL); + printf("%.*s", size, buffer); + } while (size == sizeof(buffer)); + + SetFilePointer(okfile, 0, NULL, FILE_BEGIN); + SetEndOfFile(okfile); + + winetest_add_failures(InterlockedExchange(&test_data->failures, 0)); + winetest_add_failures(InterlockedExchange(&test_data->todo_failures, 0)); +} + +#ifdef __i386__ +#define EXT "x86" +#elif defined(__x86_64__) +#define EXT "amd64" +#elif defined(__arm__) +#define EXT "arm" +#elif defined(__aarch64__) +#define EXT "arm64" +#else +#define EXT +#endif + +static const char inf_text[] = + "[Version]\n" + "Signature=$Chicago$\n" + "ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}\n" + "CatalogFile=winetest.cat\n" + "DriverVer=09/21/2006,6.0.5736.1\n" + + "[Manufacturer]\n" + "Wine=mfg_section,NT" EXT "\n" + + "[mfg_section.NT" EXT "]\n" + "Wine test root driver=device_section,test_hardware_id\n" + + "[device_section.NT" EXT "]\n" + "CopyFiles=file_section\n" + + "[device_section.NT" EXT ".Services]\n" + "AddService=winetest,0x2,svc_section\n" + + "[file_section]\n" + "winetest.sys\n" + + "[SourceDisksFiles]\n" + "winetest.sys=1\n" + + "[SourceDisksNames]\n" + "1=,winetest.sys\n" + + "[DestinationDirs]\n" + "DefaultDestDir=12\n" + + "[svc_section]\n" + "ServiceBinary=%12%\winetest.sys\n" + "ServiceType=1\n" + "StartType=3\n" + "ErrorControl=1\n" + "LoadOrderGroup=Extended Base\n" + "DisplayName="winetest bus driver"\n" + "; they don't sleep anymore, on the beach\n"; + +static void add_file_to_catalog(HANDLE catalog, const WCHAR *file) +{ + SIP_SUBJECTINFO subject_info = {sizeof(SIP_SUBJECTINFO)}; + SIP_INDIRECT_DATA *indirect_data; + const WCHAR *filepart = file; + CRYPTCATMEMBER *member; + WCHAR hash_buffer[100]; + GUID subject_guid; + unsigned int i; + DWORD size; + BOOL ret; + + ret = CryptSIPRetrieveSubjectGuidForCatalogFile(file, NULL, &subject_guid); + todo_wine winetest_ok(ret, "Failed to get subject guid, error %u\n", GetLastError()); + + size = 0; + subject_info.pgSubjectType = &subject_guid; + subject_info.pwsFileName = file; + subject_info.DigestAlgorithm.pszObjId = (char *)szOID_OIWSEC_sha1; + subject_info.dwFlags = SPC_INC_PE_RESOURCES_FLAG | SPC_INC_PE_IMPORT_ADDR_TABLE_FLAG | SPC_EXC_PE_PAGE_HASHES_FLAG | 0x10000; + ret = CryptSIPCreateIndirectData(&subject_info, &size, NULL); + todo_wine winetest_ok(ret, "Failed to get indirect data size, error %u\n", GetLastError()); + + indirect_data = malloc(size); + ret = CryptSIPCreateIndirectData(&subject_info, &size, indirect_data); + todo_wine winetest_ok(ret, "Failed to get indirect data, error %u\n", GetLastError()); + if (ret) + { + memset(hash_buffer, 0, sizeof(hash_buffer)); + for (i = 0; i < indirect_data->Digest.cbData; ++i) + swprintf(&hash_buffer[i * 2], 2, L"%02X", indirect_data->Digest.pbData[i]); + + member = CryptCATPutMemberInfo(catalog, (WCHAR *)file, + hash_buffer, &subject_guid, 0, size, (BYTE *)indirect_data); + winetest_ok(!!member, "Failed to write member, error %u\n", GetLastError()); + + if (wcsrchr(file, '\')) + filepart = wcsrchr(file, '\') + 1; + + ret = !!CryptCATPutAttrInfo(catalog, member, (WCHAR *)L"File", + CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED, + (wcslen(filepart) + 1) * 2, (BYTE *)filepart); + winetest_ok(ret, "Failed to write attr, error %u\n", GetLastError()); + + ret = !!CryptCATPutAttrInfo(catalog, member, (WCHAR *)L"OSAttr", + CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED, + sizeof(L"2:6.0"), (BYTE *)L"2:6.0"); + winetest_ok(ret, "Failed to write attr, error %u\n", GetLastError()); + } +} + +typedef void (*driver_test_callback)(void *); + +#define run_driver_test (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : run_driver_test_ +static void run_driver_test_(struct testsign_context *ctx, const WCHAR *name, + driver_test_callback callback, void *args) +{ + static const char hardware_id[] = "test_hardware_id\0"; + char path[MAX_PATH], dest[MAX_PATH], *filepart; + SP_DEVINFO_DATA device = {sizeof(device)}; + char cwd[MAX_PATH], tempdir[MAX_PATH]; + WCHAR driver_filename[MAX_PATH]; + SC_HANDLE manager, service; + BOOL ret, need_reboot; + HANDLE catalog, file; + HDEVINFO set; + FILE *f; + + GetCurrentDirectoryA(ARRAY_SIZE(cwd), cwd); + GetTempPathA(ARRAY_SIZE(tempdir), tempdir); + SetCurrentDirectoryA(tempdir); + + load_resource_(name, driver_filename); + ret = MoveFileExW(driver_filename, L"winetest.sys", MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING); + winetest_ok(ret, "failed to move file, error %u\n", GetLastError()); + + f = fopen("winetest.inf", "w"); + winetest_ok(!!f, "failed to open winetest.inf: %s\n", strerror(errno)); + fputs(inf_text, f); + fclose(f); + + /* Create the catalog file. */ + + catalog = CryptCATOpen((WCHAR *)L"winetest.cat", CRYPTCAT_OPEN_CREATENEW, 0, CRYPTCAT_VERSION_1, 0); + winetest_ok(catalog != INVALID_HANDLE_VALUE, "Failed to create catalog, error %#x\n", GetLastError()); + + add_file_to_catalog(catalog, L"winetest.sys"); + add_file_to_catalog(catalog, L"winetest.inf"); + + ret = CryptCATPersistStore(catalog); + todo_wine winetest_ok(ret, "Failed to write catalog, error %u\n", GetLastError()); + + ret = CryptCATClose(catalog); + winetest_ok(ret, "Failed to close catalog, error %u\n", GetLastError()); + + testsign_sign_(ctx, L"winetest.cat"); + + /* Install the driver. */ + + set = SetupDiCreateDeviceInfoList(NULL, NULL); + winetest_ok(set != INVALID_HANDLE_VALUE, "failed to create device list, error %#x\n", GetLastError()); + + ret = SetupDiCreateDeviceInfoA(set, "root\winetest\0", &GUID_NULL, NULL, NULL, 0, &device); + winetest_ok(ret, "failed to create device, error %#x\n", GetLastError()); + + ret = SetupDiSetDeviceRegistryPropertyA( set, &device, SPDRP_HARDWAREID, + (const BYTE *)hardware_id, sizeof(hardware_id) ); + winetest_ok(ret, "failed to create set hardware ID, error %#x\n", GetLastError()); + + ret = SetupDiCallClassInstaller(DIF_REGISTERDEVICE, set, &device); + winetest_ok(ret, "failed to register device, error %#x\n", GetLastError()); + + GetFullPathNameA("winetest.inf", sizeof(path), path, NULL); + ret = UpdateDriverForPlugAndPlayDevicesA(NULL, hardware_id, path, INSTALLFLAG_FORCE, &need_reboot); + winetest_ok(ret, "failed to install device, error %#x\n", GetLastError()); + winetest_ok(!need_reboot, "expected no reboot necessary\n"); + + callback(args); + + ret = SetupDiCallClassInstaller(DIF_REMOVE, set, &device); + winetest_ok(ret, "failed to remove device, error %#x\n", GetLastError()); + + file = CreateFileA("\\?\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0, NULL, OPEN_EXISTING, 0, NULL); + winetest_ok(file == INVALID_HANDLE_VALUE, "expected failure\n"); + winetest_ok(GetLastError() == ERROR_FILE_NOT_FOUND, "got error %u\n", GetLastError()); + + ret = SetupDiDestroyDeviceInfoList(set); + winetest_ok(ret, "failed to destroy set, error %#x\n", GetLastError()); + + /* Windows stops the service but does not delete it. */ + manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); + winetest_ok(!!manager, "failed to open service manager, error %u\n", GetLastError()); + service = OpenServiceA(manager, "winetest", SERVICE_STOP | DELETE); + winetest_ok(!!service, "failed to open service, error %u\n", GetLastError()); + unload_driver_(service); + CloseServiceHandle(manager); + + cat_okfile(); + + GetFullPathNameA("winetest.inf", sizeof(path), path, NULL); + ret = SetupCopyOEMInfA(path, NULL, 0, 0, dest, sizeof(dest), NULL, &filepart); + winetest_ok(ret, "Failed to copy INF, error %#x\n", GetLastError()); + ret = SetupUninstallOEMInfA(filepart, 0, NULL); + winetest_ok(ret, "Failed to uninstall INF, error %u\n", GetLastError()); + + ret = DeleteFileA("winetest.cat"); + winetest_ok(ret, "Failed to delete file, error %u\n", GetLastError()); + ret = DeleteFileA("winetest.inf"); + winetest_ok(ret, "Failed to delete file, error %u\n", GetLastError()); + ret = DeleteFileA("winetest.sys"); + winetest_ok(ret, "Failed to delete file, error %u\n", GetLastError()); + /* Windows 10 apparently deletes the image in SetupUninstallOEMInf(). */ + ret = DeleteFileA("C:/windows/system32/drivers/winetest.sys"); + winetest_ok(ret || GetLastError() == ERROR_FILE_NOT_FOUND, "Failed to delete file, error %u\n", GetLastError()); + + SetCurrentDirectoryA(cwd); +} + +#define driver_test_init(a) driver_test_init_(__FILE__, __LINE__, a) +static BOOL driver_test_init_(char const *file, int line, struct testsign_context *ctx) +{ + BOOL is_wow64; + + winetest_set_location(file, line); + + pSignerSign = (void *)GetProcAddress(LoadLibraryA("mssign32"), "SignerSign"); + + if (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64) + { + winetest_skip("Running in WoW64.\n"); + return FALSE; + } + + if (!testsign_create_cert(ctx)) + return FALSE; + + test_data_mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, + 0, sizeof(*test_data), "Global\winetest_ntoskrnl_section"); + winetest_ok(!!test_data_mapping, "got error %u\n", GetLastError()); + test_data = MapViewOfFile(test_data_mapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 1024); + test_data->running_under_wine = !strcmp(winetest_platform, "wine"); + test_data->winetest_report_success = winetest_report_success; + test_data->winetest_debug = winetest_debug; + + okfile = CreateFileA("C:\windows\winetest_ntoskrnl_okfile", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL); + winetest_ok(okfile != INVALID_HANDLE_VALUE, "failed to create file, error %u\n", GetLastError()); + + return TRUE; +} + +#define driver_test_cleanup (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : driver_test_cleanup_ +static void driver_test_cleanup_(struct testsign_context *ctx) +{ + testsign_cleanup(ctx); + UnmapViewOfFile(test_data); + CloseHandle(test_data_mapping); + CloseHandle(okfile); + DeleteFileA("C:\windows\winetest_ntoskrnl_okfile"); +} diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index dc10497caee..a0636099def 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -44,15 +44,12 @@ #include "ddk/hidpi.h" #include "wine/test.h" #include "wine/heap.h" -#include "wine/mssign.h" - -#include "driver.h"
static const GUID GUID_NULL;
-static HANDLE device; +#include "driver_tests.h"
-static struct test_data *test_data; +static HANDLE device;
static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(const WCHAR *, UNICODE_STRING *, WCHAR **, CURDIR *); static BOOL (WINAPI *pRtlFreeUnicodeString)(UNICODE_STRING *); @@ -63,237 +60,6 @@ static HRESULT (WINAPI *pSignerSign)(SIGNER_SUBJECT_INFO *subject, SIGNER_CERT * SIGNER_SIGNATURE_INFO *signature, SIGNER_PROVIDER_INFO *provider, const WCHAR *timestamp, CRYPT_ATTRIBUTES *attr, void *sip_data);
-static void load_resource(const WCHAR *name, WCHAR *filename) -{ - static WCHAR path[MAX_PATH]; - DWORD written; - HANDLE file; - HRSRC res; - void *ptr; - - GetTempPathW(ARRAY_SIZE(path), path); - GetTempFileNameW(path, name, 0, filename); - - file = CreateFileW(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); - ok(file != INVALID_HANDLE_VALUE, "failed to create %s, error %u\n", debugstr_w(filename), GetLastError()); - - res = FindResourceW(NULL, name, L"TESTDLL"); - ok( res != 0, "couldn't find resource\n" ); - ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res )); - WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL ); - ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" ); - CloseHandle( file ); -} - -struct testsign_context -{ - HCRYPTPROV provider; - const CERT_CONTEXT *cert, *root_cert, *publisher_cert; - HCERTSTORE root_store, publisher_store; -}; - -static BOOL testsign_create_cert(struct testsign_context *ctx) -{ - BYTE encoded_name[100], encoded_key_id[200], public_key_info_buffer[1000]; - WCHAR container_name[26]; - BYTE hash_buffer[16], cert_buffer[1000], provider_nameA[100], serial[16]; - CERT_PUBLIC_KEY_INFO *public_key_info = (CERT_PUBLIC_KEY_INFO *)public_key_info_buffer; - CRYPT_KEY_PROV_INFO provider_info = {0}; - CRYPT_ALGORITHM_IDENTIFIER algid = {0}; - CERT_AUTHORITY_KEY_ID_INFO key_info; - CERT_INFO cert_info = {0}; - WCHAR provider_nameW[100]; - CERT_EXTENSION extension; - HCRYPTKEY key; - DWORD size; - BOOL ret; - - memset(ctx, 0, sizeof(*ctx)); - - srand(time(NULL)); - swprintf(container_name, ARRAY_SIZE(container_name), L"wine_testsign%u", rand()); - - ret = CryptAcquireContextW(&ctx->provider, container_name, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET); - ok(ret, "Failed to create container, error %#x\n", GetLastError()); - - ret = CryptGenKey(ctx->provider, AT_SIGNATURE, CRYPT_EXPORTABLE, &key); - ok(ret, "Failed to create key, error %#x\n", GetLastError()); - ret = CryptDestroyKey(key); - ok(ret, "Failed to destroy key, error %#x\n", GetLastError()); - ret = CryptGetUserKey(ctx->provider, AT_SIGNATURE, &key); - ok(ret, "Failed to get user key, error %#x\n", GetLastError()); - ret = CryptDestroyKey(key); - ok(ret, "Failed to destroy key, error %#x\n", GetLastError()); - - size = sizeof(encoded_name); - ret = CertStrToNameA(X509_ASN_ENCODING, "CN=winetest_cert", CERT_X500_NAME_STR, NULL, encoded_name, &size, NULL); - ok(ret, "Failed to convert name, error %#x\n", GetLastError()); - key_info.CertIssuer.cbData = size; - key_info.CertIssuer.pbData = encoded_name; - - size = sizeof(public_key_info_buffer); - ret = CryptExportPublicKeyInfo(ctx->provider, AT_SIGNATURE, X509_ASN_ENCODING, public_key_info, &size); - ok(ret, "Failed to export public key, error %#x\n", GetLastError()); - cert_info.SubjectPublicKeyInfo = *public_key_info; - - size = sizeof(hash_buffer); - ret = CryptHashPublicKeyInfo(ctx->provider, CALG_MD5, 0, X509_ASN_ENCODING, public_key_info, hash_buffer, &size); - ok(ret, "Failed to hash public key, error %#x\n", GetLastError()); - - key_info.KeyId.cbData = size; - key_info.KeyId.pbData = hash_buffer; - - RtlGenRandom(serial, sizeof(serial)); - key_info.CertSerialNumber.cbData = sizeof(serial); - key_info.CertSerialNumber.pbData = serial; - - size = sizeof(encoded_key_id); - ret = CryptEncodeObject(X509_ASN_ENCODING, X509_AUTHORITY_KEY_ID, &key_info, encoded_key_id, &size); - ok(ret, "Failed to convert name, error %#x\n", GetLastError()); - - extension.pszObjId = (char *)szOID_AUTHORITY_KEY_IDENTIFIER; - extension.fCritical = TRUE; - extension.Value.cbData = size; - extension.Value.pbData = encoded_key_id; - - cert_info.dwVersion = CERT_V3; - cert_info.SerialNumber = key_info.CertSerialNumber; - cert_info.SignatureAlgorithm.pszObjId = (char *)szOID_RSA_SHA1RSA; - cert_info.Issuer = key_info.CertIssuer; - GetSystemTimeAsFileTime(&cert_info.NotBefore); - GetSystemTimeAsFileTime(&cert_info.NotAfter); - cert_info.NotAfter.dwHighDateTime += 1; - cert_info.Subject = key_info.CertIssuer; - cert_info.cExtension = 1; - cert_info.rgExtension = &extension; - algid.pszObjId = (char *)szOID_RSA_SHA1RSA; - size = sizeof(cert_buffer); - ret = CryptSignAndEncodeCertificate(ctx->provider, AT_SIGNATURE, X509_ASN_ENCODING, - X509_CERT_TO_BE_SIGNED, &cert_info, &algid, NULL, cert_buffer, &size); - ok(ret, "Failed to create certificate, error %#x\n", GetLastError()); - - ctx->cert = CertCreateCertificateContext(X509_ASN_ENCODING, cert_buffer, size); - ok(!!ctx->cert, "Failed to create context, error %#x\n", GetLastError()); - - size = sizeof(provider_nameA); - ret = CryptGetProvParam(ctx->provider, PP_NAME, provider_nameA, &size, 0); - ok(ret, "Failed to get prov param, error %#x\n", GetLastError()); - MultiByteToWideChar(CP_ACP, 0, (char *)provider_nameA, -1, provider_nameW, ARRAY_SIZE(provider_nameW)); - - provider_info.pwszContainerName = (WCHAR *)container_name; - provider_info.pwszProvName = provider_nameW; - provider_info.dwProvType = PROV_RSA_FULL; - provider_info.dwKeySpec = AT_SIGNATURE; - ret = CertSetCertificateContextProperty(ctx->cert, CERT_KEY_PROV_INFO_PROP_ID, 0, &provider_info); - ok(ret, "Failed to set provider info, error %#x\n", GetLastError()); - - ctx->root_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_A, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, "root"); - if (!ctx->root_store && GetLastError() == ERROR_ACCESS_DENIED) - { - skip("Failed to open root store.\n"); - - ret = CertFreeCertificateContext(ctx->cert); - ok(ret, "Failed to free certificate, error %u\n", GetLastError()); - ret = CryptReleaseContext(ctx->provider, 0); - ok(ret, "failed to release context, error %u\n", GetLastError()); - - return FALSE; - } - ok(!!ctx->root_store, "Failed to open store, error %u\n", GetLastError()); - ret = CertAddCertificateContextToStore(ctx->root_store, ctx->cert, CERT_STORE_ADD_ALWAYS, &ctx->root_cert); - if (!ret && GetLastError() == ERROR_ACCESS_DENIED) - { - skip("Failed to add self-signed certificate to store.\n"); - - ret = CertFreeCertificateContext(ctx->cert); - ok(ret, "Failed to free certificate, error %u\n", GetLastError()); - ret = CertCloseStore(ctx->root_store, CERT_CLOSE_STORE_CHECK_FLAG); - ok(ret, "Failed to close store, error %u\n", GetLastError()); - ret = CryptReleaseContext(ctx->provider, 0); - ok(ret, "failed to release context, error %u\n", GetLastError()); - - return FALSE; - } - ok(ret, "Failed to add certificate, error %u\n", GetLastError()); - - ctx->publisher_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_A, 0, 0, - CERT_SYSTEM_STORE_LOCAL_MACHINE, "trustedpublisher"); - ok(!!ctx->publisher_store, "Failed to open store, error %u\n", GetLastError()); - ret = CertAddCertificateContextToStore(ctx->publisher_store, ctx->cert, - CERT_STORE_ADD_ALWAYS, &ctx->publisher_cert); - ok(ret, "Failed to add certificate, error %u\n", GetLastError()); - - return TRUE; -} - -static void testsign_cleanup(struct testsign_context *ctx) -{ - BOOL ret; - - ret = CertFreeCertificateContext(ctx->cert); - ok(ret, "Failed to free certificate, error %u\n", GetLastError()); - - ret = CertDeleteCertificateFromStore(ctx->root_cert); - ok(ret, "Failed to remove certificate, error %u\n", GetLastError()); - ret = CertCloseStore(ctx->root_store, CERT_CLOSE_STORE_CHECK_FLAG); - ok(ret, "Failed to close store, error %u\n", GetLastError()); - - ret = CertDeleteCertificateFromStore(ctx->publisher_cert); - ok(ret, "Failed to remove certificate, error %u\n", GetLastError()); - ret = CertCloseStore(ctx->publisher_store, CERT_CLOSE_STORE_CHECK_FLAG); - ok(ret, "Failed to close store, error %u\n", GetLastError()); - - ret = CryptReleaseContext(ctx->provider, 0); - ok(ret, "failed to release context, error %u\n", GetLastError()); -} - -static void testsign_sign(struct testsign_context *ctx, const WCHAR *filename) -{ - SIGNER_ATTR_AUTHCODE authcode = {sizeof(authcode)}; - SIGNER_SIGNATURE_INFO signature = {sizeof(signature)}; - SIGNER_SUBJECT_INFO subject = {sizeof(subject)}; - SIGNER_CERT_STORE_INFO store = {sizeof(store)}; - SIGNER_CERT cert_info = {sizeof(cert_info)}; - SIGNER_FILE_INFO file = {sizeof(file)}; - DWORD index = 0; - HRESULT hr; - - subject.dwSubjectChoice = 1; - subject.pdwIndex = &index; - subject.pSignerFileInfo = &file; - file.pwszFileName = (WCHAR *)filename; - cert_info.dwCertChoice = 2; - cert_info.pCertStoreInfo = &store; - store.pSigningCert = ctx->cert; - store.dwCertPolicy = 0; - signature.algidHash = CALG_SHA_256; - signature.dwAttrChoice = SIGNER_AUTHCODE_ATTR; - signature.pAttrAuthcode = &authcode; - authcode.pwszName = L""; - authcode.pwszInfo = L""; - hr = pSignerSign(&subject, &cert_info, &signature, NULL, NULL, NULL, NULL); - todo_wine ok(hr == S_OK || broken(hr == NTE_BAD_ALGID) /* < 7 */, "Failed to sign, hr %#x\n", hr); -} - -static void unload_driver(SC_HANDLE service) -{ - SERVICE_STATUS status; - - ControlService(service, SERVICE_CONTROL_STOP, &status); - while (status.dwCurrentState == SERVICE_STOP_PENDING) - { - BOOL ret; - Sleep(100); - ret = QueryServiceStatus(service, &status); - ok(ret, "QueryServiceStatus failed: %u\n", GetLastError()); - } - ok(status.dwCurrentState == SERVICE_STOPPED, - "expected SERVICE_STOPPED, got %d\n", status.dwCurrentState); - - DeleteService(service); - CloseServiceHandle(service); -} - static SC_HANDLE load_driver(struct testsign_context *ctx, WCHAR *filename, const WCHAR *resname, const WCHAR *driver_name) { @@ -369,26 +135,6 @@ static BOOL start_driver(HANDLE service, BOOL vista_plus)
static HANDLE okfile;
-static void cat_okfile(void) -{ - char buffer[512]; - DWORD size; - - SetFilePointer(okfile, 0, NULL, FILE_BEGIN); - - do - { - ReadFile(okfile, buffer, sizeof(buffer), &size, NULL); - printf("%.*s", size, buffer); - } while (size == sizeof(buffer)); - - SetFilePointer(okfile, 0, NULL, FILE_BEGIN); - SetEndOfFile(okfile); - - winetest_add_failures(InterlockedExchange(&test_data->failures, 0)); - winetest_add_failures(InterlockedExchange(&test_data->todo_failures, 0)); -} - static ULONG64 modified_value;
static void main_test(void) @@ -1239,109 +985,6 @@ static void test_driver_netio(struct testsign_context *ctx) cat_okfile(); }
-#ifdef __i386__ -#define EXT "x86" -#elif defined(__x86_64__) -#define EXT "amd64" -#elif defined(__arm__) -#define EXT "arm" -#elif defined(__aarch64__) -#define EXT "arm64" -#else -#define EXT -#endif - -static const char inf_text[] = - "[Version]\n" - "Signature=$Chicago$\n" - "ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}\n" - "CatalogFile=winetest.cat\n" - "DriverVer=09/21/2006,6.0.5736.1\n" - - "[Manufacturer]\n" - "Wine=mfg_section,NT" EXT "\n" - - "[mfg_section.NT" EXT "]\n" - "Wine test root driver=device_section,test_hardware_id\n" - - "[device_section.NT" EXT "]\n" - "CopyFiles=file_section\n" - - "[device_section.NT" EXT ".Services]\n" - "AddService=winetest,0x2,svc_section\n" - - "[file_section]\n" - "winetest.sys\n" - - "[SourceDisksFiles]\n" - "winetest.sys=1\n" - - "[SourceDisksNames]\n" - "1=,winetest.sys\n" - - "[DestinationDirs]\n" - "DefaultDestDir=12\n" - - "[svc_section]\n" - "ServiceBinary=%12%\winetest.sys\n" - "ServiceType=1\n" - "StartType=3\n" - "ErrorControl=1\n" - "LoadOrderGroup=Extended Base\n" - "DisplayName="winetest bus driver"\n" - "; they don't sleep anymore, on the beach\n"; - -static void add_file_to_catalog(HANDLE catalog, const WCHAR *file) -{ - SIP_SUBJECTINFO subject_info = {sizeof(SIP_SUBJECTINFO)}; - SIP_INDIRECT_DATA *indirect_data; - const WCHAR *filepart = file; - CRYPTCATMEMBER *member; - WCHAR hash_buffer[100]; - GUID subject_guid; - unsigned int i; - DWORD size; - BOOL ret; - - ret = CryptSIPRetrieveSubjectGuidForCatalogFile(file, NULL, &subject_guid); - todo_wine ok(ret, "Failed to get subject guid, error %u\n", GetLastError()); - - size = 0; - subject_info.pgSubjectType = &subject_guid; - subject_info.pwsFileName = file; - subject_info.DigestAlgorithm.pszObjId = (char *)szOID_OIWSEC_sha1; - subject_info.dwFlags = SPC_INC_PE_RESOURCES_FLAG | SPC_INC_PE_IMPORT_ADDR_TABLE_FLAG | SPC_EXC_PE_PAGE_HASHES_FLAG | 0x10000; - ret = CryptSIPCreateIndirectData(&subject_info, &size, NULL); - todo_wine ok(ret, "Failed to get indirect data size, error %u\n", GetLastError()); - - indirect_data = malloc(size); - ret = CryptSIPCreateIndirectData(&subject_info, &size, indirect_data); - todo_wine ok(ret, "Failed to get indirect data, error %u\n", GetLastError()); - if (ret) - { - memset(hash_buffer, 0, sizeof(hash_buffer)); - for (i = 0; i < indirect_data->Digest.cbData; ++i) - swprintf(&hash_buffer[i * 2], 2, L"%02X", indirect_data->Digest.pbData[i]); - - member = CryptCATPutMemberInfo(catalog, (WCHAR *)file, - hash_buffer, &subject_guid, 0, size, (BYTE *)indirect_data); - ok(!!member, "Failed to write member, error %u\n", GetLastError()); - - if (wcsrchr(file, '\')) - filepart = wcsrchr(file, '\') + 1; - - ret = !!CryptCATPutAttrInfo(catalog, member, (WCHAR *)L"File", - CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED, - (wcslen(filepart) + 1) * 2, (BYTE *)filepart); - ok(ret, "Failed to write attr, error %u\n", GetLastError()); - - ret = !!CryptCATPutAttrInfo(catalog, member, (WCHAR *)L"OSAttr", - CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED, - sizeof(L"2:6.0"), (BYTE *)L"2:6.0"); - ok(ret, "Failed to write attr, error %u\n", GetLastError()); - } -} - static const GUID bus_class = {0xdeadbeef, 0x29ef, 0x4538, {0xa5, 0xfd, 0xb6, 0x95, 0x73, 0xa3, 0x62, 0xc1}}; static const GUID child_class = {0xdeadbeef, 0x29ef, 0x4538, {0xa5, 0xfd, 0xb6, 0x95, 0x73, 0xa3, 0x62, 0xc2}};
@@ -1434,7 +1077,7 @@ static void pump_messages(void) } }
-static void test_pnp_devices(void) +static void test_pnp_devices(void *args) { static const char expect_hardware_id[] = "winetest_hardware\0winetest_hardware_1\0"; static const char expect_compat_id[] = "winetest_compat\0winetest_compat_1\0"; @@ -1698,133 +1341,6 @@ static void test_pnp_devices(void) UnregisterClassA("ntoskrnl_test_wc", GetModuleHandleA(NULL)); }
-static void test_pnp_driver(struct testsign_context *ctx) -{ - static const char hardware_id[] = "test_hardware_id\0"; - char path[MAX_PATH], dest[MAX_PATH], *filepart; - SP_DEVINFO_DATA device = {sizeof(device)}; - char cwd[MAX_PATH], tempdir[MAX_PATH]; - WCHAR driver_filename[MAX_PATH]; - SC_HANDLE manager, service; - BOOL ret, need_reboot; - HANDLE catalog, file; - unsigned int i; - HDEVINFO set; - FILE *f; - - GetCurrentDirectoryA(ARRAY_SIZE(cwd), cwd); - GetTempPathA(ARRAY_SIZE(tempdir), tempdir); - SetCurrentDirectoryA(tempdir); - - load_resource(L"driver_pnp.dll", driver_filename); - ret = MoveFileExW(driver_filename, L"winetest.sys", MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING); - ok(ret, "failed to move file, error %u\n", GetLastError()); - - f = fopen("winetest.inf", "w"); - ok(!!f, "failed to open winetest.inf: %s\n", strerror(errno)); - fputs(inf_text, f); - fclose(f); - - /* Create the catalog file. */ - - catalog = CryptCATOpen((WCHAR *)L"winetest.cat", CRYPTCAT_OPEN_CREATENEW, 0, CRYPTCAT_VERSION_1, 0); - ok(catalog != INVALID_HANDLE_VALUE, "Failed to create catalog, error %#x\n", GetLastError()); - - ret = !!CryptCATPutCatAttrInfo(catalog, (WCHAR *)L"HWID1", - CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED, - sizeof(L"test_hardware_id"), (BYTE *)L"test_hardware_id"); - todo_wine ok(ret, "failed to add attribute, error %#x\n", GetLastError()); - - ret = !!CryptCATPutCatAttrInfo(catalog, (WCHAR *)L"OS", - CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED, - sizeof(L"VistaX64"), (BYTE *)L"VistaX64"); - todo_wine ok(ret, "failed to add attribute, error %#x\n", GetLastError()); - - add_file_to_catalog(catalog, L"winetest.sys"); - add_file_to_catalog(catalog, L"winetest.inf"); - - ret = CryptCATPersistStore(catalog); - todo_wine ok(ret, "Failed to write catalog, error %u\n", GetLastError()); - - ret = CryptCATClose(catalog); - ok(ret, "Failed to close catalog, error %u\n", GetLastError()); - - testsign_sign(ctx, L"winetest.cat"); - - /* Install the driver. */ - - set = SetupDiCreateDeviceInfoList(NULL, NULL); - ok(set != INVALID_HANDLE_VALUE, "failed to create device list, error %#x\n", GetLastError()); - - ret = SetupDiCreateDeviceInfoA(set, "root\winetest\0", &GUID_NULL, NULL, NULL, 0, &device); - ok(ret, "failed to create device, error %#x\n", GetLastError()); - - ret = SetupDiSetDeviceRegistryPropertyA( set, &device, SPDRP_HARDWAREID, - (const BYTE *)hardware_id, sizeof(hardware_id) ); - ok(ret, "failed to create set hardware ID, error %#x\n", GetLastError()); - - ret = SetupDiCallClassInstaller(DIF_REGISTERDEVICE, set, &device); - ok(ret, "failed to register device, error %#x\n", GetLastError()); - - GetFullPathNameA("winetest.inf", sizeof(path), path, NULL); - ret = UpdateDriverForPlugAndPlayDevicesA(NULL, hardware_id, path, INSTALLFLAG_FORCE, &need_reboot); - ok(ret, "failed to install device, error %#x\n", GetLastError()); - ok(!need_reboot, "expected no reboot necessary\n"); - - /* Tests. */ - - test_pnp_devices(); - - /* Clean up. */ - - ret = SetupDiCallClassInstaller(DIF_REMOVE, set, &device); - ok(ret, "failed to remove device, error %#x\n", GetLastError()); - - file = CreateFileA("\\?\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0, NULL, OPEN_EXISTING, 0, NULL); - ok(file == INVALID_HANDLE_VALUE, "expected failure\n"); - ok(GetLastError() == ERROR_FILE_NOT_FOUND, "got error %u\n", GetLastError()); - - ret = SetupDiDestroyDeviceInfoList(set); - ok(ret, "failed to destroy set, error %#x\n", GetLastError()); - - set = SetupDiGetClassDevsA(NULL, "wine", NULL, DIGCF_ALLCLASSES); - ok(set != INVALID_HANDLE_VALUE, "failed to get device list, error %#x\n", GetLastError()); - - for (i = 0; SetupDiEnumDeviceInfo(set, i, &device); ++i) - { - ret = SetupDiCallClassInstaller(DIF_REMOVE, set, &device); - ok(ret, "failed to remove device, error %#x\n", GetLastError()); - } - - /* Windows stops the service but does not delete it. */ - manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); - ok(!!manager, "failed to open service manager, error %u\n", GetLastError()); - service = OpenServiceA(manager, "winetest", SERVICE_STOP | DELETE); - ok(!!service, "failed to open service, error %u\n", GetLastError()); - unload_driver(service); - CloseServiceHandle(manager); - - cat_okfile(); - - GetFullPathNameA("winetest.inf", sizeof(path), path, NULL); - ret = SetupCopyOEMInfA(path, NULL, 0, 0, dest, sizeof(dest), NULL, &filepart); - ok(ret, "Failed to copy INF, error %#x\n", GetLastError()); - ret = SetupUninstallOEMInfA(filepart, 0, NULL); - ok(ret, "Failed to uninstall INF, error %u\n", GetLastError()); - - ret = DeleteFileA("winetest.cat"); - ok(ret, "Failed to delete file, error %u\n", GetLastError()); - ret = DeleteFileA("winetest.inf"); - ok(ret, "Failed to delete file, error %u\n", GetLastError()); - ret = DeleteFileA("winetest.sys"); - ok(ret, "Failed to delete file, error %u\n", GetLastError()); - /* Windows 10 apparently deletes the image in SetupUninstallOEMInf(). */ - ret = DeleteFileA("C:/windows/system32/drivers/winetest.sys"); - ok(ret || GetLastError() == ERROR_FILE_NOT_FOUND, "Failed to delete file, error %u\n", GetLastError()); - - SetCurrentDirectoryA(cwd); -} - #define check_member_(file, line, val, exp, fmt, member) \ ok_(file, line)((val).member == (exp).member, \ "got " #member " " fmt ", expected " fmt "\n", \ @@ -3131,8 +2647,16 @@ static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled HidD_FreePreparsedData(preparsed_data); }
-static void test_hid_device(DWORD report_id, DWORD polled) +struct test_hid_params +{ + BOOL report_id; + BOOL polled; +}; + +static void test_hid_device(void *args) { + struct test_hid_params *params = args; + BOOL report_id = params->report_id, polled = params->polled; char buffer[200]; SP_DEVICE_INTERFACE_DETAIL_DATA_A *iface_detail = (void *)buffer; SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}; @@ -3297,18 +2821,11 @@ static void test_hid_device(DWORD report_id, DWORD polled)
static void test_hid_driver(struct testsign_context *ctx, DWORD report_id, DWORD polled) { - static const char hardware_id[] = "test_hardware_id\0"; - char path[MAX_PATH], dest[MAX_PATH], *filepart; + struct test_hid_params params = {.report_id = report_id, .polled = polled}; SP_DEVINFO_DATA device = {sizeof(device)}; char cwd[MAX_PATH], tempdir[MAX_PATH]; - WCHAR driver_filename[MAX_PATH]; - SC_HANDLE manager, service; - BOOL ret, need_reboot; - HANDLE catalog, file; LSTATUS status; - HDEVINFO set; HKEY hkey; - FILE *f;
GetCurrentDirectoryA(ARRAY_SIZE(cwd), cwd); GetTempPathA(ARRAY_SIZE(tempdir), tempdir); @@ -3323,94 +2840,7 @@ static void test_hid_driver(struct testsign_context *ctx, DWORD report_id, DWORD status = RegSetValueExW(hkey, L"PolledMode", 0, REG_DWORD, (void *)&polled, sizeof(polled)); ok(!status, "RegSetValueExW returned %#x\n", status);
- load_resource(L"driver_hid.dll", driver_filename); - ret = MoveFileExW(driver_filename, L"winetest.sys", MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING); - ok(ret, "failed to move file, error %u\n", GetLastError()); - - f = fopen("winetest.inf", "w"); - ok(!!f, "failed to open winetest.inf: %s\n", strerror(errno)); - fputs(inf_text, f); - fclose(f); - - /* Create the catalog file. */ - - catalog = CryptCATOpen((WCHAR *)L"winetest.cat", CRYPTCAT_OPEN_CREATENEW, 0, CRYPTCAT_VERSION_1, 0); - ok(catalog != INVALID_HANDLE_VALUE, "Failed to create catalog, error %#x\n", GetLastError()); - - add_file_to_catalog(catalog, L"winetest.sys"); - add_file_to_catalog(catalog, L"winetest.inf"); - - ret = CryptCATPersistStore(catalog); - todo_wine ok(ret, "Failed to write catalog, error %u\n", GetLastError()); - - ret = CryptCATClose(catalog); - ok(ret, "Failed to close catalog, error %u\n", GetLastError()); - - testsign_sign(ctx, L"winetest.cat"); - - /* Install the driver. */ - - set = SetupDiCreateDeviceInfoList(NULL, NULL); - ok(set != INVALID_HANDLE_VALUE, "failed to create device list, error %#x\n", GetLastError()); - - ret = SetupDiCreateDeviceInfoA(set, "root\winetest\0", &GUID_NULL, NULL, NULL, 0, &device); - ok(ret, "failed to create device, error %#x\n", GetLastError()); - - ret = SetupDiSetDeviceRegistryPropertyA( set, &device, SPDRP_HARDWAREID, - (const BYTE *)hardware_id, sizeof(hardware_id) ); - ok(ret, "failed to create set hardware ID, error %#x\n", GetLastError()); - - ret = SetupDiCallClassInstaller(DIF_REGISTERDEVICE, set, &device); - ok(ret, "failed to register device, error %#x\n", GetLastError()); - - GetFullPathNameA("winetest.inf", sizeof(path), path, NULL); - ret = UpdateDriverForPlugAndPlayDevicesA(NULL, hardware_id, path, INSTALLFLAG_FORCE, &need_reboot); - ok(ret, "failed to install device, error %#x\n", GetLastError()); - ok(!need_reboot, "expected no reboot necessary\n"); - - /* Tests. */ - - test_hid_device(report_id, polled); - - /* Clean up. */ - - ret = SetupDiCallClassInstaller(DIF_REMOVE, set, &device); - ok(ret, "failed to remove device, error %#x\n", GetLastError()); - - file = CreateFileA("\\?\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0, NULL, OPEN_EXISTING, 0, NULL); - ok(file == INVALID_HANDLE_VALUE, "expected failure\n"); - ok(GetLastError() == ERROR_FILE_NOT_FOUND, "got error %u\n", GetLastError()); - - ret = SetupDiDestroyDeviceInfoList(set); - ok(ret, "failed to destroy set, error %#x\n", GetLastError()); - - /* Windows stops the service but does not delete it. */ - manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); - ok(!!manager, "failed to open service manager, error %u\n", GetLastError()); - service = OpenServiceA(manager, "winetest", SERVICE_STOP | DELETE); - ok(!!service, "failed to open service, error %u\n", GetLastError()); - unload_driver(service); - CloseServiceHandle(manager); - - cat_okfile(); - - GetFullPathNameA("winetest.inf", sizeof(path), path, NULL); - ret = SetupCopyOEMInfA(path, NULL, 0, 0, dest, sizeof(dest), NULL, &filepart); - ok(ret, "Failed to copy INF, error %#x\n", GetLastError()); - ret = SetupUninstallOEMInfA(filepart, 0, NULL); - ok(ret, "Failed to uninstall INF, error %u\n", GetLastError()); - - ret = DeleteFileA("winetest.cat"); - ok(ret, "Failed to delete file, error %u\n", GetLastError()); - ret = DeleteFileA("winetest.inf"); - ok(ret, "Failed to delete file, error %u\n", GetLastError()); - ret = DeleteFileA("winetest.sys"); - ok(ret, "Failed to delete file, error %u\n", GetLastError()); - /* Windows 10 apparently deletes the image in SetupUninstallOEMInf(). */ - ret = DeleteFileA("C:/windows/system32/drivers/winetest.sys"); - ok(ret || GetLastError() == ERROR_FILE_NOT_FOUND, "Failed to delete file, error %u\n", GetLastError()); - - SetCurrentDirectoryA(cwd); + run_driver_test(ctx, L"driver_hid.dll", test_hid_device, ¶ms); }
START_TEST(ntoskrnl) @@ -3418,9 +2848,8 @@ START_TEST(ntoskrnl) WCHAR filename[MAX_PATH], filename2[MAX_PATH]; struct testsign_context ctx; SC_HANDLE service, service2; - BOOL ret, is_wow64; - HANDLE mapping; DWORD written; + BOOL ret;
pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(GetModuleHandleA("ntdll"), "RtlDosPathNameToNtPathName_U"); pRtlFreeUnicodeString = (void *)GetProcAddress(GetModuleHandleA("ntdll"), "RtlFreeUnicodeString"); @@ -3428,29 +2857,10 @@ START_TEST(ntoskrnl) pIsWow64Process = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process"); pSetFileCompletionNotificationModes = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "SetFileCompletionNotificationModes"); - pSignerSign = (void *)GetProcAddress(LoadLibraryA("mssign32"), "SignerSign"); - - if (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64) - { - skip("Running in WoW64.\n"); - return; - }
- if (!testsign_create_cert(&ctx)) + if (!driver_test_init(&ctx)) return;
- mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, - 0, sizeof(*test_data), "Global\winetest_ntoskrnl_section"); - ok(!!mapping, "got error %u\n", GetLastError()); - test_data = MapViewOfFile(mapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 1024); - test_data->running_under_wine = !strcmp(winetest_platform, "wine"); - test_data->winetest_report_success = winetest_report_success; - test_data->winetest_debug = winetest_debug; - - okfile = CreateFileA("C:\windows\winetest_ntoskrnl_okfile", GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL); - ok(okfile != INVALID_HANDLE_VALUE, "failed to create file, error %u\n", GetLastError()); - subtest("driver"); if (!(service = load_driver(&ctx, filename, L"driver.dll", L"WineTestDriver"))) goto out; @@ -3497,7 +2907,7 @@ START_TEST(ntoskrnl) test_driver_netio(&ctx);
subtest("driver_pnp"); - test_pnp_driver(&ctx); + run_driver_test(&ctx, L"driver_pnp.dll", test_pnp_devices, NULL);
subtest("driver_hid"); test_hid_driver(&ctx, 0, FALSE); @@ -3506,9 +2916,5 @@ START_TEST(ntoskrnl) test_hid_driver(&ctx, 1, TRUE);
out: - testsign_cleanup(&ctx); - UnmapViewOfFile(test_data); - CloseHandle(mapping); - CloseHandle(okfile); - DeleteFileA("C:\windows\winetest_ntoskrnl_okfile"); + driver_test_cleanup(&ctx); }
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntoskrnl.exe/tests/utils.h | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/dlls/ntoskrnl.exe/tests/utils.h b/dlls/ntoskrnl.exe/tests/utils.h index f73f6f938ca..4393518acb9 100644 --- a/dlls/ntoskrnl.exe/tests/utils.h +++ b/dlls/ntoskrnl.exe/tests/utils.h @@ -178,19 +178,31 @@ static inline NTSTATUS winetest_init(void) FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT); }
-static inline void winetest_cleanup(void) +#define winetest_cleanup() winetest_cleanup_(__FILE__) +static inline void winetest_cleanup_(const char *file) { + char test_name[MAX_PATH], *tmp; struct test_data *data; SIZE_T size = sizeof(*data); + const char *source_file; OBJECT_ATTRIBUTES attr; UNICODE_STRING string; void *addr = NULL; HANDLE section;
+ source_file = strrchr(file,'/'); + if (!source_file) source_file = strrchr(file,'\'); + if (!source_file) source_file = file; + else source_file++; + + strcpy(test_name, source_file); + if ((tmp = strrchr(test_name, '.'))) *tmp = 0; + if (winetest_debug) { - kprintf("%04x:ntoskrnl: %d tests executed (%d marked as todo, %d %s), %d skipped.\n", - (DWORD)(DWORD_PTR)PsGetCurrentProcessId(), successes + failures + todo_successes + todo_failures, + kprintf("%04x:%s: %d tests executed (%d marked as todo, %d %s), %d skipped.\n", + (DWORD)(DWORD_PTR)PsGetCurrentProcessId(), test_name, + successes + failures + todo_successes + todo_failures, todo_successes, failures + todo_failures, (failures + todo_failures != 1) ? "failures" : "failure", skipped ); }
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=96736
Your paranoid android.
=== w7u_adm (32 bit report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl is missing some skip messages
=== w8adm (32 bit report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl is missing some skip messages
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntoskrnl.exe/tests/driver_hid.c | 8 -------- 1 file changed, 8 deletions(-)
diff --git a/dlls/ntoskrnl.exe/tests/driver_hid.c b/dlls/ntoskrnl.exe/tests/driver_hid.c index ed0767877ac..9eddcaf4132 100644 --- a/dlls/ntoskrnl.exe/tests/driver_hid.c +++ b/dlls/ntoskrnl.exe/tests/driver_hid.c @@ -37,8 +37,6 @@ #include "driver.h" #include "utils.h"
-static UNICODE_STRING control_symlink; - static unsigned int got_start_device; static DWORD report_id; static DWORD polled; @@ -111,7 +109,6 @@ static NTSTATUS WINAPI driver_pnp(DEVICE_OBJECT *device, IRP *irp) impl->removed = FALSE; KeInitializeSpinLock(&impl->lock); irp_queue_init(&impl->irp_queue); - IoSetDeviceInterfaceState(&control_symlink, TRUE); irp->IoStatus.Status = STATUS_SUCCESS; break;
@@ -137,7 +134,6 @@ static NTSTATUS WINAPI driver_pnp(DEVICE_OBJECT *device, IRP *irp)
case IRP_MN_REMOVE_DEVICE: irp_queue_clear(&impl->irp_queue); - IoSetDeviceInterfaceState(&control_symlink, FALSE); irp->IoStatus.Status = STATUS_SUCCESS; break; } @@ -640,7 +636,6 @@ static NTSTATUS WINAPI driver_ioctl(DEVICE_OBJECT *device, IRP *irp) static NTSTATUS WINAPI driver_add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *fdo) { HID_DEVICE_EXTENSION *ext = fdo->DeviceExtension; - NTSTATUS ret;
/* We should be given the FDO, not the PDO. */ ok(!!ext->PhysicalDeviceObject, "expected non-NULL pdo\n"); @@ -648,9 +643,6 @@ static NTSTATUS WINAPI driver_add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *f ext->PhysicalDeviceObject, ext->NextDeviceObject); todo_wine ok(ext->NextDeviceObject->AttachedDevice == fdo, "wrong attached device\n");
- ret = IoRegisterDeviceInterface(ext->PhysicalDeviceObject, &control_class, NULL, &control_symlink); - ok(!ret, "got %#x\n", ret); - fdo->Flags &= ~DO_DEVICE_INITIALIZING; return STATUS_SUCCESS; }
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=96737
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
ntoskrnl.exe: ntoskrnl.c:2817: Test failed: id 0: got 0xc0000034 ntoskrnl.c:2817: Test failed: id 1: got 0xc0000034 ntoskrnl.c:2817: Test failed: id 0 poll: got 0xc0000034 ntoskrnl.c:2817: Test failed: id 1 poll: got 0xc0000034
=== w7u_adm (32 bit report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl is missing some skip messages
=== w7u_el (32 bit report) ===
ntoskrnl.exe: ntoskrnl.c:2817: Test failed: id 0: got 0xc0000034 ntoskrnl.c:2817: Test failed: id 1: got 0xc0000034 ntoskrnl.c:2817: Test failed: id 0 poll: got 0xc0000034 ntoskrnl.c:2817: Test failed: id 1 poll: got 0xc0000034
=== w8 (32 bit report) ===
ntoskrnl.exe: ntoskrnl.c:2817: Test failed: id 0: got 0xc0000034 ntoskrnl.c:2817: Test failed: id 1: got 0xc0000034 ntoskrnl.c:2817: Test failed: id 0 poll: got 0xc0000034 ntoskrnl.c:2817: Test failed: id 1 poll: got 0xc0000034
=== w8adm (32 bit report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl is missing some skip messages
=== w1064_tsign (64 bit report) ===
ntoskrnl.exe: ntoskrnl.c:2817: Test failed: id 0: got 0xc0000034 ntoskrnl.c:2817: Test failed: id 1: got 0xc0000034 ntoskrnl.c:2817: Test failed: id 0 poll: got 0xc0000034 ntoskrnl.c:2817: Test failed: id 1 poll: got 0xc0000034
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/hid/tests/Makefile.in | 11 +- dlls/hid/tests/hidp.c | 1554 +++++++++++++++++++++++++++ dlls/ntoskrnl.exe/tests/Makefile.in | 4 - dlls/ntoskrnl.exe/tests/ntoskrnl.c | 1508 -------------------------- 4 files changed, 1563 insertions(+), 1514 deletions(-) create mode 100644 dlls/hid/tests/hidp.c
diff --git a/dlls/hid/tests/Makefile.in b/dlls/hid/tests/Makefile.in index 6bf377350c8..10ad66377f6 100644 --- a/dlls/hid/tests/Makefile.in +++ b/dlls/hid/tests/Makefile.in @@ -1,5 +1,12 @@ TESTDLL = hid.dll -IMPORTS = hid setupapi +IMPORTS = hid setupapi ole32 user32 advapi32 uuid crypt32 newdev wintrust +PARENTSRC = ../../ntoskrnl.exe/tests + +driver_hid_IMPORTS = winecrt0 ntoskrnl hal hidclass +driver_hid_EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -Wl,--subsystem,native
C_SRCS = \ - device.c + device.c \ + driver_hid.c \ + driver_hid.spec \ + hidp.c diff --git a/dlls/hid/tests/hidp.c b/dlls/hid/tests/hidp.c new file mode 100644 index 00000000000..711e4b52682 --- /dev/null +++ b/dlls/hid/tests/hidp.c @@ -0,0 +1,1554 @@ +/* + * 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 <stdarg.h> +#include <stddef.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + +#include "ddk/hidclass.h" +#include "ddk/hidsdi.h" +#include "ddk/hidpi.h" + +#include "driver_tests.h" + +#include "wine/test.h" + +#define check_member_(file, line, val, exp, fmt, member) \ + ok_(file, line)((val).member == (exp).member, \ + "got " #member " " fmt ", expected " fmt "\n", \ + (val).member, (exp).member) +#define check_member(val, exp, fmt, member) check_member_(__FILE__, __LINE__, val, exp, fmt, member) + +#define check_hidp_caps(a, b) check_hidp_caps_(__LINE__, a, b) +static inline void check_hidp_caps_(int line, HIDP_CAPS *caps, const HIDP_CAPS *exp) +{ + check_member_(__FILE__, line, *caps, *exp, "%04x", Usage); + check_member_(__FILE__, line, *caps, *exp, "%04x", UsagePage); + check_member_(__FILE__, line, *caps, *exp, "%d", InputReportByteLength); + check_member_(__FILE__, line, *caps, *exp, "%d", OutputReportByteLength); + check_member_(__FILE__, line, *caps, *exp, "%d", FeatureReportByteLength); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberLinkCollectionNodes); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberInputButtonCaps); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberInputValueCaps); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberInputDataIndices); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberOutputButtonCaps); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberOutputValueCaps); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberOutputDataIndices); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberFeatureButtonCaps); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberFeatureValueCaps); + check_member_(__FILE__, line, *caps, *exp, "%d", NumberFeatureDataIndices); +} + +#define check_hidp_link_collection_node(a, b) check_hidp_link_collection_node_(__LINE__, a, b) +static inline void check_hidp_link_collection_node_(int line, HIDP_LINK_COLLECTION_NODE *node, + const HIDP_LINK_COLLECTION_NODE *exp) +{ + check_member_(__FILE__, line, *node, *exp, "%04x", LinkUsage); + check_member_(__FILE__, line, *node, *exp, "%04x", LinkUsagePage); + check_member_(__FILE__, line, *node, *exp, "%d", Parent); + check_member_(__FILE__, line, *node, *exp, "%d", NumberOfChildren); + check_member_(__FILE__, line, *node, *exp, "%d", NextSibling); + check_member_(__FILE__, line, *node, *exp, "%d", FirstChild); + check_member_(__FILE__, line, *node, *exp, "%d", CollectionType); + check_member_(__FILE__, line, *node, *exp, "%d", IsAlias); +} + +#define check_hidp_button_caps(a, b) check_hidp_button_caps_(__LINE__, a, b) +static inline void check_hidp_button_caps_(int line, HIDP_BUTTON_CAPS *caps, const HIDP_BUTTON_CAPS *exp) +{ + check_member_(__FILE__, line, *caps, *exp, "%04x", UsagePage); + check_member_(__FILE__, line, *caps, *exp, "%d", ReportID); + check_member_(__FILE__, line, *caps, *exp, "%d", IsAlias); + check_member_(__FILE__, line, *caps, *exp, "%d", BitField); + check_member_(__FILE__, line, *caps, *exp, "%d", LinkCollection); + check_member_(__FILE__, line, *caps, *exp, "%04x", LinkUsage); + check_member_(__FILE__, line, *caps, *exp, "%04x", LinkUsagePage); + check_member_(__FILE__, line, *caps, *exp, "%d", IsRange); + check_member_(__FILE__, line, *caps, *exp, "%d", IsStringRange); + check_member_(__FILE__, line, *caps, *exp, "%d", IsDesignatorRange); + check_member_(__FILE__, line, *caps, *exp, "%d", IsAbsolute); + + if (!caps->IsRange && !exp->IsRange) + { + check_member_(__FILE__, line, *caps, *exp, "%04x", NotRange.Usage); + check_member_(__FILE__, line, *caps, *exp, "%d", NotRange.DataIndex); + } + else if (caps->IsRange && exp->IsRange) + { + check_member_(__FILE__, line, *caps, *exp, "%04x", Range.UsageMin); + check_member_(__FILE__, line, *caps, *exp, "%04x", Range.UsageMax); + check_member_(__FILE__, line, *caps, *exp, "%d", Range.DataIndexMin); + check_member_(__FILE__, line, *caps, *exp, "%d", Range.DataIndexMax); + } + + if (!caps->IsRange && !exp->IsRange) + check_member_(__FILE__, line, *caps, *exp, "%d", NotRange.StringIndex); + else if (caps->IsStringRange && exp->IsStringRange) + { + check_member_(__FILE__, line, *caps, *exp, "%d", Range.StringMin); + check_member_(__FILE__, line, *caps, *exp, "%d", Range.StringMax); + } + + if (!caps->IsDesignatorRange && !exp->IsDesignatorRange) + check_member_(__FILE__, line, *caps, *exp, "%d", NotRange.DesignatorIndex); + else if (caps->IsDesignatorRange && exp->IsDesignatorRange) + { + check_member_(__FILE__, line, *caps, *exp, "%d", Range.DesignatorMin); + check_member_(__FILE__, line, *caps, *exp, "%d", Range.DesignatorMax); + } +} + +#define check_hidp_value_caps(a, b) check_hidp_value_caps_(__LINE__, a, b) +static inline void check_hidp_value_caps_(int line, HIDP_VALUE_CAPS *caps, const HIDP_VALUE_CAPS *exp) +{ + check_member_(__FILE__, line, *caps, *exp, "%04x", UsagePage); + check_member_(__FILE__, line, *caps, *exp, "%d", ReportID); + check_member_(__FILE__, line, *caps, *exp, "%d", IsAlias); + check_member_(__FILE__, line, *caps, *exp, "%d", BitField); + check_member_(__FILE__, line, *caps, *exp, "%d", LinkCollection); + check_member_(__FILE__, line, *caps, *exp, "%d", LinkUsage); + check_member_(__FILE__, line, *caps, *exp, "%d", LinkUsagePage); + check_member_(__FILE__, line, *caps, *exp, "%d", IsRange); + check_member_(__FILE__, line, *caps, *exp, "%d", IsStringRange); + check_member_(__FILE__, line, *caps, *exp, "%d", IsDesignatorRange); + check_member_(__FILE__, line, *caps, *exp, "%d", IsAbsolute); + + check_member_(__FILE__, line, *caps, *exp, "%d", HasNull); + check_member_(__FILE__, line, *caps, *exp, "%d", BitSize); + check_member_(__FILE__, line, *caps, *exp, "%d", ReportCount); + check_member_(__FILE__, line, *caps, *exp, "%d", UnitsExp); + check_member_(__FILE__, line, *caps, *exp, "%d", Units); + check_member_(__FILE__, line, *caps, *exp, "%d", LogicalMin); + check_member_(__FILE__, line, *caps, *exp, "%d", LogicalMax); + check_member_(__FILE__, line, *caps, *exp, "%d", PhysicalMin); + check_member_(__FILE__, line, *caps, *exp, "%d", PhysicalMax); + + if (!caps->IsRange && !exp->IsRange) + { + check_member_(__FILE__, line, *caps, *exp, "%04x", NotRange.Usage); + check_member_(__FILE__, line, *caps, *exp, "%d", NotRange.DataIndex); + } + else if (caps->IsRange && exp->IsRange) + { + check_member_(__FILE__, line, *caps, *exp, "%04x", Range.UsageMin); + check_member_(__FILE__, line, *caps, *exp, "%04x", Range.UsageMax); + check_member_(__FILE__, line, *caps, *exp, "%d", Range.DataIndexMin); + check_member_(__FILE__, line, *caps, *exp, "%d", Range.DataIndexMax); + } + + if (!caps->IsRange && !exp->IsRange) + check_member_(__FILE__, line, *caps, *exp, "%d", NotRange.StringIndex); + else if (caps->IsStringRange && exp->IsStringRange) + { + check_member_(__FILE__, line, *caps, *exp, "%d", Range.StringMin); + check_member_(__FILE__, line, *caps, *exp, "%d", Range.StringMax); + } + + if (!caps->IsDesignatorRange && !exp->IsDesignatorRange) + check_member_(__FILE__, line, *caps, *exp, "%d", NotRange.DesignatorIndex); + else if (caps->IsDesignatorRange && exp->IsDesignatorRange) + { + check_member_(__FILE__, line, *caps, *exp, "%d", Range.DesignatorMin); + check_member_(__FILE__, line, *caps, *exp, "%d", Range.DesignatorMax); + } +} + +static BOOL sync_ioctl(HANDLE file, DWORD code, void *in_buf, DWORD in_len, void *out_buf, DWORD *ret_len) +{ + OVERLAPPED ovl = {0}; + DWORD out_len = ret_len ? *ret_len : 0; + BOOL ret; + + ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); + ret = DeviceIoControl(file, code, in_buf, in_len, out_buf, out_len, &out_len, &ovl); + if (!ret && GetLastError() == ERROR_IO_PENDING) ret = GetOverlappedResult(file, &ovl, &out_len, TRUE); + CloseHandle(ovl.hEvent); + + if (ret_len) *ret_len = out_len; + return ret; +} + +static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled) +{ + const HIDP_CAPS expect_hidp_caps[] = + { + /* without report id */ + { + .Usage = HID_USAGE_GENERIC_JOYSTICK, + .UsagePage = HID_USAGE_PAGE_GENERIC, + .InputReportByteLength = 26, + .OutputReportByteLength = 3, + .FeatureReportByteLength = 22, + .NumberLinkCollectionNodes = 10, + .NumberInputButtonCaps = 17, + .NumberInputValueCaps = 7, + .NumberInputDataIndices = 47, + .NumberFeatureButtonCaps = 1, + .NumberFeatureValueCaps = 6, + .NumberFeatureDataIndices = 8, + }, + /* with report id */ + { + .Usage = HID_USAGE_GENERIC_JOYSTICK, + .UsagePage = HID_USAGE_PAGE_GENERIC, + .InputReportByteLength = 25, + .OutputReportByteLength = 2, + .FeatureReportByteLength = 21, + .NumberLinkCollectionNodes = 10, + .NumberInputButtonCaps = 17, + .NumberInputValueCaps = 7, + .NumberInputDataIndices = 47, + .NumberFeatureButtonCaps = 1, + .NumberFeatureValueCaps = 6, + .NumberFeatureDataIndices = 8, + }, + }; + const HIDP_BUTTON_CAPS expect_button_caps[] = + { + { + .UsagePage = HID_USAGE_PAGE_BUTTON, + .ReportID = report_id, + .BitField = 2, + .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, + .LinkUsagePage = HID_USAGE_PAGE_GENERIC, + .LinkCollection = 1, + .IsRange = TRUE, + .IsAbsolute = TRUE, + .Range.UsageMin = 1, + .Range.UsageMax = 8, + .Range.DataIndexMin = 2, + .Range.DataIndexMax = 9, + }, + { + .UsagePage = HID_USAGE_PAGE_BUTTON, + .ReportID = report_id, + .BitField = 3, + .LinkCollection = 1, + .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, + .LinkUsagePage = HID_USAGE_PAGE_GENERIC, + .IsRange = TRUE, + .IsAbsolute = TRUE, + .Range.UsageMin = 0x18, + .Range.UsageMax = 0x1f, + .Range.DataIndexMin = 10, + .Range.DataIndexMax = 17, + }, + { + .UsagePage = HID_USAGE_PAGE_KEYBOARD, + .ReportID = report_id, + .BitField = 0x1fc, + .LinkCollection = 1, + .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, + .LinkUsagePage = HID_USAGE_PAGE_GENERIC, + .IsRange = TRUE, + .IsAbsolute = FALSE, + .Range.UsageMin = 0x8, + .Range.UsageMax = 0xf, + .Range.DataIndexMin = 18, + .Range.DataIndexMax = 25, + }, + { + .UsagePage = HID_USAGE_PAGE_BUTTON, + .ReportID = report_id, + .BitField = 2, + .LinkCollection = 1, + .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, + .LinkUsagePage = HID_USAGE_PAGE_GENERIC, + .IsRange = FALSE, + .IsAbsolute = TRUE, + .NotRange.Usage = 0x20, + .NotRange.Reserved1 = 0x20, + .NotRange.DataIndex = 26, + .NotRange.Reserved4 = 26, + }, + }; + const HIDP_VALUE_CAPS expect_value_caps[] = + { + { + .UsagePage = HID_USAGE_PAGE_GENERIC, + .ReportID = report_id, + .BitField = 2, + .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, + .LinkUsagePage = HID_USAGE_PAGE_GENERIC, + .LinkCollection = 1, + .IsAbsolute = TRUE, + .BitSize = 8, + .ReportCount = 1, + .LogicalMin = -128, + .LogicalMax = 127, + .NotRange.Usage = HID_USAGE_GENERIC_Y, + .NotRange.Reserved1 = HID_USAGE_GENERIC_Y, + }, + { + .UsagePage = HID_USAGE_PAGE_GENERIC, + .ReportID = report_id, + .BitField = 2, + .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, + .LinkUsagePage = HID_USAGE_PAGE_GENERIC, + .LinkCollection = 1, + .IsAbsolute = TRUE, + .BitSize = 8, + .ReportCount = 1, + .LogicalMin = -128, + .LogicalMax = 127, + .NotRange.Usage = HID_USAGE_GENERIC_X, + .NotRange.Reserved1 = HID_USAGE_GENERIC_X, + .NotRange.DataIndex = 1, + .NotRange.Reserved4 = 1, + }, + { + .UsagePage = HID_USAGE_PAGE_BUTTON, + .ReportID = report_id, + .BitField = 2, + .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, + .LinkUsagePage = HID_USAGE_PAGE_GENERIC, + .LinkCollection = 1, + .IsAbsolute = TRUE, + .ReportCount = 1, + .LogicalMax = 1, + .IsRange = TRUE, + .Range.UsageMin = 0x21, + .Range.UsageMax = 0x22, + .Range.DataIndexMin = 27, + .Range.DataIndexMax = 28, + }, + { + .UsagePage = HID_USAGE_PAGE_GENERIC, + .ReportID = report_id, + .BitField = 2, + .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, + .LinkUsagePage = HID_USAGE_PAGE_GENERIC, + .LinkCollection = 1, + .IsAbsolute = TRUE, + .BitSize = 4, + .ReportCount = 2, + .LogicalMin = 1, + .LogicalMax = 8, + .NotRange.Usage = HID_USAGE_GENERIC_HATSWITCH, + .NotRange.Reserved1 = HID_USAGE_GENERIC_HATSWITCH, + .NotRange.DataIndex = 29, + .NotRange.Reserved4 = 29, + }, + }; + static const HIDP_LINK_COLLECTION_NODE expect_collections[] = + { + { + .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, + .LinkUsagePage = HID_USAGE_PAGE_GENERIC, + .CollectionType = 1, + .NumberOfChildren = 7, + .FirstChild = 9, + }, + { + .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, + .LinkUsagePage = HID_USAGE_PAGE_GENERIC, + .CollectionType = 2, + }, + }; + static const HIDP_DATA expect_data[] = + { + { .DataIndex = 0, }, + { .DataIndex = 1, }, + { .DataIndex = 5, .RawValue = 1, }, + { .DataIndex = 7, .RawValue = 1, }, + { .DataIndex = 19, .RawValue = 1, }, + { .DataIndex = 21, .RawValue = 1, }, + { .DataIndex = 30, }, + { .DataIndex = 31, }, + { .DataIndex = 32, .RawValue = 0xfeedcafe, }, + { .DataIndex = 37, .RawValue = 1, }, + { .DataIndex = 39, .RawValue = 1, }, + }; + + OVERLAPPED overlapped = {0}, overlapped2 = {0}; + HIDP_LINK_COLLECTION_NODE collections[16]; + PHIDP_PREPARSED_DATA preparsed_data; + USAGE_AND_PAGE usage_and_pages[16]; + HIDP_BUTTON_CAPS button_caps[32]; + HIDP_VALUE_CAPS value_caps[16]; + char buffer[200], report[200]; + DWORD collection_count; + DWORD waveform_list; + HIDP_DATA data[64]; + USAGE usages[16]; + NTSTATUS status; + HIDP_CAPS caps; + unsigned int i; + USHORT count; + ULONG value; + BOOL ret; + + ret = HidD_GetPreparsedData(file, &preparsed_data); + ok(ret, "HidD_GetPreparsedData failed with error %u\n", GetLastError()); + + memset(buffer, 0, sizeof(buffer)); + status = HidP_GetCaps((PHIDP_PREPARSED_DATA)buffer, &caps); + ok(status == HIDP_STATUS_INVALID_PREPARSED_DATA, "HidP_GetCaps returned %#x\n", status); + status = HidP_GetCaps(preparsed_data, &caps); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetCaps returned %#x\n", status); + check_hidp_caps(&caps, &expect_hidp_caps[report_id]); + + collection_count = 0; + status = HidP_GetLinkCollectionNodes(collections, &collection_count, preparsed_data); + ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetLinkCollectionNodes returned %#x\n", status); + ok(collection_count == caps.NumberLinkCollectionNodes, "got %d collection nodes, expected %d\n", + collection_count, caps.NumberLinkCollectionNodes); + collection_count = ARRAY_SIZE(collections); + status = HidP_GetLinkCollectionNodes(collections, &collection_count, (PHIDP_PREPARSED_DATA)buffer); + ok(status == HIDP_STATUS_INVALID_PREPARSED_DATA, "HidP_GetLinkCollectionNodes returned %#x\n", status); + status = HidP_GetLinkCollectionNodes(collections, &collection_count, preparsed_data); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetLinkCollectionNodes returned %#x\n", status); + ok(collection_count == caps.NumberLinkCollectionNodes, "got %d collection nodes, expected %d\n", + collection_count, caps.NumberLinkCollectionNodes); + + for (i = 0; i < ARRAY_SIZE(expect_collections); ++i) + { + winetest_push_context("collections[%d]", i); + check_hidp_link_collection_node(&collections[i], &expect_collections[i]); + winetest_pop_context(); + } + + count = ARRAY_SIZE(button_caps); + status = HidP_GetButtonCaps(HidP_Output, button_caps, &count, preparsed_data); + 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); + ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetButtonCaps returned %#x\n", status); + 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); + memset(button_caps, 0, sizeof(button_caps)); + status = HidP_GetButtonCaps(HidP_Input, button_caps, &count, preparsed_data); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetButtonCaps returned %#x\n", status); + ok(count == caps.NumberInputButtonCaps, "HidP_GetButtonCaps returned count %d, expected %d\n", + count, caps.NumberInputButtonCaps); + + for (i = 0; i < ARRAY_SIZE(expect_button_caps); ++i) + { + winetest_push_context("button_caps[%d]", i); + check_hidp_button_caps(&button_caps[i], &expect_button_caps[i]); + winetest_pop_context(); + } + + count = ARRAY_SIZE(button_caps) - 1; + status = HidP_GetSpecificButtonCaps(HidP_Output, 0, 0, 0, button_caps, &count, preparsed_data); + 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); + ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetSpecificButtonCaps returned %#x\n", status); + 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); + ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetSpecificButtonCaps returned %#x\n", status); + ok(count == 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count, 0); + count = 0xbeef; + status = HidP_GetSpecificButtonCaps(HidP_Input, 0, 0xfffe, 0, button_caps, &count, preparsed_data); + ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetSpecificButtonCaps returned %#x\n", status); + ok(count == 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count, 0); + count = 0xbeef; + status = HidP_GetSpecificButtonCaps(HidP_Input, 0, 0, 0xfffe, button_caps, &count, preparsed_data); + ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetSpecificButtonCaps returned %#x\n", status); + ok(count == 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count, 0); + + count = ARRAY_SIZE(value_caps); + status = HidP_GetValueCaps(HidP_Output, value_caps, &count, preparsed_data); + 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); + ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetValueCaps returned %#x\n", status); + ok(count == caps.NumberInputValueCaps, "HidP_GetValueCaps returned count %d, expected %d\n", + count, caps.NumberInputValueCaps); + count = ARRAY_SIZE(value_caps); + status = HidP_GetValueCaps(HidP_Input, value_caps, &count, (PHIDP_PREPARSED_DATA)buffer); + ok(status == HIDP_STATUS_INVALID_PREPARSED_DATA, "HidP_GetValueCaps returned %#x\n", status); + status = HidP_GetValueCaps(HidP_Input, value_caps, &count, preparsed_data); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetValueCaps returned %#x\n", status); + ok(count == caps.NumberInputValueCaps, "HidP_GetValueCaps returned count %d, expected %d\n", + count, caps.NumberInputValueCaps); + + for (i = 0; i < ARRAY_SIZE(expect_value_caps); ++i) + { + winetest_push_context("value_caps[%d]", i); + check_hidp_value_caps(&value_caps[i], &expect_value_caps[i]); + winetest_pop_context(); + } + + count = ARRAY_SIZE(value_caps) - 4; + status = HidP_GetSpecificValueCaps(HidP_Output, 0, 0, 0, value_caps, &count, preparsed_data); + 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); + ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetSpecificValueCaps returned %#x\n", status); + ok(count == caps.NumberInputValueCaps, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", + count, caps.NumberInputValueCaps); + count = ARRAY_SIZE(value_caps) - 4; + status = HidP_GetSpecificValueCaps(HidP_Input, 0, 0, 0, value_caps + 4, &count, (PHIDP_PREPARSED_DATA)buffer); + ok(status == HIDP_STATUS_INVALID_PREPARSED_DATA, "HidP_GetSpecificValueCaps returned %#x\n", status); + + status = HidP_GetSpecificValueCaps(HidP_Input, 0, 0, 0, value_caps + 4, &count, preparsed_data); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetSpecificValueCaps returned %#x\n", status); + ok(count == caps.NumberInputValueCaps, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", + count, caps.NumberInputValueCaps); + check_hidp_value_caps(&value_caps[4], &value_caps[0]); + check_hidp_value_caps(&value_caps[5], &value_caps[1]); + check_hidp_value_caps(&value_caps[6], &value_caps[2]); + check_hidp_value_caps(&value_caps[7], &value_caps[3]); + + count = 1; + status = HidP_GetSpecificValueCaps(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_HATSWITCH, + value_caps + 4, &count, preparsed_data); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetSpecificValueCaps returned %#x\n", status); + ok(count == 1, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count, 1); + check_hidp_value_caps(&value_caps[4], &value_caps[3]); + + count = 0xdead; + status = HidP_GetSpecificValueCaps(HidP_Input, 0xfffe, 0, 0, value_caps, &count, preparsed_data); + 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); + 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); + 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); + status = HidP_InitializeReportForID(HidP_Input, 1 - report_id, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_REPORT_DOES_NOT_EXIST, "HidP_InitializeReportForID returned %#x\n", status); + + memset(report, 0xcd, sizeof(report)); + status = HidP_InitializeReportForID(HidP_Input, report_id, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_InitializeReportForID returned %#x\n", status); + + memset(buffer, 0xcd, sizeof(buffer)); + memset(buffer, 0, caps.InputReportByteLength); + buffer[0] = report_id; + ok(!memcmp(buffer, report, sizeof(buffer)), "unexpected report data\n"); + + status = HidP_SetUsageValueArray(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, buffer, + sizeof(buffer), preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_NOT_VALUE_ARRAY, "HidP_SetUsageValueArray returned %#x\n", status); + memset(buffer, 0xcd, sizeof(buffer)); + status = HidP_SetUsageValueArray(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_HATSWITCH, buffer, + 0, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_SetUsageValueArray returned %#x\n", status); + status = HidP_SetUsageValueArray(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_HATSWITCH, buffer, + 8, preparsed_data, report, caps.InputReportByteLength); + todo_wine + ok(status == HIDP_STATUS_NOT_IMPLEMENTED, "HidP_SetUsageValueArray returned %#x\n", status); + + status = HidP_GetUsageValueArray(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, buffer, + sizeof(buffer), preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_NOT_VALUE_ARRAY, "HidP_GetUsageValueArray returned %#x\n", status); + memset(buffer, 0xcd, sizeof(buffer)); + status = HidP_GetUsageValueArray(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_HATSWITCH, buffer, + 0, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetUsageValueArray returned %#x\n", status); + status = HidP_GetUsageValueArray(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_HATSWITCH, buffer, + 8, preparsed_data, report, caps.InputReportByteLength); + todo_wine + ok(status == HIDP_STATUS_NOT_IMPLEMENTED, "HidP_GetUsageValueArray returned %#x\n", status); + + value = -128; + status = HidP_SetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, + value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); + value = 0xdeadbeef; + status = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, + &value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsageValue returned %#x\n", status); + ok(value == 0x80, "got value %x, expected %#x\n", value, 0x80); + value = 0xdeadbeef; + status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, + (LONG *)&value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetScaledUsageValue returned %#x\n", status); + ok(value == -128, "got value %x, expected %#x\n", value, -128); + + value = 127; + status = HidP_SetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, + value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); + value = 0xdeadbeef; + status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, + (LONG *)&value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetScaledUsageValue returned %#x\n", status); + ok(value == 127, "got value %x, expected %#x\n", value, 127); + + value = 0; + status = HidP_SetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, + value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); + value = 0xdeadbeef; + status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, + (LONG *)&value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetScaledUsageValue returned %#x\n", status); + ok(value == 0, "got value %x, expected %#x\n", value, 0); + + value = 0x7fffffff; + status = HidP_SetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); + value = 0xdeadbeef; + status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + (LONG *)&value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_VALUE_OUT_OF_RANGE, "HidP_GetScaledUsageValue returned %#x\n", status); + ok(value == 0, "got value %x, expected %#x\n", value, 0); + value = 0xdeadbeef; + status = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + &value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsageValue returned %#x\n", status); + ok(value == 0x7fffffff, "got value %x, expected %#x\n", value, 0x7fffffff); + + value = 0x3fffffff; + status = HidP_SetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); + value = 0xdeadbeef; + status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + (LONG *)&value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetScaledUsageValue returned %#x\n", status); + ok(value == 0x7fffffff, "got value %x, expected %#x\n", value, 0x7fffffff); + + value = 0; + status = HidP_SetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); + value = 0xdeadbeef; + status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + (LONG *)&value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetScaledUsageValue returned %#x\n", status); + ok(value == 0x80000000, "got value %x, expected %#x\n", value, 0x80000000); + + value = 0; + status = HidP_SetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_RX, + value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); + value = 0xdeadbeef; + status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_RX, + (LONG *)&value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetScaledUsageValue returned %#x\n", status); + ok(value == 0, "got value %x, expected %#x\n", value, 0); + + value = 0xfeedcafe; + status = HidP_SetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_RY, + value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); + value = 0xdeadbeef; + status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_RY, + (LONG *)&value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_BAD_LOG_PHY_VALUES, "HidP_GetScaledUsageValue returned %#x\n", status); + ok(value == 0, "got value %x, expected %#x\n", value, 0); + status = HidP_SetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_RY, + 0, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_BAD_LOG_PHY_VALUES, "HidP_GetScaledUsageValue returned %#x\n", status); + ok(value == 0, "got value %x, expected %#x\n", value, 0); + + value = HidP_MaxUsageListLength(HidP_Feature + 1, 0, preparsed_data); + ok(value == 0, "HidP_MaxUsageListLength(HidP_Feature + 1, 0) returned %d, expected %d\n", value, 0); + value = HidP_MaxUsageListLength(HidP_Input, 0, preparsed_data); + ok(value == 50, "HidP_MaxUsageListLength(HidP_Input, 0) returned %d, expected %d\n", value, 50); + value = HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_BUTTON, preparsed_data); + ok(value == 32, "HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_BUTTON) returned %d, expected %d\n", value, 32); + value = HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_LED, preparsed_data); + ok(value == 8, "HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_LED) returned %d, expected %d\n", value, 8); + value = HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_BUTTON, preparsed_data); + ok(value == 8, "HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_BUTTON) returned %d, expected %d\n", value, 8); + value = HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_LED, preparsed_data); + ok(value == 0, "HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_LED) returned %d, expected %d\n", value, 0); + + usages[0] = 0xff; + value = 1; + status = HidP_SetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usages, &value, + preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_SetUsages returned %#x\n", status); + usages[1] = 2; + usages[2] = 0xff; + value = 3; + status = HidP_SetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usages, &value, + preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_SetUsages returned %#x\n", status); + usages[0] = 4; + usages[1] = 6; + value = 2; + status = HidP_SetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usages, &value, + preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsages returned %#x\n", status); + usages[0] = 4; + usages[1] = 6; + value = 2; + status = HidP_SetUsages(HidP_Input, HID_USAGE_PAGE_LED, 0, usages, &value, preparsed_data, + report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsages returned %#x\n", status); + + value = ARRAY_SIZE(usages); + status = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_KEYBOARD, 0, usages, &value, preparsed_data, + report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsages returned %#x\n", status); + ok(value == 0, "got usage count %d, expected %d\n", value, 2); + + usages[0] = 0x9; + usages[1] = 0xb; + usages[2] = 0xa; + value = 3; + ok(report[6] == 0, "got report[6] %x expected 0\n", report[6]); + ok(report[7] == 0, "got report[7] %x expected 0\n", report[7]); + memcpy(buffer, report, caps.InputReportByteLength); + status = HidP_SetUsages(HidP_Input, HID_USAGE_PAGE_KEYBOARD, 0, usages, &value, preparsed_data, + report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_SetUsages returned %#x\n", status); + buffer[6] = 2; + buffer[7] = 4; + ok(!memcmp(buffer, report, caps.InputReportByteLength), "unexpected report data\n"); + + status = HidP_SetUsageValue(HidP_Input, HID_USAGE_PAGE_LED, 0, 6, 1, + preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_SetUsageValue returned %#x\n", status); + + value = 0xdeadbeef; + status = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_LED, 0, 6, &value, + preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_SetUsageValue returned %#x\n", status); + ok(value == 0xdeadbeef, "got value %x, expected %#x\n", value, 0xdeadbeef); + + value = 1; + status = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usages, &value, + preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetUsages returned %#x\n", status); + ok(value == 2, "got usage count %d, expected %d\n", value, 2); + value = ARRAY_SIZE(usages); + memset(usages, 0xcd, sizeof(usages)); + status = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usages, &value, + preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsages returned %#x\n", status); + ok(value == 2, "got usage count %d, expected %d\n", value, 2); + ok(usages[0] == 4, "got usages[0] %x, expected %x\n", usages[0], 4); + ok(usages[1] == 6, "got usages[1] %x, expected %x\n", usages[1], 6); + + value = ARRAY_SIZE(usages); + memset(usages, 0xcd, sizeof(usages)); + status = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_LED, 0, usages, &value, preparsed_data, + report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsages returned %#x\n", status); + ok(value == 2, "got usage count %d, expected %d\n", value, 2); + ok(usages[0] == 6, "got usages[0] %x, expected %x\n", usages[0], 6); + ok(usages[1] == 4, "got usages[1] %x, expected %x\n", usages[1], 4); + + value = ARRAY_SIZE(usage_and_pages); + memset(usage_and_pages, 0xcd, sizeof(usage_and_pages)); + status = HidP_GetUsagesEx(HidP_Input, 0, usage_and_pages, &value, preparsed_data, report, + caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsagesEx returned %#x\n", status); + ok(value == 6, "got usage count %d, expected %d\n", value, 4); + ok(usage_and_pages[0].UsagePage == HID_USAGE_PAGE_BUTTON, "got usage_and_pages[0] UsagePage %x, expected %x\n", + usage_and_pages[0].UsagePage, HID_USAGE_PAGE_BUTTON); + ok(usage_and_pages[1].UsagePage == HID_USAGE_PAGE_BUTTON, "got usage_and_pages[1] UsagePage %x, expected %x\n", + usage_and_pages[1].UsagePage, HID_USAGE_PAGE_BUTTON); + ok(usage_and_pages[2].UsagePage == HID_USAGE_PAGE_KEYBOARD, "got usage_and_pages[2] UsagePage %x, expected %x\n", + usage_and_pages[2].UsagePage, HID_USAGE_PAGE_KEYBOARD); + ok(usage_and_pages[3].UsagePage == HID_USAGE_PAGE_KEYBOARD, "got usage_and_pages[3] UsagePage %x, expected %x\n", + usage_and_pages[3].UsagePage, HID_USAGE_PAGE_KEYBOARD); + ok(usage_and_pages[4].UsagePage == HID_USAGE_PAGE_LED, "got usage_and_pages[4] UsagePage %x, expected %x\n", + usage_and_pages[4].UsagePage, HID_USAGE_PAGE_LED); + ok(usage_and_pages[5].UsagePage == HID_USAGE_PAGE_LED, "got usage_and_pages[5] UsagePage %x, expected %x\n", + usage_and_pages[5].UsagePage, HID_USAGE_PAGE_LED); + ok(usage_and_pages[0].Usage == 4, "got usage_and_pages[0] Usage %x, expected %x\n", + usage_and_pages[0].Usage, 4); + ok(usage_and_pages[1].Usage == 6, "got usage_and_pages[1] Usage %x, expected %x\n", + usage_and_pages[1].Usage, 6); + ok(usage_and_pages[2].Usage == 9, "got usage_and_pages[2] Usage %x, expected %x\n", + usage_and_pages[2].Usage, 9); + ok(usage_and_pages[3].Usage == 11, "got usage_and_pages[3] Usage %x, expected %x\n", + usage_and_pages[3].Usage, 11); + ok(usage_and_pages[4].Usage == 6, "got usage_and_pages[4] Usage %x, expected %x\n", + usage_and_pages[4].Usage, 6); + ok(usage_and_pages[5].Usage == 4, "got usage_and_pages[5] Usage %x, expected %x\n", + usage_and_pages[5].Usage, 4); + + value = HidP_MaxDataListLength(HidP_Feature + 1, preparsed_data); + ok(value == 0, "HidP_MaxDataListLength(HidP_Feature + 1) returned %d, expected %d\n", value, 0); + value = HidP_MaxDataListLength(HidP_Input, preparsed_data); + ok(value == 58, "HidP_MaxDataListLength(HidP_Input) returned %d, expected %d\n", value, 58); + value = HidP_MaxDataListLength(HidP_Output, preparsed_data); + ok(value == 0, "HidP_MaxDataListLength(HidP_Output) returned %d, expected %d\n", value, 0); + value = HidP_MaxDataListLength(HidP_Feature, preparsed_data); + ok(value == 14, "HidP_MaxDataListLength(HidP_Feature) returned %d, expected %d\n", value, 14); + + value = 1; + status = HidP_GetData(HidP_Input, data, &value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetData returned %#x\n", status); + ok(value == 11, "got data count %d, expected %d\n", value, 11); + memset(data, 0, sizeof(data)); + status = HidP_GetData(HidP_Input, data, &value, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetData returned %#x\n", status); + for (i = 0; i < ARRAY_SIZE(expect_data); ++i) + { + winetest_push_context("data[%d]", i); + check_member(data[i], expect_data[i], "%d", DataIndex); + check_member(data[i], expect_data[i], "%d", RawValue); + winetest_pop_context(); + } + + /* HID nary usage collections are set with 1-based usage index in their declaration order */ + + memset(report, 0, caps.InputReportByteLength); + status = HidP_InitializeReportForID(HidP_Input, report_id, preparsed_data, report, + caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_InitializeReportForID returned %#x\n", status); + value = 2; + usages[0] = 0x8e; + usages[1] = 0x8f; + status = HidP_SetUsages(HidP_Input, HID_USAGE_PAGE_KEYBOARD, 0, usages, &value, preparsed_data, + report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsages returned %#x\n", status); + ok(report[caps.InputReportByteLength - 2] == 3, "unexpected usage index %d, expected 3\n", + report[caps.InputReportByteLength - 2]); + ok(report[caps.InputReportByteLength - 1] == 4, "unexpected usage index %d, expected 4\n", + report[caps.InputReportByteLength - 1]); + status = HidP_UnsetUsages(HidP_Input, HID_USAGE_PAGE_KEYBOARD, 0, usages, &value, preparsed_data, + report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_UnsetUsages returned %#x\n", status); + ok(report[caps.InputReportByteLength - 2] == 0, "unexpected usage index %d, expected 0\n", + report[caps.InputReportByteLength - 2]); + ok(report[caps.InputReportByteLength - 1] == 0, "unexpected usage index %d, expected 0\n", + report[caps.InputReportByteLength - 1]); + status = HidP_UnsetUsages(HidP_Input, HID_USAGE_PAGE_KEYBOARD, 0, usages, &value, preparsed_data, + report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_BUTTON_NOT_PRESSED, "HidP_UnsetUsages returned %#x\n", status); + value = 1; + usages[0] = 0x8c; + status = HidP_SetUsages(HidP_Input, HID_USAGE_PAGE_KEYBOARD, 0, usages, &value, preparsed_data, + report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsages returned %#x\n", status); + ok(report[caps.InputReportByteLength - 2] == 1, "unexpected usage index %d, expected 1\n", + report[caps.InputReportByteLength - 2]); + + memset(report, 0xcd, sizeof(report)); + status = HidP_InitializeReportForID(HidP_Feature, 3, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_REPORT_DOES_NOT_EXIST, "HidP_InitializeReportForID returned %#x\n", status); + + memset(report, 0xcd, sizeof(report)); + status = HidP_InitializeReportForID(HidP_Feature, report_id, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_InitializeReportForID returned %#x\n", status); + + memset(buffer, 0xcd, sizeof(buffer)); + memset(buffer, 0, caps.FeatureReportByteLength); + buffer[0] = report_id; + ok(!memcmp(buffer, report, sizeof(buffer)), "unexpected report data\n"); + + for (i = 0; i < caps.NumberLinkCollectionNodes; ++i) + { + if (collections[i].LinkUsagePage != HID_USAGE_PAGE_HAPTICS) continue; + if (collections[i].LinkUsage == HID_USAGE_HAPTICS_WAVEFORM_LIST) break; + } + ok(i < caps.NumberLinkCollectionNodes, + "HID_USAGE_HAPTICS_WAVEFORM_LIST collection not found\n"); + waveform_list = i; + + status = HidP_SetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, + HID_USAGE_HAPTICS_WAVEFORM_RUMBLE, (PHIDP_PREPARSED_DATA)buffer, + report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_INVALID_PREPARSED_DATA, "HidP_SetUsageValue returned %#x\n", status); + status = HidP_SetUsageValue(HidP_Feature + 1, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, + HID_USAGE_HAPTICS_WAVEFORM_RUMBLE, preparsed_data, report, + caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_INVALID_REPORT_TYPE, "HidP_SetUsageValue returned %#x\n", status); + status = HidP_SetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, + HID_USAGE_HAPTICS_WAVEFORM_RUMBLE, preparsed_data, report, + caps.FeatureReportByteLength + 1); + ok(status == HIDP_STATUS_INVALID_REPORT_LENGTH, "HidP_SetUsageValue returned %#x\n", status); + report[0] = 1 - report_id; + status = HidP_SetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, + HID_USAGE_HAPTICS_WAVEFORM_RUMBLE, preparsed_data, report, + caps.FeatureReportByteLength); + ok(status == (report_id ? HIDP_STATUS_SUCCESS : HIDP_STATUS_INCOMPATIBLE_REPORT_ID), + "HidP_SetUsageValue returned %#x\n", status); + report[0] = 2; + status = HidP_SetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, + HID_USAGE_HAPTICS_WAVEFORM_RUMBLE, preparsed_data, report, + caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_INCOMPATIBLE_REPORT_ID, "HidP_SetUsageValue returned %#x\n", status); + report[0] = report_id; + status = HidP_SetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, 0xdead, 3, HID_USAGE_HAPTICS_WAVEFORM_RUMBLE, + preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_SetUsageValue returned %#x\n", status); + + status = HidP_SetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, + HID_USAGE_HAPTICS_WAVEFORM_RUMBLE, preparsed_data, report, + caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); + + memset(buffer, 0xcd, sizeof(buffer)); + memset(buffer, 0, caps.FeatureReportByteLength); + buffer[0] = report_id; + value = HID_USAGE_HAPTICS_WAVEFORM_RUMBLE; + memcpy(buffer + 1, &value, 2); + ok(!memcmp(buffer, report, sizeof(buffer)), "unexpected report data\n"); + + status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, &value, + (PHIDP_PREPARSED_DATA)buffer, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_INVALID_PREPARSED_DATA, "HidP_GetUsageValue returned %#x\n", status); + status = HidP_GetUsageValue(HidP_Feature + 1, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, + &value, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_INVALID_REPORT_TYPE, "HidP_GetUsageValue returned %#x\n", status); + status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, &value, + preparsed_data, report, caps.FeatureReportByteLength + 1); + ok(status == HIDP_STATUS_INVALID_REPORT_LENGTH, "HidP_GetUsageValue returned %#x\n", status); + report[0] = 1 - report_id; + status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, &value, + preparsed_data, report, caps.FeatureReportByteLength); + ok(status == (report_id ? HIDP_STATUS_SUCCESS : HIDP_STATUS_INCOMPATIBLE_REPORT_ID), + "HidP_GetUsageValue returned %#x\n", status); + report[0] = 2; + status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, &value, + preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_INCOMPATIBLE_REPORT_ID, "HidP_GetUsageValue returned %#x\n", status); + report[0] = report_id; + status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, 0xdead, 3, &value, + preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetUsageValue returned %#x\n", status); + + value = 0xdeadbeef; + status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, &value, + preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsageValue returned %#x\n", status); + ok(value == HID_USAGE_HAPTICS_WAVEFORM_RUMBLE, "got value %x, expected %#x\n", value, + HID_USAGE_HAPTICS_WAVEFORM_RUMBLE); + + memset(buffer, 0xff, sizeof(buffer)); + status = HidP_SetUsageValueArray(HidP_Feature, HID_USAGE_PAGE_HAPTICS, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME, buffer, + 0, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_SetUsageValueArray returned %#x\n", status); + status = HidP_SetUsageValueArray(HidP_Feature, HID_USAGE_PAGE_HAPTICS, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME, buffer, + 64, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValueArray returned %#x\n", status); + ok(!memcmp(report + 9, buffer, 8), "unexpected report data\n"); + + memset(buffer, 0, sizeof(buffer)); + status = HidP_GetUsageValueArray(HidP_Feature, HID_USAGE_PAGE_HAPTICS, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME, buffer, + 0, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetUsageValueArray returned %#x\n", status); + status = HidP_GetUsageValueArray(HidP_Feature, HID_USAGE_PAGE_HAPTICS, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME, buffer, + 64, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsageValueArray returned %#x\n", status); + memset(buffer + 16, 0xff, 8); + ok(!memcmp(buffer, buffer + 16, 16), "unexpected report value\n"); + + + value = 0x7fffffff; + status = HidP_SetUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + value, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); + value = 0xdeadbeef; + status = HidP_GetScaledUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + (LONG *)&value, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_VALUE_OUT_OF_RANGE, "HidP_GetScaledUsageValue returned %#x\n", status); + ok(value == 0, "got value %x, expected %#x\n", value, 0); + value = 0xdeadbeef; + status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + &value, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsageValue returned %#x\n", status); + ok(value == 0x7fffffff, "got value %x, expected %#x\n", value, 0x7fffffff); + + value = 0x7fff; + status = HidP_SetUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + value, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); + value = 0xdeadbeef; + status = HidP_GetScaledUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + (LONG *)&value, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetScaledUsageValue returned %#x\n", status); + ok(value == 0x0003ffff, "got value %x, expected %#x\n", value, 0x0003ffff); + + value = 0; + status = HidP_SetUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + value, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); + value = 0xdeadbeef; + status = HidP_GetScaledUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + (LONG *)&value, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetScaledUsageValue returned %#x\n", status); + ok(value == 0xfff90000, "got value %x, expected %#x\n", value, 0xfff90000); + status = HidP_SetScaledUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + 0x1000, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetScaledUsageValue returned %#x\n", status); + value = 0; + status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + &value, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsageValue returned %#x\n", status); + ok(value == 0xfffff518, "got value %x, expected %#x\n", value, 0xfffff518); + status = HidP_SetScaledUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + 0, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetScaledUsageValue returned %#x\n", status); + value = 0; + status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + &value, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsageValue returned %#x\n", status); + ok(value == 0xfffff45e, "got value %x, expected %#x\n", value, 0xfffff45e); + status = HidP_SetScaledUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + 0xdead, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetScaledUsageValue returned %#x\n", status); + value = 0; + status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + &value, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsageValue returned %#x\n", status); + ok(value == 0xfffffe7d, "got value %x, expected %#x\n", value, 0xfffffe7d); + status = HidP_SetScaledUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + 0xbeef, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_SetScaledUsageValue returned %#x\n", status); + value = 0; + status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, + &value, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsageValue returned %#x\n", status); + ok(value == 0xfffffd0b, "got value %x, expected %#x\n", value, 0xfffffd0b); + + + memset(report, 0xcd, sizeof(report)); + status = HidP_InitializeReportForID(HidP_Input, report_id, preparsed_data, report, caps.InputReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_InitializeReportForID returned %#x\n", status); + + SetLastError(0xdeadbeef); + ret = HidD_GetInputReport(file, report, 0); + ok(!ret, "HidD_GetInputReport succeeded\n"); + ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "HidD_GetInputReport returned error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = HidD_GetInputReport(file, report, caps.InputReportByteLength - 1); + ok(!ret, "HidD_GetInputReport succeeded\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), + "HidD_GetInputReport returned error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + memset(buffer, 0x5a, sizeof(buffer)); + ret = HidD_GetInputReport(file, buffer, caps.InputReportByteLength); + if (report_id || broken(!ret) /* w7u */) + { + ok(!ret, "HidD_GetInputReport succeeded, last error %u\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), + "HidD_GetInputReport returned error %u\n", GetLastError()); + } + else + { + ok(ret, "HidD_GetInputReport failed, last error %u\n", GetLastError()); + ok(buffer[0] == 0x5a, "got buffer[0] %x, expected 0x5a\n", (BYTE)buffer[0]); + } + + SetLastError(0xdeadbeef); + ret = HidD_GetInputReport(file, report, caps.InputReportByteLength); + ok(ret, "HidD_GetInputReport failed, last error %u\n", GetLastError()); + ok(report[0] == report_id, "got report[0] %02x, expected %02x\n", report[0], report_id); + + SetLastError(0xdeadbeef); + value = caps.InputReportByteLength * 2; + ret = sync_ioctl(file, IOCTL_HID_GET_INPUT_REPORT, NULL, 0, report, &value); + ok(ret, "IOCTL_HID_GET_INPUT_REPORT failed, last error %u\n", GetLastError()); + ok(value == 3, "got length %u, expected 3\n", value); + ok(report[0] == report_id, "got report[0] %02x, expected %02x\n", report[0], report_id); + + + memset(report, 0xcd, sizeof(report)); + status = HidP_InitializeReportForID(HidP_Feature, report_id, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_InitializeReportForID returned %#x\n", status); + + SetLastError(0xdeadbeef); + ret = HidD_GetFeature(file, report, 0); + ok(!ret, "HidD_GetFeature succeeded\n"); + ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "HidD_GetFeature returned error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = HidD_GetFeature(file, report, caps.FeatureReportByteLength - 1); + ok(!ret, "HidD_GetFeature succeeded\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), + "HidD_GetFeature returned error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + memset(buffer, 0x5a, sizeof(buffer)); + ret = HidD_GetFeature(file, buffer, caps.FeatureReportByteLength); + if (report_id || broken(!ret)) + { + ok(!ret, "HidD_GetFeature succeeded, last error %u\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), + "HidD_GetFeature returned error %u\n", GetLastError()); + } + else + { + ok(ret, "HidD_GetFeature failed, last error %u\n", GetLastError()); + ok(buffer[0] == 0x5a, "got buffer[0] %x, expected 0x5a\n", (BYTE)buffer[0]); + } + + SetLastError(0xdeadbeef); + ret = HidD_GetFeature(file, report, caps.FeatureReportByteLength); + ok(ret, "HidD_GetFeature failed, last error %u\n", GetLastError()); + ok(report[0] == report_id, "got report[0] %02x, expected %02x\n", report[0], report_id); + + value = caps.FeatureReportByteLength * 2; + SetLastError(0xdeadbeef); + ret = sync_ioctl(file, IOCTL_HID_GET_FEATURE, NULL, 0, report, &value); + ok(ret, "IOCTL_HID_GET_FEATURE failed, last error %u\n", GetLastError()); + ok(value == 3, "got length %u, expected 3\n", value); + ok(report[0] == report_id, "got report[0] %02x, expected %02x\n", report[0], report_id); + + + memset(report, 0xcd, sizeof(report)); + status = HidP_InitializeReportForID(HidP_Feature, report_id, preparsed_data, report, caps.FeatureReportByteLength); + ok(status == HIDP_STATUS_SUCCESS, "HidP_InitializeReportForID returned %#x\n", status); + + SetLastError(0xdeadbeef); + ret = HidD_SetFeature(file, report, 0); + ok(!ret, "HidD_SetFeature succeeded\n"); + ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "HidD_SetFeature returned error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = HidD_SetFeature(file, report, caps.FeatureReportByteLength - 1); + ok(!ret, "HidD_SetFeature succeeded\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), + "HidD_SetFeature returned error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + memset(buffer, 0x5a, sizeof(buffer)); + ret = HidD_SetFeature(file, buffer, caps.FeatureReportByteLength); + if (report_id || broken(!ret)) + { + ok(!ret, "HidD_SetFeature succeeded, last error %u\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), + "HidD_SetFeature returned error %u\n", GetLastError()); + } + else + { + ok(ret, "HidD_SetFeature failed, last error %u\n", GetLastError()); + } + + SetLastError(0xdeadbeef); + ret = HidD_SetFeature(file, report, caps.FeatureReportByteLength); + ok(ret, "HidD_SetFeature failed, last error %u\n", GetLastError()); + + value = caps.FeatureReportByteLength * 2; + SetLastError(0xdeadbeef); + ret = sync_ioctl(file, IOCTL_HID_SET_FEATURE, NULL, 0, report, &value); + ok(!ret, "IOCTL_HID_SET_FEATURE succeeded\n"); + ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "IOCTL_HID_SET_FEATURE returned error %u\n", GetLastError()); + value = 0; + SetLastError(0xdeadbeef); + ret = sync_ioctl(file, IOCTL_HID_SET_FEATURE, report, caps.FeatureReportByteLength * 2, NULL, &value); + ok(ret, "IOCTL_HID_SET_FEATURE failed, last error %u\n", GetLastError()); + ok(value == 3, "got length %u, expected 3\n", value); + + + memset(report, 0xcd, sizeof(report)); + status = HidP_InitializeReportForID(HidP_Output, report_id, preparsed_data, report, caps.OutputReportByteLength); + ok(status == HIDP_STATUS_REPORT_DOES_NOT_EXIST, "HidP_InitializeReportForID returned %#x\n", status); + memset(report, 0, caps.OutputReportByteLength); + report[0] = report_id; + + SetLastError(0xdeadbeef); + ret = HidD_SetOutputReport(file, report, 0); + ok(!ret, "HidD_SetOutputReport succeeded\n"); + ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "HidD_SetOutputReport returned error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = HidD_SetOutputReport(file, report, caps.OutputReportByteLength - 1); + ok(!ret, "HidD_SetOutputReport succeeded\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), + "HidD_SetOutputReport returned error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + memset(buffer, 0x5a, sizeof(buffer)); + ret = HidD_SetOutputReport(file, buffer, caps.OutputReportByteLength); + if (report_id || broken(!ret)) + { + ok(!ret, "HidD_SetOutputReport succeeded, last error %u\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), + "HidD_SetOutputReport returned error %u\n", GetLastError()); + } + else + { + ok(ret, "HidD_SetOutputReport failed, last error %u\n", GetLastError()); + } + + SetLastError(0xdeadbeef); + ret = HidD_SetOutputReport(file, report, caps.OutputReportByteLength); + ok(ret, "HidD_SetOutputReport failed, last error %u\n", GetLastError()); + + value = caps.OutputReportByteLength * 2; + SetLastError(0xdeadbeef); + ret = sync_ioctl(file, IOCTL_HID_SET_OUTPUT_REPORT, NULL, 0, report, &value); + ok(!ret, "IOCTL_HID_SET_OUTPUT_REPORT succeeded\n"); + ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "IOCTL_HID_SET_OUTPUT_REPORT returned error %u\n", GetLastError()); + value = 0; + SetLastError(0xdeadbeef); + ret = sync_ioctl(file, IOCTL_HID_SET_OUTPUT_REPORT, report, caps.OutputReportByteLength * 2, NULL, &value); + ok(ret, "IOCTL_HID_SET_OUTPUT_REPORT failed, last error %u\n", GetLastError()); + ok(value == 3, "got length %u, expected 3\n", value); + + + SetLastError(0xdeadbeef); + ret = WriteFile(file, report, 0, &value, NULL); + ok(!ret, "WriteFile succeeded\n"); + ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "WriteFile returned error %u\n", GetLastError()); + ok(value == 0, "WriteFile returned %x\n", value); + SetLastError(0xdeadbeef); + ret = WriteFile(file, report, caps.OutputReportByteLength - 1, &value, NULL); + ok(!ret, "WriteFile succeeded\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_INVALID_USER_BUFFER, + "WriteFile returned error %u\n", GetLastError()); + ok(value == 0, "WriteFile returned %x\n", value); + + memset(report, 0xcd, sizeof(report)); + report[0] = 0xa5; + SetLastError(0xdeadbeef); + ret = WriteFile(file, report, caps.OutputReportByteLength * 2, &value, NULL); + if (report_id || broken(!ret) /* w7u */) + { + ok(!ret, "WriteFile succeeded\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "WriteFile returned error %u\n", GetLastError()); + ok(value == 0, "WriteFile wrote %u\n", value); + SetLastError(0xdeadbeef); + report[0] = report_id; + ret = WriteFile(file, report, caps.OutputReportByteLength, &value, NULL); + } + + if (report_id) + { + ok(ret, "WriteFile failed, last error %u\n", GetLastError()); + ok(value == 2, "WriteFile wrote %u\n", value); + } + else + { + ok(ret, "WriteFile failed, last error %u\n", GetLastError()); + ok(value == 3, "WriteFile wrote %u\n", value); + } + + + memset(report, 0xcd, sizeof(report)); + SetLastError(0xdeadbeef); + ret = ReadFile(file, report, 0, &value, NULL); + ok(!ret && GetLastError() == ERROR_INVALID_USER_BUFFER, "ReadFile failed, last error %u\n", GetLastError()); + ok(value == 0, "ReadFile returned %x\n", value); + SetLastError(0xdeadbeef); + ret = ReadFile(file, report, caps.InputReportByteLength - 1, &value, NULL); + ok(!ret && GetLastError() == ERROR_INVALID_USER_BUFFER, "ReadFile failed, last error %u\n", GetLastError()); + ok(value == 0, "ReadFile returned %x\n", value); + + if (polled) + { + memset(report, 0xcd, sizeof(report)); + SetLastError(0xdeadbeef); + ret = ReadFile(file, report, caps.InputReportByteLength, &value, NULL); + ok(ret, "ReadFile failed, last error %u\n", GetLastError()); + ok(value == (report_id ? 3 : 4), "ReadFile returned %x\n", value); + ok(report[0] == report_id, "unexpected report data\n"); + + overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL); + overlapped2.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL); + + /* drain available input reports */ + SetLastError(0xdeadbeef); + while (ReadFile(async_file, report, caps.InputReportByteLength, NULL, &overlapped)) + ResetEvent(overlapped.hEvent); + ok(GetLastError() == ERROR_IO_PENDING, "ReadFile returned error %u\n", GetLastError()); + ret = GetOverlappedResult(async_file, &overlapped, &value, TRUE); + ok(ret, "GetOverlappedResult failed, last error %u\n", GetLastError()); + ok(value == (report_id ? 3 : 4), "GetOverlappedResult returned length %u, expected 3\n", value); + ResetEvent(overlapped.hEvent); + + memcpy(buffer, report, caps.InputReportByteLength); + memcpy(buffer + caps.InputReportByteLength, report, caps.InputReportByteLength); + + SetLastError(0xdeadbeef); + ret = ReadFile(async_file, report, caps.InputReportByteLength, NULL, &overlapped); + ok(!ret, "ReadFile succeeded\n"); + ok(GetLastError() == ERROR_IO_PENDING, "ReadFile returned error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = ReadFile(async_file, buffer, caps.InputReportByteLength, NULL, &overlapped2); + ok(!ret, "ReadFile succeeded\n"); + ok(GetLastError() == ERROR_IO_PENDING, "ReadFile returned error %u\n", GetLastError()); + + /* wait for second report to be ready */ + ret = GetOverlappedResult(async_file, &overlapped2, &value, TRUE); + ok(ret, "GetOverlappedResult failed, last error %u\n", GetLastError()); + ok(value == (report_id ? 3 : 4), "GetOverlappedResult returned length %u, expected 3\n", value); + /* first report should be ready and the same */ + ret = GetOverlappedResult(async_file, &overlapped, &value, FALSE); + ok(ret, "GetOverlappedResult failed, last error %u\n", GetLastError()); + ok(value == (report_id ? 3 : 4), "GetOverlappedResult returned length %u, expected 3\n", value); + ok(memcmp(report, buffer + caps.InputReportByteLength, caps.InputReportByteLength), + "expected different report\n"); + ok(!memcmp(report, buffer, caps.InputReportByteLength), "expected identical reports\n"); + + CloseHandle(overlapped.hEvent); + CloseHandle(overlapped2.hEvent); + } + + + HidD_FreePreparsedData(preparsed_data); +} + +struct test_hid_params +{ + BOOL report_id; + BOOL polled; +}; + +static void test_hid_device(void *args) +{ + struct test_hid_params *params = args; + BOOL report_id = params->report_id, polled = params->polled; + 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)}; + ULONG count, poll_freq, out_len; + HANDLE file, async_file; + BOOL ret, found = FALSE; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING string; + IO_STATUS_BLOCK io; + NTSTATUS status; + unsigned int i; + HDEVINFO set; + GUID guid; + + winetest_push_context("id %d%s", report_id, polled ? " poll" : ""); + + HidD_GetHidGuid(&guid); + + set = SetupDiGetClassDevsA(&guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); + ok(set != INVALID_HANDLE_VALUE, "failed to get device list, error %#x\n", GetLastError()); + + for (i = 0; SetupDiEnumDeviceInfo(set, i, &device); ++i) + { + ret = SetupDiEnumDeviceInterfaces(set, &device, &guid, 0, &iface); + ok(ret, "failed to get interface, error %#x\n", GetLastError()); + ok(IsEqualGUID(&iface.InterfaceClassGuid, &guid), + "wrong class %s\n", debugstr_guid(&iface.InterfaceClassGuid)); + ok(iface.Flags == SPINT_ACTIVE, "got flags %#x\n", iface.Flags); + + iface_detail->cbSize = sizeof(*iface_detail); + ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, iface_detail, sizeof(buffer), NULL, NULL); + ok(ret, "failed to get interface path, error %#x\n", GetLastError()); + + if (strstr(iface_detail->DevicePath, "\\?\hid#winetest#1")) + { + found = TRUE; + break; + } + } + + SetupDiDestroyDeviceInfoList(set); + + todo_wine ok(found, "didn't find device\n"); + + file = CreateFileA(iface_detail->DevicePath, FILE_READ_ACCESS | FILE_WRITE_ACCESS, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); + + count = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = HidD_GetNumInputBuffers(file, &count); + ok(ret, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError()); + ok(count == 32, "HidD_GetNumInputBuffers returned %u\n", count); + + SetLastError(0xdeadbeef); + ret = HidD_SetNumInputBuffers(file, 1); + ok(!ret, "HidD_SetNumInputBuffers succeeded\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "HidD_SetNumInputBuffers returned error %u\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = HidD_SetNumInputBuffers(file, 513); + ok(!ret, "HidD_SetNumInputBuffers succeeded\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "HidD_SetNumInputBuffers returned error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = HidD_SetNumInputBuffers(file, 16); + ok(ret, "HidD_SetNumInputBuffers failed last error %u\n", GetLastError()); + + count = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = HidD_GetNumInputBuffers(file, &count); + ok(ret, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError()); + ok(count == 16, "HidD_GetNumInputBuffers returned %u\n", count); + + async_file = CreateFileA(iface_detail->DevicePath, FILE_READ_ACCESS | FILE_WRITE_ACCESS, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL); + ok(async_file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); + + count = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = HidD_GetNumInputBuffers(async_file, &count); + ok(ret, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError()); + ok(count == 32, "HidD_GetNumInputBuffers returned %u\n", count); + + SetLastError(0xdeadbeef); + ret = HidD_SetNumInputBuffers(async_file, 2); + ok(ret, "HidD_SetNumInputBuffers failed last error %u\n", GetLastError()); + + count = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = HidD_GetNumInputBuffers(async_file, &count); + ok(ret, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError()); + ok(count == 2, "HidD_GetNumInputBuffers returned %u\n", count); + count = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = HidD_GetNumInputBuffers(file, &count); + ok(ret, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError()); + ok(count == 16, "HidD_GetNumInputBuffers returned %u\n", count); + + if (polled) + { + out_len = sizeof(ULONG); + SetLastError(0xdeadbeef); + ret = sync_ioctl(file, IOCTL_HID_GET_POLL_FREQUENCY_MSEC, NULL, 0, &poll_freq, &out_len); + ok(ret, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError()); + ok(out_len == sizeof(ULONG), "got out_len %u, expected sizeof(ULONG)\n", out_len); + todo_wine ok(poll_freq == 5, "got poll_freq %u, expected 5\n", poll_freq); + + out_len = 0; + poll_freq = 500; + SetLastError(0xdeadbeef); + ret = sync_ioctl(file, IOCTL_HID_SET_POLL_FREQUENCY_MSEC, &poll_freq, sizeof(ULONG), NULL, &out_len); + ok(ret, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError()); + ok(out_len == 0, "got out_len %u, expected 0\n", out_len); + + out_len = 0; + poll_freq = 10001; + SetLastError(0xdeadbeef); + ret = sync_ioctl(file, IOCTL_HID_SET_POLL_FREQUENCY_MSEC, &poll_freq, sizeof(ULONG), NULL, &out_len); + ok(ret, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError()); + ok(out_len == 0, "got out_len %u, expected 0\n", out_len); + + out_len = 0; + poll_freq = 0; + SetLastError(0xdeadbeef); + ret = sync_ioctl(file, IOCTL_HID_SET_POLL_FREQUENCY_MSEC, &poll_freq, sizeof(ULONG), NULL, &out_len); + ok(ret, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError()); + ok(out_len == 0, "got out_len %u, expected 0\n", out_len); + + out_len = sizeof(ULONG); + SetLastError(0xdeadbeef); + ret = sync_ioctl(file, IOCTL_HID_GET_POLL_FREQUENCY_MSEC, NULL, 0, &poll_freq, &out_len); + ok(ret, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError()); + ok(out_len == sizeof(ULONG), "got out_len %u, expected sizeof(ULONG)\n", out_len); + ok(poll_freq == 10000, "got poll_freq %u, expected 10000\n", poll_freq); + + out_len = 0; + poll_freq = 500; + SetLastError(0xdeadbeef); + ret = sync_ioctl(file, IOCTL_HID_SET_POLL_FREQUENCY_MSEC, &poll_freq, sizeof(ULONG), NULL, &out_len); + ok(ret, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError()); + ok(out_len == 0, "got out_len %u, expected 0\n", out_len); + + out_len = sizeof(ULONG); + SetLastError(0xdeadbeef); + ret = sync_ioctl(async_file, IOCTL_HID_GET_POLL_FREQUENCY_MSEC, NULL, 0, &poll_freq, &out_len); + ok(ret, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError()); + ok(out_len == sizeof(ULONG), "got out_len %u, expected sizeof(ULONG)\n", out_len); + ok(poll_freq == 500, "got poll_freq %u, expected 500\n", poll_freq); + } + + test_hidp(file, async_file, report_id, polled); + + CloseHandle(async_file); + CloseHandle(file); + + RtlInitUnicodeString(&string, L"\??\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}"); + InitializeObjectAttributes(&attr, &string, OBJ_CASE_INSENSITIVE, NULL, NULL); + status = NtOpenFile(&file, SYNCHRONIZE, &attr, &io, 0, FILE_SYNCHRONOUS_IO_NONALERT); + ok(status == STATUS_OBJECT_NAME_NOT_FOUND, "got %#x\n", status); + + winetest_pop_context(); +} + +static void test_hid_driver(struct testsign_context *ctx, DWORD report_id, DWORD polled) +{ + struct test_hid_params params = {.report_id = report_id, .polled = polled}; + SP_DEVINFO_DATA device = {sizeof(device)}; + char cwd[MAX_PATH], tempdir[MAX_PATH]; + LSTATUS status; + HKEY hkey; + + GetCurrentDirectoryA(ARRAY_SIZE(cwd), cwd); + GetTempPathA(ARRAY_SIZE(tempdir), tempdir); + SetCurrentDirectoryA(tempdir); + + status = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"System\CurrentControlSet\Services\winetest", 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL); + ok(!status, "RegCreateKeyExW returned %#x\n", status); + + status = RegSetValueExW(hkey, L"ReportID", 0, REG_DWORD, (void *)&report_id, sizeof(report_id)); + ok(!status, "RegSetValueExW returned %#x\n", status); + + status = RegSetValueExW(hkey, L"PolledMode", 0, REG_DWORD, (void *)&polled, sizeof(polled)); + ok(!status, "RegSetValueExW returned %#x\n", status); + + subtest("driver_hid"); + run_driver_test(ctx, L"driver_hid.dll", test_hid_device, ¶ms); +} + +START_TEST(hidp) +{ + struct testsign_context ctx; + if (!driver_test_init(&ctx)) + return; + + test_hid_driver(&ctx, 0, FALSE); + test_hid_driver(&ctx, 1, FALSE); + test_hid_driver(&ctx, 0, TRUE); + test_hid_driver(&ctx, 1, TRUE); + + driver_test_cleanup(&ctx); +} diff --git a/dlls/ntoskrnl.exe/tests/Makefile.in b/dlls/ntoskrnl.exe/tests/Makefile.in index 85a6925138a..ab1db85adbb 100644 --- a/dlls/ntoskrnl.exe/tests/Makefile.in +++ b/dlls/ntoskrnl.exe/tests/Makefile.in @@ -7,8 +7,6 @@ driver2_IMPORTS = winecrt0 ntoskrnl hal driver2_EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -Wl,--subsystem,native driver3_IMPORTS = winecrt0 ntoskrnl hal driver3_EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -Wl,--subsystem,native -driver_hid_IMPORTS = winecrt0 ntoskrnl hal hidclass -driver_hid_EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -Wl,--subsystem,native driver_netio_IMPORTS = winecrt0 ntoskrnl hal netio driver_netio_EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -Wl,--subsystem,native driver_pnp_IMPORTS = winecrt0 ntoskrnl hal @@ -21,8 +19,6 @@ SOURCES = \ driver2.spec \ driver3.c \ driver3.spec \ - driver_hid.c \ - driver_hid.spec \ driver_netio.c \ driver_netio.spec \ driver_pnp.c \ diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index a0636099def..9c8b1f96371 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -1341,1508 +1341,6 @@ static void test_pnp_devices(void *args) UnregisterClassA("ntoskrnl_test_wc", GetModuleHandleA(NULL)); }
-#define check_member_(file, line, val, exp, fmt, member) \ - ok_(file, line)((val).member == (exp).member, \ - "got " #member " " fmt ", expected " fmt "\n", \ - (val).member, (exp).member) -#define check_member(val, exp, fmt, member) check_member_(__FILE__, __LINE__, val, exp, fmt, member) - -#define check_hidp_caps(a, b) check_hidp_caps_(__LINE__, a, b) -static inline void check_hidp_caps_(int line, HIDP_CAPS *caps, const HIDP_CAPS *exp) -{ - check_member_(__FILE__, line, *caps, *exp, "%04x", Usage); - check_member_(__FILE__, line, *caps, *exp, "%04x", UsagePage); - check_member_(__FILE__, line, *caps, *exp, "%d", InputReportByteLength); - check_member_(__FILE__, line, *caps, *exp, "%d", OutputReportByteLength); - check_member_(__FILE__, line, *caps, *exp, "%d", FeatureReportByteLength); - check_member_(__FILE__, line, *caps, *exp, "%d", NumberLinkCollectionNodes); - check_member_(__FILE__, line, *caps, *exp, "%d", NumberInputButtonCaps); - check_member_(__FILE__, line, *caps, *exp, "%d", NumberInputValueCaps); - check_member_(__FILE__, line, *caps, *exp, "%d", NumberInputDataIndices); - check_member_(__FILE__, line, *caps, *exp, "%d", NumberOutputButtonCaps); - check_member_(__FILE__, line, *caps, *exp, "%d", NumberOutputValueCaps); - check_member_(__FILE__, line, *caps, *exp, "%d", NumberOutputDataIndices); - check_member_(__FILE__, line, *caps, *exp, "%d", NumberFeatureButtonCaps); - check_member_(__FILE__, line, *caps, *exp, "%d", NumberFeatureValueCaps); - check_member_(__FILE__, line, *caps, *exp, "%d", NumberFeatureDataIndices); -} - -#define check_hidp_link_collection_node(a, b) check_hidp_link_collection_node_(__LINE__, a, b) -static inline void check_hidp_link_collection_node_(int line, HIDP_LINK_COLLECTION_NODE *node, - const HIDP_LINK_COLLECTION_NODE *exp) -{ - check_member_(__FILE__, line, *node, *exp, "%04x", LinkUsage); - check_member_(__FILE__, line, *node, *exp, "%04x", LinkUsagePage); - check_member_(__FILE__, line, *node, *exp, "%d", Parent); - check_member_(__FILE__, line, *node, *exp, "%d", NumberOfChildren); - check_member_(__FILE__, line, *node, *exp, "%d", NextSibling); - check_member_(__FILE__, line, *node, *exp, "%d", FirstChild); - check_member_(__FILE__, line, *node, *exp, "%d", CollectionType); - check_member_(__FILE__, line, *node, *exp, "%d", IsAlias); -} - -#define check_hidp_button_caps(a, b) check_hidp_button_caps_(__LINE__, a, b) -static inline void check_hidp_button_caps_(int line, HIDP_BUTTON_CAPS *caps, const HIDP_BUTTON_CAPS *exp) -{ - check_member_(__FILE__, line, *caps, *exp, "%04x", UsagePage); - check_member_(__FILE__, line, *caps, *exp, "%d", ReportID); - check_member_(__FILE__, line, *caps, *exp, "%d", IsAlias); - check_member_(__FILE__, line, *caps, *exp, "%d", BitField); - check_member_(__FILE__, line, *caps, *exp, "%d", LinkCollection); - check_member_(__FILE__, line, *caps, *exp, "%04x", LinkUsage); - check_member_(__FILE__, line, *caps, *exp, "%04x", LinkUsagePage); - check_member_(__FILE__, line, *caps, *exp, "%d", IsRange); - check_member_(__FILE__, line, *caps, *exp, "%d", IsStringRange); - check_member_(__FILE__, line, *caps, *exp, "%d", IsDesignatorRange); - check_member_(__FILE__, line, *caps, *exp, "%d", IsAbsolute); - - if (!caps->IsRange && !exp->IsRange) - { - check_member_(__FILE__, line, *caps, *exp, "%04x", NotRange.Usage); - check_member_(__FILE__, line, *caps, *exp, "%d", NotRange.DataIndex); - } - else if (caps->IsRange && exp->IsRange) - { - check_member_(__FILE__, line, *caps, *exp, "%04x", Range.UsageMin); - check_member_(__FILE__, line, *caps, *exp, "%04x", Range.UsageMax); - check_member_(__FILE__, line, *caps, *exp, "%d", Range.DataIndexMin); - check_member_(__FILE__, line, *caps, *exp, "%d", Range.DataIndexMax); - } - - if (!caps->IsRange && !exp->IsRange) - check_member_(__FILE__, line, *caps, *exp, "%d", NotRange.StringIndex); - else if (caps->IsStringRange && exp->IsStringRange) - { - check_member_(__FILE__, line, *caps, *exp, "%d", Range.StringMin); - check_member_(__FILE__, line, *caps, *exp, "%d", Range.StringMax); - } - - if (!caps->IsDesignatorRange && !exp->IsDesignatorRange) - check_member_(__FILE__, line, *caps, *exp, "%d", NotRange.DesignatorIndex); - else if (caps->IsDesignatorRange && exp->IsDesignatorRange) - { - check_member_(__FILE__, line, *caps, *exp, "%d", Range.DesignatorMin); - check_member_(__FILE__, line, *caps, *exp, "%d", Range.DesignatorMax); - } -} - -#define check_hidp_value_caps(a, b) check_hidp_value_caps_(__LINE__, a, b) -static inline void check_hidp_value_caps_(int line, HIDP_VALUE_CAPS *caps, const HIDP_VALUE_CAPS *exp) -{ - check_member_(__FILE__, line, *caps, *exp, "%04x", UsagePage); - check_member_(__FILE__, line, *caps, *exp, "%d", ReportID); - check_member_(__FILE__, line, *caps, *exp, "%d", IsAlias); - check_member_(__FILE__, line, *caps, *exp, "%d", BitField); - check_member_(__FILE__, line, *caps, *exp, "%d", LinkCollection); - check_member_(__FILE__, line, *caps, *exp, "%d", LinkUsage); - check_member_(__FILE__, line, *caps, *exp, "%d", LinkUsagePage); - check_member_(__FILE__, line, *caps, *exp, "%d", IsRange); - check_member_(__FILE__, line, *caps, *exp, "%d", IsStringRange); - check_member_(__FILE__, line, *caps, *exp, "%d", IsDesignatorRange); - check_member_(__FILE__, line, *caps, *exp, "%d", IsAbsolute); - - check_member_(__FILE__, line, *caps, *exp, "%d", HasNull); - check_member_(__FILE__, line, *caps, *exp, "%d", BitSize); - check_member_(__FILE__, line, *caps, *exp, "%d", ReportCount); - check_member_(__FILE__, line, *caps, *exp, "%d", UnitsExp); - check_member_(__FILE__, line, *caps, *exp, "%d", Units); - check_member_(__FILE__, line, *caps, *exp, "%d", LogicalMin); - check_member_(__FILE__, line, *caps, *exp, "%d", LogicalMax); - check_member_(__FILE__, line, *caps, *exp, "%d", PhysicalMin); - check_member_(__FILE__, line, *caps, *exp, "%d", PhysicalMax); - - if (!caps->IsRange && !exp->IsRange) - { - check_member_(__FILE__, line, *caps, *exp, "%04x", NotRange.Usage); - check_member_(__FILE__, line, *caps, *exp, "%d", NotRange.DataIndex); - } - else if (caps->IsRange && exp->IsRange) - { - check_member_(__FILE__, line, *caps, *exp, "%04x", Range.UsageMin); - check_member_(__FILE__, line, *caps, *exp, "%04x", Range.UsageMax); - check_member_(__FILE__, line, *caps, *exp, "%d", Range.DataIndexMin); - check_member_(__FILE__, line, *caps, *exp, "%d", Range.DataIndexMax); - } - - if (!caps->IsRange && !exp->IsRange) - check_member_(__FILE__, line, *caps, *exp, "%d", NotRange.StringIndex); - else if (caps->IsStringRange && exp->IsStringRange) - { - check_member_(__FILE__, line, *caps, *exp, "%d", Range.StringMin); - check_member_(__FILE__, line, *caps, *exp, "%d", Range.StringMax); - } - - if (!caps->IsDesignatorRange && !exp->IsDesignatorRange) - check_member_(__FILE__, line, *caps, *exp, "%d", NotRange.DesignatorIndex); - else if (caps->IsDesignatorRange && exp->IsDesignatorRange) - { - check_member_(__FILE__, line, *caps, *exp, "%d", Range.DesignatorMin); - check_member_(__FILE__, line, *caps, *exp, "%d", Range.DesignatorMax); - } -} - -static BOOL sync_ioctl(HANDLE file, DWORD code, void *in_buf, DWORD in_len, void *out_buf, DWORD *ret_len) -{ - OVERLAPPED ovl = {0}; - DWORD out_len = ret_len ? *ret_len : 0; - BOOL ret; - - ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); - ret = DeviceIoControl(file, code, in_buf, in_len, out_buf, out_len, &out_len, &ovl); - if (!ret && GetLastError() == ERROR_IO_PENDING) ret = GetOverlappedResult(file, &ovl, &out_len, TRUE); - CloseHandle(ovl.hEvent); - - if (ret_len) *ret_len = out_len; - return ret; -} - -static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled) -{ - const HIDP_CAPS expect_hidp_caps[] = - { - /* without report id */ - { - .Usage = HID_USAGE_GENERIC_JOYSTICK, - .UsagePage = HID_USAGE_PAGE_GENERIC, - .InputReportByteLength = 26, - .OutputReportByteLength = 3, - .FeatureReportByteLength = 22, - .NumberLinkCollectionNodes = 10, - .NumberInputButtonCaps = 17, - .NumberInputValueCaps = 7, - .NumberInputDataIndices = 47, - .NumberFeatureButtonCaps = 1, - .NumberFeatureValueCaps = 6, - .NumberFeatureDataIndices = 8, - }, - /* with report id */ - { - .Usage = HID_USAGE_GENERIC_JOYSTICK, - .UsagePage = HID_USAGE_PAGE_GENERIC, - .InputReportByteLength = 25, - .OutputReportByteLength = 2, - .FeatureReportByteLength = 21, - .NumberLinkCollectionNodes = 10, - .NumberInputButtonCaps = 17, - .NumberInputValueCaps = 7, - .NumberInputDataIndices = 47, - .NumberFeatureButtonCaps = 1, - .NumberFeatureValueCaps = 6, - .NumberFeatureDataIndices = 8, - }, - }; - const HIDP_BUTTON_CAPS expect_button_caps[] = - { - { - .UsagePage = HID_USAGE_PAGE_BUTTON, - .ReportID = report_id, - .BitField = 2, - .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, - .LinkUsagePage = HID_USAGE_PAGE_GENERIC, - .LinkCollection = 1, - .IsRange = TRUE, - .IsAbsolute = TRUE, - .Range.UsageMin = 1, - .Range.UsageMax = 8, - .Range.DataIndexMin = 2, - .Range.DataIndexMax = 9, - }, - { - .UsagePage = HID_USAGE_PAGE_BUTTON, - .ReportID = report_id, - .BitField = 3, - .LinkCollection = 1, - .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, - .LinkUsagePage = HID_USAGE_PAGE_GENERIC, - .IsRange = TRUE, - .IsAbsolute = TRUE, - .Range.UsageMin = 0x18, - .Range.UsageMax = 0x1f, - .Range.DataIndexMin = 10, - .Range.DataIndexMax = 17, - }, - { - .UsagePage = HID_USAGE_PAGE_KEYBOARD, - .ReportID = report_id, - .BitField = 0x1fc, - .LinkCollection = 1, - .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, - .LinkUsagePage = HID_USAGE_PAGE_GENERIC, - .IsRange = TRUE, - .IsAbsolute = FALSE, - .Range.UsageMin = 0x8, - .Range.UsageMax = 0xf, - .Range.DataIndexMin = 18, - .Range.DataIndexMax = 25, - }, - { - .UsagePage = HID_USAGE_PAGE_BUTTON, - .ReportID = report_id, - .BitField = 2, - .LinkCollection = 1, - .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, - .LinkUsagePage = HID_USAGE_PAGE_GENERIC, - .IsRange = FALSE, - .IsAbsolute = TRUE, - .NotRange.Usage = 0x20, - .NotRange.Reserved1 = 0x20, - .NotRange.DataIndex = 26, - .NotRange.Reserved4 = 26, - }, - }; - const HIDP_VALUE_CAPS expect_value_caps[] = - { - { - .UsagePage = HID_USAGE_PAGE_GENERIC, - .ReportID = report_id, - .BitField = 2, - .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, - .LinkUsagePage = HID_USAGE_PAGE_GENERIC, - .LinkCollection = 1, - .IsAbsolute = TRUE, - .BitSize = 8, - .ReportCount = 1, - .LogicalMin = -128, - .LogicalMax = 127, - .NotRange.Usage = HID_USAGE_GENERIC_Y, - .NotRange.Reserved1 = HID_USAGE_GENERIC_Y, - }, - { - .UsagePage = HID_USAGE_PAGE_GENERIC, - .ReportID = report_id, - .BitField = 2, - .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, - .LinkUsagePage = HID_USAGE_PAGE_GENERIC, - .LinkCollection = 1, - .IsAbsolute = TRUE, - .BitSize = 8, - .ReportCount = 1, - .LogicalMin = -128, - .LogicalMax = 127, - .NotRange.Usage = HID_USAGE_GENERIC_X, - .NotRange.Reserved1 = HID_USAGE_GENERIC_X, - .NotRange.DataIndex = 1, - .NotRange.Reserved4 = 1, - }, - { - .UsagePage = HID_USAGE_PAGE_BUTTON, - .ReportID = report_id, - .BitField = 2, - .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, - .LinkUsagePage = HID_USAGE_PAGE_GENERIC, - .LinkCollection = 1, - .IsAbsolute = TRUE, - .ReportCount = 1, - .LogicalMax = 1, - .IsRange = TRUE, - .Range.UsageMin = 0x21, - .Range.UsageMax = 0x22, - .Range.DataIndexMin = 27, - .Range.DataIndexMax = 28, - }, - { - .UsagePage = HID_USAGE_PAGE_GENERIC, - .ReportID = report_id, - .BitField = 2, - .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, - .LinkUsagePage = HID_USAGE_PAGE_GENERIC, - .LinkCollection = 1, - .IsAbsolute = TRUE, - .BitSize = 4, - .ReportCount = 2, - .LogicalMin = 1, - .LogicalMax = 8, - .NotRange.Usage = HID_USAGE_GENERIC_HATSWITCH, - .NotRange.Reserved1 = HID_USAGE_GENERIC_HATSWITCH, - .NotRange.DataIndex = 29, - .NotRange.Reserved4 = 29, - }, - }; - static const HIDP_LINK_COLLECTION_NODE expect_collections[] = - { - { - .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, - .LinkUsagePage = HID_USAGE_PAGE_GENERIC, - .CollectionType = 1, - .NumberOfChildren = 7, - .FirstChild = 9, - }, - { - .LinkUsage = HID_USAGE_GENERIC_JOYSTICK, - .LinkUsagePage = HID_USAGE_PAGE_GENERIC, - .CollectionType = 2, - }, - }; - static const HIDP_DATA expect_data[] = - { - { .DataIndex = 0, }, - { .DataIndex = 1, }, - { .DataIndex = 5, .RawValue = 1, }, - { .DataIndex = 7, .RawValue = 1, }, - { .DataIndex = 19, .RawValue = 1, }, - { .DataIndex = 21, .RawValue = 1, }, - { .DataIndex = 30, }, - { .DataIndex = 31, }, - { .DataIndex = 32, .RawValue = 0xfeedcafe, }, - { .DataIndex = 37, .RawValue = 1, }, - { .DataIndex = 39, .RawValue = 1, }, - }; - - OVERLAPPED overlapped = {0}, overlapped2 = {0}; - HIDP_LINK_COLLECTION_NODE collections[16]; - PHIDP_PREPARSED_DATA preparsed_data; - USAGE_AND_PAGE usage_and_pages[16]; - HIDP_BUTTON_CAPS button_caps[32]; - HIDP_VALUE_CAPS value_caps[16]; - char buffer[200], report[200]; - DWORD collection_count; - DWORD waveform_list; - HIDP_DATA data[64]; - USAGE usages[16]; - NTSTATUS status; - HIDP_CAPS caps; - unsigned int i; - USHORT count; - ULONG value; - BOOL ret; - - ret = HidD_GetPreparsedData(file, &preparsed_data); - ok(ret, "HidD_GetPreparsedData failed with error %u\n", GetLastError()); - - memset(buffer, 0, sizeof(buffer)); - status = HidP_GetCaps((PHIDP_PREPARSED_DATA)buffer, &caps); - ok(status == HIDP_STATUS_INVALID_PREPARSED_DATA, "HidP_GetCaps returned %#x\n", status); - status = HidP_GetCaps(preparsed_data, &caps); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetCaps returned %#x\n", status); - check_hidp_caps(&caps, &expect_hidp_caps[report_id]); - - collection_count = 0; - status = HidP_GetLinkCollectionNodes(collections, &collection_count, preparsed_data); - ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetLinkCollectionNodes returned %#x\n", status); - ok(collection_count == caps.NumberLinkCollectionNodes, "got %d collection nodes, expected %d\n", - collection_count, caps.NumberLinkCollectionNodes); - collection_count = ARRAY_SIZE(collections); - status = HidP_GetLinkCollectionNodes(collections, &collection_count, (PHIDP_PREPARSED_DATA)buffer); - ok(status == HIDP_STATUS_INVALID_PREPARSED_DATA, "HidP_GetLinkCollectionNodes returned %#x\n", status); - status = HidP_GetLinkCollectionNodes(collections, &collection_count, preparsed_data); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetLinkCollectionNodes returned %#x\n", status); - ok(collection_count == caps.NumberLinkCollectionNodes, "got %d collection nodes, expected %d\n", - collection_count, caps.NumberLinkCollectionNodes); - - for (i = 0; i < ARRAY_SIZE(expect_collections); ++i) - { - winetest_push_context("collections[%d]", i); - check_hidp_link_collection_node(&collections[i], &expect_collections[i]); - winetest_pop_context(); - } - - count = ARRAY_SIZE(button_caps); - status = HidP_GetButtonCaps(HidP_Output, button_caps, &count, preparsed_data); - 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); - ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetButtonCaps returned %#x\n", status); - 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); - memset(button_caps, 0, sizeof(button_caps)); - status = HidP_GetButtonCaps(HidP_Input, button_caps, &count, preparsed_data); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetButtonCaps returned %#x\n", status); - ok(count == caps.NumberInputButtonCaps, "HidP_GetButtonCaps returned count %d, expected %d\n", - count, caps.NumberInputButtonCaps); - - for (i = 0; i < ARRAY_SIZE(expect_button_caps); ++i) - { - winetest_push_context("button_caps[%d]", i); - check_hidp_button_caps(&button_caps[i], &expect_button_caps[i]); - winetest_pop_context(); - } - - count = ARRAY_SIZE(button_caps) - 1; - status = HidP_GetSpecificButtonCaps(HidP_Output, 0, 0, 0, button_caps, &count, preparsed_data); - 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); - ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetSpecificButtonCaps returned %#x\n", status); - 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); - ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetSpecificButtonCaps returned %#x\n", status); - ok(count == 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count, 0); - count = 0xbeef; - status = HidP_GetSpecificButtonCaps(HidP_Input, 0, 0xfffe, 0, button_caps, &count, preparsed_data); - ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetSpecificButtonCaps returned %#x\n", status); - ok(count == 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count, 0); - count = 0xbeef; - status = HidP_GetSpecificButtonCaps(HidP_Input, 0, 0, 0xfffe, button_caps, &count, preparsed_data); - ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetSpecificButtonCaps returned %#x\n", status); - ok(count == 0, "HidP_GetSpecificButtonCaps returned count %d, expected %d\n", count, 0); - - count = ARRAY_SIZE(value_caps); - status = HidP_GetValueCaps(HidP_Output, value_caps, &count, preparsed_data); - 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); - ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetValueCaps returned %#x\n", status); - ok(count == caps.NumberInputValueCaps, "HidP_GetValueCaps returned count %d, expected %d\n", - count, caps.NumberInputValueCaps); - count = ARRAY_SIZE(value_caps); - status = HidP_GetValueCaps(HidP_Input, value_caps, &count, (PHIDP_PREPARSED_DATA)buffer); - ok(status == HIDP_STATUS_INVALID_PREPARSED_DATA, "HidP_GetValueCaps returned %#x\n", status); - status = HidP_GetValueCaps(HidP_Input, value_caps, &count, preparsed_data); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetValueCaps returned %#x\n", status); - ok(count == caps.NumberInputValueCaps, "HidP_GetValueCaps returned count %d, expected %d\n", - count, caps.NumberInputValueCaps); - - for (i = 0; i < ARRAY_SIZE(expect_value_caps); ++i) - { - winetest_push_context("value_caps[%d]", i); - check_hidp_value_caps(&value_caps[i], &expect_value_caps[i]); - winetest_pop_context(); - } - - count = ARRAY_SIZE(value_caps) - 4; - status = HidP_GetSpecificValueCaps(HidP_Output, 0, 0, 0, value_caps, &count, preparsed_data); - 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); - ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetSpecificValueCaps returned %#x\n", status); - ok(count == caps.NumberInputValueCaps, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", - count, caps.NumberInputValueCaps); - count = ARRAY_SIZE(value_caps) - 4; - status = HidP_GetSpecificValueCaps(HidP_Input, 0, 0, 0, value_caps + 4, &count, (PHIDP_PREPARSED_DATA)buffer); - ok(status == HIDP_STATUS_INVALID_PREPARSED_DATA, "HidP_GetSpecificValueCaps returned %#x\n", status); - - status = HidP_GetSpecificValueCaps(HidP_Input, 0, 0, 0, value_caps + 4, &count, preparsed_data); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetSpecificValueCaps returned %#x\n", status); - ok(count == caps.NumberInputValueCaps, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", - count, caps.NumberInputValueCaps); - check_hidp_value_caps(&value_caps[4], &value_caps[0]); - check_hidp_value_caps(&value_caps[5], &value_caps[1]); - check_hidp_value_caps(&value_caps[6], &value_caps[2]); - check_hidp_value_caps(&value_caps[7], &value_caps[3]); - - count = 1; - status = HidP_GetSpecificValueCaps(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_HATSWITCH, - value_caps + 4, &count, preparsed_data); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetSpecificValueCaps returned %#x\n", status); - ok(count == 1, "HidP_GetSpecificValueCaps returned count %d, expected %d\n", count, 1); - check_hidp_value_caps(&value_caps[4], &value_caps[3]); - - count = 0xdead; - status = HidP_GetSpecificValueCaps(HidP_Input, 0xfffe, 0, 0, value_caps, &count, preparsed_data); - 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); - 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); - 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); - status = HidP_InitializeReportForID(HidP_Input, 1 - report_id, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_REPORT_DOES_NOT_EXIST, "HidP_InitializeReportForID returned %#x\n", status); - - memset(report, 0xcd, sizeof(report)); - status = HidP_InitializeReportForID(HidP_Input, report_id, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_InitializeReportForID returned %#x\n", status); - - memset(buffer, 0xcd, sizeof(buffer)); - memset(buffer, 0, caps.InputReportByteLength); - buffer[0] = report_id; - ok(!memcmp(buffer, report, sizeof(buffer)), "unexpected report data\n"); - - status = HidP_SetUsageValueArray(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, buffer, - sizeof(buffer), preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_NOT_VALUE_ARRAY, "HidP_SetUsageValueArray returned %#x\n", status); - memset(buffer, 0xcd, sizeof(buffer)); - status = HidP_SetUsageValueArray(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_HATSWITCH, buffer, - 0, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_SetUsageValueArray returned %#x\n", status); - status = HidP_SetUsageValueArray(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_HATSWITCH, buffer, - 8, preparsed_data, report, caps.InputReportByteLength); - todo_wine - ok(status == HIDP_STATUS_NOT_IMPLEMENTED, "HidP_SetUsageValueArray returned %#x\n", status); - - status = HidP_GetUsageValueArray(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, buffer, - sizeof(buffer), preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_NOT_VALUE_ARRAY, "HidP_GetUsageValueArray returned %#x\n", status); - memset(buffer, 0xcd, sizeof(buffer)); - status = HidP_GetUsageValueArray(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_HATSWITCH, buffer, - 0, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetUsageValueArray returned %#x\n", status); - status = HidP_GetUsageValueArray(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_HATSWITCH, buffer, - 8, preparsed_data, report, caps.InputReportByteLength); - todo_wine - ok(status == HIDP_STATUS_NOT_IMPLEMENTED, "HidP_GetUsageValueArray returned %#x\n", status); - - value = -128; - status = HidP_SetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, - value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); - value = 0xdeadbeef; - status = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, - &value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsageValue returned %#x\n", status); - ok(value == 0x80, "got value %x, expected %#x\n", value, 0x80); - value = 0xdeadbeef; - status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, - (LONG *)&value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetScaledUsageValue returned %#x\n", status); - ok(value == -128, "got value %x, expected %#x\n", value, -128); - - value = 127; - status = HidP_SetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, - value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); - value = 0xdeadbeef; - status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, - (LONG *)&value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetScaledUsageValue returned %#x\n", status); - ok(value == 127, "got value %x, expected %#x\n", value, 127); - - value = 0; - status = HidP_SetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, - value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); - value = 0xdeadbeef; - status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_X, - (LONG *)&value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetScaledUsageValue returned %#x\n", status); - ok(value == 0, "got value %x, expected %#x\n", value, 0); - - value = 0x7fffffff; - status = HidP_SetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); - value = 0xdeadbeef; - status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - (LONG *)&value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_VALUE_OUT_OF_RANGE, "HidP_GetScaledUsageValue returned %#x\n", status); - ok(value == 0, "got value %x, expected %#x\n", value, 0); - value = 0xdeadbeef; - status = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - &value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsageValue returned %#x\n", status); - ok(value == 0x7fffffff, "got value %x, expected %#x\n", value, 0x7fffffff); - - value = 0x3fffffff; - status = HidP_SetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); - value = 0xdeadbeef; - status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - (LONG *)&value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetScaledUsageValue returned %#x\n", status); - ok(value == 0x7fffffff, "got value %x, expected %#x\n", value, 0x7fffffff); - - value = 0; - status = HidP_SetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); - value = 0xdeadbeef; - status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - (LONG *)&value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetScaledUsageValue returned %#x\n", status); - ok(value == 0x80000000, "got value %x, expected %#x\n", value, 0x80000000); - - value = 0; - status = HidP_SetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_RX, - value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); - value = 0xdeadbeef; - status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_RX, - (LONG *)&value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetScaledUsageValue returned %#x\n", status); - ok(value == 0, "got value %x, expected %#x\n", value, 0); - - value = 0xfeedcafe; - status = HidP_SetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_RY, - value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); - value = 0xdeadbeef; - status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_RY, - (LONG *)&value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_BAD_LOG_PHY_VALUES, "HidP_GetScaledUsageValue returned %#x\n", status); - ok(value == 0, "got value %x, expected %#x\n", value, 0); - status = HidP_SetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_RY, - 0, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_BAD_LOG_PHY_VALUES, "HidP_GetScaledUsageValue returned %#x\n", status); - ok(value == 0, "got value %x, expected %#x\n", value, 0); - - value = HidP_MaxUsageListLength(HidP_Feature + 1, 0, preparsed_data); - ok(value == 0, "HidP_MaxUsageListLength(HidP_Feature + 1, 0) returned %d, expected %d\n", value, 0); - value = HidP_MaxUsageListLength(HidP_Input, 0, preparsed_data); - ok(value == 50, "HidP_MaxUsageListLength(HidP_Input, 0) returned %d, expected %d\n", value, 50); - value = HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_BUTTON, preparsed_data); - ok(value == 32, "HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_BUTTON) returned %d, expected %d\n", value, 32); - value = HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_LED, preparsed_data); - ok(value == 8, "HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_LED) returned %d, expected %d\n", value, 8); - value = HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_BUTTON, preparsed_data); - ok(value == 8, "HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_BUTTON) returned %d, expected %d\n", value, 8); - value = HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_LED, preparsed_data); - ok(value == 0, "HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_LED) returned %d, expected %d\n", value, 0); - - usages[0] = 0xff; - value = 1; - status = HidP_SetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usages, &value, - preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_SetUsages returned %#x\n", status); - usages[1] = 2; - usages[2] = 0xff; - value = 3; - status = HidP_SetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usages, &value, - preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_SetUsages returned %#x\n", status); - usages[0] = 4; - usages[1] = 6; - value = 2; - status = HidP_SetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usages, &value, - preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsages returned %#x\n", status); - usages[0] = 4; - usages[1] = 6; - value = 2; - status = HidP_SetUsages(HidP_Input, HID_USAGE_PAGE_LED, 0, usages, &value, preparsed_data, - report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsages returned %#x\n", status); - - value = ARRAY_SIZE(usages); - status = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_KEYBOARD, 0, usages, &value, preparsed_data, - report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsages returned %#x\n", status); - ok(value == 0, "got usage count %d, expected %d\n", value, 2); - - usages[0] = 0x9; - usages[1] = 0xb; - usages[2] = 0xa; - value = 3; - ok(report[6] == 0, "got report[6] %x expected 0\n", report[6]); - ok(report[7] == 0, "got report[7] %x expected 0\n", report[7]); - memcpy(buffer, report, caps.InputReportByteLength); - status = HidP_SetUsages(HidP_Input, HID_USAGE_PAGE_KEYBOARD, 0, usages, &value, preparsed_data, - report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_SetUsages returned %#x\n", status); - buffer[6] = 2; - buffer[7] = 4; - ok(!memcmp(buffer, report, caps.InputReportByteLength), "unexpected report data\n"); - - status = HidP_SetUsageValue(HidP_Input, HID_USAGE_PAGE_LED, 0, 6, 1, - preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_SetUsageValue returned %#x\n", status); - - value = 0xdeadbeef; - status = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_LED, 0, 6, &value, - preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_SetUsageValue returned %#x\n", status); - ok(value == 0xdeadbeef, "got value %x, expected %#x\n", value, 0xdeadbeef); - - value = 1; - status = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usages, &value, - preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetUsages returned %#x\n", status); - ok(value == 2, "got usage count %d, expected %d\n", value, 2); - value = ARRAY_SIZE(usages); - memset(usages, 0xcd, sizeof(usages)); - status = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usages, &value, - preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsages returned %#x\n", status); - ok(value == 2, "got usage count %d, expected %d\n", value, 2); - ok(usages[0] == 4, "got usages[0] %x, expected %x\n", usages[0], 4); - ok(usages[1] == 6, "got usages[1] %x, expected %x\n", usages[1], 6); - - value = ARRAY_SIZE(usages); - memset(usages, 0xcd, sizeof(usages)); - status = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_LED, 0, usages, &value, preparsed_data, - report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsages returned %#x\n", status); - ok(value == 2, "got usage count %d, expected %d\n", value, 2); - ok(usages[0] == 6, "got usages[0] %x, expected %x\n", usages[0], 6); - ok(usages[1] == 4, "got usages[1] %x, expected %x\n", usages[1], 4); - - value = ARRAY_SIZE(usage_and_pages); - memset(usage_and_pages, 0xcd, sizeof(usage_and_pages)); - status = HidP_GetUsagesEx(HidP_Input, 0, usage_and_pages, &value, preparsed_data, report, - caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsagesEx returned %#x\n", status); - ok(value == 6, "got usage count %d, expected %d\n", value, 4); - ok(usage_and_pages[0].UsagePage == HID_USAGE_PAGE_BUTTON, "got usage_and_pages[0] UsagePage %x, expected %x\n", - usage_and_pages[0].UsagePage, HID_USAGE_PAGE_BUTTON); - ok(usage_and_pages[1].UsagePage == HID_USAGE_PAGE_BUTTON, "got usage_and_pages[1] UsagePage %x, expected %x\n", - usage_and_pages[1].UsagePage, HID_USAGE_PAGE_BUTTON); - ok(usage_and_pages[2].UsagePage == HID_USAGE_PAGE_KEYBOARD, "got usage_and_pages[2] UsagePage %x, expected %x\n", - usage_and_pages[2].UsagePage, HID_USAGE_PAGE_KEYBOARD); - ok(usage_and_pages[3].UsagePage == HID_USAGE_PAGE_KEYBOARD, "got usage_and_pages[3] UsagePage %x, expected %x\n", - usage_and_pages[3].UsagePage, HID_USAGE_PAGE_KEYBOARD); - ok(usage_and_pages[4].UsagePage == HID_USAGE_PAGE_LED, "got usage_and_pages[4] UsagePage %x, expected %x\n", - usage_and_pages[4].UsagePage, HID_USAGE_PAGE_LED); - ok(usage_and_pages[5].UsagePage == HID_USAGE_PAGE_LED, "got usage_and_pages[5] UsagePage %x, expected %x\n", - usage_and_pages[5].UsagePage, HID_USAGE_PAGE_LED); - ok(usage_and_pages[0].Usage == 4, "got usage_and_pages[0] Usage %x, expected %x\n", - usage_and_pages[0].Usage, 4); - ok(usage_and_pages[1].Usage == 6, "got usage_and_pages[1] Usage %x, expected %x\n", - usage_and_pages[1].Usage, 6); - ok(usage_and_pages[2].Usage == 9, "got usage_and_pages[2] Usage %x, expected %x\n", - usage_and_pages[2].Usage, 9); - ok(usage_and_pages[3].Usage == 11, "got usage_and_pages[3] Usage %x, expected %x\n", - usage_and_pages[3].Usage, 11); - ok(usage_and_pages[4].Usage == 6, "got usage_and_pages[4] Usage %x, expected %x\n", - usage_and_pages[4].Usage, 6); - ok(usage_and_pages[5].Usage == 4, "got usage_and_pages[5] Usage %x, expected %x\n", - usage_and_pages[5].Usage, 4); - - value = HidP_MaxDataListLength(HidP_Feature + 1, preparsed_data); - ok(value == 0, "HidP_MaxDataListLength(HidP_Feature + 1) returned %d, expected %d\n", value, 0); - value = HidP_MaxDataListLength(HidP_Input, preparsed_data); - ok(value == 58, "HidP_MaxDataListLength(HidP_Input) returned %d, expected %d\n", value, 58); - value = HidP_MaxDataListLength(HidP_Output, preparsed_data); - ok(value == 0, "HidP_MaxDataListLength(HidP_Output) returned %d, expected %d\n", value, 0); - value = HidP_MaxDataListLength(HidP_Feature, preparsed_data); - ok(value == 14, "HidP_MaxDataListLength(HidP_Feature) returned %d, expected %d\n", value, 14); - - value = 1; - status = HidP_GetData(HidP_Input, data, &value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetData returned %#x\n", status); - ok(value == 11, "got data count %d, expected %d\n", value, 11); - memset(data, 0, sizeof(data)); - status = HidP_GetData(HidP_Input, data, &value, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetData returned %#x\n", status); - for (i = 0; i < ARRAY_SIZE(expect_data); ++i) - { - winetest_push_context("data[%d]", i); - check_member(data[i], expect_data[i], "%d", DataIndex); - check_member(data[i], expect_data[i], "%d", RawValue); - winetest_pop_context(); - } - - /* HID nary usage collections are set with 1-based usage index in their declaration order */ - - memset(report, 0, caps.InputReportByteLength); - status = HidP_InitializeReportForID(HidP_Input, report_id, preparsed_data, report, - caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_InitializeReportForID returned %#x\n", status); - value = 2; - usages[0] = 0x8e; - usages[1] = 0x8f; - status = HidP_SetUsages(HidP_Input, HID_USAGE_PAGE_KEYBOARD, 0, usages, &value, preparsed_data, - report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsages returned %#x\n", status); - ok(report[caps.InputReportByteLength - 2] == 3, "unexpected usage index %d, expected 3\n", - report[caps.InputReportByteLength - 2]); - ok(report[caps.InputReportByteLength - 1] == 4, "unexpected usage index %d, expected 4\n", - report[caps.InputReportByteLength - 1]); - status = HidP_UnsetUsages(HidP_Input, HID_USAGE_PAGE_KEYBOARD, 0, usages, &value, preparsed_data, - report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_UnsetUsages returned %#x\n", status); - ok(report[caps.InputReportByteLength - 2] == 0, "unexpected usage index %d, expected 0\n", - report[caps.InputReportByteLength - 2]); - ok(report[caps.InputReportByteLength - 1] == 0, "unexpected usage index %d, expected 0\n", - report[caps.InputReportByteLength - 1]); - status = HidP_UnsetUsages(HidP_Input, HID_USAGE_PAGE_KEYBOARD, 0, usages, &value, preparsed_data, - report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_BUTTON_NOT_PRESSED, "HidP_UnsetUsages returned %#x\n", status); - value = 1; - usages[0] = 0x8c; - status = HidP_SetUsages(HidP_Input, HID_USAGE_PAGE_KEYBOARD, 0, usages, &value, preparsed_data, - report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsages returned %#x\n", status); - ok(report[caps.InputReportByteLength - 2] == 1, "unexpected usage index %d, expected 1\n", - report[caps.InputReportByteLength - 2]); - - memset(report, 0xcd, sizeof(report)); - status = HidP_InitializeReportForID(HidP_Feature, 3, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_REPORT_DOES_NOT_EXIST, "HidP_InitializeReportForID returned %#x\n", status); - - memset(report, 0xcd, sizeof(report)); - status = HidP_InitializeReportForID(HidP_Feature, report_id, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_InitializeReportForID returned %#x\n", status); - - memset(buffer, 0xcd, sizeof(buffer)); - memset(buffer, 0, caps.FeatureReportByteLength); - buffer[0] = report_id; - ok(!memcmp(buffer, report, sizeof(buffer)), "unexpected report data\n"); - - for (i = 0; i < caps.NumberLinkCollectionNodes; ++i) - { - if (collections[i].LinkUsagePage != HID_USAGE_PAGE_HAPTICS) continue; - if (collections[i].LinkUsage == HID_USAGE_HAPTICS_WAVEFORM_LIST) break; - } - ok(i < caps.NumberLinkCollectionNodes, - "HID_USAGE_HAPTICS_WAVEFORM_LIST collection not found\n"); - waveform_list = i; - - status = HidP_SetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, - HID_USAGE_HAPTICS_WAVEFORM_RUMBLE, (PHIDP_PREPARSED_DATA)buffer, - report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_INVALID_PREPARSED_DATA, "HidP_SetUsageValue returned %#x\n", status); - status = HidP_SetUsageValue(HidP_Feature + 1, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, - HID_USAGE_HAPTICS_WAVEFORM_RUMBLE, preparsed_data, report, - caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_INVALID_REPORT_TYPE, "HidP_SetUsageValue returned %#x\n", status); - status = HidP_SetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, - HID_USAGE_HAPTICS_WAVEFORM_RUMBLE, preparsed_data, report, - caps.FeatureReportByteLength + 1); - ok(status == HIDP_STATUS_INVALID_REPORT_LENGTH, "HidP_SetUsageValue returned %#x\n", status); - report[0] = 1 - report_id; - status = HidP_SetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, - HID_USAGE_HAPTICS_WAVEFORM_RUMBLE, preparsed_data, report, - caps.FeatureReportByteLength); - ok(status == (report_id ? HIDP_STATUS_SUCCESS : HIDP_STATUS_INCOMPATIBLE_REPORT_ID), - "HidP_SetUsageValue returned %#x\n", status); - report[0] = 2; - status = HidP_SetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, - HID_USAGE_HAPTICS_WAVEFORM_RUMBLE, preparsed_data, report, - caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_INCOMPATIBLE_REPORT_ID, "HidP_SetUsageValue returned %#x\n", status); - report[0] = report_id; - status = HidP_SetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, 0xdead, 3, HID_USAGE_HAPTICS_WAVEFORM_RUMBLE, - preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_SetUsageValue returned %#x\n", status); - - status = HidP_SetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, - HID_USAGE_HAPTICS_WAVEFORM_RUMBLE, preparsed_data, report, - caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); - - memset(buffer, 0xcd, sizeof(buffer)); - memset(buffer, 0, caps.FeatureReportByteLength); - buffer[0] = report_id; - value = HID_USAGE_HAPTICS_WAVEFORM_RUMBLE; - memcpy(buffer + 1, &value, 2); - ok(!memcmp(buffer, report, sizeof(buffer)), "unexpected report data\n"); - - status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, &value, - (PHIDP_PREPARSED_DATA)buffer, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_INVALID_PREPARSED_DATA, "HidP_GetUsageValue returned %#x\n", status); - status = HidP_GetUsageValue(HidP_Feature + 1, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, - &value, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_INVALID_REPORT_TYPE, "HidP_GetUsageValue returned %#x\n", status); - status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, &value, - preparsed_data, report, caps.FeatureReportByteLength + 1); - ok(status == HIDP_STATUS_INVALID_REPORT_LENGTH, "HidP_GetUsageValue returned %#x\n", status); - report[0] = 1 - report_id; - status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, &value, - preparsed_data, report, caps.FeatureReportByteLength); - ok(status == (report_id ? HIDP_STATUS_SUCCESS : HIDP_STATUS_INCOMPATIBLE_REPORT_ID), - "HidP_GetUsageValue returned %#x\n", status); - report[0] = 2; - status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, &value, - preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_INCOMPATIBLE_REPORT_ID, "HidP_GetUsageValue returned %#x\n", status); - report[0] = report_id; - status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, 0xdead, 3, &value, - preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_USAGE_NOT_FOUND, "HidP_GetUsageValue returned %#x\n", status); - - value = 0xdeadbeef; - status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_ORDINAL, waveform_list, 3, &value, - preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsageValue returned %#x\n", status); - ok(value == HID_USAGE_HAPTICS_WAVEFORM_RUMBLE, "got value %x, expected %#x\n", value, - HID_USAGE_HAPTICS_WAVEFORM_RUMBLE); - - memset(buffer, 0xff, sizeof(buffer)); - status = HidP_SetUsageValueArray(HidP_Feature, HID_USAGE_PAGE_HAPTICS, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME, buffer, - 0, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_SetUsageValueArray returned %#x\n", status); - status = HidP_SetUsageValueArray(HidP_Feature, HID_USAGE_PAGE_HAPTICS, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME, buffer, - 64, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValueArray returned %#x\n", status); - ok(!memcmp(report + 9, buffer, 8), "unexpected report data\n"); - - memset(buffer, 0, sizeof(buffer)); - status = HidP_GetUsageValueArray(HidP_Feature, HID_USAGE_PAGE_HAPTICS, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME, buffer, - 0, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_BUFFER_TOO_SMALL, "HidP_GetUsageValueArray returned %#x\n", status); - status = HidP_GetUsageValueArray(HidP_Feature, HID_USAGE_PAGE_HAPTICS, 0, HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME, buffer, - 64, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsageValueArray returned %#x\n", status); - memset(buffer + 16, 0xff, 8); - ok(!memcmp(buffer, buffer + 16, 16), "unexpected report value\n"); - - - value = 0x7fffffff; - status = HidP_SetUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - value, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); - value = 0xdeadbeef; - status = HidP_GetScaledUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - (LONG *)&value, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_VALUE_OUT_OF_RANGE, "HidP_GetScaledUsageValue returned %#x\n", status); - ok(value == 0, "got value %x, expected %#x\n", value, 0); - value = 0xdeadbeef; - status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - &value, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsageValue returned %#x\n", status); - ok(value == 0x7fffffff, "got value %x, expected %#x\n", value, 0x7fffffff); - - value = 0x7fff; - status = HidP_SetUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - value, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); - value = 0xdeadbeef; - status = HidP_GetScaledUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - (LONG *)&value, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetScaledUsageValue returned %#x\n", status); - ok(value == 0x0003ffff, "got value %x, expected %#x\n", value, 0x0003ffff); - - value = 0; - status = HidP_SetUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - value, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetUsageValue returned %#x\n", status); - value = 0xdeadbeef; - status = HidP_GetScaledUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - (LONG *)&value, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetScaledUsageValue returned %#x\n", status); - ok(value == 0xfff90000, "got value %x, expected %#x\n", value, 0xfff90000); - status = HidP_SetScaledUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - 0x1000, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetScaledUsageValue returned %#x\n", status); - value = 0; - status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - &value, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsageValue returned %#x\n", status); - ok(value == 0xfffff518, "got value %x, expected %#x\n", value, 0xfffff518); - status = HidP_SetScaledUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - 0, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetScaledUsageValue returned %#x\n", status); - value = 0; - status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - &value, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsageValue returned %#x\n", status); - ok(value == 0xfffff45e, "got value %x, expected %#x\n", value, 0xfffff45e); - status = HidP_SetScaledUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - 0xdead, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetScaledUsageValue returned %#x\n", status); - value = 0; - status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - &value, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsageValue returned %#x\n", status); - ok(value == 0xfffffe7d, "got value %x, expected %#x\n", value, 0xfffffe7d); - status = HidP_SetScaledUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - 0xbeef, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_SetScaledUsageValue returned %#x\n", status); - value = 0; - status = HidP_GetUsageValue(HidP_Feature, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_Z, - &value, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_GetUsageValue returned %#x\n", status); - ok(value == 0xfffffd0b, "got value %x, expected %#x\n", value, 0xfffffd0b); - - - memset(report, 0xcd, sizeof(report)); - status = HidP_InitializeReportForID(HidP_Input, report_id, preparsed_data, report, caps.InputReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_InitializeReportForID returned %#x\n", status); - - SetLastError(0xdeadbeef); - ret = HidD_GetInputReport(file, report, 0); - ok(!ret, "HidD_GetInputReport succeeded\n"); - ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "HidD_GetInputReport returned error %u\n", GetLastError()); - - SetLastError(0xdeadbeef); - ret = HidD_GetInputReport(file, report, caps.InputReportByteLength - 1); - ok(!ret, "HidD_GetInputReport succeeded\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), - "HidD_GetInputReport returned error %u\n", GetLastError()); - - SetLastError(0xdeadbeef); - memset(buffer, 0x5a, sizeof(buffer)); - ret = HidD_GetInputReport(file, buffer, caps.InputReportByteLength); - if (report_id || broken(!ret) /* w7u */) - { - ok(!ret, "HidD_GetInputReport succeeded, last error %u\n", GetLastError()); - ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), - "HidD_GetInputReport returned error %u\n", GetLastError()); - } - else - { - ok(ret, "HidD_GetInputReport failed, last error %u\n", GetLastError()); - ok(buffer[0] == 0x5a, "got buffer[0] %x, expected 0x5a\n", (BYTE)buffer[0]); - } - - SetLastError(0xdeadbeef); - ret = HidD_GetInputReport(file, report, caps.InputReportByteLength); - ok(ret, "HidD_GetInputReport failed, last error %u\n", GetLastError()); - ok(report[0] == report_id, "got report[0] %02x, expected %02x\n", report[0], report_id); - - SetLastError(0xdeadbeef); - value = caps.InputReportByteLength * 2; - ret = sync_ioctl(file, IOCTL_HID_GET_INPUT_REPORT, NULL, 0, report, &value); - ok(ret, "IOCTL_HID_GET_INPUT_REPORT failed, last error %u\n", GetLastError()); - ok(value == 3, "got length %u, expected 3\n", value); - ok(report[0] == report_id, "got report[0] %02x, expected %02x\n", report[0], report_id); - - - memset(report, 0xcd, sizeof(report)); - status = HidP_InitializeReportForID(HidP_Feature, report_id, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_InitializeReportForID returned %#x\n", status); - - SetLastError(0xdeadbeef); - ret = HidD_GetFeature(file, report, 0); - ok(!ret, "HidD_GetFeature succeeded\n"); - ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "HidD_GetFeature returned error %u\n", GetLastError()); - - SetLastError(0xdeadbeef); - ret = HidD_GetFeature(file, report, caps.FeatureReportByteLength - 1); - ok(!ret, "HidD_GetFeature succeeded\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), - "HidD_GetFeature returned error %u\n", GetLastError()); - - SetLastError(0xdeadbeef); - memset(buffer, 0x5a, sizeof(buffer)); - ret = HidD_GetFeature(file, buffer, caps.FeatureReportByteLength); - if (report_id || broken(!ret)) - { - ok(!ret, "HidD_GetFeature succeeded, last error %u\n", GetLastError()); - ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), - "HidD_GetFeature returned error %u\n", GetLastError()); - } - else - { - ok(ret, "HidD_GetFeature failed, last error %u\n", GetLastError()); - ok(buffer[0] == 0x5a, "got buffer[0] %x, expected 0x5a\n", (BYTE)buffer[0]); - } - - SetLastError(0xdeadbeef); - ret = HidD_GetFeature(file, report, caps.FeatureReportByteLength); - ok(ret, "HidD_GetFeature failed, last error %u\n", GetLastError()); - ok(report[0] == report_id, "got report[0] %02x, expected %02x\n", report[0], report_id); - - value = caps.FeatureReportByteLength * 2; - SetLastError(0xdeadbeef); - ret = sync_ioctl(file, IOCTL_HID_GET_FEATURE, NULL, 0, report, &value); - ok(ret, "IOCTL_HID_GET_FEATURE failed, last error %u\n", GetLastError()); - ok(value == 3, "got length %u, expected 3\n", value); - ok(report[0] == report_id, "got report[0] %02x, expected %02x\n", report[0], report_id); - - - memset(report, 0xcd, sizeof(report)); - status = HidP_InitializeReportForID(HidP_Feature, report_id, preparsed_data, report, caps.FeatureReportByteLength); - ok(status == HIDP_STATUS_SUCCESS, "HidP_InitializeReportForID returned %#x\n", status); - - SetLastError(0xdeadbeef); - ret = HidD_SetFeature(file, report, 0); - ok(!ret, "HidD_SetFeature succeeded\n"); - ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "HidD_SetFeature returned error %u\n", GetLastError()); - - SetLastError(0xdeadbeef); - ret = HidD_SetFeature(file, report, caps.FeatureReportByteLength - 1); - ok(!ret, "HidD_SetFeature succeeded\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), - "HidD_SetFeature returned error %u\n", GetLastError()); - - SetLastError(0xdeadbeef); - memset(buffer, 0x5a, sizeof(buffer)); - ret = HidD_SetFeature(file, buffer, caps.FeatureReportByteLength); - if (report_id || broken(!ret)) - { - ok(!ret, "HidD_SetFeature succeeded, last error %u\n", GetLastError()); - ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), - "HidD_SetFeature returned error %u\n", GetLastError()); - } - else - { - ok(ret, "HidD_SetFeature failed, last error %u\n", GetLastError()); - } - - SetLastError(0xdeadbeef); - ret = HidD_SetFeature(file, report, caps.FeatureReportByteLength); - ok(ret, "HidD_SetFeature failed, last error %u\n", GetLastError()); - - value = caps.FeatureReportByteLength * 2; - SetLastError(0xdeadbeef); - ret = sync_ioctl(file, IOCTL_HID_SET_FEATURE, NULL, 0, report, &value); - ok(!ret, "IOCTL_HID_SET_FEATURE succeeded\n"); - ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "IOCTL_HID_SET_FEATURE returned error %u\n", GetLastError()); - value = 0; - SetLastError(0xdeadbeef); - ret = sync_ioctl(file, IOCTL_HID_SET_FEATURE, report, caps.FeatureReportByteLength * 2, NULL, &value); - ok(ret, "IOCTL_HID_SET_FEATURE failed, last error %u\n", GetLastError()); - ok(value == 3, "got length %u, expected 3\n", value); - - - memset(report, 0xcd, sizeof(report)); - status = HidP_InitializeReportForID(HidP_Output, report_id, preparsed_data, report, caps.OutputReportByteLength); - ok(status == HIDP_STATUS_REPORT_DOES_NOT_EXIST, "HidP_InitializeReportForID returned %#x\n", status); - memset(report, 0, caps.OutputReportByteLength); - report[0] = report_id; - - SetLastError(0xdeadbeef); - ret = HidD_SetOutputReport(file, report, 0); - ok(!ret, "HidD_SetOutputReport succeeded\n"); - ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "HidD_SetOutputReport returned error %u\n", GetLastError()); - - SetLastError(0xdeadbeef); - ret = HidD_SetOutputReport(file, report, caps.OutputReportByteLength - 1); - ok(!ret, "HidD_SetOutputReport succeeded\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), - "HidD_SetOutputReport returned error %u\n", GetLastError()); - - SetLastError(0xdeadbeef); - memset(buffer, 0x5a, sizeof(buffer)); - ret = HidD_SetOutputReport(file, buffer, caps.OutputReportByteLength); - if (report_id || broken(!ret)) - { - ok(!ret, "HidD_SetOutputReport succeeded, last error %u\n", GetLastError()); - ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), - "HidD_SetOutputReport returned error %u\n", GetLastError()); - } - else - { - ok(ret, "HidD_SetOutputReport failed, last error %u\n", GetLastError()); - } - - SetLastError(0xdeadbeef); - ret = HidD_SetOutputReport(file, report, caps.OutputReportByteLength); - ok(ret, "HidD_SetOutputReport failed, last error %u\n", GetLastError()); - - value = caps.OutputReportByteLength * 2; - SetLastError(0xdeadbeef); - ret = sync_ioctl(file, IOCTL_HID_SET_OUTPUT_REPORT, NULL, 0, report, &value); - ok(!ret, "IOCTL_HID_SET_OUTPUT_REPORT succeeded\n"); - ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "IOCTL_HID_SET_OUTPUT_REPORT returned error %u\n", GetLastError()); - value = 0; - SetLastError(0xdeadbeef); - ret = sync_ioctl(file, IOCTL_HID_SET_OUTPUT_REPORT, report, caps.OutputReportByteLength * 2, NULL, &value); - ok(ret, "IOCTL_HID_SET_OUTPUT_REPORT failed, last error %u\n", GetLastError()); - ok(value == 3, "got length %u, expected 3\n", value); - - - SetLastError(0xdeadbeef); - ret = WriteFile(file, report, 0, &value, NULL); - ok(!ret, "WriteFile succeeded\n"); - ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "WriteFile returned error %u\n", GetLastError()); - ok(value == 0, "WriteFile returned %x\n", value); - SetLastError(0xdeadbeef); - ret = WriteFile(file, report, caps.OutputReportByteLength - 1, &value, NULL); - ok(!ret, "WriteFile succeeded\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_INVALID_USER_BUFFER, - "WriteFile returned error %u\n", GetLastError()); - ok(value == 0, "WriteFile returned %x\n", value); - - memset(report, 0xcd, sizeof(report)); - report[0] = 0xa5; - SetLastError(0xdeadbeef); - ret = WriteFile(file, report, caps.OutputReportByteLength * 2, &value, NULL); - if (report_id || broken(!ret) /* w7u */) - { - ok(!ret, "WriteFile succeeded\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "WriteFile returned error %u\n", GetLastError()); - ok(value == 0, "WriteFile wrote %u\n", value); - SetLastError(0xdeadbeef); - report[0] = report_id; - ret = WriteFile(file, report, caps.OutputReportByteLength, &value, NULL); - } - - if (report_id) - { - ok(ret, "WriteFile failed, last error %u\n", GetLastError()); - ok(value == 2, "WriteFile wrote %u\n", value); - } - else - { - ok(ret, "WriteFile failed, last error %u\n", GetLastError()); - ok(value == 3, "WriteFile wrote %u\n", value); - } - - - memset(report, 0xcd, sizeof(report)); - SetLastError(0xdeadbeef); - ret = ReadFile(file, report, 0, &value, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_USER_BUFFER, "ReadFile failed, last error %u\n", GetLastError()); - ok(value == 0, "ReadFile returned %x\n", value); - SetLastError(0xdeadbeef); - ret = ReadFile(file, report, caps.InputReportByteLength - 1, &value, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_USER_BUFFER, "ReadFile failed, last error %u\n", GetLastError()); - ok(value == 0, "ReadFile returned %x\n", value); - - if (polled) - { - memset(report, 0xcd, sizeof(report)); - SetLastError(0xdeadbeef); - ret = ReadFile(file, report, caps.InputReportByteLength, &value, NULL); - ok(ret, "ReadFile failed, last error %u\n", GetLastError()); - ok(value == (report_id ? 3 : 4), "ReadFile returned %x\n", value); - ok(report[0] == report_id, "unexpected report data\n"); - - overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL); - overlapped2.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL); - - /* drain available input reports */ - SetLastError(0xdeadbeef); - while (ReadFile(async_file, report, caps.InputReportByteLength, NULL, &overlapped)) - ResetEvent(overlapped.hEvent); - ok(GetLastError() == ERROR_IO_PENDING, "ReadFile returned error %u\n", GetLastError()); - ret = GetOverlappedResult(async_file, &overlapped, &value, TRUE); - ok(ret, "GetOverlappedResult failed, last error %u\n", GetLastError()); - ok(value == (report_id ? 3 : 4), "GetOverlappedResult returned length %u, expected 3\n", value); - ResetEvent(overlapped.hEvent); - - memcpy(buffer, report, caps.InputReportByteLength); - memcpy(buffer + caps.InputReportByteLength, report, caps.InputReportByteLength); - - SetLastError(0xdeadbeef); - ret = ReadFile(async_file, report, caps.InputReportByteLength, NULL, &overlapped); - ok(!ret, "ReadFile succeeded\n"); - ok(GetLastError() == ERROR_IO_PENDING, "ReadFile returned error %u\n", GetLastError()); - - SetLastError(0xdeadbeef); - ret = ReadFile(async_file, buffer, caps.InputReportByteLength, NULL, &overlapped2); - ok(!ret, "ReadFile succeeded\n"); - ok(GetLastError() == ERROR_IO_PENDING, "ReadFile returned error %u\n", GetLastError()); - - /* wait for second report to be ready */ - ret = GetOverlappedResult(async_file, &overlapped2, &value, TRUE); - ok(ret, "GetOverlappedResult failed, last error %u\n", GetLastError()); - ok(value == (report_id ? 3 : 4), "GetOverlappedResult returned length %u, expected 3\n", value); - /* first report should be ready and the same */ - ret = GetOverlappedResult(async_file, &overlapped, &value, FALSE); - ok(ret, "GetOverlappedResult failed, last error %u\n", GetLastError()); - ok(value == (report_id ? 3 : 4), "GetOverlappedResult returned length %u, expected 3\n", value); - ok(memcmp(report, buffer + caps.InputReportByteLength, caps.InputReportByteLength), - "expected different report\n"); - ok(!memcmp(report, buffer, caps.InputReportByteLength), "expected identical reports\n"); - - CloseHandle(overlapped.hEvent); - CloseHandle(overlapped2.hEvent); - } - - - HidD_FreePreparsedData(preparsed_data); -} - -struct test_hid_params -{ - BOOL report_id; - BOOL polled; -}; - -static void test_hid_device(void *args) -{ - struct test_hid_params *params = args; - BOOL report_id = params->report_id, polled = params->polled; - 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)}; - ULONG count, poll_freq, out_len; - HANDLE file, async_file; - BOOL ret, found = FALSE; - OBJECT_ATTRIBUTES attr; - UNICODE_STRING string; - IO_STATUS_BLOCK io; - NTSTATUS status; - unsigned int i; - HDEVINFO set; - - winetest_push_context("id %d%s", report_id, polled ? " poll" : ""); - - set = SetupDiGetClassDevsA(&GUID_DEVINTERFACE_HID, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); - ok(set != INVALID_HANDLE_VALUE, "failed to get device list, error %#x\n", GetLastError()); - - for (i = 0; SetupDiEnumDeviceInfo(set, i, &device); ++i) - { - ret = SetupDiEnumDeviceInterfaces(set, &device, &GUID_DEVINTERFACE_HID, 0, &iface); - ok(ret, "failed to get interface, error %#x\n", GetLastError()); - ok(IsEqualGUID(&iface.InterfaceClassGuid, &GUID_DEVINTERFACE_HID), - "wrong class %s\n", debugstr_guid(&iface.InterfaceClassGuid)); - ok(iface.Flags == SPINT_ACTIVE, "got flags %#x\n", iface.Flags); - - iface_detail->cbSize = sizeof(*iface_detail); - ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, iface_detail, sizeof(buffer), NULL, NULL); - ok(ret, "failed to get interface path, error %#x\n", GetLastError()); - - if (strstr(iface_detail->DevicePath, "\\?\hid#winetest#1")) - { - found = TRUE; - break; - } - } - - SetupDiDestroyDeviceInfoList(set); - - todo_wine ok(found, "didn't find device\n"); - - file = CreateFileA(iface_detail->DevicePath, FILE_READ_ACCESS | FILE_WRITE_ACCESS, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); - - count = 0xdeadbeef; - SetLastError(0xdeadbeef); - ret = HidD_GetNumInputBuffers(file, &count); - ok(ret, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError()); - ok(count == 32, "HidD_GetNumInputBuffers returned %u\n", count); - - SetLastError(0xdeadbeef); - ret = HidD_SetNumInputBuffers(file, 1); - ok(!ret, "HidD_SetNumInputBuffers succeeded\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "HidD_SetNumInputBuffers returned error %u\n", GetLastError()); - SetLastError(0xdeadbeef); - ret = HidD_SetNumInputBuffers(file, 513); - ok(!ret, "HidD_SetNumInputBuffers succeeded\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "HidD_SetNumInputBuffers returned error %u\n", GetLastError()); - - SetLastError(0xdeadbeef); - ret = HidD_SetNumInputBuffers(file, 16); - ok(ret, "HidD_SetNumInputBuffers failed last error %u\n", GetLastError()); - - count = 0xdeadbeef; - SetLastError(0xdeadbeef); - ret = HidD_GetNumInputBuffers(file, &count); - ok(ret, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError()); - ok(count == 16, "HidD_GetNumInputBuffers returned %u\n", count); - - async_file = CreateFileA(iface_detail->DevicePath, FILE_READ_ACCESS | FILE_WRITE_ACCESS, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, - FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL); - ok(async_file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); - - count = 0xdeadbeef; - SetLastError(0xdeadbeef); - ret = HidD_GetNumInputBuffers(async_file, &count); - ok(ret, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError()); - ok(count == 32, "HidD_GetNumInputBuffers returned %u\n", count); - - SetLastError(0xdeadbeef); - ret = HidD_SetNumInputBuffers(async_file, 2); - ok(ret, "HidD_SetNumInputBuffers failed last error %u\n", GetLastError()); - - count = 0xdeadbeef; - SetLastError(0xdeadbeef); - ret = HidD_GetNumInputBuffers(async_file, &count); - ok(ret, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError()); - ok(count == 2, "HidD_GetNumInputBuffers returned %u\n", count); - count = 0xdeadbeef; - SetLastError(0xdeadbeef); - ret = HidD_GetNumInputBuffers(file, &count); - ok(ret, "HidD_GetNumInputBuffers failed last error %u\n", GetLastError()); - ok(count == 16, "HidD_GetNumInputBuffers returned %u\n", count); - - if (polled) - { - out_len = sizeof(ULONG); - SetLastError(0xdeadbeef); - ret = sync_ioctl(file, IOCTL_HID_GET_POLL_FREQUENCY_MSEC, NULL, 0, &poll_freq, &out_len); - ok(ret, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError()); - ok(out_len == sizeof(ULONG), "got out_len %u, expected sizeof(ULONG)\n", out_len); - todo_wine ok(poll_freq == 5, "got poll_freq %u, expected 5\n", poll_freq); - - out_len = 0; - poll_freq = 500; - SetLastError(0xdeadbeef); - ret = sync_ioctl(file, IOCTL_HID_SET_POLL_FREQUENCY_MSEC, &poll_freq, sizeof(ULONG), NULL, &out_len); - ok(ret, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError()); - ok(out_len == 0, "got out_len %u, expected 0\n", out_len); - - out_len = 0; - poll_freq = 10001; - SetLastError(0xdeadbeef); - ret = sync_ioctl(file, IOCTL_HID_SET_POLL_FREQUENCY_MSEC, &poll_freq, sizeof(ULONG), NULL, &out_len); - ok(ret, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError()); - ok(out_len == 0, "got out_len %u, expected 0\n", out_len); - - out_len = 0; - poll_freq = 0; - SetLastError(0xdeadbeef); - ret = sync_ioctl(file, IOCTL_HID_SET_POLL_FREQUENCY_MSEC, &poll_freq, sizeof(ULONG), NULL, &out_len); - ok(ret, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError()); - ok(out_len == 0, "got out_len %u, expected 0\n", out_len); - - out_len = sizeof(ULONG); - SetLastError(0xdeadbeef); - ret = sync_ioctl(file, IOCTL_HID_GET_POLL_FREQUENCY_MSEC, NULL, 0, &poll_freq, &out_len); - ok(ret, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError()); - ok(out_len == sizeof(ULONG), "got out_len %u, expected sizeof(ULONG)\n", out_len); - ok(poll_freq == 10000, "got poll_freq %u, expected 10000\n", poll_freq); - - out_len = 0; - poll_freq = 500; - SetLastError(0xdeadbeef); - ret = sync_ioctl(file, IOCTL_HID_SET_POLL_FREQUENCY_MSEC, &poll_freq, sizeof(ULONG), NULL, &out_len); - ok(ret, "IOCTL_HID_SET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError()); - ok(out_len == 0, "got out_len %u, expected 0\n", out_len); - - out_len = sizeof(ULONG); - SetLastError(0xdeadbeef); - ret = sync_ioctl(async_file, IOCTL_HID_GET_POLL_FREQUENCY_MSEC, NULL, 0, &poll_freq, &out_len); - ok(ret, "IOCTL_HID_GET_POLL_FREQUENCY_MSEC failed last error %u\n", GetLastError()); - ok(out_len == sizeof(ULONG), "got out_len %u, expected sizeof(ULONG)\n", out_len); - ok(poll_freq == 500, "got poll_freq %u, expected 500\n", poll_freq); - } - - test_hidp(file, async_file, report_id, polled); - - CloseHandle(async_file); - CloseHandle(file); - - RtlInitUnicodeString(&string, L"\??\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}"); - InitializeObjectAttributes(&attr, &string, OBJ_CASE_INSENSITIVE, NULL, NULL); - status = NtOpenFile(&file, SYNCHRONIZE, &attr, &io, 0, FILE_SYNCHRONOUS_IO_NONALERT); - todo_wine ok(status == STATUS_UNSUCCESSFUL, "got %#x\n", status); - - winetest_pop_context(); -} - -static void test_hid_driver(struct testsign_context *ctx, DWORD report_id, DWORD polled) -{ - struct test_hid_params params = {.report_id = report_id, .polled = polled}; - SP_DEVINFO_DATA device = {sizeof(device)}; - char cwd[MAX_PATH], tempdir[MAX_PATH]; - LSTATUS status; - HKEY hkey; - - GetCurrentDirectoryA(ARRAY_SIZE(cwd), cwd); - GetTempPathA(ARRAY_SIZE(tempdir), tempdir); - SetCurrentDirectoryA(tempdir); - - status = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"System\CurrentControlSet\Services\winetest", 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL); - ok(!status, "RegCreateKeyExW returned %#x\n", status); - - status = RegSetValueExW(hkey, L"ReportID", 0, REG_DWORD, (void *)&report_id, sizeof(report_id)); - ok(!status, "RegSetValueExW returned %#x\n", status); - - status = RegSetValueExW(hkey, L"PolledMode", 0, REG_DWORD, (void *)&polled, sizeof(polled)); - ok(!status, "RegSetValueExW returned %#x\n", status); - - run_driver_test(ctx, L"driver_hid.dll", test_hid_device, ¶ms); -} - START_TEST(ntoskrnl) { WCHAR filename[MAX_PATH], filename2[MAX_PATH]; @@ -2909,12 +1407,6 @@ START_TEST(ntoskrnl) subtest("driver_pnp"); run_driver_test(&ctx, L"driver_pnp.dll", test_pnp_devices, NULL);
- subtest("driver_hid"); - test_hid_driver(&ctx, 0, FALSE); - test_hid_driver(&ctx, 1, FALSE); - test_hid_driver(&ctx, 0, TRUE); - test_hid_driver(&ctx, 1, TRUE); - out: driver_test_cleanup(&ctx); }
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=96738
Your paranoid android.
=== w7u_adm (32 bit report) ===
Report validation errors: hid:hidp is missing some skip messages
=== w8adm (32 bit report) ===
Report validation errors: hid:hidp is missing some skip messages
=== w864 (64 bit report) ===
hid: hidp.c:1395: Test failed: id 0: didn't find device hidp.c:1399: Test failed: id 0: got error 5 hidp.c:1404: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1405: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1410: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1414: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1418: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1423: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1424: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1429: Test failed: id 0: got error 5 hidp.c:1434: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1435: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1439: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1444: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1445: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1449: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1450: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:402: Test failed: id 0: HidD_GetPreparsedData failed with error 6 hidp.c:408: Test failed: id 0: HidP_GetCaps returned 0xc0110001 hidp.c:409: Test failed: id 0: got Usage 058a, expected 0004 hidp.c:409: Test failed: id 0: got UsagePage 0148, expected 0001 hidp.c:409: Test failed: id 0: got InputReportByteLength 56695, expected 26 hidp.c:409: Test failed: id 0: got OutputReportByteLength 0, expected 3 hidp.c:409: Test failed: id 0: got FeatureReportByteLength 1, expected 22 hidp.c:409: Test failed: id 0: got NumberLinkCollectionNodes 0, expected 10 hidp.c:409: Test failed: id 0: got NumberInputButtonCaps 0, expected 17 hidp.c:409: Test failed: id 0: got NumberInputValueCaps 81, expected 7 hidp.c:409: Test failed: id 0: got NumberInputDataIndices 0, expected 47 hidp.c:409: Test failed: id 0: got NumberOutputDataIndices 17912, expected 0 hidp.c:409: Test failed: id 0: got NumberFeatureButtonCaps 62117, expected 1 hidp.c:409: Test failed: id 0: got NumberFeatureValueCaps 32761, expected 6 hidp.c:409: Test failed: id 0: got NumberFeatureDataIndices 0, expected 8 hidp.c:413: Test failed: id 0: HidP_GetLinkCollectionNodes returned 0xc0110001 hidp.c:420: Test failed: id 0: HidP_GetLinkCollectionNodes returned 0xc0110001 hidp.c:421: Test failed: id 0: got 16 collection nodes, expected 0 hidp.c:427: Test failed: id 0: collections[0]: got LinkUsage 005f, expected 0004 hidp.c:427: Test failed: id 0: collections[0]: got LinkUsagePage 0031, expected 0001 hidp.c:427: Test failed: id 0: collections[0]: got Parent 46, expected 0 hidp.c:427: Test failed: id 0: collections[0]: got NumberOfChildren 55, expected 7 hidp.c:427: Test failed: id 0: collections[0]: got NextSibling 46, expected 0 hidp.c:427: Test failed: id 0: collections[0]: got FirstChild 95, expected 9 hidp.c:427: Test failed: id 0: collections[0]: got CollectionType 95, expected 1 hidp.c:427: Test failed: id 0: collections[1]: got LinkUsage 0045, expected 0004 hidp.c:427: Test failed: id 0: collections[1]: got LinkUsagePage 005c, expected 0001 hidp.c:427: Test failed: id 0: collections[1]: got Parent 81, expected 0 hidp.c:427: Test failed: id 0: collections[1]: got NumberOfChildren 69, expected 0 hidp.c:427: Test failed: id 0: collections[1]: got NextSibling 77, expected 0 hidp.c:427: Test failed: id 0: collections[1]: got FirstChild 85, expected 0 hidp.c:427: Test failed: id 0: collections[1]: got CollectionType 95, expected 2 hidp.c:433: Test failed: id 0: HidP_GetButtonCaps returned 0xc0110001 hidp.c:435: Test failed: id 0: HidP_GetButtonCaps returned 0xc0110001 hidp.c:438: Test failed: id 0: HidP_GetButtonCaps returned 0xc0110001 hidp.c:446: Test failed: id 0: HidP_GetButtonCaps returned 0xc0110001 hidp.c:447: Test failed: id 0: HidP_GetButtonCaps returned count 32, expected 0 hidp.c:453: Test failed: id 0: button_caps[0]: got UsagePage 0000, expected 0009 hidp.c:453: Test failed: id 0: button_caps[0]: got BitField 0, expected 2 hidp.c:453: Test failed: id 0: button_caps[0]: got LinkCollection 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[0]: got LinkUsage 0000, expected 0004 hidp.c:453: Test failed: id 0: button_caps[0]: got LinkUsagePage 0000, expected 0001 hidp.c:453: Test failed: id 0: button_caps[0]: got IsRange 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[0]: got IsAbsolute 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[1]: got UsagePage 0000, expected 0009 hidp.c:453: Test failed: id 0: button_caps[1]: got BitField 0, expected 3 hidp.c:453: Test failed: id 0: button_caps[1]: got LinkCollection 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[1]: got LinkUsage 0000, expected 0004 hidp.c:453: Test failed: id 0: button_caps[1]: got LinkUsagePage 0000, expected 0001 hidp.c:453: Test failed: id 0: button_caps[1]: got IsRange 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[1]: got IsAbsolute 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[2]: got UsagePage 0000, expected 0007 hidp.c:453: Test failed: id 0: button_caps[2]: got BitField 0, expected 508 hidp.c:453: Test failed: id 0: button_caps[2]: got LinkCollection 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[2]: got LinkUsage 0000, expected 0004 hidp.c:453: Test failed: id 0: button_caps[2]: got LinkUsagePage 0000, expected 0001 hidp.c:453: Test failed: id 0: button_caps[2]: got IsRange 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[3]: got UsagePage 0000, expected 0009 hidp.c:453: Test failed: id 0: button_caps[3]: got BitField 0, expected 2 hidp.c:453: Test failed: id 0: button_caps[3]: got LinkCollection 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[3]: got LinkUsage 0000, expected 0004 hidp.c:453: Test failed: id 0: button_caps[3]: got LinkUsagePage 0000, expected 0001 hidp.c:453: Test failed: id 0: button_caps[3]: got IsAbsolute 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[3]: got NotRange.Usage 0000, expected 0020 hidp.c:453: Test failed: id 0: button_caps[3]: got NotRange.DataIndex 0, expected 26 hidp.c:459: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:461: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:464: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:472: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:473: Test failed: id 0: HidP_GetSpecificButtonCaps returned count 31, expected 0 hidp.c:479: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:480: Test failed: id 0: HidP_GetSpecificButtonCaps returned count 31, expected 1 hidp.c:485: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:486: Test failed: id 0: HidP_GetSpecificButtonCaps returned count 48879, expected 0 hidp.c:489: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:490: Test failed: id 0: HidP_GetSpecificButtonCaps returned count 48879, expected 0 hidp.c:493: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:494: Test failed: id 0: HidP_GetSpecificButtonCaps returned count 48879, expected 0 hidp.c:498: Test failed: id 0: HidP_GetValueCaps returned 0xc0110001 hidp.c:500: Test failed: id 0: HidP_GetValueCaps returned 0xc0110001 hidp.c:503: Test failed: id 0: HidP_GetValueCaps returned 0xc0110001 hidp.c:504: Test failed: id 0: HidP_GetValueCaps returned count 0, expected 81 hidp.c:510: Test failed: id 0: HidP_GetValueCaps returned 0xc0110001 hidp.c:511: Test failed: id 0: HidP_GetValueCaps returned count 16, expected 81 hidp.c:517: Test failed: id 0: value_caps[0]: got UsagePage 0000, expected 0001 hidp.c:517: Test failed: id 0: value_caps[0]: got BitField 0, expected 2 hidp.c:517: Test failed: id 0: value_caps[0]: got LinkCollection 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[0]: got LinkUsage 58936, expected 4 hidp.c:517: Test failed: id 0: value_caps[0]: got LinkUsagePage 35, expected 1 hidp.c:517: Test failed: id 0: value_caps[0]: got IsAbsolute 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[0]: got HasNull 72, expected 0 hidp.c:517: Test failed: id 0: value_caps[0]: got BitSize 0, expected 8 hidp.c:517: Test failed: id 0: value_caps[0]: got ReportCount 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[0]: got LogicalMin -67739233, expected -128 hidp.c:517: Test failed: id 0: value_caps[0]: got LogicalMax 32761, expected 127 hidp.c:517: Test failed: id 0: value_caps[0]: got PhysicalMin 4829, expected 0 hidp.c:517: Test failed: id 0: value_caps[0]: got NotRange.Usage 0002, expected 0031 hidp.c:517: Test failed: id 0: value_caps[0]: got NotRange.DesignatorIndex 62, expected 0 hidp.c:517: Test failed: id 0: value_caps[1]: got UsagePage 2000, expected 0001 hidp.c:517: Test failed: id 0: value_caps[1]: got BitField 0, expected 2 hidp.c:517: Test failed: id 0: value_caps[1]: got LinkCollection 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[1]: got LinkUsage 57985, expected 4 hidp.c:517: Test failed: id 0: value_caps[1]: got LinkUsagePage 35, expected 1 hidp.c:517: Test failed: id 0: value_caps[1]: got IsAbsolute 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[1]: got HasNull 160, expected 0 hidp.c:517: Test failed: id 0: value_caps[1]: got BitSize 35, expected 8 hidp.c:517: Test failed: id 0: value_caps[1]: got ReportCount 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[1]: got UnitsExp -107864110, expected 0 hidp.c:517: Test failed: id 0: value_caps[1]: got Units 32761, expected 0 hidp.c:517: Test failed: id 0: value_caps[1]: got LogicalMin 47, expected -128 hidp.c:517: Test failed: id 0: value_caps[1]: got LogicalMax 0, expected 127 hidp.c:517: Test failed: id 0: value_caps[1]: got PhysicalMin -107859278, expected 0 hidp.c:517: Test failed: id 0: value_caps[1]: got PhysicalMax 32761, expected 0 hidp.c:517: Test failed: id 0: value_caps[1]: got NotRange.Usage 0300, expected 0030 hidp.c:517: Test failed: id 0: value_caps[1]: got NotRange.DataIndex 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[1]: got NotRange.StringIndex 1, expected 0 hidp.c:517: Test failed: id 0: value_caps[2]: got UsagePage 0000, expected 0009 hidp.c:517: Test failed: id 0: value_caps[2]: got BitField 0, expected 2 hidp.c:517: Test failed: id 0: value_caps[2]: got LinkCollection 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[2]: got LinkUsage 36192, expected 4 hidp.c:517: Test failed: id 0: value_caps[2]: got LinkUsagePage 48, expected 1 hidp.c:517: Test failed: id 0: value_caps[2]: got IsRange 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[2]: got IsAbsolute 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[2]: got HasNull 136, expected 0 hidp.c:517: Test failed: id 0: value_caps[2]: got ReportCount 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[2]: got LogicalMax 17, expected 1 hidp.c:517: Test failed: id 0: value_caps[2]: got PhysicalMin 2352672, expected 0 hidp.c:517: Test failed: id 0: value_caps[2]: got NotRange.DesignatorIndex 58625, expected 0 hidp.c:517: Test failed: id 0: value_caps[3]: got UsagePage 0048, expected 0001 hidp.c:517: Test failed: id 0: value_caps[3]: got BitField 0, expected 2 hidp.c:517: Test failed: id 0: value_caps[3]: got LinkCollection 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[3]: got LinkUsage 17, expected 4 hidp.c:517: Test failed: id 0: value_caps[3]: got LinkUsagePage 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[3]: got IsAbsolute 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[3]: got HasNull 80, expected 0 hidp.c:517: Test failed: id 0: value_caps[3]: got BitSize 48, expected 4 hidp.c:517: Test failed: id 0: value_caps[3]: got ReportCount 0, expected 2 hidp.c:517: Test failed: id 0: value_caps[3]: got UnitsExp 12, expected 0 hidp.c:517: Test failed: id 0: value_caps[3]: got LogicalMin 256, expected 1 hidp.c:517: Test failed: id 0: value_caps[3]: got LogicalMax 0, expected 8 hidp.c:517: Test failed: id 0: value_caps[3]: got PhysicalMin 1023, expected 0 hidp.c:517: Test failed: id 0: value_caps[3]: got NotRange.Usage 000b, expected 0039 hidp.c:517: Test failed: id 0: value_caps[3]: got NotRange.DataIndex 0, expected 29 hidp.c:517: Test failed: id 0: value_caps[3]: got NotRange.StringIndex 2, expected 0 hidp.c:517: Test failed: id 0: value_caps[3]: got NotRange.DesignatorIndex 17, expected 0 hidp.c:523: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:525: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:528: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:529: Test failed: id 0: HidP_GetSpecificValueCaps returned count 0, expected 81 hidp.c:536: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:537: Test failed: id 0: HidP_GetSpecificValueCaps returned count 12, expected 81 hidp.c:539: Test failed: id 0: got BitField 2, expected 0 hidp.c:539: Test failed: id 0: got LinkUsage 0, expected 58936 hidp.c:539: Test failed: id 0: got LinkUsagePage 0, expected 35 hidp.c:539: Test failed: id 0: got IsRange 7, expected 0 hidp.c:539: Test failed: id 0: got HasNull 220, expected 72 hidp.c:539: Test failed: id 0: got BitSize 54784, expected 0 hidp.c:539: Test failed: id 0: got UnitsExp 285212689, expected 0 hidp.c:539: Test failed: id 0: got LogicalMin -107864110, expected -67739233 hidp.c:539: Test failed: id 0: got PhysicalMin 33554434, expected 4829 hidp.c:539: Test failed: id 0: got PhysicalMax 32761, expected 0 hidp.c:539: Test failed: id 0: got NotRange.DesignatorIndex 63664, expected 62 hidp.c:540: Test failed: id 0: got UsagePage 1730, expected 2000 hidp.c:540: Test failed: id 0: got ReportID 110, expected 0 hidp.c:540: Test failed: id 0: got LinkUsage 2096, expected 57985 hidp.c:540: Test failed: id 0: got LinkUsagePage 110, expected 35 hidp.c:540: Test failed: id 0: got HasNull 1, expected 160 hidp.c:540: Test failed: id 0: got BitSize 50952, expected 35 hidp.c:540: Test failed: id 0: got ReportCount 32761, expected 0 hidp.c:540: Test failed: id 0: got UnitsExp 7214896, expected -107864110 hidp.c:540: Test failed: id 0: got Units 0, expected 32761 hidp.c:540: Test failed: id 0: got LogicalMin 134336, expected 47 hidp.c:540: Test failed: id 0: got PhysicalMin -704640292, expected -107859278 hidp.c:540: Test failed: id 0: got PhysicalMax 0, expected 32761 hidp.c:540: Test failed: id 0: got NotRange.Usage 0030, expected 0300 hidp.c:540: Test failed: id 0: got NotRange.DataIndex 32761, expected 0 hidp.c:540: Test failed: id 0: got NotRange.StringIndex 0, expected 1 hidp.c:540: Test failed: id 0: got NotRange.DesignatorIndex 12492, expected 0 hidp.c:541: Test failed: id 0: got UsagePage 0001, expected 0000 hidp.c:541: Test failed: id 0: got LinkUsage 0, expected 36192 hidp.c:541: Test failed: id 0: got LinkUsagePage 512, expected 48 hidp.c:541: Test failed: id 0: got HasNull 1, expected 136 hidp.c:541: Test failed: id 0: got LogicalMin 16318467, expected 0 hidp.c:541: Test failed: id 0: got LogicalMax 0, expected 17 hidp.c:541: Test failed: id 0: got PhysicalMin 128, expected 2352672 hidp.c:541: Test failed: id 0: got NotRange.Usage 0079, expected 8d50 hidp.c:541: Test failed: id 0: got NotRange.DataIndex 0, expected 145 hidp.c:541: Test failed: id 0: got NotRange.DesignatorIndex 336, expected 58625 hidp.c:542: Test failed: id 0: got UsagePage 0001, expected 0048 hidp.c:542: Test failed: id 0: got BitField 32761, expected 0 hidp.c:542: Test failed: id 0: got LinkUsage 0, expected 17 hidp.c:542: Test failed: id 0: got LinkUsagePage 2, expected 0 hidp.c:542: Test failed: id 0: got HasNull 168, expected 80 hidp.c:542: Test failed: id 0: got BitSize 43, expected 48 hidp.c:542: Test failed: id 0: got UnitsExp 0, expected 12 hidp.c:542: Test failed: id 0: got LogicalMin 128, expected 256 hidp.c:542: Test failed: id 0: got PhysicalMin 0, expected 1023 hidp.c:542: Test failed: id 0: got NotRange.Usage 0080, expected 000b hidp.c:542: Test failed: id 0: got NotRange.StringIndex 32761, expected 2 hidp.c:542: Test failed: id 0: got NotRange.DesignatorIndex 65514, expected 17 hidp.c:547: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:549: Test failed: id 0: got UsagePage 0000, expected 0048 hidp.c:549: Test failed: id 0: got BitField 2, expected 0 hidp.c:549: Test failed: id 0: got LinkUsage 0, expected 17 hidp.c:549: Test failed: id 0: got IsRange 7, expected 0 hidp.c:549: Test failed: id 0: got HasNull 220, expected 80 hidp.c:549: Test failed: id 0: got BitSize 54784, expected 48 hidp.c:549: Test failed: id 0: got UnitsExp 285212689, expected 12 hidp.c:549: Test failed: id 0: got LogicalMin -107864110, expected 256 hidp.c:549: Test failed: id 0: got LogicalMax 32761, expected 0 hidp.c:549: Test failed: id 0: got PhysicalMin 33554434, expected 1023 hidp.c:549: Test failed: id 0: got PhysicalMax 32761, expected 0 hidp.c:549: Test failed: id 0: got NotRange.DesignatorIndex 63664, expected 17 hidp.c:553: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:554: Test failed: id 0: HidP_GetSpecificValueCaps returned count 57005, expected 0 hidp.c:557: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:558: Test failed: id 0: HidP_GetSpecificValueCaps returned count 57005, expected 0 hidp.c:561: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:562: Test failed: id 0: HidP_GetSpecificValueCaps returned count 57005, expected 0 hidp.c:567: Test failed: id 0: HidP_InitializeReportForID returned 0xc0110001 hidp.c:569: Test failed: id 0: HidP_InitializeReportForID returned 0xc0110001 hidp.c:571: Test failed: id 0: HidP_InitializeReportForID returned 0xc0110001 hidp.c:573: Test failed: id 0: HidP_InitializeReportForID returned 0xc0110001 hidp.c:577: Test failed: id 0: HidP_InitializeReportForID returned 0xc0110001
Report validation errors: hid:hidp crashed (c0000005)
=== w1064v1507 (64 bit report) ===
hid: hidp.c:1395: Test failed: id 0: didn't find device hidp.c:1399: Test failed: id 0: got error 5 hidp.c:1404: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1405: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1410: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1414: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1418: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1423: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1424: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1429: Test failed: id 0: got error 5 hidp.c:1434: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1435: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1439: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1444: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1445: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1449: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1450: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:402: Test failed: id 0: HidD_GetPreparsedData failed with error 6 hidp.c:408: Test failed: id 0: HidP_GetCaps returned 0xc0110001 hidp.c:409: Test failed: id 0: got Usage df1c, expected 0004 hidp.c:409: Test failed: id 0: got UsagePage 4efd, expected 0001 hidp.c:409: Test failed: id 0: got InputReportByteLength 8320, expected 26 hidp.c:409: Test failed: id 0: got OutputReportByteLength 53607, expected 3 hidp.c:409: Test failed: id 0: got FeatureReportByteLength 43078, expected 22 hidp.c:409: Test failed: id 0: got NumberLinkCollectionNodes 0, expected 10 hidp.c:409: Test failed: id 0: got NumberInputButtonCaps 0, expected 17 hidp.c:409: Test failed: id 0: got NumberInputValueCaps 16020, expected 7 hidp.c:409: Test failed: id 0: got NumberInputDataIndices 7265, expected 47 hidp.c:409: Test failed: id 0: got NumberOutputButtonCaps 21851, expected 0 hidp.c:409: Test failed: id 0: got NumberOutputDataIndices 38832, expected 0 hidp.c:409: Test failed: id 0: got NumberFeatureButtonCaps 98, expected 1 hidp.c:409: Test failed: id 0: got NumberFeatureValueCaps 0, expected 6 hidp.c:409: Test failed: id 0: got NumberFeatureDataIndices 0, expected 8 hidp.c:413: Test failed: id 0: HidP_GetLinkCollectionNodes returned 0xc0110001 hidp.c:420: Test failed: id 0: HidP_GetLinkCollectionNodes returned 0xc0110001 hidp.c:421: Test failed: id 0: got 16 collection nodes, expected 0 hidp.c:427: Test failed: id 0: collections[0]: got LinkUsage 0000, expected 0004 hidp.c:427: Test failed: id 0: collections[0]: got LinkUsagePage 0000, expected 0001 hidp.c:427: Test failed: id 0: collections[0]: got NumberOfChildren 0, expected 7 hidp.c:427: Test failed: id 0: collections[0]: got FirstChild 0, expected 9 hidp.c:427: Test failed: id 0: collections[0]: got CollectionType 0, expected 1 hidp.c:427: Test failed: id 0: collections[1]: got LinkUsage 99b0, expected 0004 hidp.c:427: Test failed: id 0: collections[1]: got LinkUsagePage 0061, expected 0001 hidp.c:427: Test failed: id 0: collections[1]: got NextSibling 336, expected 0 hidp.c:427: Test failed: id 0: collections[1]: got FirstChild 93, expected 0 hidp.c:427: Test failed: id 0: collections[1]: got CollectionType 0, expected 2 hidp.c:433: Test failed: id 0: HidP_GetButtonCaps returned 0xc0110001 hidp.c:435: Test failed: id 0: HidP_GetButtonCaps returned 0xc0110001 hidp.c:438: Test failed: id 0: HidP_GetButtonCaps returned 0xc0110001 hidp.c:446: Test failed: id 0: HidP_GetButtonCaps returned 0xc0110001 hidp.c:447: Test failed: id 0: HidP_GetButtonCaps returned count 32, expected 0 hidp.c:453: Test failed: id 0: button_caps[0]: got UsagePage 0000, expected 0009 hidp.c:453: Test failed: id 0: button_caps[0]: got BitField 0, expected 2 hidp.c:453: Test failed: id 0: button_caps[0]: got LinkCollection 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[0]: got LinkUsage 0000, expected 0004 hidp.c:453: Test failed: id 0: button_caps[0]: got LinkUsagePage 0000, expected 0001 hidp.c:453: Test failed: id 0: button_caps[0]: got IsRange 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[0]: got IsAbsolute 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[1]: got UsagePage 0000, expected 0009 hidp.c:453: Test failed: id 0: button_caps[1]: got BitField 0, expected 3 hidp.c:453: Test failed: id 0: button_caps[1]: got LinkCollection 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[1]: got LinkUsage 0000, expected 0004 hidp.c:453: Test failed: id 0: button_caps[1]: got LinkUsagePage 0000, expected 0001 hidp.c:453: Test failed: id 0: button_caps[1]: got IsRange 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[1]: got IsAbsolute 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[2]: got UsagePage 0000, expected 0007 hidp.c:453: Test failed: id 0: button_caps[2]: got BitField 0, expected 508 hidp.c:453: Test failed: id 0: button_caps[2]: got LinkCollection 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[2]: got LinkUsage 0000, expected 0004 hidp.c:453: Test failed: id 0: button_caps[2]: got LinkUsagePage 0000, expected 0001 hidp.c:453: Test failed: id 0: button_caps[2]: got IsRange 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[3]: got UsagePage 0000, expected 0009 hidp.c:453: Test failed: id 0: button_caps[3]: got BitField 0, expected 2 hidp.c:453: Test failed: id 0: button_caps[3]: got LinkCollection 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[3]: got LinkUsage 0000, expected 0004 hidp.c:453: Test failed: id 0: button_caps[3]: got LinkUsagePage 0000, expected 0001 hidp.c:453: Test failed: id 0: button_caps[3]: got IsAbsolute 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[3]: got NotRange.Usage 0000, expected 0020 hidp.c:453: Test failed: id 0: button_caps[3]: got NotRange.DataIndex 0, expected 26 hidp.c:459: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:461: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:464: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:472: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:473: Test failed: id 0: HidP_GetSpecificButtonCaps returned count 31, expected 0 hidp.c:479: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:480: Test failed: id 0: HidP_GetSpecificButtonCaps returned count 31, expected 1 hidp.c:485: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:486: Test failed: id 0: HidP_GetSpecificButtonCaps returned count 48879, expected 0 hidp.c:489: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:490: Test failed: id 0: HidP_GetSpecificButtonCaps returned count 48879, expected 0 hidp.c:493: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:494: Test failed: id 0: HidP_GetSpecificButtonCaps returned count 48879, expected 0 hidp.c:498: Test failed: id 0: HidP_GetValueCaps returned 0xc0110001 hidp.c:500: Test failed: id 0: HidP_GetValueCaps returned 0xc0110001 hidp.c:503: Test failed: id 0: HidP_GetValueCaps returned 0xc0110001 hidp.c:504: Test failed: id 0: HidP_GetValueCaps returned count 0, expected 16020 hidp.c:510: Test failed: id 0: HidP_GetValueCaps returned 0xc0110001 hidp.c:511: Test failed: id 0: HidP_GetValueCaps returned count 16, expected 16020 hidp.c:517: Test failed: id 0: value_caps[0]: got UsagePage 19a8, expected 0001 hidp.c:517: Test failed: id 0: value_caps[0]: got ReportID 173, expected 0 hidp.c:517: Test failed: id 0: value_caps[0]: got IsAlias 152, expected 0 hidp.c:517: Test failed: id 0: value_caps[0]: got BitField 32761, expected 2 hidp.c:517: Test failed: id 0: value_caps[0]: got LinkCollection 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[0]: got LinkUsage 58968, expected 4 hidp.c:517: Test failed: id 0: value_caps[0]: got LinkUsagePage 36, expected 1 hidp.c:517: Test failed: id 0: value_caps[0]: got IsAbsolute 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[0]: got BitSize 0, expected 8 hidp.c:517: Test failed: id 0: value_caps[0]: got ReportCount 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[0]: got UnitsExp 72, expected 0 hidp.c:517: Test failed: id 0: value_caps[0]: got LogicalMin 2418232, expected -128 hidp.c:517: Test failed: id 0: value_caps[0]: got LogicalMax 0, expected 127 hidp.c:517: Test failed: id 0: value_caps[0]: got PhysicalMin 62, expected 0 hidp.c:517: Test failed: id 0: value_caps[0]: got NotRange.Usage 5b5b, expected 0031 hidp.c:517: Test failed: id 0: value_caps[0]: got NotRange.StringIndex 32761, expected 0 hidp.c:517: Test failed: id 0: value_caps[1]: got UsagePage 0000, expected 0001 hidp.c:517: Test failed: id 0: value_caps[1]: got BitField 0, expected 2 hidp.c:517: Test failed: id 0: value_caps[1]: got LinkCollection 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[1]: got LinkUsage 72, expected 4 hidp.c:517: Test failed: id 0: value_caps[1]: got LinkUsagePage 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[1]: got IsAbsolute 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[1]: got HasNull 154, expected 0 hidp.c:517: Test failed: id 0: value_caps[1]: got BitSize 38907, expected 8 hidp.c:517: Test failed: id 0: value_caps[1]: got ReportCount 32761, expected 1 hidp.c:517: Test failed: id 0: value_caps[1]: got UnitsExp -1745341758, expected 0 hidp.c:517: Test failed: id 0: value_caps[1]: got Units 32761, expected 0 hidp.c:517: Test failed: id 0: value_caps[1]: got LogicalMin 983041, expected -128 hidp.c:517: Test failed: id 0: value_caps[1]: got LogicalMax 0, expected 127 hidp.c:517: Test failed: id 0: value_caps[1]: got PhysicalMin 6094848, expected 0 hidp.c:517: Test failed: id 0: value_caps[1]: got NotRange.Usage 0000, expected 0030 hidp.c:517: Test failed: id 0: value_caps[1]: got NotRange.DataIndex 32761, expected 1 hidp.c:517: Test failed: id 0: value_caps[1]: got NotRange.DesignatorIndex 3103, expected 0 hidp.c:517: Test failed: id 0: value_caps[2]: got UsagePage e5e0, expected 0009 hidp.c:517: Test failed: id 0: value_caps[2]: got IsAlias 152, expected 0 hidp.c:517: Test failed: id 0: value_caps[2]: got BitField 32761, expected 2 hidp.c:517: Test failed: id 0: value_caps[2]: got LinkCollection 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[2]: got LinkUsage 5920, expected 4 hidp.c:517: Test failed: id 0: value_caps[2]: got LinkUsagePage 226, expected 1 hidp.c:517: Test failed: id 0: value_caps[2]: got IsRange 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[2]: got IsAbsolute 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[2]: got ReportCount 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[2]: got UnitsExp 72, expected 0 hidp.c:517: Test failed: id 0: value_caps[2]: got LogicalMin -1745028832, expected 0 hidp.c:517: Test failed: id 0: value_caps[2]: got LogicalMax 32761, expected 1 hidp.c:517: Test failed: id 0: value_caps[2]: got PhysicalMin 2418062, expected 0 hidp.c:517: Test failed: id 0: value_caps[2]: got NotRange.DesignatorIndex 2, expected 0 hidp.c:517: Test failed: id 0: value_caps[3]: got UsagePage 0061, expected 0001 hidp.c:517: Test failed: id 0: value_caps[3]: got ReportID 112, expected 0 hidp.c:517: Test failed: id 0: value_caps[3]: got BitField 105, expected 2 hidp.c:517: Test failed: id 0: value_caps[3]: got LinkCollection 46, expected 1 hidp.c:517: Test failed: id 0: value_caps[3]: got LinkUsage 100, expected 4 hidp.c:517: Test failed: id 0: value_caps[3]: got LinkUsagePage 101, expected 1 hidp.c:517: Test failed: id 0: value_caps[3]: got IsRange 118, expected 0 hidp.c:517: Test failed: id 0: value_caps[3]: got IsDesignatorRange 46, expected 0 hidp.c:517: Test failed: id 0: value_caps[3]: got IsAbsolute 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[3]: got HasNull 108, expected 0 hidp.c:517: Test failed: id 0: value_caps[3]: got BitSize 111, expected 4 hidp.c:517: Test failed: id 0: value_caps[3]: got ReportCount 103, expected 2 hidp.c:517: Test failed: id 0: value_caps[3]: got LogicalMin 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[3]: got LogicalMax 2, expected 8 hidp.c:523: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:525: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:528: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:529: Test failed: id 0: HidP_GetSpecificValueCaps returned count 0, expected 16020 hidp.c:536: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:537: Test failed: id 0: HidP_GetSpecificValueCaps returned count 12, expected 16020 hidp.c:539: Test failed: id 0: got UsagePage 99b0, expected 19a8 hidp.c:539: Test failed: id 0: got ReportID 97, expected 173 hidp.c:539: Test failed: id 0: got IsAlias 0, expected 152 hidp.c:539: Test failed: id 0: got BitField 0, expected 32761 hidp.c:539: Test failed: id 0: got LinkUsage 0, expected 58968 hidp.c:539: Test failed: id 0: got LinkUsagePage 0, expected 36 hidp.c:539: Test failed: id 0: got HasNull 27, expected 0 hidp.c:539: Test failed: id 0: got BitSize 256, expected 0 hidp.c:539: Test failed: id 0: got UnitsExp 18, expected 72 hidp.c:539: Test failed: id 0: got LogicalMin 146, expected 2418232 hidp.c:539: Test failed: id 0: got LogicalMax 32761, expected 0 hidp.c:539: Test failed: id 0: got PhysicalMin 6396320, expected 62 hidp.c:539: Test failed: id 0: got NotRange.Usage 1720, expected 5b5b hidp.c:539: Test failed: id 0: got NotRange.StringIndex 0, expected 32761 hidp.c:539: Test failed: id 0: got NotRange.DesignatorIndex 27, expected 0 hidp.c:540: Test failed: id 0: got UsagePage 1000, expected 0000 hidp.c:540: Test failed: id 0: got LinkUsage 18, expected 72 hidp.c:540: Test failed: id 0: got HasNull 160, expected 154 hidp.c:540: Test failed: id 0: got BitSize 97, expected 38907 hidp.c:540: Test failed: id 0: got ReportCount 0, expected 32761 hidp.c:540: Test failed: id 0: got UnitsExp 0, expected -1745341758 hidp.c:540: Test failed: id 0: got Units 1023, expected 32761 hidp.c:540: Test failed: id 0: got LogicalMin 274, expected 983041 hidp.c:540: Test failed: id 0: got PhysicalMin 256, expected 6094848 hidp.c:540: Test failed: id 0: got NotRange.DataIndex 0, expected 32761 hidp.c:540: Test failed: id 0: got NotRange.DesignatorIndex 0, expected 3103 hidp.c:541: Test failed: id 0: got UsagePage 0000, expected e5e0 hidp.c:541: Test failed: id 0: got IsAlias 0, expected 152 hidp.c:541: Test failed: id 0: got BitField 0, expected 32761 hidp.c:541: Test failed: id 0: got LinkUsage 284, expected 5920 hidp.c:541: Test failed: id 0: got LinkUsagePage 7424, expected 226 hidp.c:541: Test failed: id 0: got UnitsExp 0, expected 72 hidp.c:541: Test failed: id 0: got LogicalMin 0, expected -1745028832 hidp.c:541: Test failed: id 0: got LogicalMax 0, expected 32761 hidp.c:541: Test failed: id 0: got PhysicalMin 1, expected 2418062 hidp.c:541: Test failed: id 0: got NotRange.Usage 0000, expected e610 hidp.c:541: Test failed: id 0: got NotRange.DesignatorIndex 1, expected 2 hidp.c:542: Test failed: id 0: got UsagePage 0087, expected 0061 hidp.c:542: Test failed: id 0: got ReportID 0, expected 112 hidp.c:542: Test failed: id 0: got BitField 0, expected 105 hidp.c:542: Test failed: id 0: got LinkCollection 0, expected 46 hidp.c:542: Test failed: id 0: got LinkUsage 960, expected 100 hidp.c:542: Test failed: id 0: got LinkUsagePage 98, expected 101 hidp.c:542: Test failed: id 0: got IsRange 0, expected 118 hidp.c:542: Test failed: id 0: got IsDesignatorRange 0, expected 46 hidp.c:542: Test failed: id 0: got HasNull 240, expected 108 hidp.c:542: Test failed: id 0: got BitSize 139, expected 111 hidp.c:542: Test failed: id 0: got ReportCount 0, expected 103 hidp.c:542: Test failed: id 0: got UnitsExp 56, expected 0 hidp.c:542: Test failed: id 0: got LogicalMin -2119355794, expected 0 hidp.c:542: Test failed: id 0: got LogicalMax 11, expected 2 hidp.c:542: Test failed: id 0: got PhysicalMin 1, expected 0 hidp.c:547: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:549: Test failed: id 0: got UsagePage 99b0, expected 0061 hidp.c:549: Test failed: id 0: got ReportID 97, expected 112 hidp.c:549: Test failed: id 0: got BitField 0, expected 105 hidp.c:549: Test failed: id 0: got LinkCollection 0, expected 46 hidp.c:549: Test failed: id 0: got LinkUsage 0, expected 100 hidp.c:549: Test failed: id 0: got LinkUsagePage 0, expected 101 hidp.c:549: Test failed: id 0: got IsRange 0, expected 118 hidp.c:549: Test failed: id 0: got IsDesignatorRange 0, expected 46 hidp.c:549: Test failed: id 0: got HasNull 27, expected 108 hidp.c:549: Test failed: id 0: got BitSize 256, expected 111 hidp.c:549: Test failed: id 0: got ReportCount 0, expected 103 hidp.c:549: Test failed: id 0: got UnitsExp 18, expected 0 hidp.c:549: Test failed: id 0: got LogicalMin 146, expected 0 hidp.c:549: Test failed: id 0: got LogicalMax 32761, expected 2 hidp.c:549: Test failed: id 0: got PhysicalMin 6396320, expected 0 hidp.c:553: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:554: Test failed: id 0: HidP_GetSpecificValueCaps returned count 57005, expected 0 hidp.c:557: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:558: Test failed: id 0: HidP_GetSpecificValueCaps returned count 57005, expected 0 hidp.c:561: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:562: Test failed: id 0: HidP_GetSpecificValueCaps returned count 57005, expected 0 hidp.c:567: Test failed: id 0: HidP_InitializeReportForID returned 0xc0110001 hidp.c:569: Test failed: id 0: HidP_InitializeReportForID returned 0xc0110001 hidp.c:571: Test failed: id 0: HidP_InitializeReportForID returned 0xc0110001 hidp.c:573: Test failed: id 0: HidP_InitializeReportForID returned 0xc0110001 hidp.c:577: Test failed: id 0: HidP_InitializeReportForID returned 0xc0110001 hidp.c:586: Test failed: id 0: HidP_SetUsageValueArray returned 0xc0110001 hidp.c:590: Test failed: id 0: HidP_SetUsageValueArray returned 0xc0110001 hidp.c:594: Test failed: id 0: HidP_SetUsageValueArray returned 0xc0110001 hidp.c:598: Test failed: id 0: HidP_GetUsageValueArray returned 0xc0110001 hidp.c:602: Test failed: id 0: HidP_GetUsageValueArray returned 0xc0110001 hidp.c:606: Test failed: id 0: HidP_GetUsageValueArray returned 0xc0110001 hidp.c:611: Test failed: id 0: HidP_SetUsageValue returned 0xc0110001 hidp.c:615: Test failed: id 0: HidP_GetUsageValue returned 0xc0110001 hidp.c:616: Test failed: id 0: got value deadbeef, expected 0x80 hidp.c:620: Test failed: id 0: HidP_GetScaledUsageValue returned 0xc0110001 hidp.c:621: Test failed: id 0: got value deadbeef, expected 0xffffff80 hidp.c:626: Test failed: id 0: HidP_SetUsageValue returned 0xc0110001 hidp.c:630: Test failed: id 0: HidP_GetScaledUsageValue returned 0xc0110001 hidp.c:631: Test failed: id 0: got value deadbeef, expected 0x7f hidp.c:636: Test failed: id 0: HidP_SetUsageValue returned 0xc0110001 hidp.c:640: Test failed: id 0: HidP_GetScaledUsageValue returned 0xc0110001 hidp.c:641: Test failed: id 0: got value deadbeef, expected 0 hidp.c:646: Test failed: id 0: HidP_SetUsageValue returned 0xc0110001 hidp.c:650: Test failed: id 0: HidP_GetScaledUsageValue returned 0xc0110001 hidp.c:651: Test failed: id 0: got value deadbeef, expected 0 hidp.c:655: Test failed: id 0: HidP_GetUsageValue returned 0xc0110001 hidp.c:656: Test failed: id 0: got value deadbeef, expected 0x7fffffff hidp.c:661: Test failed: id 0: HidP_SetUsageValue returned 0xc0110001 hidp.c:665: Test failed: id 0: HidP_GetScaledUsageValue returned 0xc0110001 hidp.c:666: Test failed: id 0: got value deadbeef, expected 0x7fffffff hidp.c:671: Test failed: id 0: HidP_SetUsageValue returned 0xc0110001 hidp.c:675: Test failed: id 0: HidP_GetScaledUsageValue returned 0xc0110001 hidp.c:676: Test failed: id 0: got value deadbeef, expected 0x80000000 hidp.c:681: Test failed: id 0: HidP_SetUsageValue returned 0xc0110001 hidp.c:685: Test failed: id 0: HidP_GetScaledUsageValue returned 0xc0110001 hidp.c:686: Test failed: id 0: got value deadbeef, expected 0 hidp.c:691: Test failed: id 0: HidP_SetUsageValue returned 0xc0110001 hidp.c:695: Test failed: id 0: HidP_GetScaledUsageValue returned 0xc0110001 hidp.c:696: Test failed: id 0: got value deadbeef, expected 0 hidp.c:699: Test failed: id 0: HidP_GetScaledUsageValue returned 0xc0110001 hidp.c:700: Test failed: id 0: got value deadbeef, expected 0 hidp.c:705: Test failed: id 0: HidP_MaxUsageListLength(HidP_Input, 0) returned 0, expected 50 hidp.c:707: Test failed: id 0: HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_BUTTON) returned 0, expected 32 hidp.c:709: Test failed: id 0: HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_LED) returned 0, expected 8 hidp.c:711: Test failed: id 0: HidP_MaxUsageListLength(HidP_Feature, HID_USAGE_PAGE_BUTTON) returned 0, expected 8 hidp.c:719: Test failed: id 0: HidP_SetUsages returned 0xc0110001 hidp.c:725: Test failed: id 0: HidP_SetUsages returned 0xc0110001 hidp.c:731: Test failed: id 0: HidP_SetUsages returned 0xc0110001 hidp.c:737: Test failed: id 0: HidP_SetUsages returned 0xc0110001 hidp.c:742: Test failed: id 0: HidP_GetUsages returned 0xc0110001 hidp.c:743: Test failed: id 0: got usage count 16, expected 2 hidp.c:754: Test failed: id 0: HidP_SetUsages returned 0xc0110001 hidp.c:757: Test failed: id 0: unexpected report data hidp.c:761: Test failed: id 0: HidP_SetUsageValue returned 0xc0110001 hidp.c:766: Test failed: id 0: HidP_SetUsageValue returned 0xc0110001 hidp.c:772: Test failed: id 0: HidP_GetUsages returned 0xc0110001 hidp.c:773: Test failed: id 0: got usage count 1, expected 2 hidp.c:778: Test failed: id 0: HidP_GetUsages returned 0xc0110001 hidp.c:779: Test failed: id 0: got usage count 16, expected 2 hidp.c:780: Test failed: id 0: got usages[0] cdcd, expected 4 hidp.c:781: Test failed: id 0: got usages[1] cdcd, expected 6 hidp.c:787: Test failed: id 0: HidP_GetUsages returned 0xc0110001 hidp.c:788: Test failed: id 0: got usage count 16, expected 2 hidp.c:789: Test failed: id 0: got usages[0] cdcd, expected 6 hidp.c:790: Test failed: id 0: got usages[1] cdcd, expected 4 hidp.c:796: Test failed: id 0: HidP_GetUsagesEx returned 0xc0110001 hidp.c:797: Test failed: id 0: got usage count 16, expected 4 hidp.c:798: Test failed: id 0: got usage_and_pages[0] UsagePage cdcd, expected 9 hidp.c:800: Test failed: id 0: got usage_and_pages[1] UsagePage cdcd, expected 9 hidp.c:802: Test failed: id 0: got usage_and_pages[2] UsagePage cdcd, expected 7 hidp.c:804: Test failed: id 0: got usage_and_pages[3] UsagePage cdcd, expected 7 hidp.c:806: Test failed: id 0: got usage_and_pages[4] UsagePage cdcd, expected 8 hidp.c:808: Test failed: id 0: got usage_and_pages[5] UsagePage cdcd, expected 8 hidp.c:810: Test failed: id 0: got usage_and_pages[0] Usage cdcd, expected 4 hidp.c:812: Test failed: id 0: got usage_and_pages[1] Usage cdcd, expected 6 hidp.c:814: Test failed: id 0: got usage_and_pages[2] Usage cdcd, expected 9 hidp.c:816: Test failed: id 0: got usage_and_pages[3] Usage cdcd, expected b hidp.c:818: Test failed: id 0: got usage_and_pages[4] Usage cdcd, expected 6 hidp.c:820: Test failed: id 0: got usage_and_pages[5] Usage cdcd, expected 4 hidp.c:826: Test failed: id 0: HidP_MaxDataListLength(HidP_Input) returned 0, expected 58 hidp.c:830: Test failed: id 0: HidP_MaxDataListLength(HidP_Feature) returned 0, expected 14 hidp.c:834: Test failed: id 0: HidP_GetData returned 0xc0110001 hidp.c:835: Test failed: id 0: got data count 1, expected 11 hidp.c:838: Test failed: id 0: HidP_GetData returned 0xc0110001 hidp.c:842: Test failed: id 0: data[1]: got DataIndex 0, expected 1 hidp.c:842: Test failed: id 0: data[2]: got DataIndex 0, expected 5 hidp.c:843: Test failed: id 0: data[2]: got RawValue 0, expected 1 hidp.c:842: Test failed: id 0: data[3]: got DataIndex 0, expected 7 hidp.c:843: Test failed: id 0: data[3]: got RawValue 0, expected 1 hidp.c:842: Test failed: id 0: data[4]: got DataIndex 0, expected 19 hidp.c:843: Test failed: id 0: data[4]: got RawValue 0, expected 1 hidp.c:842: Test failed: id 0: data[5]: got DataIndex 0, expected 21 hidp.c:843: Test failed: id 0: data[5]: got RawValue 0, expected 1 hidp.c:842: Test failed: id 0: data[6]: got DataIndex 0, expected 30 hidp.c:842: Test failed: id 0: data[7]: got DataIndex 0, expected 31 hidp.c:842: Test failed: id 0: data[8]: got DataIndex 0, expected 32 hidp.c:843: Test failed: id 0: data[8]: got RawValue 0, expected -17970434 hidp.c:842: Test failed: id 0: data[9]: got DataIndex 0, expected 37 hidp.c:843: Test failed: id 0: data[9]: got RawValue 0, expected 1 hidp.c:842: Test failed: id 0: data[10]: got DataIndex 0, expected 39 hidp.c:843: Test failed: id 0: data[10]: got RawValue 0, expected 1 hidp.c:852: Test failed: id 0: HidP_InitializeReportForID returned 0xc0110001 hidp.c:858: Test failed: id 0: HidP_SetUsages returned 0xc0110001 hidp.c:859: Test failed: id 0: unexpected usage index 0, expected 3 hidp.c:861: Test failed: id 0: unexpected usage index 0, expected 4 hidp.c:865: Test failed: id 0: HidP_UnsetUsages returned 0xc0110001 hidp.c:872: Test failed: id 0: HidP_UnsetUsages returned 0xc0110001 hidp.c:877: Test failed: id 0: HidP_SetUsages returned 0xc0110001 hidp.c:878: Test failed: id 0: unexpected usage index 0, expected 1 hidp.c:883: Test failed: id 0: HidP_InitializeReportForID returned 0xc0110001 hidp.c:887: Test failed: id 0: HidP_InitializeReportForID returned 0xc0110001
Report validation errors: hid:hidp crashed (c0000005)
=== w1064v1809 (64 bit report) ===
hid: hidp.c:1395: Test failed: id 0: didn't find device hidp.c:1399: Test failed: id 0: got error 5 hidp.c:1404: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1405: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1410: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1414: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1418: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1423: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1424: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1429: Test failed: id 0: got error 5 hidp.c:1434: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1435: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1439: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1444: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1445: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1449: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1450: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:402: Test failed: id 0: HidD_GetPreparsedData failed with error 6 hidp.c:408: Test failed: id 0: HidP_GetCaps returned 0xc0110001 hidp.c:409: Test failed: id 0: got Usage 0000, expected 0004 hidp.c:409: Test failed: id 0: got UsagePage 0000, expected 0001 hidp.c:409: Test failed: id 0: got InputReportByteLength 0, expected 26 hidp.c:409: Test failed: id 0: got OutputReportByteLength 0, expected 3 hidp.c:409: Test failed: id 0: got FeatureReportByteLength 40780, expected 22 hidp.c:409: Test failed: id 0: got NumberLinkCollectionNodes 0, expected 10 hidp.c:409: Test failed: id 0: got NumberInputButtonCaps 0, expected 17 hidp.c:409: Test failed: id 0: got NumberInputValueCaps 56724, expected 7 hidp.c:409: Test failed: id 0: got NumberInputDataIndices 103, expected 47 hidp.c:409: Test failed: id 0: got NumberOutputDataIndices 56736, expected 0 hidp.c:409: Test failed: id 0: got NumberFeatureButtonCaps 103, expected 1 hidp.c:409: Test failed: id 0: got NumberFeatureValueCaps 0, expected 6 hidp.c:409: Test failed: id 0: got NumberFeatureDataIndices 0, expected 8 hidp.c:413: Test failed: id 0: HidP_GetLinkCollectionNodes returned 0xc0110001 hidp.c:420: Test failed: id 0: HidP_GetLinkCollectionNodes returned 0xc0110001 hidp.c:421: Test failed: id 0: got 16 collection nodes, expected 0 hidp.c:427: Test failed: id 0: collections[0]: got LinkUsage 0000, expected 0004 hidp.c:427: Test failed: id 0: collections[0]: got LinkUsagePage 0000, expected 0001 hidp.c:427: Test failed: id 0: collections[0]: got NumberOfChildren 0, expected 7 hidp.c:427: Test failed: id 0: collections[0]: got FirstChild 0, expected 9 hidp.c:427: Test failed: id 0: collections[0]: got CollectionType 0, expected 1 hidp.c:427: Test failed: id 0: collections[1]: got LinkUsage 0000, expected 0004 hidp.c:427: Test failed: id 0: collections[1]: got LinkUsagePage 0000, expected 0001 hidp.c:427: Test failed: id 0: collections[1]: got CollectionType 0, expected 2 hidp.c:433: Test failed: id 0: HidP_GetButtonCaps returned 0xc0110001 hidp.c:435: Test failed: id 0: HidP_GetButtonCaps returned 0xc0110001 hidp.c:438: Test failed: id 0: HidP_GetButtonCaps returned 0xc0110001 hidp.c:446: Test failed: id 0: HidP_GetButtonCaps returned 0xc0110001 hidp.c:447: Test failed: id 0: HidP_GetButtonCaps returned count 32, expected 0 hidp.c:453: Test failed: id 0: button_caps[0]: got UsagePage 0000, expected 0009 hidp.c:453: Test failed: id 0: button_caps[0]: got BitField 0, expected 2 hidp.c:453: Test failed: id 0: button_caps[0]: got LinkCollection 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[0]: got LinkUsage 0000, expected 0004 hidp.c:453: Test failed: id 0: button_caps[0]: got LinkUsagePage 0000, expected 0001 hidp.c:453: Test failed: id 0: button_caps[0]: got IsRange 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[0]: got IsAbsolute 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[1]: got UsagePage 0000, expected 0009 hidp.c:453: Test failed: id 0: button_caps[1]: got BitField 0, expected 3 hidp.c:453: Test failed: id 0: button_caps[1]: got LinkCollection 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[1]: got LinkUsage 0000, expected 0004 hidp.c:453: Test failed: id 0: button_caps[1]: got LinkUsagePage 0000, expected 0001 hidp.c:453: Test failed: id 0: button_caps[1]: got IsRange 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[1]: got IsAbsolute 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[2]: got UsagePage 0000, expected 0007 hidp.c:453: Test failed: id 0: button_caps[2]: got BitField 0, expected 508 hidp.c:453: Test failed: id 0: button_caps[2]: got LinkCollection 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[2]: got LinkUsage 0000, expected 0004 hidp.c:453: Test failed: id 0: button_caps[2]: got LinkUsagePage 0000, expected 0001 hidp.c:453: Test failed: id 0: button_caps[2]: got IsRange 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[3]: got UsagePage 0000, expected 0009 hidp.c:453: Test failed: id 0: button_caps[3]: got BitField 0, expected 2 hidp.c:453: Test failed: id 0: button_caps[3]: got LinkCollection 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[3]: got LinkUsage 0000, expected 0004 hidp.c:453: Test failed: id 0: button_caps[3]: got LinkUsagePage 0000, expected 0001 hidp.c:453: Test failed: id 0: button_caps[3]: got IsAbsolute 0, expected 1 hidp.c:453: Test failed: id 0: button_caps[3]: got NotRange.Usage 0000, expected 0020 hidp.c:453: Test failed: id 0: button_caps[3]: got NotRange.DataIndex 0, expected 26 hidp.c:459: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:461: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:464: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:472: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:473: Test failed: id 0: HidP_GetSpecificButtonCaps returned count 31, expected 0 hidp.c:479: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:480: Test failed: id 0: HidP_GetSpecificButtonCaps returned count 31, expected 1 hidp.c:485: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:486: Test failed: id 0: HidP_GetSpecificButtonCaps returned count 48879, expected 0 hidp.c:489: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:490: Test failed: id 0: HidP_GetSpecificButtonCaps returned count 48879, expected 0 hidp.c:493: Test failed: id 0: HidP_GetSpecificButtonCaps returned 0xc0110001 hidp.c:494: Test failed: id 0: HidP_GetSpecificButtonCaps returned count 48879, expected 0 hidp.c:498: Test failed: id 0: HidP_GetValueCaps returned 0xc0110001 hidp.c:500: Test failed: id 0: HidP_GetValueCaps returned 0xc0110001 hidp.c:503: Test failed: id 0: HidP_GetValueCaps returned 0xc0110001 hidp.c:504: Test failed: id 0: HidP_GetValueCaps returned count 0, expected 56724 hidp.c:510: Test failed: id 0: HidP_GetValueCaps returned 0xc0110001 hidp.c:511: Test failed: id 0: HidP_GetValueCaps returned count 16, expected 56724 hidp.c:517: Test failed: id 0: value_caps[0]: got UsagePage c959, expected 0001 hidp.c:517: Test failed: id 0: value_caps[0]: got ReportID 170, expected 0 hidp.c:517: Test failed: id 0: value_caps[0]: got IsAlias 156, expected 0 hidp.c:517: Test failed: id 0: value_caps[0]: got BitField 48312, expected 2 hidp.c:517: Test failed: id 0: value_caps[0]: got LinkCollection 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[0]: got LinkUsage 0, expected 4 hidp.c:517: Test failed: id 0: value_caps[0]: got LinkUsagePage 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[0]: got IsAbsolute 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[0]: got HasNull 16, expected 0 hidp.c:517: Test failed: id 0: value_caps[0]: got BitSize 103, expected 8 hidp.c:517: Test failed: id 0: value_caps[0]: got ReportCount 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[0]: got UnitsExp 47, expected 0 hidp.c:517: Test failed: id 0: value_caps[0]: got LogicalMin -1247530334, expected -128 hidp.c:517: Test failed: id 0: value_caps[0]: got LogicalMax 32767, expected 127 hidp.c:517: Test failed: id 0: value_caps[0]: got PhysicalMin 1310720, expected 0 hidp.c:517: Test failed: id 0: value_caps[0]: got NotRange.Usage 0000, expected 0031 hidp.c:517: Test failed: id 0: value_caps[1]: got UsagePage f79b, expected 0001 hidp.c:517: Test failed: id 0: value_caps[1]: got ReportID 168, expected 0 hidp.c:517: Test failed: id 0: value_caps[1]: got IsAlias 181, expected 0 hidp.c:517: Test failed: id 0: value_caps[1]: got BitField 32767, expected 2 hidp.c:517: Test failed: id 0: value_caps[1]: got LinkCollection 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[1]: got LinkUsage 61600, expected 4 hidp.c:517: Test failed: id 0: value_caps[1]: got LinkUsagePage 46508, expected 1 hidp.c:517: Test failed: id 0: value_caps[1]: got IsRange 255, expected 0 hidp.c:517: Test failed: id 0: value_caps[1]: got IsStringRange 127, expected 0 hidp.c:517: Test failed: id 0: value_caps[1]: got IsAbsolute 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[1]: got HasNull 240, expected 0 hidp.c:517: Test failed: id 0: value_caps[1]: got BitSize 230, expected 8 hidp.c:517: Test failed: id 0: value_caps[1]: got ReportCount 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[1]: got LogicalMin 72, expected -128 hidp.c:517: Test failed: id 0: value_caps[1]: got LogicalMax 0, expected 127 hidp.c:517: Test failed: id 0: value_caps[1]: got PhysicalMin -1247214995, expected 0 hidp.c:517: Test failed: id 0: value_caps[1]: got PhysicalMax 32767, expected 0 hidp.c:517: Test failed: id 0: value_caps[2]: got UsagePage 0002, expected 0009 hidp.c:517: Test failed: id 0: value_caps[2]: got BitField 0, expected 2 hidp.c:517: Test failed: id 0: value_caps[2]: got LinkCollection 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[2]: got LinkUsage 97, expected 4 hidp.c:517: Test failed: id 0: value_caps[2]: got LinkUsagePage 112, expected 1 hidp.c:517: Test failed: id 0: value_caps[2]: got IsRange 105, expected 1 hidp.c:517: Test failed: id 0: value_caps[2]: got IsDesignatorRange 46, expected 0 hidp.c:517: Test failed: id 0: value_caps[2]: got IsAbsolute 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[2]: got HasNull 16, expected 0 hidp.c:517: Test failed: id 0: value_caps[2]: got ReportCount 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[2]: got UnitsExp 1048576, expected 0 hidp.c:517: Test failed: id 0: value_caps[2]: got LogicalMin 1468968, expected 0 hidp.c:517: Test failed: id 0: value_caps[2]: got LogicalMax 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[2]: got PhysicalMin 11, expected 0 hidp.c:517: Test failed: id 0: value_caps[2]: got Range.UsageMin 0000, expected 0021 hidp.c:517: Test failed: id 0: value_caps[2]: got Range.UsageMax 0000, expected 0022 hidp.c:517: Test failed: id 0: value_caps[2]: got Range.DataIndexMin 2, expected 27 hidp.c:517: Test failed: id 0: value_caps[2]: got Range.DataIndexMax 0, expected 28 hidp.c:517: Test failed: id 0: value_caps[3]: got UsagePage 0000, expected 0001 hidp.c:517: Test failed: id 0: value_caps[3]: got BitField 7, expected 2 hidp.c:517: Test failed: id 0: value_caps[3]: got LinkCollection 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[3]: got LinkUsage 0, expected 4 hidp.c:517: Test failed: id 0: value_caps[3]: got LinkUsagePage 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[3]: got IsAbsolute 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[3]: got HasNull 39, expected 0 hidp.c:517: Test failed: id 0: value_caps[3]: got BitSize 44128, expected 4 hidp.c:517: Test failed: id 0: value_caps[3]: got ReportCount 32767, expected 2 hidp.c:517: Test failed: id 0: value_caps[3]: got UnitsExp 48, expected 0 hidp.c:517: Test failed: id 0: value_caps[3]: got LogicalMin 0, expected 1 hidp.c:517: Test failed: id 0: value_caps[3]: got LogicalMax 0, expected 8 hidp.c:517: Test failed: id 0: value_caps[3]: got PhysicalMin 16, expected 0 hidp.c:517: Test failed: id 0: value_caps[3]: got NotRange.Usage f0a0, expected 0039 hidp.c:517: Test failed: id 0: value_caps[3]: got NotRange.DataIndex 0, expected 29 hidp.c:517: Test failed: id 0: value_caps[3]: got NotRange.StringIndex 32767, expected 0 hidp.c:517: Test failed: id 0: value_caps[3]: got NotRange.DesignatorIndex 6128, expected 0 hidp.c:523: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:525: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:528: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:529: Test failed: id 0: HidP_GetSpecificValueCaps returned count 0, expected 56724 hidp.c:536: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:537: Test failed: id 0: HidP_GetSpecificValueCaps returned count 12, expected 56724 hidp.c:539: Test failed: id 0: got UsagePage 0860, expected c959 hidp.c:539: Test failed: id 0: got ReportID 230, expected 170 hidp.c:539: Test failed: id 0: got IsAlias 0, expected 156 hidp.c:539: Test failed: id 0: got BitField 0, expected 48312 hidp.c:539: Test failed: id 0: got LinkUsage 62465, expected 0 hidp.c:539: Test failed: id 0: got LinkUsagePage 16, expected 0 hidp.c:539: Test failed: id 0: got HasNull 7, expected 16 hidp.c:539: Test failed: id 0: got BitSize 0, expected 103 hidp.c:539: Test failed: id 0: got ReportCount 6, expected 0 hidp.c:539: Test failed: id 0: got UnitsExp 1023, expected 47 hidp.c:539: Test failed: id 0: got LogicalMin 1468960, expected -1247530334 hidp.c:539: Test failed: id 0: got LogicalMax 0, expected 32767 hidp.c:539: Test failed: id 0: got PhysicalMin 0, expected 1310720 hidp.c:539: Test failed: id 0: got NotRange.Usage 0006, expected 0000 hidp.c:540: Test failed: id 0: got UsagePage 0006, expected f79b hidp.c:540: Test failed: id 0: got ReportID 0, expected 168 hidp.c:540: Test failed: id 0: got IsAlias 0, expected 181 hidp.c:540: Test failed: id 0: got BitField 0, expected 32767 hidp.c:540: Test failed: id 0: got LinkUsage 0, expected 61600 hidp.c:540: Test failed: id 0: got LinkUsagePage 0, expected 46508 hidp.c:540: Test failed: id 0: got IsRange 0, expected 255 hidp.c:540: Test failed: id 0: got IsStringRange 0, expected 127 hidp.c:540: Test failed: id 0: got HasNull 0, expected 240 hidp.c:540: Test failed: id 0: got BitSize 0, expected 230 hidp.c:540: Test failed: id 0: got UnitsExp 129, expected 0 hidp.c:540: Test failed: id 0: got LogicalMin 0, expected 72 hidp.c:540: Test failed: id 0: got PhysicalMin 0, expected -1247214995 hidp.c:540: Test failed: id 0: got PhysicalMax 0, expected 32767 hidp.c:540: Test failed: id 0: got NotRange.DesignatorIndex 43160, expected 0 hidp.c:541: Test failed: id 0: got UsagePage 0087, expected 0002 hidp.c:541: Test failed: id 0: got LinkUsage 0, expected 97 hidp.c:541: Test failed: id 0: got LinkUsagePage 0, expected 112 hidp.c:541: Test failed: id 0: got IsRange 0, expected 105 hidp.c:541: Test failed: id 0: got IsDesignatorRange 0, expected 46 hidp.c:541: Test failed: id 0: got HasNull 0, expected 16 hidp.c:541: Test failed: id 0: got UnitsExp 0, expected 1048576 hidp.c:541: Test failed: id 0: got Units 1, expected 0 hidp.c:541: Test failed: id 0: got LogicalMin 0, expected 1468968 hidp.c:541: Test failed: id 0: got PhysicalMin 0, expected 11 hidp.c:542: Test failed: id 0: got UsagePage 000c, expected 0000 hidp.c:542: Test failed: id 0: got BitField 0, expected 7 hidp.c:542: Test failed: id 0: got HasNull 64, expected 39 hidp.c:542: Test failed: id 0: got BitSize 21, expected 44128 hidp.c:542: Test failed: id 0: got ReportCount 0, expected 32767 hidp.c:542: Test failed: id 0: got UnitsExp 0, expected 48 hidp.c:542: Test failed: id 0: got LogicalMin 152, expected 0 hidp.c:542: Test failed: id 0: got LogicalMax 27, expected 0 hidp.c:542: Test failed: id 0: got PhysicalMin 1426736, expected 16 hidp.c:542: Test failed: id 0: got NotRange.Usage 03ff, expected f0a0 hidp.c:542: Test failed: id 0: got NotRange.StringIndex 0, expected 32767 hidp.c:542: Test failed: id 0: got NotRange.DesignatorIndex 50480, expected 6128 hidp.c:547: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:549: Test failed: id 0: got UsagePage 0860, expected 0000 hidp.c:549: Test failed: id 0: got ReportID 230, expected 0 hidp.c:549: Test failed: id 0: got BitField 0, expected 7 hidp.c:549: Test failed: id 0: got LinkUsage 62465, expected 0 hidp.c:549: Test failed: id 0: got LinkUsagePage 16, expected 0 hidp.c:549: Test failed: id 0: got HasNull 7, expected 39 hidp.c:549: Test failed: id 0: got BitSize 0, expected 44128 hidp.c:549: Test failed: id 0: got ReportCount 6, expected 32767 hidp.c:549: Test failed: id 0: got UnitsExp 1023, expected 48 hidp.c:549: Test failed: id 0: got LogicalMin 1468960, expected 0 hidp.c:549: Test failed: id 0: got PhysicalMin 0, expected 16 hidp.c:549: Test failed: id 0: got NotRange.Usage 0006, expected f0a0 hidp.c:549: Test failed: id 0: got NotRange.StringIndex 0, expected 32767 hidp.c:549: Test failed: id 0: got NotRange.DesignatorIndex 0, expected 6128 hidp.c:553: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:554: Test failed: id 0: HidP_GetSpecificValueCaps returned count 57005, expected 0 hidp.c:557: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:558: Test failed: id 0: HidP_GetSpecificValueCaps returned count 57005, expected 0 hidp.c:561: Test failed: id 0: HidP_GetSpecificValueCaps returned 0xc0110001 hidp.c:562: Test failed: id 0: HidP_GetSpecificValueCaps returned count 57005, expected 0 hidp.c:567: Test failed: id 0: HidP_InitializeReportForID returned 0xc0110001 hidp.c:569: Test failed: id 0: HidP_InitializeReportForID returned 0xc0110001 hidp.c:571: Test failed: id 0: HidP_InitializeReportForID returned 0xc0110001 hidp.c:573: Test failed: id 0: HidP_InitializeReportForID returned 0xc0110001 hidp.c:577: Test failed: id 0: HidP_InitializeReportForID returned 0xc0110001 hidp.c:582: Test failed: id 0: unexpected report data hidp.c:586: Test failed: id 0: HidP_SetUsageValueArray returned 0xc0110001 hidp.c:590: Test failed: id 0: HidP_SetUsageValueArray returned 0xc0110001 hidp.c:594: Test failed: id 0: HidP_SetUsageValueArray returned 0xc0110001 hidp.c:598: Test failed: id 0: HidP_GetUsageValueArray returned 0xc0110001 hidp.c:602: Test failed: id 0: HidP_GetUsageValueArray returned 0xc0110001 hidp.c:606: Test failed: id 0: HidP_GetUsageValueArray returned 0xc0110001 hidp.c:611: Test failed: id 0: HidP_SetUsageValue returned 0xc0110001 hidp.c:615: Test failed: id 0: HidP_GetUsageValue returned 0xc0110001 hidp.c:616: Test failed: id 0: got value deadbeef, expected 0x80 hidp.c:620: Test failed: id 0: HidP_GetScaledUsageValue returned 0xc0110001 hidp.c:621: Test failed: id 0: got value deadbeef, expected 0xffffff80 hidp.c:626: Test failed: id 0: HidP_SetUsageValue returned 0xc0110001 hidp.c:630: Test failed: id 0: HidP_GetScaledUsageValue returned 0xc0110001 hidp.c:631: Test failed: id 0: got value deadbeef, expected 0x7f hidp.c:636: Test failed: id 0: HidP_SetUsageValue returned 0xc0110001 hidp.c:640: Test failed: id 0: HidP_GetScaledUsageValue returned 0xc0110001 hidp.c:641: Test failed: id 0: got value deadbeef, expected 0 hidp.c:646: Test failed: id 0: HidP_SetUsageValue returned 0xc0110001 hidp.c:650: Test failed: id 0: HidP_GetScaledUsageValue returned 0xc0110001 hidp.c:651: Test failed: id 0: got value deadbeef, expected 0 hidp.c:655: Test failed: id 0: HidP_GetUsageValue returned 0xc0110001 hidp.c:656: Test failed: id 0: got value deadbeef, expected 0x7fffffff hidp.c:661: Test failed: id 0: HidP_SetUsageValue returned 0xc0110001 hidp.c:665: Test failed: id 0: HidP_GetScaledUsageValue returned 0xc0110001 hidp.c:666: Test failed: id 0: got value deadbeef, expected 0x7fffffff hidp.c:671: Test failed: id 0: HidP_SetUsageValue returned 0xc0110001 hidp.c:675: Test failed: id 0: HidP_GetScaledUsageValue returned 0xc0110001 hidp.c:676: Test failed: id 0: got value deadbeef, expected 0x80000000 hidp.c:681: Test failed: id 0: HidP_SetUsageValue returned 0xc0110001 hidp.c:685: Test failed: id 0: HidP_GetScaledUsageValue returned 0xc0110001 hidp.c:686: Test failed: id 0: got value deadbeef, expected 0 hidp.c:691: Test failed: id 0: HidP_SetUsageValue returned 0xc0110001 hidp.c:695: Test failed: id 0: HidP_GetScaledUsageValue returned 0xc0110001 hidp.c:696: Test failed: id 0: got value deadbeef, expected 0 hidp.c:699: Test failed: id 0: HidP_GetScaledUsageValue returned 0xc0110001 hidp.c:700: Test failed: id 0: got value deadbeef, expected 0 1430:hidp: unhandled exception c0000005 at 00007FFFB2172587
=== w1064 (64 bit report) ===
hid: hidp.c:1395: Test failed: id 0: didn't find device hidp.c:1399: Test failed: id 0: got error 5 hidp.c:1404: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1405: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1410: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1414: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1418: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1423: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1424: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1429: Test failed: id 0: got error 5 hidp.c:1434: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1435: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1439: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1444: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1445: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1449: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1450: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:402: Test failed: id 0: HidD_GetPreparsedData failed with error 6 0f50:hidp: unhandled exception c0000005 at 00007FFDE08C15FC
=== w1064_2qxl (64 bit report) ===
hid: hidp.c:1395: Test failed: id 0: didn't find device hidp.c:1399: Test failed: id 0: got error 5 hidp.c:1404: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1405: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1410: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1414: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1418: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1423: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1424: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1429: Test failed: id 0: got error 5 hidp.c:1434: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1435: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1439: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1444: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1445: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1449: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1450: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:402: Test failed: id 0: HidD_GetPreparsedData failed with error 6 1bd0:hidp: unhandled exception c0000005 at 00007FFAD19815FC
=== w10pro64 (64 bit report) ===
hid: hidp.c:1395: Test failed: id 0: didn't find device hidp.c:1399: Test failed: id 0: got error 5 hidp.c:1404: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1405: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1410: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1414: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1418: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1423: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1424: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1429: Test failed: id 0: got error 5 hidp.c:1434: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1435: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1439: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1444: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1445: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1449: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1450: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:402: Test failed: id 0: HidD_GetPreparsedData failed with error 6 1670:hidp: unhandled exception c0000005 at 00007FFEEC7615FC
=== w10pro64_ar (64 bit report) ===
hid: hidp.c:1395: Test failed: id 0: didn't find device hidp.c:1399: Test failed: id 0: got error 5 hidp.c:1404: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1405: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1410: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1414: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1418: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1423: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1424: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1429: Test failed: id 0: got error 5 hidp.c:1434: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1435: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1439: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1444: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1445: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1449: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1450: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:402: Test failed: id 0: HidD_GetPreparsedData failed with error 6 1c64:hidp: unhandled exception c0000005 at 00007FFB88F615FC
=== w10pro64_he (64 bit report) ===
hid: hidp.c:1395: Test failed: id 0: didn't find device hidp.c:1399: Test failed: id 0: got error 5 hidp.c:1404: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1405: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1410: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1414: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1418: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1423: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1424: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1429: Test failed: id 0: got error 5 hidp.c:1434: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1435: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1439: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1444: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1445: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1449: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1450: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:402: Test failed: id 0: HidD_GetPreparsedData failed with error 6 1d70:hidp: unhandled exception c0000005 at 00007FFAD38415FC
=== w10pro64_ja (64 bit report) ===
hid: hidp.c:1395: Test failed: id 0: didn't find device hidp.c:1399: Test failed: id 0: got error 5 hidp.c:1404: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1405: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1410: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1414: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1418: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1423: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1424: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1429: Test failed: id 0: got error 5 hidp.c:1434: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1435: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1439: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1444: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1445: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1449: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1450: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:402: Test failed: id 0: HidD_GetPreparsedData failed with error 6 1dd0:hidp: unhandled exception c0000005 at 00007FFC192E15FC
=== w10pro64_zh_CN (64 bit report) ===
hid: hidp.c:1395: Test failed: id 0: didn't find device hidp.c:1399: Test failed: id 0: got error 5 hidp.c:1404: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1405: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1410: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1414: Test failed: id 0: HidD_SetNumInputBuffers returned error 6 hidp.c:1418: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1423: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1424: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1429: Test failed: id 0: got error 5 hidp.c:1434: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1435: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1439: Test failed: id 0: HidD_SetNumInputBuffers failed last error 6 hidp.c:1444: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1445: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:1449: Test failed: id 0: HidD_GetNumInputBuffers failed last error 6 hidp.c:1450: Test failed: id 0: HidD_GetNumInputBuffers returned 3735928559 hidp.c:402: Test failed: id 0: HidD_GetPreparsedData failed with error 6 1ecc:hidp: unhandled exception c0000005 at 00007FFA42D415FC
=== w7u_adm (32 bit report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl is missing some skip messages
=== w8adm (32 bit report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl is missing some skip messages
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=96735
Your paranoid android.
=== w7u_adm (32 bit report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl is missing some skip messages
=== w8adm (32 bit report) ===
Report validation errors: ntoskrnl.exe:ntoskrnl is missing some skip messages