2005-04-18 02:12:30 +00:00
|
|
|
/*
|
2006-07-09 18:54:13 +00:00
|
|
|
* PROJECT: ReactOS Kernel
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
2005-01-26 13:58:37 +00:00
|
|
|
* FILE: ntoskrnl/ps/process.c
|
2006-07-09 18:54:13 +00:00
|
|
|
* PURPOSE: Process Manager: Process Management
|
|
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
|
|
|
* Thomas Weidenmueller (w3seek@reactos.org
|
1999-01-16 02:11:45 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
2004-08-15 16:39:12 +00:00
|
|
|
#include <ntoskrnl.h>
|
1999-11-02 08:55:45 +00:00
|
|
|
#define NDEBUG
|
2008-08-30 16:31:06 +00:00
|
|
|
#include <debug.h>
|
1999-01-16 02:11:45 +00:00
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
/* GLOBALS *******************************************************************/
|
1999-01-16 02:11:45 +00:00
|
|
|
|
2006-09-16 20:37:49 +00:00
|
|
|
extern ULONG PsMinimumWorkingSet, PsMaximumWorkingSet;
|
1999-01-16 02:11:45 +00:00
|
|
|
|
2006-09-16 20:37:49 +00:00
|
|
|
POBJECT_TYPE PsProcessType = NULL;
|
2006-07-09 18:54:13 +00:00
|
|
|
|
2005-02-17 16:41:28 +00:00
|
|
|
LIST_ENTRY PsActiveProcessHead;
|
2006-07-20 16:26:10 +00:00
|
|
|
KGUARDED_MUTEX PspActiveProcessMutex;
|
2006-07-09 18:54:13 +00:00
|
|
|
|
2006-07-20 17:44:30 +00:00
|
|
|
LARGE_INTEGER ShortPsLockDelay;
|
2006-07-20 14:53:47 +00:00
|
|
|
|
2015-09-23 05:10:58 +00:00
|
|
|
ULONG PsRawPrioritySeparation;
|
2006-07-21 19:28:38 +00:00
|
|
|
ULONG PsPrioritySeparation;
|
|
|
|
CHAR PspForegroundQuantum[3];
|
|
|
|
|
|
|
|
/* Fixed quantum table */
|
|
|
|
CHAR PspFixedQuantums[6] =
|
|
|
|
{
|
|
|
|
/* Short quantums */
|
|
|
|
3 * 6, /* Level 1 */
|
|
|
|
3 * 6, /* Level 2 */
|
|
|
|
3 * 6, /* Level 3 */
|
|
|
|
|
|
|
|
/* Long quantums */
|
|
|
|
6 * 6, /* Level 1 */
|
|
|
|
6 * 6, /* Level 2 */
|
|
|
|
6 * 6 /* Level 3 */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Variable quantum table */
|
|
|
|
CHAR PspVariableQuantums[6] =
|
|
|
|
{
|
|
|
|
/* Short quantums */
|
|
|
|
1 * 6, /* Level 1 */
|
|
|
|
2 * 6, /* Level 2 */
|
|
|
|
3 * 6, /* Level 3 */
|
|
|
|
|
|
|
|
/* Long quantums */
|
|
|
|
2 * 6, /* Level 1 */
|
|
|
|
4 * 6, /* Level 2 */
|
|
|
|
6 * 6 /* Level 3 */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Priority table */
|
|
|
|
KPRIORITY PspPriorityTable[PROCESS_PRIORITY_CLASS_ABOVE_NORMAL + 1] =
|
|
|
|
{
|
|
|
|
8,
|
|
|
|
4,
|
|
|
|
8,
|
|
|
|
13,
|
|
|
|
24,
|
|
|
|
6,
|
|
|
|
10
|
|
|
|
};
|
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
/* PRIVATE FUNCTIONS *********************************************************/
|
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
PETHREAD
|
|
|
|
NTAPI
|
|
|
|
PsGetNextProcessThread(IN PEPROCESS Process,
|
|
|
|
IN PETHREAD Thread OPTIONAL)
|
|
|
|
{
|
|
|
|
PETHREAD FoundThread = NULL;
|
|
|
|
PLIST_ENTRY ListHead, Entry;
|
|
|
|
PAGED_CODE();
|
2006-07-23 19:45:16 +00:00
|
|
|
PSTRACE(PS_PROCESS_DEBUG,
|
|
|
|
"Process: %p Thread: %p\n", Process, Thread);
|
2006-07-09 18:54:13 +00:00
|
|
|
|
|
|
|
/* Lock the process */
|
2006-07-20 17:44:30 +00:00
|
|
|
KeEnterCriticalRegion();
|
|
|
|
ExAcquirePushLockShared(&Process->ProcessLock);
|
2006-07-09 18:54:13 +00:00
|
|
|
|
|
|
|
/* Check if we're already starting somewhere */
|
|
|
|
if (Thread)
|
|
|
|
{
|
|
|
|
/* Start where we left off */
|
|
|
|
Entry = Thread->ThreadListEntry.Flink;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Start at the beginning */
|
|
|
|
Entry = Process->ThreadListHead.Flink;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the list head and start looping */
|
|
|
|
ListHead = &Process->ThreadListHead;
|
|
|
|
while (ListHead != Entry)
|
|
|
|
{
|
|
|
|
/* Get the Thread */
|
|
|
|
FoundThread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry);
|
|
|
|
|
2006-07-20 18:47:35 +00:00
|
|
|
/* Safe reference the thread */
|
|
|
|
if (ObReferenceObjectSafe(FoundThread)) break;
|
|
|
|
|
|
|
|
/* Nothing found, keep looping */
|
|
|
|
FoundThread = NULL;
|
|
|
|
Entry = Entry->Flink;
|
2006-07-09 18:54:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Unlock the process */
|
2006-07-20 17:44:30 +00:00
|
|
|
ExReleasePushLockShared(&Process->ProcessLock);
|
|
|
|
KeLeaveCriticalRegion();
|
2006-07-09 18:54:13 +00:00
|
|
|
|
|
|
|
/* Check if we had a starting thread, and dereference it */
|
|
|
|
if (Thread) ObDereferenceObject(Thread);
|
|
|
|
|
|
|
|
/* Return what we found */
|
|
|
|
return FoundThread;
|
|
|
|
}
|
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
PEPROCESS
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2006-07-20 14:53:47 +00:00
|
|
|
PsGetNextProcess(IN PEPROCESS OldProcess)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2011-01-15 19:13:22 +00:00
|
|
|
PLIST_ENTRY Entry;
|
2006-07-20 14:53:47 +00:00
|
|
|
PEPROCESS FoundProcess = NULL;
|
2006-07-09 18:54:13 +00:00
|
|
|
PAGED_CODE();
|
2006-07-23 19:45:16 +00:00
|
|
|
PSTRACE(PS_PROCESS_DEBUG, "Process: %p\n", OldProcess);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
/* Acquire the Active Process Lock */
|
2006-07-20 16:26:10 +00:00
|
|
|
KeAcquireGuardedMutex(&PspActiveProcessMutex);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Check if we're already starting somewhere */
|
|
|
|
if (OldProcess)
|
2005-04-18 02:12:30 +00:00
|
|
|
{
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Start where we left off */
|
|
|
|
Entry = OldProcess->ActiveProcessLinks.Flink;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Start at the beginning */
|
|
|
|
Entry = PsActiveProcessHead.Flink;
|
|
|
|
}
|
2004-07-19 06:08:21 +00:00
|
|
|
|
2011-01-15 19:13:22 +00:00
|
|
|
/* Loop the process list */
|
|
|
|
while (Entry != &PsActiveProcessHead)
|
2006-07-20 14:53:47 +00:00
|
|
|
{
|
2011-01-15 19:13:22 +00:00
|
|
|
/* Get the process */
|
2006-07-20 14:53:47 +00:00
|
|
|
FoundProcess = CONTAINING_RECORD(Entry, EPROCESS, ActiveProcessLinks);
|
2005-04-18 02:12:30 +00:00
|
|
|
|
2006-07-20 18:47:35 +00:00
|
|
|
/* Reference the process */
|
|
|
|
if (ObReferenceObjectSafe(FoundProcess)) break;
|
|
|
|
|
|
|
|
/* Nothing found, keep trying */
|
|
|
|
FoundProcess = NULL;
|
|
|
|
Entry = Entry->Flink;
|
2005-04-18 02:12:30 +00:00
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
/* Release the lock */
|
2006-07-20 16:26:10 +00:00
|
|
|
KeReleaseGuardedMutex(&PspActiveProcessMutex);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2011-01-15 19:13:22 +00:00
|
|
|
/* Dereference the Process we had referenced earlier */
|
2006-07-20 14:53:47 +00:00
|
|
|
if (OldProcess) ObDereferenceObject(OldProcess);
|
|
|
|
return FoundProcess;
|
1999-01-16 02:11:45 +00:00
|
|
|
}
|
|
|
|
|
2006-07-21 19:28:38 +00:00
|
|
|
KPRIORITY
|
|
|
|
NTAPI
|
|
|
|
PspComputeQuantumAndPriority(IN PEPROCESS Process,
|
|
|
|
IN PSPROCESSPRIORITYMODE Mode,
|
2006-07-23 19:14:19 +00:00
|
|
|
OUT PUCHAR Quantum)
|
2006-07-21 19:28:38 +00:00
|
|
|
{
|
|
|
|
ULONG i;
|
|
|
|
UCHAR LocalQuantum, MemoryPriority;
|
|
|
|
PAGED_CODE();
|
2006-07-23 19:45:16 +00:00
|
|
|
PSTRACE(PS_PROCESS_DEBUG, "Process: %p Mode: %lx\n", Process, Mode);
|
2006-07-21 19:28:38 +00:00
|
|
|
|
|
|
|
/* Check if this is a foreground process */
|
|
|
|
if (Mode == PsProcessPriorityForeground)
|
|
|
|
{
|
|
|
|
/* Set the memory priority and use priority separation */
|
2009-06-11 15:37:43 +00:00
|
|
|
MemoryPriority = MEMORY_PRIORITY_FOREGROUND;
|
2006-07-21 19:28:38 +00:00
|
|
|
i = PsPrioritySeparation;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Set the background memory priority and no separation */
|
2009-06-11 15:37:43 +00:00
|
|
|
MemoryPriority = MEMORY_PRIORITY_BACKGROUND;
|
2006-07-21 19:28:38 +00:00
|
|
|
i = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make sure that the process mode isn't spinning */
|
|
|
|
if (Mode != PsProcessPrioritySpinning)
|
|
|
|
{
|
|
|
|
/* Set the priority */
|
|
|
|
MmSetMemoryPriorityProcess(Process, MemoryPriority);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make sure that the process isn't idle */
|
|
|
|
if (Process->PriorityClass != PROCESS_PRIORITY_CLASS_IDLE)
|
|
|
|
{
|
|
|
|
/* Does the process have a job? */
|
|
|
|
if ((Process->Job) && (PspUseJobSchedulingClasses))
|
|
|
|
{
|
|
|
|
/* Use job quantum */
|
|
|
|
LocalQuantum = PspJobSchedulingClasses[Process->Job->
|
|
|
|
SchedulingClass];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Use calculated quantum */
|
|
|
|
LocalQuantum = PspForegroundQuantum[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Process is idle, use default quantum */
|
|
|
|
LocalQuantum = 6;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return quantum to caller */
|
|
|
|
*Quantum = LocalQuantum;
|
|
|
|
|
|
|
|
/* Return priority */
|
|
|
|
return PspPriorityTable[Process->PriorityClass];
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
PsChangeQuantumTable(IN BOOLEAN Immediate,
|
|
|
|
IN ULONG PrioritySeparation)
|
|
|
|
{
|
|
|
|
PEPROCESS Process = NULL;
|
|
|
|
ULONG i;
|
|
|
|
UCHAR Quantum;
|
|
|
|
PCHAR QuantumTable;
|
|
|
|
PAGED_CODE();
|
2006-07-23 19:45:16 +00:00
|
|
|
PSTRACE(PS_PROCESS_DEBUG,
|
|
|
|
"%lx PrioritySeparation: %lx\n", Immediate, PrioritySeparation);
|
2006-07-21 19:28:38 +00:00
|
|
|
|
|
|
|
/* Write the current priority separation */
|
|
|
|
PsPrioritySeparation = PspPrioritySeparationFromMask(PrioritySeparation);
|
|
|
|
|
|
|
|
/* Normalize it if it was too high */
|
|
|
|
if (PsPrioritySeparation == 3) PsPrioritySeparation = 2;
|
|
|
|
|
|
|
|
/* Get the quantum table to use */
|
|
|
|
if (PspQuantumTypeFromMask(PrioritySeparation) == PSP_VARIABLE_QUANTUMS)
|
|
|
|
{
|
|
|
|
/* Use a variable table */
|
|
|
|
QuantumTable = PspVariableQuantums;
|
|
|
|
}
|
2015-09-23 05:10:58 +00:00
|
|
|
else if (PspQuantumTypeFromMask(PrioritySeparation) == PSP_FIXED_QUANTUMS)
|
2006-07-21 19:28:38 +00:00
|
|
|
{
|
|
|
|
/* Use fixed table */
|
|
|
|
QuantumTable = PspFixedQuantums;
|
|
|
|
}
|
2015-09-23 05:10:58 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Use default for the type of system we're on */
|
|
|
|
QuantumTable = MmIsThisAnNtAsSystem() ? PspFixedQuantums : PspVariableQuantums;
|
|
|
|
}
|
2006-07-21 19:28:38 +00:00
|
|
|
|
|
|
|
/* Now check if we should use long or short */
|
|
|
|
if (PspQuantumLengthFromMask(PrioritySeparation) == PSP_LONG_QUANTUMS)
|
|
|
|
{
|
|
|
|
/* Use long quantums */
|
|
|
|
QuantumTable += 3;
|
|
|
|
}
|
2015-09-23 05:10:58 +00:00
|
|
|
else if (PspQuantumLengthFromMask(PrioritySeparation) == PSP_SHORT_QUANTUMS)
|
|
|
|
{
|
|
|
|
/* Keep existing table */
|
|
|
|
NOTHING;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Use default for the type of system we're on */
|
|
|
|
QuantumTable += MmIsThisAnNtAsSystem() ? 3 : 0;
|
|
|
|
}
|
2006-07-21 19:28:38 +00:00
|
|
|
|
|
|
|
/* Check if we're using long fixed quantums */
|
|
|
|
if (QuantumTable == &PspFixedQuantums[3])
|
|
|
|
{
|
|
|
|
/* Use Job scheduling classes */
|
|
|
|
PspUseJobSchedulingClasses = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Otherwise, we don't */
|
|
|
|
PspUseJobSchedulingClasses = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Copy the selected table into the Foreground Quantum table */
|
|
|
|
RtlCopyMemory(PspForegroundQuantum,
|
|
|
|
QuantumTable,
|
|
|
|
sizeof(PspForegroundQuantum));
|
|
|
|
|
|
|
|
/* Check if we should apply these changes real-time */
|
|
|
|
if (Immediate)
|
|
|
|
{
|
|
|
|
/* We are...loop every process */
|
2006-07-23 19:14:19 +00:00
|
|
|
Process = PsGetNextProcess(Process);
|
2006-07-21 19:28:38 +00:00
|
|
|
while (Process)
|
|
|
|
{
|
2015-09-23 05:10:58 +00:00
|
|
|
/* Use the priority separation if this is a foreground process */
|
|
|
|
i = (Process->Vm.Flags.MemoryPriority ==
|
|
|
|
MEMORY_PRIORITY_BACKGROUND) ?
|
|
|
|
0: PsPrioritySeparation;
|
2006-07-21 19:28:38 +00:00
|
|
|
|
|
|
|
/* Make sure that the process isn't idle */
|
|
|
|
if (Process->PriorityClass != PROCESS_PRIORITY_CLASS_IDLE)
|
|
|
|
{
|
|
|
|
/* Does the process have a job? */
|
|
|
|
if ((Process->Job) && (PspUseJobSchedulingClasses))
|
|
|
|
{
|
|
|
|
/* Use job quantum */
|
2015-09-23 05:10:58 +00:00
|
|
|
Quantum = PspJobSchedulingClasses[Process->Job->SchedulingClass];
|
2006-07-21 19:28:38 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Use calculated quantum */
|
|
|
|
Quantum = PspForegroundQuantum[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Process is idle, use default quantum */
|
|
|
|
Quantum = 6;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now set the quantum */
|
|
|
|
KeSetQuantumProcess(&Process->Pcb, Quantum);
|
|
|
|
|
|
|
|
/* Get the next process */
|
2006-07-23 19:14:19 +00:00
|
|
|
Process = PsGetNextProcess(Process);
|
2006-07-21 19:28:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-01-26 00:03:05 +00:00
|
|
|
NTSTATUS
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-01-26 00:03:05 +00:00
|
|
|
PspCreateProcess(OUT PHANDLE ProcessHandle,
|
2005-04-18 00:42:31 +00:00
|
|
|
IN ACCESS_MASK DesiredAccess,
|
2006-07-20 14:53:47 +00:00
|
|
|
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
|
|
|
IN HANDLE ParentProcess OPTIONAL,
|
2006-09-07 05:07:34 +00:00
|
|
|
IN ULONG Flags,
|
2006-07-20 14:53:47 +00:00
|
|
|
IN HANDLE SectionHandle OPTIONAL,
|
|
|
|
IN HANDLE DebugPort OPTIONAL,
|
2006-07-09 18:54:13 +00:00
|
|
|
IN HANDLE ExceptionPort OPTIONAL,
|
|
|
|
IN BOOLEAN InJob)
|
1999-01-16 02:11:45 +00:00
|
|
|
{
|
2005-04-18 00:42:31 +00:00
|
|
|
HANDLE hProcess;
|
2006-07-09 18:54:13 +00:00
|
|
|
PEPROCESS Process, Parent;
|
2006-10-30 14:17:37 +00:00
|
|
|
PVOID ExceptionPortObject;
|
2006-10-19 20:08:52 +00:00
|
|
|
PDEBUG_OBJECT DebugObject;
|
2020-10-23 09:38:20 +00:00
|
|
|
PSECTION SectionObject;
|
2006-07-23 17:01:43 +00:00
|
|
|
NTSTATUS Status, AccessStatus;
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 13:11:45 +00:00
|
|
|
ULONG_PTR DirectoryTableBase[2] = {0,0};
|
2005-04-18 00:42:31 +00:00
|
|
|
KAFFINITY Affinity;
|
2005-08-07 22:48:07 +00:00
|
|
|
HANDLE_TABLE_ENTRY CidEntry;
|
2006-07-23 19:45:16 +00:00
|
|
|
PETHREAD CurrentThread = PsGetCurrentThread();
|
|
|
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
|
|
|
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
2006-07-09 18:54:13 +00:00
|
|
|
ULONG MinWs, MaxWs;
|
2006-07-23 08:20:57 +00:00
|
|
|
ACCESS_STATE LocalAccessState;
|
|
|
|
PACCESS_STATE AccessState = &LocalAccessState;
|
2008-06-16 08:54:21 +00:00
|
|
|
AUX_ACCESS_DATA AuxData;
|
2006-07-23 17:01:43 +00:00
|
|
|
UCHAR Quantum;
|
|
|
|
BOOLEAN Result, SdAllocated;
|
|
|
|
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
|
|
|
SECURITY_SUBJECT_CONTEXT SubjectContext;
|
2009-10-15 05:56:41 +00:00
|
|
|
BOOLEAN NeedsPeb = FALSE;
|
|
|
|
INITIAL_PEB InitialPeb;
|
2006-07-09 18:54:13 +00:00
|
|
|
PAGED_CODE();
|
2006-07-23 19:45:16 +00:00
|
|
|
PSTRACE(PS_PROCESS_DEBUG,
|
2006-09-16 20:37:49 +00:00
|
|
|
"ProcessHandle: %p Parent: %p\n", ProcessHandle, ParentProcess);
|
2005-11-28 23:25:31 +00:00
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
/* Validate flags */
|
2013-08-04 19:28:37 +00:00
|
|
|
if (Flags & ~PROCESS_CREATE_FLAGS_LEGAL_MASK) return STATUS_INVALID_PARAMETER;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
/* Check for parent */
|
2006-09-16 20:37:49 +00:00
|
|
|
if (ParentProcess)
|
2005-04-18 00:42:31 +00:00
|
|
|
{
|
2006-07-09 18:54:13 +00:00
|
|
|
/* Reference it */
|
2005-04-18 00:42:31 +00:00
|
|
|
Status = ObReferenceObjectByHandle(ParentProcess,
|
|
|
|
PROCESS_CREATE_PROCESS,
|
|
|
|
PsProcessType,
|
|
|
|
PreviousMode,
|
2006-07-09 18:54:13 +00:00
|
|
|
(PVOID*)&Parent,
|
2005-04-18 00:42:31 +00:00
|
|
|
NULL);
|
2006-07-20 14:53:47 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
/* If this process should be in a job but the parent isn't */
|
|
|
|
if ((InJob) && (!Parent->Job))
|
|
|
|
{
|
|
|
|
/* This is illegal. Dereference the parent and fail */
|
|
|
|
ObDereferenceObject(Parent);
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
/* Inherit Parent process's Affinity. */
|
|
|
|
Affinity = Parent->Pcb.Affinity;
|
2005-05-09 01:38:29 +00:00
|
|
|
}
|
|
|
|
else
|
2005-04-18 00:42:31 +00:00
|
|
|
{
|
2006-07-09 18:54:13 +00:00
|
|
|
/* We have no parent */
|
|
|
|
Parent = NULL;
|
2005-04-18 00:42:31 +00:00
|
|
|
Affinity = KeActiveProcessors;
|
|
|
|
}
|
2005-01-26 00:03:05 +00:00
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
/* Save working set data */
|
|
|
|
MinWs = PsMinimumWorkingSet;
|
|
|
|
MaxWs = PsMaximumWorkingSet;
|
|
|
|
|
|
|
|
/* Create the Object */
|
|
|
|
Status = ObCreateObject(PreviousMode,
|
|
|
|
PsProcessType,
|
|
|
|
ObjectAttributes,
|
|
|
|
PreviousMode,
|
|
|
|
NULL,
|
|
|
|
sizeof(EPROCESS),
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
(PVOID*)&Process);
|
2006-07-20 14:53:47 +00:00
|
|
|
if (!NT_SUCCESS(Status)) goto Cleanup;
|
2005-01-26 00:03:05 +00:00
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
/* Clean up the Object */
|
|
|
|
RtlZeroMemory(Process, sizeof(EPROCESS));
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Initialize pushlock and rundown protection */
|
|
|
|
ExInitializeRundownProtection(&Process->RundownProtect);
|
|
|
|
Process->ProcessLock.Value = 0;
|
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
/* Setup the Thread List Head */
|
|
|
|
InitializeListHead(&Process->ThreadListHead);
|
|
|
|
|
|
|
|
/* Set up the Quota Block from the Parent */
|
|
|
|
PspInheritQuota(Process, Parent);
|
|
|
|
|
|
|
|
/* Set up Dos Device Map from the Parent */
|
|
|
|
ObInheritDeviceMap(Parent, Process);
|
|
|
|
|
|
|
|
/* Check if we have a parent */
|
|
|
|
if (Parent)
|
|
|
|
{
|
2018-04-01 13:25:15 +00:00
|
|
|
/* Inherit PID and hard-error processing */
|
2006-07-09 18:54:13 +00:00
|
|
|
Process->InheritedFromUniqueProcessId = Parent->UniqueProcessId;
|
2018-04-01 13:25:15 +00:00
|
|
|
Process->DefaultHardErrorProcessing = Parent->DefaultHardErrorProcessing;
|
2006-07-09 18:54:13 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-04-01 13:25:15 +00:00
|
|
|
/* Use default hard-error processing */
|
|
|
|
Process->DefaultHardErrorProcessing = SEM_FAILCRITICALERRORS;
|
2005-04-18 00:42:31 +00:00
|
|
|
}
|
2005-01-26 00:03:05 +00:00
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
/* Check for a section handle */
|
|
|
|
if (SectionHandle)
|
2005-04-18 00:42:31 +00:00
|
|
|
{
|
2006-07-09 18:54:13 +00:00
|
|
|
/* Get a pointer to it */
|
2005-01-26 00:03:05 +00:00
|
|
|
Status = ObReferenceObjectByHandle(SectionHandle,
|
2005-10-29 22:15:10 +00:00
|
|
|
SECTION_MAP_EXECUTE,
|
2005-01-26 00:03:05 +00:00
|
|
|
MmSectionObjectType,
|
|
|
|
PreviousMode,
|
|
|
|
(PVOID*)&SectionObject,
|
|
|
|
NULL);
|
2006-07-20 14:53:47 +00:00
|
|
|
if (!NT_SUCCESS(Status)) goto CleanupWithRef;
|
2005-04-18 00:42:31 +00:00
|
|
|
}
|
2006-07-09 18:54:13 +00:00
|
|
|
else
|
|
|
|
{
|
2006-09-16 20:37:49 +00:00
|
|
|
/* Assume no section object */
|
|
|
|
SectionObject = NULL;
|
|
|
|
|
2012-03-04 17:57:44 +00:00
|
|
|
/* Is the parent the initial process?
|
|
|
|
* Check for NULL also, as at initialization PsInitialSystemProcess is NULL */
|
|
|
|
if (Parent != PsInitialSystemProcess && (Parent != NULL))
|
2006-07-09 18:54:13 +00:00
|
|
|
{
|
|
|
|
/* It's not, so acquire the process rundown */
|
2010-08-27 22:18:10 +00:00
|
|
|
if (ExAcquireRundownProtection(&Parent->RundownProtect))
|
2007-01-18 09:44:49 +00:00
|
|
|
{
|
|
|
|
/* If the parent has a section, use it */
|
|
|
|
SectionObject = Parent->SectionObject;
|
|
|
|
if (SectionObject) ObReferenceObject(SectionObject);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2007-01-18 09:44:49 +00:00
|
|
|
/* Release process rundown */
|
2010-08-27 22:18:10 +00:00
|
|
|
ExReleaseRundownProtection(&Parent->RundownProtect);
|
2007-01-18 09:44:49 +00:00
|
|
|
}
|
2006-07-09 18:54:13 +00:00
|
|
|
|
|
|
|
/* If we don't have a section object */
|
|
|
|
if (!SectionObject)
|
|
|
|
{
|
|
|
|
/* Then the process is in termination, so fail */
|
|
|
|
Status = STATUS_PROCESS_IS_TERMINATING;
|
|
|
|
goto CleanupWithRef;
|
|
|
|
}
|
|
|
|
}
|
2005-04-18 00:42:31 +00:00
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
/* Save the pointer to the section object */
|
|
|
|
Process->SectionObject = SectionObject;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
/* Check for the debug port */
|
|
|
|
if (DebugPort)
|
2005-04-18 00:42:31 +00:00
|
|
|
{
|
2006-07-09 18:54:13 +00:00
|
|
|
/* Reference it */
|
|
|
|
Status = ObReferenceObjectByHandle(DebugPort,
|
|
|
|
DEBUG_OBJECT_ADD_REMOVE_PROCESS,
|
|
|
|
DbgkDebugObjectType,
|
|
|
|
PreviousMode,
|
|
|
|
(PVOID*)&DebugObject,
|
|
|
|
NULL);
|
2006-07-20 14:53:47 +00:00
|
|
|
if (!NT_SUCCESS(Status)) goto CleanupWithRef;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
/* Save the debug object */
|
|
|
|
Process->DebugPort = DebugObject;
|
|
|
|
|
|
|
|
/* Check if the caller doesn't want the debug stuff inherited */
|
2013-08-04 19:28:37 +00:00
|
|
|
if (Flags & PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT)
|
2006-07-20 14:53:47 +00:00
|
|
|
{
|
|
|
|
/* Set the process flag */
|
2006-07-20 16:26:10 +00:00
|
|
|
InterlockedOr((PLONG)&Process->Flags, PSF_NO_DEBUG_INHERIT_BIT);
|
2006-07-20 14:53:47 +00:00
|
|
|
}
|
2006-07-09 18:54:13 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Do we have a parent? Copy his debug port */
|
|
|
|
if (Parent) DbgkCopyProcessDebugPort(Process, Parent);
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
/* Now check for an exception port */
|
|
|
|
if (ExceptionPort)
|
|
|
|
{
|
|
|
|
/* Reference it */
|
|
|
|
Status = ObReferenceObjectByHandle(ExceptionPort,
|
|
|
|
PORT_ALL_ACCESS,
|
|
|
|
LpcPortObjectType,
|
|
|
|
PreviousMode,
|
|
|
|
(PVOID*)&ExceptionPortObject,
|
|
|
|
NULL);
|
2006-07-20 14:53:47 +00:00
|
|
|
if (!NT_SUCCESS(Status)) goto CleanupWithRef;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
/* Save the exception port */
|
|
|
|
Process->ExceptionPort = ExceptionPortObject;
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-01-21 17:36:05 +00:00
|
|
|
/* Save the pointer to the section object */
|
|
|
|
Process->SectionObject = SectionObject;
|
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
/* Set default exit code */
|
2009-02-07 22:48:51 +00:00
|
|
|
Process->ExitStatus = STATUS_PENDING;
|
2007-09-27 18:07:44 +00:00
|
|
|
|
- PS_UNKNOWN_VALUE determines if the process should be created with large pages: rename to PS_LARGE_PAGES
- Do Address Space initialization as per "Windows Internals II" slides, either for the Boot, System, Cloned User or New User Process cases.
- Rename MmCreateProcessAddressSpace to MmInitializeProcessAddressSpace, and MmCopyMmInfo to MmCreateProcessAddressSpace. What ReactOS did is correct as per "Windows Internals II", but the names were inverted.
- Clone the Object Table if we are the boot process, and only initialize part of the address space (since we don't need things like guard page, TEB, etc), however, do initialize and map the shared user data section.
- Make the initial system process and idle process share the same page directory instead of creating a new one.
- Use the same priority class as the parent process, if the process was in the idle or below-normal priority class.
- Only duplicate handles if the caller requested it, instead of always duplicating the process's handles!
- Generate a null image file name for system processes.
- Rename ObpCreateHandleTable to ObInitProcess and better handle race and out-of-memory conditions. Detect if auditing required, but don't do anything about it.
- Initialize the Idle/System process address space much earlier in the boot process, in MmInitSystem.
Thanks to Alex for providing various information, and answering all my questions.
svn path=/trunk/; revision=29223
2007-09-26 20:55:26 +00:00
|
|
|
/* Check if this is the initial process being built */
|
|
|
|
if (Parent)
|
|
|
|
{
|
|
|
|
/* Create the address space for the child */
|
|
|
|
if (!MmCreateProcessAddressSpace(MinWs,
|
|
|
|
Process,
|
2008-08-11 08:40:52 +00:00
|
|
|
DirectoryTableBase))
|
- PS_UNKNOWN_VALUE determines if the process should be created with large pages: rename to PS_LARGE_PAGES
- Do Address Space initialization as per "Windows Internals II" slides, either for the Boot, System, Cloned User or New User Process cases.
- Rename MmCreateProcessAddressSpace to MmInitializeProcessAddressSpace, and MmCopyMmInfo to MmCreateProcessAddressSpace. What ReactOS did is correct as per "Windows Internals II", but the names were inverted.
- Clone the Object Table if we are the boot process, and only initialize part of the address space (since we don't need things like guard page, TEB, etc), however, do initialize and map the shared user data section.
- Make the initial system process and idle process share the same page directory instead of creating a new one.
- Use the same priority class as the parent process, if the process was in the idle or below-normal priority class.
- Only duplicate handles if the caller requested it, instead of always duplicating the process's handles!
- Generate a null image file name for system processes.
- Rename ObpCreateHandleTable to ObInitProcess and better handle race and out-of-memory conditions. Detect if auditing required, but don't do anything about it.
- Initialize the Idle/System process address space much earlier in the boot process, in MmInitSystem.
Thanks to Alex for providing various information, and answering all my questions.
svn path=/trunk/; revision=29223
2007-09-26 20:55:26 +00:00
|
|
|
{
|
|
|
|
/* Failed */
|
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
goto CleanupWithRef;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Otherwise, we are the boot process, we're already semi-initialized */
|
|
|
|
Process->ObjectTable = CurrentProcess->ObjectTable;
|
2008-08-11 08:40:52 +00:00
|
|
|
Status = MmInitializeHandBuiltProcess(Process, DirectoryTableBase);
|
- PS_UNKNOWN_VALUE determines if the process should be created with large pages: rename to PS_LARGE_PAGES
- Do Address Space initialization as per "Windows Internals II" slides, either for the Boot, System, Cloned User or New User Process cases.
- Rename MmCreateProcessAddressSpace to MmInitializeProcessAddressSpace, and MmCopyMmInfo to MmCreateProcessAddressSpace. What ReactOS did is correct as per "Windows Internals II", but the names were inverted.
- Clone the Object Table if we are the boot process, and only initialize part of the address space (since we don't need things like guard page, TEB, etc), however, do initialize and map the shared user data section.
- Make the initial system process and idle process share the same page directory instead of creating a new one.
- Use the same priority class as the parent process, if the process was in the idle or below-normal priority class.
- Only duplicate handles if the caller requested it, instead of always duplicating the process's handles!
- Generate a null image file name for system processes.
- Rename ObpCreateHandleTable to ObInitProcess and better handle race and out-of-memory conditions. Detect if auditing required, but don't do anything about it.
- Initialize the Idle/System process address space much earlier in the boot process, in MmInitSystem.
Thanks to Alex for providing various information, and answering all my questions.
svn path=/trunk/; revision=29223
2007-09-26 20:55:26 +00:00
|
|
|
if (!NT_SUCCESS(Status)) goto CleanupWithRef;
|
|
|
|
}
|
2007-09-27 18:07:44 +00:00
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
/* We now have an address space */
|
2006-07-20 16:26:10 +00:00
|
|
|
InterlockedOr((PLONG)&Process->Flags, PSF_HAS_ADDRESS_SPACE_BIT);
|
2006-07-09 18:54:13 +00:00
|
|
|
|
|
|
|
/* Set the maximum WS */
|
|
|
|
Process->Vm.MaximumWorkingSetSize = MaxWs;
|
|
|
|
|
2005-04-18 00:42:31 +00:00
|
|
|
/* Now initialize the Kernel Process */
|
|
|
|
KeInitializeProcess(&Process->Pcb,
|
2005-09-13 23:28:21 +00:00
|
|
|
PROCESS_PRIORITY_NORMAL,
|
2005-04-18 00:42:31 +00:00
|
|
|
Affinity,
|
2008-08-11 08:40:52 +00:00
|
|
|
DirectoryTableBase,
|
2018-04-01 13:25:15 +00:00
|
|
|
BooleanFlagOn(Process->DefaultHardErrorProcessing,
|
|
|
|
SEM_NOALIGNMENTFAULTEXCEPT));
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 00:42:31 +00:00
|
|
|
/* Duplicate Parent Token */
|
2006-07-09 18:54:13 +00:00
|
|
|
Status = PspInitializeProcessSecurity(Process, Parent);
|
2006-07-20 14:53:47 +00:00
|
|
|
if (!NT_SUCCESS(Status)) goto CleanupWithRef;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
/* Set default priority class */
|
|
|
|
Process->PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
|
2007-09-27 18:07:44 +00:00
|
|
|
|
- PS_UNKNOWN_VALUE determines if the process should be created with large pages: rename to PS_LARGE_PAGES
- Do Address Space initialization as per "Windows Internals II" slides, either for the Boot, System, Cloned User or New User Process cases.
- Rename MmCreateProcessAddressSpace to MmInitializeProcessAddressSpace, and MmCopyMmInfo to MmCreateProcessAddressSpace. What ReactOS did is correct as per "Windows Internals II", but the names were inverted.
- Clone the Object Table if we are the boot process, and only initialize part of the address space (since we don't need things like guard page, TEB, etc), however, do initialize and map the shared user data section.
- Make the initial system process and idle process share the same page directory instead of creating a new one.
- Use the same priority class as the parent process, if the process was in the idle or below-normal priority class.
- Only duplicate handles if the caller requested it, instead of always duplicating the process's handles!
- Generate a null image file name for system processes.
- Rename ObpCreateHandleTable to ObInitProcess and better handle race and out-of-memory conditions. Detect if auditing required, but don't do anything about it.
- Initialize the Idle/System process address space much earlier in the boot process, in MmInitSystem.
Thanks to Alex for providing various information, and answering all my questions.
svn path=/trunk/; revision=29223
2007-09-26 20:55:26 +00:00
|
|
|
/* Check if we have a parent */
|
|
|
|
if (Parent)
|
|
|
|
{
|
|
|
|
/* Check our priority class */
|
|
|
|
if (Parent->PriorityClass == PROCESS_PRIORITY_CLASS_IDLE ||
|
2007-10-19 23:21:45 +00:00
|
|
|
Parent->PriorityClass == PROCESS_PRIORITY_CLASS_BELOW_NORMAL)
|
- PS_UNKNOWN_VALUE determines if the process should be created with large pages: rename to PS_LARGE_PAGES
- Do Address Space initialization as per "Windows Internals II" slides, either for the Boot, System, Cloned User or New User Process cases.
- Rename MmCreateProcessAddressSpace to MmInitializeProcessAddressSpace, and MmCopyMmInfo to MmCreateProcessAddressSpace. What ReactOS did is correct as per "Windows Internals II", but the names were inverted.
- Clone the Object Table if we are the boot process, and only initialize part of the address space (since we don't need things like guard page, TEB, etc), however, do initialize and map the shared user data section.
- Make the initial system process and idle process share the same page directory instead of creating a new one.
- Use the same priority class as the parent process, if the process was in the idle or below-normal priority class.
- Only duplicate handles if the caller requested it, instead of always duplicating the process's handles!
- Generate a null image file name for system processes.
- Rename ObpCreateHandleTable to ObInitProcess and better handle race and out-of-memory conditions. Detect if auditing required, but don't do anything about it.
- Initialize the Idle/System process address space much earlier in the boot process, in MmInitSystem.
Thanks to Alex for providing various information, and answering all my questions.
svn path=/trunk/; revision=29223
2007-09-26 20:55:26 +00:00
|
|
|
{
|
|
|
|
/* Normalize it */
|
|
|
|
Process->PriorityClass = Parent->PriorityClass;
|
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
- PS_UNKNOWN_VALUE determines if the process should be created with large pages: rename to PS_LARGE_PAGES
- Do Address Space initialization as per "Windows Internals II" slides, either for the Boot, System, Cloned User or New User Process cases.
- Rename MmCreateProcessAddressSpace to MmInitializeProcessAddressSpace, and MmCopyMmInfo to MmCreateProcessAddressSpace. What ReactOS did is correct as per "Windows Internals II", but the names were inverted.
- Clone the Object Table if we are the boot process, and only initialize part of the address space (since we don't need things like guard page, TEB, etc), however, do initialize and map the shared user data section.
- Make the initial system process and idle process share the same page directory instead of creating a new one.
- Use the same priority class as the parent process, if the process was in the idle or below-normal priority class.
- Only duplicate handles if the caller requested it, instead of always duplicating the process's handles!
- Generate a null image file name for system processes.
- Rename ObpCreateHandleTable to ObInitProcess and better handle race and out-of-memory conditions. Detect if auditing required, but don't do anything about it.
- Initialize the Idle/System process address space much earlier in the boot process, in MmInitSystem.
Thanks to Alex for providing various information, and answering all my questions.
svn path=/trunk/; revision=29223
2007-09-26 20:55:26 +00:00
|
|
|
/* Initialize object manager for the process */
|
2013-08-04 19:28:37 +00:00
|
|
|
Status = ObInitProcess(Flags & PROCESS_CREATE_FLAGS_INHERIT_HANDLES ?
|
|
|
|
Parent : NULL,
|
- PS_UNKNOWN_VALUE determines if the process should be created with large pages: rename to PS_LARGE_PAGES
- Do Address Space initialization as per "Windows Internals II" slides, either for the Boot, System, Cloned User or New User Process cases.
- Rename MmCreateProcessAddressSpace to MmInitializeProcessAddressSpace, and MmCopyMmInfo to MmCreateProcessAddressSpace. What ReactOS did is correct as per "Windows Internals II", but the names were inverted.
- Clone the Object Table if we are the boot process, and only initialize part of the address space (since we don't need things like guard page, TEB, etc), however, do initialize and map the shared user data section.
- Make the initial system process and idle process share the same page directory instead of creating a new one.
- Use the same priority class as the parent process, if the process was in the idle or below-normal priority class.
- Only duplicate handles if the caller requested it, instead of always duplicating the process's handles!
- Generate a null image file name for system processes.
- Rename ObpCreateHandleTable to ObInitProcess and better handle race and out-of-memory conditions. Detect if auditing required, but don't do anything about it.
- Initialize the Idle/System process address space much earlier in the boot process, in MmInitSystem.
Thanks to Alex for providing various information, and answering all my questions.
svn path=/trunk/; revision=29223
2007-09-26 20:55:26 +00:00
|
|
|
Process);
|
|
|
|
if (!NT_SUCCESS(Status)) goto CleanupWithRef;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Do the second part of the boot process memory setup */
|
|
|
|
Status = MmInitializeHandBuiltProcess2(Process);
|
|
|
|
if (!NT_SUCCESS(Status)) goto CleanupWithRef;
|
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
- PS_UNKNOWN_VALUE determines if the process should be created with large pages: rename to PS_LARGE_PAGES
- Do Address Space initialization as per "Windows Internals II" slides, either for the Boot, System, Cloned User or New User Process cases.
- Rename MmCreateProcessAddressSpace to MmInitializeProcessAddressSpace, and MmCopyMmInfo to MmCreateProcessAddressSpace. What ReactOS did is correct as per "Windows Internals II", but the names were inverted.
- Clone the Object Table if we are the boot process, and only initialize part of the address space (since we don't need things like guard page, TEB, etc), however, do initialize and map the shared user data section.
- Make the initial system process and idle process share the same page directory instead of creating a new one.
- Use the same priority class as the parent process, if the process was in the idle or below-normal priority class.
- Only duplicate handles if the caller requested it, instead of always duplicating the process's handles!
- Generate a null image file name for system processes.
- Rename ObpCreateHandleTable to ObInitProcess and better handle race and out-of-memory conditions. Detect if auditing required, but don't do anything about it.
- Initialize the Idle/System process address space much earlier in the boot process, in MmInitSystem.
Thanks to Alex for providing various information, and answering all my questions.
svn path=/trunk/; revision=29223
2007-09-26 20:55:26 +00:00
|
|
|
/* Set success for now */
|
|
|
|
Status = STATUS_SUCCESS;
|
2006-07-09 18:54:13 +00:00
|
|
|
|
- PS_UNKNOWN_VALUE determines if the process should be created with large pages: rename to PS_LARGE_PAGES
- Do Address Space initialization as per "Windows Internals II" slides, either for the Boot, System, Cloned User or New User Process cases.
- Rename MmCreateProcessAddressSpace to MmInitializeProcessAddressSpace, and MmCopyMmInfo to MmCreateProcessAddressSpace. What ReactOS did is correct as per "Windows Internals II", but the names were inverted.
- Clone the Object Table if we are the boot process, and only initialize part of the address space (since we don't need things like guard page, TEB, etc), however, do initialize and map the shared user data section.
- Make the initial system process and idle process share the same page directory instead of creating a new one.
- Use the same priority class as the parent process, if the process was in the idle or below-normal priority class.
- Only duplicate handles if the caller requested it, instead of always duplicating the process's handles!
- Generate a null image file name for system processes.
- Rename ObpCreateHandleTable to ObInitProcess and better handle race and out-of-memory conditions. Detect if auditing required, but don't do anything about it.
- Initialize the Idle/System process address space much earlier in the boot process, in MmInitSystem.
Thanks to Alex for providing various information, and answering all my questions.
svn path=/trunk/; revision=29223
2007-09-26 20:55:26 +00:00
|
|
|
/* Check if this is a real user-mode process */
|
|
|
|
if (SectionHandle)
|
|
|
|
{
|
|
|
|
/* Initialize the address space */
|
|
|
|
Status = MmInitializeProcessAddressSpace(Process,
|
2007-09-27 18:07:44 +00:00
|
|
|
NULL,
|
- PS_UNKNOWN_VALUE determines if the process should be created with large pages: rename to PS_LARGE_PAGES
- Do Address Space initialization as per "Windows Internals II" slides, either for the Boot, System, Cloned User or New User Process cases.
- Rename MmCreateProcessAddressSpace to MmInitializeProcessAddressSpace, and MmCopyMmInfo to MmCreateProcessAddressSpace. What ReactOS did is correct as per "Windows Internals II", but the names were inverted.
- Clone the Object Table if we are the boot process, and only initialize part of the address space (since we don't need things like guard page, TEB, etc), however, do initialize and map the shared user data section.
- Make the initial system process and idle process share the same page directory instead of creating a new one.
- Use the same priority class as the parent process, if the process was in the idle or below-normal priority class.
- Only duplicate handles if the caller requested it, instead of always duplicating the process's handles!
- Generate a null image file name for system processes.
- Rename ObpCreateHandleTable to ObInitProcess and better handle race and out-of-memory conditions. Detect if auditing required, but don't do anything about it.
- Initialize the Idle/System process address space much earlier in the boot process, in MmInitSystem.
Thanks to Alex for providing various information, and answering all my questions.
svn path=/trunk/; revision=29223
2007-09-26 20:55:26 +00:00
|
|
|
SectionObject,
|
2007-09-27 18:07:44 +00:00
|
|
|
&Flags,
|
- PS_UNKNOWN_VALUE determines if the process should be created with large pages: rename to PS_LARGE_PAGES
- Do Address Space initialization as per "Windows Internals II" slides, either for the Boot, System, Cloned User or New User Process cases.
- Rename MmCreateProcessAddressSpace to MmInitializeProcessAddressSpace, and MmCopyMmInfo to MmCreateProcessAddressSpace. What ReactOS did is correct as per "Windows Internals II", but the names were inverted.
- Clone the Object Table if we are the boot process, and only initialize part of the address space (since we don't need things like guard page, TEB, etc), however, do initialize and map the shared user data section.
- Make the initial system process and idle process share the same page directory instead of creating a new one.
- Use the same priority class as the parent process, if the process was in the idle or below-normal priority class.
- Only duplicate handles if the caller requested it, instead of always duplicating the process's handles!
- Generate a null image file name for system processes.
- Rename ObpCreateHandleTable to ObInitProcess and better handle race and out-of-memory conditions. Detect if auditing required, but don't do anything about it.
- Initialize the Idle/System process address space much earlier in the boot process, in MmInitSystem.
Thanks to Alex for providing various information, and answering all my questions.
svn path=/trunk/; revision=29223
2007-09-26 20:55:26 +00:00
|
|
|
&Process->
|
|
|
|
SeAuditProcessCreationInfo.
|
|
|
|
ImageFileName);
|
2007-10-19 23:21:45 +00:00
|
|
|
if (!NT_SUCCESS(Status)) goto CleanupWithRef;
|
2011-01-15 19:13:22 +00:00
|
|
|
|
2009-10-15 05:56:41 +00:00
|
|
|
//
|
|
|
|
// We need a PEB
|
|
|
|
//
|
|
|
|
NeedsPeb = TRUE;
|
- PS_UNKNOWN_VALUE determines if the process should be created with large pages: rename to PS_LARGE_PAGES
- Do Address Space initialization as per "Windows Internals II" slides, either for the Boot, System, Cloned User or New User Process cases.
- Rename MmCreateProcessAddressSpace to MmInitializeProcessAddressSpace, and MmCopyMmInfo to MmCreateProcessAddressSpace. What ReactOS did is correct as per "Windows Internals II", but the names were inverted.
- Clone the Object Table if we are the boot process, and only initialize part of the address space (since we don't need things like guard page, TEB, etc), however, do initialize and map the shared user data section.
- Make the initial system process and idle process share the same page directory instead of creating a new one.
- Use the same priority class as the parent process, if the process was in the idle or below-normal priority class.
- Only duplicate handles if the caller requested it, instead of always duplicating the process's handles!
- Generate a null image file name for system processes.
- Rename ObpCreateHandleTable to ObInitProcess and better handle race and out-of-memory conditions. Detect if auditing required, but don't do anything about it.
- Initialize the Idle/System process address space much earlier in the boot process, in MmInitSystem.
Thanks to Alex for providing various information, and answering all my questions.
svn path=/trunk/; revision=29223
2007-09-26 20:55:26 +00:00
|
|
|
}
|
|
|
|
else if (Parent)
|
|
|
|
{
|
|
|
|
/* Check if this is a child of the system process */
|
|
|
|
if (Parent != PsInitialSystemProcess)
|
|
|
|
{
|
2009-10-15 05:56:41 +00:00
|
|
|
//
|
|
|
|
// We need a PEB
|
|
|
|
//
|
|
|
|
NeedsPeb = TRUE;
|
|
|
|
|
- PS_UNKNOWN_VALUE determines if the process should be created with large pages: rename to PS_LARGE_PAGES
- Do Address Space initialization as per "Windows Internals II" slides, either for the Boot, System, Cloned User or New User Process cases.
- Rename MmCreateProcessAddressSpace to MmInitializeProcessAddressSpace, and MmCopyMmInfo to MmCreateProcessAddressSpace. What ReactOS did is correct as per "Windows Internals II", but the names were inverted.
- Clone the Object Table if we are the boot process, and only initialize part of the address space (since we don't need things like guard page, TEB, etc), however, do initialize and map the shared user data section.
- Make the initial system process and idle process share the same page directory instead of creating a new one.
- Use the same priority class as the parent process, if the process was in the idle or below-normal priority class.
- Only duplicate handles if the caller requested it, instead of always duplicating the process's handles!
- Generate a null image file name for system processes.
- Rename ObpCreateHandleTable to ObInitProcess and better handle race and out-of-memory conditions. Detect if auditing required, but don't do anything about it.
- Initialize the Idle/System process address space much earlier in the boot process, in MmInitSystem.
Thanks to Alex for providing various information, and answering all my questions.
svn path=/trunk/; revision=29223
2007-09-26 20:55:26 +00:00
|
|
|
/* This is a clone! */
|
|
|
|
ASSERTMSG("No support for cloning yet\n", FALSE);
|
|
|
|
}
|
|
|
|
else
|
2011-01-15 19:13:22 +00:00
|
|
|
{
|
2007-09-27 18:07:44 +00:00
|
|
|
/* This is the initial system process */
|
2013-08-04 19:28:37 +00:00
|
|
|
Flags &= ~PROCESS_CREATE_FLAGS_LARGE_PAGES;
|
- PS_UNKNOWN_VALUE determines if the process should be created with large pages: rename to PS_LARGE_PAGES
- Do Address Space initialization as per "Windows Internals II" slides, either for the Boot, System, Cloned User or New User Process cases.
- Rename MmCreateProcessAddressSpace to MmInitializeProcessAddressSpace, and MmCopyMmInfo to MmCreateProcessAddressSpace. What ReactOS did is correct as per "Windows Internals II", but the names were inverted.
- Clone the Object Table if we are the boot process, and only initialize part of the address space (since we don't need things like guard page, TEB, etc), however, do initialize and map the shared user data section.
- Make the initial system process and idle process share the same page directory instead of creating a new one.
- Use the same priority class as the parent process, if the process was in the idle or below-normal priority class.
- Only duplicate handles if the caller requested it, instead of always duplicating the process's handles!
- Generate a null image file name for system processes.
- Rename ObpCreateHandleTable to ObInitProcess and better handle race and out-of-memory conditions. Detect if auditing required, but don't do anything about it.
- Initialize the Idle/System process address space much earlier in the boot process, in MmInitSystem.
Thanks to Alex for providing various information, and answering all my questions.
svn path=/trunk/; revision=29223
2007-09-26 20:55:26 +00:00
|
|
|
Status = MmInitializeProcessAddressSpace(Process,
|
|
|
|
NULL,
|
2007-09-27 18:07:44 +00:00
|
|
|
NULL,
|
|
|
|
&Flags,
|
|
|
|
NULL);
|
- PS_UNKNOWN_VALUE determines if the process should be created with large pages: rename to PS_LARGE_PAGES
- Do Address Space initialization as per "Windows Internals II" slides, either for the Boot, System, Cloned User or New User Process cases.
- Rename MmCreateProcessAddressSpace to MmInitializeProcessAddressSpace, and MmCopyMmInfo to MmCreateProcessAddressSpace. What ReactOS did is correct as per "Windows Internals II", but the names were inverted.
- Clone the Object Table if we are the boot process, and only initialize part of the address space (since we don't need things like guard page, TEB, etc), however, do initialize and map the shared user data section.
- Make the initial system process and idle process share the same page directory instead of creating a new one.
- Use the same priority class as the parent process, if the process was in the idle or below-normal priority class.
- Only duplicate handles if the caller requested it, instead of always duplicating the process's handles!
- Generate a null image file name for system processes.
- Rename ObpCreateHandleTable to ObInitProcess and better handle race and out-of-memory conditions. Detect if auditing required, but don't do anything about it.
- Initialize the Idle/System process address space much earlier in the boot process, in MmInitSystem.
Thanks to Alex for providing various information, and answering all my questions.
svn path=/trunk/; revision=29223
2007-09-26 20:55:26 +00:00
|
|
|
if (!NT_SUCCESS(Status)) goto CleanupWithRef;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
- PS_UNKNOWN_VALUE determines if the process should be created with large pages: rename to PS_LARGE_PAGES
- Do Address Space initialization as per "Windows Internals II" slides, either for the Boot, System, Cloned User or New User Process cases.
- Rename MmCreateProcessAddressSpace to MmInitializeProcessAddressSpace, and MmCopyMmInfo to MmCreateProcessAddressSpace. What ReactOS did is correct as per "Windows Internals II", but the names were inverted.
- Clone the Object Table if we are the boot process, and only initialize part of the address space (since we don't need things like guard page, TEB, etc), however, do initialize and map the shared user data section.
- Make the initial system process and idle process share the same page directory instead of creating a new one.
- Use the same priority class as the parent process, if the process was in the idle or below-normal priority class.
- Only duplicate handles if the caller requested it, instead of always duplicating the process's handles!
- Generate a null image file name for system processes.
- Rename ObpCreateHandleTable to ObInitProcess and better handle race and out-of-memory conditions. Detect if auditing required, but don't do anything about it.
- Initialize the Idle/System process address space much earlier in the boot process, in MmInitSystem.
Thanks to Alex for providing various information, and answering all my questions.
svn path=/trunk/; revision=29223
2007-09-26 20:55:26 +00:00
|
|
|
/* Create a dummy image file name */
|
|
|
|
Process->SeAuditProcessCreationInfo.ImageFileName =
|
|
|
|
ExAllocatePoolWithTag(PagedPool,
|
|
|
|
sizeof(OBJECT_NAME_INFORMATION),
|
2013-07-20 17:46:38 +00:00
|
|
|
TAG_SEPA);
|
- PS_UNKNOWN_VALUE determines if the process should be created with large pages: rename to PS_LARGE_PAGES
- Do Address Space initialization as per "Windows Internals II" slides, either for the Boot, System, Cloned User or New User Process cases.
- Rename MmCreateProcessAddressSpace to MmInitializeProcessAddressSpace, and MmCopyMmInfo to MmCreateProcessAddressSpace. What ReactOS did is correct as per "Windows Internals II", but the names were inverted.
- Clone the Object Table if we are the boot process, and only initialize part of the address space (since we don't need things like guard page, TEB, etc), however, do initialize and map the shared user data section.
- Make the initial system process and idle process share the same page directory instead of creating a new one.
- Use the same priority class as the parent process, if the process was in the idle or below-normal priority class.
- Only duplicate handles if the caller requested it, instead of always duplicating the process's handles!
- Generate a null image file name for system processes.
- Rename ObpCreateHandleTable to ObInitProcess and better handle race and out-of-memory conditions. Detect if auditing required, but don't do anything about it.
- Initialize the Idle/System process address space much earlier in the boot process, in MmInitSystem.
Thanks to Alex for providing various information, and answering all my questions.
svn path=/trunk/; revision=29223
2007-09-26 20:55:26 +00:00
|
|
|
if (!Process->SeAuditProcessCreationInfo.ImageFileName)
|
|
|
|
{
|
|
|
|
/* Fail */
|
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
goto CleanupWithRef;
|
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
- PS_UNKNOWN_VALUE determines if the process should be created with large pages: rename to PS_LARGE_PAGES
- Do Address Space initialization as per "Windows Internals II" slides, either for the Boot, System, Cloned User or New User Process cases.
- Rename MmCreateProcessAddressSpace to MmInitializeProcessAddressSpace, and MmCopyMmInfo to MmCreateProcessAddressSpace. What ReactOS did is correct as per "Windows Internals II", but the names were inverted.
- Clone the Object Table if we are the boot process, and only initialize part of the address space (since we don't need things like guard page, TEB, etc), however, do initialize and map the shared user data section.
- Make the initial system process and idle process share the same page directory instead of creating a new one.
- Use the same priority class as the parent process, if the process was in the idle or below-normal priority class.
- Only duplicate handles if the caller requested it, instead of always duplicating the process's handles!
- Generate a null image file name for system processes.
- Rename ObpCreateHandleTable to ObInitProcess and better handle race and out-of-memory conditions. Detect if auditing required, but don't do anything about it.
- Initialize the Idle/System process address space much earlier in the boot process, in MmInitSystem.
Thanks to Alex for providing various information, and answering all my questions.
svn path=/trunk/; revision=29223
2007-09-26 20:55:26 +00:00
|
|
|
/* Zero it out */
|
|
|
|
RtlZeroMemory(Process->SeAuditProcessCreationInfo.ImageFileName,
|
|
|
|
sizeof(OBJECT_NAME_INFORMATION));
|
|
|
|
}
|
|
|
|
}
|
2007-09-27 18:07:44 +00:00
|
|
|
|
2010-11-02 15:16:22 +00:00
|
|
|
#if MI_TRACE_PFNS
|
|
|
|
/* Copy the process name now that we have it */
|
|
|
|
memcpy(MiGetPfnEntry(Process->Pcb.DirectoryTableBase[0] >> PAGE_SHIFT)->ProcessName, Process->ImageFileName, 16);
|
|
|
|
if (Process->Pcb.DirectoryTableBase[1]) memcpy(MiGetPfnEntry(Process->Pcb.DirectoryTableBase[1] >> PAGE_SHIFT)->ProcessName, Process->ImageFileName, 16);
|
|
|
|
if (Process->WorkingSetPage) memcpy(MiGetPfnEntry(Process->WorkingSetPage)->ProcessName, Process->ImageFileName, 16);
|
|
|
|
#endif
|
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Check if we have a section object and map the system DLL */
|
2007-09-26 16:41:35 +00:00
|
|
|
if (SectionObject) PspMapSystemDll(Process, NULL, FALSE);
|
2004-11-21 21:09:43 +00:00
|
|
|
|
2005-04-18 00:42:31 +00:00
|
|
|
/* Create a handle for the Process */
|
2006-05-19 00:32:50 +00:00
|
|
|
CidEntry.Object = Process;
|
|
|
|
CidEntry.GrantedAccess = 0;
|
2005-08-08 10:08:34 +00:00
|
|
|
Process->UniqueProcessId = ExCreateHandle(PspCidTable, &CidEntry);
|
2006-07-20 14:53:47 +00:00
|
|
|
if (!Process->UniqueProcessId)
|
2005-04-18 00:42:31 +00:00
|
|
|
{
|
2007-09-27 18:07:44 +00:00
|
|
|
/* Fail */
|
2006-07-09 18:54:13 +00:00
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
goto CleanupWithRef;
|
2005-08-01 11:20:44 +00:00
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-07-23 08:20:57 +00:00
|
|
|
/* Set the handle table PID */
|
|
|
|
Process->ObjectTable->UniqueProcessId = Process->UniqueProcessId;
|
|
|
|
|
|
|
|
/* Check if we need to audit */
|
|
|
|
if (SeDetailedAuditingWithToken(NULL)) SeAuditProcessCreate(Process);
|
|
|
|
|
|
|
|
/* Check if the parent had a job */
|
|
|
|
if ((Parent) && (Parent->Job))
|
|
|
|
{
|
|
|
|
/* FIXME: We need to insert this process */
|
|
|
|
DPRINT1("Jobs not yet supported\n");
|
|
|
|
}
|
2005-01-26 00:03:05 +00:00
|
|
|
|
2005-04-18 00:42:31 +00:00
|
|
|
/* Create PEB only for User-Mode Processes */
|
2009-10-15 05:56:41 +00:00
|
|
|
if ((Parent) && (NeedsPeb))
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Set up the initial PEB
|
|
|
|
//
|
|
|
|
RtlZeroMemory(&InitialPeb, sizeof(INITIAL_PEB));
|
|
|
|
InitialPeb.Mutant = (HANDLE)-1;
|
|
|
|
InitialPeb.ImageUsesLargePages = 0; // FIXME: Not yet supported
|
2011-01-15 19:13:22 +00:00
|
|
|
|
2009-10-15 05:56:41 +00:00
|
|
|
//
|
|
|
|
// Create it only if we have an image section
|
|
|
|
//
|
|
|
|
if (SectionHandle)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Create it
|
|
|
|
//
|
|
|
|
Status = MmCreatePeb(Process, &InitialPeb, &Process->Peb);
|
|
|
|
if (!NT_SUCCESS(Status)) goto CleanupWithRef;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// We have to clone it
|
|
|
|
//
|
|
|
|
ASSERTMSG("No support for cloning yet\n", FALSE);
|
|
|
|
}
|
|
|
|
|
2005-04-18 00:42:31 +00:00
|
|
|
}
|
2004-03-07 20:31:53 +00:00
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
/* The process can now be activated */
|
2006-07-20 16:26:10 +00:00
|
|
|
KeAcquireGuardedMutex(&PspActiveProcessMutex);
|
2005-05-06 22:54:40 +00:00
|
|
|
InsertTailList(&PsActiveProcessHead, &Process->ActiveProcessLinks);
|
2006-07-20 16:26:10 +00:00
|
|
|
KeReleaseGuardedMutex(&PspActiveProcessMutex);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-07-23 08:20:57 +00:00
|
|
|
/* Create an access state */
|
|
|
|
Status = SeCreateAccessStateEx(CurrentThread,
|
|
|
|
((Parent) &&
|
|
|
|
(Parent == PsInitialSystemProcess)) ?
|
|
|
|
Parent : CurrentProcess,
|
|
|
|
&LocalAccessState,
|
|
|
|
&AuxData,
|
|
|
|
DesiredAccess,
|
|
|
|
&PsProcessType->TypeInfo.GenericMapping);
|
|
|
|
if (!NT_SUCCESS(Status)) goto CleanupWithRef;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 00:42:31 +00:00
|
|
|
/* Insert the Process into the Object Directory */
|
|
|
|
Status = ObInsertObject(Process,
|
2006-07-23 08:20:57 +00:00
|
|
|
AccessState,
|
2005-04-18 00:42:31 +00:00
|
|
|
DesiredAccess,
|
2006-06-29 05:05:27 +00:00
|
|
|
1,
|
2007-01-18 09:44:49 +00:00
|
|
|
NULL,
|
2005-04-18 00:42:31 +00:00
|
|
|
&hProcess);
|
2006-07-23 08:20:57 +00:00
|
|
|
|
|
|
|
/* Free the access state */
|
|
|
|
if (AccessState) SeDeleteAccessState(AccessState);
|
|
|
|
|
|
|
|
/* Cleanup on failure */
|
2006-07-20 14:53:47 +00:00
|
|
|
if (!NT_SUCCESS(Status)) goto Cleanup;
|
2006-07-09 18:54:13 +00:00
|
|
|
|
2006-07-23 17:01:43 +00:00
|
|
|
/* Compute Quantum and Priority */
|
2007-01-18 09:44:49 +00:00
|
|
|
ASSERT(IsListEmpty(&Process->ThreadListHead) == TRUE);
|
|
|
|
Process->Pcb.BasePriority =
|
|
|
|
(SCHAR)PspComputeQuantumAndPriority(Process,
|
|
|
|
PsProcessPriorityBackground,
|
|
|
|
&Quantum);
|
2006-07-23 17:01:43 +00:00
|
|
|
Process->Pcb.QuantumReset = Quantum;
|
|
|
|
|
|
|
|
/* Check if we have a parent other then the initial system process */
|
2007-01-18 09:44:49 +00:00
|
|
|
Process->GrantedAccess = PROCESS_TERMINATE;
|
2006-07-23 17:01:43 +00:00
|
|
|
if ((Parent) && (Parent != PsInitialSystemProcess))
|
|
|
|
{
|
|
|
|
/* Get the process's SD */
|
|
|
|
Status = ObGetObjectSecurity(Process,
|
|
|
|
&SecurityDescriptor,
|
|
|
|
&SdAllocated);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* We failed, close the handle and clean up */
|
|
|
|
ObCloseHandle(hProcess, PreviousMode);
|
|
|
|
goto CleanupWithRef;
|
|
|
|
}
|
2006-07-09 18:54:13 +00:00
|
|
|
|
2006-07-23 17:01:43 +00:00
|
|
|
/* Create the subject context */
|
|
|
|
SubjectContext.ProcessAuditId = Process;
|
|
|
|
SubjectContext.PrimaryToken = PsReferencePrimaryToken(Process);
|
|
|
|
SubjectContext.ClientToken = NULL;
|
|
|
|
|
|
|
|
/* Do the access check */
|
|
|
|
Result = SeAccessCheck(SecurityDescriptor,
|
|
|
|
&SubjectContext,
|
|
|
|
FALSE,
|
|
|
|
MAXIMUM_ALLOWED,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
&PsProcessType->TypeInfo.GenericMapping,
|
|
|
|
PreviousMode,
|
|
|
|
&Process->GrantedAccess,
|
|
|
|
&AccessStatus);
|
|
|
|
|
|
|
|
/* Dereference the token and let go the SD */
|
|
|
|
ObFastDereferenceObject(&Process->Token,
|
|
|
|
SubjectContext.PrimaryToken);
|
|
|
|
ObReleaseObjectSecurity(SecurityDescriptor, SdAllocated);
|
|
|
|
|
|
|
|
/* Remove access if it failed */
|
|
|
|
if (!Result) Process->GrantedAccess = 0;
|
|
|
|
|
|
|
|
/* Give the process some basic access */
|
|
|
|
Process->GrantedAccess |= (PROCESS_VM_OPERATION |
|
|
|
|
PROCESS_VM_READ |
|
|
|
|
PROCESS_VM_WRITE |
|
|
|
|
PROCESS_QUERY_INFORMATION |
|
|
|
|
PROCESS_TERMINATE |
|
|
|
|
PROCESS_CREATE_THREAD |
|
|
|
|
PROCESS_DUP_HANDLE |
|
|
|
|
PROCESS_CREATE_PROCESS |
|
2007-01-18 09:44:49 +00:00
|
|
|
PROCESS_SET_INFORMATION |
|
|
|
|
STANDARD_RIGHTS_ALL |
|
|
|
|
PROCESS_SET_QUOTA);
|
2006-07-23 17:01:43 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Set full granted access */
|
|
|
|
Process->GrantedAccess = PROCESS_ALL_ACCESS;
|
|
|
|
}
|
2006-07-09 18:54:13 +00:00
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Set the Creation Time */
|
|
|
|
KeQuerySystemTime(&Process->CreateTime);
|
|
|
|
|
|
|
|
/* Protect against bad user-mode pointer */
|
2008-11-24 13:40:26 +00:00
|
|
|
_SEH2_TRY
|
2006-07-20 14:53:47 +00:00
|
|
|
{
|
2013-07-25 18:32:52 +00:00
|
|
|
/* Hacky way of returning the PEB to the user-mode creator */
|
|
|
|
if ((Process->Peb) && (CurrentThread->Tcb.Teb))
|
|
|
|
{
|
|
|
|
CurrentThread->Tcb.Teb->NtTib.ArbitraryUserPointer = Process->Peb;
|
|
|
|
}
|
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Save the process handle */
|
|
|
|
*ProcessHandle = hProcess;
|
|
|
|
}
|
2008-11-24 13:40:26 +00:00
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
2006-07-20 14:53:47 +00:00
|
|
|
{
|
|
|
|
/* Get the exception code */
|
2008-11-24 13:40:26 +00:00
|
|
|
Status = _SEH2_GetExceptionCode();
|
2005-10-29 22:15:10 +00:00
|
|
|
}
|
2008-11-24 13:40:26 +00:00
|
|
|
_SEH2_END;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2009-01-09 06:13:14 +00:00
|
|
|
/* Run the Notification Routines */
|
|
|
|
PspRunCreateProcessNotifyRoutines(Process, TRUE);
|
2011-01-15 19:13:22 +00:00
|
|
|
|
2010-01-28 15:51:18 +00:00
|
|
|
/* If 12 processes have been created, enough of user-mode is ready */
|
2010-02-01 03:51:45 +00:00
|
|
|
if (++ProcessCount == 12) Ki386PerfEnd();
|
2009-01-09 06:13:14 +00:00
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
CleanupWithRef:
|
2007-10-19 23:21:45 +00:00
|
|
|
/*
|
2006-07-09 18:54:13 +00:00
|
|
|
* Dereference the process. For failures, kills the process and does
|
|
|
|
* cleanup present in PspDeleteProcess. For success, kills the extra
|
2006-07-20 14:53:47 +00:00
|
|
|
* reference added by ObInsertObject.
|
2006-07-09 18:54:13 +00:00
|
|
|
*/
|
|
|
|
ObDereferenceObject(Process);
|
|
|
|
|
2005-10-29 22:15:10 +00:00
|
|
|
Cleanup:
|
2006-07-09 18:54:13 +00:00
|
|
|
/* Dereference the parent */
|
|
|
|
if (Parent) ObDereferenceObject(Parent);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-07-09 18:54:13 +00:00
|
|
|
/* Return status to caller */
|
2005-04-18 00:42:31 +00:00
|
|
|
return Status;
|
2005-01-26 00:03:05 +00:00
|
|
|
}
|
|
|
|
|
2006-07-23 19:45:16 +00:00
|
|
|
/* PUBLIC FUNCTIONS **********************************************************/
|
2005-01-26 00:03:05 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2005-05-09 01:38:29 +00:00
|
|
|
NTSTATUS
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2006-07-20 14:53:47 +00:00
|
|
|
PsCreateSystemProcess(OUT PHANDLE ProcessHandle,
|
|
|
|
IN ACCESS_MASK DesiredAccess,
|
|
|
|
IN POBJECT_ATTRIBUTES ObjectAttributes)
|
2005-01-26 00:03:05 +00:00
|
|
|
{
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Call the internal API */
|
2005-04-18 02:12:30 +00:00
|
|
|
return PspCreateProcess(ProcessHandle,
|
|
|
|
DesiredAccess,
|
|
|
|
ObjectAttributes,
|
2006-07-09 18:54:13 +00:00
|
|
|
NULL,
|
|
|
|
0,
|
2005-04-18 02:12:30 +00:00
|
|
|
NULL,
|
|
|
|
NULL,
|
2006-07-09 18:54:13 +00:00
|
|
|
NULL,
|
|
|
|
FALSE);
|
2005-01-26 00:03:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2005-05-09 01:38:29 +00:00
|
|
|
NTSTATUS
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsLookupProcessByProcessId(IN HANDLE ProcessId,
|
|
|
|
OUT PEPROCESS *Process)
|
2005-01-26 00:03:05 +00:00
|
|
|
{
|
2005-08-07 22:48:07 +00:00
|
|
|
PHANDLE_TABLE_ENTRY CidEntry;
|
|
|
|
PEPROCESS FoundProcess;
|
|
|
|
NTSTATUS Status = STATUS_INVALID_PARAMETER;
|
|
|
|
PAGED_CODE();
|
2006-07-23 19:45:16 +00:00
|
|
|
PSTRACE(PS_PROCESS_DEBUG, "ProcessId: %p\n", ProcessId);
|
2005-08-08 10:54:32 +00:00
|
|
|
KeEnterCriticalRegion();
|
2005-08-07 22:48:07 +00:00
|
|
|
|
|
|
|
/* Get the CID Handle Entry */
|
2006-07-20 14:53:47 +00:00
|
|
|
CidEntry = ExMapHandleToPointer(PspCidTable, ProcessId);
|
|
|
|
if (CidEntry)
|
2005-08-07 22:48:07 +00:00
|
|
|
{
|
|
|
|
/* Get the Process */
|
2006-05-19 00:32:50 +00:00
|
|
|
FoundProcess = CidEntry->Object;
|
2005-04-18 02:12:30 +00:00
|
|
|
|
2005-08-07 22:48:07 +00:00
|
|
|
/* Make sure it's really a process */
|
|
|
|
if (FoundProcess->Pcb.Header.Type == ProcessObject)
|
|
|
|
{
|
2006-07-20 18:47:35 +00:00
|
|
|
/* Safe Reference and return it */
|
|
|
|
if (ObReferenceObjectSafe(FoundProcess))
|
|
|
|
{
|
|
|
|
*Process = FoundProcess;
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
}
|
2005-08-07 22:48:07 +00:00
|
|
|
}
|
2005-01-26 00:03:05 +00:00
|
|
|
|
2005-08-07 22:48:07 +00:00
|
|
|
/* Unlock the Entry */
|
|
|
|
ExUnlockHandleTableEntry(PspCidTable, CidEntry);
|
|
|
|
}
|
2005-04-18 02:12:30 +00:00
|
|
|
|
2005-08-07 22:48:07 +00:00
|
|
|
/* Return to caller */
|
2006-07-09 18:54:13 +00:00
|
|
|
KeLeaveCriticalRegion();
|
2005-08-07 22:48:07 +00:00
|
|
|
return Status;
|
|
|
|
}
|
1999-01-16 02:11:45 +00:00
|
|
|
|
2005-08-07 22:48:07 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
NTSTATUS
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-08-07 22:48:07 +00:00
|
|
|
PsLookupProcessThreadByCid(IN PCLIENT_ID Cid,
|
|
|
|
OUT PEPROCESS *Process OPTIONAL,
|
|
|
|
OUT PETHREAD *Thread)
|
|
|
|
{
|
|
|
|
PHANDLE_TABLE_ENTRY CidEntry;
|
|
|
|
PETHREAD FoundThread;
|
2005-08-07 23:00:51 +00:00
|
|
|
NTSTATUS Status = STATUS_INVALID_CID;
|
2005-08-07 22:48:07 +00:00
|
|
|
PAGED_CODE();
|
2006-07-23 19:45:16 +00:00
|
|
|
PSTRACE(PS_PROCESS_DEBUG, "Cid: %p\n", Cid);
|
2005-08-08 10:54:32 +00:00
|
|
|
KeEnterCriticalRegion();
|
2005-08-07 22:48:07 +00:00
|
|
|
|
|
|
|
/* Get the CID Handle Entry */
|
2006-07-20 14:53:47 +00:00
|
|
|
CidEntry = ExMapHandleToPointer(PspCidTable, Cid->UniqueThread);
|
|
|
|
if (CidEntry)
|
2005-08-07 22:48:07 +00:00
|
|
|
{
|
|
|
|
/* Get the Process */
|
2006-05-19 00:32:50 +00:00
|
|
|
FoundThread = CidEntry->Object;
|
2005-04-18 02:12:30 +00:00
|
|
|
|
2005-08-07 22:48:07 +00:00
|
|
|
/* Make sure it's really a thread and this process' */
|
2011-10-07 16:18:52 +00:00
|
|
|
if ((FoundThread->Tcb.Header.Type == ThreadObject) &&
|
2005-08-07 22:48:07 +00:00
|
|
|
(FoundThread->Cid.UniqueProcess == Cid->UniqueProcess))
|
|
|
|
{
|
2006-07-20 18:47:35 +00:00
|
|
|
/* Safe Reference and return it */
|
|
|
|
if (ObReferenceObjectSafe(FoundThread))
|
2005-08-07 22:48:07 +00:00
|
|
|
{
|
2006-07-20 18:47:35 +00:00
|
|
|
*Thread = FoundThread;
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
/* Check if we should return the Process too */
|
|
|
|
if (Process)
|
|
|
|
{
|
|
|
|
/* Return it and reference it */
|
|
|
|
*Process = FoundThread->ThreadsProcess;
|
|
|
|
ObReferenceObject(*Process);
|
|
|
|
}
|
2005-08-07 22:48:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unlock the Entry */
|
|
|
|
ExUnlockHandleTableEntry(PspCidTable, CidEntry);
|
2005-04-18 02:12:30 +00:00
|
|
|
}
|
2006-07-20 14:53:47 +00:00
|
|
|
|
2005-08-07 22:48:07 +00:00
|
|
|
/* Return to caller */
|
2006-07-09 18:54:13 +00:00
|
|
|
KeLeaveCriticalRegion();
|
2005-08-07 22:48:07 +00:00
|
|
|
return Status;
|
2005-04-18 02:12:30 +00:00
|
|
|
}
|
1999-01-16 02:11:45 +00:00
|
|
|
|
2003-07-11 01:23:16 +00:00
|
|
|
/*
|
2005-04-18 02:12:30 +00:00
|
|
|
* @implemented
|
2003-07-11 01:23:16 +00:00
|
|
|
*/
|
2006-07-20 14:53:47 +00:00
|
|
|
LARGE_INTEGER
|
|
|
|
NTAPI
|
2001-11-29 16:41:22 +00:00
|
|
|
PsGetProcessExitTime(VOID)
|
|
|
|
{
|
2006-07-20 14:53:47 +00:00
|
|
|
return PsGetCurrentProcess()->ExitTime;
|
2001-11-29 16:41:22 +00:00
|
|
|
}
|
|
|
|
|
2003-07-11 01:23:16 +00:00
|
|
|
/*
|
Implemented PsGetProcessCreateTimeQuadPart, PsGetProcessDebugPort, PsGetProcessExitProcessCalled, PsGetProcessExitStatus, PsGetProcessId, PsGetProcessImageFileName, PsGetProcessInheritedFromUniqueProcessId, PsGetProcessPeb,
PsGetProcessPriorityClass, PsGetProcessSectionBaseAddress,
PsGetProcessSecurityPort, PsGetProcessWin32Process,
PsGetProcessWin32WindowStation, PsIsProcessBeingDebugged,
PsGetCurrentProcessSessionId, PsGetProcessSessionId, PsSetProcessPriorityClass, PsSetProcessSecurityPort, PsSetProcessWin32Process, PsSetProcessWin32WindowStation
svn path=/trunk/; revision=10237
2004-07-20 23:58:35 +00:00
|
|
|
* @implemented
|
2004-07-19 06:08:21 +00:00
|
|
|
*/
|
Implemented PsGetProcessCreateTimeQuadPart, PsGetProcessDebugPort, PsGetProcessExitProcessCalled, PsGetProcessExitStatus, PsGetProcessId, PsGetProcessImageFileName, PsGetProcessInheritedFromUniqueProcessId, PsGetProcessPeb,
PsGetProcessPriorityClass, PsGetProcessSectionBaseAddress,
PsGetProcessSecurityPort, PsGetProcessWin32Process,
PsGetProcessWin32WindowStation, PsIsProcessBeingDebugged,
PsGetCurrentProcessSessionId, PsGetProcessSessionId, PsSetProcessPriorityClass, PsSetProcessSecurityPort, PsSetProcessWin32Process, PsSetProcessWin32WindowStation
svn path=/trunk/; revision=10237
2004-07-20 23:58:35 +00:00
|
|
|
LONGLONG
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsGetProcessCreateTimeQuadPart(PEPROCESS Process)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2005-04-18 02:12:30 +00:00
|
|
|
return Process->CreateTime.QuadPart;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Implemented PsGetProcessCreateTimeQuadPart, PsGetProcessDebugPort, PsGetProcessExitProcessCalled, PsGetProcessExitStatus, PsGetProcessId, PsGetProcessImageFileName, PsGetProcessInheritedFromUniqueProcessId, PsGetProcessPeb,
PsGetProcessPriorityClass, PsGetProcessSectionBaseAddress,
PsGetProcessSecurityPort, PsGetProcessWin32Process,
PsGetProcessWin32WindowStation, PsIsProcessBeingDebugged,
PsGetCurrentProcessSessionId, PsGetProcessSessionId, PsSetProcessPriorityClass, PsSetProcessSecurityPort, PsSetProcessWin32Process, PsSetProcessWin32WindowStation
svn path=/trunk/; revision=10237
2004-07-20 23:58:35 +00:00
|
|
|
* @implemented
|
2004-07-19 06:08:21 +00:00
|
|
|
*/
|
|
|
|
PVOID
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsGetProcessDebugPort(PEPROCESS Process)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2005-04-18 02:12:30 +00:00
|
|
|
return Process->DebugPort;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Implemented PsGetProcessCreateTimeQuadPart, PsGetProcessDebugPort, PsGetProcessExitProcessCalled, PsGetProcessExitStatus, PsGetProcessId, PsGetProcessImageFileName, PsGetProcessInheritedFromUniqueProcessId, PsGetProcessPeb,
PsGetProcessPriorityClass, PsGetProcessSectionBaseAddress,
PsGetProcessSecurityPort, PsGetProcessWin32Process,
PsGetProcessWin32WindowStation, PsIsProcessBeingDebugged,
PsGetCurrentProcessSessionId, PsGetProcessSessionId, PsSetProcessPriorityClass, PsSetProcessSecurityPort, PsSetProcessWin32Process, PsSetProcessWin32WindowStation
svn path=/trunk/; revision=10237
2004-07-20 23:58:35 +00:00
|
|
|
* @implemented
|
2004-07-19 06:08:21 +00:00
|
|
|
*/
|
|
|
|
BOOLEAN
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsGetProcessExitProcessCalled(PEPROCESS Process)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2006-10-26 01:49:51 +00:00
|
|
|
return (BOOLEAN)Process->ProcessExiting;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Implemented PsGetProcessCreateTimeQuadPart, PsGetProcessDebugPort, PsGetProcessExitProcessCalled, PsGetProcessExitStatus, PsGetProcessId, PsGetProcessImageFileName, PsGetProcessInheritedFromUniqueProcessId, PsGetProcessPeb,
PsGetProcessPriorityClass, PsGetProcessSectionBaseAddress,
PsGetProcessSecurityPort, PsGetProcessWin32Process,
PsGetProcessWin32WindowStation, PsIsProcessBeingDebugged,
PsGetCurrentProcessSessionId, PsGetProcessSessionId, PsSetProcessPriorityClass, PsSetProcessSecurityPort, PsSetProcessWin32Process, PsSetProcessWin32WindowStation
svn path=/trunk/; revision=10237
2004-07-20 23:58:35 +00:00
|
|
|
* @implemented
|
2004-07-19 06:08:21 +00:00
|
|
|
*/
|
|
|
|
NTSTATUS
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsGetProcessExitStatus(PEPROCESS Process)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2005-04-18 02:12:30 +00:00
|
|
|
return Process->ExitStatus;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Implemented PsGetProcessCreateTimeQuadPart, PsGetProcessDebugPort, PsGetProcessExitProcessCalled, PsGetProcessExitStatus, PsGetProcessId, PsGetProcessImageFileName, PsGetProcessInheritedFromUniqueProcessId, PsGetProcessPeb,
PsGetProcessPriorityClass, PsGetProcessSectionBaseAddress,
PsGetProcessSecurityPort, PsGetProcessWin32Process,
PsGetProcessWin32WindowStation, PsIsProcessBeingDebugged,
PsGetCurrentProcessSessionId, PsGetProcessSessionId, PsSetProcessPriorityClass, PsSetProcessSecurityPort, PsSetProcessWin32Process, PsSetProcessWin32WindowStation
svn path=/trunk/; revision=10237
2004-07-20 23:58:35 +00:00
|
|
|
* @implemented
|
2004-07-19 06:08:21 +00:00
|
|
|
*/
|
|
|
|
HANDLE
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsGetProcessId(PEPROCESS Process)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2005-04-18 02:12:30 +00:00
|
|
|
return (HANDLE)Process->UniqueProcessId;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Implemented PsGetProcessCreateTimeQuadPart, PsGetProcessDebugPort, PsGetProcessExitProcessCalled, PsGetProcessExitStatus, PsGetProcessId, PsGetProcessImageFileName, PsGetProcessInheritedFromUniqueProcessId, PsGetProcessPeb,
PsGetProcessPriorityClass, PsGetProcessSectionBaseAddress,
PsGetProcessSecurityPort, PsGetProcessWin32Process,
PsGetProcessWin32WindowStation, PsIsProcessBeingDebugged,
PsGetCurrentProcessSessionId, PsGetProcessSessionId, PsSetProcessPriorityClass, PsSetProcessSecurityPort, PsSetProcessWin32Process, PsSetProcessWin32WindowStation
svn path=/trunk/; revision=10237
2004-07-20 23:58:35 +00:00
|
|
|
* @implemented
|
2004-07-19 06:08:21 +00:00
|
|
|
*/
|
Implemented PsGetProcessCreateTimeQuadPart, PsGetProcessDebugPort, PsGetProcessExitProcessCalled, PsGetProcessExitStatus, PsGetProcessId, PsGetProcessImageFileName, PsGetProcessInheritedFromUniqueProcessId, PsGetProcessPeb,
PsGetProcessPriorityClass, PsGetProcessSectionBaseAddress,
PsGetProcessSecurityPort, PsGetProcessWin32Process,
PsGetProcessWin32WindowStation, PsIsProcessBeingDebugged,
PsGetCurrentProcessSessionId, PsGetProcessSessionId, PsSetProcessPriorityClass, PsSetProcessSecurityPort, PsSetProcessWin32Process, PsSetProcessWin32WindowStation
svn path=/trunk/; revision=10237
2004-07-20 23:58:35 +00:00
|
|
|
LPSTR
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsGetProcessImageFileName(PEPROCESS Process)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2005-04-18 02:12:30 +00:00
|
|
|
return (LPSTR)Process->ImageFileName;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Implemented PsGetProcessCreateTimeQuadPart, PsGetProcessDebugPort, PsGetProcessExitProcessCalled, PsGetProcessExitStatus, PsGetProcessId, PsGetProcessImageFileName, PsGetProcessInheritedFromUniqueProcessId, PsGetProcessPeb,
PsGetProcessPriorityClass, PsGetProcessSectionBaseAddress,
PsGetProcessSecurityPort, PsGetProcessWin32Process,
PsGetProcessWin32WindowStation, PsIsProcessBeingDebugged,
PsGetCurrentProcessSessionId, PsGetProcessSessionId, PsSetProcessPriorityClass, PsSetProcessSecurityPort, PsSetProcessWin32Process, PsSetProcessWin32WindowStation
svn path=/trunk/; revision=10237
2004-07-20 23:58:35 +00:00
|
|
|
* @implemented
|
2004-07-19 06:08:21 +00:00
|
|
|
*/
|
|
|
|
HANDLE
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsGetProcessInheritedFromUniqueProcessId(PEPROCESS Process)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2005-04-18 02:12:30 +00:00
|
|
|
return Process->InheritedFromUniqueProcessId;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2004-09-22 14:53:26 +00:00
|
|
|
* @implemented
|
2004-07-19 06:08:21 +00:00
|
|
|
*/
|
2004-09-22 14:53:26 +00:00
|
|
|
PEJOB
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsGetProcessJob(PEPROCESS Process)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2005-04-18 02:12:30 +00:00
|
|
|
return Process->Job;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Implemented PsGetProcessCreateTimeQuadPart, PsGetProcessDebugPort, PsGetProcessExitProcessCalled, PsGetProcessExitStatus, PsGetProcessId, PsGetProcessImageFileName, PsGetProcessInheritedFromUniqueProcessId, PsGetProcessPeb,
PsGetProcessPriorityClass, PsGetProcessSectionBaseAddress,
PsGetProcessSecurityPort, PsGetProcessWin32Process,
PsGetProcessWin32WindowStation, PsIsProcessBeingDebugged,
PsGetCurrentProcessSessionId, PsGetProcessSessionId, PsSetProcessPriorityClass, PsSetProcessSecurityPort, PsSetProcessWin32Process, PsSetProcessWin32WindowStation
svn path=/trunk/; revision=10237
2004-07-20 23:58:35 +00:00
|
|
|
* @implemented
|
2003-07-11 01:23:16 +00:00
|
|
|
*/
|
2004-07-19 06:08:21 +00:00
|
|
|
PPEB
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsGetProcessPeb(PEPROCESS Process)
|
2001-11-29 16:41:22 +00:00
|
|
|
{
|
2005-04-18 02:12:30 +00:00
|
|
|
return Process->Peb;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Implemented PsGetProcessCreateTimeQuadPart, PsGetProcessDebugPort, PsGetProcessExitProcessCalled, PsGetProcessExitStatus, PsGetProcessId, PsGetProcessImageFileName, PsGetProcessInheritedFromUniqueProcessId, PsGetProcessPeb,
PsGetProcessPriorityClass, PsGetProcessSectionBaseAddress,
PsGetProcessSecurityPort, PsGetProcessWin32Process,
PsGetProcessWin32WindowStation, PsIsProcessBeingDebugged,
PsGetCurrentProcessSessionId, PsGetProcessSessionId, PsSetProcessPriorityClass, PsSetProcessSecurityPort, PsSetProcessWin32Process, PsSetProcessWin32WindowStation
svn path=/trunk/; revision=10237
2004-07-20 23:58:35 +00:00
|
|
|
* @implemented
|
2004-07-19 06:08:21 +00:00
|
|
|
*/
|
|
|
|
ULONG
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsGetProcessPriorityClass(PEPROCESS Process)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2005-04-18 02:12:30 +00:00
|
|
|
return Process->PriorityClass;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Implemented PsGetProcessCreateTimeQuadPart, PsGetProcessDebugPort, PsGetProcessExitProcessCalled, PsGetProcessExitStatus, PsGetProcessId, PsGetProcessImageFileName, PsGetProcessInheritedFromUniqueProcessId, PsGetProcessPeb,
PsGetProcessPriorityClass, PsGetProcessSectionBaseAddress,
PsGetProcessSecurityPort, PsGetProcessWin32Process,
PsGetProcessWin32WindowStation, PsIsProcessBeingDebugged,
PsGetCurrentProcessSessionId, PsGetProcessSessionId, PsSetProcessPriorityClass, PsSetProcessSecurityPort, PsSetProcessWin32Process, PsSetProcessWin32WindowStation
svn path=/trunk/; revision=10237
2004-07-20 23:58:35 +00:00
|
|
|
* @implemented
|
2004-07-19 06:08:21 +00:00
|
|
|
*/
|
2006-07-27 18:28:26 +00:00
|
|
|
HANDLE
|
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsGetCurrentProcessId(VOID)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2006-07-27 18:28:26 +00:00
|
|
|
return (HANDLE)PsGetCurrentProcess()->UniqueProcessId;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Implemented PsGetProcessCreateTimeQuadPart, PsGetProcessDebugPort, PsGetProcessExitProcessCalled, PsGetProcessExitStatus, PsGetProcessId, PsGetProcessImageFileName, PsGetProcessInheritedFromUniqueProcessId, PsGetProcessPeb,
PsGetProcessPriorityClass, PsGetProcessSectionBaseAddress,
PsGetProcessSecurityPort, PsGetProcessWin32Process,
PsGetProcessWin32WindowStation, PsIsProcessBeingDebugged,
PsGetCurrentProcessSessionId, PsGetProcessSessionId, PsSetProcessPriorityClass, PsSetProcessSecurityPort, PsSetProcessWin32Process, PsSetProcessWin32WindowStation
svn path=/trunk/; revision=10237
2004-07-20 23:58:35 +00:00
|
|
|
* @implemented
|
2004-07-19 06:08:21 +00:00
|
|
|
*/
|
2005-04-18 02:12:30 +00:00
|
|
|
ULONG
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsGetCurrentProcessSessionId(VOID)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2012-08-01 07:54:37 +00:00
|
|
|
return MmGetSessionId(PsGetCurrentProcess());
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Implemented PsGetProcessCreateTimeQuadPart, PsGetProcessDebugPort, PsGetProcessExitProcessCalled, PsGetProcessExitStatus, PsGetProcessId, PsGetProcessImageFileName, PsGetProcessInheritedFromUniqueProcessId, PsGetProcessPeb,
PsGetProcessPriorityClass, PsGetProcessSectionBaseAddress,
PsGetProcessSecurityPort, PsGetProcessWin32Process,
PsGetProcessWin32WindowStation, PsIsProcessBeingDebugged,
PsGetCurrentProcessSessionId, PsGetProcessSessionId, PsSetProcessPriorityClass, PsSetProcessSecurityPort, PsSetProcessWin32Process, PsSetProcessWin32WindowStation
svn path=/trunk/; revision=10237
2004-07-20 23:58:35 +00:00
|
|
|
* @implemented
|
2004-07-19 06:08:21 +00:00
|
|
|
*/
|
|
|
|
PVOID
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsGetProcessSectionBaseAddress(PEPROCESS Process)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2005-04-18 02:12:30 +00:00
|
|
|
return Process->SectionBaseAddress;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Implemented PsGetProcessCreateTimeQuadPart, PsGetProcessDebugPort, PsGetProcessExitProcessCalled, PsGetProcessExitStatus, PsGetProcessId, PsGetProcessImageFileName, PsGetProcessInheritedFromUniqueProcessId, PsGetProcessPeb,
PsGetProcessPriorityClass, PsGetProcessSectionBaseAddress,
PsGetProcessSecurityPort, PsGetProcessWin32Process,
PsGetProcessWin32WindowStation, PsIsProcessBeingDebugged,
PsGetCurrentProcessSessionId, PsGetProcessSessionId, PsSetProcessPriorityClass, PsSetProcessSecurityPort, PsSetProcessWin32Process, PsSetProcessWin32WindowStation
svn path=/trunk/; revision=10237
2004-07-20 23:58:35 +00:00
|
|
|
* @implemented
|
2004-07-19 06:08:21 +00:00
|
|
|
*/
|
|
|
|
PVOID
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsGetProcessSecurityPort(PEPROCESS Process)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2005-04-18 02:12:30 +00:00
|
|
|
return Process->SecurityPort;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Implemented PsGetProcessCreateTimeQuadPart, PsGetProcessDebugPort, PsGetProcessExitProcessCalled, PsGetProcessExitStatus, PsGetProcessId, PsGetProcessImageFileName, PsGetProcessInheritedFromUniqueProcessId, PsGetProcessPeb,
PsGetProcessPriorityClass, PsGetProcessSectionBaseAddress,
PsGetProcessSecurityPort, PsGetProcessWin32Process,
PsGetProcessWin32WindowStation, PsIsProcessBeingDebugged,
PsGetCurrentProcessSessionId, PsGetProcessSessionId, PsSetProcessPriorityClass, PsSetProcessSecurityPort, PsSetProcessWin32Process, PsSetProcessWin32WindowStation
svn path=/trunk/; revision=10237
2004-07-20 23:58:35 +00:00
|
|
|
* @implemented
|
2004-07-19 06:08:21 +00:00
|
|
|
*/
|
2013-09-21 20:14:22 +00:00
|
|
|
ULONG
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2013-09-22 18:47:36 +00:00
|
|
|
PsGetProcessSessionId(IN PEPROCESS Process)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2013-09-21 20:14:22 +00:00
|
|
|
return MmGetSessionId(Process);
|
2001-11-29 16:41:22 +00:00
|
|
|
}
|
|
|
|
|
2013-09-22 18:47:36 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
ULONG
|
|
|
|
NTAPI
|
|
|
|
PsGetProcessSessionIdEx(IN PEPROCESS Process)
|
|
|
|
{
|
|
|
|
return MmGetSessionIdEx(Process);
|
|
|
|
}
|
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2008-10-18 20:34:36 +00:00
|
|
|
PVOID
|
2006-07-20 14:53:47 +00:00
|
|
|
NTAPI
|
|
|
|
PsGetCurrentProcessWin32Process(VOID)
|
2005-06-26 16:06:32 +00:00
|
|
|
{
|
2008-10-18 20:34:36 +00:00
|
|
|
return PsGetCurrentProcess()->Win32Process;
|
2005-06-26 16:06:32 +00:00
|
|
|
}
|
|
|
|
|
2003-07-11 01:23:16 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2005-04-18 02:12:30 +00:00
|
|
|
PVOID
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsGetProcessWin32Process(PEPROCESS Process)
|
2003-12-30 00:12:47 +00:00
|
|
|
{
|
2005-04-18 02:12:30 +00:00
|
|
|
return Process->Win32Process;
|
2003-12-30 00:12:47 +00:00
|
|
|
}
|
2002-01-03 18:02:34 +00:00
|
|
|
|
2003-07-11 01:23:16 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2005-04-18 02:12:30 +00:00
|
|
|
PVOID
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsGetProcessWin32WindowStation(PEPROCESS Process)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2005-04-18 02:12:30 +00:00
|
|
|
return Process->Win32WindowStation;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
2004-03-07 20:31:53 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2005-04-18 02:12:30 +00:00
|
|
|
BOOLEAN
|
2006-07-27 18:28:26 +00:00
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsIsProcessBeingDebugged(PEPROCESS Process)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2006-07-20 14:53:47 +00:00
|
|
|
return Process->DebugPort != NULL;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
2008-09-25 14:39:38 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
PsIsSystemProcess(IN PEPROCESS Process)
|
|
|
|
{
|
|
|
|
/* Return if this is the System Process */
|
|
|
|
return Process == PsInitialSystemProcess;
|
|
|
|
}
|
|
|
|
|
2004-07-19 06:08:21 +00:00
|
|
|
/*
|
Implemented PsGetProcessCreateTimeQuadPart, PsGetProcessDebugPort, PsGetProcessExitProcessCalled, PsGetProcessExitStatus, PsGetProcessId, PsGetProcessImageFileName, PsGetProcessInheritedFromUniqueProcessId, PsGetProcessPeb,
PsGetProcessPriorityClass, PsGetProcessSectionBaseAddress,
PsGetProcessSecurityPort, PsGetProcessWin32Process,
PsGetProcessWin32WindowStation, PsIsProcessBeingDebugged,
PsGetCurrentProcessSessionId, PsGetProcessSessionId, PsSetProcessPriorityClass, PsSetProcessSecurityPort, PsSetProcessWin32Process, PsSetProcessWin32WindowStation
svn path=/trunk/; revision=10237
2004-07-20 23:58:35 +00:00
|
|
|
* @implemented
|
2005-05-09 01:38:29 +00:00
|
|
|
*/
|
2004-07-19 06:08:21 +00:00
|
|
|
VOID
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsSetProcessPriorityClass(PEPROCESS Process,
|
|
|
|
ULONG PriorityClass)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2006-10-26 01:49:51 +00:00
|
|
|
Process->PriorityClass = (UCHAR)PriorityClass;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Implemented PsGetProcessCreateTimeQuadPart, PsGetProcessDebugPort, PsGetProcessExitProcessCalled, PsGetProcessExitStatus, PsGetProcessId, PsGetProcessImageFileName, PsGetProcessInheritedFromUniqueProcessId, PsGetProcessPeb,
PsGetProcessPriorityClass, PsGetProcessSectionBaseAddress,
PsGetProcessSecurityPort, PsGetProcessWin32Process,
PsGetProcessWin32WindowStation, PsIsProcessBeingDebugged,
PsGetCurrentProcessSessionId, PsGetProcessSessionId, PsSetProcessPriorityClass, PsSetProcessSecurityPort, PsSetProcessWin32Process, PsSetProcessWin32WindowStation
svn path=/trunk/; revision=10237
2004-07-20 23:58:35 +00:00
|
|
|
* @implemented
|
2005-05-09 01:38:29 +00:00
|
|
|
*/
|
2014-01-22 14:48:45 +00:00
|
|
|
NTSTATUS
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
PsSetProcessSecurityPort(PEPROCESS Process,
|
|
|
|
PVOID SecurityPort)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2005-04-18 02:12:30 +00:00
|
|
|
Process->SecurityPort = SecurityPort;
|
2014-01-22 14:48:45 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Implemented PsGetProcessCreateTimeQuadPart, PsGetProcessDebugPort, PsGetProcessExitProcessCalled, PsGetProcessExitStatus, PsGetProcessId, PsGetProcessImageFileName, PsGetProcessInheritedFromUniqueProcessId, PsGetProcessPeb,
PsGetProcessPriorityClass, PsGetProcessSectionBaseAddress,
PsGetProcessSecurityPort, PsGetProcessWin32Process,
PsGetProcessWin32WindowStation, PsIsProcessBeingDebugged,
PsGetCurrentProcessSessionId, PsGetProcessSessionId, PsSetProcessPriorityClass, PsSetProcessSecurityPort, PsSetProcessWin32Process, PsSetProcessWin32WindowStation
svn path=/trunk/; revision=10237
2004-07-20 23:58:35 +00:00
|
|
|
* @implemented
|
2004-11-20 16:46:06 +00:00
|
|
|
*/
|
2014-01-22 14:48:45 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2013-11-11 18:52:59 +00:00
|
|
|
PsSetProcessWin32Process(
|
2014-01-22 14:48:45 +00:00
|
|
|
_Inout_ PEPROCESS Process,
|
|
|
|
_In_opt_ PVOID Win32Process,
|
2013-11-11 18:52:59 +00:00
|
|
|
_In_opt_ PVOID OldWin32Process)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2013-11-11 18:52:59 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Assume success */
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
/* Lock the process */
|
|
|
|
KeEnterCriticalRegion();
|
|
|
|
ExAcquirePushLockExclusive(&Process->ProcessLock);
|
|
|
|
|
|
|
|
/* Check if we set a new win32 process */
|
|
|
|
if (Win32Process != NULL)
|
|
|
|
{
|
|
|
|
/* Check if the process is in the right state */
|
|
|
|
if (((Process->Flags & PSF_PROCESS_DELETE_BIT) == 0) &&
|
|
|
|
(Process->Win32Process == NULL))
|
|
|
|
{
|
|
|
|
/* Set the new win32 process */
|
|
|
|
Process->Win32Process = Win32Process;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Otherwise fail */
|
|
|
|
Status = STATUS_PROCESS_IS_TERMINATING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Reset the win32 process, did the caller specify the correct old value? */
|
|
|
|
if (Process->Win32Process == OldWin32Process)
|
|
|
|
{
|
|
|
|
/* Yes, so reset the win32 process to NULL */
|
2017-06-19 14:48:59 +00:00
|
|
|
Process->Win32Process = NULL;
|
2013-11-11 18:52:59 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Otherwise fail */
|
|
|
|
Status = STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unlock the process */
|
|
|
|
ExReleasePushLockExclusive(&Process->ProcessLock);
|
|
|
|
KeLeaveCriticalRegion();
|
|
|
|
|
|
|
|
return Status;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2004-08-08 20:33:17 +00:00
|
|
|
* @implemented
|
2004-07-19 06:08:21 +00:00
|
|
|
*/
|
|
|
|
VOID
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-08-02 13:52:10 +00:00
|
|
|
PsSetProcessWindowStation(PEPROCESS Process,
|
|
|
|
PVOID WindowStation)
|
2004-07-19 06:08:21 +00:00
|
|
|
{
|
2005-04-18 02:12:30 +00:00
|
|
|
Process->Win32WindowStation = WindowStation;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
2005-08-02 13:52:10 +00:00
|
|
|
/*
|
2006-07-21 19:28:38 +00:00
|
|
|
* @implemented
|
2005-08-02 13:52:10 +00:00
|
|
|
*/
|
2006-07-21 19:28:38 +00:00
|
|
|
VOID
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
2005-08-02 13:52:10 +00:00
|
|
|
PsSetProcessPriorityByClass(IN PEPROCESS Process,
|
2006-07-21 19:28:38 +00:00
|
|
|
IN PSPROCESSPRIORITYMODE Type)
|
2005-08-02 13:52:10 +00:00
|
|
|
{
|
2006-07-21 19:28:38 +00:00
|
|
|
UCHAR Quantum;
|
|
|
|
ULONG Priority;
|
2006-07-23 19:45:16 +00:00
|
|
|
PSTRACE(PS_PROCESS_DEBUG, "Process: %p Type: %lx\n", Process, Type);
|
2006-07-21 19:28:38 +00:00
|
|
|
|
|
|
|
/* Compute quantum and priority */
|
|
|
|
Priority = PspComputeQuantumAndPriority(Process, Type, &Quantum);
|
|
|
|
|
|
|
|
/* Set them */
|
|
|
|
KeSetPriorityAndQuantumProcess(&Process->Pcb, Priority, Quantum);
|
2005-08-02 13:52:10 +00:00
|
|
|
}
|
|
|
|
|
2004-07-19 06:08:21 +00:00
|
|
|
/*
|
2004-08-08 20:33:17 +00:00
|
|
|
* @implemented
|
2004-07-19 06:08:21 +00:00
|
|
|
*/
|
2005-05-09 01:38:29 +00:00
|
|
|
NTSTATUS
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
|
|
|
NtCreateProcessEx(OUT PHANDLE ProcessHandle,
|
|
|
|
IN ACCESS_MASK DesiredAccess,
|
2006-07-23 19:45:16 +00:00
|
|
|
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
2006-07-09 18:54:13 +00:00
|
|
|
IN HANDLE ParentProcess,
|
|
|
|
IN ULONG Flags,
|
|
|
|
IN HANDLE SectionHandle OPTIONAL,
|
|
|
|
IN HANDLE DebugPort OPTIONAL,
|
|
|
|
IN HANDLE ExceptionPort OPTIONAL,
|
|
|
|
IN BOOLEAN InJob)
|
2005-04-18 02:12:30 +00:00
|
|
|
{
|
2009-08-26 17:31:02 +00:00
|
|
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
|
|
|
NTSTATUS Status;
|
2005-04-18 02:12:30 +00:00
|
|
|
PAGED_CODE();
|
2006-07-23 19:45:16 +00:00
|
|
|
PSTRACE(PS_PROCESS_DEBUG,
|
|
|
|
"ParentProcess: %p Flags: %lx\n", ParentProcess, Flags);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Check if we came from user mode */
|
2009-08-26 17:31:02 +00:00
|
|
|
if (PreviousMode != KernelMode)
|
2005-04-18 02:12:30 +00:00
|
|
|
{
|
2008-11-24 13:40:26 +00:00
|
|
|
_SEH2_TRY
|
2005-04-18 02:12:30 +00:00
|
|
|
{
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Probe process handle */
|
2005-08-21 15:38:47 +00:00
|
|
|
ProbeForWriteHandle(ProcessHandle);
|
2005-04-18 02:12:30 +00:00
|
|
|
}
|
2008-11-24 13:40:26 +00:00
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
2005-04-18 02:12:30 +00:00
|
|
|
{
|
2009-08-26 17:31:02 +00:00
|
|
|
/* Return the exception code */
|
|
|
|
_SEH2_YIELD(return _SEH2_GetExceptionCode());
|
2004-08-08 20:33:17 +00:00
|
|
|
}
|
2008-11-24 13:40:26 +00:00
|
|
|
_SEH2_END;
|
2004-08-08 20:33:17 +00:00
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
/* Make sure there's a parent process */
|
2006-07-20 14:53:47 +00:00
|
|
|
if (!ParentProcess)
|
2005-04-18 02:12:30 +00:00
|
|
|
{
|
|
|
|
/* Can't create System Processes like this */
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
2004-08-08 20:33:17 +00:00
|
|
|
}
|
2005-04-18 02:12:30 +00:00
|
|
|
else
|
|
|
|
{
|
2005-10-29 23:40:05 +00:00
|
|
|
/* Create a user Process */
|
|
|
|
Status = PspCreateProcess(ProcessHandle,
|
2005-04-18 02:12:30 +00:00
|
|
|
DesiredAccess,
|
|
|
|
ObjectAttributes,
|
|
|
|
ParentProcess,
|
2006-07-09 18:54:13 +00:00
|
|
|
Flags,
|
2005-04-18 02:12:30 +00:00
|
|
|
SectionHandle,
|
|
|
|
DebugPort,
|
2006-07-09 18:54:13 +00:00
|
|
|
ExceptionPort,
|
|
|
|
InJob);
|
2005-04-18 02:12:30 +00:00
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
/* Return Status */
|
|
|
|
return Status;
|
2004-07-19 06:08:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2005-04-18 02:12:30 +00:00
|
|
|
* @implemented
|
|
|
|
*/
|
2005-05-09 01:38:29 +00:00
|
|
|
NTSTATUS
|
2006-07-09 18:54:13 +00:00
|
|
|
NTAPI
|
|
|
|
NtCreateProcess(OUT PHANDLE ProcessHandle,
|
|
|
|
IN ACCESS_MASK DesiredAccess,
|
2006-07-20 14:53:47 +00:00
|
|
|
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
2006-07-09 18:54:13 +00:00
|
|
|
IN HANDLE ParentProcess,
|
|
|
|
IN BOOLEAN InheritObjectTable,
|
2006-07-20 14:53:47 +00:00
|
|
|
IN HANDLE SectionHandle OPTIONAL,
|
|
|
|
IN HANDLE DebugPort OPTIONAL,
|
|
|
|
IN HANDLE ExceptionPort OPTIONAL)
|
2006-07-09 18:54:13 +00:00
|
|
|
{
|
|
|
|
ULONG Flags = 0;
|
2006-07-23 19:45:16 +00:00
|
|
|
PSTRACE(PS_PROCESS_DEBUG,
|
|
|
|
"Parent: %p Attributes: %p\n", ParentProcess, ObjectAttributes);
|
2006-07-09 18:54:13 +00:00
|
|
|
|
|
|
|
/* Set new-style flags */
|
2017-11-13 14:06:29 +00:00
|
|
|
if ((ULONG_PTR)SectionHandle & 1) Flags |= PROCESS_CREATE_FLAGS_BREAKAWAY;
|
|
|
|
if ((ULONG_PTR)DebugPort & 1) Flags |= PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT;
|
2013-08-04 19:28:37 +00:00
|
|
|
if (InheritObjectTable) Flags |= PROCESS_CREATE_FLAGS_INHERIT_HANDLES;
|
2006-07-09 18:54:13 +00:00
|
|
|
|
|
|
|
/* Call the new API */
|
|
|
|
return NtCreateProcessEx(ProcessHandle,
|
|
|
|
DesiredAccess,
|
|
|
|
ObjectAttributes,
|
|
|
|
ParentProcess,
|
|
|
|
Flags,
|
|
|
|
SectionHandle,
|
|
|
|
DebugPort,
|
|
|
|
ExceptionPort,
|
|
|
|
FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2005-04-18 02:12:30 +00:00
|
|
|
NtOpenProcess(OUT PHANDLE ProcessHandle,
|
2006-07-09 18:54:13 +00:00
|
|
|
IN ACCESS_MASK DesiredAccess,
|
|
|
|
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
|
|
|
IN PCLIENT_ID ClientId)
|
2004-11-20 16:46:06 +00:00
|
|
|
{
|
2006-07-20 14:53:47 +00:00
|
|
|
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
|
2005-10-29 23:40:05 +00:00
|
|
|
CLIENT_ID SafeClientId;
|
|
|
|
ULONG Attributes = 0;
|
|
|
|
HANDLE hProcess;
|
|
|
|
BOOLEAN HasObjectName = FALSE;
|
2005-04-18 02:12:30 +00:00
|
|
|
PETHREAD Thread = NULL;
|
2005-10-29 23:40:05 +00:00
|
|
|
PEPROCESS Process = NULL;
|
2009-08-26 17:31:02 +00:00
|
|
|
NTSTATUS Status;
|
2006-07-20 14:53:47 +00:00
|
|
|
ACCESS_STATE AccessState;
|
2008-06-16 08:54:21 +00:00
|
|
|
AUX_ACCESS_DATA AuxData;
|
2005-04-18 02:12:30 +00:00
|
|
|
PAGED_CODE();
|
2006-07-23 19:45:16 +00:00
|
|
|
PSTRACE(PS_PROCESS_DEBUG,
|
|
|
|
"ClientId: %p Attributes: %p\n", ClientId, ObjectAttributes);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Check if we were called from user mode */
|
|
|
|
if (PreviousMode != KernelMode)
|
2005-10-29 23:40:05 +00:00
|
|
|
{
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Enter SEH for probing */
|
2008-11-24 13:40:26 +00:00
|
|
|
_SEH2_TRY
|
2005-10-29 23:40:05 +00:00
|
|
|
{
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Probe the thread handle */
|
2005-10-29 23:40:05 +00:00
|
|
|
ProbeForWriteHandle(ProcessHandle);
|
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Check for a CID structure */
|
|
|
|
if (ClientId)
|
2005-10-29 23:40:05 +00:00
|
|
|
{
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Probe and capture it */
|
|
|
|
ProbeForRead(ClientId, sizeof(CLIENT_ID), sizeof(ULONG));
|
2005-10-29 23:40:05 +00:00
|
|
|
SafeClientId = *ClientId;
|
|
|
|
ClientId = &SafeClientId;
|
|
|
|
}
|
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
/*
|
|
|
|
* Just probe the object attributes structure, don't capture it
|
|
|
|
* completely. This is done later if necessary
|
|
|
|
*/
|
2005-10-29 23:40:05 +00:00
|
|
|
ProbeForRead(ObjectAttributes,
|
|
|
|
sizeof(OBJECT_ATTRIBUTES),
|
|
|
|
sizeof(ULONG));
|
|
|
|
HasObjectName = (ObjectAttributes->ObjectName != NULL);
|
2015-09-24 02:40:30 +00:00
|
|
|
|
|
|
|
/* Validate user attributes */
|
|
|
|
Attributes = ObpValidateAttributes(ObjectAttributes->Attributes, PreviousMode);
|
2005-10-29 23:40:05 +00:00
|
|
|
}
|
2008-11-24 13:40:26 +00:00
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
2005-10-29 23:40:05 +00:00
|
|
|
{
|
2009-08-26 17:31:02 +00:00
|
|
|
/* Return the exception code */
|
|
|
|
_SEH2_YIELD(return _SEH2_GetExceptionCode());
|
2005-10-29 23:40:05 +00:00
|
|
|
}
|
2008-11-24 13:40:26 +00:00
|
|
|
_SEH2_END;
|
2005-10-29 23:40:05 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Otherwise just get the data directly */
|
2005-10-29 23:40:05 +00:00
|
|
|
HasObjectName = (ObjectAttributes->ObjectName != NULL);
|
2015-09-24 02:40:30 +00:00
|
|
|
|
|
|
|
/* Still have to sanitize attributes */
|
|
|
|
Attributes = ObpValidateAttributes(ObjectAttributes->Attributes, PreviousMode);
|
2005-10-29 23:40:05 +00:00
|
|
|
}
|
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Can't pass both, fail */
|
|
|
|
if ((HasObjectName) && (ClientId)) return STATUS_INVALID_PARAMETER_MIX;
|
|
|
|
|
|
|
|
/* Create an access state */
|
|
|
|
Status = SeCreateAccessState(&AccessState,
|
|
|
|
&AuxData,
|
|
|
|
DesiredAccess,
|
|
|
|
&PsProcessType->TypeInfo.GenericMapping);
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
|
|
|
/* Check if this is a debugger */
|
|
|
|
if (SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode))
|
2005-10-29 23:40:05 +00:00
|
|
|
{
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Did he want full access? */
|
|
|
|
if (AccessState.RemainingDesiredAccess & MAXIMUM_ALLOWED)
|
|
|
|
{
|
|
|
|
/* Give it to him */
|
|
|
|
AccessState.PreviouslyGrantedAccess |= PROCESS_ALL_ACCESS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Otherwise just give every other access he could want */
|
|
|
|
AccessState.PreviouslyGrantedAccess |=
|
|
|
|
AccessState.RemainingDesiredAccess;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The caller desires nothing else now */
|
|
|
|
AccessState.RemainingDesiredAccess = 0;
|
2005-10-29 23:40:05 +00:00
|
|
|
}
|
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
/* Open by name if one was given */
|
2005-10-29 23:40:05 +00:00
|
|
|
if (HasObjectName)
|
2004-11-20 16:46:06 +00:00
|
|
|
{
|
2005-05-09 01:38:29 +00:00
|
|
|
/* Open it */
|
2005-04-18 02:12:30 +00:00
|
|
|
Status = ObOpenObjectByName(ObjectAttributes,
|
|
|
|
PsProcessType,
|
|
|
|
PreviousMode,
|
2006-07-20 14:53:47 +00:00
|
|
|
&AccessState,
|
|
|
|
0,
|
2005-04-18 02:12:30 +00:00
|
|
|
NULL,
|
2005-10-29 23:40:05 +00:00
|
|
|
&hProcess);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Get rid of the access state */
|
|
|
|
SeDeleteAccessState(&AccessState);
|
2004-11-20 16:46:06 +00:00
|
|
|
}
|
2006-07-20 14:53:47 +00:00
|
|
|
else if (ClientId)
|
2004-11-20 16:46:06 +00:00
|
|
|
{
|
2005-04-18 02:12:30 +00:00
|
|
|
/* Open by Thread ID */
|
2005-10-29 23:40:05 +00:00
|
|
|
if (ClientId->UniqueThread)
|
2004-11-20 16:46:06 +00:00
|
|
|
{
|
2005-04-18 02:12:30 +00:00
|
|
|
/* Get the Process */
|
2006-07-20 14:53:47 +00:00
|
|
|
Status = PsLookupProcessThreadByCid(ClientId, &Process, &Thread);
|
2005-05-09 01:38:29 +00:00
|
|
|
}
|
|
|
|
else
|
2005-04-18 02:12:30 +00:00
|
|
|
{
|
|
|
|
/* Get the Process */
|
2005-10-29 23:40:05 +00:00
|
|
|
Status = PsLookupProcessByProcessId(ClientId->UniqueProcess,
|
2005-04-18 02:12:30 +00:00
|
|
|
&Process);
|
2004-11-20 16:46:06 +00:00
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Check if we didn't find anything */
|
|
|
|
if (!NT_SUCCESS(Status))
|
2005-04-18 02:12:30 +00:00
|
|
|
{
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Get rid of the access state and return */
|
|
|
|
SeDeleteAccessState(&AccessState);
|
2005-04-18 02:12:30 +00:00
|
|
|
return Status;
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
/* Open the Process Object */
|
|
|
|
Status = ObOpenObjectByPointer(Process,
|
2005-10-29 23:40:05 +00:00
|
|
|
Attributes,
|
2006-07-20 14:53:47 +00:00
|
|
|
&AccessState,
|
|
|
|
0,
|
2005-04-18 02:12:30 +00:00
|
|
|
PsProcessType,
|
|
|
|
PreviousMode,
|
2005-10-29 23:40:05 +00:00
|
|
|
&hProcess);
|
2006-07-20 14:53:47 +00:00
|
|
|
|
|
|
|
/* Delete the access state */
|
|
|
|
SeDeleteAccessState(&AccessState);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
/* Dereference the thread if we used it */
|
|
|
|
if (Thread) ObDereferenceObject(Thread);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
/* Dereference the Process */
|
|
|
|
ObDereferenceObject(Process);
|
2004-11-20 16:46:06 +00:00
|
|
|
}
|
2005-10-29 23:40:05 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* neither an object name nor a client id was passed */
|
|
|
|
return STATUS_INVALID_PARAMETER_MIX;
|
|
|
|
}
|
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Check for success */
|
|
|
|
if (NT_SUCCESS(Status))
|
2005-10-29 23:40:05 +00:00
|
|
|
{
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Use SEH for write back */
|
2008-11-24 13:40:26 +00:00
|
|
|
_SEH2_TRY
|
2005-10-29 23:40:05 +00:00
|
|
|
{
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Write back the handle */
|
2005-10-29 23:40:05 +00:00
|
|
|
*ProcessHandle = hProcess;
|
|
|
|
}
|
2008-11-24 13:40:26 +00:00
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
2005-10-29 23:40:05 +00:00
|
|
|
{
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Get the exception code */
|
2008-11-24 13:40:26 +00:00
|
|
|
Status = _SEH2_GetExceptionCode();
|
2005-10-29 23:40:05 +00:00
|
|
|
}
|
2008-11-24 13:40:26 +00:00
|
|
|
_SEH2_END;
|
2005-10-29 23:40:05 +00:00
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
/* Return status */
|
2005-04-18 02:12:30 +00:00
|
|
|
return Status;
|
2004-11-20 16:46:06 +00:00
|
|
|
}
|
2019-01-01 20:58:18 +00:00
|
|
|
|
2000-05-14 09:31:05 +00:00
|
|
|
/* EOF */
|