reactos操作系统实现(36)

前面分析了进程管理器的初始化工作,主要就是把进程管理器的列表、对象初始化,还有第一和第二阶段的初始化工作。接着下来,我们来分析一下进程创建函数,看看进程在Reactos里是怎么样创建的,需要调用什么函数来创建进程,还有应用程序是怎么样调用API函数来创建进程的。

可以从前面分析的代码里,看到创建第二个进程代码如下:

#196      Status = PsCreateSystemThread(&SysThreadHandle,

#197                                    THREAD_ALL_ACCESS,

#198                                    &ObjectAttributes,

#199                                    0,

#200                                    NULL,

#201                                    Phase1Initialization,

#202                                    LoaderBlock);

#203      if (!NT_SUCCESS(Status)) return FALSE;

 

这里调用函数PsCreateSystemThread来创建进程,它的代码如下:

#001  NTSTATUS

#002  NTAPI

#003  PspCreateProcess(OUT PHANDLE ProcessHandle,

#004                   IN ACCESS_MASK DesiredAccess,

#005                   IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,

#006                   IN HANDLE ParentProcess OPTIONAL,

#007                   IN ULONG Flags,

#008                   IN HANDLE SectionHandle OPTIONAL,

#009                   IN HANDLE DebugPort OPTIONAL,

#010                   IN HANDLE ExceptionPort OPTIONAL,

#011                   IN BOOLEAN InJob)

#012  {

这个函数的参数:

ProcessHandle创建进程输出的句柄。

DesiredAccess访问进程权限。

ObjectAttributes是进程对象属性。

ParentProcess是父进程的句柄。

Flags是创建进程标志。

SectionHandle是段句柄。

DebugPort是调试输出端口。

ExceptionPort是异常输出端口。

InJob是工作集标志。

 

 

#013      HANDLE hProcess;

#014      PEPROCESS Process, Parent;

#015      PVOID ExceptionPortObject;

#016      PDEBUG_OBJECT DebugObject;

#017      PSECTION_OBJECT SectionObject;

#018      NTSTATUS Status, AccessStatus;

#019      ULONG DirectoryTableBase[2] = {0,0};

#020      KAFFINITY Affinity;

#021      HANDLE_TABLE_ENTRY CidEntry;

#022      PETHREAD CurrentThread = PsGetCurrentThread();

#023      KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();

#024      PEPROCESS CurrentProcess = PsGetCurrentProcess();

#025      ULONG MinWs, MaxWs;

#026      ACCESS_STATE LocalAccessState;

#027      PACCESS_STATE AccessState = &LocalAccessState;

#028      AUX_ACCESS_DATA AuxData;

#029      UCHAR Quantum;

#030      BOOLEAN Result, SdAllocated;

#031      PSECURITY_DESCRIPTOR SecurityDescriptor;

#032      SECURITY_SUBJECT_CONTEXT SubjectContext;

 

下面判断是否能调用内核代码。

#033      PAGED_CODE();

#034      PSTRACE(PS_PROCESS_DEBUG,

#035              "ProcessHandle: %p Parent: %p/n", ProcessHandle, ParentProcess);

#036 

 

检查调用标志。

#037      /* Validate flags */

#038      if (Flags & ~PS_ALL_FLAGS) return STATUS_INVALID_PARAMETER;

#039 

 

检查是否有父进程。

#040      /* Check for parent */

#041      if (ParentProcess)

#042      {

 

如果有父进程,就要增加父进程的引用计数。

#043          /* Reference it */

#044          Status = ObReferenceObjectByHandle(ParentProcess,

#045                                             PROCESS_CREATE_PROCESS,

#046                                             PsProcessType,

#047                                             PreviousMode,

#048                                             (PVOID*)&Parent,

#049                                             NULL);

#050          if (!NT_SUCCESS(Status)) return Status;

#051 

 

如果创建进程要求是工作集的,但它的父进程不是,就出错。

#052          /* If this process should be in a job but the parent isn't */

#053          if ((InJob) && (!Parent->Job))

#054          {

#055              /* This is illegal. Dereference the parent and fail */

#056              ObDereferenceObject(Parent);

#057              return STATUS_INVALID_PARAMETER;

#058          }

#059 

 

继承父进程的特性。

#060          /* Inherit Parent process's Affinity. */

#061          Affinity = Parent->Pcb.Affinity;

#062      }

#063      else

#064      {

 

否则是没有父进程的。

#065          /* We have no parent */

#066          Parent = NULL;

#067          Affinity = KeActiveProcessors;

#068      }

#069 

你可能感兴趣的:(object,Access,reference,Descriptor,attributes,initialization)