/* 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;
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 */
/* 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)
if(!Process->UniqueProcessId)
{
DPRINT1("Failed to create CID handle\n");
- ObDereferenceObject(Process);
- goto exitdereferenceobjects;
+ 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;
}
PEPROCESS FoundProcess;
NTSTATUS Status = STATUS_INVALID_PARAMETER;
PAGED_CODE();
+
+ KeEnterCriticalRegion();
/* Get the CID Handle Entry */
if ((CidEntry = ExMapHandleToPointer(PspCidTable,
/* Unlock the Entry */
ExUnlockHandleTableEntry(PspCidTable, CidEntry);
}
+
+ KeLeaveCriticalRegion();
/* Return to caller */
return Status;
PETHREAD FoundThread;
NTSTATUS Status = STATUS_INVALID_CID;
PAGED_CODE();
+
+ KeEnterCriticalRegion();
/* Get the CID Handle Entry */
if ((CidEntry = ExMapHandleToPointer(PspCidTable,
/* Unlock the Entry */
ExUnlockHandleTableEntry(PspCidTable, CidEntry);
}
+
+ KeLeaveCriticalRegion();
/* Return to caller */
return Status;
{
_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)
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;
}