mirror of
https://github.com/reactos/reactos.git
synced 2024-09-30 06:27:38 +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 */
|
||||
KePrepareForApplicationProcessorInit(KeNumberProcessors);
|
||||
PsPrepareForApplicationProcessorInit(KeNumberProcessors);
|
||||
KeCreateApplicationProcessorIdleThread(KeNumberProcessors);
|
||||
|
||||
/* Allocate a stack for use when booting the processor */
|
||||
ProcessorStack = Ki386InitialStackArray[((int)KeNumberProcessors)] + MM_STACK_SIZE;
|
||||
|
|
|
@ -587,7 +587,12 @@ QSI_DEF(SystemProcessInformation)
|
|||
|
||||
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
|
||||
curSize = sizeof(SYSTEM_PROCESSES)-sizeof(SYSTEM_THREADS)+sizeof(SYSTEM_THREADS)*nThreads;
|
||||
|
@ -667,7 +672,7 @@ QSI_DEF(SystemProcessInformation)
|
|||
}
|
||||
|
||||
pr = PsGetNextProcess(pr);
|
||||
|
||||
nThreads = 0;
|
||||
if ((pr == syspr) || (pr == NULL))
|
||||
{
|
||||
SpiCur->NextEntryDelta = 0;
|
||||
|
|
|
@ -198,6 +198,10 @@ ULONG KeAllocateGdtSelector(ULONG Desc[2]);
|
|||
VOID KeFreeGdtSelector(ULONG Entry);
|
||||
VOID
|
||||
NtEarlyInitVdm(VOID);
|
||||
VOID
|
||||
KeApplicationProcessorInitDispatcher(VOID);
|
||||
VOID
|
||||
KeCreateApplicationProcessorIdleThread(ULONG Id);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define LOCK "lock ; "
|
||||
|
|
|
@ -437,8 +437,6 @@ struct _EPROCESS
|
|||
*/
|
||||
MADDRESS_SPACE AddressSpace;
|
||||
LIST_ENTRY ProcessListEntry;
|
||||
PVOID TebBlock;
|
||||
PVOID TebLastAllocated;
|
||||
};
|
||||
|
||||
#define PROCESS_STATE_TERMINATED (1)
|
||||
|
|
|
@ -26,6 +26,8 @@ BOOLEAN Ke386NoExecute = FALSE;
|
|||
BOOLEAN Ke386Pae = FALSE;
|
||||
BOOLEAN Ke386GlobalPagesEnabled = FALSE;
|
||||
ULONG KiFastSystemCallDisable = 1;
|
||||
extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
|
||||
extern ULONG IdleProcessorMask;
|
||||
|
||||
/* 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
|
||||
KePrepareForApplicationProcessorInit(ULONG Id)
|
||||
{
|
||||
|
|
|
@ -342,6 +342,46 @@ KiSuspendThreadNormalRoutine(PVOID NormalContext,
|
|||
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
|
||||
STDCALL
|
||||
KeRundownThread(VOID)
|
||||
|
@ -423,6 +463,50 @@ STDCALL
|
|||
KiInsertQueueApc(PKAPC Apc,
|
||||
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
|
||||
STDCALL
|
||||
KeSuspendThread(PKTHREAD Thread)
|
||||
|
|
|
@ -109,7 +109,7 @@ KiSystemStartup(BOOLEAN BootProcessor)
|
|||
} else {
|
||||
|
||||
/* Do application processor initialization */
|
||||
PsApplicationProcessorInit();
|
||||
KeApplicationProcessorInitDispatcher();
|
||||
|
||||
/* Lower IRQL and go to Idle Thread */
|
||||
KeLowerIrql(PASSIVE_LEVEL);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
extern ULONG NtMajorVersion;
|
||||
extern ULONG NtMinorVersion;
|
||||
extern ULONG NtOSCSDVersion;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
PVOID
|
||||
|
@ -28,25 +29,33 @@ MiCreatePebOrTeb(PEPROCESS Process,
|
|||
PMEMORY_AREA MemoryArea;
|
||||
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
||||
BoundaryAddressMultiple.QuadPart = 0;
|
||||
PVOID AllocatedBase = BaseAddress;
|
||||
|
||||
/* Acquire the Lock */
|
||||
MmLockAddressSpace(ProcessAddressSpace);
|
||||
|
||||
/* Create a Peb or Teb */
|
||||
/*
|
||||
* Create a Peb or Teb.
|
||||
* Loop until it works, decreasing by PAGE_SIZE each time. The logic here
|
||||
* is that a PEB allocation should never fail since the address is free,
|
||||
* while TEB allocation can fail, and we should simply try the address
|
||||
* below. Is there a nicer way of doing this automagically? (ie: findning)
|
||||
* a gap region? -- Alex
|
||||
*/
|
||||
do {
|
||||
DPRINT("Trying to allocate: %x\n", AllocatedBase);
|
||||
Status = MmCreateMemoryArea(Process,
|
||||
ProcessAddressSpace,
|
||||
MEMORY_AREA_PEB_OR_TEB,
|
||||
&BaseAddress,
|
||||
&AllocatedBase,
|
||||
PAGE_SIZE,
|
||||
PAGE_READWRITE,
|
||||
&MemoryArea,
|
||||
FALSE,
|
||||
TRUE,
|
||||
FALSE,
|
||||
BoundaryAddressMultiple);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to allocate PEB or TEB\n");
|
||||
}
|
||||
AllocatedBase = AllocatedBase - PAGE_SIZE;
|
||||
} while (Status != STATUS_SUCCESS);
|
||||
|
||||
/* Initialize the Region */
|
||||
MmInitialiseRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead,
|
||||
|
@ -60,7 +69,7 @@ MiCreatePebOrTeb(PEPROCESS Process,
|
|||
/* Unlock Address Space */
|
||||
DPRINT("Returning\n");
|
||||
MmUnlockAddressSpace(ProcessAddressSpace);
|
||||
return BaseAddress;
|
||||
return AllocatedBase + PAGE_SIZE;
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -93,6 +102,54 @@ MmDeleteKernelStack(PVOID Stack,
|
|||
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
|
||||
STDCALL
|
||||
MmCreateKernelStack(BOOLEAN GuiStack)
|
||||
|
@ -218,11 +275,64 @@ MmCreatePeb(PEPROCESS Process)
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID
|
||||
PTEB
|
||||
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
|
||||
|
|
|
@ -24,6 +24,11 @@ BOOLEAN PspReaping = FALSE;
|
|||
extern LIST_ENTRY PsActiveProcessHead;
|
||||
extern FAST_MUTEX PspActiveProcessMutex;
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
MmDeleteTeb(PEPROCESS Process,
|
||||
PTEB Teb);
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
STDCALL
|
||||
|
@ -204,9 +209,8 @@ PspExitThread(NTSTATUS ExitStatus)
|
|||
PETHREAD CurrentThread;
|
||||
BOOLEAN Last;
|
||||
PEPROCESS CurrentProcess;
|
||||
SIZE_T Length = PAGE_SIZE;
|
||||
PVOID TebBlock;
|
||||
PTERMINATION_PORT TerminationPort;
|
||||
PTEB Teb;
|
||||
|
||||
DPRINT("PspExitThread(ExitStatus %x), Current: 0x%x\n", ExitStatus, PsGetCurrentThread());
|
||||
|
||||
|
@ -285,26 +289,10 @@ PspExitThread(NTSTATUS ExitStatus)
|
|||
//CmNotifyRunDown(CurrentThread);
|
||||
|
||||
/* Free the TEB */
|
||||
if(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);
|
||||
}
|
||||
if((Teb = CurrentThread->Tcb.Teb)) {
|
||||
|
||||
DPRINT1("Decommit teb at %p\n", Teb);
|
||||
MmDeleteTeb(CurrentProcess, Teb);
|
||||
CurrentThread->Tcb.Teb = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
#define MAX_THREAD_NOTIFY_ROUTINE_COUNT 8
|
||||
#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
|
||||
PiThreadNotifyRoutine[MAX_THREAD_NOTIFY_ROUTINE_COUNT];
|
||||
PspThreadNotifyRoutine[MAX_THREAD_NOTIFY_ROUTINE_COUNT];
|
||||
|
||||
static PCREATE_PROCESS_NOTIFY_ROUTINE
|
||||
PspProcessNotifyRoutine[MAX_PROCESS_NOTIFY_ROUTINE_COUNT];
|
||||
|
@ -28,6 +28,8 @@ PspProcessNotifyRoutine[MAX_PROCESS_NOTIFY_ROUTINE_COUNT];
|
|||
static PLOAD_IMAGE_NOTIFY_ROUTINE
|
||||
PspLoadImageNotifyRoutine[MAX_LOAD_IMAGE_NOTIFY_ROUTINE_COUNT];
|
||||
|
||||
static PVOID PspLegoNotifyRoutine;
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
/*
|
||||
|
@ -74,6 +76,20 @@ PsSetCreateProcessNotifyRoutine(IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,
|
|||
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
|
||||
*/
|
||||
|
@ -124,17 +140,60 @@ PsSetLoadImageNotifyRoutine(IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine)
|
|||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
PspRunCreateThreadNotifyRoutines (
|
||||
PETHREAD CurrentThread,
|
||||
BOOLEAN Create )
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
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;
|
||||
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 */
|
||||
|
|
|
@ -15,15 +15,26 @@
|
|||
#include <internal/debug.h>
|
||||
|
||||
extern LARGE_INTEGER ShortPsLockDelay, PsLockTimeout;
|
||||
extern LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY];
|
||||
|
||||
static GENERIC_MAPPING PiProcessMapping = {
|
||||
STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
|
||||
STANDARD_RIGHTS_WRITE | PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD |
|
||||
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,
|
||||
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
|
||||
INIT_FUNCTION
|
||||
PsInitClientIDManagment(VOID);
|
||||
|
@ -48,6 +59,60 @@ PiInitProcessManager(VOID)
|
|||
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
|
||||
INIT_FUNCTION
|
||||
PsInitProcessManagment(VOID)
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue