ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

bootsup.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.