在安装一个操作系统时,绝大多数都是把引导程序安装在硬盘里,下面就来了解安装到硬盘里具体过程,实现代码如下:
#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
判断分区路径里是否存在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("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 }