Do not overwrite the disk signature, if we install the boot code into the mbr.
[reactos.git] / reactos / subsys / system / usetup / bootsup.c
index eaa4645..22ce216 100644 (file)
  * PROGRAMMER:      Eric Kohl
  */
 
-#include <ddk/ntddk.h>
-#include <ntdll/rtl.h>
-
-#include "usetup.h"
-#include "inicache.h"
-#include "bootsup.h"
+#include <usetup.h>
 
+#define NDEBUG
+#include <debug.h>
 
 #define SECTORSIZE 512
 
@@ -53,14 +50,12 @@ CreateCommonFreeLoaderSections(PINICACHE IniCache)
                    L"DefaultOS",
                    L"ReactOS");
 
-#if 0
   /* Timeout=10 */
   IniCacheInsertKey(IniSection,
                    NULL,
                    INSERT_LAST,
                    L"TimeOut",
                    L"10");
-#endif
 
   /* Create "Display" section */
   IniSection = IniCacheAppendSection(IniCache,
@@ -245,12 +240,12 @@ CreateFreeLoaderIniForDos(PWCHAR IniPath,
                    L"SystemPath",
                    ArcPath);
 
-  /* Options=/DEBUGPORT=SCREEN */
+  /* Options=/DEBUGPORT=SCREEN /NOGUIBOOT */
   IniCacheInsertKey(IniSection,
                    NULL,
                    INSERT_LAST,
                    L"Options",
-                   L"/DEBUGPORT=SCREEN");
+                   L"/DEBUGPORT=SCREEN /NOGUIBOOT");
 
   /* Create "DOS" section */
   IniSection = IniCacheAppendSection(IniCache,
@@ -356,12 +351,12 @@ CreateFreeLoaderIniForReactos(PWCHAR IniPath,
                    L"SystemPath",
                    ArcPath);
 
-  /* Options=/DEBUGPORT=SCREEN */
+  /* Options=/DEBUGPORT=SCREEN /NOGUIBOOT */
   IniCacheInsertKey(IniSection,
                    NULL,
                    INSERT_LAST,
                    L"Options",
-                   L"/DEBUGPORT=SCREEN");
+                   L"/DEBUGPORT=SCREEN /NOGUIBOOT");
 
   /* Save the ini file */
   IniCacheSave(IniCache, IniPath);
@@ -378,17 +373,21 @@ UpdateFreeLoaderIni(PWCHAR IniPath,
   UNICODE_STRING Name;
   PINICACHE IniCache;
   PINICACHESECTION IniSection;
+  PINICACHESECTION OsIniSection;
   WCHAR SectionName[80];
   WCHAR OsName[80];
+  WCHAR SystemPath[200];
+  WCHAR SectionName2[200];
   PWCHAR KeyData;
-  ULONG i;
+  ULONG i,j;
   NTSTATUS Status;
 
   RtlInitUnicodeString(&Name,
                       IniPath);
 
   Status = IniCacheLoad(&IniCache,
-                       &Name);
+                       &Name,
+                       FALSE);
   if (!NT_SUCCESS(Status))
     return(Status);
 
@@ -396,9 +395,12 @@ UpdateFreeLoaderIni(PWCHAR IniPath,
   IniSection = IniCacheGetSection(IniCache,
                                  L"Operating Systems");
   if (IniSection == NULL)
+  {
+    IniCacheDestroy(IniCache);
     return(STATUS_UNSUCCESSFUL);
+  }
 
-  /* Find an unused section name */
+  /* Find an existing usable or an unused section name */
   i = 1;
   wcscpy(SectionName, L"ReactOS");
   wcscpy(OsName, L"\"ReactOS\"");
@@ -410,6 +412,77 @@ UpdateFreeLoaderIni(PWCHAR IniPath,
     if (!NT_SUCCESS(Status))
       break;
 
+    /* Get operation system section */
+    if (KeyData[0] == '"')
+    {
+      wcscpy(SectionName2, &KeyData[1]);
+      j = wcslen(SectionName2);
+      if (j > 0)
+      {
+        SectionName2[j-1] = 0;
+      }
+    }
+    else
+    {
+      wcscpy(SectionName2, KeyData);
+    }
+
+    OsIniSection = IniCacheGetSection(IniCache,
+      SectionName2);
+    if (OsIniSection != NULL)
+    {
+      BOOLEAN UseExistingEntry = TRUE;
+
+      /* Check BootType */
+      Status = IniCacheGetKey(OsIniSection,
+        L"BootType",
+        &KeyData);
+      if (NT_SUCCESS(Status))
+      {
+        if (KeyData == NULL
+          || (_wcsicmp(KeyData, L"ReactOS") != 0
+          && _wcsicmp(KeyData, L"\"ReactOS\"") != 0))
+        {
+          /* This is not a ReactOS entry */
+          UseExistingEntry = FALSE;
+        }
+      }
+      else
+      {
+        UseExistingEntry = FALSE;
+      }
+
+      if (UseExistingEntry)
+      {
+        /* BootType is ReactOS. Now check SystemPath */
+        Status = IniCacheGetKey(OsIniSection,
+          L"SystemPath",
+          &KeyData);
+        if (NT_SUCCESS(Status))
+        {
+          swprintf(SystemPath, L"\"%S\"", ArcPath);
+          if (KeyData == NULL
+            || (_wcsicmp(KeyData, ArcPath) != 0
+            && _wcsicmp(KeyData, SystemPath) != 0))
+          {
+            /* This entry is a ReactOS entry, but the SystemRoot does not
+               match the one we are looking for */
+            UseExistingEntry = FALSE;
+          }
+        }
+        else
+        {
+          UseExistingEntry = FALSE;
+        }
+      }
+
+      if (UseExistingEntry)
+      {
+        IniCacheDestroy(IniCache);
+        return(STATUS_SUCCESS);
+      }
+    }
+
     swprintf(SectionName, L"ReactOS_%lu", i);
     swprintf(OsName, L"\"ReactOS %lu\"", i);
     i++;
@@ -476,11 +549,11 @@ SaveCurrentBootSector(PWSTR RootPath,
                             NULL);
 
   Status = NtOpenFile(&FileHandle,
-                     FILE_READ_ACCESS,
+                     GENERIC_READ,
                      &ObjectAttributes,
                      &IoStatusBlock,
                      0,
-                     FILE_SYNCHRONOUS_IO_ALERT);
+                     FILE_SYNCHRONOUS_IO_NONALERT);
   if (!NT_SUCCESS(Status))
   {
     RtlFreeHeap(ProcessHeap, 0, BootSector);
@@ -514,14 +587,14 @@ SaveCurrentBootSector(PWSTR RootPath,
                             NULL);
 
   Status = NtCreateFile(&FileHandle,
-                       FILE_WRITE_ACCESS,
+                       GENERIC_WRITE,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        NULL,
                        FILE_ATTRIBUTE_NORMAL,
                        0,
                        FILE_SUPERSEDE,
-                       FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY,
+                       FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY,
                        NULL,
                        0);
   if (!NT_SUCCESS(Status))
@@ -579,11 +652,11 @@ InstallFat16BootCodeToFile(PWSTR SrcPath,
                             NULL);
 
   Status = NtOpenFile(&FileHandle,
-                     FILE_READ_ACCESS,
+                     GENERIC_READ,
                      &ObjectAttributes,
                      &IoStatusBlock,
                      0,
-                     FILE_SYNCHRONOUS_IO_ALERT);
+                     FILE_SYNCHRONOUS_IO_NONALERT);
   if (!NT_SUCCESS(Status))
   {
     RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
@@ -628,11 +701,11 @@ InstallFat16BootCodeToFile(PWSTR SrcPath,
                             NULL);
 
   Status = NtOpenFile(&FileHandle,
-                     FILE_READ_ACCESS,
+                     GENERIC_READ,
                      &ObjectAttributes,
                      &IoStatusBlock,
                      0,
-                     FILE_SYNCHRONOUS_IO_ALERT);
+                     FILE_SYNCHRONOUS_IO_NONALERT);
   if (!NT_SUCCESS(Status))
   {
     RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
@@ -674,14 +747,14 @@ InstallFat16BootCodeToFile(PWSTR SrcPath,
                             NULL);
 
   Status = NtCreateFile(&FileHandle,
-                       FILE_WRITE_ACCESS,
+                       GENERIC_WRITE,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        NULL,
                        FILE_ATTRIBUTE_NORMAL,
                        0,
                        FILE_OVERWRITE_IF,
-                       FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY,
+                       FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY,
                        NULL,
                        0);
   if (!NT_SUCCESS(Status))
@@ -743,11 +816,11 @@ InstallFat32BootCodeToFile(PWSTR SrcPath,
                             NULL);
 
   Status = NtOpenFile(&FileHandle,
-                     FILE_READ_ACCESS,
+                     GENERIC_READ,
                      &ObjectAttributes,
                      &IoStatusBlock,
                      0,
-                     FILE_SYNCHRONOUS_IO_ALERT);
+                     FILE_SYNCHRONOUS_IO_NONALERT);
   if (!NT_SUCCESS(Status))
   {
     RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
@@ -792,11 +865,11 @@ CHECKPOINT1;
                             NULL);
 
   Status = NtOpenFile(&FileHandle,
-                     FILE_READ_ACCESS,
+                     GENERIC_READ,
                      &ObjectAttributes,
                      &IoStatusBlock,
                      0,
-                     FILE_SYNCHRONOUS_IO_ALERT);
+                     FILE_SYNCHRONOUS_IO_NONALERT);
   if (!NT_SUCCESS(Status))
   {
     RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
@@ -827,8 +900,8 @@ CHECKPOINT1;
         87); /* FAT32 BPB length */
 
   /* Disable the backup boot sector */
-  NewBootSector[0x32] = 0xFF;
-  NewBootSector[0x33] = 0xFF;
+  NewBootSector[0x32] = 0x00;
+  NewBootSector[0x33] = 0x00;
 
   /* Free the original boot sector */
   RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
@@ -844,14 +917,14 @@ CHECKPOINT1;
                             NULL);
 
   Status = NtCreateFile(&FileHandle,
-                       FILE_WRITE_ACCESS,
+                       GENERIC_WRITE,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        NULL,
                        FILE_ATTRIBUTE_NORMAL,
                        0,
                        FILE_SUPERSEDE,
-                       FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY,
+                       FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY,
                        NULL,
                        0);
   if (!NT_SUCCESS(Status))
@@ -887,11 +960,11 @@ CHECKPOINT1;
                             NULL);
 
   Status = NtOpenFile(&FileHandle,
-                     FILE_WRITE_ACCESS,
+                     GENERIC_WRITE,
                      &ObjectAttributes,
                      &IoStatusBlock,
                      0,
-                     FILE_SYNCHRONOUS_IO_ALERT);
+                     FILE_SYNCHRONOUS_IO_NONALERT);
   if (!NT_SUCCESS(Status))
   {
     RtlFreeHeap(ProcessHeap, 0, NewBootSector);
@@ -920,6 +993,163 @@ CHECKPOINT1;
 }
 
 
+NTSTATUS
+InstallMbrBootCodeToDisk (PWSTR SrcPath,
+                         PWSTR RootPath)
+{
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  IO_STATUS_BLOCK IoStatusBlock;
+  UNICODE_STRING Name;
+  HANDLE FileHandle;
+  NTSTATUS Status;
+  PPARTITION_SECTOR OrigBootSector;
+  PPARTITION_SECTOR NewBootSector;
+
+  /* Allocate buffer for original bootsector */
+  OrigBootSector = (PPARTITION_SECTOR)RtlAllocateHeap(ProcessHeap,
+                                                     0,
+                                                      sizeof(PARTITION_SECTOR));
+  if (OrigBootSector == NULL)
+    return(STATUS_INSUFFICIENT_RESOURCES);
+
+  /* Read current boot sector into buffer */
+  RtlInitUnicodeString(&Name,
+                      RootPath);
+
+  InitializeObjectAttributes(&ObjectAttributes,
+                            &Name,
+                            OBJ_CASE_INSENSITIVE,
+                            NULL,
+                            NULL);
+
+  Status = NtOpenFile(&FileHandle,
+                     GENERIC_READ,
+                     &ObjectAttributes,
+                     &IoStatusBlock,
+                     0,
+                     FILE_SYNCHRONOUS_IO_NONALERT);
+  if (!NT_SUCCESS(Status))
+  {
+    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+    return(Status);
+  }
+
+  Status = NtReadFile(FileHandle,
+                     NULL,
+                     NULL,
+                     NULL,
+                     &IoStatusBlock,
+                     OrigBootSector,
+                     SECTORSIZE,
+                     NULL,
+                     NULL);
+  NtClose(FileHandle);
+  if (!NT_SUCCESS(Status))
+  {
+    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+    return(Status);
+  }
+
+
+  /* Allocate buffer for new bootsector */
+  NewBootSector = (PPARTITION_SECTOR)RtlAllocateHeap(ProcessHeap,
+                                                    0,
+                                                     sizeof(PARTITION_SECTOR));
+  if (NewBootSector == NULL)
+  {
+    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+    return(STATUS_INSUFFICIENT_RESOURCES);
+  }
+
+  /* Read new bootsector from SrcPath */
+  RtlInitUnicodeString(&Name,
+                      SrcPath);
+
+  InitializeObjectAttributes(&ObjectAttributes,
+                            &Name,
+                            OBJ_CASE_INSENSITIVE,
+                            NULL,
+                            NULL);
+
+  Status = NtOpenFile(&FileHandle,
+                     GENERIC_READ,
+                     &ObjectAttributes,
+                     &IoStatusBlock,
+                     0,
+                     FILE_SYNCHRONOUS_IO_NONALERT);
+  if (!NT_SUCCESS(Status))
+  {
+    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+    RtlFreeHeap(ProcessHeap, 0, NewBootSector);
+    return(Status);
+  }
+
+  Status = NtReadFile(FileHandle,
+                     NULL,
+                     NULL,
+                     NULL,
+                     &IoStatusBlock,
+                     NewBootSector,
+                     sizeof(PARTITION_SECTOR),
+                     NULL,
+                     NULL);
+  NtClose(FileHandle);
+  if (!NT_SUCCESS(Status))
+  {
+    RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+    RtlFreeHeap(ProcessHeap, 0, NewBootSector);
+    return(Status);
+  }
+
+  /* Copy partition table from old MBR to new */
+  RtlCopyMemory (&NewBootSector->Signature,
+                &OrigBootSector->Signature,
+                sizeof(PARTITION_SECTOR) - offsetof(PARTITION_SECTOR, Signature) /* Length of partition table */);
+
+  /* Free the original boot sector */
+  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
+
+  /* Write new bootsector to RootPath */
+  RtlInitUnicodeString(&Name,
+                      RootPath);
+
+  InitializeObjectAttributes(&ObjectAttributes,
+                            &Name,
+                            0,
+                            NULL,
+                            NULL);
+
+  Status = NtOpenFile(&FileHandle,
+                     GENERIC_WRITE,
+                     &ObjectAttributes,
+                     &IoStatusBlock,
+                     0,
+                     FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY);
+  if (!NT_SUCCESS(Status))
+  {
+    DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
+    RtlFreeHeap(ProcessHeap, 0, NewBootSector);
+    return(Status);
+  }
+
+  Status = NtWriteFile(FileHandle,
+                      NULL,
+                      NULL,
+                      NULL,
+                      &IoStatusBlock,
+                      NewBootSector,
+                      SECTORSIZE,
+                      NULL,
+                      NULL);
+  NtClose(FileHandle);
+
+  /* Free the new boot sector */
+  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
+
+  return(Status);
+}
+
+
 NTSTATUS
 InstallFat16BootCodeToDisk(PWSTR SrcPath,
                           PWSTR RootPath)
@@ -950,11 +1180,11 @@ InstallFat16BootCodeToDisk(PWSTR SrcPath,
                             NULL);
 
   Status = NtOpenFile(&FileHandle,
-                     FILE_READ_ACCESS,
+                     GENERIC_READ,
                      &ObjectAttributes,
                      &IoStatusBlock,
                      0,
-                     FILE_SYNCHRONOUS_IO_ALERT);
+                     FILE_SYNCHRONOUS_IO_NONALERT);
   if (!NT_SUCCESS(Status))
   {
     RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
@@ -999,11 +1229,11 @@ InstallFat16BootCodeToDisk(PWSTR SrcPath,
                             NULL);
 
   Status = NtOpenFile(&FileHandle,
-                     FILE_READ_ACCESS,
+                     GENERIC_READ,
                      &ObjectAttributes,
                      &IoStatusBlock,
                      0,
-                     FILE_SYNCHRONOUS_IO_ALERT);
+                     FILE_SYNCHRONOUS_IO_NONALERT);
   if (!NT_SUCCESS(Status))
   {
     RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
@@ -1028,8 +1258,10 @@ InstallFat16BootCodeToDisk(PWSTR SrcPath,
     return(Status);
   }
 
-  /* Adjust bootsector (copy a part of the FAT BPB) */
-  memcpy((NewBootSector + 11), (OrigBootSector + 11), 51 /*fat BPB length*/);
+  /* Adjust bootsector (copy a part of the FAT16 BPB) */
+  memcpy((NewBootSector + 3),
+        (OrigBootSector + 3),
+        59);  /* FAT16 BPB length*/
 
   /* Free the original boot sector */
   RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
@@ -1044,19 +1276,15 @@ InstallFat16BootCodeToDisk(PWSTR SrcPath,
                             NULL,
                             NULL);
 
-  Status = NtCreateFile(&FileHandle,
-                       FILE_WRITE_ACCESS,
-                       &ObjectAttributes,
-                       &IoStatusBlock,
-                       NULL,
-                       FILE_ATTRIBUTE_NORMAL,
-                       0,
-                       FILE_OVERWRITE_IF,
-                       FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY,
-                       NULL,
-                       0);
+  Status = NtOpenFile(&FileHandle,
+                     GENERIC_WRITE,
+                     &ObjectAttributes,
+                     &IoStatusBlock,
+                     0,
+                     FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY);
   if (!NT_SUCCESS(Status))
   {
+    DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
     RtlFreeHeap(ProcessHeap, 0, NewBootSector);
     return(Status);
   }
@@ -1114,11 +1342,11 @@ InstallFat32BootCodeToDisk(PWSTR SrcPath,
                             NULL);
 
   Status = NtOpenFile(&FileHandle,
-                     FILE_READ_ACCESS,
+                     GENERIC_READ,
                      &ObjectAttributes,
                      &IoStatusBlock,
                      0,
-                     FILE_SYNCHRONOUS_IO_ALERT);
+                     FILE_SYNCHRONOUS_IO_NONALERT);
   if (!NT_SUCCESS(Status))
   {
     RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
@@ -1163,11 +1391,11 @@ InstallFat32BootCodeToDisk(PWSTR SrcPath,
                             NULL);
 
   Status = NtOpenFile(&FileHandle,
-                     FILE_READ_ACCESS,
+                     GENERIC_READ,
                      &ObjectAttributes,
                      &IoStatusBlock,
                      0,
-                     FILE_SYNCHRONOUS_IO_ALERT);
+                     FILE_SYNCHRONOUS_IO_NONALERT);
   if (!NT_SUCCESS(Status))
   {
     RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
@@ -1198,7 +1426,7 @@ InstallFat32BootCodeToDisk(PWSTR SrcPath,
         87); /* FAT32 BPB length */
 
   /* Get the location of the backup boot sector */
-  BackupBootSector = (OrigBootSector[0x33] << 8) + OrigBootSector[0x33];
+  BackupBootSector = (OrigBootSector[0x33] << 8) + OrigBootSector[0x32];
 
   /* Free the original boot sector */
   RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
@@ -1214,11 +1442,11 @@ InstallFat32BootCodeToDisk(PWSTR SrcPath,
                             NULL);
 
   Status = NtOpenFile(&FileHandle,
-                     FILE_WRITE_ACCESS | FILE_WRITE_ATTRIBUTES,
+                     GENERIC_WRITE,
                      &ObjectAttributes,
                      &IoStatusBlock,
                      0,
-                     FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY);
+                     FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY);
   if (!NT_SUCCESS(Status))
   {
     DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
@@ -1246,7 +1474,7 @@ InstallFat32BootCodeToDisk(PWSTR SrcPath,
   }
 
   /* Write backup boot sector */
-  if (BackupBootSector != 0xFFFF)
+  if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF))
   {
     FileOffset.QuadPart = (ULONGLONG)((ULONG)BackupBootSector * SECTORSIZE);
     Status = NtWriteFile(FileHandle,
@@ -1312,11 +1540,11 @@ UnprotectBootIni(PWSTR FileName,
                             NULL);
 
   Status = NtOpenFile(&FileHandle,
-                     FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
+                     GENERIC_READ|GENERIC_WRITE,
                      &ObjectAttributes,
                      &IoStatusBlock,
                      0,
-                     FILE_SYNCHRONOUS_IO_ALERT);
+                     FILE_SYNCHRONOUS_IO_NONALERT);
   if (Status == STATUS_NO_SUCH_FILE)
   {
     DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
@@ -1383,11 +1611,11 @@ ProtectBootIni(PWSTR FileName,
                             NULL);
 
   Status = NtOpenFile(&FileHandle,
-                     FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
+                     GENERIC_READ|GENERIC_WRITE,
                      &ObjectAttributes,
                      &IoStatusBlock,
                      0,
-                     FILE_SYNCHRONOUS_IO_ALERT);
+                     FILE_SYNCHRONOUS_IO_NONALERT);
   if (!NT_SUCCESS(Status))
   {
     DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
@@ -1438,10 +1666,10 @@ UpdateBootIni(PWSTR BootIniPath,
                       BootIniPath);
 
   Status = IniCacheLoad(&Cache,
-                       &Name);
+                       &Name,
+                       FALSE);
   if (!NT_SUCCESS(Status))
   {
-CHECKPOINT1;
     return(Status);
   }
 
@@ -1449,7 +1677,6 @@ CHECKPOINT1;
                               L"operating systems");
   if (Section == NULL)
   {
-CHECKPOINT1;
     IniCacheDestroy(Cache);
     return(STATUS_UNSUCCESSFUL);
   }
@@ -1464,7 +1691,6 @@ CHECKPOINT1;
                            &FileAttribute);
   if (!NT_SUCCESS(Status))
   {
-CHECKPOINT1;
     IniCacheDestroy(Cache);
     return(Status);
   }
@@ -1473,7 +1699,6 @@ CHECKPOINT1;
                        BootIniPath);
   if (!NT_SUCCESS(Status))
   {
-CHECKPOINT1;
     IniCacheDestroy(Cache);
     return(Status);
   }
@@ -1487,4 +1712,389 @@ CHECKPOINT1;
   return(Status);
 }
 
-/* EOF */
\ No newline at end of file
+
+BOOLEAN
+CheckInstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath)
+{
+  if (DoesFileExist(SystemRootPath->Buffer, L"ntldr") ||
+      DoesFileExist(SystemRootPath->Buffer, L"boot.ini"))
+    {
+      return TRUE;
+    }
+  else if (DoesFileExist(SystemRootPath->Buffer, L"io.sys") ||
+          DoesFileExist(SystemRootPath->Buffer, L"msdos.sys"))
+    {
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+
+NTSTATUS
+InstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath,
+                             PUNICODE_STRING SourceRootPath,
+                             PUNICODE_STRING DestinationArcPath,
+                             UCHAR PartitionType)
+{
+  WCHAR SrcPath[MAX_PATH];
+  WCHAR DstPath[MAX_PATH];
+  NTSTATUS Status;
+
+  /* FAT or FAT32 partition */
+  DPRINT1("System path: '%wZ'\n", SystemRootPath);
+
+  if (DoesFileExist(SystemRootPath->Buffer, L"ntldr") == TRUE ||
+      DoesFileExist(SystemRootPath->Buffer, L"boot.ini") == TRUE)
+    {
+      /* Search root directory for 'ntldr' and 'boot.ini'. */
+      DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
+
+      /* Copy FreeLoader to the boot partition */
+      wcscpy(SrcPath, SourceRootPath->Buffer);
+      wcscat(SrcPath, L"\\loader\\freeldr.sys");
+      wcscpy(DstPath, SystemRootPath->Buffer);
+      wcscat(DstPath, L"\\freeldr.sys");
+
+      DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
+      Status = SetupCopyFile(SrcPath, DstPath);
+      if (!NT_SUCCESS(Status))
+      {
+       DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
+       return Status;
+      }
+
+      /* Create or update freeldr.ini */
+      if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE)
+      {
+       /* Create new 'freeldr.ini' */
+       DPRINT1("Create new 'freeldr.ini'\n");
+       wcscpy(DstPath, SystemRootPath->Buffer);
+       wcscat(DstPath, L"\\freeldr.ini");
+
+       Status = CreateFreeLoaderIniForReactos(DstPath,
+                                              DestinationArcPath->Buffer);
+       if (!NT_SUCCESS(Status))
+       {
+         DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status);
+         return Status;
+       }
+
+       /* Install new bootcode */
+       if (PartitionType == PARTITION_FAT32 ||
+           PartitionType == PARTITION_FAT32_XINT13)
+       {
+         /* Install FAT32 bootcode */
+         wcscpy(SrcPath, SourceRootPath->Buffer);
+         wcscat(SrcPath, L"\\loader\\fat32.bin");
+         wcscpy(DstPath, SystemRootPath->Buffer);
+         wcscat(DstPath, L"\\bootsect.ros");
+
+         DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, DstPath);
+         Status = InstallFat32BootCodeToFile(SrcPath,
+                                             DstPath,
+                                             SystemRootPath->Buffer);
+         if (!NT_SUCCESS(Status))
+         {
+           DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status);
+           return Status;
+         }
+       }
+       else
+       {
+         /* Install FAT16 bootcode */
+         wcscpy(SrcPath, SourceRootPath->Buffer);
+         wcscat(SrcPath, L"\\loader\\fat.bin");
+         wcscpy(DstPath, SystemRootPath->Buffer);
+         wcscat(DstPath, L"\\bootsect.ros");
+
+         DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath);
+         Status = InstallFat16BootCodeToFile(SrcPath,
+                                             DstPath,
+                                             SystemRootPath->Buffer);
+         if (!NT_SUCCESS(Status))
+         {
+           DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status);
+           return Status;
+         }
+       }
+
+       /* Update 'boot.ini' */
+       wcscpy(DstPath, SystemRootPath->Buffer);
+       wcscat(DstPath, L"\\boot.ini");
+
+       DPRINT1("Update 'boot.ini': %S\n", DstPath);
+       Status = UpdateBootIni(DstPath,
+                              L"C:\\bootsect.ros",
+                              L"\"ReactOS\"");
+       if (!NT_SUCCESS(Status))
+       {
+         DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status);
+         return Status;
+       }
+      }
+      else
+      {
+       /* Update existing 'freeldr.ini' */
+       DPRINT1("Update existing 'freeldr.ini'\n");
+       wcscpy(DstPath, SystemRootPath->Buffer);
+       wcscat(DstPath, L"\\freeldr.ini");
+
+       Status = UpdateFreeLoaderIni(DstPath,
+                                    DestinationArcPath->Buffer);
+       if (!NT_SUCCESS(Status))
+       {
+         DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
+         return Status;
+       }
+      }
+    }
+    else if (DoesFileExist(SystemRootPath->Buffer, L"io.sys") == TRUE ||
+            DoesFileExist(SystemRootPath->Buffer, L"msdos.sys") == TRUE)
+    {
+      /* Search for root directory for 'io.sys' and 'msdos.sys'. */
+      DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
+
+      /* Copy FreeLoader to the boot partition */
+      wcscpy(SrcPath, SourceRootPath->Buffer);
+      wcscat(SrcPath, L"\\loader\\freeldr.sys");
+      wcscpy(DstPath, SystemRootPath->Buffer);
+      wcscat(DstPath, L"\\freeldr.sys");
+
+      DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
+      Status = SetupCopyFile(SrcPath, DstPath);
+      if (!NT_SUCCESS(Status))
+      {
+       DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
+       return Status;
+      }
+
+      /* Create or update 'freeldr.ini' */
+      if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE)
+      {
+       /* Create new 'freeldr.ini' */
+       DPRINT1("Create new 'freeldr.ini'\n");
+       wcscpy(DstPath, SystemRootPath->Buffer);
+       wcscat(DstPath, L"\\freeldr.ini");
+
+       Status = CreateFreeLoaderIniForDos(DstPath,
+                                          DestinationArcPath->Buffer);
+       if (!NT_SUCCESS(Status))
+       {
+         DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status);
+         return Status;
+       }
+
+       /* Save current bootsector as 'BOOTSECT.DOS' */
+       wcscpy(SrcPath, SystemRootPath->Buffer);
+       wcscpy(DstPath, SystemRootPath->Buffer);
+       wcscat(DstPath, L"\\bootsect.dos");
+
+       DPRINT1("Save bootsector: %S ==> %S\n", SrcPath, DstPath);
+       Status = SaveCurrentBootSector(SrcPath,
+                                      DstPath);
+       if (!NT_SUCCESS(Status))
+       {
+         DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status);
+         return Status;
+       }
+
+       /* Install new bootsector */
+       if (PartitionType == PARTITION_FAT32 ||
+           PartitionType == PARTITION_FAT32_XINT13)
+       {
+         wcscpy(SrcPath, SourceRootPath->Buffer);
+         wcscat(SrcPath, L"\\loader\\fat32.bin");
+
+         DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
+         Status = InstallFat32BootCodeToDisk(SrcPath,
+                                             SystemRootPath->Buffer);
+         if (!NT_SUCCESS(Status))
+         {
+           DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status);
+           return Status;
+         }
+       }
+       else
+       {
+         wcscpy(SrcPath, SourceRootPath->Buffer);
+         wcscat(SrcPath, L"\\loader\\fat.bin");
+
+         DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
+         Status = InstallFat16BootCodeToDisk(SrcPath,
+                                             SystemRootPath->Buffer);
+         if (!NT_SUCCESS(Status))
+         {
+           DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status);
+           return Status;
+         }
+       }
+      }
+      else
+      {
+       /* Update existing 'freeldr.ini' */
+       wcscpy(DstPath, SystemRootPath->Buffer);
+       wcscat(DstPath, L"\\freeldr.ini");
+
+       Status = UpdateFreeLoaderIni(DstPath,
+                                    DestinationArcPath->Buffer);
+       if (!NT_SUCCESS(Status))
+       {
+         DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
+         return Status;
+       }
+      }
+    }
+    else
+    {
+      /* No or unknown boot loader */
+      DPRINT1("No or unknown boot loader found\n");
+
+      /* Copy FreeLoader to the boot partition */
+      wcscpy(SrcPath, SourceRootPath->Buffer);
+      wcscat(SrcPath, L"\\loader\\freeldr.sys");
+      wcscpy(DstPath, SystemRootPath->Buffer);
+      wcscat(DstPath, L"\\freeldr.sys");
+
+      DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath);
+      Status = SetupCopyFile(SrcPath, DstPath);
+      if (!NT_SUCCESS(Status))
+      {
+       DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
+       return Status;
+      }
+
+      /* Create or update 'freeldr.ini' */
+      if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE)
+      {
+       /* Create new freeldr.ini */
+       wcscpy(DstPath, SystemRootPath->Buffer);
+       wcscat(DstPath, L"\\freeldr.ini");
+
+       DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath);
+       Status = CreateFreeLoaderIniForReactos(DstPath,
+                                              DestinationArcPath->Buffer);
+       if (!NT_SUCCESS(Status))
+       {
+         DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status);
+         return Status;
+       }
+
+       /* Save current bootsector as 'BOOTSECT.OLD' */
+       wcscpy(SrcPath, SystemRootPath->Buffer);
+       wcscpy(DstPath, SystemRootPath->Buffer);
+       wcscat(DstPath, L"\\bootsect.old");
+
+       DPRINT1("Save bootsector: %S ==> %S\n", SrcPath, DstPath);
+       Status = SaveCurrentBootSector(SrcPath,
+                                      DstPath);
+       if (!NT_SUCCESS(Status))
+       {
+         DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status);
+         return Status;
+       }
+
+       /* Install new bootsector */
+       if (PartitionType == PARTITION_FAT32 ||
+           PartitionType == PARTITION_FAT32_XINT13)
+       {
+         wcscpy(SrcPath, SourceRootPath->Buffer);
+         wcscat(SrcPath, L"\\loader\\fat32.bin");
+
+         DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
+         Status = InstallFat32BootCodeToDisk(SrcPath,
+                                             SystemRootPath->Buffer);
+         if (!NT_SUCCESS(Status))
+         {
+           DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status);
+           return Status;
+         }
+       }
+       else
+       {
+         wcscpy(SrcPath, SourceRootPath->Buffer);
+         wcscat(SrcPath, L"\\loader\\fat.bin");
+
+         DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
+         Status = InstallFat16BootCodeToDisk(SrcPath,
+                                             SystemRootPath->Buffer);
+         if (!NT_SUCCESS(Status))
+         {
+           DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status);
+           return Status;
+         }
+       }
+      }
+      else
+      {
+       /* Update existing 'freeldr.ini' */
+       wcscpy(DstPath, SystemRootPath->Buffer);
+       wcscat(DstPath, L"\\freeldr.ini");
+
+       Status = UpdateFreeLoaderIni(DstPath,
+                                    DestinationArcPath->Buffer);
+       if (!NT_SUCCESS(Status))
+       {
+         DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
+         return Status;
+       }
+      }
+    }
+
+  return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+InstallFatBootcodeToFloppy(PUNICODE_STRING SourceRootPath,
+                          PUNICODE_STRING DestinationArcPath)
+{
+  WCHAR SrcPath[MAX_PATH];
+  WCHAR DstPath[MAX_PATH];
+  NTSTATUS Status;
+
+  /* Copy FreeLoader to the boot partition */
+  wcscpy(SrcPath, SourceRootPath->Buffer);
+  wcscat(SrcPath, L"\\loader\\freeldr.sys");
+
+  wcscpy(DstPath, L"\\Device\\Floppy0\\freeldr.sys");
+
+  DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
+  Status = SetupCopyFile(SrcPath, DstPath);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
+      return Status;
+    }
+
+  /* Create new 'freeldr.ini' */
+  wcscpy(DstPath, L"\\Device\\Floppy0\\freeldr.ini");
+
+  DPRINT("Create new 'freeldr.ini'\n");
+  Status = CreateFreeLoaderIniForReactos(DstPath,
+                                        DestinationArcPath->Buffer);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status);
+      return Status;
+    }
+
+  /* Install FAT12/16 boosector */
+  wcscpy(SrcPath, SourceRootPath->Buffer);
+  wcscat(SrcPath, L"\\loader\\fat.bin");
+
+  wcscpy(DstPath, L"\\Device\\Floppy0");
+
+  DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath);
+  Status = InstallFat16BootCodeToDisk(SrcPath,
+                                     DstPath);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status);
+      return Status;
+    }
+
+  return STATUS_SUCCESS;
+}
+
+/* EOF */