ntoskrnl.exe: Implement KeExpandKernelStackAndCallout and KeExpandKernelStackAndCalloutEx.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
stable
Jacek Caban 2019-02-01 16:28:16 +01:00 committed by Alexandre Julliard
parent 962aed5120
commit 5bfbcb735b
4 changed files with 105 additions and 3 deletions

View File

@ -2307,6 +2307,25 @@ VOID WINAPI IoRegisterFileSystem(PDEVICE_OBJECT DeviceObject)
FIXME("(%p): stub\n", 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.@)
*/

View File

@ -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)

View File

@ -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)

View File

@ -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);