zl程序教程

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

当前栏目

reactos操作系统实现(64)

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

在安装一个操作系统时,绝大多数都是把引导程序安装在硬盘里,下面就来了解安装到硬盘里具体过程,实现代码如下:

#001  static PAGE_NUMBER

#002  BootLoaderHarddiskPage(PINPUT_RECORD Ir)

#003  {

#004      UCHAR PartitionType;

#005      NTSTATUS Status;

#006 

 

获取硬盘分区的类型,然后判断是否可以安装引导程序。

#007      PartitionType = PartitionList->ActiveBootPartition->PartInfo[0].PartitionType;

#008      if ((PartitionType == PARTITION_FAT_12) ||

#009          (PartitionType == PARTITION_FAT_16) ||

#010          (PartitionType == PARTITION_HUGE) ||

#011          (PartitionType == PARTITION_XINT13) ||

#012          (PartitionType == PARTITION_FAT32) ||

#013          (PartitionType == PARTITION_FAT32_XINT13))

#014      {

 

可以安装引导程序,调用函数InstallFatBootcodeToPartition实现。

#015          Status = InstallFatBootcodeToPartition(&SystemRootPath,

#016                                                 &SourceRootPath,

#017                                                 &DestinationArcPath,

#018                                                 PartitionType);

#019          if (!NT_SUCCESS(Status))

#020          {

#021              MUIDisplayError(ERROR_INSTALL_BOOTCODE, Ir, POPUP_WAIT_ENTER);

#022              return QUIT_PAGE;

#023          }

#024 

#025          return SUCCESS_PAGE;

#026      }

#027      else

#028      {

 

如果不能安装,就提示出错。

#029          MUIDisplayError(ERROR_WRITE_BOOT, Ir, POPUP_WAIT_ENTER);

#030          return QUIT_PAGE;

#031      }

#032 

#033      return BOOT_LOADER_HARDDISK_PAGE;

#034  }

 

下面继续分析函数InstallFatBootcodeToPartition的实现,如下:

#001  NTSTATUS

#002  InstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath,

#003                           PUNICODE_STRING SourceRootPath,

#004                           PUNICODE_STRING DestinationArcPath,

#005                           UCHAR PartitionType)

#006  {

#007  #ifdef __REACTOS__

#008       WCHAR SrcPath[MAX_PATH];

#009       WCHAR DstPath[MAX_PATH];

#010       NTSTATUS Status;

#011 

#012       /* FAT or FAT32 partition */

#013       DPRINT("System path: '%wZ'/n", SystemRootPath);

#014 

 

判断分区路径里是否存在ntldrboot.ini文件。

#015       if (DoesFileExist(SystemRootPath->Buffer, L"ntldr") == TRUE ||

#016              DoesFileExist(SystemRootPath->Buffer, L"boot.ini") == TRUE)

#017       {

 

如果发现NT2000XP的引导程序,就只需要设置选项,让ntldr来加freeldr.sys程序就行了。

#018              /* Search root directory for 'ntldr' and 'boot.ini'. */

#019              DPRINT("Found Microsoft Windows NT/2000/XP boot loader/n");

#020 

#021              /* Copy FreeLoader to the boot partition */

#022              wcscpy(SrcPath, SourceRootPath->Buffer);

#023              wcscat(SrcPath, L"//loader//freeldr.sys");

#024              wcscpy(DstPath, SystemRootPath->Buffer);

#025              wcscat(DstPath, L"//freeldr.sys");

#026 

 

这里开始拷贝文件。

#027              DPRINT("Copy: %S ==> %S/n", SrcPath, DstPath);

#028              Status = SetupCopyFile(SrcPath, DstPath);

#029              if (!NT_SUCCESS(Status))

#030              {

#031                     DPRINT1("SetupCopyFile() failed (Status %lx)/n", Status);

#032                     return Status;

#033              }

#034 

 

更新freeldr.ini文件。

#035              /* Create or update freeldr.ini */

#036              if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE)

#037              {

#038                     /* Create new 'freeldr.ini' */

#039                     DPRINT1("Create new 'freeldr.ini'/n");

#040                     wcscpy(DstPath, SystemRootPath->Buffer);

#041                     wcscat(DstPath, L"//freeldr.ini");

#042 

#043                     Status = CreateFreeLoaderIniForReactos(DstPath,

#044                            DestinationArcPath->Buffer);

#045                     if (!NT_SUCCESS(Status))

#046                     {

#047                            DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)/n", Status);

#048                            return Status;

#049                     }

#050 

 

安装新的引导代码到引导扇区。

#051                     /* Install new bootcode */

#052                     if (PartitionType == PARTITION_FAT32 ||

#053                            PartitionType == PARTITION_FAT32_XINT13)

#054                     {

#055                            /* Install FAT32 bootcode */

#056                            wcscpy(SrcPath, SourceRootPath->Buffer);

#057                            wcscat(SrcPath, L"//loader//fat32.bin");

#058                            wcscpy(DstPath, SystemRootPath->Buffer);

#059                            wcscat(DstPath, L"//bootsect.ros");

#060 

#061                            DPRINT1("Install FAT32 bootcode: %S ==> %S/n", SrcPath, DstPath);

#062                            Status = InstallFat32BootCodeToFile(SrcPath,

#063                                   DstPath,

#064                                   SystemRootPath->Buffer);

#065                            if (!NT_SUCCESS(Status))

#066                            {

#067                                   DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)/n", Status);

#068                                   return Status;

#069                            }

#070                     }

#071                     else

#072                     {

#073                            /* Install FAT16 bootcode */

#074                            wcscpy(SrcPath, SourceRootPath->Buffer);

#075                            wcscat(SrcPath, L"//loader//fat.bin");

#076                            wcscpy(DstPath, SystemRootPath->Buffer);

#077                            wcscat(DstPath, L"//bootsect.ros");

#078 

#079                            DPRINT1("Install FAT bootcode: %S ==> %S/n", SrcPath, DstPath);

#080                            Status = InstallFat16BootCodeToFile(SrcPath,

#081                                   DstPath,

#082                                   SystemRootPath->Buffer);

#083                            if (!NT_SUCCESS(Status))

#084                            {

#085                                   DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)/n", Status);

#086                                   return Status;

#087                            }

#088                     }

#089              }

#090              else

#091              {

#092                     /* Update existing 'freeldr.ini' */

#093                     DPRINT1("Update existing 'freeldr.ini'/n");

#094                     wcscpy(DstPath, SystemRootPath->Buffer);

#095                     wcscat(DstPath, L"//freeldr.ini");

#096 

#097                     Status = UpdateFreeLoaderIni(DstPath,

#098                            DestinationArcPath->Buffer);

#099                     if (!NT_SUCCESS(Status))

#100                     {

#101                            DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)/n", Status);

#102                            return Status;

#103                     }

#104              }

#105 

#106              /* Update 'boot.ini' */

#107              wcscpy(DstPath, SystemRootPath->Buffer);

#108              wcscat(DstPath, L"//boot.ini");

#109 

#110              DPRINT1("Update 'boot.ini': %S/n", DstPath);

#111              Status = UpdateBootIni(DstPath,

#112                     L"C://bootsect.ros",

#113                     L"/"ReactOS/"");

#114              if (!NT_SUCCESS(Status))

#115              {

#116                     DPRINT1("UpdateBootIni() failed (Status %lx)/n", Status);

#117                     return Status;

#118              }

#119       }

#120       else if (DoesFileExist(SystemRootPath->Buffer, L"io.sys") == TRUE ||

#121              DoesFileExist(SystemRootPath->Buffer, L"msdos.sys") == TRUE)

#122       {

 

查找分区里是否有DOS操作系统。

#123              /* Search for root directory for 'io.sys' and 'msdos.sys'. */

#124              DPRINT1("Found Microsoft DOS or Windows 9x boot loader/n");

#125 

#126              /* Copy FreeLoader to the boot partition */

#127              wcscpy(SrcPath, SourceRootPath->Buffer);

#128              wcscat(SrcPath, L"//loader//freeldr.sys");

#129              wcscpy(DstPath, SystemRootPath->Buffer);

#130              wcscat(DstPath, L"//freeldr.sys");

#131 

 

拷贝文件。

#132              DPRINT("Copy: %S ==> %S/n", SrcPath, DstPath);

#133              Status = SetupCopyFile(SrcPath, DstPath);

#134              if (!NT_SUCCESS(Status))

#135              {

#136                     DPRINT1("SetupCopyFile() failed (Status %lx)/n", Status);

#137                     return Status;

#138              }

#139 

 

创建并更新freeldr.ini文件。

#140              /* Create or update 'freeldr.ini' */

#141              if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE)

#142              {

#143                     /* Create new 'freeldr.ini' */

#144                     DPRINT1("Create new 'freeldr.ini'/n");

#145                     wcscpy(DstPath, SystemRootPath->Buffer);

#146                     wcscat(DstPath, L"//freeldr.ini");

#147 

#148                     Status = CreateFreeLoaderIniForDos(DstPath,

#149                            DestinationArcPath->Buffer);

#150                     if (!NT_SUCCESS(Status))

#151                     {

#152                            DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)/n", Status);

#153                            return Status;

#154                     }

#155 

#156                     /* Save current bootsector as 'BOOTSECT.DOS' */

#157                     wcscpy(SrcPath, SystemRootPath->Buffer);

#158                     wcscpy(DstPath, SystemRootPath->Buffer);

#159                     wcscat(DstPath, L"//bootsect.dos");

#160 

#161                     DPRINT1("Save bootsector: %S ==> %S/n", SrcPath, DstPath);

#162                     Status = SaveCurrentBootSector(SrcPath,

#163                            DstPath);

#164                     if (!NT_SUCCESS(Status))

#165                     {

#166                            DPRINT1("SaveCurrentBootSector() failed (Status %lx)/n", Status);

#167                            return Status;

#168                     }

#169 

#170                     /* Install new bootsector */

#171                     if (PartitionType == PARTITION_FAT32 ||

#172                            PartitionType == PARTITION_FAT32_XINT13)

#173                     {

#174                            wcscpy(SrcPath, SourceRootPath->Buffer);

#175                            wcscat(SrcPath, L"//loader//fat32.bin");

#176 

#177                            DPRINT1("Install FAT32 bootcode: %S ==> %S/n", SrcPath, SystemRootPath->Buffer);

#178                            Status = InstallFat32BootCodeToDisk(SrcPath,

#179                                   SystemRootPath->Buffer);

#180                            if (!NT_SUCCESS(Status))

#181                            {

#182                                   DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)/n", Status);

#183                                   return Status;

#184                            }

#185                     }

#186                     else

#187                     {

#188                            wcscpy(SrcPath, SourceRootPath->Buffer);

#189                            wcscat(SrcPath, L"//loader//fat.bin");

#190 

#191                            DPRINT1("Install FAT bootcode: %S ==> %S/n", SrcPath, SystemRootPath->Buffer);

#192                            Status = InstallFat16BootCodeToDisk(SrcPath,

#193                                   SystemRootPath->Buffer);

#194                            if (!NT_SUCCESS(Status))

#195                            {

#196                                   DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)/n", Status);

#197                                   return Status;

#198                            }

#199                     }

#200              }

#201              else

#202              {

#203                     /* Update existing 'freeldr.ini' */

#204                     wcscpy(DstPath, SystemRootPath->Buffer);

#205                     wcscat(DstPath, L"//freeldr.ini");

#206 

#207                     Status = UpdateFreeLoaderIni(DstPath,

#208                            DestinationArcPath->Buffer);

#209                     if (!NT_SUCCESS(Status))

#210                     {

#211                            DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)/n", Status);

#212                            return Status;

#213                     }

#214              }

#215       }

#216       else

#217       {

 

这个硬盘分区没有任何已经安装的系统。

#218              /* No or unknown boot loader */

#219              DPRINT1("No or unknown boot loader found/n");

#220 

 

拷贝Reactos的引导程序和配置文件。

#221              /* Copy FreeLoader to the boot partition */

#222              wcscpy(SrcPath, SourceRootPath->Buffer);

#223              wcscat(SrcPath, L"//loader//freeldr.sys");

#224              wcscpy(DstPath, SystemRootPath->Buffer);

#225              wcscat(DstPath, L"//freeldr.sys");

#226 

#227              DPRINT("Copy: %S ==> %S/n", SrcPath, DstPath);

#228              Status = SetupCopyFile(SrcPath, DstPath);

#229              if (!NT_SUCCESS(Status))

#230              {

#231                     DPRINT1("SetupCopyFile() failed (Status %lx)/n", Status);

#232                     return Status;

#233              }

#234 

 

创建和更新引导配置freeldr.ini文件。

#235              /* Create or update 'freeldr.ini' */

#236              if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE)

#237              {

#238                     /* Create new freeldr.ini */

#239                     wcscpy(DstPath, SystemRootPath->Buffer);

#240                     wcscat(DstPath, L"//freeldr.ini");

#241 

#242                     DPRINT("Copy: %S ==> %S/n", SrcPath, DstPath);

#243                     Status = CreateFreeLoaderIniForReactos(DstPath,

#244                            DestinationArcPath->Buffer);

#245                     if (!NT_SUCCESS(Status))

#246                     {

#247                            DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)/n", Status);

#248                            return Status;

#249                     }

#250 

 

保存当前引导扇区代码为BOOTSECT.OLD

#251                     /* Save current bootsector as 'BOOTSECT.OLD' */

#252                     wcscpy(SrcPath, SystemRootPath->Buffer);

#253                     wcscpy(DstPath, SystemRootPath->Buffer);

#254                     wcscat(DstPath, L"//bootsect.old");

#255 

#256                     DPRINT("Save bootsector: %S ==> %S/n", SrcPath, DstPath);

#257                     Status = SaveCurrentBootSector(SrcPath,

#258                            DstPath);

#259                     if (!NT_SUCCESS(Status))

#260                     {

#261                            DPRINT1("SaveCurrentBootSector() failed (Status %lx)/n", Status);

#262                            return Status;

#263                     }

#264 

 

安装新的引导扇区代码硬盘分区。

#265                     /* Install new bootsector */

#266                     if (PartitionType == PARTITION_FAT32 ||

#267                            PartitionType == PARTITION_FAT32_XINT13)

#268                     {

#269                            wcscpy(SrcPath, SourceRootPath->Buffer);

#270                            wcscat(SrcPath, L"//loader//fat32.bin");

#271 

#272                            DPRINT("Install FAT32 bootcode: %S ==> %S/n", SrcPath, SystemRootPath->Buffer);

#273                            Status = InstallFat32BootCodeToDisk(SrcPath,

#274                                   SystemRootPath->Buffer);

#275                            if (!NT_SUCCESS(Status))

#276                            {

#277                                   DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)/n", Status);

#278                                   return Status;

#279                            }

#280                     }

#281                     else

#282                     {

#283                            wcscpy(SrcPath, SourceRootPath->Buffer);

#284                            wcscat(SrcPath, L"//loader//fat.bin");

#285 

#286                            DPRINT("Install FAT bootcode: %S ==> %S/n", SrcPath, SystemRootPath->Buffer);

#287                            Status = InstallFat16BootCodeToDisk(SrcPath,

#288                                   SystemRootPath->Buffer);

#289                            if (!NT_SUCCESS(Status))

#290                            {

#291                                   DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)/n", Status);

#292                                   return Status;

#293                            }

#294                     }

#295              }

#296              else

#297              {

#298                     /* Update existing 'freeldr.ini' */

#299                     wcscpy(DstPath, SystemRootPath->Buffer);

#300                     wcscat(DstPath, L"//freeldr.ini");

#301 

#302                     Status = UpdateFreeLoaderIni(DstPath,

#303                            DestinationArcPath->Buffer);

#304                     if (!NT_SUCCESS(Status))

#305                     {

#306                            DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)/n", Status);

#307                            return Status;

#308                     }

#309              }

#310       }

#311 

#312       return STATUS_SUCCESS;

#313  #else

#314       return STATUS_NOT_IMPLEMENTED;

#315  #endif

#316  }