在安装一个操作系统时,绝大多数都是把引导程序安装在硬盘里,下面就来了解安装到硬盘里具体过程,实现代码如下:
#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
判断分区路径里是否存在ntldr和boot.ini文件。
#015 if (DoesFileExist(SystemRootPath->Buffer, L"ntldr") == TRUE ||
#016 DoesFileExist(SystemRootPath->Buffer, L"boot.ini") == TRUE)
#017 {
如果发现NT、2000、XP的引导程序,就只需要设置选项,让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 }