mirror of
https://github.com/reactos/reactos.git
synced 2025-02-28 19:32:59 +00:00
[NTOS:KE] Implement mechanism for callout-stacks
This commit is contained in:
parent
6fe60acc1d
commit
5d03d26812
10 changed files with 549 additions and 2 deletions
|
@ -239,7 +239,8 @@ Enable this if the module uses typeid or dynamic_cast. You will probably need to
|
||||||
-DMINGW_HAS_SECURE_API=1
|
-DMINGW_HAS_SECURE_API=1
|
||||||
-DD3D_UMD_INTERFACE_VERSION=0x000C # Vista
|
-DD3D_UMD_INTERFACE_VERSION=0x000C # Vista
|
||||||
-DDXGKDDI_INTERFACE_VERSION=0x1052 # Vista
|
-DDXGKDDI_INTERFACE_VERSION=0x1052 # Vista
|
||||||
-DDLL_EXPORT_VERSION=${DLL_EXPORT_VERSION})
|
-DDLL_EXPORT_VERSION=${DLL_EXPORT_VERSION}
|
||||||
|
-DENABLE_CALLBACK_STACKS=${ENABLE_CALLBACK_STACKS})
|
||||||
|
|
||||||
# Arch Options
|
# Arch Options
|
||||||
if(ARCH STREQUAL "i386")
|
if(ARCH STREQUAL "i386")
|
||||||
|
|
|
@ -1079,6 +1079,11 @@ KeBugCheckUnicodeToAnsi(
|
||||||
IN ULONG Length
|
IN ULONG Length
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ULONG_PTR
|
||||||
|
NTAPI
|
||||||
|
KiGetStackPointer(
|
||||||
|
VOID);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
||||||
|
|
|
@ -1701,6 +1701,12 @@ MmGrowKernelStack(
|
||||||
IN PVOID StackPointer
|
IN PVOID StackPointer
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MmGrowKernelStackEx(
|
||||||
|
_In_ PVOID StackPointer,
|
||||||
|
_In_ ULONG GrowSize
|
||||||
|
);
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -147,5 +147,59 @@ PUBLIC KiCallbackReturn
|
||||||
|
|
||||||
.ENDP
|
.ENDP
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VOID
|
||||||
|
* NTAPI
|
||||||
|
* KiSwitchStackAndCallout(
|
||||||
|
* _In_opt_ PVOID Parameter@<rcx>,
|
||||||
|
* _In_ PEXPAND_STACK_CALLOUT Callout@<rdx>,
|
||||||
|
* _In_ PVOID Stack@<r8>)
|
||||||
|
*/
|
||||||
|
PUBLIC KiSwitchStackAndCallout
|
||||||
|
.PROC KiSwitchStackAndCallout
|
||||||
|
/* Save rbp */
|
||||||
|
mov [rsp + 8], rbp
|
||||||
|
.SAVEREG rbp, 8
|
||||||
|
|
||||||
|
/* Save stack pointer in rbp for unwinding */
|
||||||
|
mov rbp, rsp
|
||||||
|
.SETFRAME rbp, 0
|
||||||
|
|
||||||
|
.ENDPROLOG
|
||||||
|
|
||||||
|
/* Save the current stack pointer on the new stack */
|
||||||
|
mov [r8 - 8], rsp
|
||||||
|
|
||||||
|
/* Switch to the new stack and reserve home space */
|
||||||
|
lea rsp, [r8 - 48]
|
||||||
|
|
||||||
|
/* Enable interrupts again */
|
||||||
|
sti
|
||||||
|
|
||||||
|
/* Call the callout */
|
||||||
|
call rdx
|
||||||
|
|
||||||
|
/* Disable interrupts */
|
||||||
|
cli
|
||||||
|
|
||||||
|
/* Restore the stack pointer */
|
||||||
|
mov rsp, [rsp + 48 - 8]
|
||||||
|
|
||||||
|
/* Return */
|
||||||
|
mov rbp, [rsp + 8]
|
||||||
|
ret
|
||||||
|
|
||||||
|
.ENDP
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ULONG_PTR KiGetStackPointer(VOID);
|
||||||
|
*/
|
||||||
|
PUBLIC KiGetStackPointer
|
||||||
|
KiGetStackPointer:
|
||||||
|
|
||||||
|
/* Return the stack pointer */
|
||||||
|
lea rax, [rsp + 8]
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
END
|
END
|
||||||
|
|
376
ntoskrnl/ke/callout.c
Normal file
376
ntoskrnl/ke/callout.c
Normal file
|
@ -0,0 +1,376 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Kernel
|
||||||
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||||
|
* PURPOSE: Kernel stack expansion functions
|
||||||
|
* COPYRIGHT: Copyright 2023 Timo Kreuzer <timo.kreuzer@reactos.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include <ntoskrnl.h>
|
||||||
|
#include <minwin/ntosifs.h>
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
/* This function is implemented in asm */
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
KiSwitchStackAndCallout(
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_ PEXPAND_STACK_CALLOUT Callout,
|
||||||
|
_In_ PVOID Stack);
|
||||||
|
|
||||||
|
ULONG KiNumberOfCalloutStacks = 0;
|
||||||
|
|
||||||
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Allocate a callout stack
|
||||||
|
*
|
||||||
|
* @param StackType - Type of the stack to allocate
|
||||||
|
* @param RecursionDepth - Recursion depth
|
||||||
|
* @param Reserved - Reserved, must be 0
|
||||||
|
* @param StackContext - Pointer to a variable that receives the stack context
|
||||||
|
*
|
||||||
|
* @return STATUS_SUCCESS on success, STATUS_INSUFFICIENT_RESOURCES if the stack could not be allocated
|
||||||
|
*/
|
||||||
|
_Must_inspect_result_
|
||||||
|
_IRQL_requires_max_(APC_LEVEL)
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
KeAllocateCalloutStackEx(
|
||||||
|
_In_ _Strict_type_match_ KSTACK_TYPE StackType,
|
||||||
|
_In_ UCHAR RecursionDepth,
|
||||||
|
_In_ _Reserved_ SIZE_T Reserved,
|
||||||
|
_Outptr_ PVOID *StackContext)
|
||||||
|
{
|
||||||
|
BOOLEAN LargeStack = (StackType == ReserveStackLarge);
|
||||||
|
SIZE_T StackSize = LargeStack ? KERNEL_LARGE_STACK_SIZE : KERNEL_STACK_SIZE;
|
||||||
|
PVOID StackBase;
|
||||||
|
PKSTACK_CONTROL StackControl;
|
||||||
|
UCHAR Node = KeGetCurrentThread()->Process->IdealNode;
|
||||||
|
|
||||||
|
/* Validate the StackType */
|
||||||
|
if (StackType > MaximumReserveStacks)
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate a stack with Mm */
|
||||||
|
StackBase = MmCreateKernelStackEx(LargeStack, StackSize, Node);
|
||||||
|
if (StackBase == NULL)
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to allocate callout stack\n");
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Only commit as much as needed, but this function doesn't have a size parameter
|
||||||
|
// Use KiAllocateStackSegment
|
||||||
|
|
||||||
|
/* Get the stack control structure and initialize it */
|
||||||
|
StackControl = (PKSTACK_CONTROL)StackBase - 1;
|
||||||
|
StackControl->StackBase = (ULONG_PTR)StackBase;
|
||||||
|
StackControl->ActualLimit = (ULONG_PTR)StackBase - StackSize;
|
||||||
|
StackControl->StackExpansion = 1;
|
||||||
|
|
||||||
|
/* Return the stack control as context */
|
||||||
|
*StackContext = StackControl;
|
||||||
|
|
||||||
|
KiNumberOfCalloutStacks++;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief Allocate a callout stack
|
||||||
|
*
|
||||||
|
* @param LargeStack - TRUE if a large stack should be allocated, FALSE for a normal stack
|
||||||
|
*
|
||||||
|
* @return Pointer to the stack context on success, NULL if the stack could not be allocated
|
||||||
|
*/
|
||||||
|
_Must_inspect_result_
|
||||||
|
_IRQL_requires_max_(APC_LEVEL)
|
||||||
|
PVOID
|
||||||
|
NTAPI
|
||||||
|
KeAllocateCalloutStack(
|
||||||
|
_In_ BOOLEAN LargeStack)
|
||||||
|
{
|
||||||
|
KSTACK_TYPE StackType = LargeStack ? ReserveStackLarge : ReserveStackNormal;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PVOID StackContext;
|
||||||
|
|
||||||
|
/* Forward to KeAllocateCalloutStackEx */
|
||||||
|
Status = KeAllocateCalloutStackEx(StackType, 0, 0, &StackContext);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return StackContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief Free a callout stack
|
||||||
|
*
|
||||||
|
* @param Context - Pointer to the stack context
|
||||||
|
*/
|
||||||
|
_IRQL_requires_max_(APC_LEVEL)
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
KeFreeCalloutStack(
|
||||||
|
_In_ PVOID Context)
|
||||||
|
{
|
||||||
|
PKSTACK_CONTROL StackControl = (PKSTACK_CONTROL)Context;
|
||||||
|
SIZE_T StackSize;
|
||||||
|
BOOLEAN IsLargeStack;
|
||||||
|
|
||||||
|
/* Check if the stack is a large stack */
|
||||||
|
StackSize = StackControl->StackBase - StackControl->ActualLimit & ~1;
|
||||||
|
IsLargeStack = StackSize > KERNEL_STACK_SIZE;
|
||||||
|
|
||||||
|
/* Free the stack */
|
||||||
|
MmDeleteKernelStack((PVOID)StackControl->StackBase, IsLargeStack);
|
||||||
|
KiNumberOfCalloutStacks--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Free a callout stack
|
||||||
|
*
|
||||||
|
* @param StackContext - Pointer to the stack context
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
KiRemoveThreadCalloutStack(
|
||||||
|
_In_ PKTHREAD Thread)
|
||||||
|
{
|
||||||
|
PKSTACK_CONTROL StackControl;
|
||||||
|
|
||||||
|
ASSERT(Thread != KeGetCurrentThread());
|
||||||
|
|
||||||
|
ASSERT(Thread->CalloutActive);
|
||||||
|
Thread->CalloutActive--;
|
||||||
|
|
||||||
|
/* Unlink the callout stack */
|
||||||
|
StackControl = ((PKSTACK_CONTROL)Thread->StackBase) - 1;
|
||||||
|
Thread->StackBase = (PVOID)StackControl->Previous.StackBase;
|
||||||
|
Thread->StackLimit = StackControl->Previous.StackLimit;
|
||||||
|
Thread->KernelStack = (PVOID)StackControl->Previous.KernelStack;
|
||||||
|
Thread->InitialStack = (PVOID)StackControl->Previous.InitialStack;
|
||||||
|
|
||||||
|
/* Delete the callout stack */
|
||||||
|
KeFreeCalloutStack(StackControl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Expand the kernel stack and call a function
|
||||||
|
*
|
||||||
|
* @param Callout - Callout function to call
|
||||||
|
* @param Parameter - Parameter to pass to the callout function
|
||||||
|
* @param Size - Size of the stack to allocate
|
||||||
|
* @param Wait - TRUE if the callout should be called with interrupts enabled, FALSE if interrupts should be disabled
|
||||||
|
* @param Context - Reserved, must be NULL
|
||||||
|
*
|
||||||
|
* @return STATUS_SUCCESS on success,
|
||||||
|
* STATUS_INVALID_PARAMETER if the size is too large,
|
||||||
|
* STATUS_INSUFFICIENT_RESOURCES if the stack could not be allocated
|
||||||
|
*/
|
||||||
|
_Must_inspect_result_
|
||||||
|
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||||
|
static
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
KiAllocateStackSegmentAndCallout(
|
||||||
|
_In_ PEXPAND_STACK_CALLOUT Callout,
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_ SIZE_T Size,
|
||||||
|
_In_ BOOLEAN Wait,
|
||||||
|
_In_opt_ PVOID Context)
|
||||||
|
{
|
||||||
|
PKTHREAD CurrentThread = KeGetCurrentThread();
|
||||||
|
PKIPCR Pcr = (PKIPCR)KeGetPcr();
|
||||||
|
PKSTACK_CONTROL StackControl;
|
||||||
|
NTSTATUS Status;
|
||||||
|
KSTACK_TYPE StackType;
|
||||||
|
PVOID StackContext;
|
||||||
|
SIZE_T StackCommit;
|
||||||
|
BOOLEAN PreviousCalloutActive;
|
||||||
|
|
||||||
|
UNREFERENCED_PARAMETER(Wait);
|
||||||
|
UNREFERENCED_PARAMETER(Context);
|
||||||
|
|
||||||
|
ASSERT(__readeflags() & EFLAGS_INTERRUPT_MASK);
|
||||||
|
|
||||||
|
/* Check if the size is too large */
|
||||||
|
if (Size > MAXIMUM_EXPANSION_SIZE)
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allow a maximum of 5 stacks to be allocated before bailing out */
|
||||||
|
if (CurrentThread->CalloutActive >= 5)
|
||||||
|
{
|
||||||
|
return STATUS_STACK_OVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we need a large stack */
|
||||||
|
if ((Size > KERNEL_STACK_SIZE) || CurrentThread->LargeStack)
|
||||||
|
{
|
||||||
|
StackType = ReserveStackLarge;
|
||||||
|
StackCommit = KERNEL_LARGE_STACK_COMMIT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StackType = ReserveStackNormal;
|
||||||
|
StackCommit = KERNEL_STACK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate the stack */
|
||||||
|
Status = KeAllocateCalloutStackEx(StackType, 0, 0, &StackContext);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to allocate callout stack\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save previous CalloutActive and set it to TRUE */
|
||||||
|
PreviousCalloutActive = CurrentThread->CalloutActive;
|
||||||
|
CurrentThread->CalloutActive = TRUE;
|
||||||
|
|
||||||
|
/* Get the stack control from the context */
|
||||||
|
StackControl = (PKSTACK_CONTROL)StackContext;
|
||||||
|
|
||||||
|
/* Link the previous stack */
|
||||||
|
StackControl->Previous.StackBase = (ULONG_PTR)CurrentThread->StackBase;
|
||||||
|
StackControl->Previous.StackLimit = CurrentThread->StackLimit;
|
||||||
|
StackControl->Previous.KernelStack = (ULONG_PTR)CurrentThread->KernelStack;
|
||||||
|
StackControl->Previous.InitialStack = (ULONG_PTR)CurrentThread->InitialStack;
|
||||||
|
|
||||||
|
/* Disable interrupts */
|
||||||
|
_disable();
|
||||||
|
|
||||||
|
/* Set up the new stack in the thread */
|
||||||
|
CurrentThread->StackBase = (PVOID)StackControl->StackBase;
|
||||||
|
CurrentThread->StackLimit = StackControl->StackBase - StackCommit;
|
||||||
|
CurrentThread->InitialStack = StackControl;
|
||||||
|
CurrentThread->KernelStack = (PVOID)((ULONG_PTR)CurrentThread->InitialStack - sizeof(KTRAP_FRAME));
|
||||||
|
ASSERT(((ULONG_PTR)CurrentThread->KernelStack & 0xF) == 0);
|
||||||
|
|
||||||
|
#if defined(_M_AMD64)
|
||||||
|
/* Set up the new stack in the PRCB and TSS */
|
||||||
|
Pcr->Prcb.RspBase = (ULONG_PTR)CurrentThread->InitialStack;
|
||||||
|
Pcr->TssBase->Rsp0 = (ULONG_PTR)CurrentThread->InitialStack;
|
||||||
|
#elif defined(_M_IX86)
|
||||||
|
Pcr->TSS->Esp0 = (ULONG_PTR)CurrentThread->InitialStack - sizeof(FX_SAVE_AREA);
|
||||||
|
#else
|
||||||
|
UNIMPLEMENTED_DBGBREAK();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Switch to the new stack and invoke the callout function */
|
||||||
|
KiSwitchStackAndCallout(Parameter, Callout, CurrentThread->KernelStack);
|
||||||
|
|
||||||
|
/* Restore the old stack */
|
||||||
|
CurrentThread->StackBase = (PVOID)StackControl->Previous.StackBase;
|
||||||
|
CurrentThread->StackLimit = StackControl->Previous.StackLimit;
|
||||||
|
CurrentThread->KernelStack = (PVOID)StackControl->Previous.KernelStack;
|
||||||
|
CurrentThread->InitialStack = (PVOID)StackControl->Previous.InitialStack;
|
||||||
|
|
||||||
|
#if defined(_M_AMD64)
|
||||||
|
/* Restore the old stack in the PCR and TSS */
|
||||||
|
Pcr->Prcb.RspBase = (ULONG_PTR)CurrentThread->InitialStack;
|
||||||
|
Pcr->TssBase->Rsp0 = (ULONG_PTR)CurrentThread->InitialStack;
|
||||||
|
#elif defined(_M_IX86)
|
||||||
|
Pcr->TSS->Esp0 = (ULONG_PTR)CurrentThread->InitialStack - sizeof(FX_SAVE_AREA);
|
||||||
|
#else
|
||||||
|
UNIMPLEMENTED_DBGBREAK();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Enable interrupts */
|
||||||
|
_enable();
|
||||||
|
|
||||||
|
/* Restore CalloutActive */
|
||||||
|
CurrentThread->CalloutActive = PreviousCalloutActive;
|
||||||
|
|
||||||
|
/* Free the stack */
|
||||||
|
KeFreeCalloutStack(StackContext);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Expand the kernel stack to the requested size and call a function
|
||||||
|
*
|
||||||
|
* @param Callout - Callout function to call
|
||||||
|
* @param Parameter - Parameter to pass to the callout function
|
||||||
|
* @param Size - Size of the stack to allocate
|
||||||
|
* @param Wait - TRUE if the callout should be called with interrupts enabled, FALSE if interrupts should be disabled
|
||||||
|
* @param Context - Reserved, must be NULL
|
||||||
|
*
|
||||||
|
* @return STATUS_SUCCESS on success,
|
||||||
|
* STATUS_INVALID_PARAMETER if the size is too large,
|
||||||
|
* STATUS_INSUFFICIENT_RESOURCES if the stack could not be allocated
|
||||||
|
*/
|
||||||
|
ULONG g_Count;
|
||||||
|
_Must_inspect_result_
|
||||||
|
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
KeExpandKernelStackAndCalloutEx(
|
||||||
|
_In_ PEXPAND_STACK_CALLOUT Callout,
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_ SIZE_T Size,
|
||||||
|
_In_ BOOLEAN Wait,
|
||||||
|
_In_opt_ PVOID Context)
|
||||||
|
{
|
||||||
|
ULONG_PTR CurrentStackPointer;
|
||||||
|
SIZE_T RemainingStack;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Check if we already have enough space on the stack */
|
||||||
|
CurrentStackPointer = KiGetStackPointer();
|
||||||
|
RemainingStack = CurrentStackPointer - (ULONG_PTR)KeGetCurrentThread()->StackLimit;
|
||||||
|
if (RemainingStack >= Size)
|
||||||
|
{
|
||||||
|
/* We have enough space, just call the callout */
|
||||||
|
Callout(Parameter);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we have a large stack */
|
||||||
|
if (KeGetCurrentThread()->LargeStack)
|
||||||
|
{
|
||||||
|
/* Try to grow it */
|
||||||
|
Status = MmGrowKernelStackEx((PVOID)CurrentStackPointer, Size);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* We have enough space now, call the callout */
|
||||||
|
Callout(Parameter);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No luck, we need to allocate a new stack segment */
|
||||||
|
return KiAllocateStackSegmentAndCallout(Callout, Parameter, Size, Wait, Context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief Expand the kernel stack and call a function
|
||||||
|
*
|
||||||
|
* @param Callout - Callout function to call
|
||||||
|
* @param Parameter - Parameter to pass to the callout function
|
||||||
|
* @param Size - Size of the stack to allocate
|
||||||
|
*
|
||||||
|
* @return STATUS_SUCCESS on success,
|
||||||
|
* STATUS_INVALID_PARAMETER if the size is too large,
|
||||||
|
* STATUS_INSUFFICIENT_RESOURCES if the stack could not be allocated
|
||||||
|
*/
|
||||||
|
_Must_inspect_result_
|
||||||
|
_IRQL_requires_max_(APC_LEVEL)
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
KeExpandKernelStackAndCallout(
|
||||||
|
_In_ PEXPAND_STACK_CALLOUT Callout,
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_ SIZE_T Size)
|
||||||
|
{
|
||||||
|
return KeExpandKernelStackAndCalloutEx(Callout, Parameter, Size, FALSE, NULL);
|
||||||
|
}
|
|
@ -199,4 +199,27 @@ V86Switch:
|
||||||
pop esi
|
pop esi
|
||||||
ret 8
|
ret 8
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VOID
|
||||||
|
* NTAPI
|
||||||
|
* KiSwitchStackAndCallout(
|
||||||
|
* _In_opt_ PVOID Parameter,
|
||||||
|
* _In_ PEXPAND_STACK_CALLOUT Callout,
|
||||||
|
* _In_ PVOID Stack)
|
||||||
|
*/
|
||||||
|
PUBLIC _KiSwitchStackAndCallout@12
|
||||||
|
_KiSwitchStackAndCallout@12:
|
||||||
|
int 3
|
||||||
|
ret
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ULONG_PTR KiGetStackPointer(VOID);
|
||||||
|
*/
|
||||||
|
PUBLIC _KiGetStackPointer@0
|
||||||
|
_KiGetStackPointer@0:
|
||||||
|
|
||||||
|
/* Return the stack pointer */
|
||||||
|
lea eax, [esp + 8]
|
||||||
|
ret
|
||||||
|
|
||||||
END
|
END
|
||||||
|
|
|
@ -295,6 +295,12 @@ list(APPEND SOURCE
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/wmi/wmi.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/wmi/wmi.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/wmi/wmidrv.c)
|
${REACTOS_SOURCE_DIR}/ntoskrnl/wmi/wmidrv.c)
|
||||||
|
|
||||||
|
if(DLL_EXPORT_VERSION GREATER_EQUAL 0x600)
|
||||||
|
list(APPEND SOURCE
|
||||||
|
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/callout.c
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(DBG)
|
if(DBG)
|
||||||
list(APPEND SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/se/debug.c)
|
list(APPEND SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/se/debug.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -582,7 +582,9 @@
|
||||||
@ stdcall KeEnterCriticalRegion() _KeEnterCriticalRegion
|
@ stdcall KeEnterCriticalRegion() _KeEnterCriticalRegion
|
||||||
@ stdcall KeEnterGuardedRegion() _KeEnterGuardedRegion
|
@ stdcall KeEnterGuardedRegion() _KeEnterGuardedRegion
|
||||||
@ stdcall KeEnterKernelDebugger()
|
@ stdcall KeEnterKernelDebugger()
|
||||||
;@ stdcall -arch=x86_64 KeExpandKernelStackAndCallout(ptr ptr double)
|
@ stdcall -version=0x502 -arch=x86_64 KeExpandKernelStackAndCallout(ptr ptr ptr)
|
||||||
|
@ stdcall -version=0x600+ KeExpandKernelStackAndCallout(ptr ptr ptr long ptr)
|
||||||
|
@ stdcall -version=0x600+ KeExpandKernelStackAndCalloutEx(ptr ptr ptr long ptr)
|
||||||
@ stdcall KeFindConfigurationEntry(ptr long long ptr)
|
@ stdcall KeFindConfigurationEntry(ptr long long ptr)
|
||||||
@ stdcall KeFindConfigurationNextEntry(ptr long long ptr ptr)
|
@ stdcall KeFindConfigurationNextEntry(ptr long long ptr ptr)
|
||||||
@ stdcall KeFlushEntireTb(long long)
|
@ stdcall KeFlushEntireTb(long long)
|
||||||
|
|
55
sdk/include/minwin/ntosifs.h
Normal file
55
sdk/include/minwin/ntosifs.h
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#define _NTOSIFS_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (NTDDI_VERSION >= NTDDI_VISTA) || defined(__REACTOS__)
|
||||||
|
|
||||||
|
_Must_inspect_result_
|
||||||
|
_IRQL_requires_min_(PASSIVE_LEVEL)
|
||||||
|
_IRQL_requires_max_(APC_LEVEL)
|
||||||
|
NTKERNELAPI
|
||||||
|
PVOID
|
||||||
|
NTAPI
|
||||||
|
KeAllocateCalloutStack(
|
||||||
|
_In_ BOOLEAN LargeStack);
|
||||||
|
|
||||||
|
_IRQL_requires_min_(PASSIVE_LEVEL)
|
||||||
|
_IRQL_requires_max_(APC_LEVEL)
|
||||||
|
NTKERNELAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
KeFreeCalloutStack (
|
||||||
|
_In_ PVOID Context);
|
||||||
|
|
||||||
|
#endif // (NTDDI_VERSION >= NTDDI_VISTA) || defined(__REACTOS__)
|
||||||
|
|
||||||
|
#if (NTDDI_VERSION >= NTDDI_WIN7) || defined(__REACTOS__)
|
||||||
|
|
||||||
|
typedef enum _KSTACK_TYPE
|
||||||
|
{
|
||||||
|
ReserveStackNormal = 0,
|
||||||
|
ReserveStackLarge,
|
||||||
|
MaximumReserveStacks
|
||||||
|
} KSTACK_TYPE;
|
||||||
|
|
||||||
|
_Must_inspect_result_
|
||||||
|
_IRQL_requires_max_(APC_LEVEL)
|
||||||
|
_IRQL_requires_min_(PASSIVE_LEVEL)
|
||||||
|
NTKERNELAPI
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
KeAllocateCalloutStackEx(
|
||||||
|
_In_ _Strict_type_match_ KSTACK_TYPE StackType,
|
||||||
|
_In_ UCHAR RecursionDepth,
|
||||||
|
_Reserved_ SIZE_T Reserved,
|
||||||
|
_Outptr_ PVOID *StackContext);
|
||||||
|
|
||||||
|
#endif // (NTDDI_VERSION >= NTDDI_WIN7) || defined(__REACTOS__)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
|
@ -2176,6 +2176,25 @@ typedef struct _KENTROPY_TIMING_STATE
|
||||||
|
|
||||||
#endif /* (NTDDI_VERSION >= NTDDI_WIN8) */
|
#endif /* (NTDDI_VERSION >= NTDDI_WIN8) */
|
||||||
|
|
||||||
|
typedef struct _KERNEL_STACK_SEGMENT
|
||||||
|
{
|
||||||
|
ULONG_PTR StackBase;
|
||||||
|
ULONG_PTR StackLimit;
|
||||||
|
ULONG_PTR KernelStack;
|
||||||
|
ULONG_PTR InitialStack;
|
||||||
|
} KERNEL_STACK_SEGMENT, *PKERNEL_STACK_SEGMENT;
|
||||||
|
|
||||||
|
typedef struct _KSTACK_CONTROL
|
||||||
|
{
|
||||||
|
ULONG_PTR StackBase;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
ULONG_PTR ActualLimit;
|
||||||
|
ULONG_PTR StackExpansion : 1;
|
||||||
|
};
|
||||||
|
KERNEL_STACK_SEGMENT Previous;
|
||||||
|
} KSTACK_CONTROL, *PKSTACK_CONTROL;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Exported Loader Parameter Block
|
// Exported Loader Parameter Block
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue