mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Added patches to implement ntoskrnl driver testing framework.
This commit is contained in:
parent
1d5798b7d0
commit
29bbba1e0f
@ -37,7 +37,7 @@ Wine. All those differences are also documented on the
|
||||
Included bug fixes and improvements
|
||||
===================================
|
||||
|
||||
**Bugfixes and features included in the next upcoming release [18]:**
|
||||
**Bugfixes and features included in the next upcoming release [19]:**
|
||||
|
||||
* Add stub for KeWaitForMultipleObjects
|
||||
* Add stubs for D3DXCreateAnimationController interface
|
||||
@ -50,6 +50,7 @@ Included bug fixes and improvements
|
||||
* Fix init of LONGLONG variable with a negative value in TGA decoder
|
||||
* Fix wrong colors in Wolfenstein (2009) ([Wine Bug #34692](https://bugs.winehq.org/show_bug.cgi?id=34692))
|
||||
* Graphical issues in Inquisitor ([Wine Bug #32490](https://bugs.winehq.org/show_bug.cgi?id=32490))
|
||||
* Implement ntoskrnl driver testing framework.
|
||||
* Implement semi-stub for IDirectPlayVoiceClient::GetCompressionTypes ([Wine Bug #29238](https://bugs.winehq.org/show_bug.cgi?id=29238))
|
||||
* Multiple applications start wrong executable if whitespace present in name ([Wine Bug #19666](https://bugs.winehq.org/show_bug.cgi?id=19666))
|
||||
* Port Royale doesn't display ocean correctly ([Wine Bug #17913](https://bugs.winehq.org/show_bug.cgi?id=17913))
|
||||
|
1
debian/changelog
vendored
1
debian/changelog
vendored
@ -14,6 +14,7 @@ wine-staging (1.7.35) UNRELEASED; urgency=low
|
||||
* Added patch to implement stubs for D3DXCreateAnimationController interface.
|
||||
* Added patch to implement semi-stub for IDirectPlayVoiceClient::GetCompressionTypes.
|
||||
* Added patch to fix cursor clip regression / broken raw input in multiple games.
|
||||
* Added patches to implement ntoskrnl driver testing framework.
|
||||
* Removed patch to fix RandR on some broken nVidia systems (accepted upstream).
|
||||
* Removed patch to set last error on success in WSARecv (accepted upstream).
|
||||
* Removed patch to fix handling of subdirectory in FtpFindFirstFile (accepted upstream).
|
||||
|
@ -11,14 +11,12 @@ diff --git a/tools/makedep.c b/tools/makedep.c
|
||||
index 54aab45..d68bc03 100644
|
||||
--- a/tools/makedep.c
|
||||
+++ b/tools/makedep.c
|
||||
@@ -161,6 +161,7 @@ struct makefile
|
||||
const char *top_src_dir;
|
||||
@@ -162,4 +162,5 @@ struct makefile
|
||||
const char *top_obj_dir;
|
||||
const char *parent_dir;
|
||||
+ const char *parent_spec;
|
||||
const char *module;
|
||||
const char *testdll;
|
||||
const char *staticlib;
|
||||
@@ -2081,7 +2082,13 @@ static struct strarray output_sources( struct makefile *make, struct strarray *t
|
||||
char *spec_file = NULL;
|
||||
|
||||
@ -34,14 +32,12 @@ index 54aab45..d68bc03 100644
|
||||
for (i = 0; i < make->delayimports.count; i++)
|
||||
strarray_add( &all_libs, strmake( "-l%s", make->delayimports.str[i] ));
|
||||
for (i = 0; i < make->imports.count; i++)
|
||||
@@ -2597,6 +2604,7 @@ static void update_makefile( const char *path )
|
||||
strarray_set_value( &make->vars, "srcdir", src_dir_path( make, "" ));
|
||||
@@ -2598,4 +2605,5 @@ static void update_makefile( const char *path )
|
||||
|
||||
make->parent_dir = get_expanded_make_variable( make, "PARENTSRC" );
|
||||
+ make->parent_spec = get_expanded_make_variable( make, "PARENTSPEC" );
|
||||
make->module = get_expanded_make_variable( make, "MODULE" );
|
||||
make->testdll = get_expanded_make_variable( make, "TESTDLL" );
|
||||
make->staticlib = get_expanded_make_variable( make, "STATICLIB" );
|
||||
--
|
||||
2.1.3
|
||||
|
||||
|
@ -0,0 +1,785 @@
|
||||
From daa8ccd8d94c1e8c53d26b2e985d75c7c7a47f1b Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sun, 18 Jan 2015 05:42:10 +0100
|
||||
Subject: ntoskrnl.exe/tests: Add initial driver testing framework and
|
||||
corrsponding changes to Makefile system. (rev 2)
|
||||
|
||||
---
|
||||
aclocal.m4 | 31 +++
|
||||
configure.ac | 2 +
|
||||
dlls/ntoskrnl.exe/tests/Makefile.in | 8 +
|
||||
dlls/ntoskrnl.exe/tests/driver.sys/Makefile.in | 11 +
|
||||
dlls/ntoskrnl.exe/tests/driver.sys/driver.c | 130 ++++++++++++
|
||||
dlls/ntoskrnl.exe/tests/driver.sys/driver.h | 28 +++
|
||||
dlls/ntoskrnl.exe/tests/driver.sys/driver.sys.spec | 1 +
|
||||
dlls/ntoskrnl.exe/tests/ntoskrnl.c | 226 +++++++++++++++++++++
|
||||
tools/make_makefiles | 9 +-
|
||||
tools/makedep.c | 174 +++++++++++++++-
|
||||
10 files changed, 617 insertions(+), 3 deletions(-)
|
||||
create mode 100644 dlls/ntoskrnl.exe/tests/Makefile.in
|
||||
create mode 100644 dlls/ntoskrnl.exe/tests/driver.sys/Makefile.in
|
||||
create mode 100644 dlls/ntoskrnl.exe/tests/driver.sys/driver.c
|
||||
create mode 100644 dlls/ntoskrnl.exe/tests/driver.sys/driver.h
|
||||
create mode 100644 dlls/ntoskrnl.exe/tests/driver.sys/driver.sys.spec
|
||||
create mode 100644 dlls/ntoskrnl.exe/tests/ntoskrnl.c
|
||||
|
||||
diff --git a/aclocal.m4 b/aclocal.m4
|
||||
index 3d43721..adc6b04 100644
|
||||
--- a/aclocal.m4
|
||||
+++ b/aclocal.m4
|
||||
@@ -617,6 +617,28 @@ $ac_dir/crosstest: $ac_dir/Makefile __builddeps__ dummy
|
||||
fi
|
||||
}
|
||||
|
||||
+wine_fn_config_resource ()
|
||||
+{
|
||||
+ ac_dir=$[1]
|
||||
+ ac_name=$[2]
|
||||
+ ac_flags=$[3]
|
||||
+ ac_dll=$ac_name
|
||||
+
|
||||
+ case $ac_name in
|
||||
+ *.*) ;;
|
||||
+ *) ac_dll=$ac_dll.dll ;;
|
||||
+ esac
|
||||
+
|
||||
+ ac_clean=
|
||||
+ test -n "$CROSSTARGET" && ac_clean=`expr $ac_dir/$ac_dll : "\\(.*\\)\\."`_crossres.`expr $ac_dll : ".*\\.\\(.*\\)"`
|
||||
+ test -n "$DLLEXT" || ac_clean="$ac_dir/$ac_dll"
|
||||
+
|
||||
+ AS_VAR_IF([enable_tests],[no],[wine_fn_disabled_rules $ac_clean; return])
|
||||
+
|
||||
+ wine_fn_depend_rules
|
||||
+ wine_fn_clean_rules $ac_clean
|
||||
+}
|
||||
+
|
||||
wine_fn_config_tool ()
|
||||
{
|
||||
ac_dir=$[1]
|
||||
@@ -722,6 +744,15 @@ wine_fn_config_test $1 ac_name[]ac_suffix [$2]dnl
|
||||
m4_popdef([ac_suffix])dnl
|
||||
m4_popdef([ac_name])])
|
||||
|
||||
+dnl **** Create a test resource makefile from config.status ****
|
||||
+dnl
|
||||
+dnl Usage: WINE_CONFIG_RESOURCE(dir,flags)
|
||||
+dnl
|
||||
+AC_DEFUN([WINE_CONFIG_RESOURCE],[AC_REQUIRE([WINE_CONFIG_HELPERS])dnl
|
||||
+m4_pushdef([ac_name],[m4_bpatsubst([$1],[.*/\([^/\]*\)$],[\1])])dnl
|
||||
+wine_fn_config_resource $1 ac_name [$2]dnl
|
||||
+m4_popdef([ac_name])])
|
||||
+
|
||||
dnl **** Create a static lib makefile from config.status ****
|
||||
dnl
|
||||
dnl Usage: WINE_CONFIG_LIB(name,flags)
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index ab8945a..dfc3d07 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -3126,4 +3126,6 @@ WINE_CONFIG_DLL(ntdsapi,,[implib])
|
||||
WINE_CONFIG_TEST(dlls/ntdsapi/tests)
|
||||
WINE_CONFIG_DLL(ntoskrnl.exe,,[implib])
|
||||
+WINE_CONFIG_TEST(dlls/ntoskrnl.exe/tests)
|
||||
+WINE_CONFIG_RESOURCE(dlls/ntoskrnl.exe/tests/driver.sys)
|
||||
WINE_CONFIG_DLL(ntprint)
|
||||
WINE_CONFIG_TEST(dlls/ntprint/tests)
|
||||
diff --git a/dlls/ntoskrnl.exe/tests/Makefile.in b/dlls/ntoskrnl.exe/tests/Makefile.in
|
||||
new file mode 100644
|
||||
index 0000000..f0c2460
|
||||
--- /dev/null
|
||||
+++ b/dlls/ntoskrnl.exe/tests/Makefile.in
|
||||
@@ -0,0 +1,8 @@
|
||||
+TESTDLL = ntoskrnl.exe
|
||||
+IMPORTS = advapi32
|
||||
+
|
||||
+C_SRCS = \
|
||||
+ ntoskrnl.c
|
||||
+
|
||||
+RC_DLLS = \
|
||||
+ driver.sys
|
||||
diff --git a/dlls/ntoskrnl.exe/tests/driver.sys/Makefile.in b/dlls/ntoskrnl.exe/tests/driver.sys/Makefile.in
|
||||
new file mode 100644
|
||||
index 0000000..bc040e4
|
||||
--- /dev/null
|
||||
+++ b/dlls/ntoskrnl.exe/tests/driver.sys/Makefile.in
|
||||
@@ -0,0 +1,11 @@
|
||||
+RESOURCE = driver.sys
|
||||
+IMPORTS = ntoskrnl.exe
|
||||
+
|
||||
+WINEFLAGS = -Wb,--subsystem,native
|
||||
+CROSSFLAGS = -nostartfiles -nostdlib -nodefaultlibs \
|
||||
+ -Wl,--subsystem,native \
|
||||
+ -Wl,--image-base,0x10000 \
|
||||
+ -Wl,-entry,_DriverEntry@8
|
||||
+
|
||||
+C_SRCS = \
|
||||
+ driver.c
|
||||
diff --git a/dlls/ntoskrnl.exe/tests/driver.sys/driver.c b/dlls/ntoskrnl.exe/tests/driver.sys/driver.c
|
||||
new file mode 100644
|
||||
index 0000000..5756090
|
||||
--- /dev/null
|
||||
+++ b/dlls/ntoskrnl.exe/tests/driver.sys/driver.c
|
||||
@@ -0,0 +1,130 @@
|
||||
+/*
|
||||
+ * ntoskrnl.exe testing framework
|
||||
+ *
|
||||
+ * Copyright 2015 Sebastian Lackner
|
||||
+ * Copyright 2015 Michael Müller
|
||||
+ * Copyright 2015 Christian Costa
|
||||
+ *
|
||||
+ * 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 "ntstatus.h"
|
||||
+#define WIN32_NO_STATUS
|
||||
+#include "windef.h"
|
||||
+#include "winbase.h"
|
||||
+#include "winternl.h"
|
||||
+#include "winioctl.h"
|
||||
+#include "ddk/wdm.h"
|
||||
+
|
||||
+#include "driver.h"
|
||||
+
|
||||
+const WCHAR driver_device[] = {'\\','D','e','v','i','c','e',
|
||||
+ '\\','W','i','n','e','T','e','s','t','D','r','i','v','e','r',0};
|
||||
+const WCHAR driver_link[] = {'\\','D','o','s','D','e','v','i','c','e','s',
|
||||
+ '\\','W','i','n','e','T','e','s','t','D','r','i','v','e','r',0};
|
||||
+
|
||||
+
|
||||
+static NTSTATUS test_basic_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
|
||||
+{
|
||||
+ const char str[] = "Wine is not an emulator";
|
||||
+ ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
+ char *buffer = irp->AssociatedIrp.SystemBuffer;
|
||||
+ int i;
|
||||
+
|
||||
+ if (!buffer)
|
||||
+ return STATUS_ACCESS_VIOLATION;
|
||||
+
|
||||
+ if (length < sizeof(str)-1)
|
||||
+ return STATUS_BUFFER_TOO_SMALL;
|
||||
+
|
||||
+ for (i = 0; i < sizeof(str)-1; i++)
|
||||
+ buffer[i] = str[i];
|
||||
+
|
||||
+ *info = sizeof(str)-1;
|
||||
+ return STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static NTSTATUS WINAPI driver_Create(DEVICE_OBJECT *device, IRP *irp)
|
||||
+{
|
||||
+ return STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static NTSTATUS WINAPI driver_IoControl(DEVICE_OBJECT *device, IRP *irp)
|
||||
+{
|
||||
+ IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp);
|
||||
+ NTSTATUS status = STATUS_NOT_SUPPORTED;
|
||||
+ ULONG_PTR information = 0;
|
||||
+
|
||||
+ switch (stack->Parameters.DeviceIoControl.IoControlCode)
|
||||
+ {
|
||||
+ case IOCTL_WINETEST_BASIC_IOCTL:
|
||||
+ status = test_basic_ioctl(irp, stack, &information);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ irp->IoStatus.Status = status;
|
||||
+ irp->IoStatus.Information = information;
|
||||
+ IoCompleteRequest(irp, IO_NO_INCREMENT);
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+static NTSTATUS WINAPI driver_Close(DEVICE_OBJECT *device, IRP *irp)
|
||||
+{
|
||||
+ return STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static VOID WINAPI driver_Unload(DRIVER_OBJECT *driver)
|
||||
+{
|
||||
+ UNICODE_STRING linkW;
|
||||
+
|
||||
+ DbgPrint("unloading driver\n");
|
||||
+
|
||||
+ RtlInitUnicodeString(&linkW, driver_link);
|
||||
+ IoDeleteSymbolicLink(&linkW);
|
||||
+
|
||||
+ IoDeleteDevice(driver->DeviceObject);
|
||||
+}
|
||||
+
|
||||
+NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, PUNICODE_STRING registry)
|
||||
+{
|
||||
+ UNICODE_STRING nameW, linkW;
|
||||
+ DEVICE_OBJECT *device;
|
||||
+ NTSTATUS status;
|
||||
+
|
||||
+ DbgPrint("loading driver\n");
|
||||
+
|
||||
+ /* Allow unloading of the driver */
|
||||
+ driver->DriverUnload = driver_Unload;
|
||||
+
|
||||
+ /* Set driver functions */
|
||||
+ driver->MajorFunction[IRP_MJ_CREATE] = driver_Create;
|
||||
+ driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = driver_IoControl;
|
||||
+ driver->MajorFunction[IRP_MJ_CLOSE] = driver_Close;
|
||||
+
|
||||
+ RtlInitUnicodeString(&nameW, driver_device);
|
||||
+ RtlInitUnicodeString(&linkW, driver_link);
|
||||
+
|
||||
+ if (!(status = IoCreateDevice(driver, 0, &nameW, FILE_DEVICE_UNKNOWN,
|
||||
+ FILE_DEVICE_SECURE_OPEN, FALSE, &device)))
|
||||
+ status = IoCreateSymbolicLink(&linkW, &nameW);
|
||||
+
|
||||
+ return status;
|
||||
+}
|
||||
diff --git a/dlls/ntoskrnl.exe/tests/driver.sys/driver.h b/dlls/ntoskrnl.exe/tests/driver.sys/driver.h
|
||||
new file mode 100644
|
||||
index 0000000..372e908
|
||||
--- /dev/null
|
||||
+++ b/dlls/ntoskrnl.exe/tests/driver.sys/driver.h
|
||||
@@ -0,0 +1,28 @@
|
||||
+/*
|
||||
+ * ntoskrnl.exe testing framework
|
||||
+ *
|
||||
+ * Copyright 2015 Sebastian Lackner
|
||||
+ * Copyright 2015 Michael Müller
|
||||
+ * Copyright 2015 Christian Costa
|
||||
+ *
|
||||
+ * 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
|
||||
+ */
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * All custom IOCTLs need to have a function value >= 0x800.
|
||||
+ */
|
||||
+
|
||||
+#define IOCTL_WINETEST_BASIC_IOCTL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
diff --git a/dlls/ntoskrnl.exe/tests/driver.sys/driver.sys.spec b/dlls/ntoskrnl.exe/tests/driver.sys/driver.sys.spec
|
||||
new file mode 100644
|
||||
index 0000000..76421d7
|
||||
--- /dev/null
|
||||
+++ b/dlls/ntoskrnl.exe/tests/driver.sys/driver.sys.spec
|
||||
@@ -0,0 +1 @@
|
||||
+# nothing to export
|
||||
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
|
||||
new file mode 100644
|
||||
index 0000000..9b8a6a7
|
||||
--- /dev/null
|
||||
+++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
|
||||
@@ -0,0 +1,226 @@
|
||||
+/*
|
||||
+ * ntoskrnl.exe testing framework
|
||||
+ *
|
||||
+ * Copyright 2015 Sebastian Lackner
|
||||
+ * Copyright 2015 Michael Müller
|
||||
+ * Copyright 2015 Christian Costa
|
||||
+ *
|
||||
+ * 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 "windows.h"
|
||||
+#include "winsvc.h"
|
||||
+#include "winioctl.h"
|
||||
+#include "wine/test.h"
|
||||
+
|
||||
+#include "driver.sys/driver.h"
|
||||
+
|
||||
+static const char driver_name[] = "WineTestDriver";
|
||||
+static const char device_path[] = "\\\\.\\WineTestDriver";
|
||||
+
|
||||
+/* extracts a driver from a resource to a filename */
|
||||
+static BOOL extract_resource(const char *name, const char *filename)
|
||||
+{
|
||||
+ DWORD size, written = 0;
|
||||
+ HGLOBAL reshandle;
|
||||
+ HRSRC resinfo;
|
||||
+ HANDLE file;
|
||||
+ char *data;
|
||||
+
|
||||
+ resinfo = FindResourceA(NULL, name, (LPCSTR)RT_RCDATA);
|
||||
+ if (!resinfo)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ reshandle = LoadResource(NULL, resinfo);
|
||||
+ if (!reshandle)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ data = LockResource(reshandle);
|
||||
+ if (!data)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ size = SizeofResource(NULL, resinfo);
|
||||
+ if (!size)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ file = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
+ if (file == INVALID_HANDLE_VALUE)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ while (size)
|
||||
+ {
|
||||
+ if (!WriteFile(file, data, size, &written, NULL))
|
||||
+ {
|
||||
+ CloseHandle(file);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ data += written;
|
||||
+ size -= written;
|
||||
+ }
|
||||
+
|
||||
+ CloseHandle(file);
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+static void wait_driver(SC_HANDLE service, SERVICE_STATUS *status)
|
||||
+{
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ Sleep(100);
|
||||
+
|
||||
+ if (!QueryServiceStatus(service, status))
|
||||
+ {
|
||||
+ ok(0, "QueryServiceStatus failed with %x\n", GetLastError());
|
||||
+ status->dwCurrentState = SERVICE_STOPPED;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (status->dwCurrentState != SERVICE_STOP_PENDING &&
|
||||
+ status->dwCurrentState != SERVICE_START_PENDING)
|
||||
+ return;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* unload a driver and delete the temporary file */
|
||||
+static void unload_driver(SC_HANDLE service, const char *filename)
|
||||
+{
|
||||
+ SERVICE_STATUS status;
|
||||
+
|
||||
+ if (service)
|
||||
+ {
|
||||
+ /* Wine specific hack - when the test is the first application
|
||||
+ * in a wineprefix, then the driver will need some time to start up,
|
||||
+ * before we can stop them again. */
|
||||
+ wait_driver(service, &status);
|
||||
+
|
||||
+ ControlService(service, SERVICE_CONTROL_STOP, &status);
|
||||
+ wait_driver(service, &status);
|
||||
+ ok(status.dwCurrentState == SERVICE_STOPPED,
|
||||
+ "expected SERVICE_STOPPED, got %d\n", status.dwCurrentState);
|
||||
+
|
||||
+ DeleteService(service);
|
||||
+ CloseServiceHandle(service);
|
||||
+ }
|
||||
+ if (filename)
|
||||
+ {
|
||||
+ ok(DeleteFileA(filename),
|
||||
+ "DeleteFileA failed with %x\n", GetLastError());
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* load a driver and return the service handle */
|
||||
+static SC_HANDLE load_driver(char *filename)
|
||||
+{
|
||||
+ SC_HANDLE manager, service;
|
||||
+ SERVICE_STATUS status;
|
||||
+ char temp[MAX_PATH];
|
||||
+
|
||||
+ manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
||||
+ if (!manager)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ /* before we start with the actual tests, make sure to terminate
|
||||
+ * any old wine test drivers. */
|
||||
+ service = OpenServiceA(manager, driver_name, SERVICE_ALL_ACCESS);
|
||||
+ if (service) unload_driver(service, NULL);
|
||||
+
|
||||
+ /* extract the new driver which is embedded into a resource */
|
||||
+ GetTempPathA(sizeof(temp), temp);
|
||||
+ GetTempFileNameA(temp, "drv", 0, filename);
|
||||
+
|
||||
+ if (!extract_resource("driver.sys", filename))
|
||||
+ {
|
||||
+ ok(0, "Failed to extract driver resource\n");
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ trace("Trying to load driver %s\n", filename);
|
||||
+
|
||||
+ /* load the new driver */
|
||||
+ service = CreateServiceA(manager, driver_name, driver_name,
|
||||
+ SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER,
|
||||
+ SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
|
||||
+ filename, NULL, NULL, NULL, NULL, NULL);
|
||||
+ if (!service)
|
||||
+ {
|
||||
+ ok(0, "CreateServiceA failed with %x\n", GetLastError());
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ ok(StartServiceA(service, 0, NULL),
|
||||
+ "StartServiceA failed with %x\n", GetLastError());
|
||||
+
|
||||
+ CloseServiceHandle(manager);
|
||||
+
|
||||
+ /* wait for the service to start up properly */
|
||||
+ wait_driver(service, &status);
|
||||
+ ok(status.dwCurrentState == SERVICE_RUNNING,
|
||||
+ "expected SERVICE_RUNNING, got %d\n", status.dwCurrentState);
|
||||
+
|
||||
+ if (status.dwCurrentState != SERVICE_RUNNING)
|
||||
+ {
|
||||
+ unload_driver(service, filename);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return service;
|
||||
+
|
||||
+err:
|
||||
+ CloseServiceHandle(manager);
|
||||
+ unload_driver(NULL, filename);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void test_basic_ioctl(void)
|
||||
+{
|
||||
+ const char str[] = "Wine is not an emulator";
|
||||
+ DWORD bytes_returned;
|
||||
+ char buf[32];
|
||||
+ HANDLE file;
|
||||
+ BOOL res;
|
||||
+
|
||||
+ file = CreateFileA(device_path, GENERIC_READ | GENERIC_WRITE,
|
||||
+ 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
+ if (file == INVALID_HANDLE_VALUE)
|
||||
+ {
|
||||
+ ok(0, "Connecting to driver failed with %x\n", GetLastError());
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ res = DeviceIoControl(file, IOCTL_WINETEST_BASIC_IOCTL, NULL, 0, buf,
|
||||
+ sizeof(buf), &bytes_returned, NULL);
|
||||
+ ok(res, "DeviceIoControl failed with %x\n", GetLastError());
|
||||
+ ok(bytes_returned == sizeof(str)-1, "Unexpected number of bytes\n");
|
||||
+ ok(!memcmp(buf, str, sizeof(str)-1), "Unexpected response data\n");
|
||||
+
|
||||
+ CloseHandle(file);
|
||||
+}
|
||||
+
|
||||
+START_TEST(ntoskrnl)
|
||||
+{
|
||||
+ char filename[MAX_PATH];
|
||||
+ SC_HANDLE service;
|
||||
+
|
||||
+ if (!(service = load_driver(filename)))
|
||||
+ {
|
||||
+ win_skip("Failed to load driver, skipping tests.\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ test_basic_ioctl();
|
||||
+
|
||||
+ unload_driver(service, filename);
|
||||
+}
|
||||
diff --git a/tools/make_makefiles b/tools/make_makefiles
|
||||
index f0b40c0..46b8389 100755
|
||||
--- a/tools/make_makefiles
|
||||
+++ b/tools/make_makefiles
|
||||
@@ -257,7 +257,7 @@ sub parse_makefile($)
|
||||
while (/\\$/) { chop; $_ .= <MAKE>; chomp; } # merge continued lines
|
||||
next if (/^\s*$/);
|
||||
|
||||
- if (/^\s*(MODULE|IMPORTLIB|TESTDLL|PARENTSRC|APPMODE)\s*=\s*(.*)/)
|
||||
+ if (/^\s*(MODULE|IMPORTLIB|TESTDLL|RESOURCE|PARENTSRC|APPMODE)\s*=\s*(.*)/)
|
||||
{
|
||||
my $var = $1;
|
||||
$make{$var} = $2;
|
||||
@@ -476,6 +476,13 @@ sub update_makefiles(@)
|
||||
(my $dir = $file) =~ s/^(.*)\/Makefile/$1/;
|
||||
push @lines, "WINE_CONFIG_TEST($dir$flag_args)\n";
|
||||
}
|
||||
+ elsif (defined($make{"RESOURCE"})) # test resource
|
||||
+ {
|
||||
+ die "MODULE should not be defined in $file" if defined $make{"MODULE"};
|
||||
+ die "STATICLIB should not be defined in $file" if defined $make{"STATICLIB"};
|
||||
+ (my $dir = $file) =~ s/^(.*)\/Makefile/$1/;
|
||||
+ push @lines, "WINE_CONFIG_RESOURCE($dir$flag_args)\n";
|
||||
+ }
|
||||
elsif (defined($make{"MODULE"}) && $make{"MODULE"} =~ /\.a$/) # import lib
|
||||
{
|
||||
die "MODULE should not be defined as static lib in $file" unless $file =~ /^dlls\//;
|
||||
diff --git a/tools/makedep.c b/tools/makedep.c
|
||||
index 54aab45..c9f48fe 100644
|
||||
--- a/tools/makedep.c
|
||||
+++ b/tools/makedep.c
|
||||
@@ -164,4 +164,5 @@ struct makefile
|
||||
const char *module;
|
||||
const char *testdll;
|
||||
+ const char *resource;
|
||||
const char *staticlib;
|
||||
const char *importlib;
|
||||
@@ -466,6 +467,30 @@ static char *get_extension( char *filename )
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
+ * prepend_extension
|
||||
+ */
|
||||
+static char *prepend_extension( const char *name, const char *prepend, const char *new_ext )
|
||||
+{
|
||||
+ int name_len, prepend_len = strlen(prepend);
|
||||
+ const char *ext;
|
||||
+ char *ret;
|
||||
+
|
||||
+ ext = strrchr( name, '.' );
|
||||
+ if (ext && strchr(ext, '/')) ext = NULL;
|
||||
+ name_len = ext ? (ext - name) : strlen( name );
|
||||
+
|
||||
+ if (!ext) ext = new_ext;
|
||||
+ if (!ext) ext = "";
|
||||
+
|
||||
+ ret = xmalloc( name_len + prepend_len + strlen(ext) + 1 );
|
||||
+ memcpy( ret, name, name_len );
|
||||
+ memcpy( ret + name_len, prepend, prepend_len );
|
||||
+ strcpy( ret + name_len + prepend_len, ext );
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*******************************************************************
|
||||
* replace_extension
|
||||
*/
|
||||
static char *replace_extension( const char *name, const char *old_ext, const char *new_ext )
|
||||
@@ -1747,6 +1772,7 @@ static struct strarray output_sources( struct makefile *make, struct strarray *t
|
||||
struct strarray subdirs = empty_strarray;
|
||||
struct strarray phony_targets = empty_strarray;
|
||||
struct strarray all_targets = get_expanded_make_var_array( make, "PROGRAMS" );
|
||||
+ struct strarray resource_dlls = get_expanded_make_var_array( make, "RC_DLLS" );
|
||||
|
||||
for (i = 0; i < linguas.count; i++)
|
||||
strarray_add( &mo_files, strmake( "%s/%s.mo", top_obj_dir_path( make, "po" ), linguas.str[i] ));
|
||||
@@ -1980,7 +2006,7 @@ static struct strarray output_sources( struct makefile *make, struct strarray *t
|
||||
}
|
||||
else
|
||||
{
|
||||
- int need_cross = make->testdll ||
|
||||
+ int need_cross = make->testdll || make->resource ||
|
||||
(source->file->flags & FLAG_C_IMPLIB) ||
|
||||
(make->module && make->staticlib);
|
||||
|
||||
@@ -1994,7 +2020,7 @@ static struct strarray output_sources( struct makefile *make, struct strarray *t
|
||||
output_filenames( includes );
|
||||
output_filenames( make->define_args );
|
||||
output_filenames( extradefs );
|
||||
- if (make->module || make->staticlib || make->testdll)
|
||||
+ if (make->module || make->staticlib || make->testdll || make->resource)
|
||||
{
|
||||
output_filenames( dll_flags );
|
||||
if (make->use_msvcrt) output_filenames( msvcrt_flags );
|
||||
@@ -2074,6 +2100,72 @@ static struct strarray output_sources( struct makefile *make, struct strarray *t
|
||||
output( "\n" );
|
||||
}
|
||||
|
||||
+ /* rules for resource dlls, call Makefile in subdirectory */
|
||||
+
|
||||
+ if (resource_dlls.count)
|
||||
+ {
|
||||
+ for (i = 0; i < resource_dlls.count; i++)
|
||||
+ {
|
||||
+ output( "%s/Makefile: dummy\n", resource_dlls.str[i] );
|
||||
+ output( "\t@cd %s && $(MAKE) %s/Makefile\n", make->top_obj_dir,
|
||||
+ base_dir_path( make, resource_dlls.str[i] ) );
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < resource_dlls.count; i++)
|
||||
+ {
|
||||
+ output( "%s/%s%s: %s/Makefile dummy\n", resource_dlls.str[i],
|
||||
+ resource_dlls.str[i], dll_ext, resource_dlls.str[i] );
|
||||
+ output( "\t@cd %s && $(MAKE) %s%s\n", resource_dlls.str[i],
|
||||
+ resource_dlls.str[i], dll_ext );
|
||||
+ }
|
||||
+
|
||||
+ output( "%s:", obj_dir_path( make, "resource_dlls.o" ));
|
||||
+ for (i = 0; i < resource_dlls.count; i++)
|
||||
+ output( " %s/%s%s", resource_dlls.str[i], resource_dlls.str[i], dll_ext );
|
||||
+ output( "\n" );
|
||||
+ output( "\t(" );
|
||||
+ for (i = 0; i < resource_dlls.count; i++)
|
||||
+ {
|
||||
+ if (i != 0) output( "; \\\n " );
|
||||
+ output( "echo \"%s RCDATA %s/%s%s\"", resource_dlls.str[i],
|
||||
+ resource_dlls.str[i], resource_dlls.str[i], dll_ext );
|
||||
+ }
|
||||
+ output( ") | %s -o $@\n", tools_path( make, "wrc" ) );
|
||||
+ strarray_add( &clean_files, "resource_dlls.o" );
|
||||
+ strarray_add( &object_files, "resource_dlls.o" );
|
||||
+
|
||||
+ if (crosstarget && (make->testdll || (make->module && make->staticlib)))
|
||||
+ {
|
||||
+ for (i = 0; i < resource_dlls.count; i++)
|
||||
+ {
|
||||
+ char *name = prepend_extension( resource_dlls.str[i], "_crossres", ".dll" );
|
||||
+ output( "%s/%s: %s/Makefile dummy\n", resource_dlls.str[i], name, resource_dlls.str[i] );
|
||||
+ output( "\t@cd %s && $(MAKE) %s\n", resource_dlls.str[i], name );
|
||||
+ free( name );
|
||||
+ }
|
||||
+
|
||||
+ output( "%s:", obj_dir_path( make, "resource_dlls.cross.o" ));
|
||||
+ for (i = 0; i < resource_dlls.count; i++)
|
||||
+ {
|
||||
+ char *name = prepend_extension( resource_dlls.str[i], "_crossres", ".dll" );
|
||||
+ output( " %s/%s", resource_dlls.str[i], name );
|
||||
+ free( name );
|
||||
+ }
|
||||
+ output( "\n" );
|
||||
+ output( "\t(" );
|
||||
+ for (i = 0; i < resource_dlls.count; i++)
|
||||
+ {
|
||||
+ char *name = prepend_extension( resource_dlls.str[i], "_crossres", ".dll" );
|
||||
+ if (i != 0) output( "; \\\n " );
|
||||
+ output( "echo \"%s RCDATA %s/%s\"", resource_dlls.str[i], resource_dlls.str[i], name );
|
||||
+ free( name );
|
||||
+ }
|
||||
+ output( ") | %s -o $@\n", tools_path( make, "wrc" ) );
|
||||
+ strarray_add( &clean_files, "resource_dlls.cross.o" );
|
||||
+ strarray_add( &crossobj_files, "resource_dlls.cross.o" );
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (make->module && !make->staticlib)
|
||||
{
|
||||
struct strarray all_libs = empty_strarray;
|
||||
@@ -2331,6 +2423,83 @@ static struct strarray output_sources( struct makefile *make, struct strarray *t
|
||||
*testlist_files = strarray_replace_extension( &ok_files, ".ok", "" );
|
||||
}
|
||||
|
||||
+ if (make->resource)
|
||||
+ {
|
||||
+ char *extra_wine_flags = get_expanded_make_variable( make, "WINEFLAGS" );
|
||||
+ char *extra_cross_flags = get_expanded_make_variable( make, "CROSSFLAGS" );
|
||||
+ struct strarray all_libs = empty_strarray;
|
||||
+ char *module_path = obj_dir_path( make, make->resource );
|
||||
+ char *spec_file = NULL;
|
||||
+
|
||||
+ if (!make->appmode.count)
|
||||
+ spec_file = src_dir_path( make, replace_extension( make->resource, ".dll", ".spec" ));
|
||||
+ for (i = 0; i < make->imports.count; i++)
|
||||
+ strarray_add( &all_libs, strmake( "-l%s", make->imports.str[i] ));
|
||||
+ strarray_addall( &all_libs, get_expanded_make_var_array( make, "LIBS" ));
|
||||
+
|
||||
+ if (*dll_ext)
|
||||
+ {
|
||||
+ strarray_add( &all_targets, strmake( "%s%s", make->resource, dll_ext ));
|
||||
+ strarray_add( &all_targets, strmake( "%s.fake", make->resource ));
|
||||
+ output( "%s%s %s.fake:", module_path, dll_ext, module_path );
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ strarray_add( &all_targets, make->resource );
|
||||
+ output( "%s:", module_path );
|
||||
+ }
|
||||
+ if (spec_file) output_filename( spec_file );
|
||||
+ output_filenames_obj_dir( make, object_files );
|
||||
+ output_filenames_obj_dir( make, res_files );
|
||||
+ output( "\n" );
|
||||
+ output( "\t%s -o $@", tools_path( make, "winegcc" ));
|
||||
+ output_filename( strmake( "-B%s", tools_dir_path( make, "winebuild" )));
|
||||
+ if (tools_dir) output_filename( strmake( "--sysroot=%s", top_obj_dir_path( make, "" )));
|
||||
+ output_filenames( target_flags );
|
||||
+ output_filenames( unwind_flags );
|
||||
+ if (spec_file)
|
||||
+ {
|
||||
+ output( " -shared %s", spec_file );
|
||||
+ output_filenames( make->extradllflags );
|
||||
+ }
|
||||
+ else output_filenames( make->appmode );
|
||||
+ if (extra_wine_flags) output( " %s", extra_wine_flags );
|
||||
+ output_filenames_obj_dir( make, object_files );
|
||||
+ output_filenames_obj_dir( make, res_files );
|
||||
+ output_filenames( all_libs );
|
||||
+ output_filename( "$(LDFLAGS)" );
|
||||
+ output( "\n" );
|
||||
+
|
||||
+ if (crosstarget)
|
||||
+ {
|
||||
+ char *crossres = prepend_extension( make->resource, "_crossres", ".dll" );
|
||||
+
|
||||
+ strarray_add( &clean_files, crossres );
|
||||
+ output( "%s:", obj_dir_path( make, crossres ));
|
||||
+ output_filenames_obj_dir( make, crossobj_files );
|
||||
+ output_filenames_obj_dir( make, res_files );
|
||||
+ output( "\n" );
|
||||
+ output( "\t%s -o $@ -b %s", tools_path( make, "winegcc" ), crosstarget );
|
||||
+ output_filename( strmake( "-B%s", tools_dir_path( make, "winebuild" )));
|
||||
+ if (tools_dir) output_filename( strmake( "--sysroot=%s", top_obj_dir_path( make, "" )));
|
||||
+ output_filename( "--lib-suffix=.cross.a" );
|
||||
+ if (spec_file)
|
||||
+ {
|
||||
+ output( " -shared %s", spec_file );
|
||||
+ output_filenames( make->extradllflags );
|
||||
+ }
|
||||
+ else output_filenames( make->appmode );
|
||||
+ if (extra_cross_flags) output( " %s", extra_cross_flags );
|
||||
+ output_filenames_obj_dir( make, crossobj_files );
|
||||
+ output_filenames_obj_dir( make, res_files );
|
||||
+ output_filenames( all_libs );
|
||||
+ output_filename( "$(LDFLAGS)" );
|
||||
+ output( "\n" );
|
||||
+ strarray_add( &phony_targets, obj_dir_path( make, "crosstest" ));
|
||||
+ if (make->obj_dir) output( "crosstest: %s\n", obj_dir_path( make, "crosstest" ));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (all_targets.count)
|
||||
{
|
||||
output( "all:" );
|
||||
@@ -2600,4 +2769,5 @@ static void update_makefile( const char *path )
|
||||
make->module = get_expanded_make_variable( make, "MODULE" );
|
||||
make->testdll = get_expanded_make_variable( make, "TESTDLL" );
|
||||
+ make->resource = get_expanded_make_variable( make, "RESOURCE" );
|
||||
make->staticlib = get_expanded_make_variable( make, "STATICLIB" );
|
||||
make->importlib = get_expanded_make_variable( make, "IMPORTLIB" );
|
||||
--
|
||||
2.2.1
|
||||
|
@ -0,0 +1,752 @@
|
||||
From 2532d093c1ae0f4846879cca9c8e08f04a1e7bfc Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Tue, 20 Jan 2015 18:39:36 +0100
|
||||
Subject: ntoskrnl.exe/tests: Add kernel compliant test functions.
|
||||
|
||||
---
|
||||
dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +-
|
||||
dlls/ntoskrnl.exe/tests/driver.sys/Makefile.in | 3 +-
|
||||
dlls/ntoskrnl.exe/tests/driver.sys/driver.c | 38 ++---
|
||||
dlls/ntoskrnl.exe/tests/driver.sys/driver.h | 18 ++-
|
||||
dlls/ntoskrnl.exe/tests/driver.sys/test.c | 195 ++++++++++++++++++++++++
|
||||
dlls/ntoskrnl.exe/tests/driver.sys/test.h | 197 +++++++++++++++++++++++++
|
||||
dlls/ntoskrnl.exe/tests/driver.sys/util.h | 47 ++++++
|
||||
dlls/ntoskrnl.exe/tests/ntoskrnl.c | 53 +++++--
|
||||
include/wine/test.h | 39 ++++-
|
||||
9 files changed, 551 insertions(+), 41 deletions(-)
|
||||
create mode 100644 dlls/ntoskrnl.exe/tests/driver.sys/test.c
|
||||
create mode 100644 dlls/ntoskrnl.exe/tests/driver.sys/test.h
|
||||
create mode 100644 dlls/ntoskrnl.exe/tests/driver.sys/util.h
|
||||
|
||||
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
|
||||
index b824250..c104002 100644
|
||||
--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
|
||||
+++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
|
||||
@@ -1423,7 +1423,7 @@
|
||||
@ cdecl -private _strrev(str) msvcrt._strrev
|
||||
@ cdecl -private _strset(str long) msvcrt._strset
|
||||
@ cdecl -private _strupr(str) msvcrt._strupr
|
||||
-@ cdecl -private _vsnprintf(ptr long str ptr) msvcrt._vsnprintf
|
||||
+@ cdecl _vsnprintf(ptr long str ptr) msvcrt._vsnprintf
|
||||
@ cdecl -private _vsnwprintf(ptr long wstr ptr) msvcrt._vsnwprintf
|
||||
@ cdecl -private _wcsicmp(wstr wstr) msvcrt._wcsicmp
|
||||
@ cdecl -private _wcslwr(wstr) msvcrt._wcslwr
|
||||
diff --git a/dlls/ntoskrnl.exe/tests/driver.sys/Makefile.in b/dlls/ntoskrnl.exe/tests/driver.sys/Makefile.in
|
||||
index bc040e4..b3a6839 100644
|
||||
--- a/dlls/ntoskrnl.exe/tests/driver.sys/Makefile.in
|
||||
+++ b/dlls/ntoskrnl.exe/tests/driver.sys/Makefile.in
|
||||
@@ -8,4 +8,5 @@ CROSSFLAGS = -nostartfiles -nostdlib -nodefaultlibs \
|
||||
-Wl,-entry,_DriverEntry@8
|
||||
|
||||
C_SRCS = \
|
||||
- driver.c
|
||||
+ driver.c \
|
||||
+ test.c
|
||||
diff --git a/dlls/ntoskrnl.exe/tests/driver.sys/driver.c b/dlls/ntoskrnl.exe/tests/driver.sys/driver.c
|
||||
index 5756090..81f938d 100644
|
||||
--- a/dlls/ntoskrnl.exe/tests/driver.sys/driver.c
|
||||
+++ b/dlls/ntoskrnl.exe/tests/driver.sys/driver.c
|
||||
@@ -30,6 +30,9 @@
|
||||
#include "winioctl.h"
|
||||
#include "ddk/wdm.h"
|
||||
|
||||
+#define WINE_KERNEL
|
||||
+#include "util.h"
|
||||
+#include "test.h"
|
||||
#include "driver.h"
|
||||
|
||||
const WCHAR driver_device[] = {'\\','D','e','v','i','c','e',
|
||||
@@ -37,24 +40,17 @@ const WCHAR driver_device[] = {'\\','D','e','v','i','c','e',
|
||||
const WCHAR driver_link[] = {'\\','D','o','s','D','e','v','i','c','e','s',
|
||||
'\\','W','i','n','e','T','e','s','t','D','r','i','v','e','r',0};
|
||||
|
||||
-
|
||||
-static NTSTATUS test_basic_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
|
||||
+KERNEL_TESTCASE(PsGetCurrentProcessId)
|
||||
{
|
||||
- const char str[] = "Wine is not an emulator";
|
||||
- ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
- char *buffer = irp->AssociatedIrp.SystemBuffer;
|
||||
- int i;
|
||||
-
|
||||
- if (!buffer)
|
||||
- return STATUS_ACCESS_VIOLATION;
|
||||
-
|
||||
- if (length < sizeof(str)-1)
|
||||
- return STATUS_BUFFER_TOO_SMALL;
|
||||
-
|
||||
- for (i = 0; i < sizeof(str)-1; i++)
|
||||
- buffer[i] = str[i];
|
||||
+ test->processid = (DWORD)PsGetCurrentProcessId();
|
||||
+ ok(test->processid, "Expected processid to be non zero\n");
|
||||
+ return STATUS_SUCCESS;
|
||||
+}
|
||||
|
||||
- *info = sizeof(str)-1;
|
||||
+KERNEL_TESTCASE(PsGetCurrentThread)
|
||||
+{
|
||||
+ PETHREAD thread = PsGetCurrentThread();
|
||||
+ todo_wine ok(thread != NULL, "Expected thread to be non-NULL\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -70,16 +66,20 @@ static NTSTATUS WINAPI driver_IoControl(DEVICE_OBJECT *device, IRP *irp)
|
||||
NTSTATUS status = STATUS_NOT_SUPPORTED;
|
||||
ULONG_PTR information = 0;
|
||||
|
||||
+#define DECLARE_TEST(name) \
|
||||
+ case WINE_IOCTL_##name: status = RUN_TESTCASE(name, irp, stack, &information); break;
|
||||
+
|
||||
switch (stack->Parameters.DeviceIoControl.IoControlCode)
|
||||
{
|
||||
- case IOCTL_WINETEST_BASIC_IOCTL:
|
||||
- status = test_basic_ioctl(irp, stack, &information);
|
||||
- break;
|
||||
+ DECLARE_TEST(PsGetCurrentProcessId);
|
||||
+ DECLARE_TEST(PsGetCurrentThread);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
+#undef DECLARE_TEST
|
||||
+
|
||||
irp->IoStatus.Status = status;
|
||||
irp->IoStatus.Information = information;
|
||||
IoCompleteRequest(irp, IO_NO_INCREMENT);
|
||||
diff --git a/dlls/ntoskrnl.exe/tests/driver.sys/driver.h b/dlls/ntoskrnl.exe/tests/driver.sys/driver.h
|
||||
index 372e908..e48bbdd 100644
|
||||
--- a/dlls/ntoskrnl.exe/tests/driver.sys/driver.h
|
||||
+++ b/dlls/ntoskrnl.exe/tests/driver.sys/driver.h
|
||||
@@ -20,9 +20,19 @@
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
+#include "test.h"
|
||||
|
||||
-/*
|
||||
- * All custom IOCTLs need to have a function value >= 0x800.
|
||||
- */
|
||||
+#define WINE_IOCTL_PsGetCurrentProcessId WINE_TEST_IOCTL(0)
|
||||
+#define WINE_IOCTL_PsGetCurrentThread WINE_TEST_IOCTL(1)
|
||||
+
|
||||
+struct test_PsGetCurrentProcessId_state
|
||||
+{
|
||||
+ struct kernel_test_state __state;
|
||||
+ DWORD processid; /* output */
|
||||
+};
|
||||
+
|
||||
+struct test_PsGetCurrentThread_state
|
||||
+{
|
||||
+ struct kernel_test_state __state;
|
||||
+};
|
||||
|
||||
-#define IOCTL_WINETEST_BASIC_IOCTL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
diff --git a/dlls/ntoskrnl.exe/tests/driver.sys/test.c b/dlls/ntoskrnl.exe/tests/driver.sys/test.c
|
||||
new file mode 100644
|
||||
index 0000000..5e17c90
|
||||
--- /dev/null
|
||||
+++ b/dlls/ntoskrnl.exe/tests/driver.sys/test.c
|
||||
@@ -0,0 +1,195 @@
|
||||
+/*
|
||||
+ * ntoskrnl.exe testing framework
|
||||
+ *
|
||||
+ * Copyright 2015 Michael Müller
|
||||
+ *
|
||||
+ * 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 "ntstatus.h"
|
||||
+#define WIN32_NO_STATUS
|
||||
+#include "windef.h"
|
||||
+#include "winbase.h"
|
||||
+#include "winternl.h"
|
||||
+#include "winioctl.h"
|
||||
+#include "ddk/wdm.h"
|
||||
+
|
||||
+#define WINE_KERNEL
|
||||
+#include "util.h"
|
||||
+#include "test.h"
|
||||
+
|
||||
+extern int _vsnprintf(char *buffer, size_t count, const char *format, __ms_va_list argptr);
|
||||
+
|
||||
+static void safe_vsnprintf(struct kernel_test_state *state, const char *msg, __ms_va_list args)
|
||||
+{
|
||||
+ int remaining;
|
||||
+ int length;
|
||||
+
|
||||
+ if (state->output.overflow)
|
||||
+ return;
|
||||
+
|
||||
+ if (state->output.offset >= sizeof(state->output.debug) - 1)
|
||||
+ {
|
||||
+ state->output.overflow = TRUE;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ remaining = (sizeof(state->output.debug) - 1) - state->output.offset;
|
||||
+ length = _vsnprintf(&state->output.debug[state->output.offset], remaining, msg, args);
|
||||
+ if (length < 0)
|
||||
+ {
|
||||
+ state->output.debug[state->output.offset] = 0;
|
||||
+ state->output.overflow = TRUE;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ state->output.offset += length;
|
||||
+}
|
||||
+
|
||||
+static void __winetest_cdecl safe_snprintf(struct kernel_test_state *state, const char *msg, ...)
|
||||
+{
|
||||
+ __ms_va_list valist;
|
||||
+
|
||||
+ __ms_va_start(valist, msg);
|
||||
+ safe_vsnprintf(state, msg, valist);
|
||||
+ __ms_va_end(valist);
|
||||
+}
|
||||
+
|
||||
+void winetest_set_location(struct kernel_test_state *state, const char *file, int line)
|
||||
+{
|
||||
+ state->temp.file = kernel_strrchr(file, '/');
|
||||
+ if (state->temp.file == NULL)
|
||||
+ state->temp.file = kernel_strrchr(file, '\\');
|
||||
+ if (state->temp.file == NULL)
|
||||
+ state->temp.file = file;
|
||||
+ else
|
||||
+ state->temp.file++;
|
||||
+ state->temp.line = line;
|
||||
+}
|
||||
+
|
||||
+int winetest_vok(struct kernel_test_state *state, int condition, const char *msg, __ms_va_list args)
|
||||
+{
|
||||
+ if (state->temp.todo_level)
|
||||
+ {
|
||||
+ if (condition)
|
||||
+ {
|
||||
+ safe_snprintf( state, "%s:%d: Test succeeded inside todo block: ",
|
||||
+ state->temp.file, state->temp.line );
|
||||
+ safe_vsnprintf(state, msg, args);
|
||||
+ state->output.todo_failures++;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (state->input.debug_level > 0)
|
||||
+ {
|
||||
+ safe_snprintf( state, "%s:%d: Test marked todo: ",
|
||||
+ state->temp.file, state->temp.line );
|
||||
+ safe_vsnprintf(state, msg, args);
|
||||
+ }
|
||||
+ state->output.todo_successes++;
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (!condition)
|
||||
+ {
|
||||
+ safe_snprintf( state, "%s:%d: Test failed: ",
|
||||
+ state->temp.file, state->temp.line );
|
||||
+ safe_vsnprintf(state, msg, args);
|
||||
+ state->output.failures++;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (state->input.report_success)
|
||||
+ safe_snprintf( state, "%s:%d: Test succeeded\n",
|
||||
+ state->temp.file, state->temp.line);
|
||||
+ state->output.successes++;
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void __winetest_cdecl winetest_ok(struct kernel_test_state *state, int condition, const char *msg, ...)
|
||||
+{
|
||||
+ __ms_va_list valist;
|
||||
+
|
||||
+ __ms_va_start(valist, msg);
|
||||
+ winetest_vok(state, condition, msg, valist);
|
||||
+ __ms_va_end(valist);
|
||||
+}
|
||||
+
|
||||
+void __winetest_cdecl winetest_trace(struct kernel_test_state *state, const char *msg, ...)
|
||||
+{
|
||||
+ __ms_va_list valist;
|
||||
+
|
||||
+ if (state->input.debug_level > 0)
|
||||
+ {
|
||||
+ safe_snprintf( state, "%s:%d: ", state->temp.file, state->temp.line );
|
||||
+ __ms_va_start(valist, msg);
|
||||
+ safe_vsnprintf(state, msg, valist);
|
||||
+ __ms_va_end(valist);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void winetest_vskip(struct kernel_test_state *state, const char *msg, __ms_va_list args)
|
||||
+{
|
||||
+ safe_snprintf( state, "%s:%d: Tests skipped: ", state->temp.file, state->temp.line );
|
||||
+ safe_vsnprintf(state, msg, args);
|
||||
+ state->output.skipped++;
|
||||
+}
|
||||
+
|
||||
+void __winetest_cdecl winetest_skip(struct kernel_test_state *state, const char *msg, ...)
|
||||
+{
|
||||
+ __ms_va_list valist;
|
||||
+ __ms_va_start(valist, msg);
|
||||
+ winetest_vskip(state, msg, valist);
|
||||
+ __ms_va_end(valist);
|
||||
+}
|
||||
+
|
||||
+void __winetest_cdecl winetest_win_skip(struct kernel_test_state *state, const char *msg, ...)
|
||||
+{
|
||||
+ __ms_va_list valist;
|
||||
+ __ms_va_start(valist, msg);
|
||||
+ if (!state->input.windows)
|
||||
+ winetest_vskip(state, msg, valist);
|
||||
+ else
|
||||
+ winetest_vok(state, 0, msg, valist);
|
||||
+ __ms_va_end(valist);
|
||||
+}
|
||||
+
|
||||
+void winetest_start_todo(struct kernel_test_state *state, int windows)
|
||||
+{
|
||||
+ if (state->input.windows == windows)
|
||||
+ state->temp.todo_level++;
|
||||
+ state->temp.todo_do_loop=1;
|
||||
+}
|
||||
+
|
||||
+int winetest_loop_todo(struct kernel_test_state *state)
|
||||
+{
|
||||
+ int do_loop=state->temp.todo_do_loop;
|
||||
+ state->temp.todo_do_loop=0;
|
||||
+ return do_loop;
|
||||
+}
|
||||
+
|
||||
+void winetest_end_todo(struct kernel_test_state *state, int windows)
|
||||
+{
|
||||
+ if (state->input.windows == windows)
|
||||
+ state->temp.todo_level--;
|
||||
+}
|
||||
diff --git a/dlls/ntoskrnl.exe/tests/driver.sys/test.h b/dlls/ntoskrnl.exe/tests/driver.sys/test.h
|
||||
new file mode 100644
|
||||
index 0000000..eca3b46
|
||||
--- /dev/null
|
||||
+++ b/dlls/ntoskrnl.exe/tests/driver.sys/test.h
|
||||
@@ -0,0 +1,197 @@
|
||||
+/*
|
||||
+ * ntoskrnl.exe testing framework
|
||||
+ *
|
||||
+ * Copyright 2015 Michael Müller
|
||||
+ *
|
||||
+ * 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
|
||||
+ */
|
||||
+
|
||||
+#ifndef _WINE_KERNEL_TEST_
|
||||
+#define _WINE_KERNEL_TEST_
|
||||
+
|
||||
+struct kernel_test_state
|
||||
+{
|
||||
+ struct
|
||||
+ {
|
||||
+ int debug_level;
|
||||
+ int report_success;
|
||||
+ BOOL windows;
|
||||
+ } input;
|
||||
+ struct
|
||||
+ {
|
||||
+ const char *file;
|
||||
+ int line;
|
||||
+ int todo_level;
|
||||
+ int todo_do_loop;
|
||||
+ } temp;
|
||||
+ struct
|
||||
+ {
|
||||
+ LONG failures;
|
||||
+ LONG successes;
|
||||
+ LONG todo_failures;
|
||||
+ LONG todo_successes;
|
||||
+ LONG skipped;
|
||||
+
|
||||
+ BOOL overflow;
|
||||
+ DWORD offset;
|
||||
+ char debug[4096];
|
||||
+ } output;
|
||||
+};
|
||||
+
|
||||
+#define WINE_TEST_IOCTL(index) CTL_CODE(FILE_DEVICE_UNKNOWN, (index) + 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
+
|
||||
+#ifdef WINE_KERNEL
|
||||
+
|
||||
+#if defined(__x86_64__) && defined(__GNUC__) && defined(__WINE_USE_MSVCRT)
|
||||
+# define __ms_va_start(list,arg) __builtin_ms_va_start(list,arg)
|
||||
+# define __ms_va_end(list) __builtin_ms_va_end(list)
|
||||
+#else
|
||||
+# define __ms_va_start(list,arg) va_start(list,arg)
|
||||
+# define __ms_va_end(list) va_end(list)
|
||||
+#endif
|
||||
+
|
||||
+#if defined(__x86_64__) && defined(__GNUC__) && defined(__WINE_USE_MSVCRT)
|
||||
+#define __winetest_cdecl __cdecl
|
||||
+#define __ms_va_list __builtin_ms_va_list
|
||||
+#else
|
||||
+#define __winetest_cdecl
|
||||
+#define __ms_va_list va_list
|
||||
+#endif
|
||||
+
|
||||
+#ifdef __GNUC__
|
||||
+void __winetest_cdecl winetest_ok(struct kernel_test_state *state, int condition, const char *msg, ...) __attribute__((format (printf,3,4) ));
|
||||
+void __winetest_cdecl winetest_skip(struct kernel_test_state *state, const char *msg, ...) __attribute__((format (printf,2,3)));
|
||||
+void __winetest_cdecl winetest_win_skip(struct kernel_test_state *state, const char *msg, ...) __attribute__((format (printf,2,3)));
|
||||
+void __winetest_cdecl winetest_trace(struct kernel_test_state *state, const char *msg, ...) __attribute__((format (printf,2,3)));
|
||||
+#else
|
||||
+void __winetest_cdecl winetest_ok(struct kernel_test_state *state, int condition, const char *msg, ...);
|
||||
+void __winetest_cdecl winetest_skip(struct kernel_test_state *state, const char *msg, ...);
|
||||
+void __winetest_cdecl winetest_win_skip(struct kernel_test_state *state, const char *msg, ...);
|
||||
+void __winetest_cdecl winetest_trace(struct kernel_test_state *state, const char *msg, ...);
|
||||
+#endif /* __GNUC__ */
|
||||
+
|
||||
+void winetest_set_location(struct kernel_test_state *state, const char* file, int line);
|
||||
+void winetest_start_todo(struct kernel_test_state *state, int windows);
|
||||
+int winetest_loop_todo(struct kernel_test_state *state);
|
||||
+void winetest_end_todo(struct kernel_test_state *state, int windows);
|
||||
+
|
||||
+#define ok_(file, line) (winetest_set_location(__state, file, line), 0) ? (void)0 : winetest_ok
|
||||
+#define skip_(file, line) (winetest_set_location(__state, file, line), 0) ? (void)0 : winetest_skip
|
||||
+#define win_skip_(file, line) (winetest_set_location(__state, file, line), 0) ? (void)0 : winetest_win_skip
|
||||
+#define trace_(file, line) (winetest_set_location(__state, file, line), 0) ? (void)0 : winetest_trace
|
||||
+
|
||||
+#define _ok ok_(__FILE__, __LINE__)
|
||||
+#define _skip skip_(__FILE__, __LINE__)
|
||||
+#define _win_skip win_skip_(__FILE__, __LINE__)
|
||||
+#define _trace trace_(__FILE__, __LINE__)
|
||||
+
|
||||
+/* Variadic Macros */
|
||||
+#define ok(...) _ok(__state, __VA_ARGS__)
|
||||
+#define skip(...) _skip(__state, __VA_ARGS__)
|
||||
+#define win_skip(...) _win_skip(__state, __VA_ARGS__)
|
||||
+#define trace(...) _trace(__state, __VA_ARGS__)
|
||||
+
|
||||
+#define todo(windows) for (winetest_start_todo(__state, windows); \
|
||||
+ winetest_loop_todo(__state); \
|
||||
+ winetest_end_todo(__state, windows))
|
||||
+#define todo_wine todo(0)
|
||||
+
|
||||
+#define KERNEL_TESTCASE(name) \
|
||||
+ static NTSTATUS test_##name(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info, \
|
||||
+ struct test_##name##_state *test, struct kernel_test_state *__state); \
|
||||
+ \
|
||||
+ static NTSTATUS __test_##name(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info) \
|
||||
+ { \
|
||||
+ ULONG input_length = stack->Parameters.DeviceIoControl.InputBufferLength; \
|
||||
+ ULONG output_length = stack->Parameters.DeviceIoControl.OutputBufferLength; \
|
||||
+ struct kernel_test_state *state = irp->AssociatedIrp.SystemBuffer; \
|
||||
+ NTSTATUS status; \
|
||||
+ \
|
||||
+ if (!state) \
|
||||
+ return STATUS_ACCESS_VIOLATION; \
|
||||
+ \
|
||||
+ if (input_length < sizeof(struct test_##name##_state) || \
|
||||
+ output_length < sizeof(struct test_##name##_state)) \
|
||||
+ return STATUS_BUFFER_TOO_SMALL; \
|
||||
+ \
|
||||
+ kernel_memset(&state->temp, 0, sizeof(state->temp)); \
|
||||
+ kernel_memset(&state->output, 0, sizeof(state->output)); \
|
||||
+ status = test_##name(irp, stack, info, irp->AssociatedIrp.SystemBuffer, state); \
|
||||
+ \
|
||||
+ kernel_memset(&state->temp, 0, sizeof(state->temp)); \
|
||||
+ *info = sizeof(struct test_##name##_state); \
|
||||
+ return status; \
|
||||
+ } \
|
||||
+ \
|
||||
+ static NTSTATUS test_##name(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info, \
|
||||
+ struct test_##name##_state *test, struct kernel_test_state *__state)
|
||||
+
|
||||
+#define RUN_TESTCASE(name, irp, stack, info) \
|
||||
+ __test_##name(irp, stack, info)
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+#define wine_run_kernel_test(device, ioctl, state, size, returned) \
|
||||
+ __wine_run_kernel_test(__FILE__, __LINE__, device, ioctl, state, size, returned)
|
||||
+
|
||||
+static BOOL __wine_run_kernel_test(const char* file, int line, HANDLE device, DWORD ioctl,
|
||||
+ void *data, DWORD size, DWORD *returned)
|
||||
+{
|
||||
+ struct kernel_test_state *state = data;
|
||||
+ DWORD bytes_returned;
|
||||
+ BOOL res;
|
||||
+
|
||||
+ if (!returned)
|
||||
+ returned = &bytes_returned;
|
||||
+
|
||||
+ memset(state, 0, sizeof(*state));
|
||||
+ state->input.debug_level = winetest_get_debug();
|
||||
+ state->input.report_success = winetest_get_report_success();
|
||||
+ state->input.windows = !strcmp(winetest_platform, "windows");
|
||||
+
|
||||
+ res = DeviceIoControl(device, ioctl, data, size, data, size, returned, NULL);
|
||||
+
|
||||
+ if (returned == &bytes_returned)
|
||||
+ ok_(file, line)(bytes_returned == size,
|
||||
+ "DeviceIoControl returned %u bytes, expected %u bytes\n", bytes_returned, size);
|
||||
+
|
||||
+ if (state->output.offset >= sizeof(state->output.debug))
|
||||
+ state->output.offset = sizeof(state->output.debug) - 1;
|
||||
+
|
||||
+ if (state->output.offset)
|
||||
+ {
|
||||
+ state->output.debug[state->output.offset] = 0;
|
||||
+ fprintf(stdout, "%s", state->output.debug);
|
||||
+ if (state->output.debug[state->output.offset - 1] != '\n')
|
||||
+ fprintf(stdout, "<line truncated>\n");
|
||||
+ }
|
||||
+
|
||||
+ if (state->output.overflow)
|
||||
+ skip_(file, line)("Buffer was too small, kernel debug output is truncated!\n");
|
||||
+
|
||||
+ winetest_add_failures(state->output.failures);
|
||||
+ winetest_add_successes(state->output.successes);
|
||||
+ winetest_add_todo_failures(state->output.todo_failures);
|
||||
+ winetest_add_todo_successes(state->output.todo_successes);
|
||||
+ winetest_add_skipped(state->output.skipped);
|
||||
+
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+#endif /* _WINE_KERNEL_TEST_ */
|
||||
diff --git a/dlls/ntoskrnl.exe/tests/driver.sys/util.h b/dlls/ntoskrnl.exe/tests/driver.sys/util.h
|
||||
new file mode 100644
|
||||
index 0000000..881a4a2
|
||||
--- /dev/null
|
||||
+++ b/dlls/ntoskrnl.exe/tests/driver.sys/util.h
|
||||
@@ -0,0 +1,47 @@
|
||||
+/*
|
||||
+ * ntoskrnl.exe testing framework
|
||||
+ *
|
||||
+ * Copyright 2015 Sebastian Lackner
|
||||
+ *
|
||||
+ * 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 <stddef.h>
|
||||
+
|
||||
+static inline const char* kernel_strrchr(const char *str, int character)
|
||||
+{
|
||||
+ const char *ret = NULL;
|
||||
+ for (; *str; str++)
|
||||
+ {
|
||||
+ if (*str == character)
|
||||
+ ret = str;
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static inline void* kernel_memcpy(void *destination, const void *source, size_t num)
|
||||
+{
|
||||
+ const char *src = source;
|
||||
+ char *dst = destination;
|
||||
+ while (num--) *dst++ = *src++;
|
||||
+ return destination;
|
||||
+}
|
||||
+
|
||||
+static inline void* kernel_memset(void *ptr, int value, size_t num)
|
||||
+{
|
||||
+ char *dst = ptr;
|
||||
+ while (num--) *dst++ = value;
|
||||
+ return ptr;
|
||||
+}
|
||||
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
|
||||
index 9b8a6a7..64e9d97 100644
|
||||
--- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c
|
||||
+++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "winioctl.h"
|
||||
#include "wine/test.h"
|
||||
|
||||
+#include "driver.sys/test.h"
|
||||
#include "driver.sys/driver.h"
|
||||
|
||||
static const char driver_name[] = "WineTestDriver";
|
||||
@@ -184,29 +185,52 @@ err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-static void test_basic_ioctl(void)
|
||||
+static void test_PsGetCurrentProcessId(void)
|
||||
{
|
||||
- const char str[] = "Wine is not an emulator";
|
||||
- DWORD bytes_returned;
|
||||
- char buf[32];
|
||||
- HANDLE file;
|
||||
+ struct test_PsGetCurrentProcessId_state state;
|
||||
+ DWORD processid;
|
||||
+ HANDLE device;
|
||||
BOOL res;
|
||||
|
||||
- file = CreateFileA(device_path, GENERIC_READ | GENERIC_WRITE,
|
||||
- 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
- if (file == INVALID_HANDLE_VALUE)
|
||||
+ trace("Running tests for PsGetCurrentProcessId\n");
|
||||
+
|
||||
+ device = CreateFileA(device_path, GENERIC_READ | GENERIC_WRITE,
|
||||
+ 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
+ if (device == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
ok(0, "Connecting to driver failed with %x\n", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
- res = DeviceIoControl(file, IOCTL_WINETEST_BASIC_IOCTL, NULL, 0, buf,
|
||||
- sizeof(buf), &bytes_returned, NULL);
|
||||
+ res = wine_run_kernel_test(device, WINE_IOCTL_PsGetCurrentProcessId, &state, sizeof(state), NULL);
|
||||
ok(res, "DeviceIoControl failed with %x\n", GetLastError());
|
||||
- ok(bytes_returned == sizeof(str)-1, "Unexpected number of bytes\n");
|
||||
- ok(!memcmp(buf, str, sizeof(str)-1), "Unexpected response data\n");
|
||||
|
||||
- CloseHandle(file);
|
||||
+ processid = GetCurrentProcessId();
|
||||
+ ok(state.processid == processid, "Expected processid %u, got %u\n", processid, state.processid);
|
||||
+
|
||||
+ CloseHandle(device);
|
||||
+}
|
||||
+
|
||||
+static void test_PsGetCurrentThread(void)
|
||||
+{
|
||||
+ struct test_PsGetCurrentThread_state state;
|
||||
+ HANDLE device;
|
||||
+ BOOL res;
|
||||
+
|
||||
+ trace("Running tests for PsGetCurrentThread\n");
|
||||
+
|
||||
+ device = CreateFileA(device_path, GENERIC_READ | GENERIC_WRITE,
|
||||
+ 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
+ if (device == INVALID_HANDLE_VALUE)
|
||||
+ {
|
||||
+ ok(0, "Connecting to driver failed with %x\n", GetLastError());
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ res = wine_run_kernel_test(device, WINE_IOCTL_PsGetCurrentThread, &state, sizeof(state), NULL);
|
||||
+ ok(res, "DeviceIoControl failed with %x\n", GetLastError());
|
||||
+
|
||||
+ CloseHandle(device);
|
||||
}
|
||||
|
||||
START_TEST(ntoskrnl)
|
||||
@@ -220,7 +244,8 @@ START_TEST(ntoskrnl)
|
||||
return;
|
||||
}
|
||||
|
||||
- test_basic_ioctl();
|
||||
+ test_PsGetCurrentProcessId();
|
||||
+ test_PsGetCurrentThread();
|
||||
|
||||
unload_driver(service, filename);
|
||||
}
|
||||
diff --git a/include/wine/test.h b/include/wine/test.h
|
||||
index f8b608f..b7ef81a 100644
|
||||
--- a/include/wine/test.h
|
||||
+++ b/include/wine/test.h
|
||||
@@ -61,7 +61,13 @@ extern int winetest_loop_todo(void);
|
||||
extern void winetest_end_todo( const char* platform );
|
||||
extern int winetest_get_mainargs( char*** pargv );
|
||||
extern LONG winetest_get_failures(void);
|
||||
+extern int winetest_get_report_success(void);
|
||||
+extern int winetest_get_debug(void);
|
||||
extern void winetest_add_failures( LONG new_failures );
|
||||
+extern void winetest_add_successes( LONG new_successes );
|
||||
+extern void winetest_add_todo_failures( LONG new_todo_failures );
|
||||
+extern void winetest_add_todo_successes( LONG new_todo_successes );
|
||||
+extern void winetest_add_skipped( LONG new_skipped );
|
||||
extern void winetest_wait_child_process( HANDLE process );
|
||||
|
||||
extern const char *wine_dbgstr_wn( const WCHAR *str, int n );
|
||||
@@ -436,10 +442,39 @@ LONG winetest_get_failures(void)
|
||||
return failures;
|
||||
}
|
||||
|
||||
+int winetest_get_report_success(void)
|
||||
+{
|
||||
+ return report_success;
|
||||
+}
|
||||
+
|
||||
+int winetest_get_debug(void)
|
||||
+{
|
||||
+ return winetest_debug;
|
||||
+}
|
||||
+
|
||||
void winetest_add_failures( LONG new_failures )
|
||||
{
|
||||
- while (new_failures-- > 0)
|
||||
- InterlockedIncrement( &failures );
|
||||
+ InterlockedExchangeAdd( &failures, new_failures );
|
||||
+}
|
||||
+
|
||||
+void winetest_add_successes( LONG new_successes )
|
||||
+{
|
||||
+ InterlockedExchangeAdd( &successes, new_successes );
|
||||
+}
|
||||
+
|
||||
+void winetest_add_todo_failures( LONG new_todo_failures )
|
||||
+{
|
||||
+ InterlockedExchangeAdd( &todo_failures, new_todo_failures );
|
||||
+}
|
||||
+
|
||||
+void winetest_add_todo_successes( LONG new_todo_successes )
|
||||
+{
|
||||
+ InterlockedExchangeAdd( &todo_successes, new_todo_successes );
|
||||
+}
|
||||
+
|
||||
+void winetest_add_skipped( LONG new_skipped )
|
||||
+{
|
||||
+ InterlockedExchangeAdd( &skipped, new_skipped );
|
||||
}
|
||||
|
||||
void winetest_wait_child_process( HANDLE process )
|
||||
--
|
||||
2.2.1
|
||||
|
1
patches/ntoskrnl-DriverTest/definition
Normal file
1
patches/ntoskrnl-DriverTest/definition
Normal file
@ -0,0 +1 @@
|
||||
Fixes: Implement ntoskrnl driver testing framework.
|
@ -41,8 +41,7 @@ index 73e67bb..f76fa4d 100644
|
||||
|
||||
dnl Disable winetest too if tests are disabled
|
||||
enable_winetest=${enable_winetest:-$enable_tests}
|
||||
@@ -3125,6 +3131,9 @@ WINE_CONFIG_TEST(dlls/ntdsapi/tests)
|
||||
WINE_CONFIG_DLL(ntoskrnl.exe,,[implib])
|
||||
@@ -3128,4 +3134,7 @@ WINE_CONFIG_DLL(ntoskrnl.exe,,[implib])
|
||||
WINE_CONFIG_DLL(ntprint)
|
||||
WINE_CONFIG_TEST(dlls/ntprint/tests)
|
||||
+WINE_CONFIG_DLL(nvapi,enable_win32)
|
||||
@ -50,7 +49,6 @@ index 73e67bb..f76fa4d 100644
|
||||
+WINE_CONFIG_DLL(nvapi64,enable_win64)
|
||||
WINE_CONFIG_DLL(nvcuda)
|
||||
WINE_CONFIG_TEST(dlls/nvcuda/tests)
|
||||
WINE_CONFIG_DLL(objsel,,[clean])
|
||||
diff --git a/dlls/nvapi/Makefile.in b/dlls/nvapi/Makefile.in
|
||||
new file mode 100644
|
||||
index 0000000..606177f
|
||||
|
@ -19,14 +19,12 @@ diff --git a/configure.ac b/configure.ac
|
||||
index b67a7e7..6e3108b 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -3125,6 +3125,7 @@ WINE_CONFIG_TEST(dlls/ntdsapi/tests)
|
||||
WINE_CONFIG_DLL(ntoskrnl.exe,,[implib])
|
||||
@@ -3128,4 +3128,5 @@ WINE_CONFIG_DLL(ntoskrnl.exe,,[implib])
|
||||
WINE_CONFIG_DLL(ntprint)
|
||||
WINE_CONFIG_TEST(dlls/ntprint/tests)
|
||||
+WINE_CONFIG_DLL(nvcuda)
|
||||
WINE_CONFIG_DLL(objsel,,[clean])
|
||||
WINE_CONFIG_DLL(odbc32,,[implib])
|
||||
WINE_CONFIG_DLL(odbccp32,,[implib])
|
||||
diff --git a/dlls/nvcuda/Makefile.in b/dlls/nvcuda/Makefile.in
|
||||
new file mode 100644
|
||||
index 0000000..4b33278
|
||||
|
@ -127,6 +127,7 @@ patch_enable_all ()
|
||||
enable_ntdll_User_Shared_Data="$1"
|
||||
enable_ntdll_WRITECOPY="$1"
|
||||
enable_ntdll_WinSqm="$1"
|
||||
enable_ntoskrnl_DriverTest="$1"
|
||||
enable_ntoskrnl_Emulator="$1"
|
||||
enable_ntoskrnl_KeWaitForMultipleObjects="$1"
|
||||
enable_nvapi_Stub_DLL="$1"
|
||||
@ -408,6 +409,9 @@ patch_enable ()
|
||||
ntdll-WinSqm)
|
||||
enable_ntdll_WinSqm="$2"
|
||||
;;
|
||||
ntoskrnl-DriverTest)
|
||||
enable_ntoskrnl_DriverTest="$2"
|
||||
;;
|
||||
ntoskrnl-Emulator)
|
||||
enable_ntoskrnl_Emulator="$2"
|
||||
;;
|
||||
@ -2177,6 +2181,25 @@ if test "$enable_ntdll_WinSqm" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset ntoskrnl-DriverTest
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * aclocal.m4, configure.ac, dlls/ntoskrnl.exe/ntoskrnl.exe.spec, dlls/ntoskrnl.exe/tests/Makefile.in,
|
||||
# | dlls/ntoskrnl.exe/tests/driver.sys/Makefile.in, dlls/ntoskrnl.exe/tests/driver.sys/driver.c,
|
||||
# | dlls/ntoskrnl.exe/tests/driver.sys/driver.h, dlls/ntoskrnl.exe/tests/driver.sys/driver.sys.spec,
|
||||
# | dlls/ntoskrnl.exe/tests/driver.sys/test.c, dlls/ntoskrnl.exe/tests/driver.sys/test.h,
|
||||
# | dlls/ntoskrnl.exe/tests/driver.sys/util.h, dlls/ntoskrnl.exe/tests/ntoskrnl.c, include/wine/test.h,
|
||||
# | tools/make_makefiles, tools/makedep.c
|
||||
# |
|
||||
if test "$enable_ntoskrnl_DriverTest" -eq 1; then
|
||||
patch_apply ntoskrnl-DriverTest/0001-ntoskrnl.exe-tests-Add-initial-driver-testing-framew.patch
|
||||
patch_apply ntoskrnl-DriverTest/0002-ntoskrnl.exe-tests-Add-kernel-compliant-test-functio.patch
|
||||
(
|
||||
echo '+ { "Sebastian Lackner", "ntoskrnl.exe/tests: Add initial driver testing framework and corrsponding changes to Makefile system.", 2 },';
|
||||
echo '+ { "Michael Müller", "ntoskrnl.exe/tests: Add kernel compliant test functions.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset ntoskrnl-Emulator
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
|
Loading…
Reference in New Issue
Block a user