- 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.
Modified: trunk/reactos/ntoskrnl/ke/i386/syscall.S
Modified: trunk/reactos/ntoskrnl/ke/kthread.c
Modified: trunk/reactos/ntoskrnl/ps/win32.c
_____
Modified: trunk/reactos/ntoskrnl/ke/i386/syscall.S
--- trunk/reactos/ntoskrnl/ke/i386/syscall.S 2006-01-11 05:24:40 UTC
(rev 20778)
+++ trunk/reactos/ntoskrnl/ke/i386/syscall.S 2006-01-11 05:42:32 UTC
(rev 20779)
@@ -614,7 +614,7 @@
/* Set up Win32K Table */
push edx
push ebx
- call _KiServiceCheck@0
+ call _PsConvertToGuiThread@0
/* FIXME: Handle failure */
pop eax
_____
Modified: trunk/reactos/ntoskrnl/ke/kthread.c
--- trunk/reactos/ntoskrnl/ke/kthread.c 2006-01-11 05:24:40 UTC (rev
20778)
+++ trunk/reactos/ntoskrnl/ke/kthread.c 2006-01-11 05:42:32 UTC (rev
20779)
@@ -1466,21 +1466,6 @@
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
_____
Modified: trunk/reactos/ntoskrnl/ps/win32.c
--- trunk/reactos/ntoskrnl/ps/win32.c 2006-01-11 05:24:40 UTC (rev
20778)
+++ trunk/reactos/ntoskrnl/ps/win32.c 2006-01-11 05:42:32 UTC (rev
20779)
@@ -41,6 +41,13 @@
} NTW32CALL_SAVED_STATE, *PNTW32CALL_SAVED_STATE;
#endif
+PVOID
+STDCALL
+KeSwitchKernelStack(
+ IN PVOID StackBase,
+ IN PVOID StackLimit
+);
+
/* FUNCTIONS
***************************************************************/
/*
@@ -62,33 +69,105 @@
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;
+ /* Validate the previous mode */
+ if (KeGetPreviousMode() == KernelMode)
+ {
+ DPRINT1("Danger: win32k call being made in kernel-mode?!\n");
+ return STATUS_INVALID_PARAMETER;
+ }
- if (Process->Win32Process == NULL)
+ /* Make sure win32k is here */
+ if (!PspWin32ProcessCallback)
{
- if (PspWin32ProcessCallback != NULL)
+ 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
- if (Thread->Tcb.Win32Thread == NULL)
+ /* This check is bizare. Check out win32k later */
+ if (!Process->Win32Process)
{
- if (PspWin32ThreadCallback != NULL)
+ /* Now tell win32k about us */
+ Status = PspWin32ProcessCallback(Process, TRUE);
+ if (!NT_SUCCESS(Status))
{
- Status = PspWin32ThreadCallback(Thread, TRUE);
+ DPRINT1("Danger: Win32k wasn't happy about us!\n");
+ return Status;
}
}
+ /* 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))
+ {
+ /* 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 @@
}
}
-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,