Home | Info | Community | Development | myReactOS | Contact Us
Definition at line 1366 of file process.c.
{ KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); CLIENT_ID SafeClientId; ULONG Attributes = 0; HANDLE hProcess; BOOLEAN HasObjectName = FALSE; PETHREAD Thread = NULL; PEPROCESS Process = NULL; NTSTATUS Status; ACCESS_STATE AccessState; AUX_ACCESS_DATA AuxData; PAGED_CODE(); PSTRACE(PS_PROCESS_DEBUG, "ClientId: %p Attributes: %p\n", ClientId, ObjectAttributes); /* Check if we were called from user mode */ if (PreviousMode != KernelMode) { /* Enter SEH for probing */ _SEH2_TRY { /* Probe the thread handle */ ProbeForWriteHandle(ProcessHandle); /* Check for a CID structure */ if (ClientId) { /* Probe and capture it */ 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; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { /* Return the exception code */ _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; } else { /* Otherwise just get the data directly */ HasObjectName = (ObjectAttributes->ObjectName != NULL); Attributes = ObjectAttributes->Attributes; } /* 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)) { /* 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; } /* Open by name if one was given */ if (HasObjectName) { /* Open it */ Status = ObOpenObjectByName(ObjectAttributes, PsProcessType, PreviousMode, &AccessState, 0, NULL, &hProcess); /* Get rid of the access state */ SeDeleteAccessState(&AccessState); } else if (ClientId) { /* Open by Thread ID */ if (ClientId->UniqueThread) { /* Get the Process */ Status = PsLookupProcessThreadByCid(ClientId, &Process, &Thread); } else { /* Get the Process */ Status = PsLookupProcessByProcessId(ClientId->UniqueProcess, &Process); } /* Check if we didn't find anything */ if (!NT_SUCCESS(Status)) { /* Get rid of the access state and return */ SeDeleteAccessState(&AccessState); return Status; } /* Open the Process Object */ Status = ObOpenObjectByPointer(Process, Attributes, &AccessState, 0, PsProcessType, PreviousMode, &hProcess); /* Delete the access state */ SeDeleteAccessState(&AccessState); /* Dereference the thread if we used it */ if (Thread) ObDereferenceObject(Thread); /* Dereference the Process */ ObDereferenceObject(Process); } else { /* neither an object name nor a client id was passed */ return STATUS_INVALID_PARAMETER_MIX; } /* Check for success */ if (NT_SUCCESS(Status)) { /* Use SEH for write back */ _SEH2_TRY { /* Write back the handle */ *ProcessHandle = hProcess; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { /* Get the exception code */ Status = _SEH2_GetExceptionCode(); } _SEH2_END; } /* Return status */ return Status; }