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;
/* INTERNAL FUNCTIONS *****************************************************************/
NTSTATUS
+NTAPI
PsLockProcess(PEPROCESS Process, BOOLEAN Timeout)
{
ULONG Attempts = 0;
}
VOID
+NTAPI
PsUnlockProcess(PEPROCESS Process)
{
PAGED_CODE();
IN HANDLE ExceptionPort OPTIONAL)
{
HANDLE hProcess;
- PEPROCESS Process;
- PEPROCESS pParentProcess;
+ PEPROCESS Process = NULL;
+ PEPROCESS pParentProcess = NULL;
PEPORT pDebugPort = NULL;
PEPORT pExceptionPort = NULL;
PSECTION_OBJECT SectionObject = NULL;
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);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to reference the parent process: Status: 0x%x\n", Status);
- return(Status);
+ goto Cleanup;
}
/* Inherit Parent process's Affinity. */
else
{
pParentProcess = NULL;
+#ifdef CONFIG_SMP
+ /* FIXME:
+ * Only the boot cpu is initialized in the early boot phase.
+ */
+ Affinity = 0xffffffff;
+#else
Affinity = KeActiveProcessors;
+#endif
}
/* Add the debug port */
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to reference the debug port: Status: 0x%x\n", Status);
- goto exitdereferenceobjects;
+ goto Cleanup;
}
}
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to reference the exception port: Status: 0x%x\n", Status);
- goto exitdereferenceobjects;
+ goto Cleanup;
}
}
if (SectionHandle != NULL)
{
Status = ObReferenceObjectByHandle(SectionHandle,
- 0,
+ SECTION_MAP_EXECUTE,
MmSectionObjectType,
PreviousMode,
(PVOID*)&SectionObject,
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to reference process image section: Status: 0x%x\n", Status);
- goto exitdereferenceobjects;
+ goto Cleanup;
}
}
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create process object, Status: 0x%x\n", Status);
- goto exitdereferenceobjects;
+ goto Cleanup;
}
/* Clean up the Object */
Process->Session = pParentProcess->Session;
}
- /* FIXME: Set up the Quota Block from the Parent
- PspInheritQuota(Parent, Process); */
+ /* Set up the Quota Block from the Parent */
+ PspInheritQuota(Process, pParentProcess);
/* FIXME: Set up Dos Device Map from the Parent
ObInheritDeviceMap(Parent, Process) */
/* Now initialize the Kernel Process */
DPRINT("Initialzing Kernel Process\n");
KeInitializeProcess(&Process->Pcb,
- PROCESS_PRIO_NORMAL,
+ PROCESS_PRIORITY_NORMAL,
Affinity,
DirectoryTableBase);
if (!NT_SUCCESS(Status))
{
DbgPrint("PspInitializeProcessSecurity failed (Status %x)\n", Status);
- ObDereferenceObject(Process);
- goto exitdereferenceobjects;
+ goto Cleanup;
}
/* Create the Process' Address Space */
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create Address Space\n");
- ObDereferenceObject(Process);
- goto exitdereferenceobjects;
+ goto Cleanup;
}
if (SectionObject)
{
/* Map the System Dll */
DPRINT("Mapping System DLL\n");
- LdrpMapSystemDll(Process, NULL);
+ PspMapSystemDll(Process, NULL);
}
/* Create a handle for the Process */
DPRINT("Initialzing Process CID Handle\n");
- Status = PsCreateCidHandle(Process,
- PsProcessType,
- &Process->UniqueProcessId);
+ CidEntry.u1.Object = Process;
+ CidEntry.u2.GrantedAccess = 0;
+ Process->UniqueProcessId = ExCreateHandle(PspCidTable, &CidEntry);
DPRINT("Created CID: %d\n", Process->UniqueProcessId);
- if(!NT_SUCCESS(Status))
+ if(!Process->UniqueProcessId)
{
- DPRINT1("Failed to create CID handle (unique process ID)! Status: 0x%x\n", Status);
- ObDereferenceObject(Process);
- goto exitdereferenceobjects;
- }
+ DPRINT1("Failed to create CID handle\n");
+ Status = STATUS_UNSUCCESSFUL; /* FIXME - what error should we return? */
+ goto Cleanup;
+ }
/* FIXME: Insert into Job Object */
if (!NT_SUCCESS(Status))
{
DbgPrint("NtCreateProcess() Peb creation failed: Status %x\n",Status);
- ObDereferenceObject(Process);
- goto exitdereferenceobjects;
+ goto Cleanup;
}
-
- /* Let's take advantage of this time to kill the reference too */
- ObDereferenceObject(pParentProcess);
- pParentProcess = NULL;
}
/* W00T! The process can now be activated */
ExAcquireFastMutex(&PspActiveProcessMutex);
InsertTailList(&PsActiveProcessHead, &Process->ActiveProcessLinks);
ExReleaseFastMutex(&PspActiveProcessMutex);
+
+ ProcessCreated = TRUE;
/* FIXME: SeCreateAccessStateEx */
0,
NULL,
&hProcess);
- if (!NT_SUCCESS(Status))
+ if (NT_SUCCESS(Status))
{
- DPRINT1("Could not get a handle to the Process Object\n");
- ObDereferenceObject(Process);
- goto exitdereferenceobjects;
- }
+ /* Set the Creation Time */
+ KeQuerySystemTime(&Process->CreateTime);
- /* Set the Creation Time */
- KeQuerySystemTime(&Process->CreateTime);
+ DPRINT("Done. Returning handle: %x\n", hProcess);
+ _SEH_TRY
+ {
+ *ProcessHandle = hProcess;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ } _SEH_END;
+ /* FIXME: ObGetObjectSecurity(Process, &SecurityDescriptor)
+ SeAccessCheck
+ */
+ }
- DPRINT("Done. Returning handle: %x\n", hProcess);
- _SEH_TRY
+Cleanup:
+ if(pParentProcess != NULL) ObDereferenceObject(pParentProcess);
+ if(SectionObject != NULL) ObDereferenceObject(SectionObject);
+ if (!ProcessCreated)
{
- *ProcessHandle = hProcess;
+ if(pExceptionPort != NULL) ObDereferenceObject(pExceptionPort);
+ if(pDebugPort != NULL) ObDereferenceObject(pDebugPort);
+ if(Process != NULL) ObDereferenceObject(Process);
}
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- } _SEH_END;
- /* FIXME: ObGetObjectSecurity(Process, &SecurityDescriptor)
- SeAccessCheck
- */
- ObDereferenceObject(Process);
- return Status;
-
-exitdereferenceobjects:
- if(SectionObject != NULL) ObDereferenceObject(SectionObject);
- if(pExceptionPort != NULL) ObDereferenceObject(pExceptionPort);
- if(pDebugPort != NULL) ObDereferenceObject(pDebugPort);
- if(pParentProcess != NULL) ObDereferenceObject(pParentProcess);
return Status;
}
PsLookupProcessByProcessId(IN HANDLE ProcessId,
OUT PEPROCESS *Process)
{
- PHANDLE_TABLE_ENTRY CidEntry;
- PEPROCESS FoundProcess;
+ 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;
- PAGED_CODE();
+ /* 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();
- ASSERT(Process);
+ /* Return to caller */
+ return Status;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+STDCALL
+PsLookupProcessThreadByCid(IN PCLIENT_ID Cid,
+ OUT PEPROCESS *Process OPTIONAL,
+ OUT PETHREAD *Thread)
+{
+ PHANDLE_TABLE_ENTRY CidEntry;
+ PETHREAD FoundThread;
+ NTSTATUS Status = STATUS_INVALID_CID;
+ PAGED_CODE();
+
+ KeEnterCriticalRegion();
- CidEntry = PsLookupCidHandle(ProcessId, PsProcessType, (PVOID*)&FoundProcess);
- if(CidEntry != NULL)
- {
- ObReferenceObject(FoundProcess);
+ /* Get the CID Handle Entry */
+ if ((CidEntry = ExMapHandleToPointer(PspCidTable,
+ Cid->UniqueThread)))
+ {
+ /* Get the Process */
+ FoundThread = CidEntry->u1.Object;
- PsUnlockCidHandle(CidEntry);
+ /* 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);
+ }
+ }
- *Process = FoundProcess;
- return STATUS_SUCCESS;
+ /* Unlock the Entry */
+ ExUnlockHandleTableEntry(PspCidTable, CidEntry);
}
+
+ KeLeaveCriticalRegion();
- return STATUS_INVALID_PARAMETER;
+ /* Return to caller */
+ return Status;
}
/*
return (HANDLE)Process->Session;
}
+struct _W32THREAD*
+STDCALL
+PsGetWin32Thread(VOID)
+{
+ return(PsGetCurrentThread()->Tcb.Win32Thread);
+}
+
+struct _W32PROCESS*
+STDCALL
+PsGetWin32Process(VOID)
+{
+ return (struct _W32PROCESS*)PsGetCurrentProcess()->Win32Process;
+}
+
/*
* @implemented
*/
*/
VOID
STDCALL
-PsSetProcessWin32WindowStation(PEPROCESS Process,
- PVOID WindowStation)
+PsSetProcessWindowStation(PEPROCESS Process,
+ PVOID WindowStation)
{
Process->Win32WindowStation = WindowStation;
}
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+PsSetProcessPriorityByClass(IN PEPROCESS Process,
+ IN ULONG Type)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
/*
* FUNCTION: Creates a process.
* ARGUMENTS:
{
_SEH_TRY
{
- ProbeForWrite(ProcessHandle,
- sizeof(HANDLE),
- sizeof(ULONG));
+ ProbeForWriteHandle(ProcessHandle);
}
_SEH_HANDLE
{
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId)
{
- KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
- NTSTATUS Status = STATUS_INVALID_PARAMETER;
- PEPROCESS Process;
+ KPROCESSOR_MODE PreviousMode;
+ CLIENT_ID SafeClientId;
+ ULONG Attributes = 0;
+ HANDLE hProcess;
+ BOOLEAN HasObjectName = FALSE;
PETHREAD Thread = NULL;
-
- DPRINT("NtOpenProcess(ProcessHandle %x, DesiredAccess %x, "
- "ObjectAttributes %x, ClientId %x { UniP %d, UniT %d })\n",
- ProcessHandle, DesiredAccess, ObjectAttributes, ClientId,
- ClientId->UniqueProcess, ClientId->UniqueThread);
+ PEPROCESS Process = NULL;
+ NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
+ PreviousMode = KeGetPreviousMode();
+
+ /* 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;
+
+ if(!NT_SUCCESS(Status)) return Status;
+ }
+ else
+ {
+ HasObjectName = (ObjectAttributes->ObjectName != NULL);
+ Attributes = ObjectAttributes->Attributes;
+ }
+
+ if (HasObjectName && ClientId != NULL)
+ {
+ /* can't pass both, n object name and a client id */
+ return STATUS_INVALID_PARAMETER_MIX;
+ }
+
/* Open by name if one was given */
DPRINT("Checking type\n");
- if (ObjectAttributes->ObjectName)
+ if (HasObjectName)
{
/* Open it */
DPRINT("Opening by name\n");
PreviousMode,
DesiredAccess,
NULL,
- ProcessHandle);
+ &hProcess);
- if (Status != STATUS_SUCCESS)
+ if (!NT_SUCCESS(Status))
{
DPRINT1("Could not open object by name\n");
}
-
- /* Return Status */
- DPRINT("Found: %x\n", ProcessHandle);
- return(Status);
}
- else if (ClientId)
+ else if (ClientId != NULL)
{
/* Open by Thread ID */
if (ClientId->UniqueThread)
{
/* Get the Process */
- if (ClientId->UniqueThread == (HANDLE)-1) KEBUGCHECK(0);
DPRINT("Opening by Thread ID: %x\n", ClientId->UniqueThread);
Status = PsLookupProcessThreadByCid(ClientId,
&Process,
&Thread);
- DPRINT("Found: %x\n", Process);
}
else
{
DPRINT("Opening by Process ID: %x\n", ClientId->UniqueProcess);
Status = PsLookupProcessByProcessId(ClientId->UniqueProcess,
&Process);
- DPRINT("Found: %x\n", Process);
}
if(!NT_SUCCESS(Status))
/* Open the Process Object */
Status = ObOpenObjectByPointer(Process,
- ObjectAttributes->Attributes,
+ Attributes,
NULL,
DesiredAccess,
PsProcessType,
PreviousMode,
- ProcessHandle);
+ &hProcess);
if(!NT_SUCCESS(Status))
{
DPRINT1("Failure to open process\n");
/* Dereference the Process */
ObDereferenceObject(Process);
}
+ else
+ {
+ /* 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
+ {
+ *ProcessHandle = hProcess;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ }
return Status;
}