mirror of
https://github.com/reactos/reactos.git
synced 2025-07-14 09:34:13 +00:00
- 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
This commit is contained in:
parent
c193938e1b
commit
7816643eb5
3 changed files with 94 additions and 96 deletions
|
@ -614,7 +614,7 @@ KiBBTUnexpectedRange:
|
||||||
/* Set up Win32K Table */
|
/* Set up Win32K Table */
|
||||||
push edx
|
push edx
|
||||||
push ebx
|
push ebx
|
||||||
call _KiServiceCheck@0
|
call _PsConvertToGuiThread@0
|
||||||
|
|
||||||
/* FIXME: Handle failure */
|
/* FIXME: Handle failure */
|
||||||
pop eax
|
pop eax
|
||||||
|
|
|
@ -1466,21 +1466,6 @@ KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)
|
||||||
return OldState;
|
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
|
* NOT EXPORTED
|
||||||
|
|
|
@ -41,6 +41,13 @@ typedef struct _NTW32CALL_SAVED_STATE
|
||||||
} NTW32CALL_SAVED_STATE, *PNTW32CALL_SAVED_STATE;
|
} NTW32CALL_SAVED_STATE, *PNTW32CALL_SAVED_STATE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
STDCALL
|
||||||
|
KeSwitchKernelStack(
|
||||||
|
IN PVOID StackBase,
|
||||||
|
IN PVOID StackLimit
|
||||||
|
);
|
||||||
|
|
||||||
/* FUNCTIONS ***************************************************************/
|
/* FUNCTIONS ***************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -62,33 +69,105 @@ PsEstablishWin32Callouts(PW32_CALLOUT_DATA CalloutData)
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
PsInitWin32Thread (PETHREAD Thread)
|
PsConvertToGuiThread(VOID)
|
||||||
{
|
{
|
||||||
PEPROCESS Process;
|
//PVOID NewStack, OldStack;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
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)
|
||||||
|
{
|
||||||
|
/* 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);
|
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;
|
||||||
if (PspWin32ThreadCallback != NULL)
|
ASSERT(Thread->Tcb.Win32Thread == 0);
|
||||||
{
|
|
||||||
|
/* Tell Win32k about our thread */
|
||||||
Status = PspWin32ThreadCallback(Thread, TRUE);
|
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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
PsTerminateWin32Process (PEPROCESS Process)
|
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
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
NtW32Call(IN ULONG RoutineIndex,
|
NtW32Call(IN ULONG RoutineIndex,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue