reactos操作系统实现(64)

时间:2021-01-28 14:27:23

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

#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_STRINGSystemRootPath,

#003                           PUNICODE_STRING SourceRootPath,

#004                           PUNICODE_STRING DestinationArcPath,

#005                           UCHAR PartitionType)

#006  {

#007  #ifdef __REACTOS__

#008       WCHARSrcPath[MAX_PATH];

#009       WCHARDstPath[MAX_PATH];

#010       NTSTATUSStatus;

#011 

#012       /*FAT or FAT32 partition */

#013       DPRINT("Systempath: '%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("FoundMicrosoft 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                     returnStatus;

#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("Createnew '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                            returnStatus;

#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("InstallFAT32 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                                   returnStatus;

#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("InstallFAT 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                                   returnStatus;

#087                            }

#088                     }

#089              }

#090              else

#091              {

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

#093                     DPRINT1("Updateexisting '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                            returnStatus;

#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                     returnStatus;

#118              }

#119       }

#120       elseif (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("FoundMicrosoft 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                     returnStatus;

#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("Createnew '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                            returnStatus;

#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("Savebootsector: %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                            returnStatus;

#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("InstallFAT32 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                                   returnStatus;

#184                            }

#185                     }

#186                     else

#187                     {

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

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

#190 

#191                            DPRINT1("InstallFAT 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                                   returnStatus;

#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                            returnStatus;

#213                     }

#214              }

#215       }

#216       else

#217       {

 

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

#218              /*No or unknown boot loader */

#219              DPRINT1("Noor 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                     returnStatus;

#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                            returnStatus;

#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("Savebootsector: %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                            returnStatus;

#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("InstallFAT32 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                                   returnStatus;

#279                            }

#280                     }

#281                     else

#282                     {

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

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

#285 

#286                            DPRINT("InstallFAT 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                                   returnStatus;

#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                            returnStatus;

#308                     }

#309              }

#310       }

#311 

#312       returnSTATUS_SUCCESS;

#313  #else

#314       returnSTATUS_NOT_IMPLEMENTED;

#315  #endif

#316  }