-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ps/process.c
* PURPOSE: Process managment
*
- * PROGRAMMERS: David Welch (welch@cwcom.net)
+ * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
+ * David Welch (welch@cwcom.net)
*/
/* INCLUDES ******************************************************************/
/* GLOBALS ******************************************************************/
-VOID INIT_FUNCTION PsInitClientIDManagment(VOID);
-
PEPROCESS EXPORTED PsInitialSystemProcess = NULL;
PEPROCESS PsIdleProcess = NULL;
-
POBJECT_TYPE EXPORTED PsProcessType = NULL;
+extern PHANDLE_TABLE PspCidTable;
+
+EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock;
LIST_ENTRY PsActiveProcessHead;
FAST_MUTEX PspActiveProcessMutex;
-static LARGE_INTEGER ShortPsLockDelay, PsLockTimeout;
+LARGE_INTEGER ShortPsLockDelay, PsLockTimeout;
-static GENERIC_MAPPING PiProcessMapping = {STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
- STANDARD_RIGHTS_WRITE | PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD |
- PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_DUP_HANDLE |
- PROCESS_TERMINATE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION | PROCESS_SET_PORT,
- STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
- PROCESS_ALL_ACCESS};
+/* INTERNAL FUNCTIONS *****************************************************************/
-#define MAX_PROCESS_NOTIFY_ROUTINE_COUNT 8
-#define MAX_LOAD_IMAGE_NOTIFY_ROUTINE_COUNT 8
-
-static PCREATE_PROCESS_NOTIFY_ROUTINE
-PiProcessNotifyRoutine[MAX_PROCESS_NOTIFY_ROUTINE_COUNT];
-static PLOAD_IMAGE_NOTIFY_ROUTINE
-PiLoadImageNotifyRoutine[MAX_LOAD_IMAGE_NOTIFY_ROUTINE_COUNT];
-
-
-/* FUNCTIONS *****************************************************************/
-
-PEPROCESS
-PsGetNextProcess(PEPROCESS OldProcess)
+NTSTATUS
+NTAPI
+PsLockProcess(PEPROCESS Process, BOOLEAN Timeout)
{
- PEPROCESS NextProcess;
- NTSTATUS Status;
-
- if (OldProcess == NULL)
- {
- Status = ObReferenceObjectByPointer(PsIdleProcess,
- PROCESS_ALL_ACCESS,
- PsProcessType,
- KernelMode);
- if (!NT_SUCCESS(Status))
- {
- CPRINT("PsGetNextProcess(): ObReferenceObjectByPointer failed for PsIdleProcess\n");
- KEBUGCHECK(0);
- }
- return PsIdleProcess;
- }
-
- ExAcquireFastMutex(&PspActiveProcessMutex);
- NextProcess = OldProcess;
- while (1)
- {
- PLIST_ENTRY Flink = (NextProcess == PsIdleProcess ? PsActiveProcessHead.Flink :
- NextProcess->ProcessListEntry.Flink);
- if (Flink != &PsActiveProcessHead)
- {
- NextProcess = CONTAINING_RECORD(Flink,
- EPROCESS,
- ProcessListEntry);
- }
- else
- {
- NextProcess = NULL;
- break;
- }
-
- Status = ObReferenceObjectByPointer(NextProcess,
- PROCESS_ALL_ACCESS,
- PsProcessType,
- KernelMode);
- if (NT_SUCCESS(Status))
- {
- break;
- }
- else if (Status == STATUS_PROCESS_IS_TERMINATING)
- {
- continue;
- }
- else if (!NT_SUCCESS(Status))
- {
- continue;
- }
- }
+ ULONG Attempts = 0;
+ PKTHREAD PrevLockOwner;
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
+ PLARGE_INTEGER Delay = (Timeout ? &PsLockTimeout : NULL);
+ PKTHREAD CallingThread = KeGetCurrentThread();
- ExReleaseFastMutex(&PspActiveProcessMutex);
- ObDereferenceObject(OldProcess);
-
- return(NextProcess);
-}
+ PAGED_CODE();
-VOID
-PiKillMostProcesses(VOID)
-{
- PLIST_ENTRY current_entry;
- PEPROCESS current;
-
- ExAcquireFastMutex(&PspActiveProcessMutex);
-
- current_entry = PsActiveProcessHead.Flink;
- while (current_entry != &PsActiveProcessHead)
- {
- current = CONTAINING_RECORD(current_entry, EPROCESS,
- ProcessListEntry);
- current_entry = current_entry->Flink;
-
- if (current->UniqueProcessId != PsInitialSystemProcess->UniqueProcessId &&
- current->UniqueProcessId != PsGetCurrentProcessId())
- {
- PspTerminateProcessThreads(current, STATUS_SUCCESS);
- }
- }
-
- ExReleaseFastMutex(&PspActiveProcessMutex);
-}
+ KeEnterCriticalRegion();
-VOID INIT_FUNCTION
-PsInitProcessManagment(VOID)
-{
- PKPROCESS KProcess;
- NTSTATUS Status;
-
- ShortPsLockDelay.QuadPart = -100LL;
- PsLockTimeout.QuadPart = -10000000LL; /* one second */
- /*
- * Register the process object type
- */
-
- PsProcessType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
-
- PsProcessType->Tag = TAG('P', 'R', 'O', 'C');
- PsProcessType->TotalObjects = 0;
- PsProcessType->TotalHandles = 0;
- PsProcessType->PeakObjects = 0;
- PsProcessType->PeakHandles = 0;
- PsProcessType->PagedPoolCharge = 0;
- PsProcessType->NonpagedPoolCharge = sizeof(EPROCESS);
- PsProcessType->Mapping = &PiProcessMapping;
- PsProcessType->Dump = NULL;
- PsProcessType->Open = NULL;
- PsProcessType->Close = NULL;
- PsProcessType->Delete = PspDeleteProcess;
- PsProcessType->Parse = NULL;
- PsProcessType->Security = NULL;
- PsProcessType->QueryName = NULL;
- PsProcessType->OkayToClose = NULL;
- PsProcessType->Create = NULL;
- PsProcessType->DuplicationNotify = NULL;
-
- RtlInitUnicodeString(&PsProcessType->TypeName, L"Process");
-
- ObpCreateTypeObject(PsProcessType);
-
- InitializeListHead(&PsActiveProcessHead);
- ExInitializeFastMutex(&PspActiveProcessMutex);
-
- RtlZeroMemory(PiProcessNotifyRoutine, sizeof(PiProcessNotifyRoutine));
- RtlZeroMemory(PiLoadImageNotifyRoutine, sizeof(PiLoadImageNotifyRoutine));
-
- /*
- * Initialize the idle process
- */
- Status = ObCreateObject(KernelMode,
- PsProcessType,
- NULL,
- KernelMode,
- NULL,
- sizeof(EPROCESS),
- 0,
- 0,
- (PVOID*)&PsIdleProcess);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to create the idle process object, Status: 0x%x\n", Status);
- KEBUGCHECK(0);
- return;
- }
+ for(;;)
+ {
+ PrevLockOwner = (PKTHREAD)InterlockedCompareExchangePointer(
+ &Process->LockOwner, CallingThread, NULL);
+ if(PrevLockOwner == NULL || PrevLockOwner == CallingThread)
+ {
+ /* we got the lock or already locked it */
+ if(InterlockedIncrementUL(&Process->LockCount) == 1)
+ {
+ KeClearEvent(&Process->LockEvent);
+ }
- RtlZeroMemory(PsIdleProcess, sizeof(EPROCESS));
-
- PsIdleProcess->Pcb.Affinity = 0xFFFFFFFF;
- PsIdleProcess->Pcb.IopmOffset = 0xffff;
- PsIdleProcess->Pcb.LdtDescriptor[0] = 0;
- PsIdleProcess->Pcb.LdtDescriptor[1] = 0;
- PsIdleProcess->Pcb.BasePriority = PROCESS_PRIO_IDLE;
- PsIdleProcess->Pcb.ThreadQuantum = 6;
- InitializeListHead(&PsIdleProcess->Pcb.ThreadListHead);
- InitializeListHead(&PsIdleProcess->ThreadListHead);
- InitializeListHead(&PsIdleProcess->ProcessListEntry);
- KeInitializeDispatcherHeader(&PsIdleProcess->Pcb.DispatcherHeader,
- ProcessObject,
- sizeof(EPROCESS),
- FALSE);
- PsIdleProcess->Pcb.DirectoryTableBase =
- (LARGE_INTEGER)(LONGLONG)(ULONG)MmGetPageDirectory();
- strcpy(PsIdleProcess->ImageFileName, "Idle");
-
- /*
- * Initialize the system process
- */
- Status = ObCreateObject(KernelMode,
- PsProcessType,
- NULL,
- KernelMode,
- NULL,
- sizeof(EPROCESS),
- 0,
- 0,
- (PVOID*)&PsInitialSystemProcess);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to create the system process object, Status: 0x%x\n", Status);
- KEBUGCHECK(0);
- return;
- }
-
- /* System threads may run on any processor. */
- PsInitialSystemProcess->Pcb.Affinity = 0xFFFFFFFF;
- PsInitialSystemProcess->Pcb.IopmOffset = 0xffff;
- PsInitialSystemProcess->Pcb.LdtDescriptor[0] = 0;
- PsInitialSystemProcess->Pcb.LdtDescriptor[1] = 0;
- PsInitialSystemProcess->Pcb.BasePriority = PROCESS_PRIO_NORMAL;
- PsInitialSystemProcess->Pcb.ThreadQuantum = 6;
- InitializeListHead(&PsInitialSystemProcess->Pcb.ThreadListHead);
- KeInitializeDispatcherHeader(&PsInitialSystemProcess->Pcb.DispatcherHeader,
- ProcessObject,
- sizeof(EPROCESS),
- FALSE);
- KProcess = &PsInitialSystemProcess->Pcb;
-
- MmInitializeAddressSpace(PsInitialSystemProcess,
- &PsInitialSystemProcess->AddressSpace);
-
- KeInitializeEvent(&PsInitialSystemProcess->LockEvent, SynchronizationEvent, FALSE);
- PsInitialSystemProcess->LockCount = 0;
- PsInitialSystemProcess->LockOwner = NULL;
-
-#if defined(__GNUC__)
- KProcess->DirectoryTableBase =
- (LARGE_INTEGER)(LONGLONG)(ULONG)MmGetPageDirectory();
-#else
- {
- LARGE_INTEGER dummy;
- dummy.QuadPart = (LONGLONG)(ULONG)MmGetPageDirectory();
- KProcess->DirectoryTableBase = dummy;
- }
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ if(++Attempts > 2)
+ {
+ Status = KeWaitForSingleObject(&Process->LockEvent,
+ Executive,
+ KernelMode,
+ FALSE,
+ Delay);
+ if(!NT_SUCCESS(Status) || Status == STATUS_TIMEOUT)
+ {
+#ifndef NDEBUG
+ if(Status == STATUS_TIMEOUT)
+ {
+ DPRINT1("PsLockProcess(0x%x) timed out!\n", Process);
+ }
#endif
+ KeLeaveCriticalRegion();
+ break;
+ }
+ }
+ else
+ {
+ KeDelayExecutionThread(KernelMode, FALSE, &ShortPsLockDelay);
+ }
+ }
+ }
- strcpy(PsInitialSystemProcess->ImageFileName, "System");
-
- PsInitialSystemProcess->Win32WindowStation = (HANDLE)0;
-
- InsertHeadList(&PsActiveProcessHead,
- &PsInitialSystemProcess->ProcessListEntry);
- InitializeListHead(&PsInitialSystemProcess->ThreadListHead);
-
- SepCreateSystemProcessToken(PsInitialSystemProcess);
+ return Status;
}
VOID
-PspPostInitSystemProcess(VOID)
+NTAPI
+PsUnlockProcess(PEPROCESS Process)
{
- NTSTATUS Status;
-
- /* this routine is called directly after the exectuive handle tables were
- initialized. We'll set up the Client ID handle table and assign the system
- process a PID */
- PsInitClientIDManagment();
-
- ObCreateHandleTable(NULL, FALSE, PsInitialSystemProcess);
-
- Status = PsCreateCidHandle(PsInitialSystemProcess,
- PsProcessType,
- &PsInitialSystemProcess->UniqueProcessId);
- if(!NT_SUCCESS(Status))
+ PAGED_CODE();
+
+ ASSERT(Process->LockOwner == KeGetCurrentThread());
+
+ if(InterlockedDecrementUL(&Process->LockCount) == 0)
{
- DPRINT1("Failed to create CID handle (unique process id) for the system process!\n");
- KEBUGCHECK(0);
+ InterlockedExchangePointer(&Process->LockOwner, NULL);
+ KeSetEvent(&Process->LockEvent, IO_NO_INCREMENT, FALSE);
}
+
+ KeLeaveCriticalRegion();
}
-static NTSTATUS
-PsCreatePeb(HANDLE ProcessHandle,
- PEPROCESS Process,
- PVOID ImageBase)
+PEPROCESS
+STDCALL
+PsGetNextProcess(PEPROCESS OldProcess)
{
- ULONG AllocSize;
- ULONG PebSize;
- PPEB Peb;
- LARGE_INTEGER SectionOffset;
- ULONG ViewSize;
- PVOID TableBase;
- NTSTATUS Status;
-
- PAGED_CODE();
+ PEPROCESS NextProcess;
+ NTSTATUS Status;
- /* Allocate the Process Environment Block (PEB) */
- Process->TebBlock = (PVOID) MM_ROUND_DOWN(PEB_BASE, MM_VIRTMEM_GRANULARITY);
- AllocSize = MM_VIRTMEM_GRANULARITY;
- Status = NtAllocateVirtualMemory(ProcessHandle,
- &Process->TebBlock,
- 0,
- &AllocSize,
- MEM_RESERVE,
- PAGE_READWRITE);
- if (!NT_SUCCESS(Status))
+ /* Check if we have a previous process */
+ if (OldProcess == NULL)
{
- DPRINT1("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
- return(Status);
- }
- ASSERT((ULONG_PTR) Process->TebBlock <= PEB_BASE &&
- PEB_BASE + PAGE_SIZE <= (ULONG_PTR) Process->TebBlock + AllocSize);
- Peb = (PPEB)PEB_BASE;
- PebSize = PAGE_SIZE;
- Status = NtAllocateVirtualMemory(ProcessHandle,
- (PVOID*)&Peb,
- 0,
- &PebSize,
- MEM_COMMIT,
- PAGE_READWRITE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
- return(Status);
- }
- DPRINT("Peb %p PebSize %lu\n", Peb, PebSize);
- ASSERT((PPEB) PEB_BASE == Peb && PAGE_SIZE <= PebSize);
- Process->TebLastAllocated = (PVOID) Peb;
-
- ViewSize = 0;
- SectionOffset.QuadPart = (ULONGLONG)0;
- TableBase = NULL;
- Status = MmMapViewOfSection(NlsSectionObject,
- Process,
- &TableBase,
- 0,
- 0,
- &SectionOffset,
- &ViewSize,
- ViewShare,
- MEM_TOP_DOWN,
- PAGE_READONLY);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("MmMapViewOfSection() failed (Status %lx)\n", Status);
- return(Status);
- }
- DPRINT("TableBase %p ViewSize %lx\n", TableBase, ViewSize);
-
- KeAttachProcess(&Process->Pcb);
+ /* We don't, start with the Idle Process */
+ Status = ObReferenceObjectByPointer(PsIdleProcess,
+ PROCESS_ALL_ACCESS,
+ PsProcessType,
+ KernelMode);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("PsGetNextProcess(): ObReferenceObjectByPointer failed for PsIdleProcess\n");
+ KEBUGCHECK(0);
+ }
- /* Initialize the PEB */
- RtlZeroMemory(Peb, sizeof(PEB));
- Peb->ImageBaseAddress = ImageBase;
+ return PsIdleProcess;
+ }
- Peb->OSMajorVersion = 4;
- Peb->OSMinorVersion = 0;
- Peb->OSBuildNumber = 1381;
- Peb->OSPlatformId = 2; //VER_PLATFORM_WIN32_NT;
- Peb->OSCSDVersion = 6 << 8;
+ /* Acquire the Active Process Lock */
+ ExAcquireFastMutex(&PspActiveProcessMutex);
- Peb->AnsiCodePageData = (char*)TableBase + NlsAnsiTableOffset;
- Peb->OemCodePageData = (char*)TableBase + NlsOemTableOffset;
- Peb->UnicodeCaseTableData = (char*)TableBase + NlsUnicodeTableOffset;
+ /* Start at the previous process */
+ NextProcess = OldProcess;
- Process->Peb = Peb;
- KeDetachProcess();
+ /* Loop until we fail */
+ while (1)
+ {
+ /* Get the Process Link */
+ PLIST_ENTRY Flink = (NextProcess == PsIdleProcess ? PsActiveProcessHead.Flink :
+ NextProcess->ActiveProcessLinks.Flink);
- DPRINT("PsCreatePeb: Peb created at %p\n", Peb);
+ /* Move to the next Process if we're not back at the beginning */
+ if (Flink != &PsActiveProcessHead)
+ {
+ NextProcess = CONTAINING_RECORD(Flink, EPROCESS, ActiveProcessLinks);
+ }
+ else
+ {
+ NextProcess = NULL;
+ break;
+ }
- return(STATUS_SUCCESS);
-}
+ /* Reference the Process */
+ Status = ObReferenceObjectByPointer(NextProcess,
+ PROCESS_ALL_ACCESS,
+ PsProcessType,
+ KernelMode);
+ /* Exit the loop if the reference worked, keep going if there's an error */
+ if (NT_SUCCESS(Status)) break;
+ }
-PKPROCESS
-KeGetCurrentProcess(VOID)
-/*
- * FUNCTION: Returns a pointer to the current process
- */
-{
- return(&(PsGetCurrentProcess()->Pcb));
-}
+ /* Release the lock */
+ ExReleaseFastMutex(&PspActiveProcessMutex);
-/*
- * Warning: Even though it returns HANDLE, it's not a real HANDLE but really a
- * ULONG ProcessId! (Skywing)
- */
-/*
- * @implemented
- */
-HANDLE STDCALL
-PsGetCurrentProcessId(VOID)
-{
- return((HANDLE)PsGetCurrentProcess()->UniqueProcessId);
+ /* Reference the Process we had referenced earlier */
+ ObDereferenceObject(OldProcess);
+ return(NextProcess);
}
-/*
- * @unimplemented
- */
-ULONG
+NTSTATUS
STDCALL
-PsGetCurrentProcessSessionId (
- VOID
- )
+PspCreateProcess(OUT PHANDLE ProcessHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
+ IN HANDLE ParentProcess OPTIONAL,
+ IN BOOLEAN InheritObjectTable,
+ IN HANDLE SectionHandle OPTIONAL,
+ IN HANDLE DebugPort OPTIONAL,
+ IN HANDLE ExceptionPort OPTIONAL)
{
- return PsGetCurrentProcess()->SessionId;
-}
+ HANDLE hProcess;
+ PEPROCESS Process = NULL;
+ PEPROCESS pParentProcess = NULL;
+ PEPORT pDebugPort = NULL;
+ PEPORT pExceptionPort = NULL;
+ PSECTION_OBJECT SectionObject = NULL;
+ NTSTATUS Status = STATUS_SUCCESS;
+ KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+ PHYSICAL_ADDRESS DirectoryTableBase;
+ KAFFINITY Affinity;
+ HANDLE_TABLE_ENTRY CidEntry;
+ DirectoryTableBase.QuadPart = (ULONGLONG)0;
+ BOOLEAN ProcessCreated = FALSE;
+
+ DPRINT("PspCreateProcess(ObjectAttributes %x)\n", ObjectAttributes);
+
+ /* Reference the Parent if there is one */
+ if(ParentProcess != NULL)
+ {
+ Status = ObReferenceObjectByHandle(ParentProcess,
+ PROCESS_CREATE_PROCESS,
+ PsProcessType,
+ PreviousMode,
+ (PVOID*)&pParentProcess,
+ NULL);
-/*
- * FUNCTION: Returns a pointer to the current process
- *
- * @implemented
- */
-PEPROCESS STDCALL
-IoGetCurrentProcess(VOID)
-{
- if (PsGetCurrentThread() == NULL ||
- PsGetCurrentThread()->Tcb.ApcState.Process == NULL)
- {
- return(PsInitialSystemProcess);
- }
- else
- {
- return(PEPROCESS)(PsGetCurrentThread()->Tcb.ApcState.Process);
- }
-}
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to reference the parent process: Status: 0x%x\n", Status);
+ goto Cleanup;
+ }
-NTSTATUS
-PspCreateProcess(OUT PHANDLE ProcessHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
- IN HANDLE ParentProcess OPTIONAL,
- IN BOOLEAN InheritObjectTable,
- IN HANDLE SectionHandle OPTIONAL,
- IN HANDLE DebugPort OPTIONAL,
- IN HANDLE ExceptionPort OPTIONAL)
-{
- HANDLE hProcess;
- PEPROCESS Process;
- PEPROCESS pParentProcess;
- PKPROCESS KProcess;
- PVOID LdrStartupAddr;
- PVOID BaseAddress;
- PMEMORY_AREA MemoryArea;
- PHYSICAL_ADDRESS BoundaryAddressMultiple;
- KPROCESSOR_MODE PreviousMode;
- PVOID ImageBase = NULL;
- PEPORT pDebugPort = NULL;
- PEPORT pExceptionPort = NULL;
- PSECTION_OBJECT SectionObject = NULL;
- NTSTATUS Status = STATUS_SUCCESS;
-
- DPRINT("PspCreateProcess(ObjectAttributes %x)\n", ObjectAttributes);
-
- PreviousMode = ExGetPreviousMode();
-
- BoundaryAddressMultiple.QuadPart = 0;
-
- if(ParentProcess != NULL)
- {
- Status = ObReferenceObjectByHandle(ParentProcess,
- PROCESS_CREATE_PROCESS,
- PsProcessType,
- PreviousMode,
- (PVOID*)&pParentProcess,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to reference the parent process: Status: 0x%x\n", Status);
- return(Status);
- }
- }
- else
- {
- pParentProcess = NULL;
- }
+ /* Inherit Parent process's Affinity. */
+ Affinity = pParentProcess->Pcb.Affinity;
- /*
- * Add the debug port
+ }
+ else
+ {
+ pParentProcess = NULL;
+#ifdef CONFIG_SMP
+ /* FIXME:
+ * Only the boot cpu is initialized in the early boot phase.
*/
- if (DebugPort != NULL)
- {
- Status = ObReferenceObjectByHandle(DebugPort,
- PORT_ALL_ACCESS,
- LpcPortObjectType,
- PreviousMode,
- (PVOID*)&pDebugPort,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to reference the debug port: Status: 0x%x\n", Status);
- goto exitdereferenceobjects;
- }
- }
+ Affinity = 0xffffffff;
+#else
+ Affinity = KeActiveProcessors;
+#endif
+ }
- /*
- * Add the exception port
- */
- if (ExceptionPort != NULL)
- {
- Status = ObReferenceObjectByHandle(ExceptionPort,
- PORT_ALL_ACCESS,
- LpcPortObjectType,
- PreviousMode,
- (PVOID*)&pExceptionPort,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to reference the exception port: Status: 0x%x\n", Status);
- goto exitdereferenceobjects;
- }
- }
+ /* Add the debug port */
+ if (DebugPort != NULL)
+ {
+ Status = ObReferenceObjectByHandle(DebugPort,
+ PORT_ALL_ACCESS,
+ LpcPortObjectType,
+ PreviousMode,
+ (PVOID*)&pDebugPort,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to reference the debug port: Status: 0x%x\n", Status);
+ goto Cleanup;
+ }
+ }
- if (SectionHandle != NULL)
- {
+ /* Add the exception port */
+ if (ExceptionPort != NULL)
+ {
+ Status = ObReferenceObjectByHandle(ExceptionPort,
+ PORT_ALL_ACCESS,
+ LpcPortObjectType,
+ PreviousMode,
+ (PVOID*)&pExceptionPort,
+ NULL);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to reference the exception port: Status: 0x%x\n", Status);
+ goto Cleanup;
+ }
+ }
+
+ /* Add the Section */
+ if (SectionHandle != NULL)
+ {
Status = ObReferenceObjectByHandle(SectionHandle,
- 0,
+ SECTION_MAP_EXECUTE,
MmSectionObjectType,
PreviousMode,
(PVOID*)&SectionObject,
NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to reference process image section: Status: 0x%x\n", Status);
- goto exitdereferenceobjects;
- }
- }
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to reference process image section: Status: 0x%x\n", Status);
+ goto Cleanup;
+ }
+ }
- Status = ObCreateObject(PreviousMode,
- PsProcessType,
- ObjectAttributes,
- PreviousMode,
- NULL,
- sizeof(EPROCESS),
- 0,
- 0,
- (PVOID*)&Process);
- if (!NT_SUCCESS(Status))
- {
+ /* Create the Object */
+ DPRINT("Creating Process Object\n");
+ Status = ObCreateObject(PreviousMode,
+ PsProcessType,
+ ObjectAttributes,
+ PreviousMode,
+ NULL,
+ sizeof(EPROCESS),
+ 0,
+ 0,
+ (PVOID*)&Process);
+
+ if (!NT_SUCCESS(Status))
+ {
DPRINT1("Failed to create process object, Status: 0x%x\n", Status);
-
-exitdereferenceobjects:
- if(SectionObject != NULL)
- ObDereferenceObject(SectionObject);
- if(pExceptionPort != NULL)
- ObDereferenceObject(pExceptionPort);
- if(pDebugPort != NULL)
- ObDereferenceObject(pDebugPort);
- if(pParentProcess != NULL)
- ObDereferenceObject(pParentProcess);
- return Status;
- }
+ goto Cleanup;
+ }
- KProcess = &Process->Pcb;
-
- RtlZeroMemory(Process, sizeof(EPROCESS));
-
- Status = PsCreateCidHandle(Process,
- PsProcessType,
- &Process->UniqueProcessId);
- if(!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to create CID handle (unique process ID)! Status: 0x%x\n", Status);
- ObDereferenceObject(Process);
- goto exitdereferenceobjects;
- }
-
- Process->DebugPort = pDebugPort;
- Process->ExceptionPort = pExceptionPort;
-
- if(SectionObject != NULL)
- {
- UNICODE_STRING FileName;
- PWCHAR szSrc;
- PCHAR szDest;
- USHORT lnFName = 0;
-
- /*
- * Determine the image file name and save it to the EPROCESS structure
- */
-
- FileName = SectionObject->FileObject->FileName;
- szSrc = (PWCHAR)(FileName.Buffer + (FileName.Length / sizeof(WCHAR)) - 1);
- while(szSrc >= FileName.Buffer)
- {
- if(*szSrc == L'\\')
- {
- szSrc++;
- break;
- }
- else
- {
- szSrc--;
- lnFName++;
- }
- }
+ /* Clean up the Object */
+ DPRINT("Cleaning Process Object\n");
+ RtlZeroMemory(Process, sizeof(EPROCESS));
- /* copy the image file name to the process and truncate it to 15 characters
- if necessary */
- szDest = Process->ImageFileName;
- lnFName = min(lnFName, sizeof(Process->ImageFileName) - 1);
- while(lnFName-- > 0)
- {
- *(szDest++) = (UCHAR)*(szSrc++);
- }
- /* *szDest = '\0'; */
- }
-
- KeInitializeDispatcherHeader(&KProcess->DispatcherHeader,
- ProcessObject,
- sizeof(EPROCESS),
- FALSE);
-
- /* Inherit parent process's affinity. */
- if(pParentProcess != NULL)
- {
- KProcess->Affinity = pParentProcess->Pcb.Affinity;
- Process->InheritedFromUniqueProcessId = pParentProcess->UniqueProcessId;
- Process->SessionId = pParentProcess->SessionId;
- }
- else
- {
- KProcess->Affinity = KeActiveProcessors;
- }
-
- KProcess->BasePriority = PROCESS_PRIO_NORMAL;
- KProcess->IopmOffset = 0xffff;
- KProcess->LdtDescriptor[0] = 0;
- KProcess->LdtDescriptor[1] = 0;
- InitializeListHead(&KProcess->ThreadListHead);
- KProcess->ThreadQuantum = 6;
- KProcess->AutoAlignment = 0;
- MmInitializeAddressSpace(Process,
- &Process->AddressSpace);
-
- ObCreateHandleTable(pParentProcess,
- InheritObjectTable,
- Process);
- MmCopyMmInfo(pParentProcess ? pParentProcess : PsInitialSystemProcess, Process);
-
- KeInitializeEvent(&Process->LockEvent, SynchronizationEvent, FALSE);
- Process->LockCount = 0;
- Process->LockOwner = NULL;
-
- Process->Win32WindowStation = (HANDLE)0;
-
- ExAcquireFastMutex(&PspActiveProcessMutex);
- InsertTailList(&PsActiveProcessHead, &Process->ProcessListEntry);
- InitializeListHead(&Process->ThreadListHead);
- ExReleaseFastMutex(&PspActiveProcessMutex);
-
- Process->Pcb.State = PROCESS_STATE_ACTIVE;
-
- /*
- * Now we have created the process proper
- */
+ /* Inherit stuff from the Parent since we now have the object created */
+ if (pParentProcess)
+ {
+ Process->InheritedFromUniqueProcessId = pParentProcess->UniqueProcessId;
+ Process->Session = pParentProcess->Session;
+ }
- MmLockAddressSpace(&Process->AddressSpace);
-
- /* Protect the highest 64KB of the process address space */
- BaseAddress = (PVOID)MmUserProbeAddress;
- Status = MmCreateMemoryArea(Process,
- &Process->AddressSpace,
- MEMORY_AREA_NO_ACCESS,
- &BaseAddress,
- 0x10000,
- PAGE_NOACCESS,
- &MemoryArea,
- FALSE,
- FALSE,
- BoundaryAddressMultiple);
- if (!NT_SUCCESS(Status))
- {
- MmUnlockAddressSpace(&Process->AddressSpace);
- DPRINT1("Failed to protect the highest 64KB of the process address space\n");
- ObDereferenceObject(Process);
- goto exitdereferenceobjects;
- }
+ /* Set up the Quota Block from the Parent */
+ PspInheritQuota(Process, pParentProcess);
+
+ /* FIXME: Set up Dos Device Map from the Parent
+ ObInheritDeviceMap(Parent, Process) */
+
+ /* Set the Process' LPC Ports */
+ Process->DebugPort = pDebugPort;
+ Process->ExceptionPort = pExceptionPort;
+
+ /* Setup the Lock Event */
+ DPRINT("Initialzing Process Lock\n");
+ KeInitializeEvent(&Process->LockEvent, SynchronizationEvent, FALSE);
+
+ /* Setup the Thread List Head */
+ DPRINT("Initialzing Process ThreadListHead\n");
+ InitializeListHead(&Process->ThreadListHead);
+
+ /* Create or Clone the Handle Table */
+ DPRINT("Initialzing Process Handle Table\n");
+ ObCreateHandleTable(pParentProcess, InheritObjectTable, Process);
+ DPRINT("Handle Table: %x\n", Process->ObjectTable);
+
+ /* Set Process's Directory Base */
+ DPRINT("Initialzing Process Directory Base\n");
+ MmCopyMmInfo(pParentProcess ? pParentProcess : PsInitialSystemProcess,
+ Process,
+ &DirectoryTableBase);
+
+ /* Now initialize the Kernel Process */
+ DPRINT("Initialzing Kernel Process\n");
+ KeInitializeProcess(&Process->Pcb,
+ PROCESS_PRIORITY_NORMAL,
+ Affinity,
+ DirectoryTableBase);
+
+ /* Duplicate Parent Token */
+ DPRINT("Initialzing Process Token\n");
+ Status = PspInitializeProcessSecurity(Process, pParentProcess);
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("PspInitializeProcessSecurity failed (Status %x)\n", Status);
+ goto Cleanup;
+ }
- /* Protect the lowest 64KB of the process address space */
-#if 0
- BaseAddress = (PVOID)0x00000000;
- Status = MmCreateMemoryArea(Process,
- &Process->AddressSpace,
- MEMORY_AREA_NO_ACCESS,
- &BaseAddress,
- 0x10000,
- PAGE_NOACCESS,
- &MemoryArea,
- FALSE,
- FALSE,
- BoundaryAddressMultiple);
- if (!NT_SUCCESS(Status))
- {
- MmUnlockAddressSpace(&Process->AddressSpace);
- DPRINT1("Failed to protect the lowest 64KB of the process address space\n");
- ObDereferenceObject(Process);
- goto exitdereferenceobjects;
- }
-#endif
+ /* Create the Process' Address Space */
+ DPRINT("Initialzing Process Address Space\n");
+ Status = MmCreateProcessAddressSpace(Process, SectionObject);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create Address Space\n");
+ goto Cleanup;
+ }
- /* Protect the 60KB above the shared user page */
- BaseAddress = (char*)USER_SHARED_DATA + PAGE_SIZE;
- Status = MmCreateMemoryArea(Process,
- &Process->AddressSpace,
- MEMORY_AREA_NO_ACCESS,
- &BaseAddress,
- 0x10000 - PAGE_SIZE,
- PAGE_NOACCESS,
- &MemoryArea,
- FALSE,
- FALSE,
- BoundaryAddressMultiple);
- if (!NT_SUCCESS(Status))
- {
- MmUnlockAddressSpace(&Process->AddressSpace);
- DPRINT1("Failed to protect the memory above the shared user page\n");
- ObDereferenceObject(Process);
- goto exitdereferenceobjects;
- }
+ if (SectionObject)
+ {
+ /* Map the System Dll */
+ DPRINT("Mapping System DLL\n");
+ PspMapSystemDll(Process, NULL);
+ }
- /* Create the shared data page */
- BaseAddress = (PVOID)USER_SHARED_DATA;
- Status = MmCreateMemoryArea(Process,
- &Process->AddressSpace,
- MEMORY_AREA_SHARED_DATA,
- &BaseAddress,
- PAGE_SIZE,
- PAGE_READONLY,
- &MemoryArea,
- FALSE,
- FALSE,
- BoundaryAddressMultiple);
- MmUnlockAddressSpace(&Process->AddressSpace);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to create shared data page\n");
- ObDereferenceObject(Process);
- goto exitdereferenceobjects;
- }
+ /* Create a handle for the Process */
+ DPRINT("Initialzing Process CID Handle\n");
+ CidEntry.u1.Object = Process;
+ CidEntry.u2.GrantedAccess = 0;
+ Process->UniqueProcessId = ExCreateHandle(PspCidTable, &CidEntry);
+ DPRINT("Created CID: %d\n", Process->UniqueProcessId);
+ if(!Process->UniqueProcessId)
+ {
+ DPRINT1("Failed to create CID handle\n");
+ Status = STATUS_UNSUCCESSFUL; /* FIXME - what error should we return? */
+ goto Cleanup;
+ }
-#if 1
- /*
- * FIXME - the handle should be created after all things are initialized, NOT HERE!
- */
- Status = ObInsertObject ((PVOID)Process,
- NULL,
- DesiredAccess,
- 0,
- NULL,
- &hProcess);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to create a handle for the process\n");
- ObDereferenceObject(Process);
- goto exitdereferenceobjects;
- }
-#endif
+ /* FIXME: Insert into Job Object */
- /*
- * FIXME - Map ntdll
- */
- Status = LdrpMapSystemDll(hProcess, /* FIXME - hProcess shouldn't be available at this point! */
- &LdrStartupAddr);
- if (!NT_SUCCESS(Status))
- {
- DbgPrint("LdrpMapSystemDll failed (Status %x)\n", Status);
- ObDereferenceObject(Process);
- goto exitdereferenceobjects;
- }
-
- /*
- * Map the process image
- */
- if (SectionObject != NULL)
- {
- ULONG ViewSize = 0;
- DPRINT("Mapping process image\n");
- Status = MmMapViewOfSection(SectionObject,
- Process,
- (PVOID*)&ImageBase,
- 0,
- ViewSize,
- NULL,
- &ViewSize,
- 0,
- MEM_COMMIT,
- PAGE_READWRITE);
- ObDereferenceObject(SectionObject);
- if (!NT_SUCCESS(Status))
- {
- DbgPrint("Failed to map the process section (Status %x)\n", Status);
- ObDereferenceObject(Process);
- goto exitdereferenceobjects;
- }
- }
+ /* Create PEB only for User-Mode Processes */
+ if (pParentProcess)
+ {
+ DPRINT("Creating PEB\n");
+ Status = MmCreatePeb(Process);
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("NtCreateProcess() Peb creation failed: Status %x\n",Status);
+ goto Cleanup;
+ }
+ }
- if(pParentProcess != NULL)
- {
- /*
- * Duplicate the token
- */
- Status = SepInitializeNewProcess(Process, pParentProcess);
- if (!NT_SUCCESS(Status))
- {
- DbgPrint("SepInitializeNewProcess failed (Status %x)\n", Status);
- ObDereferenceObject(Process);
- goto exitdereferenceobjects;
- }
- }
- else
- {
- /* FIXME */
- }
+ /* W00T! The process can now be activated */
+ DPRINT("Inserting into Active Process List\n");
+ ExAcquireFastMutex(&PspActiveProcessMutex);
+ InsertTailList(&PsActiveProcessHead, &Process->ActiveProcessLinks);
+ ExReleaseFastMutex(&PspActiveProcessMutex);
+
+ ProcessCreated = TRUE;
+
+ /* FIXME: SeCreateAccessStateEx */
+
+ /* Insert the Process into the Object Directory */
+ DPRINT("Inserting Process Object\n");
+ Status = ObInsertObject(Process,
+ NULL,
+ DesiredAccess,
+ 0,
+ NULL,
+ &hProcess);
+ if (NT_SUCCESS(Status))
+ {
+ /* Set the Creation Time */
+ KeQuerySystemTime(&Process->CreateTime);
- /*
- * FIXME - Create PEB
- */
- DPRINT("Creating PEB\n");
- Status = PsCreatePeb(hProcess, /* FIXME - hProcess shouldn't be available at this point! */
- Process,
- ImageBase);
- if (!NT_SUCCESS(Status))
- {
- DbgPrint("NtCreateProcess() Peb creation failed: Status %x\n",Status);
- ObDereferenceObject(Process);
- goto exitdereferenceobjects;
- }
-
- /*
- * Maybe send a message to the creator process's debugger
- */
-#if 0
- if (pParentProcess->DebugPort != NULL)
- {
- LPC_DBG_MESSAGE Message;
- HANDLE FileHandle;
-
- ObCreateHandle(NULL, // Debugger Process
- NULL, // SectionHandle
- FILE_ALL_ACCESS,
- FALSE,
- &FileHandle);
-
- Message.Header.MessageSize = sizeof(LPC_DBG_MESSAGE);
- Message.Header.DataSize = sizeof(LPC_DBG_MESSAGE) -
- sizeof(LPC_MESSAGE);
- Message.Type = DBG_EVENT_CREATE_PROCESS;
- Message.Data.CreateProcess.FileHandle = FileHandle;
- Message.Data.CreateProcess.Base = ImageBase;
- Message.Data.CreateProcess.EntryPoint = NULL; //
-
- Status = LpcSendDebugMessagePort(pParentProcess->DebugPort,
- &Message);
- }
-#endif
+ DPRINT("Done. Returning handle: %x\n", hProcess);
+ _SEH_TRY
+ {
+ *ProcessHandle = hProcess;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ } _SEH_END;
+ /* FIXME: ObGetObjectSecurity(Process, &SecurityDescriptor)
+ SeAccessCheck
+ */
+ }
- PspRunCreateProcessNotifyRoutines(Process, TRUE);
-
- /*
- * FIXME - the handle should be created not before this point!
- */
-#if 0
- Status = ObInsertObject ((PVOID)Process,
- NULL,
- DesiredAccess,
- 0,
- NULL,
- &hProcess);
-#endif
- if (NT_SUCCESS(Status))
- {
- _SEH_TRY
- {
- *ProcessHandle = hProcess;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
- }
-
- /*
- * don't dereference the debug port, exception port and section object even
- * if ObInsertObject() failed, the process is alive! We just couldn't return
- * the handle to the caller!
- */
-
- ObDereferenceObject(Process);
- if(pParentProcess != NULL)
- ObDereferenceObject(pParentProcess);
+Cleanup:
+ if(pParentProcess != NULL) ObDereferenceObject(pParentProcess);
+ if(SectionObject != NULL) ObDereferenceObject(SectionObject);
+ if (!ProcessCreated)
+ {
+ if(pExceptionPort != NULL) ObDereferenceObject(pExceptionPort);
+ if(pDebugPort != NULL) ObDereferenceObject(pDebugPort);
+ if(Process != NULL) ObDereferenceObject(Process);
+ }
- return Status;
+ return Status;
}
+/* PUBLIC FUNCTIONS *****************************************************************/
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS
+STDCALL
PsCreateSystemProcess(PHANDLE ProcessHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes)
+ ACCESS_MASK DesiredAccess,
+ POBJECT_ATTRIBUTES ObjectAttributes)
{
- return PspCreateProcess(ProcessHandle,
- DesiredAccess,
- ObjectAttributes,
- NULL, /* no parent process */
- FALSE,
- NULL,
- NULL,
- NULL);
+ return PspCreateProcess(ProcessHandle,
+ DesiredAccess,
+ ObjectAttributes,
+ NULL, /* no parent process */
+ FALSE,
+ NULL,
+ NULL,
+ NULL);
}
-
/*
* @implemented
*/
-NTSTATUS STDCALL
-NtCreateProcess(OUT PHANDLE ProcessHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
- IN HANDLE ParentProcess,
- IN BOOLEAN InheritObjectTable,
- IN HANDLE SectionHandle OPTIONAL,
- IN HANDLE DebugPort OPTIONAL,
- IN HANDLE ExceptionPort OPTIONAL)
-/*
- * FUNCTION: Creates a process.
- * ARGUMENTS:
- * ProcessHandle (OUT) = Caller supplied storage for the resulting
- * handle
- * DesiredAccess = Specifies the allowed or desired access to the
- * process can be a combination of
- * STANDARD_RIGHTS_REQUIRED| ..
- * ObjectAttribute = Initialized attributes for the object, contains
- * the rootdirectory and the filename
- * ParentProcess = Handle to the parent process.
- * InheritObjectTable = Specifies to inherit the objects of the parent
- * process if true.
- * SectionHandle = Handle to a section object to back the image file
- * DebugPort = Handle to a DebugPort if NULL the system default debug
- * port will be used.
- * ExceptionPort = Handle to a exception port.
- * REMARKS:
- * This function maps to the win32 CreateProcess.
- * RETURNS: Status
+NTSTATUS
+STDCALL
+PsLookupProcessByProcessId(IN HANDLE ProcessId,
+ OUT PEPROCESS *Process)
+{
+ PHANDLE_TABLE_ENTRY CidEntry;
+ PEPROCESS FoundProcess;
+ NTSTATUS Status = STATUS_INVALID_PARAMETER;
+ PAGED_CODE();
+
+ KeEnterCriticalRegion();
+
+ /* Get the CID Handle Entry */
+ if ((CidEntry = ExMapHandleToPointer(PspCidTable,
+ ProcessId)))
+ {
+ /* Get the Process */
+ FoundProcess = CidEntry->u1.Object;
+
+ /* Make sure it's really a process */
+ if (FoundProcess->Pcb.Header.Type == ProcessObject)
+ {
+ /* Reference and return it */
+ ObReferenceObject(FoundProcess);
+ *Process = FoundProcess;
+ Status = STATUS_SUCCESS;
+ }
+
+ /* Unlock the Entry */
+ ExUnlockHandleTableEntry(PspCidTable, CidEntry);
+ }
+
+ KeLeaveCriticalRegion();
+
+ /* Return to caller */
+ return Status;
+}
+
+/*
+ * @implemented
*/
+NTSTATUS
+STDCALL
+PsLookupProcessThreadByCid(IN PCLIENT_ID Cid,
+ OUT PEPROCESS *Process OPTIONAL,
+ OUT PETHREAD *Thread)
{
- KPROCESSOR_MODE PreviousMode;
- NTSTATUS Status = STATUS_SUCCESS;
-
- PAGED_CODE();
-
- PreviousMode = ExGetPreviousMode();
-
- if(PreviousMode != KernelMode)
- {
- _SEH_TRY
- {
- ProbeForWrite(ProcessHandle,
- sizeof(HANDLE),
- sizeof(ULONG));
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
+ PHANDLE_TABLE_ENTRY CidEntry;
+ PETHREAD FoundThread;
+ NTSTATUS Status = STATUS_INVALID_CID;
+ PAGED_CODE();
+
+ KeEnterCriticalRegion();
- if(!NT_SUCCESS(Status))
- {
- return Status;
- }
- }
-
- if(ParentProcess == NULL)
- {
- Status = STATUS_INVALID_PARAMETER;
- }
- else
- {
- Status = PspCreateProcess(ProcessHandle,
- DesiredAccess,
- ObjectAttributes,
- ParentProcess,
- InheritObjectTable,
- SectionHandle,
- DebugPort,
- ExceptionPort);
- }
-
- return Status;
-}
+ /* Get the CID Handle Entry */
+ if ((CidEntry = ExMapHandleToPointer(PspCidTable,
+ Cid->UniqueThread)))
+ {
+ /* Get the Process */
+ FoundThread = CidEntry->u1.Object;
+
+ /* Make sure it's really a thread and this process' */
+ if ((FoundThread->Tcb.DispatcherHeader.Type == ThreadObject) &&
+ (FoundThread->Cid.UniqueProcess == Cid->UniqueProcess))
+ {
+ /* Reference and return it */
+ ObReferenceObject(FoundThread);
+ *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);
+ }
+ }
+
+ /* Unlock the Entry */
+ ExUnlockHandleTableEntry(PspCidTable, CidEntry);
+ }
+
+ KeLeaveCriticalRegion();
+ /* Return to caller */
+ return Status;
+}
/*
- * @unimplemented
+ * FUNCTION: Returns a pointer to the current process
+ *
+ * @implemented
*/
-NTSTATUS STDCALL
-NtOpenProcess(OUT PHANDLE ProcessHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN PCLIENT_ID ClientId)
+PEPROCESS STDCALL
+IoGetCurrentProcess(VOID)
{
- DPRINT("NtOpenProcess(ProcessHandle %x, DesiredAccess %x, "
- "ObjectAttributes %x, ClientId %x { UniP %d, UniT %d })\n",
- ProcessHandle, DesiredAccess, ObjectAttributes, ClientId,
- ClientId->UniqueProcess, ClientId->UniqueThread);
-
- PAGED_CODE();
-
- /*
- * Not sure of the exact semantics
- */
- if (ObjectAttributes != NULL && ObjectAttributes->ObjectName != NULL &&
- ObjectAttributes->ObjectName->Buffer != NULL)
+ if (PsGetCurrentThread() == NULL ||
+ PsGetCurrentThread()->Tcb.ApcState.Process == NULL)
{
- NTSTATUS Status;
- PEPROCESS Process;
-
- Status = ObReferenceObjectByName(ObjectAttributes->ObjectName,
- ObjectAttributes->Attributes,
- NULL,
- DesiredAccess,
- PsProcessType,
- UserMode,
- NULL,
- (PVOID*)&Process);
- if (Status != STATUS_SUCCESS)
- {
- return(Status);
- }
-
- Status = ObCreateHandle(PsGetCurrentProcess(),
- Process,
- DesiredAccess,
- FALSE,
- ProcessHandle);
- ObDereferenceObject(Process);
-
- return(Status);
+ return(PsInitialSystemProcess);
}
else
{
- PLIST_ENTRY current_entry;
- PEPROCESS current;
- NTSTATUS Status;
-
- ExAcquireFastMutex(&PspActiveProcessMutex);
- current_entry = PsActiveProcessHead.Flink;
- while (current_entry != &PsActiveProcessHead)
- {
- current = CONTAINING_RECORD(current_entry, EPROCESS,
- ProcessListEntry);
- if (current->UniqueProcessId == ClientId->UniqueProcess)
- {
- if (current->Pcb.State == PROCESS_STATE_TERMINATED)
- {
- Status = STATUS_PROCESS_IS_TERMINATING;
- }
- else
- {
- Status = ObReferenceObjectByPointer(current,
- DesiredAccess,
- PsProcessType,
- UserMode);
- }
- ExReleaseFastMutex(&PspActiveProcessMutex);
- if (NT_SUCCESS(Status))
- {
- Status = ObCreateHandle(PsGetCurrentProcess(),
- current,
- DesiredAccess,
- FALSE,
- ProcessHandle);
- ObDereferenceObject(current);
- DPRINT("*ProcessHandle %x\n", ProcessHandle);
- DPRINT("NtOpenProcess() = %x\n", Status);
- }
- return(Status);
- }
- current_entry = current_entry->Flink;
- }
- ExReleaseFastMutex(&PspActiveProcessMutex);
- DPRINT("NtOpenProcess() = STATUS_UNSUCCESSFUL\n");
- return(STATUS_UNSUCCESSFUL);
+ return(PEPROCESS)(PsGetCurrentThread()->Tcb.ApcState.Process);
}
}
*/
LONGLONG
STDCALL
-PsGetProcessCreateTimeQuadPart(
- PEPROCESS Process
- )
+PsGetProcessCreateTimeQuadPart(PEPROCESS Process)
{
- return Process->CreateTime.QuadPart;
+ return Process->CreateTime.QuadPart;
}
/*
*/
PVOID
STDCALL
-PsGetProcessDebugPort(
- PEPROCESS Process
- )
+PsGetProcessDebugPort(PEPROCESS Process)
{
- return Process->DebugPort;
+ return Process->DebugPort;
}
/*
*/
BOOLEAN
STDCALL
-PsGetProcessExitProcessCalled(
- PEPROCESS Process
- )
+PsGetProcessExitProcessCalled(PEPROCESS Process)
{
- return Process->ExitProcessCalled;
+ return Process->ProcessExiting;
}
/*
*/
NTSTATUS
STDCALL
-PsGetProcessExitStatus(
- PEPROCESS Process
- )
+PsGetProcessExitStatus(PEPROCESS Process)
{
- return Process->ExitStatus;
+ return Process->ExitStatus;
}
/*
*/
HANDLE
STDCALL
-PsGetProcessId(
- PEPROCESS Process
- )
+PsGetProcessId(PEPROCESS Process)
{
- return (HANDLE)Process->UniqueProcessId;
+ return (HANDLE)Process->UniqueProcessId;
}
/*
*/
LPSTR
STDCALL
-PsGetProcessImageFileName(
- PEPROCESS Process
- )
+PsGetProcessImageFileName(PEPROCESS Process)
{
- return (LPSTR)Process->ImageFileName;
+ return (LPSTR)Process->ImageFileName;
}
/*
*/
HANDLE
STDCALL
-PsGetProcessInheritedFromUniqueProcessId(
- PEPROCESS Process
- )
+PsGetProcessInheritedFromUniqueProcessId(PEPROCESS Process)
{
- return Process->InheritedFromUniqueProcessId;
+ return Process->InheritedFromUniqueProcessId;
}
/*
*/
PEJOB
STDCALL
-PsGetProcessJob(
- PEPROCESS Process
- )
+PsGetProcessJob(PEPROCESS Process)
{
- return Process->Job;
+ return Process->Job;
}
/*
*/
PPEB
STDCALL
-PsGetProcessPeb(
- PEPROCESS Process
- )
+PsGetProcessPeb(PEPROCESS Process)
{
- return Process->Peb;
+ return Process->Peb;
}
/*
*/
ULONG
STDCALL
-PsGetProcessPriorityClass(
- PEPROCESS Process
- )
-{
- return Process->PriorityClass;
-}
-
-/*
- * @implemented
- */
-PVOID
-STDCALL
-PsGetProcessSectionBaseAddress(
- PEPROCESS Process
- )
+PsGetProcessPriorityClass(PEPROCESS Process)
{
- return Process->SectionBaseAddress;
+ return Process->PriorityClass;
}
/*
* @implemented
*/
-PVOID
-STDCALL
-PsGetProcessSecurityPort(
- PEPROCESS Process
- )
+HANDLE STDCALL
+PsGetCurrentProcessId(VOID)
{
- return Process->SecurityPort;
+ return((HANDLE)PsGetCurrentProcess()->UniqueProcessId);
}
/*
* @implemented
*/
-HANDLE
+ULONG
STDCALL
-PsGetProcessSessionId(
- PEPROCESS Process
- )
+PsGetCurrentProcessSessionId(VOID)
{
- return (HANDLE)Process->SessionId;
+ return PsGetCurrentProcess()->Session;
}
/*
*/
PVOID
STDCALL
-PsGetProcessWin32Process(
- PEPROCESS Process
- )
+PsGetProcessSectionBaseAddress(PEPROCESS Process)
{
- return Process->Win32Process;
+ return Process->SectionBaseAddress;
}
/*
*/
PVOID
STDCALL
-PsGetProcessWin32WindowStation(
- PEPROCESS Process
- )
+PsGetProcessSecurityPort(PEPROCESS Process)
{
- return Process->Win32WindowStation;
+ return Process->SecurityPort;
}
/*
* @implemented
*/
-BOOLEAN
+HANDLE
STDCALL
-PsIsProcessBeingDebugged(
- PEPROCESS Process
- )
+PsGetProcessSessionId(PEPROCESS Process)
{
- return FALSE/*Process->IsProcessBeingDebugged*/;
+ return (HANDLE)Process->Session;
}
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-PsLookupProcessByProcessId(IN HANDLE ProcessId,
- OUT PEPROCESS *Process)
+struct _W32THREAD*
+STDCALL
+PsGetWin32Thread(VOID)
{
- PHANDLE_TABLE_ENTRY CidEntry;
- PEPROCESS FoundProcess;
-
- PAGED_CODE();
-
- ASSERT(Process);
-
- CidEntry = PsLookupCidHandle(ProcessId, PsProcessType, (PVOID*)&FoundProcess);
- if(CidEntry != NULL)
- {
- ObReferenceObject(FoundProcess);
-
- PsUnlockCidHandle(CidEntry);
-
- *Process = FoundProcess;
- return STATUS_SUCCESS;
- }
-
- return STATUS_INVALID_PARAMETER;
+ return(PsGetCurrentThread()->Tcb.Win32Thread);
}
-VOID
+struct _W32PROCESS*
STDCALL
-PspRunCreateProcessNotifyRoutines
-(
- PEPROCESS CurrentProcess,
- BOOLEAN Create
-)
+PsGetWin32Process(VOID)
{
- ULONG i;
- HANDLE ProcessId = (HANDLE)CurrentProcess->UniqueProcessId;
- HANDLE ParentId = CurrentProcess->InheritedFromUniqueProcessId;
-
- for(i = 0; i < MAX_PROCESS_NOTIFY_ROUTINE_COUNT; ++ i)
- if(PiProcessNotifyRoutine[i])
- PiProcessNotifyRoutine[i](ParentId, ProcessId, Create);
+ return (struct _W32PROCESS*)PsGetCurrentProcess()->Win32Process;
}
/*
* @implemented
*/
-NTSTATUS STDCALL
-PsSetCreateProcessNotifyRoutine(IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,
- IN BOOLEAN Remove)
-{
- ULONG i;
-
- if (Remove)
- {
- for(i=0;i<MAX_PROCESS_NOTIFY_ROUTINE_COUNT;i++)
- {
- if ((PVOID)PiProcessNotifyRoutine[i] == (PVOID)NotifyRoutine)
- {
- PiProcessNotifyRoutine[i] = NULL;
- break;
- }
- }
-
- return(STATUS_SUCCESS);
- }
-
- /*insert*/
- for(i=0;i<MAX_PROCESS_NOTIFY_ROUTINE_COUNT;i++)
- {
- if (PiProcessNotifyRoutine[i] == NULL)
- {
- PiProcessNotifyRoutine[i] = NotifyRoutine;
- break;
- }
- }
-
- if (i == MAX_PROCESS_NOTIFY_ROUTINE_COUNT)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- return STATUS_SUCCESS;
-}
-
-VOID STDCALL
-PspRunLoadImageNotifyRoutines(
- PUNICODE_STRING FullImageName,
- HANDLE ProcessId,
- PIMAGE_INFO ImageInfo)
-{
- ULONG i;
-
- for (i = 0; i < MAX_PROCESS_NOTIFY_ROUTINE_COUNT; ++ i)
- if (PiLoadImageNotifyRoutine[i])
- PiLoadImageNotifyRoutine[i](FullImageName, ProcessId, ImageInfo);
-}
-
-/*
- * @unimplemented
- */
-NTSTATUS
+PVOID
STDCALL
-PsRemoveLoadImageNotifyRoutine(
- IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine
- )
+PsGetProcessWin32Process(PEPROCESS Process)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ return Process->Win32Process;
}
/*
* @implemented
*/
-NTSTATUS STDCALL
-PsSetLoadImageNotifyRoutine(IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine)
+PVOID
+STDCALL
+PsGetProcessWin32WindowStation(PEPROCESS Process)
{
- ULONG i;
-
- for (i = 0; i < MAX_LOAD_IMAGE_NOTIFY_ROUTINE_COUNT; i++)
- {
- if (PiLoadImageNotifyRoutine[i] == NULL)
- {
- PiLoadImageNotifyRoutine[i] = NotifyRoutine;
- break;
- }
- }
-
- if (i == MAX_PROCESS_NOTIFY_ROUTINE_COUNT)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- return STATUS_SUCCESS;
+ return Process->Win32WindowStation;
}
/*
* @implemented
- */
-VOID
+ */
+BOOLEAN
STDCALL
-PsSetProcessPriorityClass(
- PEPROCESS Process,
- ULONG PriorityClass
- )
+PsIsProcessBeingDebugged(PEPROCESS Process)
{
- Process->PriorityClass = PriorityClass;
+ return FALSE; //Process->IsProcessBeingDebugged;
}
/*
* @implemented
- */
+ */
VOID
STDCALL
-PsSetProcessSecurityPort(
- PEPROCESS Process,
- PVOID SecurityPort
- )
+PsSetProcessPriorityClass(PEPROCESS Process,
+ ULONG PriorityClass)
{
- Process->SecurityPort = SecurityPort;
+ Process->PriorityClass = PriorityClass;
}
/*
*/
VOID
STDCALL
-PsSetProcessWin32Process(
- PEPROCESS Process,
- PVOID Win32Process
- )
+PsSetProcessSecurityPort(PEPROCESS Process,
+ PVOID SecurityPort)
{
- Process->Win32Process = Win32Process;
+ Process->SecurityPort = SecurityPort;
}
/*
*/
VOID
STDCALL
-PsSetProcessWin32WindowStation(
- PEPROCESS Process,
- PVOID WindowStation
- )
+PsSetProcessWin32Process(PEPROCESS Process,
+ PVOID Win32Process)
{
- Process->Win32WindowStation = WindowStation;
+ Process->Win32Process = Win32Process;
}
-/* Pool Quotas */
/*
* @implemented
*/
VOID
STDCALL
-PsChargePoolQuota(
- IN PEPROCESS Process,
- IN POOL_TYPE PoolType,
- IN ULONG_PTR Amount
- )
+PsSetProcessWindowStation(PEPROCESS Process,
+ PVOID WindowStation)
{
- NTSTATUS Status;
-
- /* Charge the usage */
- Status = PsChargeProcessPoolQuota(Process, PoolType, Amount);
-
- /* Raise Exception */
- if (!NT_SUCCESS(Status)) {
- ExRaiseStatus(Status);
- }
+ Process->Win32WindowStation = WindowStation;
}
/*
- * @implemented
+ * @unimplemented
*/
NTSTATUS
STDCALL
-PsChargeProcessNonPagedPoolQuota (
- IN PEPROCESS Process,
- IN ULONG_PTR Amount
- )
+PsSetProcessPriorityByClass(IN PEPROCESS Process,
+ IN ULONG Type)
{
- /* Call the general function */
- return PsChargeProcessPoolQuota(Process, NonPagedPool, Amount);
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
}
/*
+ * FUNCTION: Creates a process.
+ * ARGUMENTS:
+ * ProcessHandle (OUT) = Caller supplied storage for the resulting
+ * handle
+ * DesiredAccess = Specifies the allowed or desired access to the
+ * process can be a combination of
+ * STANDARD_RIGHTS_REQUIRED| ..
+ * ObjectAttribute = Initialized attributes for the object, contains
+ * the rootdirectory and the filename
+ * ParentProcess = Handle to the parent process.
+ * InheritObjectTable = Specifies to inherit the objects of the parent
+ * process if true.
+ * SectionHandle = Handle to a section object to back the image file
+ * DebugPort = Handle to a DebugPort if NULL the system default debug
+ * port will be used.
+ * ExceptionPort = Handle to a exception port.
+ * REMARKS:
+ * This function maps to the win32 CreateProcess.
+ * RETURNS: Status
+ *
* @implemented
*/
NTSTATUS
STDCALL
-PsChargeProcessPagedPoolQuota (
- IN PEPROCESS Process,
- IN ULONG_PTR Amount
- )
+NtCreateProcess(OUT PHANDLE ProcessHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
+ IN HANDLE ParentProcess,
+ IN BOOLEAN InheritObjectTable,
+ IN HANDLE SectionHandle OPTIONAL,
+ IN HANDLE DebugPort OPTIONAL,
+ IN HANDLE ExceptionPort OPTIONAL)
{
- /* Call the general function */
- return PsChargeProcessPoolQuota(Process, PagedPool, Amount);
+ KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ PAGED_CODE();
+
+ /* Check parameters */
+ if(PreviousMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForWriteHandle(ProcessHandle);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status)) return Status;
+ }
+
+ /* Make sure there's a parent process */
+ if(ParentProcess == NULL)
+ {
+ /* Can't create System Processes like this */
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ else
+ {
+ /* Create a user Process */
+ Status = PspCreateProcess(ProcessHandle,
+ DesiredAccess,
+ ObjectAttributes,
+ ParentProcess,
+ InheritObjectTable,
+ SectionHandle,
+ DebugPort,
+ ExceptionPort);
+ }
+
+ /* Return Status */
+ return Status;
}
/*
*/
NTSTATUS
STDCALL
-PsChargeProcessPoolQuota(
- IN PEPROCESS Process,
- IN POOL_TYPE PoolType,
- IN ULONG_PTR Amount
- )
+NtOpenProcess(OUT PHANDLE ProcessHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes,
+ IN PCLIENT_ID ClientId)
{
- PEPROCESS_QUOTA_BLOCK QuotaBlock;
- ULONG NewUsageSize;
- ULONG NewMaxQuota;
-
- /* Get current Quota Block */
- QuotaBlock = Process->QuotaBlock;
-
- /* Quota Operations are not to be done on the SYSTEM Process */
- if (Process == PsInitialSystemProcess) return STATUS_SUCCESS;
-
- /* New Size in use */
- NewUsageSize = QuotaBlock->QuotaEntry[PoolType].Usage + Amount;
+ KPROCESSOR_MODE PreviousMode;
+ CLIENT_ID SafeClientId;
+ ULONG Attributes = 0;
+ HANDLE hProcess;
+ BOOLEAN HasObjectName = FALSE;
+ PETHREAD Thread = NULL;
+ PEPROCESS Process = NULL;
+ NTSTATUS Status = STATUS_SUCCESS;
- /* Does this size respect the quota? */
- if (NewUsageSize > QuotaBlock->QuotaEntry[PoolType].Limit) {
+ PAGED_CODE();
- /* It doesn't, so keep raising the Quota */
- while (MiRaisePoolQuota(PoolType, QuotaBlock->QuotaEntry[PoolType].Limit, &NewMaxQuota)) {
- /* Save new Maximum Quota */
- QuotaBlock->QuotaEntry[PoolType].Limit = NewMaxQuota;
+ PreviousMode = KeGetPreviousMode();
- /* See if the new Maximum Quota fulfills our need */
- if (NewUsageSize <= NewMaxQuota) goto QuotaChanged;
+ /* Probe the paraemeters */
+ if(PreviousMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForWriteHandle(ProcessHandle);
+
+ if(ClientId != NULL)
+ {
+ ProbeForRead(ClientId,
+ sizeof(CLIENT_ID),
+ sizeof(ULONG));
+
+ SafeClientId = *ClientId;
+ ClientId = &SafeClientId;
+ }
+
+ /* just probe the object attributes structure, don't capture it
+ completely. This is done later if necessary */
+ ProbeForRead(ObjectAttributes,
+ sizeof(OBJECT_ATTRIBUTES),
+ sizeof(ULONG));
+ HasObjectName = (ObjectAttributes->ObjectName != NULL);
+ Attributes = ObjectAttributes->Attributes;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
}
+ _SEH_END;
- return STATUS_QUOTA_EXCEEDED;
+ if(!NT_SUCCESS(Status)) return Status;
+ }
+ else
+ {
+ HasObjectName = (ObjectAttributes->ObjectName != NULL);
+ Attributes = ObjectAttributes->Attributes;
}
-QuotaChanged:
- /* Save new Usage */
- QuotaBlock->QuotaEntry[PoolType].Usage = NewUsageSize;
-
- /* Is this a new peak? */
- if (NewUsageSize > QuotaBlock->QuotaEntry[PoolType].Peak) {
- QuotaBlock->QuotaEntry[PoolType].Peak = NewUsageSize;
+ if (HasObjectName && ClientId != NULL)
+ {
+ /* can't pass both, n object name and a client id */
+ return STATUS_INVALID_PARAMETER_MIX;
}
- /* All went well */
- return STATUS_SUCCESS;
-}
+ /* Open by name if one was given */
+ DPRINT("Checking type\n");
+ if (HasObjectName)
+ {
+ /* Open it */
+ DPRINT("Opening by name\n");
+ Status = ObOpenObjectByName(ObjectAttributes,
+ PsProcessType,
+ NULL,
+ PreviousMode,
+ DesiredAccess,
+ NULL,
+ &hProcess);
-/*
- * @unimplemented
- */
-VOID
-STDCALL
-PsReturnPoolQuota(
- IN PEPROCESS Process,
- IN POOL_TYPE PoolType,
- IN ULONG_PTR Amount
- )
-{
- UNIMPLEMENTED;
-}
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not open object by name\n");
+ }
+ }
+ else if (ClientId != NULL)
+ {
+ /* Open by Thread ID */
+ if (ClientId->UniqueThread)
+ {
+ /* Get the Process */
+ DPRINT("Opening by Thread ID: %x\n", ClientId->UniqueThread);
+ Status = PsLookupProcessThreadByCid(ClientId,
+ &Process,
+ &Thread);
+ }
+ else
+ {
+ /* Get the Process */
+ DPRINT("Opening by Process ID: %x\n", ClientId->UniqueProcess);
+ Status = PsLookupProcessByProcessId(ClientId->UniqueProcess,
+ &Process);
+ }
-/*
- * @unimplemented
- */
-VOID
-STDCALL
-PsReturnProcessNonPagedPoolQuota(
- IN PEPROCESS Process,
- IN ULONG_PTR Amount
- )
-{
- UNIMPLEMENTED;
-}
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failure to find process\n");
+ return Status;
+ }
-/*
- * @unimplemented
- */
-VOID
-STDCALL
-PsReturnProcessPagedPoolQuota(
- IN PEPROCESS Process,
- IN ULONG_PTR Amount
- )
-{
- UNIMPLEMENTED;
-}
+ /* Open the Process Object */
+ Status = ObOpenObjectByPointer(Process,
+ Attributes,
+ NULL,
+ DesiredAccess,
+ PsProcessType,
+ PreviousMode,
+ &hProcess);
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failure to open process\n");
+ }
-NTSTATUS
-PsLockProcess(PEPROCESS Process, BOOLEAN Timeout)
-{
- ULONG Attempts = 0;
- PKTHREAD PrevLockOwner;
- NTSTATUS Status = STATUS_UNSUCCESSFUL;
- PLARGE_INTEGER Delay = (Timeout ? &PsLockTimeout : NULL);
- PKTHREAD CallingThread = KeGetCurrentThread();
-
- PAGED_CODE();
-
- KeEnterCriticalRegion();
-
- for(;;)
- {
- PrevLockOwner = (PKTHREAD)InterlockedCompareExchangePointer(
- &Process->LockOwner, CallingThread, NULL);
- if(PrevLockOwner == NULL || PrevLockOwner == CallingThread)
- {
- /* we got the lock or already locked it */
- if(InterlockedIncrementUL(&Process->LockCount) == 1)
- {
- KeClearEvent(&Process->LockEvent);
- }
+ /* Dereference the thread if we used it */
+ if (Thread) ObDereferenceObject(Thread);
- return STATUS_SUCCESS;
+ /* Dereference the Process */
+ ObDereferenceObject(Process);
}
else
{
- if(++Attempts > 2)
- {
- Status = KeWaitForSingleObject(&Process->LockEvent,
- Executive,
- KernelMode,
- FALSE,
- Delay);
- if(!NT_SUCCESS(Status) || Status == STATUS_TIMEOUT)
+ /* neither an object name nor a client id was passed */
+ return STATUS_INVALID_PARAMETER_MIX;
+ }
+
+ /* Write back the handle */
+ if(NT_SUCCESS(Status))
+ {
+ _SEH_TRY
{
-#ifndef NDEBUG
- if(Status == STATUS_TIMEOUT)
- {
- DPRINT1("PsLockProcess(0x%x) timed out!\n", Process);
- }
-#endif
- KeLeaveCriticalRegion();
- break;
+ *ProcessHandle = hProcess;
}
- }
- else
- {
- KeDelayExecutionThread(KernelMode, FALSE, &ShortPsLockDelay);
- }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
}
- }
-
- return Status;
-}
-VOID
-PsUnlockProcess(PEPROCESS Process)
-{
- PAGED_CODE();
-
- ASSERT(Process->LockOwner == KeGetCurrentThread());
-
- if(InterlockedDecrementUL(&Process->LockCount) == 0)
- {
- InterlockedExchangePointer(&Process->LockOwner, NULL);
- KeSetEvent(&Process->LockEvent, IO_NO_INCREMENT, FALSE);
- }
-
- KeLeaveCriticalRegion();
+ return Status;
}
-
/* EOF */