zl程序教程

您现在的位置是:首页 >  系统

当前栏目

reactos操作系统实现(50)

操作系统 实现 50 reactos
2023-09-14 09:10:38 时间

 

当运行到内核函数Phase1Initialization里,就是进行内核第一阶段初始化了,这时在这个函数又调用函数Phase1InitializationDiscard进行复杂的处理,在这里有一个重要的步骤,就是打开内核应用程序smss.exe来运行。具体代码如下:

#001  /* Update progress bar */

#002      InbvUpdateProgressBar(90);

#003 

#004      /* Launch initial process */

#005      ProcessInfo = &InitBuffer->ProcessInfo;

#006      ExpLoadInitialProcess(InitBuffer, &ProcessParameters, &Environment);

#007 

#008       DPRINT1("ExpLoadInitialProcess/n");

#009 

#010      /* Update progress bar */

#011      InbvUpdateProgressBar(100);

 

上面代码就是通过调用函数ExpLoadInitialProcess来初始化一个内核应用程序运行,它的代码如下:

#001  VOID

#002  NTAPI

#003  ExpLoadInitialProcess(IN PINIT_BUFFER InitBuffer,

#004                        OUT PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,

#005                        OUT PCHAR *ProcessEnvironment)

#006  {

#007      NTSTATUS Status;

#008      ULONG Size;

#009      PWSTR p;

#010      UNICODE_STRING NullString = RTL_CONSTANT_STRING(L"");

#011      UNICODE_STRING SmssName, Environment, SystemDriveString, DebugString;

#012      PVOID EnvironmentPtr = NULL;

#013      PRTL_USER_PROCESS_INFORMATION ProcessInformation;

#014      PRTL_USER_PROCESS_PARAMETERS ProcessParams = NULL;

#015 

#016      NullString.Length = sizeof(WCHAR);

#017 

 

 

获取处理器信息。

#018      /* Use the initial buffer, after the strings */

#019      ProcessInformation = &InitBuffer->ProcessInfo;

#020 

 

给处理器参数分配内存。

#021      /* Allocate memory for the process parameters */

#022      Size = sizeof(*ProcessParams) + ((MAX_PATH * 6) * sizeof(WCHAR));

#023      Status = ZwAllocateVirtualMemory(NtCurrentProcess(),

#024                                       (PVOID*)&ProcessParams,

#025                                       0,

#026                                       &Size,

#027                                       MEM_COMMIT,

#028                                       PAGE_READWRITE);

#029      if (!NT_SUCCESS(Status))

#030      {

 

显示出错信息。

#031          /* Failed, display error */

#032          p = InitBuffer->DebugBuffer;

#033          _snwprintf(p,

#034                     256 * sizeof(WCHAR),

#035                     L"INIT: Unable to allocate Process Parameters. 0x%lx",

#036                     Status);

#037          RtlInitUnicodeString(&DebugString, p);

#038          ZwDisplayString(&DebugString);

#039 

#040          /* Bugcheck the system */

#041          KeBugCheckEx(SESSION1_INITIALIZATION_FAILED, Status, 0, 0, 0);

#042      }

#043 

 

设置处理器参数。

#044      /* Setup the basic header, and give the process the low 1MB to itself */

#045      ProcessParams->Length = Size;

#046      ProcessParams->MaximumLength = Size;

#047      ProcessParams->Flags = RTL_USER_PROCESS_PARAMETERS_NORMALIZED |

#048                             RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB;

#049 

 

分配一页作环境内存使用。

#050      /* Allocate a page for the environment */

#051      Size = PAGE_SIZE;

#052      Status = ZwAllocateVirtualMemory(NtCurrentProcess(),

#053                                       &EnvironmentPtr,

#054                                       0,

#055                                       &Size,

#056                                       MEM_COMMIT,

#057                                       PAGE_READWRITE);

#058      if (!NT_SUCCESS(Status))

#059      {

#060          /* Failed, display error */

#061          p = InitBuffer->DebugBuffer;

#062          _snwprintf(p,

#063                     256 * sizeof(WCHAR),

#064                     L"INIT: Unable to allocate Process Environment. 0x%lx",

#065                     Status);

#066          RtlInitUnicodeString(&DebugString, p);

#067          ZwDisplayString(&DebugString);

#068 

#069          /* Bugcheck the system */

#070          KeBugCheckEx(SESSION2_INITIALIZATION_FAILED, Status, 0, 0, 0);

#071      }

#072 

#073      /* Write the pointer */

#074      ProcessParams->Environment = EnvironmentPtr;

#075 

#076      /* Make a buffer for the DOS path */

#077      p = (PWSTR)(ProcessParams + 1);

#078      ProcessParams->CurrentDirectory.DosPath.Buffer = p;

#079      ProcessParams->CurrentDirectory.DosPath.MaximumLength = MAX_PATH *

#080                                                              sizeof(WCHAR);

#081 

#082      /* Copy the DOS path */

#083      RtlCopyUnicodeString(&ProcessParams->CurrentDirectory.DosPath,

#084                           &NtSystemRoot);

#085 

#086      /* Make a buffer for the DLL Path */

#087      p = (PWSTR)((PCHAR)ProcessParams->CurrentDirectory.DosPath.Buffer +

#088                  ProcessParams->CurrentDirectory.DosPath.MaximumLength);

#089      ProcessParams->DllPath.Buffer = p;

#090      ProcessParams->DllPath.MaximumLength = MAX_PATH * sizeof(WCHAR);

#091 

 

拷贝SYSTEM32的目录。

#092      /* Copy the DLL path and append the system32 directory */

#093      RtlCopyUnicodeString(&ProcessParams->DllPath,

#094                           &ProcessParams->CurrentDirectory.DosPath);

#095      RtlAppendUnicodeToString(&ProcessParams->DllPath, L"//System32");

#096 

#097      /* Make a buffer for the image name */

#098      p = (PWSTR)((PCHAR)ProcessParams->DllPath.Buffer +

#099                  ProcessParams->DllPath.MaximumLength);

#100      ProcessParams->ImagePathName.Buffer = p;

#101      ProcessParams->ImagePathName.MaximumLength = MAX_PATH * sizeof(WCHAR);

#102 

#103      /* Make sure the buffer is a valid string which within the given length */

#104      if ((NtInitialUserProcessBufferType != REG_SZ) ||

#105          ((NtInitialUserProcessBufferLength != -1U) &&

#106           ((NtInitialUserProcessBufferLength < sizeof(WCHAR)) ||

#107            (NtInitialUserProcessBufferLength >

#108             sizeof(NtInitialUserProcessBuffer) - sizeof(WCHAR)))))

#109      {

#110          /* Invalid initial process string, bugcheck */

#111          KeBugCheckEx(SESSION2_INITIALIZATION_FAILED,

#112                       STATUS_INVALID_PARAMETER,

#113                       NtInitialUserProcessBufferType,

#114                       NtInitialUserProcessBufferLength,

#115                       sizeof(NtInitialUserProcessBuffer));

#116      }

#117 

#118      /* Cut out anything after a space */

#119      p = NtInitialUserProcessBuffer;

#120      while ((*p) && (*p != L' ')) p++;

#121 

#122      /* Set the image path length */

#123      ProcessParams->ImagePathName.Length =

#124          (USHORT)((PCHAR)p - (PCHAR)NtInitialUserProcessBuffer);

#125 

#126      /* Copy the actual buffer */

#127      RtlCopyMemory(ProcessParams->ImagePathName.Buffer,

#128                    NtInitialUserProcessBuffer,

#129                    ProcessParams->ImagePathName.Length);

#130 

#131      /* Null-terminate it */

#132      ProcessParams->ImagePathName.Buffer[ProcessParams->ImagePathName.Length /

#133                                          sizeof(WCHAR)] = UNICODE_NULL;

#134 

#135      /* Make a buffer for the command line */

#136      p = (PWSTR)((PCHAR)ProcessParams->ImagePathName.Buffer +

#137                  ProcessParams->ImagePathName.MaximumLength);

#138      ProcessParams->CommandLine.Buffer = p;

#139      ProcessParams->CommandLine.MaximumLength = MAX_PATH * sizeof(WCHAR);

#140 

#141      /* Add the image name to the command line */

#142      RtlAppendUnicodeToString(&ProcessParams->CommandLine,

#143                               NtInitialUserProcessBuffer);

#144 

#145      /* Create the environment string */

#146      RtlInitEmptyUnicodeString(&Environment,

#147                                ProcessParams->Environment,

#148                                (USHORT)Size);

#149 

#150      /* Append the DLL path to it */

#151      RtlAppendUnicodeToString(&Environment, L"Path=" );

#152      RtlAppendUnicodeStringToString(&Environment, &ProcessParams->DllPath);

#153      RtlAppendUnicodeStringToString(&Environment, &NullString);

#154 

#155      /* Create the system drive string */

#156      SystemDriveString = NtSystemRoot;

#157      SystemDriveString.Length = 2 * sizeof(WCHAR);

#158 

#159      /* Append it to the environment */

#160      RtlAppendUnicodeToString(&Environment, L"SystemDrive=");

#161      RtlAppendUnicodeStringToString(&Environment, &SystemDriveString);

#162      RtlAppendUnicodeStringToString(&Environment, &NullString);

#163 

#164      /* Append the system root to the environment */

#165      RtlAppendUnicodeToString(&Environment, L"SystemRoot=");

#166      RtlAppendUnicodeStringToString(&Environment, &NtSystemRoot);

#167      RtlAppendUnicodeStringToString(&Environment, &NullString);

#168 

#169      /* Prepare the prefetcher */

#170      //CcPfBeginBootPhase(150);

#171 

 

这里加载smss.exe程序,并创建一个进程运行。当是安装的时候,已经在制作光盘时,把usetup.exe文件改名为smss.exe文件,所以这里运行的就是usetup.exe程序。

#172      /* Create SMSS process */

#173      SmssName = ProcessParams->ImagePathName;

#174      Status = RtlCreateUserProcess(&SmssName,

#175                                    OBJ_CASE_INSENSITIVE,

#176                                    RtlDeNormalizeProcessParams(ProcessParams),

#177                                    NULL,

#178                                    NULL,

#179                                    NULL,

#180                                    FALSE,

#181                                    NULL,

#182                                    NULL,

#183                                    ProcessInformation);

#184      if (!NT_SUCCESS(Status))

#185      {

#186          /* Failed, display error */

#187          p = InitBuffer->DebugBuffer;

#188          _snwprintf(p,

#189                     256 * sizeof(WCHAR),

#190                     L"INIT: Unable to create Session Manager. 0x%lx",

#191                     Status);

#192          RtlInitUnicodeString(&DebugString, p);

#193          ZwDisplayString(&DebugString);

#194 

#195          /* Bugcheck the system */

#196          KeBugCheckEx(SESSION3_INITIALIZATION_FAILED, Status, 0, 0, 0);

#197      }

#198 

#199      /* Resume the thread */

#200      Status = ZwResumeThread(ProcessInformation->ThreadHandle, NULL);

#201      if (!NT_SUCCESS(Status))

#202      {

#203          /* Failed, display error */

#204          p = InitBuffer->DebugBuffer;

#205          _snwprintf(p,

#206                     256 * sizeof(WCHAR),

#207                     L"INIT: Unable to resume Session Manager. 0x%lx",

#208                     Status);

#209          RtlInitUnicodeString(&DebugString, p);

#210          ZwDisplayString(&DebugString);

#211 

#212          /* Bugcheck the system */

#213          KeBugCheckEx(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0);

#214      }

#215 

#216      /* Return success */

#217      *ProcessParameters = ProcessParams;

#218      *ProcessEnvironment = EnvironmentPtr;

#219  }

 

通过上面的过程,就可以把usetup.exe安装程序运行起来了。结果就出现下面的界面: