mirror of
https://github.com/reactos/reactos.git
synced 2024-07-01 18:24:24 +00:00
Implement PsSetLegoNotifyRoutine and PsRemoveCreateThreadNotifyroutine. Clean up ps/thread.c, move things to their own subsystem, do proper TEB Allocation with MmCreateTeb, remove TEB EPROCESS hack fields. Rename PsFrezeAllThreads to KeFreezeAllThreads and implement a working version.
svn path=/trunk/; revision=14663
This commit is contained in:
parent
f4d2ac0b1e
commit
6829bd8c8b
|
@ -461,7 +461,7 @@ ExpInitializeExecutive(VOID)
|
||||||
|
|
||||||
/* Set up the Kernel and Process Manager for this CPU */
|
/* Set up the Kernel and Process Manager for this CPU */
|
||||||
KePrepareForApplicationProcessorInit(KeNumberProcessors);
|
KePrepareForApplicationProcessorInit(KeNumberProcessors);
|
||||||
PsPrepareForApplicationProcessorInit(KeNumberProcessors);
|
KeCreateApplicationProcessorIdleThread(KeNumberProcessors);
|
||||||
|
|
||||||
/* Allocate a stack for use when booting the processor */
|
/* Allocate a stack for use when booting the processor */
|
||||||
ProcessorStack = Ki386InitialStackArray[((int)KeNumberProcessors)] + MM_STACK_SIZE;
|
ProcessorStack = Ki386InitialStackArray[((int)KeNumberProcessors)] + MM_STACK_SIZE;
|
||||||
|
|
|
@ -587,8 +587,13 @@ QSI_DEF(SystemProcessInformation)
|
||||||
|
|
||||||
SpiCur = (PSYSTEM_PROCESSES)pCur;
|
SpiCur = (PSYSTEM_PROCESSES)pCur;
|
||||||
|
|
||||||
nThreads = PsEnumThreadsByProcess(pr);
|
current_entry = pr->ThreadListHead.Flink;
|
||||||
|
while (current_entry != &pr->ThreadListHead)
|
||||||
|
{
|
||||||
|
nThreads++;
|
||||||
|
current_entry = current_entry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
// size of the structure for every process
|
// size of the structure for every process
|
||||||
curSize = sizeof(SYSTEM_PROCESSES)-sizeof(SYSTEM_THREADS)+sizeof(SYSTEM_THREADS)*nThreads;
|
curSize = sizeof(SYSTEM_PROCESSES)-sizeof(SYSTEM_THREADS)+sizeof(SYSTEM_THREADS)*nThreads;
|
||||||
ovlSize += curSize+inLen;
|
ovlSize += curSize+inLen;
|
||||||
|
@ -667,7 +672,7 @@ QSI_DEF(SystemProcessInformation)
|
||||||
}
|
}
|
||||||
|
|
||||||
pr = PsGetNextProcess(pr);
|
pr = PsGetNextProcess(pr);
|
||||||
|
nThreads = 0;
|
||||||
if ((pr == syspr) || (pr == NULL))
|
if ((pr == syspr) || (pr == NULL))
|
||||||
{
|
{
|
||||||
SpiCur->NextEntryDelta = 0;
|
SpiCur->NextEntryDelta = 0;
|
||||||
|
|
|
@ -198,6 +198,10 @@ ULONG KeAllocateGdtSelector(ULONG Desc[2]);
|
||||||
VOID KeFreeGdtSelector(ULONG Entry);
|
VOID KeFreeGdtSelector(ULONG Entry);
|
||||||
VOID
|
VOID
|
||||||
NtEarlyInitVdm(VOID);
|
NtEarlyInitVdm(VOID);
|
||||||
|
VOID
|
||||||
|
KeApplicationProcessorInitDispatcher(VOID);
|
||||||
|
VOID
|
||||||
|
KeCreateApplicationProcessorIdleThread(ULONG Id);
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
#define LOCK "lock ; "
|
#define LOCK "lock ; "
|
||||||
|
|
|
@ -437,8 +437,6 @@ struct _EPROCESS
|
||||||
*/
|
*/
|
||||||
MADDRESS_SPACE AddressSpace;
|
MADDRESS_SPACE AddressSpace;
|
||||||
LIST_ENTRY ProcessListEntry;
|
LIST_ENTRY ProcessListEntry;
|
||||||
PVOID TebBlock;
|
|
||||||
PVOID TebLastAllocated;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PROCESS_STATE_TERMINATED (1)
|
#define PROCESS_STATE_TERMINATED (1)
|
||||||
|
|
|
@ -26,6 +26,8 @@ BOOLEAN Ke386NoExecute = FALSE;
|
||||||
BOOLEAN Ke386Pae = FALSE;
|
BOOLEAN Ke386Pae = FALSE;
|
||||||
BOOLEAN Ke386GlobalPagesEnabled = FALSE;
|
BOOLEAN Ke386GlobalPagesEnabled = FALSE;
|
||||||
ULONG KiFastSystemCallDisable = 1;
|
ULONG KiFastSystemCallDisable = 1;
|
||||||
|
extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
|
||||||
|
extern ULONG IdleProcessorMask;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
@ -123,6 +125,42 @@ Ki386GetCpuId(VOID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
KeApplicationProcessorInitDispatcher(VOID)
|
||||||
|
{
|
||||||
|
KIRQL oldIrql;
|
||||||
|
oldIrql = KeAcquireDispatcherDatabaseLock();
|
||||||
|
IdleProcessorMask |= (1 << KeGetCurrentProcessorNumber());
|
||||||
|
KeReleaseDispatcherDatabaseLock(oldIrql);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
INIT_FUNCTION
|
||||||
|
KeCreateApplicationProcessorIdleThread(ULONG Id)
|
||||||
|
{
|
||||||
|
PETHREAD IdleThread;
|
||||||
|
PKPRCB Prcb = ((PKPCR)((ULONG_PTR)KPCR_BASE + Id * PAGE_SIZE))->Prcb;
|
||||||
|
|
||||||
|
PsInitializeThread(PsIdleProcess,
|
||||||
|
&IdleThread,
|
||||||
|
NULL,
|
||||||
|
KernelMode,
|
||||||
|
FALSE);
|
||||||
|
IdleThread->Tcb.State = THREAD_STATE_RUNNING;
|
||||||
|
IdleThread->Tcb.FreezeCount = 0;
|
||||||
|
IdleThread->Tcb.Affinity = 1 << Id;
|
||||||
|
IdleThread->Tcb.UserAffinity = 1 << Id;
|
||||||
|
IdleThread->Tcb.Priority = LOW_PRIORITY;
|
||||||
|
IdleThread->Tcb.BasePriority = LOW_PRIORITY;
|
||||||
|
Prcb->IdleThread = &IdleThread->Tcb;
|
||||||
|
Prcb->CurrentThread = &IdleThread->Tcb;
|
||||||
|
|
||||||
|
Ki386InitialStackArray[Id] = (PVOID)IdleThread->Tcb.StackLimit;
|
||||||
|
|
||||||
|
DPRINT("IdleThread for Processor %d has PID %d\n",
|
||||||
|
Id, IdleThread->Cid.UniqueThread);
|
||||||
|
}
|
||||||
|
|
||||||
VOID INIT_FUNCTION
|
VOID INIT_FUNCTION
|
||||||
KePrepareForApplicationProcessorInit(ULONG Id)
|
KePrepareForApplicationProcessorInit(ULONG Id)
|
||||||
{
|
{
|
||||||
|
|
|
@ -342,6 +342,46 @@ KiSuspendThreadNormalRoutine(PVOID NormalContext,
|
||||||
DPRINT("Done Waiting\n");
|
DPRINT("Done Waiting\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef KeGetCurrentThread
|
||||||
|
#undef KeGetCurrentThread
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
PKTHREAD
|
||||||
|
STDCALL
|
||||||
|
KeGetCurrentThread(VOID)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
ULONG Flags;
|
||||||
|
PKTHREAD Thread;
|
||||||
|
Ke386SaveFlags(Flags);
|
||||||
|
Ke386DisableInterrupts();
|
||||||
|
Thread = KeGetCurrentPrcb()->CurrentThread;
|
||||||
|
Ke386RestoreFlags(Flags);
|
||||||
|
return Thread;
|
||||||
|
#else
|
||||||
|
return(KeGetCurrentPrcb()->CurrentThread);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
STDCALL
|
||||||
|
KeSetPreviousMode(ULONG Mode)
|
||||||
|
{
|
||||||
|
PsGetCurrentThread()->Tcb.PreviousMode = (UCHAR)Mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
KPROCESSOR_MODE
|
||||||
|
STDCALL
|
||||||
|
KeGetPreviousMode(VOID)
|
||||||
|
{
|
||||||
|
return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
STDCALL
|
||||||
KeRundownThread(VOID)
|
KeRundownThread(VOID)
|
||||||
|
@ -422,7 +462,51 @@ BOOLEAN
|
||||||
STDCALL
|
STDCALL
|
||||||
KiInsertQueueApc(PKAPC Apc,
|
KiInsertQueueApc(PKAPC Apc,
|
||||||
KPRIORITY PriorityBoost);
|
KPRIORITY PriorityBoost);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used by the debugging code to freeze all the process's threads
|
||||||
|
* while the debugger is examining their state.
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
STDCALL
|
||||||
|
KeFreezeAllThreads(PKPROCESS Process)
|
||||||
|
{
|
||||||
|
KIRQL OldIrql;
|
||||||
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
PKTHREAD Current;
|
||||||
|
PKTHREAD CurrentThread = KeGetCurrentThread();
|
||||||
|
|
||||||
|
/* Acquire Lock */
|
||||||
|
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||||
|
|
||||||
|
/* Loop the Process's Threads */
|
||||||
|
CurrentEntry = Process->ThreadListHead.Flink;
|
||||||
|
while (CurrentEntry != &Process->ThreadListHead)
|
||||||
|
{
|
||||||
|
/* Get the Thread */
|
||||||
|
Current = CONTAINING_RECORD(CurrentEntry, KTHREAD, ThreadListEntry);
|
||||||
|
|
||||||
|
/* Make sure it's not ours */
|
||||||
|
if (Current == CurrentThread) continue;
|
||||||
|
|
||||||
|
/* Make sure it wasn't already frozen, and that it's not suspended */
|
||||||
|
if (!(++Current->FreezeCount) && !(Current->SuspendCount))
|
||||||
|
{
|
||||||
|
/* Insert the APC */
|
||||||
|
if (!KiInsertQueueApc(&Current->SuspendApc, IO_NO_INCREMENT))
|
||||||
|
{
|
||||||
|
/* Unsignal the Semaphore, the APC already got inserted */
|
||||||
|
Current->SuspendSemaphore.Header.SignalState--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the lock */
|
||||||
|
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
KeSuspendThread(PKTHREAD Thread)
|
KeSuspendThread(PKTHREAD Thread)
|
||||||
|
|
|
@ -109,7 +109,7 @@ KiSystemStartup(BOOLEAN BootProcessor)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Do application processor initialization */
|
/* Do application processor initialization */
|
||||||
PsApplicationProcessorInit();
|
KeApplicationProcessorInitDispatcher();
|
||||||
|
|
||||||
/* Lower IRQL and go to Idle Thread */
|
/* Lower IRQL and go to Idle Thread */
|
||||||
KeLowerIrql(PASSIVE_LEVEL);
|
KeLowerIrql(PASSIVE_LEVEL);
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
extern ULONG NtMajorVersion;
|
extern ULONG NtMajorVersion;
|
||||||
extern ULONG NtMinorVersion;
|
extern ULONG NtMinorVersion;
|
||||||
extern ULONG NtOSCSDVersion;
|
extern ULONG NtOSCSDVersion;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
PVOID
|
PVOID
|
||||||
|
@ -28,25 +29,33 @@ MiCreatePebOrTeb(PEPROCESS Process,
|
||||||
PMEMORY_AREA MemoryArea;
|
PMEMORY_AREA MemoryArea;
|
||||||
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
||||||
BoundaryAddressMultiple.QuadPart = 0;
|
BoundaryAddressMultiple.QuadPart = 0;
|
||||||
|
PVOID AllocatedBase = BaseAddress;
|
||||||
|
|
||||||
/* Acquire the Lock */
|
/* Acquire the Lock */
|
||||||
MmLockAddressSpace(ProcessAddressSpace);
|
MmLockAddressSpace(ProcessAddressSpace);
|
||||||
|
|
||||||
/* Create a Peb or Teb */
|
/*
|
||||||
Status = MmCreateMemoryArea(Process,
|
* Create a Peb or Teb.
|
||||||
ProcessAddressSpace,
|
* Loop until it works, decreasing by PAGE_SIZE each time. The logic here
|
||||||
MEMORY_AREA_PEB_OR_TEB,
|
* is that a PEB allocation should never fail since the address is free,
|
||||||
&BaseAddress,
|
* while TEB allocation can fail, and we should simply try the address
|
||||||
PAGE_SIZE,
|
* below. Is there a nicer way of doing this automagically? (ie: findning)
|
||||||
PAGE_READWRITE,
|
* a gap region? -- Alex
|
||||||
&MemoryArea,
|
*/
|
||||||
FALSE,
|
do {
|
||||||
FALSE,
|
DPRINT("Trying to allocate: %x\n", AllocatedBase);
|
||||||
BoundaryAddressMultiple);
|
Status = MmCreateMemoryArea(Process,
|
||||||
if (!NT_SUCCESS(Status))
|
ProcessAddressSpace,
|
||||||
{
|
MEMORY_AREA_PEB_OR_TEB,
|
||||||
DPRINT1("Failed to allocate PEB or TEB\n");
|
&AllocatedBase,
|
||||||
}
|
PAGE_SIZE,
|
||||||
|
PAGE_READWRITE,
|
||||||
|
&MemoryArea,
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
BoundaryAddressMultiple);
|
||||||
|
AllocatedBase = AllocatedBase - PAGE_SIZE;
|
||||||
|
} while (Status != STATUS_SUCCESS);
|
||||||
|
|
||||||
/* Initialize the Region */
|
/* Initialize the Region */
|
||||||
MmInitialiseRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead,
|
MmInitialiseRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead,
|
||||||
|
@ -60,7 +69,7 @@ MiCreatePebOrTeb(PEPROCESS Process,
|
||||||
/* Unlock Address Space */
|
/* Unlock Address Space */
|
||||||
DPRINT("Returning\n");
|
DPRINT("Returning\n");
|
||||||
MmUnlockAddressSpace(ProcessAddressSpace);
|
MmUnlockAddressSpace(ProcessAddressSpace);
|
||||||
return BaseAddress;
|
return AllocatedBase + PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -77,7 +86,7 @@ MiFreeStackPage(PVOID Context,
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
STDCALL
|
||||||
MmDeleteKernelStack(PVOID Stack,
|
MmDeleteKernelStack(PVOID Stack,
|
||||||
BOOLEAN GuiStack)
|
BOOLEAN GuiStack)
|
||||||
{
|
{
|
||||||
/* Lock the Address Space */
|
/* Lock the Address Space */
|
||||||
|
@ -93,6 +102,54 @@ MmDeleteKernelStack(PVOID Stack,
|
||||||
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MiFreePebPage(PVOID Context,
|
||||||
|
MEMORY_AREA* MemoryArea,
|
||||||
|
PVOID Address,
|
||||||
|
PFN_TYPE Page,
|
||||||
|
SWAPENTRY SwapEntry,
|
||||||
|
BOOLEAN Dirty)
|
||||||
|
{
|
||||||
|
PEPROCESS Process = (PEPROCESS)Context;
|
||||||
|
|
||||||
|
if (Page != 0)
|
||||||
|
{
|
||||||
|
SWAPENTRY SavedSwapEntry;
|
||||||
|
SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
|
||||||
|
if (SavedSwapEntry != 0)
|
||||||
|
{
|
||||||
|
MmFreeSwapPage(SavedSwapEntry);
|
||||||
|
MmSetSavedSwapEntryPage(Page, 0);
|
||||||
|
}
|
||||||
|
MmDeleteRmap(Page, Process, Address);
|
||||||
|
MmReleasePageMemoryConsumer(MC_USER, Page);
|
||||||
|
}
|
||||||
|
else if (SwapEntry != 0)
|
||||||
|
{
|
||||||
|
MmFreeSwapPage(SwapEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
STDCALL
|
||||||
|
MmDeleteTeb(PEPROCESS Process,
|
||||||
|
PTEB Teb)
|
||||||
|
{
|
||||||
|
PMADDRESS_SPACE ProcessAddressSpace = &Process->AddressSpace;
|
||||||
|
|
||||||
|
/* Lock the Address Space */
|
||||||
|
MmLockAddressSpace(ProcessAddressSpace);
|
||||||
|
|
||||||
|
/* Delete the Stack */
|
||||||
|
MmFreeMemoryAreaByPtr(ProcessAddressSpace,
|
||||||
|
Teb,
|
||||||
|
MiFreePebPage,
|
||||||
|
Process);
|
||||||
|
|
||||||
|
/* Unlock the Address Space */
|
||||||
|
MmUnlockAddressSpace(ProcessAddressSpace);
|
||||||
|
}
|
||||||
|
|
||||||
PVOID
|
PVOID
|
||||||
STDCALL
|
STDCALL
|
||||||
MmCreateKernelStack(BOOLEAN GuiStack)
|
MmCreateKernelStack(BOOLEAN GuiStack)
|
||||||
|
@ -218,11 +275,64 @@ MmCreatePeb(PEPROCESS Process)
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
PTEB
|
||||||
STDCALL
|
STDCALL
|
||||||
MmCreateTeb(VOID)
|
MmCreateTeb(PEPROCESS Process,
|
||||||
|
PCLIENT_ID ClientId,
|
||||||
|
PINITIAL_TEB InitialTeb)
|
||||||
{
|
{
|
||||||
|
PTEB Teb;
|
||||||
|
BOOLEAN Attached = FALSE;
|
||||||
|
|
||||||
|
/* Attach to the process */
|
||||||
|
DPRINT("MmCreateTeb\n");
|
||||||
|
if (Process != PsGetCurrentProcess())
|
||||||
|
{
|
||||||
|
/* Attach to Target */
|
||||||
|
KeAttachProcess(&Process->Pcb);
|
||||||
|
Attached = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate the TEB */
|
||||||
|
Teb = MiCreatePebOrTeb(Process, (PVOID)TEB_BASE);
|
||||||
|
|
||||||
|
/* Initialize the PEB */
|
||||||
|
RtlZeroMemory(Teb, sizeof(TEB));
|
||||||
|
|
||||||
|
/* Set TIB Data */
|
||||||
|
Teb->Tib.ExceptionList = (PVOID)0xFFFFFFFF;
|
||||||
|
Teb->Tib.Version = 1;
|
||||||
|
Teb->Tib.Self = (PNT_TIB)Teb;
|
||||||
|
|
||||||
|
/* Set TEB Data */
|
||||||
|
Teb->Cid = *ClientId;
|
||||||
|
Teb->RealClientId = *ClientId;
|
||||||
|
Teb->Peb = Process->Peb;
|
||||||
|
Teb->CurrentLocale = PsDefaultThreadLocaleId;
|
||||||
|
|
||||||
|
/* Store stack information from InitialTeb */
|
||||||
|
if(InitialTeb != NULL)
|
||||||
|
{
|
||||||
|
/* fixed-size stack */
|
||||||
|
if(InitialTeb->StackBase && InitialTeb->StackLimit)
|
||||||
|
{
|
||||||
|
Teb->Tib.StackBase = InitialTeb->StackBase;
|
||||||
|
Teb->Tib.StackLimit = InitialTeb->StackLimit;
|
||||||
|
Teb->DeallocationStack = InitialTeb->StackLimit;
|
||||||
|
}
|
||||||
|
/* expandable stack */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Teb->Tib.StackBase = InitialTeb->StackCommit;
|
||||||
|
Teb->Tib.StackLimit = InitialTeb->StackCommitMax;
|
||||||
|
Teb->DeallocationStack = InitialTeb->StackReserved;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return TEB Address */
|
||||||
|
DPRINT("Allocated: %x\n", Teb);
|
||||||
|
if (Attached) KeDetachProcess();
|
||||||
|
return Teb;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -24,6 +24,11 @@ BOOLEAN PspReaping = FALSE;
|
||||||
extern LIST_ENTRY PsActiveProcessHead;
|
extern LIST_ENTRY PsActiveProcessHead;
|
||||||
extern FAST_MUTEX PspActiveProcessMutex;
|
extern FAST_MUTEX PspActiveProcessMutex;
|
||||||
|
|
||||||
|
VOID
|
||||||
|
STDCALL
|
||||||
|
MmDeleteTeb(PEPROCESS Process,
|
||||||
|
PTEB Teb);
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
STDCALL
|
STDCALL
|
||||||
|
@ -204,9 +209,8 @@ PspExitThread(NTSTATUS ExitStatus)
|
||||||
PETHREAD CurrentThread;
|
PETHREAD CurrentThread;
|
||||||
BOOLEAN Last;
|
BOOLEAN Last;
|
||||||
PEPROCESS CurrentProcess;
|
PEPROCESS CurrentProcess;
|
||||||
SIZE_T Length = PAGE_SIZE;
|
|
||||||
PVOID TebBlock;
|
|
||||||
PTERMINATION_PORT TerminationPort;
|
PTERMINATION_PORT TerminationPort;
|
||||||
|
PTEB Teb;
|
||||||
|
|
||||||
DPRINT("PspExitThread(ExitStatus %x), Current: 0x%x\n", ExitStatus, PsGetCurrentThread());
|
DPRINT("PspExitThread(ExitStatus %x), Current: 0x%x\n", ExitStatus, PsGetCurrentThread());
|
||||||
|
|
||||||
|
@ -285,26 +289,10 @@ PspExitThread(NTSTATUS ExitStatus)
|
||||||
//CmNotifyRunDown(CurrentThread);
|
//CmNotifyRunDown(CurrentThread);
|
||||||
|
|
||||||
/* Free the TEB */
|
/* Free the TEB */
|
||||||
if(CurrentThread->Tcb.Teb) {
|
if((Teb = CurrentThread->Tcb.Teb)) {
|
||||||
|
|
||||||
DPRINT("Decommit teb at %p\n", CurrentThread->Tcb.Teb);
|
|
||||||
TebBlock = MM_ROUND_DOWN(CurrentThread->Tcb.Teb, MM_VIRTMEM_GRANULARITY);
|
|
||||||
|
|
||||||
ZwFreeVirtualMemory(NtCurrentProcess(),
|
|
||||||
(PVOID *)&CurrentThread->Tcb.Teb,
|
|
||||||
&Length,
|
|
||||||
MEM_DECOMMIT);
|
|
||||||
|
|
||||||
DPRINT("teb %p, TebBlock %p\n", CurrentThread->Tcb.Teb, TebBlock);
|
|
||||||
|
|
||||||
if (TebBlock != CurrentProcess->TebBlock ||
|
|
||||||
CurrentProcess->TebBlock == CurrentProcess->TebLastAllocated) {
|
|
||||||
|
|
||||||
MmLockAddressSpace(&CurrentProcess->AddressSpace);
|
|
||||||
MmReleaseMemoryAreaIfDecommitted(CurrentProcess, &CurrentProcess->AddressSpace, TebBlock);
|
|
||||||
MmUnlockAddressSpace(&CurrentProcess->AddressSpace);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
DPRINT1("Decommit teb at %p\n", Teb);
|
||||||
|
MmDeleteTeb(CurrentProcess, Teb);
|
||||||
CurrentThread->Tcb.Teb = NULL;
|
CurrentThread->Tcb.Teb = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
#define MAX_THREAD_NOTIFY_ROUTINE_COUNT 8
|
#define MAX_THREAD_NOTIFY_ROUTINE_COUNT 8
|
||||||
#define TAG_KAPC TAG('k','p','a','p') /* kpap - kernel ps apc */
|
#define TAG_KAPC TAG('k','p','a','p') /* kpap - kernel ps apc */
|
||||||
|
|
||||||
static ULONG PiThreadNotifyRoutineCount = 0;
|
static ULONG PspThreadNotifyRoutineCount = 0;
|
||||||
static PCREATE_THREAD_NOTIFY_ROUTINE
|
static PCREATE_THREAD_NOTIFY_ROUTINE
|
||||||
PiThreadNotifyRoutine[MAX_THREAD_NOTIFY_ROUTINE_COUNT];
|
PspThreadNotifyRoutine[MAX_THREAD_NOTIFY_ROUTINE_COUNT];
|
||||||
|
|
||||||
static PCREATE_PROCESS_NOTIFY_ROUTINE
|
static PCREATE_PROCESS_NOTIFY_ROUTINE
|
||||||
PspProcessNotifyRoutine[MAX_PROCESS_NOTIFY_ROUTINE_COUNT];
|
PspProcessNotifyRoutine[MAX_PROCESS_NOTIFY_ROUTINE_COUNT];
|
||||||
|
@ -28,6 +28,8 @@ PspProcessNotifyRoutine[MAX_PROCESS_NOTIFY_ROUTINE_COUNT];
|
||||||
static PLOAD_IMAGE_NOTIFY_ROUTINE
|
static PLOAD_IMAGE_NOTIFY_ROUTINE
|
||||||
PspLoadImageNotifyRoutine[MAX_LOAD_IMAGE_NOTIFY_ROUTINE_COUNT];
|
PspLoadImageNotifyRoutine[MAX_LOAD_IMAGE_NOTIFY_ROUTINE_COUNT];
|
||||||
|
|
||||||
|
static PVOID PspLegoNotifyRoutine;
|
||||||
|
|
||||||
/* FUNCTIONS ***************************************************************/
|
/* FUNCTIONS ***************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -74,6 +76,20 @@ PsSetCreateProcessNotifyRoutine(IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
ULONG
|
||||||
|
STDCALL
|
||||||
|
PsSetLegoNotifyRoutine(PVOID LegoNotifyRoutine)
|
||||||
|
{
|
||||||
|
/* Set the System-Wide Lego Routine */
|
||||||
|
PspLegoNotifyRoutine = LegoNotifyRoutine;
|
||||||
|
|
||||||
|
/* Return the location to the Lego Data */
|
||||||
|
return FIELD_OFFSET(KTHREAD, LegoData);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
@ -124,17 +140,60 @@ PsSetLoadImageNotifyRoutine(IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID STDCALL
|
/*
|
||||||
PspRunCreateThreadNotifyRoutines (
|
* @implemented
|
||||||
PETHREAD CurrentThread,
|
*/
|
||||||
BOOLEAN Create )
|
NTSTATUS
|
||||||
|
STDCALL
|
||||||
|
PsRemoveCreateThreadNotifyRoutine(IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
/* Loop the routines */
|
||||||
|
for(i=0;i<MAX_THREAD_NOTIFY_ROUTINE_COUNT;i++)
|
||||||
|
{
|
||||||
|
/* Check for a match */
|
||||||
|
if ((PVOID)PspThreadNotifyRoutine[i] == (PVOID)NotifyRoutine)
|
||||||
|
{
|
||||||
|
/* Remove and return */
|
||||||
|
PspThreadNotifyRoutine[i] = NULL;
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nothing found */
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
NTSTATUS
|
||||||
|
STDCALL
|
||||||
|
PsSetCreateThreadNotifyRoutine(IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine)
|
||||||
|
{
|
||||||
|
if (PspThreadNotifyRoutineCount >= MAX_THREAD_NOTIFY_ROUTINE_COUNT)
|
||||||
|
{
|
||||||
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
|
}
|
||||||
|
|
||||||
|
PspThreadNotifyRoutine[PspThreadNotifyRoutineCount] = NotifyRoutine;
|
||||||
|
PspThreadNotifyRoutineCount++;
|
||||||
|
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
STDCALL
|
||||||
|
PspRunCreateThreadNotifyRoutines(PETHREAD CurrentThread,
|
||||||
|
BOOLEAN Create)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
CLIENT_ID Cid = CurrentThread->Cid;
|
CLIENT_ID Cid = CurrentThread->Cid;
|
||||||
|
|
||||||
for (i = 0; i < PiThreadNotifyRoutineCount; i++)
|
for (i = 0; i < PspThreadNotifyRoutineCount; i++)
|
||||||
{
|
{
|
||||||
PiThreadNotifyRoutine[i](Cid.UniqueProcess, Cid.UniqueThread, Create);
|
PspThreadNotifyRoutine[i](Cid.UniqueProcess, Cid.UniqueThread, Create);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,22 +232,4 @@ PspRunLoadImageNotifyRoutines(PUNICODE_STRING FullImageName,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
NTSTATUS STDCALL
|
|
||||||
PsSetCreateThreadNotifyRoutine (
|
|
||||||
IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine )
|
|
||||||
{
|
|
||||||
if (PiThreadNotifyRoutineCount >= MAX_THREAD_NOTIFY_ROUTINE_COUNT)
|
|
||||||
{
|
|
||||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
|
||||||
}
|
|
||||||
|
|
||||||
PiThreadNotifyRoutine[PiThreadNotifyRoutineCount] = NotifyRoutine;
|
|
||||||
PiThreadNotifyRoutineCount++;
|
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -15,15 +15,26 @@
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
extern LARGE_INTEGER ShortPsLockDelay, PsLockTimeout;
|
extern LARGE_INTEGER ShortPsLockDelay, PsLockTimeout;
|
||||||
|
extern LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY];
|
||||||
|
|
||||||
static GENERIC_MAPPING PiProcessMapping = {
|
static GENERIC_MAPPING PiProcessMapping = {
|
||||||
STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
|
STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
|
||||||
STANDARD_RIGHTS_WRITE | PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD |
|
STANDARD_RIGHTS_WRITE | PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD |
|
||||||
PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_DUP_HANDLE |
|
PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_DUP_HANDLE |
|
||||||
PROCESS_TERMINATE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION | PROCESS_SET_PORT,
|
PROCESS_TERMINATE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION |
|
||||||
|
PROCESS_SET_PORT,
|
||||||
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
|
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
|
||||||
PROCESS_ALL_ACCESS};
|
PROCESS_ALL_ACCESS};
|
||||||
|
|
||||||
|
static GENERIC_MAPPING PiThreadMapping = {
|
||||||
|
STANDARD_RIGHTS_READ | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION,
|
||||||
|
STANDARD_RIGHTS_WRITE | THREAD_TERMINATE | THREAD_SUSPEND_RESUME |
|
||||||
|
THREAD_ALERT | THREAD_SET_INFORMATION | THREAD_SET_CONTEXT,
|
||||||
|
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
|
||||||
|
THREAD_ALL_ACCESS};
|
||||||
|
|
||||||
|
BOOLEAN DoneInitYet = FALSE;
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
INIT_FUNCTION
|
INIT_FUNCTION
|
||||||
PsInitClientIDManagment(VOID);
|
PsInitClientIDManagment(VOID);
|
||||||
|
@ -48,6 +59,60 @@ PiInitProcessManager(VOID)
|
||||||
PsInitialiseW32Call();
|
PsInitialiseW32Call();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
INIT_FUNCTION
|
||||||
|
PsInitThreadManagment(VOID)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Initialize thread managment
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PETHREAD FirstThread;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
for (i=0; i < MAXIMUM_PRIORITY; i++)
|
||||||
|
{
|
||||||
|
InitializeListHead(&PriorityListHead[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
PsThreadType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
|
||||||
|
|
||||||
|
PsThreadType->Tag = TAG('T', 'H', 'R', 'T');
|
||||||
|
PsThreadType->TotalObjects = 0;
|
||||||
|
PsThreadType->TotalHandles = 0;
|
||||||
|
PsThreadType->PeakObjects = 0;
|
||||||
|
PsThreadType->PeakHandles = 0;
|
||||||
|
PsThreadType->PagedPoolCharge = 0;
|
||||||
|
PsThreadType->NonpagedPoolCharge = sizeof(ETHREAD);
|
||||||
|
PsThreadType->Mapping = &PiThreadMapping;
|
||||||
|
PsThreadType->Dump = NULL;
|
||||||
|
PsThreadType->Open = NULL;
|
||||||
|
PsThreadType->Close = NULL;
|
||||||
|
PsThreadType->Delete = PspDeleteThread;
|
||||||
|
PsThreadType->Parse = NULL;
|
||||||
|
PsThreadType->Security = NULL;
|
||||||
|
PsThreadType->QueryName = NULL;
|
||||||
|
PsThreadType->OkayToClose = NULL;
|
||||||
|
PsThreadType->Create = NULL;
|
||||||
|
PsThreadType->DuplicationNotify = NULL;
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&PsThreadType->TypeName, L"Thread");
|
||||||
|
|
||||||
|
ObpCreateTypeObject(PsThreadType);
|
||||||
|
|
||||||
|
PsInitializeThread(NULL, &FirstThread, NULL, KernelMode, TRUE);
|
||||||
|
FirstThread->Tcb.State = THREAD_STATE_RUNNING;
|
||||||
|
FirstThread->Tcb.FreezeCount = 0;
|
||||||
|
FirstThread->Tcb.UserAffinity = (1 << 0); /* Set the affinity of the first thread to the boot processor */
|
||||||
|
FirstThread->Tcb.Affinity = (1 << 0);
|
||||||
|
KeGetCurrentPrcb()->CurrentThread = (PVOID)FirstThread;
|
||||||
|
|
||||||
|
DPRINT("FirstThread %x\n",FirstThread);
|
||||||
|
|
||||||
|
DoneInitYet = TRUE;
|
||||||
|
|
||||||
|
ExInitializeWorkItem(&PspReaperWorkItem, PspReapRoutine, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
INIT_FUNCTION
|
INIT_FUNCTION
|
||||||
PsInitProcessManagment(VOID)
|
PsInitProcessManagment(VOID)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue