Wine-devel
Threads by month
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
August 2021
- 78 participants
- 929 discussions
30 Aug '21
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/gdi32/font.c | 61 +++------------------------------
dlls/gdi32/gdi32.spec | 2 +-
dlls/gdi32/text.c | 19 +++++++++-
dlls/gdi32/uniscribe/opentype.c | 2 +-
dlls/gdi32/uniscribe/shape.c | 30 ++++++++--------
dlls/gdi32/uniscribe/usp10.c | 5 +--
include/ntgdi.h | 2 ++
7 files changed, 46 insertions(+), 75 deletions(-)
2
1
[PATCH] kernelbase: Mind OS version in the PE header when reporting OS version.
by Paul Gofman 30 Aug '21
by Paul Gofman 30 Aug '21
30 Aug '21
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/kernel32/tests/version.c | 175 ++++++++++++++++++++++++++++++++++
dlls/kernelbase/version.c | 34 ++++++-
2 files changed, 205 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/tests/version.c b/dlls/kernel32/tests/version.c
index 835c5398685..ad87bb38a16 100644
--- a/dlls/kernel32/tests/version.c
+++ b/dlls/kernel32/tests/version.c
@@ -918,13 +918,188 @@ static void test_PackageIdFromFullName(void)
ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %u.\n", ret);
}
+#define TEST_VERSION_WIN7 1
+#define TEST_VERSION_WIN8 2
+#define TEST_VERSION_WIN8_1 4
+#define TEST_VERSION_WIN10 8
+
+static const struct
+{
+ unsigned int pe_version_major, pe_version_minor;
+ unsigned int manifest_versions;
+ unsigned int expected_major, expected_minor;
+}
+test_pe_os_version_tests[] =
+{
+ { 4, 0, 0, 6, 2},
+ { 4, 0, TEST_VERSION_WIN10, 10, 0},
+ { 6, 3, TEST_VERSION_WIN8, 6, 2},
+ {10, 0, 0, 10, 0},
+ { 6, 3, 0, 6, 3},
+ { 6, 4, 0, 6, 3},
+ { 9, 0, 0, 6, 3},
+ {11, 0, 0, 10, 0},
+ {10, 0,
+ TEST_VERSION_WIN7 | TEST_VERSION_WIN8 | TEST_VERSION_WIN8_1,
+ 6, 3},
+};
+
+static void test_pe_os_version_child(unsigned int test)
+{
+ OSVERSIONINFOEXA info;
+ BOOL ret;
+
+ info.dwOSVersionInfoSize = sizeof(info);
+ ret = GetVersionExA((OSVERSIONINFOA *)&info);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ ok(info.dwMajorVersion == test_pe_os_version_tests[test].expected_major,
+ "Test %u, expected major version %u, got %u.\n", test, test_pe_os_version_tests[test].expected_major,
+ info.dwMajorVersion);
+ ok(info.dwMinorVersion == test_pe_os_version_tests[test].expected_minor,
+ "Test %u, expected minor version %u, got %u.\n", test, test_pe_os_version_tests[test].expected_minor,
+ info.dwMinorVersion);
+}
+
+static void test_pe_os_version(void)
+{
+ static const char manifest_header[] =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
+ "<assembly manifestVersion=\"1.0\" xmlns=\"urn:schemas-microsoft-com:asm.v1\""
+ " xmlns:asmv3=\"urn:schemas-microsoft-com:asm.v3\">\n"
+ "\t<compatibility xmlns=\"urn:schemas-microsoft-com:compatibility.v1\">\n"
+ "\t\t<application>\n";
+ static const char manifest_footer[] =
+ "\t\t</application>\n"
+ "\t</compatibility>\n"
+ "</assembly>\n";
+ static const char *version_guids[] =
+ {
+ "{35138b9a-5d96-4fbd-8e2d-a2440225f93a}",
+ "{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}",
+ "{1f676c76-80e1-4239-95bb-83d0f6d0da78}",
+ "{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}",
+ };
+ LONG hdr_offset, offset_major, offset_minor;
+ char str[MAX_PATH], tmp_exe_name[9];
+ RTL_OSVERSIONINFOEXW rtlinfo;
+ STARTUPINFOA si = { 0 };
+ PROCESS_INFORMATION pi;
+ DWORD result, code;
+ unsigned int i, j;
+ HANDLE file;
+ char **argv;
+ DWORD size;
+ BOOL ret;
+
+ winetest_get_mainargs( &argv );
+
+ if (!pRtlGetVersion)
+ {
+ win_skip("RtlGetVersion is not supported, skipping tests.\n");
+ return;
+ }
+
+ rtlinfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
+ ok(!pRtlGetVersion(&rtlinfo), "RtlGetVersion failed.\n");
+ if (rtlinfo.dwMajorVersion < 10)
+ {
+ skip("Too old Windows version %u.%u, skipping tests.\n", rtlinfo.dwMajorVersion, rtlinfo.dwMinorVersion);
+ return;
+ }
+
+ file = CreateFileA(argv[0], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+ ok(file != INVALID_HANDLE_VALUE, "CreateFile failed, GetLastError() %u.\n", GetLastError());
+ SetFilePointer(file, 0x3c, NULL, FILE_BEGIN);
+ ReadFile(file, &hdr_offset, sizeof(hdr_offset), &size, NULL);
+ CloseHandle(file);
+
+ offset_major = hdr_offset + FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader)
+ + FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, MajorOperatingSystemVersion);
+ offset_minor = hdr_offset + FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader)
+ + FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, MinorOperatingSystemVersion);
+
+ si.cb = sizeof(si);
+
+ for (i = 0; i < ARRAY_SIZE(test_pe_os_version_tests); ++i)
+ {
+ sprintf(tmp_exe_name, "tmp%u.exe", i);
+ ret = CopyFileA(argv[0], tmp_exe_name, FALSE);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+
+ file = CreateFileA(tmp_exe_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
+ ok(file != INVALID_HANDLE_VALUE, "CreateFile failed, GetLastError() %u.\n", GetLastError());
+
+ SetFilePointer(file, offset_major, NULL, FILE_BEGIN);
+ WriteFile(file, &test_pe_os_version_tests[i].pe_version_major,
+ sizeof(test_pe_os_version_tests[i].pe_version_major), &size, NULL);
+ SetFilePointer(file, offset_minor, NULL, FILE_BEGIN);
+ WriteFile(file, &test_pe_os_version_tests[i].pe_version_minor,
+ sizeof(test_pe_os_version_tests[i].pe_version_minor), &size, NULL);
+
+ CloseHandle(file);
+
+ sprintf(str, "%s.manifest", tmp_exe_name);
+ file = CreateFileA(str, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ ok(file != INVALID_HANDLE_VALUE, "CreateFile failed, GetLastError() %u.\n", GetLastError());
+
+ WriteFile(file, manifest_header, strlen(manifest_header), &size, NULL);
+ for (j = 0; j < ARRAY_SIZE(version_guids); ++j)
+ {
+ if (test_pe_os_version_tests[i].manifest_versions & (1 << j))
+ {
+ sprintf(str, "\t\t\t<supportedOS Id=\"%s\"/>\n", version_guids[j]);
+ WriteFile(file, str, strlen(str), &size, NULL);
+ }
+ }
+ WriteFile(file, manifest_footer, strlen(manifest_footer), &size, NULL);
+
+ CloseHandle(file);
+
+ sprintf(str, "%s version pe_os_version %u", tmp_exe_name, i);
+
+ ret = CreateProcessA(NULL, str, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ CloseHandle(pi.hThread);
+ result = WaitForSingleObject(pi.hProcess, 10000);
+ ok(result == WAIT_OBJECT_0, "Got unexpected result %#x.\n", result);
+
+ ret = GetExitCodeProcess(pi.hProcess, &code);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ ok(!code, "Test %u failed.\n", i);
+
+ CloseHandle(pi.hProcess);
+
+ DeleteFileA(tmp_exe_name);
+ sprintf(str, "%s.manifest", tmp_exe_name);
+ DeleteFileA(str);
+ }
+}
+
START_TEST(version)
{
+ char **argv;
+ int argc;
+
+ argc = winetest_get_mainargs( &argv );
+
init_function_pointers();
+ if (argc >= 4)
+ {
+ if (!strcmp(argv[2], "pe_os_version"))
+ {
+ unsigned int test;
+
+ test = atoi(argv[3]);
+ test_pe_os_version_child(test);
+ }
+ return;
+ }
+
test_GetProductInfo();
test_GetVersionEx();
test_VerifyVersionInfo();
+ test_pe_os_version();
test_GetSystemFirmwareTable();
test_PackageIdFromFullName();
}
diff --git a/dlls/kernelbase/version.c b/dlls/kernelbase/version.c
index a5a1f67087f..d670df27690 100644
--- a/dlls/kernelbase/version.c
+++ b/dlls/kernelbase/version.c
@@ -127,10 +127,17 @@ typedef struct
/***********************************************************************
- * Win8 info, reported if app doesn't provide compat GUID in manifest.
+ * Win8 info, reported if the app doesn't provide compat GUID in the manifest and
+ * doesn't have higher OS version in PE header.
*/
static const struct version_info windows8_version_info = { 6, 2, 0x23f0 };
+/***********************************************************************
+ * Win8.1 info, reported if the app doesn't provide compat GUID in the manifest and
+ * OS version in PE header is 8.1 or higher but below 10.
+ */
+static const struct version_info windows8_1_version_info = { 6, 3, 0x2580 };
+
/***********************************************************************
* Windows versions that need compatibility GUID specified in manifest
@@ -161,7 +168,8 @@ static const struct
* Initialize the current_version variable.
*
* For compatibility, Windows 8.1 and later report Win8 version unless the app
- * has a manifest that confirms its compatibility with newer versions of Windows.
+ * has a manifest or higher OS version in the PE optional header
+ * that confirms its compatibility with newer versions of Windows.
*
*/
static RTL_OSVERSIONINFOEXW current_version;
@@ -173,7 +181,9 @@ static BOOL CALLBACK init_current_version(PINIT_ONCE init_once, PVOID parameter,
DWORD ElementCount;
COMPATIBILITY_CONTEXT_ELEMENT Elements[1];
} *acci;
+ BOOL have_os_compat_elements = FALSE;
const struct version_info *ver;
+ IMAGE_NT_HEADERS *nt;
SIZE_T req;
int idx;
@@ -209,8 +219,12 @@ static BOOL CALLBACK init_current_version(PINIT_ONCE init_once, PVOID parameter,
for (i = 0; i < acci->ElementCount; i++)
{
- if (acci->Elements[i].Type == ACTCTX_COMPATIBILITY_ELEMENT_TYPE_OS &&
- IsEqualGUID(&acci->Elements[i].Id, &version_data[idx].guid))
+ if (acci->Elements[i].Type != ACTCTX_COMPATIBILITY_ELEMENT_TYPE_OS)
+ continue;
+
+ have_os_compat_elements = TRUE;
+
+ if (IsEqualGUID(&acci->Elements[i].Id, &version_data[idx].guid))
{
ver = &version_data[idx].info;
@@ -227,6 +241,18 @@ static BOOL CALLBACK init_current_version(PINIT_ONCE init_once, PVOID parameter,
HeapFree(GetProcessHeap(), 0, acci);
done:
+ if (!have_os_compat_elements && current_version.dwMajorVersion >= 10
+ && (nt = RtlImageNtHeader(NtCurrentTeb()->Peb->ImageBaseAddress))
+ && (nt->OptionalHeader.MajorOperatingSystemVersion > 6
+ || (nt->OptionalHeader.MajorOperatingSystemVersion == 6
+ && nt->OptionalHeader.MinorOperatingSystemVersion >= 3)))
+ {
+ if (current_version.dwMajorVersion > 10)
+ FIXME("Unsupported current_version.dwMajorVersion %u.\n", current_version.dwMajorVersion);
+
+ ver = nt->OptionalHeader.MajorOperatingSystemVersion >= 10 ? NULL : &windows8_1_version_info;
+ }
+
if (ver)
{
current_version.dwMajorVersion = ver->major;
--
2.31.1
1
0
[PATCH v2 1/3] ntoskrnl.exe/tests: Move driver testing helpers to a separate file.
by Rémi Bernon 30 Aug '21
by Rémi Bernon 30 Aug '21
30 Aug '21
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
Supersedes: 212831-212833
v2: * Use the caller source location for skip messages.
* Drop the symlink remove patch, seems like it was actually used.
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..751b2f9b208
--- /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)
+ {
+ winetest_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)
+ {
+ winetest_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);
}
--
2.33.0
2
5
30 Aug '21
Allocated on the caller side.
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/winebus.sys/main.c | 13 ++++++++++++-
dlls/winebus.sys/unixlib.h | 10 ++++++++++
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c
index e9c85deb846..973931fe517 100644
--- a/dlls/winebus.sys/main.c
+++ b/dlls/winebus.sys/main.c
@@ -632,6 +632,7 @@ struct bus_main_params
HANDLE init_done;
unsigned int init_code;
unsigned int wait_code;
+ struct bus_event *bus_event;
};
static DWORD CALLBACK bus_main_thread(void *args)
@@ -644,11 +645,13 @@ static DWORD CALLBACK bus_main_thread(void *args)
SetEvent(bus.init_done);
TRACE("%s main loop started\n", debugstr_w(bus.name));
+ bus.bus_event->type = BUS_EVENT_TYPE_NONE;
if (status) WARN("%s bus init returned status %#x\n", debugstr_w(bus.name), status);
- else status = winebus_call(bus.wait_code, NULL);
+ else while ((status = winebus_call(bus.wait_code, bus.bus_event)) == STATUS_PENDING) {}
if (status) WARN("%s bus wait returned status %#x\n", debugstr_w(bus.name), status);
else TRACE("%s main loop exited\n", debugstr_w(bus.name));
+ HeapFree(GetProcessHeap(), 0, bus.bus_event);
return status;
}
@@ -663,6 +666,14 @@ static NTSTATUS bus_main_thread_start(struct bus_main_params *bus)
return STATUS_UNSUCCESSFUL;
}
+ if (!(bus->bus_event = HeapAlloc(GetProcessHeap(), 0, sizeof(struct bus_event))))
+ {
+ ERR("failed to allocate %s bus event.\n", debugstr_w(bus->name));
+ CloseHandle(bus->init_done);
+ bus_count--;
+ return STATUS_UNSUCCESSFUL;
+ }
+
if (!(bus_thread[i] = CreateThread(NULL, 0, bus_main_thread, bus, 0, NULL)))
{
ERR("failed to create %s bus thread.\n", debugstr_w(bus->name));
diff --git a/dlls/winebus.sys/unixlib.h b/dlls/winebus.sys/unixlib.h
index c0de991d20a..e6abd98601f 100644
--- a/dlls/winebus.sys/unixlib.h
+++ b/dlls/winebus.sys/unixlib.h
@@ -46,6 +46,16 @@ struct iohid_bus_options
struct unix_device;
+enum bus_event_type
+{
+ BUS_EVENT_TYPE_NONE,
+};
+
+struct bus_event
+{
+ enum bus_event_type type;
+};
+
enum unix_funcs
{
sdl_init,
--
2.33.0
1
4
[PATCH 1/4] ntoskrnl.exe/tests: Move driver testing helpers to a separate file.
by Rémi Bernon 30 Aug '21
by Rémi Bernon 30 Aug '21
30 Aug '21
Signed-off-by: Rémi Bernon <rbernon(a)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);
}
--
2.33.0
2
7
Signed-off-by: Georg Lehmann <dadschoorse(a)gmail.com>
---
dlls/winevulkan/make_vulkan | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
index ef4693651d2..ac1b43bbf12 100755
--- a/dlls/winevulkan/make_vulkan
+++ b/dlls/winevulkan/make_vulkan
@@ -64,7 +64,7 @@ from enum import Enum
LOGGER = logging.Logger("vulkan")
LOGGER.addHandler(logging.StreamHandler())
-VK_XML_VERSION = "1.2.188"
+VK_XML_VERSION = "1.2.190"
WINE_VK_VERSION = (1, 2)
# Filenames to create.
--
2.33.0
1
0
30 Aug '21
1
0
The following series implements various bug fixes, as well as improved
support for various debug info (enum types, compiland, module...).
---
Eric Pouech (11):
dbghelp: fix NameLen usage in SYMBOL_INFO(W)
dbghelp: fills more fields in SYMBOL_INFO in SymGetTypeFromName
dbghelp: fix two internal buffer allocations
dbghelp: correctly store and report bitfield information
dbghelp: introducing internal type (symt_module) to match SymTagExe
dbghelp: now returning the stored name for a compiland
dbghelp: return the symt_module when requesting lexical parent of an UDT
dbghelp: enum:s should be found by name (as UDT:s are)
dbghelp: return the correct length for an enumeration
dbghelp: return a lexical parent for enums (as we do for UDT:s)
dbghelp: added missing break statement
dlls/dbghelp/dbghelp_private.h | 17 +++++++++--
dlls/dbghelp/dwarf.c | 2 +-
dlls/dbghelp/module.c | 3 ++
dlls/dbghelp/msc.c | 8 +++---
dlls/dbghelp/stabs.c | 12 ++------
dlls/dbghelp/symbol.c | 25 ++++++++++++----
dlls/dbghelp/type.c | 52 +++++++++++++++++++++++++++-------
7 files changed, 84 insertions(+), 35 deletions(-)
1
11
Signed-off-by: Anton Baskanov <baskanov(a)gmail.com>
---
dlls/quartz/vmr9.c | 60 +++++++++++++++++++++++++++-------------------
1 file changed, 35 insertions(+), 25 deletions(-)
diff --git a/dlls/quartz/vmr9.c b/dlls/quartz/vmr9.c
index 2562b74932a..546af3d2a39 100644
--- a/dlls/quartz/vmr9.c
+++ b/dlls/quartz/vmr9.c
@@ -206,6 +206,37 @@ static inline struct quartz_vmr *impl_from_IBaseFilter(IBaseFilter *iface)
return CONTAINING_RECORD(iface, struct quartz_vmr, renderer.filter.IBaseFilter_iface);
}
+static void copy_plane(int height, int row_size, int src_pitch, int dst_pitch, BYTE *src, BYTE *dst)
+{
+ BYTE *row_src;
+ BYTE *row_dst;
+ int row;
+
+ if (src_pitch >= 0)
+ {
+ if (src_pitch == dst_pitch)
+ {
+ memcpy(dst, src, src_pitch * height);
+ return;
+ }
+ TRACE("Source pitch %d does not match dest pitch %d; copying manually.\n",
+ src_pitch, dst_pitch);
+ }
+ else
+ {
+ TRACE("Inverting image.\n");
+ }
+
+ row_src = src;
+ row_dst = dst;
+ for (row = 0; row < height; ++row)
+ {
+ memcpy(row_dst, row_src, row_size);
+ row_src += src_pitch;
+ row_dst += dst_pitch;
+ }
+}
+
static HRESULT vmr_render(struct strmbase_renderer *iface, IMediaSample *sample)
{
struct quartz_vmr *filter = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface);
@@ -273,34 +304,13 @@ static HRESULT vmr_render(struct strmbase_renderer *iface, IMediaSample *sample)
if (height > 0 && bitmap_header->biCompression == BI_RGB)
{
- BYTE *dst = (BYTE *)locked_rect.pBits + (height * locked_rect.Pitch);
- const BYTE *src = data;
-
- TRACE("Inverting image.\n");
-
- while (height--)
- {
- dst -= locked_rect.Pitch;
- memcpy(dst, src, width * depth / 8);
- src += src_pitch;
- }
+ copy_plane(height, width * depth / 8, -(int)src_pitch, locked_rect.Pitch,
+ data + src_pitch * (height - 1), locked_rect.pBits);
}
else if (locked_rect.Pitch != src_pitch)
{
- BYTE *dst = locked_rect.pBits;
- const BYTE *src = data;
-
- height = abs(height);
-
- TRACE("Source pitch %u does not match dest pitch %u; copying manually.\n",
- src_pitch, locked_rect.Pitch);
-
- while (height--)
- {
- memcpy(dst, src, width * depth / 8);
- src += src_pitch;
- dst += locked_rect.Pitch;
- }
+ copy_plane(abs(height), width * depth / 8, src_pitch, locked_rect.Pitch,
+ data, locked_rect.pBits);
}
else
{
--
2.25.1
1
3
Fixes a regression introduced by 76f949577aac88bbde4e9e7b904587f5bc8c808d.
nt_name or redir is used in open_unix_file() because attr.ObjectName
points to either of them.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51702
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/ntdll/unix/process.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
1
0