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