@H_404_3@在安装一个操作系统时,绝大多数都是把引导程序安装在硬盘里,下面就来了解安装到硬盘里具体过程,实现代码如下:
#001@H_404_3@ static PAGE_NUMBER
#002@H_404_3@ BootLoaderHarddiskPage(PINPUT_RECORD Ir)
#003@H_404_3@ {
#004@H_404_3@ UCHAR PartitionType;
#005@H_404_3@ NTSTATUS Status;
#006@H_404_3@
@H_404_3@获取硬盘分区的类型,然后判断是否可以安装引导程序。
#007@H_404_3@ PartitionType = PartitionList->ActiveBootPartition->PartInfo[0].PartitionType;
#008@H_404_3@ if ((PartitionType == PARTITION_FAT_12) ||
#009@H_404_3@ (PartitionType == PARTITION_FAT_16) ||
#010@H_404_3@ (PartitionType == PARTITION_HUGE) ||
#011@H_404_3@ (PartitionType == PARTITION_XINT13) ||
#012@H_404_3@ (PartitionType == PARTITION_FAT32) ||
#013@H_404_3@ (PartitionType == PARTITION_FAT32_XINT13))
#014@H_404_3@ {
@H_404_3@可以安装引导程序,调用函数InstallFatBootcodeToPartition@H_404_3@实现。
#015@H_404_3@ Status = InstallFatBootcodeToPartition(&SystemRootPath,
#016@H_404_3@ &SourceRootPath,
#017@H_404_3@ @H_404_3@&DestinationArcPath,
#018@H_404_3@ PartitionType);
#019@H_404_3@ if (!NT_SUCCESS(Status))
#020@H_404_3@ {
#021@H_404_3@ MUIDisplayError(ERROR_INSTALL_BOOTCODE,Ir,POPUP_WAIT_ENTER);
#022@H_404_3@ return QUIT_PAGE;
#023@H_404_3@ }
#024@H_404_3@
#025@H_404_3@ return SUCCESS_PAGE;
#026@H_404_3@ }
#027@H_404_3@ else
#028@H_404_3@ {
#029@H_404_3@ MUIDisplayError(ERROR_WRITE_BOOT,POPUP_WAIT_ENTER);
#030@H_404_3@ return QUIT_PAGE;
#031@H_404_3@ }
#032@H_404_3@
#033 @H_404_3@return BOOT_LOADER_HARDDISK_PAGE;
#034@H_404_3@ }
@H_404_3@下面继续分析函数InstallFatBootcodeToPartition@H_404_3@的实现,如下:
#001@H_404_3@ NTSTATUS
#002@H_404_3@ InstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath,
#003@H_404_3@ @H_404_3@ @H_404_3@PUNICODE_STRING SourceRootPath,
#004@H_404_3@ @H_404_3@ @H_404_3@PUNICODE_STRING DestinationArcPath,
#005@H_404_3@ @H_404_3@ @H_404_3@UCHAR PartitionType)
#006@H_404_3@ {
#007@H_404_3@ #ifdef __REACTOS__
#008@H_404_3@ @H_404_3@ WCHAR SrcPath[MAX_PATH];
#009@H_404_3@ @H_404_3@ WCHAR DstPath[MAX_PATH];
#010@H_404_3@ @H_404_3@ NTSTATUS Status;
#011@H_404_3@
#012@H_404_3@ @H_404_3@ /* FAT or FAT32 partition */
#013@H_404_3@ @H_404_3@ DPRINT("System path: '%wZ'/n",SystemRootPath);
#014@H_404_3@
@H_404_3@判断分区路径里是否存在ntldr@H_404_3@和boot.ini@H_404_3@文件。
#015@H_404_3@ @H_404_3@ if (DoesFileExist(SystemRootPath->Buffer,L"ntldr") == TRUE ||
#016@H_404_3@ @H_404_3@ DoesFileExist(SystemRootPath->Buffer,L"boot.ini") == TRUE)
@H_404_3@如果发现NT@H_404_3@、2000@H_404_3@、XP@H_404_3@的引导程序,就只需要设置选项,让ntldr@H_404_3@来加freeldr.sys@H_404_3@程序就行了。
#018@H_404_3@ @H_404_3@ /* Search root directory for 'ntldr' and 'boot.ini'. */
#019@H_404_3@ @H_404_3@ DPRINT("Found Microsoft Windows NT/2000/XP boot loader/n");
#020@H_404_3@
#021@H_404_3@ @H_404_3@ /* Copy FreeLoader to the boot partition */
#022@H_404_3@ @H_404_3@ wcscpy(SrcPath,SourceRootPath->Buffer);
#023@H_404_3@ @H_404_3@ wcscat(SrcPath,L"//loader//freeldr.sys");
#024@H_404_3@ @H_404_3@ wcscpy(DstPath,SystemRootPath->Buffer);
#025@H_404_3@ @H_404_3@ wcscat(DstPath,L"//freeldr.sys");
#026@H_404_3@
#027@H_404_3@ @H_404_3@ DPRINT("Copy: %S ==> %S/n",SrcPath,DstPath);
#028@H_404_3@ @H_404_3@ Status = SetupCopyFile(SrcPath,DstPath);
#029 @H_404_3@@H_404_3@ if (!NT_SUCCESS(Status))
#031@H_404_3@ @H_404_3@ DPRINT1("SetupCopyFile() Failed (Status %lx)/n",Status);
#032@H_404_3@ @H_404_3@ return Status;
#034@H_404_3@
@H_404_3@更新freeldr.ini@H_404_3@文件。
#035@H_404_3@ @H_404_3@ /* Create or update freeldr.ini */
#036@H_404_3@ @H_404_3@ if (DoesFileExist(SystemRootPath->Buffer,L"freeldr.ini") == FALSE)
#038@H_404_3@ @H_404_3@ /* Create new 'freeldr.ini' */
#039@H_404_3@ @H_404_3@ DPRINT1("Create new 'freeldr.ini'/n");
#040@H_404_3@ @H_404_3@ wcscpy(DstPath,SystemRootPath->Buffer);
#041@H_404_3@ @H_404_3@ wcscat(DstPath,L"//freeldr.ini");
#042@H_404_3@
#043@H_404_3@ @H_404_3@ Status = CreateFreeLoaderIniForReactos(DstPath,
#044@H_404_3@ @H_404_3@ DestinationArcPath->Buffer);
#045@H_404_3@ @H_404_3@ if (!NT_SUCCESS(Status))
#047@H_404_3@ @H_404_3@ DPRINT1("CreateFreeLoaderIniForReactos() Failed (Status %lx)/n",Status);
#048@H_404_3@ @H_404_3@ return Status;
#050@H_404_3@
#051@H_404_3@ @H_404_3@ /* Install new bootcode */
#052@H_404_3@ @H_404_3@ if (PartitionType == PARTITION_FAT32 ||
#053@H_404_3@ @H_404_3@ PartitionType == PARTITION_FAT32_XINT13)
#055@H_404_3@ @H_404_3@ /* Install FAT32 bootcode */
#056@H_404_3@ @H_404_3@ wcscpy(SrcPath,SourceRootPath->Buffer);
#057@H_404_3@ @H_404_3@ wcscat(SrcPath,L"//loader//fat32.bin");
#058@H_404_3@ @H_404_3@ wcscpy(DstPath,SystemRootPath->Buffer);
#059@H_404_3@ @H_404_3@ wcscat(DstPath,L"//bootsect.ros");
#060@H_404_3@
#061@H_404_3@ @H_404_3@ DPRINT1("Install FAT32 bootcode: %S ==> %S/n",DstPath);
#062@H_404_3@ @H_404_3@ Status = InstallFat32BootCodeToFile(SrcPath,
#063@H_404_3@ @H_404_3@ DstPath,
#064@H_404_3@ @H_404_3@ SystemRootPath->Buffer);
#065@H_404_3@ @H_404_3@ if (!NT_SUCCESS(Status))
#067@H_404_3@ @H_404_3@ DPRINT1("InstallFat32BootCodeToFile() Failed (Status %lx)/n",Status);
#068@H_404_3@ @H_404_3@ return Status;
#073@H_404_3@ @H_404_3@ /* Install FAT16 bootcode */
#074@H_404_3@ @H_404_3@ wcscpy(SrcPath,SourceRootPath->Buffer);
#075@H_404_3@ @H_404_3@ wcscat(SrcPath,L"//loader//fat.bin");
#076@H_404_3@ @H_404_3@ wcscpy(DstPath,SystemRootPath->Buffer);
#077@H_404_3@ @H_404_3@ wcscat(DstPath,L"//bootsect.ros");
#078@H_404_3@
#079@H_404_3@ @H_404_3@ DPRINT1("Install FAT bootcode: %S ==> %S/n",DstPath);
#080@H_404_3@ @H_404_3@ Status = InstallFat16BootCodeToFile(SrcPath,
#081@H_404_3@ @H_404_3@ DstPath,
#082@H_404_3@ @H_404_3@ SystemRootPath->Buffer);
#083@H_404_3@ @H_404_3@ if (!NT_SUCCESS(Status))
#085@H_404_3@ @H_404_3@ DPRINT1("InstallFat16BootCodeToFile() Failed (Status %lx)/n",Status);
#086@H_404_3@ @H_404_3@ return Status;
#092@H_404_3@ @H_404_3@ /* Update existing 'freeldr.ini' */
#093@H_404_3@ @H_404_3@ DPRINT1("Update existing 'freeldr.ini'/n");
#094@H_404_3@ @H_404_3@ wcscpy(DstPath,SystemRootPath->Buffer);
#095@H_404_3@ @H_404_3@ wcscat(DstPath,L"//freeldr.ini");
#096@H_404_3@
#097@H_404_3@ @H_404_3@ Status = UpdateFreeLoaderIni(DstPath,
#098@H_404_3@ @H_404_3@ DestinationArcPath->Buffer);
#099@H_404_3@ @H_404_3@ if (!NT_SUCCESS(Status))
#101@H_404_3@ @H_404_3@ DPRINT1("UpdateFreeLoaderIni() Failed (Status %lx)/n",Status);
#102@H_404_3@ @H_404_3@ return Status;
#105@H_404_3@
#106@H_404_3@ @H_404_3@ /* Update 'boot.ini' */
#107@H_404_3@ @H_404_3@ wcscpy(DstPath,SystemRootPath->Buffer);
#108@H_404_3@ @H_404_3@ wcscat(DstPath,L"//boot.ini");
#109@H_404_3@
#110@H_404_3@ @H_404_3@ DPRINT1("Update 'boot.ini': %S/n",DstPath);
#111@H_404_3@ @H_404_3@ Status = UpdateBootIni(DstPath,
#112 @H_404_3@@H_404_3@ L"C://bootsect.ros",
#113 @H_404_3@@H_404_3@ L"/"ReactOS/"");
#114@H_404_3@ @H_404_3@ if (!NT_SUCCESS(Status))
#116@H_404_3@ @H_404_3@ DPRINT1("UpdateBootIni() Failed (Status %lx)/n",Status);
#117@H_404_3@ @H_404_3@ return Status;
#120@H_404_3@ @H_404_3@ else if (DoesFileExist(SystemRootPath->Buffer,L"io.sys") == TRUE ||
#121@H_404_3@ @H_404_3@ DoesFileExist(SystemRootPath->Buffer,L"msdos.sys") == TRUE)
@H_404_3@查找分区里是否有DOS@H_404_3@操作系统。
#123@H_404_3@ @H_404_3@ /* Search for root directory for 'io.sys' and 'msdos.sys'. */
#124@H_404_3@ @H_404_3@ DPRINT1("Found Microsoft DOS or Windows 9x boot loader/n");
#125@H_404_3@
#126@H_404_3@ @H_404_3@ /* Copy FreeLoader to the boot partition */
#127@H_404_3@ @H_404_3@ wcscpy(SrcPath,SourceRootPath->Buffer);
#128@H_404_3@ @H_404_3@ wcscat(SrcPath,L"//loader//freeldr.sys");
#129@H_404_3@ @H_404_3@ wcscpy(DstPath,SystemRootPath->Buffer);
#130@H_404_3@ @H_404_3@ wcscat(DstPath,L"//freeldr.sys");
#131@H_404_3@
#132@H_404_3@ @H_404_3@ DPRINT("Copy: %S ==> %S/n",DstPath);
#133@H_404_3@ @H_404_3@ Status = SetupCopyFile(SrcPath,DstPath);
#134@H_404_3@ @H_404_3@ if (!NT_SUCCESS(Status))
#136@H_404_3@ @H_404_3@ DPRINT1("SetupCopyFile() Failed (Status %lx)/n",Status);
#137@H_404_3@ @H_404_3@ return Status;
#139@H_404_3@
@H_404_3@创建并更新freeldr.ini@H_404_3@文件。
#140@H_404_3@ @H_404_3@ /* Create or update 'freeldr.ini' */
#141@H_404_3@ @H_404_3@ if (DoesFileExist(SystemRootPath->Buffer,L"freeldr.ini") == FALSE)
#143@H_404_3@ @H_404_3@ /* Create new 'freeldr.ini' */
#144@H_404_3@ @H_404_3@ DPRINT1("Create new 'freeldr.ini'/n");
#145@H_404_3@ @H_404_3@ wcscpy(DstPath,SystemRootPath->Buffer);
#146@H_404_3@ @H_404_3@ wcscat(DstPath,L"//freeldr.ini");
#147@H_404_3@
#148@H_404_3@ @H_404_3@ Status = CreateFreeLoaderIniForDos(DstPath,
#149@H_404_3@ @H_404_3@ DestinationArcPath->Buffer);
#150@H_404_3@ @H_404_3@ if (!NT_SUCCESS(Status))
#152@H_404_3@ @H_404_3@ DPRINT1("CreateFreeLoaderIniForDos() Failed (Status %lx)/n",Status);
#153@H_404_3@ @H_404_3@ return Status;
#155@H_404_3@
#156@H_404_3@ @H_404_3@ /* Save current bootsector as 'BOOTSECT.DOS' */
#157@H_404_3@ @H_404_3@ wcscpy(SrcPath,SystemRootPath->Buffer);
#158@H_404_3@ @H_404_3@ wcscpy(DstPath,SystemRootPath->Buffer);
#159@H_404_3@ @H_404_3@ wcscat(DstPath,L"//bootsect.dos");
#160@H_404_3@
#161@H_404_3@ @H_404_3@ DPRINT1("Save bootsector: %S ==> %S/n",DstPath);
#162@H_404_3@ @H_404_3@ Status = SaveCurrentBootSector(SrcPath,
#163@H_404_3@ @H_404_3@ DstPath);
#164@H_404_3@ @H_404_3@ if (!NT_SUCCESS(Status))
#166@H_404_3@ @H_404_3@ DPRINT1("SaveCurrentBootSector() Failed (Status %lx)/n",Status);
#167@H_404_3@ @H_404_3@ return Status;
#169@H_404_3@
#170@H_404_3@ @H_404_3@ /* Install new bootsector */
#171@H_404_3@ @H_404_3@ if (PartitionType == PARTITION_FAT32 ||
#172@H_404_3@ @H_404_3@ PartitionType == PARTITION_FAT32_XINT13)
#174@H_404_3@ @H_404_3@ wcscpy(SrcPath,SourceRootPath->Buffer);
#175@H_404_3@ @H_404_3@ wcscat(SrcPath,L"//loader//fat32.bin");
#176@H_404_3@
#177@H_404_3@ @H_404_3@ DPRINT1("Install FAT32 bootcode: %S ==> %S/n",SystemRootPath->Buffer);
#178@H_404_3@ @H_404_3@ Status = InstallFat32BootCodeToDisk(SrcPath,
#179@H_404_3@ @H_404_3@ SystemRootPath->Buffer);
#180@H_404_3@ @H_404_3@ if (!NT_SUCCESS(Status))
#182@H_404_3@ @H_404_3@ DPRINT1("InstallFat32BootCodeToDisk() Failed (Status %lx)/n",Status);
#183@H_404_3@ @H_404_3@ return Status;
#188@H_404_3@ @H_404_3@ wcscpy(SrcPath,SourceRootPath->Buffer);
#189@H_404_3@ @H_404_3@ wcscat(SrcPath,L"//loader//fat.bin");
#190@H_404_3@
#191@H_404_3@ @H_404_3@ DPRINT1("Install FAT bootcode: %S ==> %S/n",SystemRootPath->Buffer);
#192@H_404_3@ @H_404_3@ Status = InstallFat16BootCodeToDisk(SrcPath,
#193@H_404_3@ @H_404_3@ SystemRootPath->Buffer);
#194@H_404_3@ @H_404_3@ if (!NT_SUCCESS(Status))
#196@H_404_3@ @H_404_3@ DPRINT1("InstallFat16BootCodeToDisk() Failed (Status %lx)/n",Status);
#197@H_404_3@ @H_404_3@ return Status;
#203@H_404_3@ @H_404_3@ /* Update existing 'freeldr.ini' */
#204@H_404_3@ @H_404_3@ wcscpy(DstPath,SystemRootPath->Buffer);
#205@H_404_3@ @H_404_3@ wcscat(DstPath,L"//freeldr.ini");
#206@H_404_3@
#207@H_404_3@ @H_404_3@ Status = UpdateFreeLoaderIni(DstPath,
#208@H_404_3@ @H_404_3@ DestinationArcPath->Buffer);
#209@H_404_3@ @H_404_3@ if (!NT_SUCCESS(Status))
#211@H_404_3@ @H_404_3@ DPRINT1("UpdateFreeLoaderIni() Failed (Status %lx)/n",Status);
#212@H_404_3@ @H_404_3@ return Status;
@H_404_3@这个硬盘分区没有任何已经安装的系统。
#218@H_404_3@ @H_404_3@ /* No or unknown boot loader */
#219@H_404_3@ @H_404_3@ DPRINT1("No or unknown boot loader found/n");
#220@H_404_3@
@H_404_3@拷贝Reactos@H_404_3@的引导程序和配置文件。
#221@H_404_3@ @H_404_3@ /* Copy FreeLoader to the boot partition */
#222@H_404_3@ @H_404_3@ wcscpy(SrcPath,SourceRootPath->Buffer);
#223@H_404_3@ @H_404_3@ wcscat(SrcPath,L"//loader//freeldr.sys");
#224@H_404_3@ @H_404_3@ wcscpy(DstPath,SystemRootPath->Buffer);
#225@H_404_3@ @H_404_3@ wcscat(DstPath,L"//freeldr.sys");
#226@H_404_3@
#227@H_404_3@ @H_404_3@ DPRINT("Copy: %S ==> %S/n",DstPath);
#228@H_404_3@ @H_404_3@ Status = SetupCopyFile(SrcPath,DstPath);
#229@H_404_3@ @H_404_3@ if (!NT_SUCCESS(Status))
#231@H_404_3@ @H_404_3@ DPRINT1("SetupCopyFile() Failed (Status %lx)/n",Status);
#232@H_404_3@ @H_404_3@ return Status;
#234@H_404_3@
@H_404_3@创建和更新引导配置freeldr.ini@H_404_3@文件。
#235@H_404_3@ @H_404_3@ /* Create or update 'freeldr.ini' */
#236@H_404_3@ @H_404_3@ if (DoesFileExist(SystemRootPath->Buffer,L"freeldr.ini") == FALSE)
#238@H_404_3@ @H_404_3@ /* Create new freeldr.ini */
#239@H_404_3@ @H_404_3@ wcscpy(DstPath,SystemRootPath->Buffer);
#240@H_404_3@ @H_404_3@ wcscat(DstPath,L"//freeldr.ini");
#241@H_404_3@
#242@H_404_3@ @H_404_3@ DPRINT("Copy: %S ==> %S/n",DstPath);
#243@H_404_3@ @H_404_3@ Status = CreateFreeLoaderIniForReactos(DstPath,
#244@H_404_3@ @H_404_3@ DestinationArcPath->Buffer);
#245@H_404_3@ @H_404_3@ if (!NT_SUCCESS(Status))
#247@H_404_3@ @H_404_3@ DPRINT1("CreateFreeLoaderIniForReactos() Failed (Status %lx)/n",Status);
#248@H_404_3@ @H_404_3@ return Status;
#250@H_404_3@
@H_404_3@保存当前引导扇区代码为BOOTSECT.OLD@H_404_3@。
#251@H_404_3@ @H_404_3@ /* Save current bootsector as 'BOOTSECT.OLD' */
#252@H_404_3@ @H_404_3@ wcscpy(SrcPath,SystemRootPath->Buffer);
#253@H_404_3@ @H_404_3@ wcscpy(DstPath,SystemRootPath->Buffer);
#254@H_404_3@ @H_404_3@ wcscat(DstPath,L"//bootsect.old");
#255@H_404_3@
#256@H_404_3@ @H_404_3@ DPRINT("Save bootsector: %S ==> %S/n",DstPath);
#257@H_404_3@ @H_404_3@ Status = SaveCurrentBootSector(SrcPath,
#258@H_404_3@ @H_404_3@ DstPath);
#259@H_404_3@ @H_404_3@ if (!NT_SUCCESS(Status))
#261@H_404_3@ @H_404_3@ DPRINT1("SaveCurrentBootSector() Failed (Status %lx)/n",Status);
#262@H_404_3@ @H_404_3@ return Status;
#264@H_404_3@
#265@H_404_3@ @H_404_3@ /* Install new bootsector */
#266@H_404_3@ @H_404_3@ if (PartitionType == PARTITION_FAT32 ||
#267@H_404_3@ @H_404_3@ PartitionType == PARTITION_FAT32_XINT13)
#269@H_404_3@ @H_404_3@ wcscpy(SrcPath,SourceRootPath->Buffer);
#270@H_404_3@ @H_404_3@ wcscat(SrcPath,L"//loader//fat32.bin");
#271@H_404_3@
#272@H_404_3@ @H_404_3@ DPRINT("Install FAT32 bootcode: %S ==> %S/n",SystemRootPath->Buffer);
#273@H_404_3@ @H_404_3@ Status = InstallFat32BootCodeToDisk(SrcPath,
#274@H_404_3@ @H_404_3@ SystemRootPath->Buffer);
#275@H_404_3@ @H_404_3@ if (!NT_SUCCESS(Status))
#277@H_404_3@ @H_404_3@ DPRINT1("InstallFat32BootCodeToDisk() Failed (Status %lx)/n",Status);
#278@H_404_3@ @H_404_3@ return Status;
#283@H_404_3@ @H_404_3@ wcscpy(SrcPath,SourceRootPath->Buffer);
#284@H_404_3@ @H_404_3@ wcscat(SrcPath,L"//loader//fat.bin");
#285@H_404_3@
#286@H_404_3@ @H_404_3@ DPRINT("Install FAT bootcode: %S ==> %S/n",SystemRootPath->Buffer);
#287@H_404_3@ @H_404_3@ Status = InstallFat16BootCodeToDisk(SrcPath,
#288@H_404_3@ @H_404_3@ SystemRootPath->Buffer);
#289@H_404_3@ @H_404_3@ if (!NT_SUCCESS(Status))
#291@H_404_3@ @H_404_3@ DPRINT1("InstallFat16BootCodeToDisk() Failed (Status %lx)/n",Status);
#292@H_404_3@ @H_404_3@ return Status;
#298@H_404_3@ @H_404_3@ /* Update existing 'freeldr.ini' */
#299@H_404_3@ @H_404_3@ wcscpy(DstPath,SystemRootPath->Buffer);
#300@H_404_3@ @H_404_3@ wcscat(DstPath,L"//freeldr.ini");
#302@H_404_3@ @H_404_3@ Status = UpdateFreeLoaderIni(DstPath,
#303@H_404_3@ @H_404_3@ DestinationArcPath->Buffer);
#304@H_404_3@ @H_404_3@ if (!NT_SUCCESS(Status))
#306@H_404_3@ @H_404_3@ DPRINT1("UpdateFreeLoaderIni() Failed (Status %lx)/n",Status);
#307@H_404_3@ @H_404_3@ return Status;
#311@H_404_3@
#312@H_404_3@ @H_404_3@ return STATUS_SUCCESS;
#313@H_404_3@ #else
#314@H_404_3@ @H_404_3@ return STATUS_NOT_IMPLEMENTED;
#315@H_404_3@ #endif
#316}