Jacek Caban : ntoskrnl.exe: Implement KeExpandKernelStackAndCallout and KeExpandKernelStackAndCalloutEx.
Alexandre Julliard
julliard at winehq.org
Mon Feb 4 13:29:54 CST 2019
Module: wine
Branch: master
Commit: 5bfbcb735bd05a5df9a8d7e96d832b3c1205b45f
URL: https://source.winehq.org/git/wine.git/?a=commit;h=5bfbcb735bd05a5df9a8d7e96d832b3c1205b45f
Author: Jacek Caban <jacek at codeweavers.com>
Date: Fri Feb 1 16:28:16 2019 +0100
ntoskrnl.exe: Implement KeExpandKernelStackAndCallout and KeExpandKernelStackAndCalloutEx.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntoskrnl.exe/ntoskrnl.c | 19 +++++++++
dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +
dlls/ntoskrnl.exe/tests/driver.c | 84 +++++++++++++++++++++++++++++++++++--
include/ddk/ntddk.h | 3 ++
4 files changed, 105 insertions(+), 3 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 298247b..f21d6f7 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -2308,6 +2308,25 @@ VOID WINAPI IoRegisterFileSystem(PDEVICE_OBJECT DeviceObject)
}
/***********************************************************************
+ * KeExpandKernelStackAndCalloutEx (NTOSKRNL.EXE.@)
+ */
+NTSTATUS WINAPI KeExpandKernelStackAndCalloutEx(PEXPAND_STACK_CALLOUT callout, void *parameter, SIZE_T size,
+ BOOLEAN wait, void *context)
+{
+ WARN("(%p %p %lu %x %p) semi-stub: ignoring stack expand\n", callout, parameter, size, wait, context);
+ callout(parameter);
+ return STATUS_SUCCESS;
+}
+
+/***********************************************************************
+ * KeExpandKernelStackAndCallout (NTOSKRNL.EXE.@)
+ */
+NTSTATUS WINAPI KeExpandKernelStackAndCallout(PEXPAND_STACK_CALLOUT callout, void *parameter, SIZE_T size)
+{
+ return KeExpandKernelStackAndCalloutEx(callout, parameter, size, TRUE, NULL);
+}
+
+/***********************************************************************
* IoUnregisterFileSystem (NTOSKRNL.EXE.@)
*/
VOID WINAPI IoUnregisterFileSystem(PDEVICE_OBJECT DeviceObject)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
index df2f15b..40f5b27 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
+++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
@@ -44,6 +44,8 @@
@ stdcall -arch=arm,arm64,x86_64 KeAcquireInStackQueuedSpinLock(ptr ptr)
@ stdcall -norelay KeAcquireInStackQueuedSpinLockAtDpcLevel(ptr ptr)
@ stdcall KeEnterGuardedRegion()
+@ stdcall KeExpandKernelStackAndCallout(ptr ptr long)
+@ stdcall KeExpandKernelStackAndCalloutEx(ptr ptr long long ptr)
@ stdcall KeLeaveGuardedRegion()
@ stdcall -arch=arm,arm64,x86_64 KeReleaseInStackQueuedSpinLock(ptr)
@ stdcall -norelay KeReleaseInStackQueuedSpinLockFromDpcLevel(ptr)
diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c
index 5c34b41..cbf8bdc 100644
--- a/dlls/ntoskrnl.exe/tests/driver.c
+++ b/dlls/ntoskrnl.exe/tests/driver.c
@@ -28,6 +28,7 @@
#include "winbase.h"
#include "winternl.h"
#include "winioctl.h"
+#include "ddk/ntddk.h"
#include "ddk/wdm.h"
#include "driver.h"
@@ -68,10 +69,9 @@ static void WINAPIV kprintf(const char *format, ...)
__ms_va_end(valist);
}
-static void WINAPIV ok_(const char *file, int line, int condition, const char *msg, ...)
+static void WINAPIV vok_(const char *file, int line, int condition, const char *msg, __ms_va_list args)
{
const char *current_file;
- __ms_va_list args;
if (!(current_file = drv_strrchr(file, '/')) &&
!(current_file = drv_strrchr(file, '\\')))
@@ -79,7 +79,6 @@ static void WINAPIV ok_(const char *file, int line, int condition, const char *m
else
current_file++;
- __ms_va_start(args, msg);
if (todo_level)
{
if (condition)
@@ -113,6 +112,39 @@ static void WINAPIV ok_(const char *file, int line, int condition, const char *m
InterlockedIncrement(&successes);
}
}
+}
+
+static void WINAPIV ok_(const char *file, int line, int condition, const char *msg, ...)
+{
+ __ms_va_list args;
+ __ms_va_start(args, msg);
+ vok_(file, line, condition, msg, args);
+ __ms_va_end(args);
+}
+
+void vskip_(const char *file, int line, const char *msg, __ms_va_list args)
+{
+ const char *current_file;
+
+ if (!(current_file = drv_strrchr(file, '/')) &&
+ !(current_file = drv_strrchr(file, '\\')))
+ current_file = file;
+ else
+ current_file++;
+
+ kprintf("%s:%d: Tests skipped: ", current_file, line);
+ kvprintf(msg, args);
+ skipped++;
+}
+
+void WINAPIV win_skip_(const char *file, int line, const char *msg, ...)
+{
+ __ms_va_list args;
+ __ms_va_start(args, msg);
+ if (running_under_wine)
+ vok_(file, line, 0, msg, args);
+ else
+ vskip_(file, line, msg, args);
__ms_va_end(args);
}
@@ -140,6 +172,7 @@ static void winetest_end_todo(void)
winetest_end_todo())
#define todo_wine todo_if(running_under_wine)
#define todo_wine_if(is_todo) todo_if((is_todo) && running_under_wine)
+#define win_skip(...) win_skip_(__FILE__, __LINE__, __VA_ARGS__)
static void test_currentprocess(void)
{
@@ -498,6 +531,50 @@ static void test_sync(void)
KeCancelTimer(&timer);
}
+static int callout_cnt;
+
+static void WINAPI callout(void *parameter)
+{
+ ok(parameter == (void*)0xdeadbeef, "parameter = %p\n", parameter);
+ callout_cnt++;
+}
+
+static void test_stack_callout(void)
+{
+ NTSTATUS (WINAPI *pKeExpandKernelStackAndCallout)(PEXPAND_STACK_CALLOUT,void*,SIZE_T);
+ NTSTATUS (WINAPI *pKeExpandKernelStackAndCalloutEx)(PEXPAND_STACK_CALLOUT,void*,SIZE_T,BOOLEAN,void*);
+ UNICODE_STRING str;
+ NTSTATUS ret;
+
+ static const WCHAR KeExpandKernelStackAndCalloutW[] =
+ {'K','e','E','x','p','a','n','d','K','e','r','n','e','l','S','t','a','c','k','A','n','d','C','a','l','l','o','u','t',0};
+ static const WCHAR KeExpandKernelStackAndCalloutExW[] =
+ {'K','e','E','x','p','a','n','d','K','e','r','n','e','l','S','t','a','c','k','A','n','d','C','a','l','l','o','u','t','E','x',0};
+
+
+ RtlInitUnicodeString(&str, KeExpandKernelStackAndCalloutW);
+ pKeExpandKernelStackAndCallout = MmGetSystemRoutineAddress(&str);
+ if (pKeExpandKernelStackAndCallout)
+ {
+ callout_cnt = 0;
+ ret = pKeExpandKernelStackAndCallout(callout, (void*)0xdeadbeef, 4096);
+ ok(ret == STATUS_SUCCESS, "KeExpandKernelStackAndCallout failed: %#x\n", ret);
+ ok(callout_cnt == 1, "callout_cnt = %u\n", callout_cnt);
+ }
+ else win_skip("KeExpandKernelStackAndCallout is not available\n");
+
+ RtlInitUnicodeString(&str, KeExpandKernelStackAndCalloutExW);
+ pKeExpandKernelStackAndCalloutEx = MmGetSystemRoutineAddress(&str);
+ if (pKeExpandKernelStackAndCalloutEx)
+ {
+ callout_cnt = 0;
+ ret = pKeExpandKernelStackAndCalloutEx(callout, (void*)0xdeadbeef, 4096, FALSE, NULL);
+ ok(ret == STATUS_SUCCESS, "KeExpandKernelStackAndCalloutEx failed: %#x\n", ret);
+ ok(callout_cnt == 1, "callout_cnt = %u\n", callout_cnt);
+ }
+ else win_skip("KeExpandKernelStackAndCalloutEx is not available\n");
+}
+
static NTSTATUS main_test(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
{
ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength;
@@ -527,6 +604,7 @@ static NTSTATUS main_test(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
test_init_funcs();
test_load_driver();
test_sync();
+ test_stack_callout();
/* print process report */
if (test_input->winetest_debug)
diff --git a/include/ddk/ntddk.h b/include/ddk/ntddk.h
index dc051e1..452e510 100644
--- a/include/ddk/ntddk.h
+++ b/include/ddk/ntddk.h
@@ -200,11 +200,14 @@ typedef VOID (WINAPI *PDRIVER_REINITIALIZE)(PDRIVER_OBJECT,PVOID,ULONG);
typedef VOID (WINAPI *PLOAD_IMAGE_NOTIFY_ROUTINE)(PUNICODE_STRING,HANDLE,PIMAGE_INFO);
typedef NTSTATUS (WINAPI *PIO_QUERY_DEVICE_ROUTINE)(PVOID,PUNICODE_STRING,INTERFACE_TYPE,ULONG,
PKEY_VALUE_FULL_INFORMATION*,CONFIGURATION_TYPE,ULONG,PKEY_VALUE_FULL_INFORMATION*);
+typedef void (NTAPI EXPAND_STACK_CALLOUT)(void*);
+typedef EXPAND_STACK_CALLOUT *PEXPAND_STACK_CALLOUT;
NTSTATUS WINAPI IoQueryDeviceDescription(PINTERFACE_TYPE,PULONG,PCONFIGURATION_TYPE,PULONG,
PCONFIGURATION_TYPE,PULONG,PIO_QUERY_DEVICE_ROUTINE,PVOID);
void WINAPI IoRegisterDriverReinitialization(PDRIVER_OBJECT,PDRIVER_REINITIALIZE,PVOID);
NTSTATUS WINAPI IoRegisterShutdownNotification(PDEVICE_OBJECT);
+NTSTATUS WINAPI KeExpandKernelStackAndCallout(PEXPAND_STACK_CALLOUT,void*,SIZE_T);
void WINAPI KeSetTargetProcessorDpc(PRKDPC,CCHAR);
BOOLEAN WINAPI MmIsAddressValid(void *);
NTSTATUS WINAPI PsSetLoadImageNotifyRoutine(PLOAD_IMAGE_NOTIFY_ROUTINE);
More information about the wine-cvs
mailing list