From 7816643eb5247615c330b8cdf9bcbe45f18a6a6d Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 11 Jan 2006 05:42:32 +0000 Subject: [PATCH] - Remove KiServiceCheck and implement PsConvertToGuiThread in its place. Has support for detecting and returning errors in case of invalid cases, currently disabled code for doing the required 4kb->12kb stack conversion, and handling certain failures. svn path=/trunk/; revision=20779 --- reactos/ntoskrnl/ke/i386/syscall.S | 2 +- reactos/ntoskrnl/ke/kthread.c | 15 --- reactos/ntoskrnl/ps/win32.c | 173 ++++++++++++++++------------- 3 files changed, 94 insertions(+), 96 deletions(-) diff --git a/reactos/ntoskrnl/ke/i386/syscall.S b/reactos/ntoskrnl/ke/i386/syscall.S index 7fc9b7372df..8b02df443c9 100644 --- a/reactos/ntoskrnl/ke/i386/syscall.S +++ b/reactos/ntoskrnl/ke/i386/syscall.S @@ -614,7 +614,7 @@ KiBBTUnexpectedRange: /* Set up Win32K Table */ push edx push ebx - call _KiServiceCheck@0 + call _PsConvertToGuiThread@0 /* FIXME: Handle failure */ pop eax diff --git a/reactos/ntoskrnl/ke/kthread.c b/reactos/ntoskrnl/ke/kthread.c index 72a643a1e78..b9ccbec93ac 100644 --- a/reactos/ntoskrnl/ke/kthread.c +++ b/reactos/ntoskrnl/ke/kthread.c @@ -1466,21 +1466,6 @@ KeTestAlertThread(IN KPROCESSOR_MODE AlertMode) return OldState; } -VOID -NTAPI -KiServiceCheck(VOID) -{ - PKTHREAD Thread = KeGetCurrentThread(); - - /* Check if we need to inialize Win32 for this Thread */ - if (Thread->ServiceTable != KeServiceDescriptorTableShadow) { - - /* We do. Initialize it and save the new table */ - Thread->ServiceTable = KeServiceDescriptorTableShadow; - PsInitWin32Thread((PETHREAD)Thread); - } -} - /* * * NOT EXPORTED diff --git a/reactos/ntoskrnl/ps/win32.c b/reactos/ntoskrnl/ps/win32.c index ee5590ce0fa..082d9e70fdb 100644 --- a/reactos/ntoskrnl/ps/win32.c +++ b/reactos/ntoskrnl/ps/win32.c @@ -41,6 +41,13 @@ typedef struct _NTW32CALL_SAVED_STATE } NTW32CALL_SAVED_STATE, *PNTW32CALL_SAVED_STATE; #endif +PVOID +STDCALL +KeSwitchKernelStack( + IN PVOID StackBase, + IN PVOID StackLimit +); + /* FUNCTIONS ***************************************************************/ /* @@ -62,33 +69,105 @@ PsEstablishWin32Callouts(PW32_CALLOUT_DATA CalloutData) NTSTATUS NTAPI -PsInitWin32Thread (PETHREAD Thread) +PsConvertToGuiThread(VOID) { - PEPROCESS Process; - NTSTATUS Status = STATUS_SUCCESS; + //PVOID NewStack, OldStack; + PETHREAD Thread = PsGetCurrentThread(); + PEPROCESS Process = PsGetCurrentProcess(); + NTSTATUS Status; + PAGED_CODE(); - Process = Thread->ThreadsProcess; - - if (Process->Win32Process == NULL) + /* Validate the previous mode */ + if (KeGetPreviousMode() == KernelMode) { - if (PspWin32ProcessCallback != NULL) + DPRINT1("Danger: win32k call being made in kernel-mode?!\n"); + return STATUS_INVALID_PARAMETER; + } + + /* Make sure win32k is here */ + if (!PspWin32ProcessCallback) + { + DPRINT1("Danger: Win32K call attempted but Win32k not ready!\n"); + return STATUS_ACCESS_DENIED; + } + + /* Make sure it's not already win32 */ + if (Thread->Tcb.ServiceTable != KeServiceDescriptorTable) + { + DPRINT1("Danger: Thread is already a win32 thread. Limit bypassed?\n"); + return STATUS_ALREADY_WIN32; + } + + /* Check if we don't already have a kernel-mode stack */ +#if 0 + if (!Thread->Tcb.LargeStack) + { + /* We don't create one */ + DPRINT1("Creating large stack\n"); + NewStack = MmCreateKernelStack(TRUE); + if (!NewStack) { - Status = PspWin32ProcessCallback(Process, TRUE); + /* Panic in user-mode */ + NtCurrentTeb()->LastErrorValue = ERROR_NOT_ENOUGH_MEMORY; + return STATUS_NO_MEMORY; + } + + /* We're about to switch stacks. Enter a critical region */ + KeEnterCriticalRegion(); + + /* Switch stacks */ + DPRINT1("Switching stacks. NS IT, SL, SB, KS %p %p %p %p %p\n", + NewStack, + Thread->Tcb.InitialStack, + Thread->Tcb.StackLimit, + Thread->Tcb.StackBase, + Thread->Tcb.KernelStack); + OldStack = KeSwitchKernelStack((PVOID)((ULONG_PTR)NewStack + 0x3000), + NewStack); + + /* Leave the critical region */ + KeLeaveCriticalRegion(); + DPRINT1("We made it!\n"); + + /* Delete the old stack */ + //MmDeleteKernelStack(OldStack, FALSE); + DPRINT1("Old stack deleted. IT, SL, SB, KS %p %p %p %p\n", + Thread->Tcb.InitialStack, + Thread->Tcb.StackLimit, + Thread->Tcb.StackBase, + Thread->Tcb.KernelStack); + } +#endif + + /* This check is bizare. Check out win32k later */ + if (!Process->Win32Process) + { + /* Now tell win32k about us */ + Status = PspWin32ProcessCallback(Process, TRUE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Danger: Win32k wasn't happy about us!\n"); + return Status; } } - if (Thread->Tcb.Win32Thread == NULL) + /* Set the new service table */ + Thread->Tcb.ServiceTable = KeServiceDescriptorTableShadow; + ASSERT(Thread->Tcb.Win32Thread == 0); + + /* Tell Win32k about our thread */ + Status = PspWin32ThreadCallback(Thread, TRUE); + if (!NT_SUCCESS(Status)) { - if (PspWin32ThreadCallback != NULL) - { - Status = PspWin32ThreadCallback(Thread, TRUE); - } + /* Revert our table */ + DPRINT1("Danger: Win32k wasn't happy about us!\n"); + Thread->Tcb.ServiceTable = KeServiceDescriptorTable; } + /* Return status */ return Status; } - VOID NTAPI PsTerminateWin32Process (PEPROCESS Process) @@ -122,72 +201,6 @@ PsTerminateWin32Thread (PETHREAD Thread) } } -VOID -STDCALL -DumpEspData(ULONG Esp, ULONG ThLimit, ULONG ThStack, ULONG PcrLimit, ULONG PcrStack, ULONG Esp0) -{ - DPRINT1("Current Esp: %p\n Thread Stack Limit: %p\n Thread Stack: %p\n Pcr Limit: %p, Pcr Stack: %p\n Esp0 :%p\n",Esp, ThLimit, ThStack, PcrLimit, PcrStack, Esp0) ; -} - - PVOID -STDCALL - PsAllocateCallbackStack(ULONG StackSize) - { - PVOID KernelStack = NULL; - NTSTATUS Status; - PMEMORY_AREA StackArea; - ULONG i, j; - PHYSICAL_ADDRESS BoundaryAddressMultiple; - PPFN_TYPE Pages = alloca(sizeof(PFN_TYPE) * (StackSize /PAGE_SIZE)); - - DPRINT1("PsAllocateCallbackStack\n"); - BoundaryAddressMultiple.QuadPart = 0; - StackSize = PAGE_ROUND_UP(StackSize); - MmLockAddressSpace(MmGetKernelAddressSpace()); - Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), - MEMORY_AREA_KERNEL_STACK, - &KernelStack, - StackSize, - PAGE_READWRITE, - &StackArea, - FALSE, - 0, - BoundaryAddressMultiple); - MmUnlockAddressSpace(MmGetKernelAddressSpace()); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to create thread stack\n"); - return(NULL); - } - for (i = 0; i < (StackSize / PAGE_SIZE); i++) - { - Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Pages[i]); - if (!NT_SUCCESS(Status)) - { - for (j = 0; j < i; j++) - { - MmReleasePageMemoryConsumer(MC_NPPOOL, Pages[j]); - } - return(NULL); - } - } - Status = MmCreateVirtualMapping(NULL, - KernelStack, - PAGE_READWRITE, - Pages, - StackSize / PAGE_SIZE); - if (!NT_SUCCESS(Status)) - { - for (i = 0; i < (StackSize / PAGE_SIZE); i++) - { - MmReleasePageMemoryConsumer(MC_NPPOOL, Pages[i]); - } - return(NULL); - } - DPRINT1("PsAllocateCallbackStack %x\n", KernelStack); - return(KernelStack); -} - NTSTATUS STDCALL NtW32Call(IN ULONG RoutineIndex,