Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbootsup.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS text-mode setup 00004 * FILE: subsys/system/usetup/bootsup.c 00005 * PURPOSE: Bootloader support functions 00006 * PROGRAMMER: Eric Kohl 00007 */ 00008 00009 #include "usetup.h" 00010 00011 #define NDEBUG 00012 #include <debug.h> 00013 00014 #define SECTORSIZE 512 00015 00016 #include <pshpack1.h> 00017 typedef struct _FAT_BOOTSECTOR 00018 { 00019 UCHAR JumpBoot[3]; // Jump instruction to boot code 00020 CHAR OemName[8]; // "MSWIN4.1" for MS formatted volumes 00021 USHORT BytesPerSector; // Bytes per sector 00022 UCHAR SectorsPerCluster; // Number of sectors in a cluster 00023 USHORT ReservedSectors; // Reserved sectors, usually 1 (the bootsector) 00024 UCHAR NumberOfFats; // Number of FAT tables 00025 USHORT RootDirEntries; // Number of root directory entries (fat12/16) 00026 USHORT TotalSectors; // Number of total sectors on the drive, 16-bit 00027 UCHAR MediaDescriptor; // Media descriptor byte 00028 USHORT SectorsPerFat; // Sectors per FAT table (fat12/16) 00029 USHORT SectorsPerTrack; // Number of sectors in a track 00030 USHORT NumberOfHeads; // Number of heads on the disk 00031 ULONG HiddenSectors; // Hidden sectors (sectors before the partition start like the partition table) 00032 ULONG TotalSectorsBig; // This field is the new 32-bit total count of sectors on the volume 00033 UCHAR DriveNumber; // Int 0x13 drive number (e.g. 0x80) 00034 UCHAR Reserved1; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0. 00035 UCHAR BootSignature; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present. 00036 ULONG VolumeSerialNumber; // Volume serial number 00037 CHAR VolumeLabel[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory 00038 CHAR FileSystemType[8]; // One of the strings "FAT12 ", "FAT16 ", or "FAT " 00039 00040 UCHAR BootCodeAndData[448]; // The remainder of the boot sector 00041 00042 USHORT BootSectorMagic; // 0xAA55 00043 00044 } FAT_BOOTSECTOR, *PFAT_BOOTSECTOR; 00045 00046 typedef struct _FAT32_BOOTSECTOR 00047 { 00048 UCHAR JumpBoot[3]; // Jump instruction to boot code 00049 CHAR OemName[8]; // "MSWIN4.1" for MS formatted volumes 00050 USHORT BytesPerSector; // Bytes per sector 00051 UCHAR SectorsPerCluster; // Number of sectors in a cluster 00052 USHORT ReservedSectors; // Reserved sectors, usually 1 (the bootsector) 00053 UCHAR NumberOfFats; // Number of FAT tables 00054 USHORT RootDirEntries; // Number of root directory entries (fat12/16) 00055 USHORT TotalSectors; // Number of total sectors on the drive, 16-bit 00056 UCHAR MediaDescriptor; // Media descriptor byte 00057 USHORT SectorsPerFat; // Sectors per FAT table (fat12/16) 00058 USHORT SectorsPerTrack; // Number of sectors in a track 00059 USHORT NumberOfHeads; // Number of heads on the disk 00060 ULONG HiddenSectors; // Hidden sectors (sectors before the partition start like the partition table) 00061 ULONG TotalSectorsBig; // This field is the new 32-bit total count of sectors on the volume 00062 ULONG SectorsPerFatBig; // This field is the FAT32 32-bit count of sectors occupied by ONE FAT. BPB_FATSz16 must be 0 00063 USHORT ExtendedFlags; // Extended flags (fat32) 00064 USHORT FileSystemVersion; // File system version (fat32) 00065 ULONG RootDirStartCluster; // Starting cluster of the root directory (fat32) 00066 USHORT FsInfo; // Sector number of FSINFO structure in the reserved area of the FAT32 volume. Usually 1. 00067 USHORT BackupBootSector; // If non-zero, indicates the sector number in the reserved area of the volume of a copy of the boot record. Usually 6. 00068 UCHAR Reserved[12]; // Reserved for future expansion 00069 UCHAR DriveNumber; // Int 0x13 drive number (e.g. 0x80) 00070 UCHAR Reserved1; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0. 00071 UCHAR BootSignature; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present. 00072 ULONG VolumeSerialNumber; // Volume serial number 00073 CHAR VolumeLabel[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory 00074 CHAR FileSystemType[8]; // Always set to the string "FAT32 " 00075 00076 UCHAR BootCodeAndData[420]; // The remainder of the boot sector 00077 00078 USHORT BootSectorMagic; // 0xAA55 00079 00080 } FAT32_BOOTSECTOR, *PFAT32_BOOTSECTOR; 00081 #include <poppack.h> 00082 00083 extern PPARTLIST PartitionList; 00084 00085 /* FUNCTIONS ****************************************************************/ 00086 00087 00088 static 00089 VOID 00090 CreateCommonFreeLoaderSections(PINICACHE IniCache) 00091 { 00092 PINICACHESECTION IniSection; 00093 00094 /* Create "FREELOADER" section */ 00095 IniSection = IniCacheAppendSection(IniCache, 00096 L"FREELOADER"); 00097 00098 #if DBG 00099 if (IsUnattendedSetup) 00100 { 00101 /* DefaultOS=ReactOS */ 00102 IniCacheInsertKey(IniSection, 00103 NULL, 00104 INSERT_LAST, 00105 L"DefaultOS", 00106 #ifndef _WINKD_ 00107 L"ReactOS_KdSerial"); 00108 #else 00109 L"ReactOS_Debug"); 00110 #endif 00111 } 00112 else 00113 #endif 00114 { 00115 /* DefaultOS=ReactOS */ 00116 IniCacheInsertKey(IniSection, 00117 NULL, 00118 INSERT_LAST, 00119 L"DefaultOS", 00120 L"ReactOS"); 00121 } 00122 00123 #if DBG 00124 if (IsUnattendedSetup) 00125 #endif 00126 { 00127 /* Timeout=0 for unattended or non debug*/ 00128 IniCacheInsertKey(IniSection, 00129 NULL, 00130 INSERT_LAST, 00131 L"TimeOut", 00132 L"0"); 00133 } 00134 #if DBG 00135 else 00136 { 00137 /* Timeout=0 or 10 */ 00138 IniCacheInsertKey(IniSection, 00139 NULL, 00140 INSERT_LAST, 00141 L"TimeOut", 00142 L"10"); 00143 } 00144 #endif 00145 00146 /* Create "Display" section */ 00147 IniSection = IniCacheAppendSection(IniCache, L"Display"); 00148 00149 /* TitleText=ReactOS Boot Manager */ 00150 IniCacheInsertKey(IniSection, 00151 NULL, 00152 INSERT_LAST, 00153 L"TitleText", 00154 L"ReactOS Boot Manager"); 00155 00156 /* StatusBarColor=Cyan */ 00157 IniCacheInsertKey(IniSection, 00158 NULL, 00159 INSERT_LAST, 00160 L"StatusBarColor", 00161 L"Cyan"); 00162 00163 /* StatusBarTextColor=Black */ 00164 IniCacheInsertKey(IniSection, 00165 NULL, 00166 INSERT_LAST, 00167 L"StatusBarTextColor", 00168 L"Black"); 00169 00170 /* BackdropTextColor=White */ 00171 IniCacheInsertKey(IniSection, 00172 NULL, 00173 INSERT_LAST, 00174 L"BackdropTextColor", 00175 L"White"); 00176 00177 /* BackdropColor=Blue */ 00178 IniCacheInsertKey(IniSection, 00179 NULL, 00180 INSERT_LAST, 00181 L"BackdropColor", 00182 L"Blue"); 00183 00184 /* BackdropFillStyle=Medium */ 00185 IniCacheInsertKey(IniSection, 00186 NULL, 00187 INSERT_LAST, 00188 L"BackdropFillStyle", 00189 L"Medium"); 00190 00191 /* TitleBoxTextColor=White */ 00192 IniCacheInsertKey(IniSection, 00193 NULL, 00194 INSERT_LAST, 00195 L"TitleBoxTextColor", 00196 L"White"); 00197 00198 /* TitleBoxColor=Red */ 00199 IniCacheInsertKey(IniSection, 00200 NULL, 00201 INSERT_LAST, 00202 L"TitleBoxColor", 00203 L"Red"); 00204 00205 /* MessageBoxTextColor=White */ 00206 IniCacheInsertKey(IniSection, 00207 NULL, 00208 INSERT_LAST, 00209 L"MessageBoxTextColor", 00210 L"White"); 00211 00212 /* MessageBoxColor=Blue */ 00213 IniCacheInsertKey(IniSection, 00214 NULL, 00215 INSERT_LAST, 00216 L"MessageBoxColor", 00217 L"Blue"); 00218 00219 /* MenuTextColor=White */ 00220 IniCacheInsertKey(IniSection, 00221 NULL, 00222 INSERT_LAST, 00223 L"MenuTextColor", 00224 L"Gray"); 00225 00226 /* MenuColor=Blue */ 00227 IniCacheInsertKey(IniSection, 00228 NULL, 00229 INSERT_LAST, 00230 L"MenuColor", 00231 L"Black"); 00232 00233 /* TextColor=Yellow */ 00234 IniCacheInsertKey(IniSection, 00235 NULL, 00236 INSERT_LAST, 00237 L"TextColor", 00238 L"Gray"); 00239 00240 /* SelectedTextColor=Black */ 00241 IniCacheInsertKey(IniSection, 00242 NULL, 00243 INSERT_LAST, 00244 L"SelectedTextColor", 00245 L"Black"); 00246 00247 /* SelectedColor=Gray */ 00248 IniCacheInsertKey(IniSection, 00249 NULL, 00250 INSERT_LAST, 00251 L"SelectedColor", 00252 L"Gray"); 00253 00254 /* SelectedColor=Gray */ 00255 IniCacheInsertKey(IniSection, 00256 NULL, 00257 INSERT_LAST, 00258 L"ShowTime", 00259 L"No"); 00260 00261 /* SelectedColor=Gray */ 00262 IniCacheInsertKey(IniSection, 00263 NULL, 00264 INSERT_LAST, 00265 L"MenuBox", 00266 L"No"); 00267 00268 /* SelectedColor=Gray */ 00269 IniCacheInsertKey(IniSection, 00270 NULL, 00271 INSERT_LAST, 00272 L"CenterMenu", 00273 L"No"); 00274 00275 /* SelectedColor=Gray */ 00276 IniCacheInsertKey(IniSection, 00277 NULL, 00278 INSERT_LAST, 00279 L"MinimalUI", 00280 L"Yes"); 00281 00282 /* SelectedColor=Gray */ 00283 IniCacheInsertKey(IniSection, 00284 NULL, 00285 INSERT_LAST, 00286 L"TimeText", 00287 L"Seconds until highlighted choice will be started automatically: "); 00288 } 00289 00290 00291 NTSTATUS 00292 CreateFreeLoaderIniForDos( 00293 PWCHAR IniPath, 00294 PWCHAR ArcPath) 00295 { 00296 PINICACHE IniCache; 00297 PINICACHESECTION IniSection; 00298 00299 IniCache = IniCacheCreate(); 00300 00301 CreateCommonFreeLoaderSections(IniCache); 00302 00303 /* Create "Operating Systems" section */ 00304 IniSection = IniCacheAppendSection(IniCache, L"Operating Systems"); 00305 00306 /* REACTOS=ReactOS */ 00307 IniCacheInsertKey(IniSection, 00308 NULL, 00309 INSERT_LAST, 00310 L"ReactOS", 00311 L"\"ReactOS\""); 00312 00313 /* ReactOS_Debug="ReactOS (Debug)" */ 00314 IniCacheInsertKey(IniSection, 00315 NULL, 00316 INSERT_LAST, 00317 L"ReactOS_Debug", 00318 L"\"ReactOS (Debug)\""); 00319 00320 /* DOS=Dos/Windows */ 00321 IniCacheInsertKey(IniSection, 00322 NULL, 00323 INSERT_LAST, 00324 L"DOS", 00325 L"\"DOS/Windows\""); 00326 00327 /* Create "ReactOS" section */ 00328 IniSection = IniCacheAppendSection(IniCache, L"ReactOS"); 00329 00330 /* BootType=ReactOS */ 00331 IniCacheInsertKey(IniSection, 00332 NULL, 00333 INSERT_LAST, 00334 L"BootType", 00335 L"ReactOS"); 00336 00337 /* SystemPath=<ArcPath> */ 00338 IniCacheInsertKey(IniSection, 00339 NULL, 00340 INSERT_LAST, 00341 L"SystemPath", 00342 ArcPath); 00343 00344 /* Create "ReactOS_Debug" section */ 00345 IniSection = IniCacheAppendSection(IniCache, L"ReactOS_Debug"); 00346 00347 /* BootType=ReactOS */ 00348 IniCacheInsertKey(IniSection, 00349 NULL, 00350 INSERT_LAST, 00351 L"BootType", 00352 L"ReactOS"); 00353 00354 /* SystemPath=<ArcPath> */ 00355 IniCacheInsertKey(IniSection, 00356 NULL, 00357 INSERT_LAST, 00358 L"SystemPath", 00359 ArcPath); 00360 00361 /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS */ 00362 IniCacheInsertKey(IniSection, 00363 NULL, 00364 INSERT_LAST, 00365 L"Options", 00366 L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS"); 00367 00368 /* Create "DOS" section */ 00369 IniSection = IniCacheAppendSection(IniCache, 00370 L"DOS"); 00371 00372 /* BootType=BootSector */ 00373 IniCacheInsertKey(IniSection, 00374 NULL, 00375 INSERT_LAST, 00376 L"BootType", 00377 L"BootSector"); 00378 00379 /* BootDrive=hd0 */ 00380 IniCacheInsertKey(IniSection, 00381 NULL, 00382 INSERT_LAST, 00383 L"BootDrive", 00384 L"hd0"); 00385 00386 /* BootPartition=1 */ 00387 IniCacheInsertKey(IniSection, 00388 NULL, 00389 INSERT_LAST, 00390 L"BootPartition", 00391 L"1"); 00392 00393 /* BootSector=BOOTSECT.DOS */ 00394 IniCacheInsertKey(IniSection, 00395 NULL, 00396 INSERT_LAST, 00397 L"BootSectorFile", 00398 L"BOOTSECT.DOS"); 00399 00400 IniCacheSave(IniCache, IniPath); 00401 IniCacheDestroy(IniCache); 00402 00403 return STATUS_SUCCESS; 00404 } 00405 00406 00407 NTSTATUS 00408 CreateFreeLoaderEntry( 00409 PINICACHE IniCache, 00410 PINICACHESECTION OSSection, 00411 PWCHAR Section, 00412 PWCHAR Description, 00413 PWCHAR BootType, 00414 PWCHAR ArcPath, 00415 PWCHAR Options) 00416 { 00417 PINICACHESECTION IniSection; 00418 00419 /* Insert entry into "Operating Systems" section */ 00420 IniCacheInsertKey(OSSection, 00421 NULL, 00422 INSERT_LAST, 00423 Section, 00424 Description); 00425 00426 /* Create new section */ 00427 IniSection = IniCacheAppendSection(IniCache, Section); 00428 00429 /* BootType= */ 00430 IniCacheInsertKey(IniSection, 00431 NULL, 00432 INSERT_LAST, 00433 L"BootType", 00434 BootType); 00435 00436 /* SystemPath= */ 00437 IniCacheInsertKey(IniSection, 00438 NULL, 00439 INSERT_LAST, 00440 L"SystemPath", 00441 ArcPath); 00442 00443 /* Options=*/ 00444 IniCacheInsertKey(IniSection, 00445 NULL, 00446 INSERT_LAST, 00447 L"Options", 00448 Options); 00449 00450 return STATUS_SUCCESS; 00451 } 00452 00453 NTSTATUS 00454 CreateFreeLoaderIniForReactos( 00455 PWCHAR IniPath, 00456 PWCHAR ArcPath) 00457 { 00458 PINICACHE IniCache; 00459 PINICACHESECTION IniSection; 00460 00461 IniCache = IniCacheCreate(); 00462 00463 CreateCommonFreeLoaderSections(IniCache); 00464 00465 /* Create "Operating Systems" section */ 00466 IniSection = IniCacheAppendSection(IniCache, L"Operating Systems"); 00467 00468 /* ReactOS */ 00469 CreateFreeLoaderEntry(IniCache, IniSection, 00470 L"ReactOS", L"\"ReactOS\"", 00471 L"Windows2003", ArcPath, 00472 L""); 00473 00474 /* ReactOS_Debug */ 00475 CreateFreeLoaderEntry(IniCache, IniSection, 00476 L"ReactOS_Debug", L"\"ReactOS (Debug)\"", 00477 L"Windows2003", ArcPath, 00478 L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS"); 00479 00480 #if DBG 00481 #ifndef _WINKD_ 00482 /* ReactOS_KdSerial */ 00483 CreateFreeLoaderEntry(IniCache, IniSection, 00484 L"ReactOS_KdSerial", L"\"ReactOS (RosDbg)\"", 00485 L"Windows2003", ArcPath, 00486 L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL"); 00487 #endif 00488 00489 /* ReactOS_Screen */ 00490 CreateFreeLoaderEntry(IniCache, IniSection, 00491 L"ReactOS_Screen", L"\"ReactOS (Screen)\"", 00492 L"Windows2003", ArcPath, 00493 L"/DEBUG /DEBUGPORT=SCREEN /SOS"); 00494 00495 /* ReactOS_LogFile */ 00496 CreateFreeLoaderEntry(IniCache, IniSection, 00497 L"ReactOS_LogFile", L"\"ReactOS (Log file)\"", 00498 L"Windows2003", ArcPath, 00499 L"/DEBUG /DEBUGPORT=FILE /SOS"); 00500 00501 /* ReactOS_Ram */ 00502 CreateFreeLoaderEntry(IniCache, IniSection, 00503 L"ReactOS_Ram", L"\"ReactOS (RAM Disk)\"", 00504 L"ReactOS", L"ramdisk(0)\\ReactOS", 00505 L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256"); 00506 #endif 00507 00508 /* Save the ini file */ 00509 IniCacheSave(IniCache, IniPath); 00510 IniCacheDestroy(IniCache); 00511 00512 return STATUS_SUCCESS; 00513 } 00514 00515 00516 NTSTATUS 00517 UpdateFreeLoaderIni( 00518 PWCHAR IniPath, 00519 PWCHAR ArcPath) 00520 { 00521 UNICODE_STRING Name; 00522 PINICACHE IniCache; 00523 PINICACHESECTION IniSection; 00524 PINICACHESECTION OsIniSection; 00525 WCHAR SectionName[80]; 00526 WCHAR OsName[80]; 00527 WCHAR SystemPath[200]; 00528 WCHAR SectionName2[200]; 00529 PWCHAR KeyData; 00530 ULONG i,j; 00531 NTSTATUS Status; 00532 00533 RtlInitUnicodeString(&Name, IniPath); 00534 00535 Status = IniCacheLoad(&IniCache, &Name, FALSE); 00536 if (!NT_SUCCESS(Status)) 00537 return Status; 00538 00539 /* Get "Operating Systems" section */ 00540 IniSection = IniCacheGetSection(IniCache, L"Operating Systems"); 00541 if (IniSection == NULL) 00542 { 00543 IniCacheDestroy(IniCache); 00544 return STATUS_UNSUCCESSFUL; 00545 } 00546 00547 /* Find an existing usable or an unused section name */ 00548 i = 1; 00549 wcscpy(SectionName, L"ReactOS"); 00550 wcscpy(OsName, L"\"ReactOS\""); 00551 while(TRUE) 00552 { 00553 Status = IniCacheGetKey(IniSection, SectionName, &KeyData); 00554 if (!NT_SUCCESS(Status)) 00555 break; 00556 00557 /* Get operation system section */ 00558 if (KeyData[0] == '"') 00559 { 00560 wcscpy(SectionName2, &KeyData[1]); 00561 j = wcslen(SectionName2); 00562 if (j > 0) 00563 { 00564 SectionName2[j-1] = 0; 00565 } 00566 } 00567 else 00568 { 00569 wcscpy(SectionName2, KeyData); 00570 } 00571 00572 OsIniSection = IniCacheGetSection(IniCache, SectionName2); 00573 if (OsIniSection != NULL) 00574 { 00575 BOOLEAN UseExistingEntry = TRUE; 00576 00577 /* Check BootType */ 00578 Status = IniCacheGetKey(OsIniSection, L"BootType", &KeyData); 00579 if (NT_SUCCESS(Status)) 00580 { 00581 if ((KeyData == NULL) || 00582 ( (_wcsicmp(KeyData, L"ReactOS") != 0) && 00583 (_wcsicmp(KeyData, L"\"ReactOS\"") != 0) )) 00584 { 00585 /* This is not a ReactOS entry */ 00586 UseExistingEntry = FALSE; 00587 } 00588 } 00589 else 00590 { 00591 UseExistingEntry = FALSE; 00592 } 00593 00594 if (UseExistingEntry) 00595 { 00596 /* BootType is ReactOS. Now check SystemPath */ 00597 Status = IniCacheGetKey(OsIniSection, L"SystemPath", &KeyData); 00598 if (NT_SUCCESS(Status)) 00599 { 00600 swprintf(SystemPath, L"\"%S\"", ArcPath); 00601 if ((KeyData == NULL) || 00602 ((_wcsicmp(KeyData, ArcPath) != 0) && 00603 (_wcsicmp(KeyData, SystemPath) != 0) )) 00604 { 00605 /* This entry is a ReactOS entry, but the SystemRoot does not 00606 match the one we are looking for */ 00607 UseExistingEntry = FALSE; 00608 } 00609 } 00610 else 00611 { 00612 UseExistingEntry = FALSE; 00613 } 00614 } 00615 00616 if (UseExistingEntry) 00617 { 00618 IniCacheDestroy(IniCache); 00619 return STATUS_SUCCESS; 00620 } 00621 } 00622 00623 swprintf(SectionName, L"ReactOS_%lu", i); 00624 swprintf(OsName, L"\"ReactOS %lu\"", i); 00625 i++; 00626 } 00627 00628 /* <SectionName>=<OsName> */ 00629 IniCacheInsertKey(IniSection, 00630 NULL, 00631 INSERT_LAST, 00632 SectionName, 00633 OsName); 00634 00635 /* Create <SectionName> section */ 00636 IniSection = IniCacheAppendSection(IniCache, SectionName); 00637 00638 /* BootType=ReactOS */ 00639 IniCacheInsertKey(IniSection, 00640 NULL, 00641 INSERT_LAST, 00642 L"BootType", 00643 L"ReactOS"); 00644 00645 /* SystemPath=<ArcPath> */ 00646 IniCacheInsertKey(IniSection, 00647 NULL, 00648 INSERT_LAST, 00649 L"SystemPath", 00650 ArcPath); 00651 00652 IniCacheSave(IniCache, IniPath); 00653 IniCacheDestroy(IniCache); 00654 00655 return STATUS_SUCCESS; 00656 } 00657 00658 00659 NTSTATUS 00660 SaveCurrentBootSector( 00661 PWSTR RootPath, 00662 PWSTR DstPath) 00663 { 00664 OBJECT_ATTRIBUTES ObjectAttributes; 00665 IO_STATUS_BLOCK IoStatusBlock; 00666 UNICODE_STRING Name; 00667 HANDLE FileHandle; 00668 NTSTATUS Status; 00669 PUCHAR BootSector; 00670 00671 /* Allocate buffer for bootsector */ 00672 BootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); 00673 if (BootSector == NULL) 00674 return STATUS_INSUFFICIENT_RESOURCES; 00675 00676 /* Read current boot sector into buffer */ 00677 RtlInitUnicodeString(&Name, RootPath); 00678 00679 InitializeObjectAttributes(&ObjectAttributes, 00680 &Name, 00681 OBJ_CASE_INSENSITIVE, 00682 NULL, 00683 NULL); 00684 00685 Status = NtOpenFile(&FileHandle, 00686 GENERIC_READ, 00687 &ObjectAttributes, 00688 &IoStatusBlock, 00689 0, 00690 FILE_SYNCHRONOUS_IO_NONALERT); 00691 if (!NT_SUCCESS(Status)) 00692 { 00693 RtlFreeHeap(ProcessHeap, 0, BootSector); 00694 return Status; 00695 } 00696 00697 Status = NtReadFile(FileHandle, 00698 NULL, 00699 NULL, 00700 NULL, 00701 &IoStatusBlock, 00702 BootSector, 00703 SECTORSIZE, 00704 NULL, 00705 NULL); 00706 NtClose(FileHandle); 00707 if (!NT_SUCCESS(Status)) 00708 { 00709 RtlFreeHeap(ProcessHeap, 0, BootSector); 00710 return Status; 00711 } 00712 00713 /* Write bootsector to DstPath */ 00714 RtlInitUnicodeString(&Name, DstPath); 00715 00716 InitializeObjectAttributes(&ObjectAttributes, 00717 &Name, 00718 0, 00719 NULL, 00720 NULL); 00721 00722 Status = NtCreateFile(&FileHandle, 00723 GENERIC_WRITE, 00724 &ObjectAttributes, 00725 &IoStatusBlock, 00726 NULL, 00727 FILE_ATTRIBUTE_NORMAL, 00728 0, 00729 FILE_SUPERSEDE, 00730 FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY, 00731 NULL, 00732 0); 00733 if (!NT_SUCCESS(Status)) 00734 { 00735 RtlFreeHeap(ProcessHeap, 0, BootSector); 00736 return Status; 00737 } 00738 00739 Status = NtWriteFile(FileHandle, 00740 NULL, 00741 NULL, 00742 NULL, 00743 &IoStatusBlock, 00744 BootSector, 00745 SECTORSIZE, 00746 NULL, 00747 NULL); 00748 NtClose(FileHandle); 00749 00750 /* Free the new boot sector */ 00751 RtlFreeHeap(ProcessHeap, 0, BootSector); 00752 00753 return Status; 00754 } 00755 00756 00757 NTSTATUS 00758 InstallFat16BootCodeToFile( 00759 PWSTR SrcPath, 00760 PWSTR DstPath, 00761 PWSTR RootPath) 00762 { 00763 OBJECT_ATTRIBUTES ObjectAttributes; 00764 IO_STATUS_BLOCK IoStatusBlock; 00765 UNICODE_STRING Name; 00766 HANDLE FileHandle; 00767 NTSTATUS Status; 00768 PFAT_BOOTSECTOR OrigBootSector; 00769 PFAT_BOOTSECTOR NewBootSector; 00770 00771 /* Allocate buffer for original bootsector */ 00772 OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); 00773 if (OrigBootSector == NULL) 00774 return STATUS_INSUFFICIENT_RESOURCES ; 00775 00776 /* Read current boot sector into buffer */ 00777 RtlInitUnicodeString(&Name, RootPath); 00778 00779 InitializeObjectAttributes(&ObjectAttributes, 00780 &Name, 00781 OBJ_CASE_INSENSITIVE, 00782 NULL, 00783 NULL); 00784 00785 Status = NtOpenFile(&FileHandle, 00786 GENERIC_READ, 00787 &ObjectAttributes, 00788 &IoStatusBlock, 00789 0, 00790 FILE_SYNCHRONOUS_IO_NONALERT); 00791 if (!NT_SUCCESS(Status)) 00792 { 00793 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 00794 return Status; 00795 } 00796 00797 Status = NtReadFile(FileHandle, 00798 NULL, 00799 NULL, 00800 NULL, 00801 &IoStatusBlock, 00802 OrigBootSector, 00803 SECTORSIZE, 00804 NULL, 00805 NULL); 00806 NtClose(FileHandle); 00807 if (!NT_SUCCESS(Status)) 00808 { 00809 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 00810 return Status; 00811 } 00812 00813 /* Allocate buffer for new bootsector */ 00814 NewBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); 00815 if (NewBootSector == NULL) 00816 { 00817 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 00818 return STATUS_INSUFFICIENT_RESOURCES; 00819 } 00820 00821 /* Read new bootsector from SrcPath */ 00822 RtlInitUnicodeString(&Name, SrcPath); 00823 00824 InitializeObjectAttributes(&ObjectAttributes, 00825 &Name, 00826 OBJ_CASE_INSENSITIVE, 00827 NULL, 00828 NULL); 00829 00830 Status = NtOpenFile(&FileHandle, 00831 GENERIC_READ, 00832 &ObjectAttributes, 00833 &IoStatusBlock, 00834 0, 00835 FILE_SYNCHRONOUS_IO_NONALERT); 00836 if (!NT_SUCCESS(Status)) 00837 { 00838 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 00839 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 00840 return Status; 00841 } 00842 00843 Status = NtReadFile(FileHandle, 00844 NULL, 00845 NULL, 00846 NULL, 00847 &IoStatusBlock, 00848 NewBootSector, 00849 SECTORSIZE, 00850 NULL, 00851 NULL); 00852 NtClose(FileHandle); 00853 if (!NT_SUCCESS(Status)) 00854 { 00855 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 00856 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 00857 return Status; 00858 } 00859 00860 /* Adjust bootsector (copy a part of the FAT BPB) */ 00861 memcpy(&NewBootSector->OemName, 00862 &OrigBootSector->OemName, 00863 FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) - 00864 FIELD_OFFSET(FAT_BOOTSECTOR, OemName)); 00865 00866 /* Free the original boot sector */ 00867 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 00868 00869 /* Write new bootsector to DstPath */ 00870 RtlInitUnicodeString(&Name, DstPath); 00871 00872 InitializeObjectAttributes(&ObjectAttributes, 00873 &Name, 00874 0, 00875 NULL, 00876 NULL); 00877 00878 Status = NtCreateFile(&FileHandle, 00879 GENERIC_WRITE, 00880 &ObjectAttributes, 00881 &IoStatusBlock, 00882 NULL, 00883 FILE_ATTRIBUTE_NORMAL, 00884 0, 00885 FILE_OVERWRITE_IF, 00886 FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY, 00887 NULL, 00888 0); 00889 if (!NT_SUCCESS(Status)) 00890 { 00891 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 00892 return Status; 00893 } 00894 00895 #if 0 00896 FilePosition.QuadPart = 0; 00897 #endif 00898 Status = NtWriteFile(FileHandle, 00899 NULL, 00900 NULL, 00901 NULL, 00902 &IoStatusBlock, 00903 NewBootSector, 00904 SECTORSIZE, 00905 NULL, 00906 NULL); 00907 NtClose(FileHandle); 00908 00909 /* Free the new boot sector */ 00910 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 00911 00912 return Status; 00913 } 00914 00915 00916 NTSTATUS 00917 InstallFat32BootCodeToFile( 00918 PWSTR SrcPath, 00919 PWSTR DstPath, 00920 PWSTR RootPath) 00921 { 00922 OBJECT_ATTRIBUTES ObjectAttributes; 00923 IO_STATUS_BLOCK IoStatusBlock; 00924 UNICODE_STRING Name; 00925 HANDLE FileHandle; 00926 NTSTATUS Status; 00927 PFAT32_BOOTSECTOR OrigBootSector; 00928 PFAT32_BOOTSECTOR NewBootSector; 00929 LARGE_INTEGER FileOffset; 00930 00931 /* Allocate buffer for original bootsector */ 00932 OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); 00933 if (OrigBootSector == NULL) 00934 return STATUS_INSUFFICIENT_RESOURCES; 00935 00936 /* Read current boot sector into buffer */ 00937 RtlInitUnicodeString(&Name, RootPath); 00938 00939 InitializeObjectAttributes(&ObjectAttributes, 00940 &Name, 00941 OBJ_CASE_INSENSITIVE, 00942 NULL, 00943 NULL); 00944 00945 Status = NtOpenFile(&FileHandle, 00946 GENERIC_READ, 00947 &ObjectAttributes, 00948 &IoStatusBlock, 00949 0, 00950 FILE_SYNCHRONOUS_IO_NONALERT); 00951 if (!NT_SUCCESS(Status)) 00952 { 00953 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 00954 return Status; 00955 } 00956 00957 Status = NtReadFile(FileHandle, 00958 NULL, 00959 NULL, 00960 NULL, 00961 &IoStatusBlock, 00962 OrigBootSector, 00963 SECTORSIZE, 00964 NULL, 00965 NULL); 00966 NtClose(FileHandle); 00967 if (!NT_SUCCESS(Status)) 00968 { 00969 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 00970 return Status; 00971 } 00972 00973 /* Allocate buffer for new bootsector (2 sectors) */ 00974 NewBootSector = RtlAllocateHeap(ProcessHeap, 0, 2 * SECTORSIZE); 00975 if (NewBootSector == NULL) 00976 { 00977 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 00978 return STATUS_INSUFFICIENT_RESOURCES; 00979 } 00980 00981 /* Read new bootsector from SrcPath */ 00982 RtlInitUnicodeString(&Name, SrcPath); 00983 00984 InitializeObjectAttributes(&ObjectAttributes, 00985 &Name, 00986 OBJ_CASE_INSENSITIVE, 00987 NULL, 00988 NULL); 00989 00990 Status = NtOpenFile(&FileHandle, 00991 GENERIC_READ, 00992 &ObjectAttributes, 00993 &IoStatusBlock, 00994 0, 00995 FILE_SYNCHRONOUS_IO_NONALERT); 00996 if (!NT_SUCCESS(Status)) 00997 { 00998 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 00999 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01000 return Status; 01001 } 01002 01003 Status = NtReadFile(FileHandle, 01004 NULL, 01005 NULL, 01006 NULL, 01007 &IoStatusBlock, 01008 NewBootSector, 01009 2 * SECTORSIZE, 01010 NULL, 01011 NULL); 01012 NtClose(FileHandle); 01013 if (!NT_SUCCESS(Status)) 01014 { 01015 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01016 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01017 return Status; 01018 } 01019 01020 /* Adjust bootsector (copy a part of the FAT32 BPB) */ 01021 memcpy(&NewBootSector->OemName, 01022 &OrigBootSector->OemName, 01023 FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) - 01024 FIELD_OFFSET(FAT32_BOOTSECTOR, OemName)); 01025 01026 /* Disable the backup boot sector */ 01027 NewBootSector->BackupBootSector = 0; 01028 01029 /* Free the original boot sector */ 01030 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01031 01032 /* Write the first sector of the new bootcode to DstPath */ 01033 RtlInitUnicodeString(&Name, DstPath); 01034 01035 InitializeObjectAttributes(&ObjectAttributes, 01036 &Name, 01037 0, 01038 NULL, 01039 NULL); 01040 01041 Status = NtCreateFile(&FileHandle, 01042 GENERIC_WRITE, 01043 &ObjectAttributes, 01044 &IoStatusBlock, 01045 NULL, 01046 FILE_ATTRIBUTE_NORMAL, 01047 0, 01048 FILE_SUPERSEDE, 01049 FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY, 01050 NULL, 01051 0); 01052 if (!NT_SUCCESS(Status)) 01053 { 01054 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01055 return Status; 01056 } 01057 01058 Status = NtWriteFile(FileHandle, 01059 NULL, 01060 NULL, 01061 NULL, 01062 &IoStatusBlock, 01063 NewBootSector, 01064 SECTORSIZE, 01065 NULL, 01066 NULL); 01067 NtClose(FileHandle); 01068 if (!NT_SUCCESS(Status)) 01069 { 01070 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01071 return Status; 01072 } 01073 01074 /* Write the second sector of the new bootcode to boot disk sector 14 */ 01075 RtlInitUnicodeString(&Name, RootPath); 01076 01077 InitializeObjectAttributes(&ObjectAttributes, 01078 &Name, 01079 0, 01080 NULL, 01081 NULL); 01082 01083 Status = NtOpenFile(&FileHandle, 01084 GENERIC_WRITE, 01085 &ObjectAttributes, 01086 &IoStatusBlock, 01087 0, 01088 FILE_SYNCHRONOUS_IO_NONALERT); 01089 if (!NT_SUCCESS(Status)) 01090 { 01091 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01092 return Status; 01093 } 01094 01095 FileOffset.QuadPart = (ULONGLONG)(14 * SECTORSIZE); 01096 Status = NtWriteFile(FileHandle, 01097 NULL, 01098 NULL, 01099 NULL, 01100 &IoStatusBlock, 01101 ((PUCHAR)NewBootSector + SECTORSIZE), 01102 SECTORSIZE, 01103 &FileOffset, 01104 NULL); 01105 if (!NT_SUCCESS(Status)) 01106 { 01107 } 01108 NtClose(FileHandle); 01109 01110 /* Free the new boot sector */ 01111 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01112 01113 return Status; 01114 } 01115 01116 01117 NTSTATUS 01118 InstallMbrBootCodeToDisk( 01119 PWSTR SrcPath, 01120 PWSTR RootPath) 01121 { 01122 OBJECT_ATTRIBUTES ObjectAttributes; 01123 IO_STATUS_BLOCK IoStatusBlock; 01124 UNICODE_STRING Name; 01125 HANDLE FileHandle; 01126 NTSTATUS Status; 01127 PPARTITION_SECTOR OrigBootSector; 01128 PPARTITION_SECTOR NewBootSector; 01129 01130 /* Allocate buffer for original bootsector */ 01131 OrigBootSector = (PPARTITION_SECTOR)RtlAllocateHeap(ProcessHeap, 01132 0, 01133 sizeof(PARTITION_SECTOR)); 01134 if (OrigBootSector == NULL) 01135 return STATUS_INSUFFICIENT_RESOURCES; 01136 01137 /* Read current boot sector into buffer */ 01138 RtlInitUnicodeString(&Name, 01139 RootPath); 01140 01141 InitializeObjectAttributes(&ObjectAttributes, 01142 &Name, 01143 OBJ_CASE_INSENSITIVE, 01144 NULL, 01145 NULL); 01146 01147 Status = NtOpenFile(&FileHandle, 01148 GENERIC_READ, 01149 &ObjectAttributes, 01150 &IoStatusBlock, 01151 0, 01152 FILE_SYNCHRONOUS_IO_NONALERT); 01153 if (!NT_SUCCESS(Status)) 01154 { 01155 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01156 return Status; 01157 } 01158 01159 Status = NtReadFile(FileHandle, 01160 NULL, 01161 NULL, 01162 NULL, 01163 &IoStatusBlock, 01164 OrigBootSector, 01165 SECTORSIZE, 01166 NULL, 01167 NULL); 01168 NtClose(FileHandle); 01169 if (!NT_SUCCESS(Status)) 01170 { 01171 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01172 return Status; 01173 } 01174 01175 01176 /* Allocate buffer for new bootsector */ 01177 NewBootSector = (PPARTITION_SECTOR)RtlAllocateHeap(ProcessHeap, 01178 0, 01179 sizeof(PARTITION_SECTOR)); 01180 if (NewBootSector == NULL) 01181 { 01182 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01183 return STATUS_INSUFFICIENT_RESOURCES; 01184 } 01185 01186 /* Read new bootsector from SrcPath */ 01187 RtlInitUnicodeString(&Name, SrcPath); 01188 01189 InitializeObjectAttributes(&ObjectAttributes, 01190 &Name, 01191 OBJ_CASE_INSENSITIVE, 01192 NULL, 01193 NULL); 01194 01195 Status = NtOpenFile(&FileHandle, 01196 GENERIC_READ, 01197 &ObjectAttributes, 01198 &IoStatusBlock, 01199 0, 01200 FILE_SYNCHRONOUS_IO_NONALERT); 01201 if (!NT_SUCCESS(Status)) 01202 { 01203 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01204 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01205 return Status; 01206 } 01207 01208 Status = NtReadFile(FileHandle, 01209 NULL, 01210 NULL, 01211 NULL, 01212 &IoStatusBlock, 01213 NewBootSector, 01214 sizeof(PARTITION_SECTOR), 01215 NULL, 01216 NULL); 01217 NtClose(FileHandle); 01218 if (!NT_SUCCESS(Status)) 01219 { 01220 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01221 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01222 return Status; 01223 } 01224 01225 /* Copy partition table from old MBR to new */ 01226 RtlCopyMemory (&NewBootSector->Signature, 01227 &OrigBootSector->Signature, 01228 sizeof(PARTITION_SECTOR) - offsetof(PARTITION_SECTOR, Signature) /* Length of partition table */); 01229 01230 /* Free the original boot sector */ 01231 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01232 01233 /* Write new bootsector to RootPath */ 01234 RtlInitUnicodeString(&Name, RootPath); 01235 01236 InitializeObjectAttributes(&ObjectAttributes, 01237 &Name, 01238 0, 01239 NULL, 01240 NULL); 01241 01242 Status = NtOpenFile(&FileHandle, 01243 GENERIC_WRITE, 01244 &ObjectAttributes, 01245 &IoStatusBlock, 01246 0, 01247 FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY); 01248 if (!NT_SUCCESS(Status)) 01249 { 01250 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); 01251 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01252 return Status; 01253 } 01254 01255 Status = NtWriteFile(FileHandle, 01256 NULL, 01257 NULL, 01258 NULL, 01259 &IoStatusBlock, 01260 NewBootSector, 01261 SECTORSIZE, 01262 NULL, 01263 NULL); 01264 NtClose(FileHandle); 01265 01266 /* Free the new boot sector */ 01267 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01268 01269 return Status; 01270 } 01271 01272 NTSTATUS 01273 InstallFat12BootCodeToFloppy(PWSTR SrcPath, 01274 PWSTR RootPath) 01275 { 01276 OBJECT_ATTRIBUTES ObjectAttributes; 01277 IO_STATUS_BLOCK IoStatusBlock; 01278 UNICODE_STRING Name; 01279 HANDLE FileHandle; 01280 NTSTATUS Status; 01281 PFAT_BOOTSECTOR OrigBootSector; 01282 PFAT_BOOTSECTOR NewBootSector; 01283 01284 /* Allocate buffer for original bootsector */ 01285 OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); 01286 if (OrigBootSector == NULL) 01287 return STATUS_INSUFFICIENT_RESOURCES; 01288 01289 /* Read current boot sector into buffer */ 01290 RtlInitUnicodeString(&Name, RootPath); 01291 01292 InitializeObjectAttributes(&ObjectAttributes, 01293 &Name, 01294 OBJ_CASE_INSENSITIVE, 01295 NULL, 01296 NULL); 01297 01298 Status = NtOpenFile(&FileHandle, 01299 GENERIC_READ, 01300 &ObjectAttributes, 01301 &IoStatusBlock, 01302 0, 01303 FILE_SYNCHRONOUS_IO_NONALERT); 01304 if (!NT_SUCCESS(Status)) 01305 { 01306 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01307 return Status; 01308 } 01309 01310 Status = NtReadFile(FileHandle, 01311 NULL, 01312 NULL, 01313 NULL, 01314 &IoStatusBlock, 01315 OrigBootSector, 01316 SECTORSIZE, 01317 NULL, 01318 NULL); 01319 NtClose(FileHandle); 01320 if (!NT_SUCCESS(Status)) 01321 { 01322 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01323 return Status; 01324 } 01325 01326 01327 /* Allocate buffer for new bootsector */ 01328 NewBootSector = RtlAllocateHeap(ProcessHeap, 01329 0, 01330 SECTORSIZE); 01331 if (NewBootSector == NULL) 01332 { 01333 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01334 return STATUS_INSUFFICIENT_RESOURCES; 01335 } 01336 01337 /* Read new bootsector from SrcPath */ 01338 RtlInitUnicodeString(&Name, SrcPath); 01339 01340 InitializeObjectAttributes(&ObjectAttributes, 01341 &Name, 01342 OBJ_CASE_INSENSITIVE, 01343 NULL, 01344 NULL); 01345 01346 Status = NtOpenFile(&FileHandle, 01347 GENERIC_READ, 01348 &ObjectAttributes, 01349 &IoStatusBlock, 01350 0, 01351 FILE_SYNCHRONOUS_IO_NONALERT); 01352 if (!NT_SUCCESS(Status)) 01353 { 01354 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01355 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01356 return Status; 01357 } 01358 01359 Status = NtReadFile(FileHandle, 01360 NULL, 01361 NULL, 01362 NULL, 01363 &IoStatusBlock, 01364 NewBootSector, 01365 SECTORSIZE, 01366 NULL, 01367 NULL); 01368 NtClose(FileHandle); 01369 if (!NT_SUCCESS(Status)) 01370 { 01371 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01372 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01373 return Status; 01374 } 01375 01376 /* Adjust bootsector (copy a part of the FAT16 BPB) */ 01377 memcpy(&NewBootSector->OemName, 01378 &OrigBootSector->OemName, 01379 FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) - 01380 FIELD_OFFSET(FAT_BOOTSECTOR, OemName)); 01381 01382 /* Free the original boot sector */ 01383 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01384 01385 /* Write new bootsector to RootPath */ 01386 RtlInitUnicodeString(&Name, RootPath); 01387 01388 InitializeObjectAttributes(&ObjectAttributes, 01389 &Name, 01390 0, 01391 NULL, 01392 NULL); 01393 01394 Status = NtOpenFile(&FileHandle, 01395 GENERIC_WRITE, 01396 &ObjectAttributes, 01397 &IoStatusBlock, 01398 0, 01399 FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY); 01400 if (!NT_SUCCESS(Status)) 01401 { 01402 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); 01403 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01404 return Status; 01405 } 01406 01407 #if 0 01408 FilePosition.QuadPart = 0; 01409 #endif 01410 Status = NtWriteFile(FileHandle, 01411 NULL, 01412 NULL, 01413 NULL, 01414 &IoStatusBlock, 01415 NewBootSector, 01416 SECTORSIZE, 01417 NULL, 01418 NULL); 01419 NtClose(FileHandle); 01420 01421 /* Free the new boot sector */ 01422 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01423 01424 return Status; 01425 } 01426 01427 01428 NTSTATUS 01429 InstallFat16BootCodeToDisk( 01430 PWSTR SrcPath, 01431 PWSTR RootPath) 01432 { 01433 OBJECT_ATTRIBUTES ObjectAttributes; 01434 IO_STATUS_BLOCK IoStatusBlock; 01435 UNICODE_STRING Name; 01436 HANDLE FileHandle; 01437 NTSTATUS Status; 01438 PFAT_BOOTSECTOR OrigBootSector; 01439 PFAT_BOOTSECTOR NewBootSector; 01440 PARTITION_INFORMATION *PartInfo; 01441 01442 /* Allocate buffer for original bootsector */ 01443 OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); 01444 if (OrigBootSector == NULL) 01445 return STATUS_INSUFFICIENT_RESOURCES; 01446 01447 /* Read current boot sector into buffer */ 01448 RtlInitUnicodeString(&Name, RootPath); 01449 01450 InitializeObjectAttributes(&ObjectAttributes, 01451 &Name, 01452 OBJ_CASE_INSENSITIVE, 01453 NULL, 01454 NULL); 01455 01456 Status = NtOpenFile(&FileHandle, 01457 GENERIC_READ, 01458 &ObjectAttributes, 01459 &IoStatusBlock, 01460 0, 01461 FILE_SYNCHRONOUS_IO_NONALERT); 01462 if (!NT_SUCCESS(Status)) 01463 { 01464 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01465 return Status; 01466 } 01467 01468 Status = NtReadFile(FileHandle, 01469 NULL, 01470 NULL, 01471 NULL, 01472 &IoStatusBlock, 01473 OrigBootSector, 01474 SECTORSIZE, 01475 NULL, 01476 NULL); 01477 NtClose(FileHandle); 01478 if (!NT_SUCCESS(Status)) 01479 { 01480 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01481 return Status; 01482 } 01483 01484 01485 /* Allocate buffer for new bootsector */ 01486 NewBootSector = RtlAllocateHeap(ProcessHeap, 01487 0, 01488 SECTORSIZE); 01489 if (NewBootSector == NULL) 01490 { 01491 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01492 return STATUS_INSUFFICIENT_RESOURCES; 01493 } 01494 01495 /* Read new bootsector from SrcPath */ 01496 RtlInitUnicodeString(&Name, SrcPath); 01497 01498 InitializeObjectAttributes(&ObjectAttributes, 01499 &Name, 01500 OBJ_CASE_INSENSITIVE, 01501 NULL, 01502 NULL); 01503 01504 Status = NtOpenFile(&FileHandle, 01505 GENERIC_READ, 01506 &ObjectAttributes, 01507 &IoStatusBlock, 01508 0, 01509 FILE_SYNCHRONOUS_IO_NONALERT); 01510 if (!NT_SUCCESS(Status)) 01511 { 01512 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01513 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01514 return Status; 01515 } 01516 01517 Status = NtReadFile(FileHandle, 01518 NULL, 01519 NULL, 01520 NULL, 01521 &IoStatusBlock, 01522 NewBootSector, 01523 SECTORSIZE, 01524 NULL, 01525 NULL); 01526 NtClose(FileHandle); 01527 if (!NT_SUCCESS(Status)) 01528 { 01529 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01530 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01531 return Status; 01532 } 01533 01534 /* Adjust bootsector (copy a part of the FAT16 BPB) */ 01535 memcpy(&NewBootSector->OemName, 01536 &OrigBootSector->OemName, 01537 FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) - 01538 FIELD_OFFSET(FAT_BOOTSECTOR, OemName)); 01539 01540 PartInfo = &PartitionList->CurrentPartition->PartInfo[PartitionList->CurrentPartitionNumber]; 01541 NewBootSector->HiddenSectors = PartInfo->HiddenSectors; 01542 01543 /* Free the original boot sector */ 01544 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01545 01546 /* Write new bootsector to RootPath */ 01547 RtlInitUnicodeString(&Name, RootPath); 01548 01549 InitializeObjectAttributes(&ObjectAttributes, 01550 &Name, 01551 0, 01552 NULL, 01553 NULL); 01554 01555 Status = NtOpenFile(&FileHandle, 01556 GENERIC_WRITE, 01557 &ObjectAttributes, 01558 &IoStatusBlock, 01559 0, 01560 FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY); 01561 if (!NT_SUCCESS(Status)) 01562 { 01563 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); 01564 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01565 return Status; 01566 } 01567 01568 #if 0 01569 FilePosition.QuadPart = 0; 01570 #endif 01571 Status = NtWriteFile(FileHandle, 01572 NULL, 01573 NULL, 01574 NULL, 01575 &IoStatusBlock, 01576 NewBootSector, 01577 SECTORSIZE, 01578 NULL, 01579 NULL); 01580 NtClose(FileHandle); 01581 01582 /* Free the new boot sector */ 01583 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01584 01585 return Status; 01586 } 01587 01588 01589 NTSTATUS 01590 InstallFat32BootCodeToDisk( 01591 PWSTR SrcPath, 01592 PWSTR RootPath) 01593 { 01594 OBJECT_ATTRIBUTES ObjectAttributes; 01595 IO_STATUS_BLOCK IoStatusBlock; 01596 UNICODE_STRING Name; 01597 HANDLE FileHandle; 01598 NTSTATUS Status; 01599 PFAT32_BOOTSECTOR OrigBootSector; 01600 PFAT32_BOOTSECTOR NewBootSector; 01601 LARGE_INTEGER FileOffset; 01602 USHORT BackupBootSector; 01603 PARTITION_INFORMATION *PartInfo; 01604 01605 /* Allocate buffer for original bootsector */ 01606 OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); 01607 if (OrigBootSector == NULL) 01608 return STATUS_INSUFFICIENT_RESOURCES; 01609 01610 /* Read current boot sector into buffer */ 01611 RtlInitUnicodeString(&Name, RootPath); 01612 01613 InitializeObjectAttributes(&ObjectAttributes, 01614 &Name, 01615 OBJ_CASE_INSENSITIVE, 01616 NULL, 01617 NULL); 01618 01619 Status = NtOpenFile(&FileHandle, 01620 GENERIC_READ, 01621 &ObjectAttributes, 01622 &IoStatusBlock, 01623 0, 01624 FILE_SYNCHRONOUS_IO_NONALERT); 01625 if (!NT_SUCCESS(Status)) 01626 { 01627 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01628 return Status; 01629 } 01630 01631 Status = NtReadFile(FileHandle, 01632 NULL, 01633 NULL, 01634 NULL, 01635 &IoStatusBlock, 01636 OrigBootSector, 01637 SECTORSIZE, 01638 NULL, 01639 NULL); 01640 NtClose(FileHandle); 01641 if (!NT_SUCCESS(Status)) 01642 { 01643 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01644 return Status; 01645 } 01646 01647 01648 /* Allocate buffer for new bootsector (2 sectors) */ 01649 NewBootSector = RtlAllocateHeap(ProcessHeap, 0, 2 * SECTORSIZE); 01650 if (NewBootSector == NULL) 01651 { 01652 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01653 return STATUS_INSUFFICIENT_RESOURCES; 01654 } 01655 01656 /* Read new bootsector from SrcPath */ 01657 RtlInitUnicodeString(&Name, SrcPath); 01658 01659 InitializeObjectAttributes(&ObjectAttributes, 01660 &Name, 01661 OBJ_CASE_INSENSITIVE, 01662 NULL, 01663 NULL); 01664 01665 Status = NtOpenFile(&FileHandle, 01666 GENERIC_READ, 01667 &ObjectAttributes, 01668 &IoStatusBlock, 01669 0, 01670 FILE_SYNCHRONOUS_IO_NONALERT); 01671 if (!NT_SUCCESS(Status)) 01672 { 01673 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01674 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01675 return Status; 01676 } 01677 01678 Status = NtReadFile(FileHandle, 01679 NULL, 01680 NULL, 01681 NULL, 01682 &IoStatusBlock, 01683 NewBootSector, 01684 2 * SECTORSIZE, 01685 NULL, 01686 NULL); 01687 NtClose(FileHandle); 01688 if (!NT_SUCCESS(Status)) 01689 { 01690 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01691 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01692 return Status; 01693 } 01694 01695 /* Adjust bootsector (copy a part of the FAT32 BPB) */ 01696 memcpy(&NewBootSector->OemName, 01697 &OrigBootSector->OemName, 01698 FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) - 01699 FIELD_OFFSET(FAT32_BOOTSECTOR, OemName)); 01700 01701 PartInfo = &PartitionList->CurrentPartition->PartInfo[PartitionList->CurrentPartitionNumber]; 01702 NewBootSector->HiddenSectors = PartInfo->HiddenSectors; 01703 01704 /* Get the location of the backup boot sector */ 01705 BackupBootSector = OrigBootSector->BackupBootSector; 01706 01707 /* Free the original boot sector */ 01708 RtlFreeHeap(ProcessHeap, 0, OrigBootSector); 01709 01710 /* Write the first sector of the new bootcode to DstPath */ 01711 RtlInitUnicodeString(&Name, RootPath); 01712 01713 InitializeObjectAttributes(&ObjectAttributes, 01714 &Name, 01715 0, 01716 NULL, 01717 NULL); 01718 01719 Status = NtOpenFile(&FileHandle, 01720 GENERIC_WRITE, 01721 &ObjectAttributes, 01722 &IoStatusBlock, 01723 0, 01724 FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY); 01725 if (!NT_SUCCESS(Status)) 01726 { 01727 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); 01728 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01729 return Status; 01730 } 01731 01732 /* Write sector 0 */ 01733 FileOffset.QuadPart = 0ULL; 01734 Status = NtWriteFile(FileHandle, 01735 NULL, 01736 NULL, 01737 NULL, 01738 &IoStatusBlock, 01739 NewBootSector, 01740 SECTORSIZE, 01741 &FileOffset, 01742 NULL); 01743 if (!NT_SUCCESS(Status)) 01744 { 01745 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); 01746 NtClose(FileHandle); 01747 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01748 return Status; 01749 } 01750 01751 /* Write backup boot sector */ 01752 if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF)) 01753 { 01754 FileOffset.QuadPart = (ULONGLONG)((ULONG)BackupBootSector * SECTORSIZE); 01755 Status = NtWriteFile(FileHandle, 01756 NULL, 01757 NULL, 01758 NULL, 01759 &IoStatusBlock, 01760 NewBootSector, 01761 SECTORSIZE, 01762 &FileOffset, 01763 NULL); 01764 if (!NT_SUCCESS(Status)) 01765 { 01766 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); 01767 NtClose(FileHandle); 01768 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01769 return Status; 01770 } 01771 } 01772 01773 /* Write sector 14 */ 01774 FileOffset.QuadPart = 14 * SECTORSIZE; 01775 Status = NtWriteFile(FileHandle, 01776 NULL, 01777 NULL, 01778 NULL, 01779 &IoStatusBlock, 01780 ((PUCHAR)NewBootSector + SECTORSIZE), 01781 SECTORSIZE, 01782 &FileOffset, 01783 NULL); 01784 if (!NT_SUCCESS(Status)) 01785 { 01786 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); 01787 } 01788 NtClose(FileHandle); 01789 01790 /* Free the new boot sector */ 01791 RtlFreeHeap(ProcessHeap, 0, NewBootSector); 01792 01793 return Status; 01794 } 01795 01796 01797 static 01798 NTSTATUS 01799 UnprotectBootIni( 01800 PWSTR FileName, 01801 PULONG Attributes) 01802 { 01803 UNICODE_STRING Name; 01804 OBJECT_ATTRIBUTES ObjectAttributes; 01805 IO_STATUS_BLOCK IoStatusBlock; 01806 FILE_BASIC_INFORMATION FileInfo; 01807 HANDLE FileHandle; 01808 NTSTATUS Status; 01809 01810 RtlInitUnicodeString(&Name, FileName); 01811 01812 InitializeObjectAttributes(&ObjectAttributes, 01813 &Name, 01814 OBJ_CASE_INSENSITIVE, 01815 NULL, 01816 NULL); 01817 01818 Status = NtOpenFile(&FileHandle, 01819 GENERIC_READ|GENERIC_WRITE, 01820 &ObjectAttributes, 01821 &IoStatusBlock, 01822 0, 01823 FILE_SYNCHRONOUS_IO_NONALERT); 01824 if (Status == STATUS_NO_SUCH_FILE) 01825 { 01826 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); 01827 *Attributes = 0; 01828 return STATUS_SUCCESS; 01829 } 01830 if (!NT_SUCCESS(Status)) 01831 { 01832 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); 01833 return Status; 01834 } 01835 01836 Status = NtQueryInformationFile(FileHandle, 01837 &IoStatusBlock, 01838 &FileInfo, 01839 sizeof(FILE_BASIC_INFORMATION), 01840 FileBasicInformation); 01841 if (!NT_SUCCESS(Status)) 01842 { 01843 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status); 01844 NtClose(FileHandle); 01845 return Status; 01846 } 01847 01848 *Attributes = FileInfo.FileAttributes; 01849 01850 /* Delete attributes SYSTEM, HIDDEN and READONLY */ 01851 FileInfo.FileAttributes = FileInfo.FileAttributes & 01852 ~(FILE_ATTRIBUTE_SYSTEM | 01853 FILE_ATTRIBUTE_HIDDEN | 01854 FILE_ATTRIBUTE_READONLY); 01855 01856 Status = NtSetInformationFile(FileHandle, 01857 &IoStatusBlock, 01858 &FileInfo, 01859 sizeof(FILE_BASIC_INFORMATION), 01860 FileBasicInformation); 01861 if (!NT_SUCCESS(Status)) 01862 { 01863 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status); 01864 } 01865 01866 NtClose(FileHandle); 01867 return Status; 01868 } 01869 01870 01871 static 01872 NTSTATUS 01873 ProtectBootIni( 01874 PWSTR FileName, 01875 ULONG Attributes) 01876 { 01877 UNICODE_STRING Name; 01878 OBJECT_ATTRIBUTES ObjectAttributes; 01879 IO_STATUS_BLOCK IoStatusBlock; 01880 FILE_BASIC_INFORMATION FileInfo; 01881 HANDLE FileHandle; 01882 NTSTATUS Status; 01883 01884 RtlInitUnicodeString(&Name, FileName); 01885 01886 InitializeObjectAttributes(&ObjectAttributes, 01887 &Name, 01888 OBJ_CASE_INSENSITIVE, 01889 NULL, 01890 NULL); 01891 01892 Status = NtOpenFile(&FileHandle, 01893 GENERIC_READ|GENERIC_WRITE, 01894 &ObjectAttributes, 01895 &IoStatusBlock, 01896 0, 01897 FILE_SYNCHRONOUS_IO_NONALERT); 01898 if (!NT_SUCCESS(Status)) 01899 { 01900 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); 01901 return Status; 01902 } 01903 01904 Status = NtQueryInformationFile(FileHandle, 01905 &IoStatusBlock, 01906 &FileInfo, 01907 sizeof(FILE_BASIC_INFORMATION), 01908 FileBasicInformation); 01909 if (!NT_SUCCESS(Status)) 01910 { 01911 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status); 01912 NtClose(FileHandle); 01913 return Status; 01914 } 01915 01916 FileInfo.FileAttributes = FileInfo.FileAttributes | Attributes; 01917 01918 Status = NtSetInformationFile(FileHandle, 01919 &IoStatusBlock, 01920 &FileInfo, 01921 sizeof(FILE_BASIC_INFORMATION), 01922 FileBasicInformation); 01923 if (!NT_SUCCESS(Status)) 01924 { 01925 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status); 01926 } 01927 01928 NtClose(FileHandle); 01929 return Status; 01930 } 01931 01932 01933 NTSTATUS 01934 UpdateBootIni( 01935 PWSTR BootIniPath, 01936 PWSTR EntryName, 01937 PWSTR EntryValue) 01938 { 01939 UNICODE_STRING Name; 01940 PINICACHE Cache = NULL; 01941 PINICACHESECTION Section = NULL; 01942 NTSTATUS Status; 01943 ULONG FileAttribute; 01944 PWCHAR OldValue = NULL; 01945 01946 RtlInitUnicodeString(&Name, BootIniPath); 01947 01948 Status = IniCacheLoad(&Cache, &Name, FALSE); 01949 if (!NT_SUCCESS(Status)) 01950 { 01951 return Status; 01952 } 01953 01954 Section = IniCacheGetSection(Cache, 01955 L"operating systems"); 01956 if (Section == NULL) 01957 { 01958 IniCacheDestroy(Cache); 01959 return STATUS_UNSUCCESSFUL; 01960 } 01961 01962 /* Check - maybe record already exists */ 01963 Status = IniCacheGetKey(Section, EntryName, &OldValue); 01964 01965 /* If either key was not found, or contains something else - add new one */ 01966 if (!NT_SUCCESS(Status) || wcscmp(OldValue, EntryValue)) 01967 { 01968 IniCacheInsertKey(Section, 01969 NULL, 01970 INSERT_LAST, 01971 EntryName, 01972 EntryValue); 01973 } 01974 01975 Status = UnprotectBootIni(BootIniPath, 01976 &FileAttribute); 01977 if (!NT_SUCCESS(Status)) 01978 { 01979 IniCacheDestroy(Cache); 01980 return Status; 01981 } 01982 01983 Status = IniCacheSave(Cache, BootIniPath); 01984 if (!NT_SUCCESS(Status)) 01985 { 01986 IniCacheDestroy(Cache); 01987 return Status; 01988 } 01989 01990 FileAttribute |= (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY); 01991 Status = ProtectBootIni(BootIniPath, FileAttribute); 01992 01993 IniCacheDestroy(Cache); 01994 01995 return Status; 01996 } 01997 01998 BOOLEAN 01999 CheckInstallFatBootcodeToPartition( 02000 PUNICODE_STRING SystemRootPath) 02001 { 02002 #ifdef __REACTOS__ 02003 if (DoesFileExist(SystemRootPath->Buffer, L"ntldr") || 02004 DoesFileExist(SystemRootPath->Buffer, L"boot.ini")) 02005 { 02006 return TRUE; 02007 } 02008 else if (DoesFileExist(SystemRootPath->Buffer, L"io.sys") || 02009 DoesFileExist(SystemRootPath->Buffer, L"msdos.sys")) 02010 { 02011 return TRUE; 02012 } 02013 #endif 02014 02015 return FALSE; 02016 } 02017 02018 02019 NTSTATUS 02020 InstallFatBootcodeToPartition( 02021 PUNICODE_STRING SystemRootPath, 02022 PUNICODE_STRING SourceRootPath, 02023 PUNICODE_STRING DestinationArcPath, 02024 UCHAR PartitionType) 02025 { 02026 #ifdef __REACTOS__ 02027 WCHAR SrcPath[MAX_PATH]; 02028 WCHAR DstPath[MAX_PATH]; 02029 NTSTATUS Status; 02030 02031 /* FAT or FAT32 partition */ 02032 DPRINT("System path: '%wZ'\n", SystemRootPath); 02033 02034 if (DoesFileExist(SystemRootPath->Buffer, L"ntldr") == TRUE || 02035 DoesFileExist(SystemRootPath->Buffer, L"boot.ini") == TRUE) 02036 { 02037 /* Search root directory for 'ntldr' and 'boot.ini'. */ 02038 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n"); 02039 02040 /* Copy FreeLoader to the boot partition */ 02041 wcscpy(SrcPath, SourceRootPath->Buffer); 02042 wcscat(SrcPath, L"\\loader\\freeldr.sys"); 02043 wcscpy(DstPath, SystemRootPath->Buffer); 02044 wcscat(DstPath, L"\\freeldr.sys"); 02045 02046 DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath); 02047 Status = SetupCopyFile(SrcPath, DstPath); 02048 if (!NT_SUCCESS(Status)) 02049 { 02050 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status); 02051 return Status; 02052 } 02053 02054 /* Create or update freeldr.ini */ 02055 if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE) 02056 { 02057 /* Create new 'freeldr.ini' */ 02058 DPRINT1("Create new 'freeldr.ini'\n"); 02059 wcscpy(DstPath, SystemRootPath->Buffer); 02060 wcscat(DstPath, L"\\freeldr.ini"); 02061 02062 Status = CreateFreeLoaderIniForReactos(DstPath, 02063 DestinationArcPath->Buffer); 02064 if (!NT_SUCCESS(Status)) 02065 { 02066 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status); 02067 return Status; 02068 } 02069 02070 /* Install new bootcode */ 02071 if (PartitionType == PARTITION_FAT32 || 02072 PartitionType == PARTITION_FAT32_XINT13) 02073 { 02074 /* Install FAT32 bootcode */ 02075 wcscpy(SrcPath, SourceRootPath->Buffer); 02076 wcscat(SrcPath, L"\\loader\\fat32.bin"); 02077 wcscpy(DstPath, SystemRootPath->Buffer); 02078 wcscat(DstPath, L"\\bootsect.ros"); 02079 02080 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, DstPath); 02081 Status = InstallFat32BootCodeToFile(SrcPath, 02082 DstPath, 02083 SystemRootPath->Buffer); 02084 if (!NT_SUCCESS(Status)) 02085 { 02086 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status); 02087 return Status; 02088 } 02089 } 02090 else 02091 { 02092 /* Install FAT16 bootcode */ 02093 wcscpy(SrcPath, SourceRootPath->Buffer); 02094 wcscat(SrcPath, L"\\loader\\fat.bin"); 02095 wcscpy(DstPath, SystemRootPath->Buffer); 02096 wcscat(DstPath, L"\\bootsect.ros"); 02097 02098 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath); 02099 Status = InstallFat16BootCodeToFile(SrcPath, 02100 DstPath, 02101 SystemRootPath->Buffer); 02102 if (!NT_SUCCESS(Status)) 02103 { 02104 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status); 02105 return Status; 02106 } 02107 } 02108 } 02109 else 02110 { 02111 /* Update existing 'freeldr.ini' */ 02112 DPRINT1("Update existing 'freeldr.ini'\n"); 02113 wcscpy(DstPath, SystemRootPath->Buffer); 02114 wcscat(DstPath, L"\\freeldr.ini"); 02115 02116 Status = UpdateFreeLoaderIni(DstPath, 02117 DestinationArcPath->Buffer); 02118 if (!NT_SUCCESS(Status)) 02119 { 02120 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status); 02121 return Status; 02122 } 02123 } 02124 02125 /* Update 'boot.ini' */ 02126 wcscpy(DstPath, SystemRootPath->Buffer); 02127 wcscat(DstPath, L"\\boot.ini"); 02128 02129 DPRINT1("Update 'boot.ini': %S\n", DstPath); 02130 Status = UpdateBootIni(DstPath, 02131 L"C:\\bootsect.ros", 02132 L"\"ReactOS\""); 02133 if (!NT_SUCCESS(Status)) 02134 { 02135 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status); 02136 return Status; 02137 } 02138 } 02139 else if (DoesFileExist(SystemRootPath->Buffer, L"io.sys") == TRUE || 02140 DoesFileExist(SystemRootPath->Buffer, L"msdos.sys") == TRUE) 02141 { 02142 /* Search for root directory for 'io.sys' and 'msdos.sys'. */ 02143 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n"); 02144 02145 /* Copy FreeLoader to the boot partition */ 02146 wcscpy(SrcPath, SourceRootPath->Buffer); 02147 wcscat(SrcPath, L"\\loader\\freeldr.sys"); 02148 wcscpy(DstPath, SystemRootPath->Buffer); 02149 wcscat(DstPath, L"\\freeldr.sys"); 02150 02151 DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath); 02152 Status = SetupCopyFile(SrcPath, DstPath); 02153 if (!NT_SUCCESS(Status)) 02154 { 02155 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status); 02156 return Status; 02157 } 02158 02159 /* Create or update 'freeldr.ini' */ 02160 if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE) 02161 { 02162 /* Create new 'freeldr.ini' */ 02163 DPRINT1("Create new 'freeldr.ini'\n"); 02164 wcscpy(DstPath, SystemRootPath->Buffer); 02165 wcscat(DstPath, L"\\freeldr.ini"); 02166 02167 Status = CreateFreeLoaderIniForDos(DstPath, 02168 DestinationArcPath->Buffer); 02169 if (!NT_SUCCESS(Status)) 02170 { 02171 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status); 02172 return Status; 02173 } 02174 02175 /* Save current bootsector as 'BOOTSECT.DOS' */ 02176 wcscpy(SrcPath, SystemRootPath->Buffer); 02177 wcscpy(DstPath, SystemRootPath->Buffer); 02178 wcscat(DstPath, L"\\bootsect.dos"); 02179 02180 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath, DstPath); 02181 Status = SaveCurrentBootSector(SrcPath, 02182 DstPath); 02183 if (!NT_SUCCESS(Status)) 02184 { 02185 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status); 02186 return Status; 02187 } 02188 02189 /* Install new bootsector */ 02190 if (PartitionType == PARTITION_FAT32 || 02191 PartitionType == PARTITION_FAT32_XINT13) 02192 { 02193 wcscpy(SrcPath, SourceRootPath->Buffer); 02194 wcscat(SrcPath, L"\\loader\\fat32.bin"); 02195 02196 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); 02197 Status = InstallFat32BootCodeToDisk(SrcPath, 02198 SystemRootPath->Buffer); 02199 if (!NT_SUCCESS(Status)) 02200 { 02201 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status); 02202 return Status; 02203 } 02204 } 02205 else 02206 { 02207 wcscpy(SrcPath, SourceRootPath->Buffer); 02208 wcscat(SrcPath, L"\\loader\\fat.bin"); 02209 02210 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); 02211 Status = InstallFat16BootCodeToDisk(SrcPath, 02212 SystemRootPath->Buffer); 02213 if (!NT_SUCCESS(Status)) 02214 { 02215 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status); 02216 return Status; 02217 } 02218 } 02219 } 02220 else 02221 { 02222 /* Update existing 'freeldr.ini' */ 02223 wcscpy(DstPath, SystemRootPath->Buffer); 02224 wcscat(DstPath, L"\\freeldr.ini"); 02225 02226 Status = UpdateFreeLoaderIni(DstPath, DestinationArcPath->Buffer); 02227 if (!NT_SUCCESS(Status)) 02228 { 02229 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status); 02230 return Status; 02231 } 02232 } 02233 } 02234 else 02235 { 02236 /* No or unknown boot loader */ 02237 DPRINT1("No or unknown boot loader found\n"); 02238 02239 /* Copy FreeLoader to the boot partition */ 02240 wcscpy(SrcPath, SourceRootPath->Buffer); 02241 wcscat(SrcPath, L"\\loader\\freeldr.sys"); 02242 wcscpy(DstPath, SystemRootPath->Buffer); 02243 wcscat(DstPath, L"\\freeldr.sys"); 02244 02245 DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath); 02246 Status = SetupCopyFile(SrcPath, DstPath); 02247 if (!NT_SUCCESS(Status)) 02248 { 02249 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status); 02250 return Status; 02251 } 02252 02253 /* Create or update 'freeldr.ini' */ 02254 if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE) 02255 { 02256 /* Create new freeldr.ini */ 02257 wcscpy(DstPath, SystemRootPath->Buffer); 02258 wcscat(DstPath, L"\\freeldr.ini"); 02259 02260 DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath); 02261 Status = CreateFreeLoaderIniForReactos(DstPath, 02262 DestinationArcPath->Buffer); 02263 if (!NT_SUCCESS(Status)) 02264 { 02265 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status); 02266 return Status; 02267 } 02268 02269 /* Save current bootsector as 'BOOTSECT.OLD' */ 02270 wcscpy(SrcPath, SystemRootPath->Buffer); 02271 wcscpy(DstPath, SystemRootPath->Buffer); 02272 wcscat(DstPath, L"\\bootsect.old"); 02273 02274 DPRINT("Save bootsector: %S ==> %S\n", SrcPath, DstPath); 02275 Status = SaveCurrentBootSector(SrcPath, 02276 DstPath); 02277 if (!NT_SUCCESS(Status)) 02278 { 02279 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status); 02280 return Status; 02281 } 02282 02283 /* Install new bootsector */ 02284 if ((PartitionType == PARTITION_FAT32) || 02285 (PartitionType == PARTITION_FAT32_XINT13)) 02286 { 02287 wcscpy(SrcPath, SourceRootPath->Buffer); 02288 wcscat(SrcPath, L"\\loader\\fat32.bin"); 02289 02290 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); 02291 Status = InstallFat32BootCodeToDisk(SrcPath, 02292 SystemRootPath->Buffer); 02293 if (!NT_SUCCESS(Status)) 02294 { 02295 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status); 02296 return Status; 02297 } 02298 } 02299 else 02300 { 02301 wcscpy(SrcPath, SourceRootPath->Buffer); 02302 wcscat(SrcPath, L"\\loader\\fat.bin"); 02303 02304 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer); 02305 Status = InstallFat16BootCodeToDisk(SrcPath, 02306 SystemRootPath->Buffer); 02307 if (!NT_SUCCESS(Status)) 02308 { 02309 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status); 02310 return Status; 02311 } 02312 } 02313 } 02314 else 02315 { 02316 /* Update existing 'freeldr.ini' */ 02317 wcscpy(DstPath, SystemRootPath->Buffer); 02318 wcscat(DstPath, L"\\freeldr.ini"); 02319 02320 Status = UpdateFreeLoaderIni(DstPath, 02321 DestinationArcPath->Buffer); 02322 if (!NT_SUCCESS(Status)) 02323 { 02324 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status); 02325 return Status; 02326 } 02327 } 02328 } 02329 02330 return STATUS_SUCCESS; 02331 #else 02332 return STATUS_NOT_IMPLEMENTED; 02333 #endif 02334 } 02335 02336 NTSTATUS 02337 InstallVBRToPartition( 02338 PUNICODE_STRING SystemRootPath, 02339 PUNICODE_STRING SourceRootPath, 02340 PUNICODE_STRING DestinationArcPath, 02341 UCHAR PartitionType) 02342 { 02343 if ((PartitionType == PARTITION_FAT_12) || 02344 (PartitionType == PARTITION_FAT_16) || 02345 (PartitionType == PARTITION_HUGE) || 02346 (PartitionType == PARTITION_XINT13) || 02347 (PartitionType == PARTITION_FAT32) || 02348 (PartitionType == PARTITION_FAT32_XINT13)) 02349 { 02350 return InstallFatBootcodeToPartition(SystemRootPath, 02351 SourceRootPath, 02352 DestinationArcPath, 02353 PartitionType); 02354 } 02355 02356 return STATUS_UNSUCCESSFUL; 02357 } 02358 02359 02360 NTSTATUS 02361 InstallFatBootcodeToFloppy( 02362 PUNICODE_STRING SourceRootPath, 02363 PUNICODE_STRING DestinationArcPath) 02364 { 02365 #ifdef __REACTOS__ 02366 UNICODE_STRING FloppyDevice = RTL_CONSTANT_STRING(L"\\Device\\Floppy0"); 02367 WCHAR SrcPath[MAX_PATH]; 02368 WCHAR DstPath[MAX_PATH]; 02369 NTSTATUS Status; 02370 02371 /* Format the floppy first */ 02372 Status = VfatFormat(&FloppyDevice, 02373 FMIFS_FLOPPY, 02374 NULL, 02375 TRUE, 02376 0, 02377 NULL); 02378 if (!NT_SUCCESS(Status)) 02379 { 02380 DPRINT1("VfatFormat() failed (Status %lx)\n", Status); 02381 return Status; 02382 } 02383 02384 /* Copy FreeLoader to the boot partition */ 02385 wcscpy(SrcPath, SourceRootPath->Buffer); 02386 wcscat(SrcPath, L"\\loader\\freeldr.sys"); 02387 02388 wcscpy(DstPath, L"\\Device\\Floppy0\\freeldr.sys"); 02389 02390 DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath); 02391 Status = SetupCopyFile(SrcPath, DstPath); 02392 if (!NT_SUCCESS(Status)) 02393 { 02394 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status); 02395 return Status; 02396 } 02397 02398 /* Create new 'freeldr.ini' */ 02399 wcscpy(DstPath, L"\\Device\\Floppy0\\freeldr.ini"); 02400 02401 DPRINT("Create new 'freeldr.ini'\n"); 02402 Status = CreateFreeLoaderIniForReactos(DstPath, DestinationArcPath->Buffer); 02403 if (!NT_SUCCESS(Status)) 02404 { 02405 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status); 02406 return Status; 02407 } 02408 02409 /* Install FAT12/16 boosector */ 02410 wcscpy(SrcPath, SourceRootPath->Buffer); 02411 wcscat(SrcPath, L"\\loader\\fat.bin"); 02412 02413 wcscpy(DstPath, L"\\Device\\Floppy0"); 02414 02415 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath); 02416 Status = InstallFat12BootCodeToFloppy(SrcPath, DstPath); 02417 if (!NT_SUCCESS(Status)) 02418 { 02419 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status); 02420 return Status; 02421 } 02422 02423 return STATUS_SUCCESS; 02424 #else 02425 return STATUS_NOT_IMPLEMENTED; 02426 #endif 02427 } 02428 02429 /* EOF */ Generated on Sun May 27 2012 04:17:57 for ReactOS by
1.7.6.1
|