- Remove usercall.c from portable part of Ke and add it to ke\i386. The implementation is slightly arch-specific.

- Remove code in userapc.c and move it into usercall.c, since both functions basically deal with user-mode callouts.
- Handle STATUS_CALLBACK_POP_STACK and add the status to ntstatus.h
- Also handle future support for GDI Batch flushing.

svn path=/trunk/; revision=24089
This commit is contained in:
Alex Ionescu 2006-09-13 01:00:50 +00:00
parent a614833b08
commit 07a0973e21
5 changed files with 453 additions and 349 deletions

View file

@ -877,6 +877,7 @@ extern "C" {
#define STATUS_PKINIT_CLIENT_FAILURE ((NTSTATUS)0xC000038CL) #define STATUS_PKINIT_CLIENT_FAILURE ((NTSTATUS)0xC000038CL)
#define STATUS_SMARTCARD_CERT_EXPIRED ((NTSTATUS)0xC000038DL) #define STATUS_SMARTCARD_CERT_EXPIRED ((NTSTATUS)0xC000038DL)
#define STATUS_DRIVER_FAILED_PRIOR_UNLOAD ((NTSTATUS)0xC000038EL) #define STATUS_DRIVER_FAILED_PRIOR_UNLOAD ((NTSTATUS)0xC000038EL)
#define STATUS_CALLBACK_POP_STACK ((NTSTATUS)0xC0000423L)
#define STATUS_WOW_ASSERTION ((NTSTATUS)0xC0009898L) #define STATUS_WOW_ASSERTION ((NTSTATUS)0xC0009898L)
#define RPC_NT_INVALID_STRING_BINDING ((NTSTATUS)0xC0020001L) #define RPC_NT_INVALID_STRING_BINDING ((NTSTATUS)0xC0020001L)
#define RPC_NT_WRONG_KIND_OF_BINDING ((NTSTATUS)0xC0020002L) #define RPC_NT_WRONG_KIND_OF_BINDING ((NTSTATUS)0xC0020002L)

View file

@ -921,6 +921,7 @@
#define STATUS_AUTHENTICATION_FIREWALL_FAILED ((NTSTATUS)0xC0000413) #define STATUS_AUTHENTICATION_FIREWALL_FAILED ((NTSTATUS)0xC0000413)
#define STATUS_VDM_DISALLOWED ((NTSTATUS)0xC0000414) #define STATUS_VDM_DISALLOWED ((NTSTATUS)0xC0000414)
#define STATUS_HUNG_DISPLAY_DRIVER_THREAD ((NTSTATUS)0xC0000415) #define STATUS_HUNG_DISPLAY_DRIVER_THREAD ((NTSTATUS)0xC0000415)
#define STATUS_CALLBACK_POP_STACK ((NTSTATUS)0xC0000423)
#define STATUS_WOW_ASSERTION ((NTSTATUS)0xC0009898) #define STATUS_WOW_ASSERTION ((NTSTATUS)0xC0009898)
#define RPC_NT_INVALID_STRING_BINDING ((NTSTATUS)0xC0020001) #define RPC_NT_INVALID_STRING_BINDING ((NTSTATUS)0xC0020001)

View file

@ -823,6 +823,19 @@ KiInsertQueueApc(
IN KPRIORITY PriorityBoost IN KPRIORITY PriorityBoost
); );
NTSTATUS
NTAPI
KiCallUserMode(
IN PVOID *OutputBuffer,
IN PULONG OutputLength
);
PULONG
NTAPI
KiGetUserModeStackAddress(
VOID
);
#include "ke_x.h" #include "ke_x.h"
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_KE_H */ #endif /* __NTOSKRNL_INCLUDE_INTERNAL_KE_H */

View file

@ -1,16 +1,16 @@
/* /*
* PROJECT: ReactOS Kernel * PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ke/i386/userapc.c * FILE: ntoskrnl/ke/i386/usercall.c
* PURPOSE: Implements User-Mode APC Initialization * PURPOSE: User-mode Callout Mechanisms (APC and Win32K Callbacks)
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/ */
/* INCLUDES *****************************************************************/ /* INCLUDES ******************************************************************/
#include <ntoskrnl.h> #include <ntoskrnl.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <internal/debug.h>
/* PRIVATE FUNCTIONS *********************************************************/ /* PRIVATE FUNCTIONS *********************************************************/
@ -56,7 +56,7 @@ _SEH_FILTER(KiCopyInformation2)
* *
*--*/ *--*/
VOID VOID
STDCALL NTAPI
KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame, KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame,
IN PKTRAP_FRAME TrapFrame, IN PKTRAP_FRAME TrapFrame,
IN PKNORMAL_ROUTINE NormalRoutine, IN PKNORMAL_ROUTINE NormalRoutine,
@ -134,3 +134,93 @@ KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame,
_SEH_END; _SEH_END;
} }
/* PUBLIC FUNCTIONS **********************************************************/
/*
* @implemented
*/
NTSTATUS
NTAPI
KeUserModeCallback(IN ULONG RoutineIndex,
IN PVOID Argument,
IN ULONG ArgumentLength,
OUT PVOID *Result,
OUT PULONG ResultLength)
{
ULONG_PTR NewStack, OldStack;
PULONG UserEsp;
NTSTATUS CallbackStatus = STATUS_SUCCESS;
PEXCEPTION_REGISTRATION_RECORD ExceptionList;
PTEB Teb;
ULONG GdiBatchCount = 0;
ASSERT(KeGetCurrentThread()->ApcState.KernelApcInProgress == FALSE);
ASSERT(KeGetPreviousMode() == UserMode);
/* Get the current user-mode stack */
UserEsp = KiGetUserModeStackAddress();
OldStack = *UserEsp;
/* Enter a SEH Block */
_SEH_TRY
{
/* Calculate and align the stack size */
NewStack = (OldStack - ArgumentLength) & ~3;
/* Make sure it's writable */
ProbeForWrite((PVOID)(NewStack - 6 * sizeof(ULONG_PTR)),
ArgumentLength + 6 * sizeof(ULONG_PTR),
sizeof(CHAR));
/* Copy the buffer into the stack */
RtlCopyMemory((PVOID)NewStack, Argument, ArgumentLength);
/* Write the arguments */
NewStack -= 24;
*(PULONG)NewStack = 0;
*(PULONG)(NewStack + 4) = RoutineIndex;
*(PULONG)(NewStack + 8) = (NewStack + 24);
*(PULONG)(NewStack + 12) = ArgumentLength;
/* Save the exception list */
Teb = KeGetCurrentThread()->Teb;
ExceptionList = Teb->Tib.ExceptionList;
/* Jump to user mode */
*UserEsp = NewStack;
CallbackStatus = KiCallUserMode(Result, ResultLength);
if (CallbackStatus != STATUS_CALLBACK_POP_STACK)
{
/* Only restore the exception list if we didn't crash in ring 3 */
Teb->Tib.ExceptionList = ExceptionList;
CallbackStatus = STATUS_SUCCESS;
}
else
{
/* Otherwise, pop the stack */
OldStack = *UserEsp;
}
/* Read the GDI Batch count */
GdiBatchCount = Teb->GdiBatchCount;
}
_SEH_HANDLE
{
/* Get the SEH exception */
CallbackStatus = _SEH_GetExceptionCode();
}
_SEH_END;
if (!NT_SUCCESS(CallbackStatus)) return CallbackStatus;
/* Check if we have GDI Batch operations */
if (GdiBatchCount)
{
/* Shouldn't happen in ROS yet */
ASSERT(FALSE);
}
/* Restore stack and return */
*UserEsp = OldStack;
return CallbackStatus;
}
/* EOF */

View file

@ -40,7 +40,7 @@
<file>thread.c</file> <file>thread.c</file>
<file>trap.s</file> <file>trap.s</file>
<file>usercall_asm.S</file> <file>usercall_asm.S</file>
<file>userapc.c</file> <file>usercall.c</file>
<file>v86vdm.c</file> <file>v86vdm.c</file>
<file>v86m_sup.S</file> <file>v86m_sup.S</file>
</directory> </directory>
@ -67,7 +67,6 @@
<file>thrdschd.c</file> <file>thrdschd.c</file>
<file>thrdobj.c</file> <file>thrdobj.c</file>
<file>timer.c</file> <file>timer.c</file>
<file>usercall.c</file>
<file>wait.c</file> <file>wait.c</file>
</directory> </directory>
<directory name="deprecated"> <directory name="deprecated">