mirror of
https://github.com/reactos/reactos.git
synced 2024-12-14 06:33:30 +08:00
129 lines
4.1 KiB
C
129 lines
4.1 KiB
C
/*
|
|
* PROJECT: ReactOS Kernel
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
* FILE: ntoskrnl/ps/win32.c
|
|
* PURPOSE: Process Manager: Win32K Initialization and Support
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
|
*/
|
|
|
|
/* INCLUDES ****************************************************************/
|
|
|
|
#include <ntoskrnl.h>
|
|
#include <winerror.h>
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
/* GLOBALS ******************************************************************/
|
|
|
|
PKWIN32_PROCESS_CALLOUT PspW32ProcessCallout = NULL;
|
|
PKWIN32_THREAD_CALLOUT PspW32ThreadCallout = NULL;
|
|
PGDI_BATCHFLUSH_ROUTINE KeGdiFlushUserBatch = NULL;
|
|
extern PKWIN32_SESSION_CALLOUT ExpWindowStationObjectParse;
|
|
extern PKWIN32_SESSION_CALLOUT ExpWindowStationObjectDelete;
|
|
extern PKWIN32_SESSION_CALLOUT ExpWindowStationObjectOkToClose;
|
|
extern PKWIN32_SESSION_CALLOUT ExpDesktopObjectOkToClose;
|
|
extern PKWIN32_SESSION_CALLOUT ExpDesktopObjectDelete;
|
|
extern PKWIN32_SESSION_CALLOUT ExpDesktopObjectOpen;
|
|
extern PKWIN32_SESSION_CALLOUT ExpDesktopObjectClose;
|
|
extern PKWIN32_POWEREVENT_CALLOUT PopEventCallout;
|
|
|
|
/* PRIVATE FUNCTIONS *********************************************************/
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
PsConvertToGuiThread(VOID)
|
|
{
|
|
ULONG_PTR NewStack;
|
|
PVOID OldStack;
|
|
PETHREAD Thread = PsGetCurrentThread();
|
|
PEPROCESS Process = PsGetCurrentProcess();
|
|
NTSTATUS Status;
|
|
PAGED_CODE();
|
|
|
|
/* Validate the previous mode */
|
|
if (KeGetPreviousMode() == KernelMode) return STATUS_INVALID_PARAMETER;
|
|
|
|
/* If no win32k, crashes later */
|
|
ASSERT(PspW32ProcessCallout != NULL);
|
|
|
|
/* Make sure win32k is here */
|
|
if (!PspW32ProcessCallout) return STATUS_ACCESS_DENIED;
|
|
|
|
/* Make sure it's not already win32 */
|
|
if (Thread->Tcb.ServiceTable != KeServiceDescriptorTable)
|
|
{
|
|
/* We're already a win32 thread */
|
|
return STATUS_ALREADY_WIN32;
|
|
}
|
|
|
|
/* Check if we don't already have a kernel-mode stack */
|
|
if (!Thread->Tcb.LargeStack)
|
|
{
|
|
/* We don't create one */
|
|
NewStack = (ULONG_PTR)MmCreateKernelStack(TRUE, 0);
|
|
if (!NewStack)
|
|
{
|
|
/* Panic in user-mode */
|
|
NtCurrentTeb()->LastErrorValue = ERROR_NOT_ENOUGH_MEMORY;
|
|
return STATUS_NO_MEMORY;
|
|
}
|
|
|
|
/* We're about to switch stacks. Enter a guarded region */
|
|
KeEnterGuardedRegion();
|
|
|
|
/* Switch stacks */
|
|
OldStack = KeSwitchKernelStack((PVOID)NewStack,
|
|
(PVOID)(NewStack - KERNEL_STACK_SIZE));
|
|
|
|
/* Leave the guarded region */
|
|
KeLeaveGuardedRegion();
|
|
|
|
/* Delete the old stack */
|
|
MmDeleteKernelStack(OldStack, FALSE);
|
|
}
|
|
|
|
/* Always do the process callout! */
|
|
Status = PspW32ProcessCallout(Process, TRUE);
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
/* Set the new service table */
|
|
Thread->Tcb.ServiceTable = KeServiceDescriptorTableShadow;
|
|
ASSERT(Thread->Tcb.Win32Thread == 0);
|
|
|
|
/* Tell Win32k about our thread */
|
|
Status = PspW32ThreadCallout(Thread, PsW32ThreadCalloutInitialize);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
/* Revert our table */
|
|
Thread->Tcb.ServiceTable = KeServiceDescriptorTable;
|
|
}
|
|
|
|
/* Return status */
|
|
return Status;
|
|
}
|
|
|
|
/* PUBLIC FUNCTIONS **********************************************************/
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
VOID
|
|
NTAPI
|
|
PsEstablishWin32Callouts(IN PWIN32_CALLOUTS_FPNS CalloutData)
|
|
{
|
|
/* Setup the callback pointers */
|
|
PspW32ProcessCallout = CalloutData->ProcessCallout;
|
|
PspW32ThreadCallout = CalloutData->ThreadCallout;
|
|
ExpWindowStationObjectParse = CalloutData->WindowStationParseProcedure;
|
|
ExpWindowStationObjectDelete = CalloutData->WindowStationDeleteProcedure;
|
|
ExpWindowStationObjectOkToClose = CalloutData->WindowStationOkToCloseProcedure;
|
|
ExpDesktopObjectOkToClose = CalloutData->DesktopOkToCloseProcedure;
|
|
ExpDesktopObjectDelete = CalloutData->DesktopDeleteProcedure;
|
|
ExpDesktopObjectOpen = CalloutData->DesktopOpenProcedure;
|
|
ExpDesktopObjectClose = CalloutData->DesktopCloseProcedure;
|
|
PopEventCallout = CalloutData->PowerEventCallout;
|
|
KeGdiFlushUserBatch = CalloutData->BatchFlushRoutine;
|
|
}
|
|
|
|
/* EOF */
|