branch update for HEAD-2003091401
[reactos.git] / subsys / system / usetup / usetup.c
index 96620cf..6f47017 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ReactOS kernel
 /*
  *  ReactOS kernel
- *  Copyright (C) 2002 ReactOS Team
+ *  Copyright (C) 2002, 2003 ReactOS Team
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
 #include "bootsup.h"
 #include "registry.h"
 #include "format.h"
 #include "bootsup.h"
 #include "registry.h"
 #include "format.h"
+#include "fslist.h"
+#include "cabinet.h"
 
 #define NDEBUG
 #include <debug.h>
 
 
 #define NDEBUG
 #include <debug.h>
 
+
 typedef enum _PAGE_NUMBER
 {
   START_PAGE,
 typedef enum _PAGE_NUMBER
 {
   START_PAGE,
@@ -53,9 +56,12 @@ typedef enum _PAGE_NUMBER
 
   SELECT_PARTITION_PAGE,
   CREATE_PARTITION_PAGE,
 
   SELECT_PARTITION_PAGE,
   CREATE_PARTITION_PAGE,
+  DELETE_PARTITION_PAGE,
+
   SELECT_FILE_SYSTEM_PAGE,
   FORMAT_PARTITION_PAGE,
   CHECK_FILE_SYSTEM_PAGE,
   SELECT_FILE_SYSTEM_PAGE,
   FORMAT_PARTITION_PAGE,
   CHECK_FILE_SYSTEM_PAGE,
+
   PREPARE_COPY_PAGE,
   INSTALL_DIRECTORY_PAGE,
   FILE_COPY_PAGE,
   PREPARE_COPY_PAGE,
   INSTALL_DIRECTORY_PAGE,
   FILE_COPY_PAGE,
@@ -64,6 +70,8 @@ typedef enum _PAGE_NUMBER
 
   REPAIR_INTRO_PAGE,
 
 
   REPAIR_INTRO_PAGE,
 
+  EMERGENCY_INTRO_PAGE,
+
   SUCCESS_PAGE,
   QUIT_PAGE,
   REBOOT_PAGE,                 /* virtual page */
   SUCCESS_PAGE,
   QUIT_PAGE,
   REBOOT_PAGE,                 /* virtual page */
@@ -82,29 +90,31 @@ typedef struct _COPYCONTEXT
 HANDLE ProcessHeap;
 UNICODE_STRING SourceRootPath;
 
 HANDLE ProcessHeap;
 UNICODE_STRING SourceRootPath;
 
+
 /* LOCALS *******************************************************************/
 
 /* LOCALS *******************************************************************/
 
-static BOOLEAN PartDataValid;
-static PARTDATA PartData;
+static PPARTLIST PartitionList = NULL;
+
+static PFILE_SYSTEM_LIST FileSystemList = NULL;
 
 
-static BOOLEAN ActivePartitionValid;
-static PARTDATA ActivePartition;
 
 static UNICODE_STRING SourcePath;
 
 static UNICODE_STRING InstallPath;
 
 static UNICODE_STRING SourcePath;
 
 static UNICODE_STRING InstallPath;
+
+/* Path to the install directory */
 static UNICODE_STRING DestinationPath;
 static UNICODE_STRING DestinationArcPath;
 static UNICODE_STRING DestinationRootPath;
 
 static UNICODE_STRING DestinationPath;
 static UNICODE_STRING DestinationArcPath;
 static UNICODE_STRING DestinationRootPath;
 
-static UNICODE_STRING SystemRootPath; /* Path to the active partition */
+/* Path to the active partition (boot manager) */
+static UNICODE_STRING SystemRootPath;
 
 static HINF SetupInf;
 
 static HSPFILEQ SetupFileQueue = NULL;
 
 
 static HINF SetupInf;
 
 static HSPFILEQ SetupFileQueue = NULL;
 
-static PPARTLIST CurrentPartitionList = NULL;
-static PFILE_SYSTEM_LIST CurrentFileSystemList;
+static BOOLEAN WarnLinuxPartitions = TRUE;
 
 
 /* FUNCTIONS ****************************************************************/
 
 
 /* FUNCTIONS ****************************************************************/
@@ -354,8 +364,8 @@ ConfirmQuit(PINPUT_RECORD Ir)
             "computer. If you quit Setup now, you will need to\n"
             "run Setup again to install ReactOS.\n"
             "\n"
             "computer. If you quit Setup now, you will need to\n"
             "run Setup again to install ReactOS.\n"
             "\n"
-            "  * Press ENTER to continue Setup.\n"
-            "  * Press F3 to quit Setup.",
+            "  \x07  Press ENTER to continue Setup.\n"
+            "  \x07  Press F3 to quit Setup.",
             "F3= Quit  ENTER = Continue");
 
   while(TRUE)
             "F3= Quit  ENTER = Continue");
 
   while(TRUE)
@@ -391,12 +401,10 @@ StartPage(PINPUT_RECORD Ir)
   NTSTATUS Status;
   WCHAR FileNameBuffer[MAX_PATH];
   UNICODE_STRING FileName;
   NTSTATUS Status;
   WCHAR FileNameBuffer[MAX_PATH];
   UNICODE_STRING FileName;
-
   INFCONTEXT Context;
   PWCHAR Value;
   ULONG ErrorLine;
 
   INFCONTEXT Context;
   PWCHAR Value;
   ULONG ErrorLine;
 
-
   SetStatusText("   Please wait...");
 
   Status = GetSourcePaths(&SourcePath,
   SetStatusText("   Please wait...");
 
   Status = GetSourcePaths(&SourcePath,
@@ -404,17 +412,29 @@ StartPage(PINPUT_RECORD Ir)
   if (!NT_SUCCESS(Status))
     {
       PrintTextXY(6, 15, "GetSourcePath() failed (Status 0x%08lx)", Status);
   if (!NT_SUCCESS(Status))
     {
       PrintTextXY(6, 15, "GetSourcePath() failed (Status 0x%08lx)", Status);
+      PopupError("Setup could not find its source drive.\n",
+                "ENTER = Reboot computer");
+      while(TRUE)
+       {
+         ConInKey(Ir);
+
+         if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
+           {
+             return(QUIT_PAGE);
+           }
+       }
     }
     }
+#if 0
   else
     {
       PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath);
       PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath);
     }
   else
     {
       PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath);
       PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath);
     }
-
+#endif
 
   /* Load txtsetup.sif from install media. */
   wcscpy(FileNameBuffer, SourceRootPath.Buffer);
 
   /* Load txtsetup.sif from install media. */
   wcscpy(FileNameBuffer, SourceRootPath.Buffer);
-  wcscat(FileNameBuffer, L"\\install\\txtsetup.sif");
+  wcscat(FileNameBuffer, L"\\reactos\\txtsetup.sif");
   RtlInitUnicodeString(&FileName,
                       FileNameBuffer);
 
   RtlInitUnicodeString(&FileName,
                       FileNameBuffer);
 
@@ -493,18 +513,70 @@ StartPage(PINPUT_RECORD Ir)
 }
 
 
 }
 
 
+/*
+ * First setup page
+ * RETURNS
+ *     Next page number.
+ */
+static PAGE_NUMBER
+IntroPage(PINPUT_RECORD Ir)
+{
+  SetHighlightedTextXY(6, 8, "Welcome to ReactOS Setup");
+
+  SetTextXY(6, 11, "This part of the setup copies the ReactOS Operating System to your");
+  SetTextXY(6, 12, "computer and prepares the second part of the setup.");
+
+  SetTextXY(8, 15, "\x07  Press ENTER to install ReactOS.");
+
+  SetTextXY(8, 17, "\x07  Press E to start the emergency console.");
+
+  SetTextXY(8, 19, "\x07  Press R to repair ReactOS.");
+
+  SetTextXY(8, 21, "\x07  Press F3 to quit without installing ReactOS.");
+
+
+  SetStatusText("   ENTER = Continue   F3 = Quit");
+
+  while(TRUE)
+    {
+      ConInKey(Ir);
+
+      if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
+       {
+         if (ConfirmQuit(Ir) == TRUE)
+           return(QUIT_PAGE);
+         break;
+       }
+      else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+       {
+         return(INSTALL_INTRO_PAGE);
+       }
+      else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'E') /* E */
+       {
+         return(EMERGENCY_INTRO_PAGE);
+       }
+      else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'R') /* R */
+       {
+         return(REPAIR_INTRO_PAGE);
+       }
+    }
+
+  return(INTRO_PAGE);
+}
+
 
 static PAGE_NUMBER
 
 static PAGE_NUMBER
-RepairIntroPage(PINPUT_RECORD Ir)
+EmergencyIntroPage(PINPUT_RECORD Ir)
 {
   SetTextXY(6, 8, "ReactOS Setup is in an early development phase. It does not yet");
   SetTextXY(6, 9, "support all the functions of a fully usable setup application.");
 
 {
   SetTextXY(6, 8, "ReactOS Setup is in an early development phase. It does not yet");
   SetTextXY(6, 9, "support all the functions of a fully usable setup application.");
 
-  SetTextXY(6, 12, "The repair functions are not implemented yet.");
+  SetTextXY(6, 12, "The emergency console is not implemented yet.");
 
 
-  SetTextXY(8, 15, "\xfa  Press ESC to return to the main page.");
+  SetTextXY(8, 15, "\x07  Press ESC to return to the main page.");
 
 
-  SetTextXY(8, 17, "\xfa  Press ENTER to reboot your computer.");
+  SetTextXY(8, 17, "\x07  Press ENTER to reboot your computer.");
 
   SetStatusText("   ESC = Main page  ENTER = Reboot");
 
 
   SetStatusText("   ESC = Main page  ENTER = Reboot");
 
@@ -527,59 +599,36 @@ RepairIntroPage(PINPUT_RECORD Ir)
 }
 
 
 }
 
 
-/*
- * First setup page
- * RETURNS
- *     TRUE: setup/repair completed successfully
- *     FALSE: setup/repair terminated by user
- */
 static PAGE_NUMBER
 static PAGE_NUMBER
-IntroPage(PINPUT_RECORD Ir)
+RepairIntroPage(PINPUT_RECORD Ir)
 {
 {
-  SetHighlightedTextXY(6, 8, "Welcome to ReactOS Setup");
-
-  SetTextXY(6, 11, "This part of the setup copies the ReactOS Operating System to your");
-  SetTextXY(6, 12, "computer and prepares the second part of the setup.");
-
-  SetTextXY(8, 15, "\xfa  Press ENTER to install ReactOS.");
-
-  SetTextXY(8, 17, "\xfa  Press E to start the emergency repair console.");
+  SetTextXY(6, 8, "ReactOS Setup is in an early development phase. It does not yet");
+  SetTextXY(6, 9, "support all the functions of a fully usable setup application.");
 
 
-  SetTextXY(8, 19, "\xfa  Press R to repair ReactOS.");
+  SetTextXY(6, 12, "The repair functions are not implemented yet.");
 
 
-  SetTextXY(8, 21, "\xfa  Press F3 to quit without installing ReactOS.");
+  SetTextXY(8, 15, "\x07  Press ESC to return to the main page.");
 
 
+  SetTextXY(8, 17, "\x07  Press ENTER to reboot your computer.");
 
 
-  SetStatusText("   ENTER = Continue   F3 = Quit");
+  SetStatusText("   ESC = Main page  ENTER = Reboot");
 
   while(TRUE)
     {
       ConInKey(Ir);
 
 
   while(TRUE)
     {
       ConInKey(Ir);
 
-      if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
-         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
-       {
-         if (ConfirmQuit(Ir) == TRUE)
-           return(QUIT_PAGE);
-         break;
-       }
-      else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
-       {
-         return(INSTALL_INTRO_PAGE);
-       }
-#if 0
-      else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'E') /* E */
+      if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
        {
        {
-         return(RepairConsole());
+         return(REBOOT_PAGE);
        }
        }
-#endif
-      else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'R') /* R */
+      else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+              (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */
        {
        {
-         return(REPAIR_INTRO_PAGE);
+         return(INTRO_PAGE);
        }
     }
 
        }
     }
 
-  return(INTRO_PAGE);
+  return(REPAIR_INTRO_PAGE);
 }
 
 
 }
 
 
@@ -597,9 +646,9 @@ InstallIntroPage(PINPUT_RECORD Ir)
 
 
 
 
 
 
-  SetTextXY(8, 21, "\xfa  Press ENTER to install ReactOS.");
+  SetTextXY(8, 21, "\x07  Press ENTER to install ReactOS.");
 
 
-  SetTextXY(8, 23, "\xfa  Press F3 to quit without installing ReactOS.");
+  SetTextXY(8, 23, "\x07  Press F3 to quit without installing ReactOS.");
 
 
   SetStatusText("   ENTER = Continue   F3 = Quit");
 
 
   SetStatusText("   ENTER = Continue   F3 = Quit");
@@ -625,83 +674,83 @@ InstallIntroPage(PINPUT_RECORD Ir)
 }
 
 
 }
 
 
-/*
- * Confirm delete partition
- * RETURNS
- *   TRUE: Delete currently selected partition.
- *   FALSE: Don't delete currently selected partition.
- */
-static BOOL
-ConfirmDeletePartition(PINPUT_RECORD Ir)
-{
-  BOOL Result = FALSE;
-
-  PopupError("Are you sure you want to delete this partition?\n"
-            "\n"
-            "  * Press ENTER to delete the partition.\n"
-            "  * Press ESC to NOT delete the partition.",
-            "ESC = Cancel  ENTER = Delete partition");
-
-  while(TRUE)
-    {
-      ConInKey(Ir);
-
-      if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)  /* ESC */
-       {
-         Result = FALSE;
-         break;
-       }
-      else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN)        /* ENTER */
-       {
-         Result = TRUE;
-         break;
-       }
-    }
-
-  return(Result);
-}
-
-
 static PAGE_NUMBER
 SelectPartitionPage(PINPUT_RECORD Ir)
 {
 static PAGE_NUMBER
 SelectPartitionPage(PINPUT_RECORD Ir)
 {
-  WCHAR PathBuffer[MAX_PATH];
-  PPARTLIST PartList;
   SHORT xScreen;
   SHORT yScreen;
 
   SetTextXY(6, 8, "The list below shows existing partitions and unused disk");
   SetTextXY(6, 9, "space for new partitions.");
 
   SHORT xScreen;
   SHORT yScreen;
 
   SetTextXY(6, 8, "The list below shows existing partitions and unused disk");
   SetTextXY(6, 9, "space for new partitions.");
 
-  SetTextXY(8, 11, "\xfa  Press UP or DOWN to select a list entry.");
-  SetTextXY(8, 13, "\xfa  Press ENTER to install ReactOS onto the selected partition.");
-  SetTextXY(8, 15, "\xfa  Press C to create a new partition.");
-  SetTextXY(8, 17, "\xfa  Press D to delete an existing partition.");
+  SetTextXY(8, 11, "\x07  Press UP or DOWN to select a list entry.");
+  SetTextXY(8, 13, "\x07  Press ENTER to install ReactOS onto the selected partition.");
+  SetTextXY(8, 15, "\x07  Press C to create a new partition.");
+  SetTextXY(8, 17, "\x07  Press D to delete an existing partition.");
 
   SetStatusText("   Please wait...");
 
 
   SetStatusText("   Please wait...");
 
-  RtlFreeUnicodeString(&DestinationPath);
-  RtlFreeUnicodeString(&DestinationRootPath);
-
   GetScreenSize(&xScreen, &yScreen);
 
   GetScreenSize(&xScreen, &yScreen);
 
-  PartList = CreatePartitionList(2, 19, xScreen - 3, yScreen - 3);
-  if (PartList == NULL)
+  if (PartitionList == NULL)
     {
     {
-      /* FIXME: show an error dialog */
-      return(QUIT_PAGE);
+      PartitionList = CreatePartitionList (2,
+                                          19,
+                                          xScreen - 3,
+                                          yScreen - 3);
+      if (PartitionList == NULL)
+       {
+         /* FIXME: show an error dialog */
+         return(QUIT_PAGE);
+       }
     }
 
     }
 
-  if (CurrentPartitionList != NULL)
+  CheckActiveBootPartition (PartitionList);
+
+  DrawPartitionList (PartitionList);
+
+  /* Warn about partitions created by Linux Fdisk */
+  if (WarnLinuxPartitions == TRUE &&
+      CheckForLinuxFdiskPartitions (PartitionList) == TRUE)
     {
     {
-      DestroyPartitionList(CurrentPartitionList);
-    }
-  CurrentPartitionList = PartList;
+      PopupError ("Setup found that at least one harddisk contains an incompatible\n"
+                 "partition table that can not be handled properly!\n"
+                 "\n"
+                 "Creating or deleting partitions can destroy the partiton table.\n"
+                 "\n"
+                 "  \x07  Press F3 to quit Setup."
+                 "  \x07  Press ENTER to continue.",
+                 "F3= Quit  ENTER = Continue");
+      while (TRUE)
+       {
+         ConInKey (Ir);
 
 
-  SetStatusText("   ENTER = Continue   F3 = Quit");
+         if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+             (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
+           {
+             return QUIT_PAGE;
+           }
+         else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
+           {
+             WarnLinuxPartitions = FALSE;
+             return SELECT_PARTITION_PAGE;
+           }
+       }
+    }
 
   while(TRUE)
     {
 
   while(TRUE)
     {
+      /* Update status text */
+      if (PartitionList->CurrentPartition == NULL ||
+         PartitionList->CurrentPartition->Unpartitioned == TRUE)
+       {
+         SetStatusText ("   ENTER = Install   C = Create Partition   F3 = Quit");
+       }
+      else
+       {
+         SetStatusText ("   ENTER = Install   D = Delete Partition   F3 = Quit");
+       }
+
       ConInKey(Ir);
 
       if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
       ConInKey(Ir);
 
       if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
@@ -709,91 +758,71 @@ SelectPartitionPage(PINPUT_RECORD Ir)
        {
          if (ConfirmQuit(Ir) == TRUE)
            {
        {
          if (ConfirmQuit(Ir) == TRUE)
            {
-             DestroyPartitionList(PartList);
-             return(QUIT_PAGE);
+             DestroyPartitionList (PartitionList);
+             PartitionList = NULL;
+             return QUIT_PAGE;
            }
          break;
        }
       else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
               (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
        {
            }
          break;
        }
       else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
               (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
        {
-         ScrollDownPartitionList(PartList);
+         ScrollDownPartitionList (PartitionList);
        }
       else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
               (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
        {
        }
       else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
               (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
        {
-         ScrollUpPartitionList(PartList);
+         ScrollUpPartitionList (PartitionList);
        }
       else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
        {
        }
       else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
        {
-         PartDataValid = GetSelectedPartition(PartList,
-                                              &PartData);
-    if (PartDataValid)
-      {
-         ActivePartitionValid = GetActiveBootPartition(PartList,
-                                                       &ActivePartition);
-    
-         RtlFreeUnicodeString(&DestinationRootPath);
-         swprintf(PathBuffer,
-                  L"\\Device\\Harddisk%lu\\Partition%lu",
-                  PartData.DiskNumber,
-                  PartData.PartNumber);
-         RtlCreateUnicodeString(&DestinationRootPath,
-                                PathBuffer);
-    
-         RtlFreeUnicodeString(&SystemRootPath);
-    
-          if (ActivePartitionValid)
-            {
-             swprintf(PathBuffer,
-                   L"\\Device\\Harddisk%lu\\Partition%lu",
-                   ActivePartition.DiskNumber,
-                   ActivePartition.PartNumber);
-            }
-          else
-            {
-              /* We mark the selected partition as bootable */
-             swprintf(PathBuffer,
-                   L"\\Device\\Harddisk%lu\\Partition%lu",
-                   PartData.DiskNumber,
-                   PartData.PartNumber);
-            }
-         RtlCreateUnicodeString(&SystemRootPath,
-                                PathBuffer);
-    
-         return(SELECT_FILE_SYSTEM_PAGE);
-      }
-    else
-      {
-        /* FIXME: show an error dialog */
-        return(SELECT_PARTITION_PAGE);
-      }
+         if (PartitionList->CurrentPartition == NULL ||
+             PartitionList->CurrentPartition->Unpartitioned == TRUE)
+           {
+             CreateNewPartition (PartitionList,
+                                 0ULL,
+                                 TRUE);
+           }
+
+         return SELECT_FILE_SYSTEM_PAGE;
        }
       else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_C) /* C */
        {
        }
       else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_C) /* C */
        {
-#ifdef ENABLE_FORMAT
-    /* Don't destroy the parition list here */;
-    return(CREATE_PARTITION_PAGE);
-#endif
+         if (PartitionList->CurrentPartition->Unpartitioned == FALSE)
+           {
+             PopupError ("You can not create a new Partition inside\n"
+                         "of an already existing Partition!\n"
+                         "\n"
+                         "  * Press any key to continue.",
+                         NULL);
+             ConInKey (Ir);
+
+             return SELECT_PARTITION_PAGE;
+           }
+
+         return CREATE_PARTITION_PAGE;
        }
       else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_D) /* D */
        {
        }
       else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_D) /* D */
        {
-#ifdef ENABLE_FORMAT
-         if (ConfirmDeletePartition(Ir) == TRUE)
-      {
-        (BOOLEAN) DeleteSelectedPartition(CurrentPartitionList);
-      }
-    return(SELECT_PARTITION_PAGE);
-#endif
-       }
+         if (PartitionList->CurrentPartition->Unpartitioned == TRUE)
+           {
+             PopupError ("You can not delete unpartitioned disk space!\n"
+                         "\n"
+                         "  * Press any key to continue.",
+                         NULL);
+             ConInKey (Ir);
 
 
-      /* FIXME: Update status text */
+             return SELECT_PARTITION_PAGE;
+           }
 
 
+         return DELETE_PARTITION_PAGE;
+       }
     }
 
     }
 
-  return(SELECT_PARTITION_PAGE);
+  return SELECT_PARTITION_PAGE;
 }
 
 }
 
+
 static VOID
 DrawInputField(ULONG FieldLength,
   SHORT Left,
 static VOID
 DrawInputField(ULONG FieldLength,
   SHORT Left,
@@ -808,46 +837,41 @@ DrawInputField(ULONG FieldLength,
   memset(buf, '_', sizeof(buf));
   buf[FieldLength - strlen(FieldContent)] = 0;
   strcat(buf, FieldContent);
   memset(buf, '_', sizeof(buf));
   buf[FieldLength - strlen(FieldContent)] = 0;
   strcat(buf, FieldContent);
-  WriteConsoleOutputCharacters(buf,
-              strlen(buf),
-              coPos);
+
+  WriteConsoleOutputCharacters (buf,
+                               strlen (buf),
+                               coPos);
 }
 
 }
 
+
 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
 
 static VOID
 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
 
 static VOID
-ShowPartitionSizeInputBox(ULONG MaxSize,
-  PCHAR InputBuffer,
-  PBOOLEAN Quit,
-  PBOOLEAN Cancel)
+ShowPartitionSizeInputBox(SHORT Left,
+                         SHORT Top,
+                         SHORT Right,
+                         SHORT Bottom,
+                         ULONG MaxSize,
+                         PCHAR InputBuffer,
+                         PBOOLEAN Quit,
+                         PBOOLEAN Cancel)
 {
 {
-  SHORT Left;
-  SHORT Top;
-  SHORT Right;
-  SHORT Bottom;
   INPUT_RECORD Ir;
   COORD coPos;
   ULONG Written;
   SHORT i;
   INPUT_RECORD Ir;
   COORD coPos;
   ULONG Written;
   SHORT i;
-  CHAR buf[100];
-  ULONG index;
+  CHAR Buffer[100];
+  ULONG Index;
   CHAR ch;
   SHORT iLeft;
   SHORT iTop;
   CHAR ch;
   SHORT iLeft;
   SHORT iTop;
-  SHORT xScreen;
-  SHORT yScreen;
 
   if (Quit != NULL)
     *Quit = FALSE;
 
   if (Quit != NULL)
     *Quit = FALSE;
+
   if (Cancel != NULL)
     *Cancel = FALSE;
 
   if (Cancel != NULL)
     *Cancel = FALSE;
 
-  GetScreenSize(&xScreen, &yScreen);
-  Left = 12;
-  Top = 11;
-  Right = xScreen - 12;
-  Bottom = 15;
-
   /* draw upper left corner */
   coPos.X = Left;
   coPos.Y = Top;
   /* draw upper left corner */
   coPos.X = Left;
   coPos.Y = Top;
@@ -916,75 +940,86 @@ ShowPartitionSizeInputBox(ULONG MaxSize,
   /* Print message */
   coPos.X = Left + 2;
   coPos.Y = Top + 2;
   /* Print message */
   coPos.X = Left + 2;
   coPos.Y = Top + 2;
-  strcpy(buf, "Size of new partition:");
-  iLeft = coPos.X + strlen(buf) + 1;
+  strcpy (Buffer, "Size of new partition:");
+  iLeft = coPos.X + strlen (Buffer) + 1;
   iTop = coPos.Y;
   iTop = coPos.Y;
-  WriteConsoleOutputCharacters(buf,
-                      strlen(buf),
-                      coPos);
+  WriteConsoleOutputCharacters (Buffer,
+                                strlen (Buffer),
+                                coPos);
 
 
-  sprintf(buf, "MB (max. %d MB)", MaxSize / (1024 * 1024));
+  sprintf (Buffer, "MB (max. %d MB)", MaxSize);
   coPos.X = iLeft + PARTITION_SIZE_INPUT_FIELD_LENGTH + 1;
   coPos.Y = iTop;
   coPos.X = iLeft + PARTITION_SIZE_INPUT_FIELD_LENGTH + 1;
   coPos.Y = iTop;
-  WriteConsoleOutputCharacters(buf,
-                      strlen(buf),
-                      coPos);
+  WriteConsoleOutputCharacters (Buffer,
+                               strlen (Buffer),
+                               coPos);
 
 
-  buf[0] = 0;
-  index = 0;
-  DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH, iLeft, iTop, buf);
+  Buffer[0] = 0;
+  Index = 0;
+  DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH,
+                 iLeft,
+                 iTop,
+                 Buffer);
 
 
-  while(TRUE)
+  while (TRUE)
     {
     {
-      ConInKey(&Ir);
+      ConInKey (&Ir);
+
       if ((Ir.Event.KeyEvent.uChar.AsciiChar == 0x00) &&
       if ((Ir.Event.KeyEvent.uChar.AsciiChar == 0x00) &&
-           (Ir.Event.KeyEvent.wVirtualKeyCode == VK_F3))       /* F3 */
-       {
-          if (Quit != NULL)
-            *Quit = TRUE;
-          buf[0] = 0;
-         break;
-       }
+         (Ir.Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
+       {
+         if (Quit != NULL)
+           *Quit = TRUE;
+         Buffer[0] = 0;
+         break;
+       }
       else if (Ir.Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
       else if (Ir.Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
-       {
-                 break;
-       }
+       {
+         break;
+       }
       else if (Ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESCAPE */
       else if (Ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESCAPE */
-       {
-          if (Cancel != NULL)
-            *Cancel = FALSE;
-          buf[0] = 0;
-                 break;
-       }
-      else if ((Ir.Event.KeyEvent.wVirtualKeyCode == VK_BACK) && (index > 0)) /* BACKSPACE */
-       {
-          index--;
-          buf[index] = 0;
-          DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH, iLeft, iTop, buf);
-       }
-      else if ((Ir.Event.KeyEvent.uChar.AsciiChar != 0x00)
-        && (index < PARTITION_SIZE_INPUT_FIELD_LENGTH))
-        {
-          ch = Ir.Event.KeyEvent.uChar.AsciiChar;
-          if ((ch >= '0') && (ch <= '9'))
-            {
-              buf[index] = ch;
-              index++;
-              buf[index] = 0;
-              DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH, iLeft, iTop, buf);
-            }
-        }
+       {
+         if (Cancel != NULL)
+           *Cancel = TRUE;
+         Buffer[0] = 0;
+         break;
+       }
+      else if ((Ir.Event.KeyEvent.wVirtualKeyCode == VK_BACK) &&  /* BACKSPACE */
+              (Index > 0))
+       {
+         Index--;
+         Buffer[Index] = 0;
+         DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH,
+                         iLeft,
+                         iTop,
+                         Buffer);
+       }
+      else if ((Ir.Event.KeyEvent.uChar.AsciiChar != 0x00) &&
+              (Index < PARTITION_SIZE_INPUT_FIELD_LENGTH))
+       {
+         ch = Ir.Event.KeyEvent.uChar.AsciiChar;
+         if ((ch >= '0') && (ch <= '9'))
+           {
+             Buffer[Index] = ch;
+             Index++;
+             Buffer[Index] = 0;
+             DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH,
+                             iLeft,
+                             iTop,
+                             Buffer);
+           }
+       }
     }
     }
-  strcpy(InputBuffer, buf);
+
+  strcpy (InputBuffer,
+         Buffer);
 }
 
 
 static PAGE_NUMBER
 }
 
 
 static PAGE_NUMBER
-CreatePartitionPage(PINPUT_RECORD Ir)
+CreatePartitionPage (PINPUT_RECORD Ir)
 {
 {
-  BOOLEAN Valid;
-  WCHAR PathBuffer[MAX_PATH];
-  PPARTLIST PartList;
+  PDISKENTRY DiskEntry;
   PPARTENTRY PartEntry;
   SHORT xScreen;
   SHORT yScreen;
   PPARTENTRY PartEntry;
   SHORT xScreen;
   SHORT yScreen;
@@ -993,282 +1028,366 @@ CreatePartitionPage(PINPUT_RECORD Ir)
   CHAR InputBuffer[50];
   ULONG MaxSize;
   ULONGLONG PartSize;
   CHAR InputBuffer[50];
   ULONG MaxSize;
   ULONGLONG PartSize;
+  ULONGLONG DiskSize;
+  PCHAR Unit;
 
 
-  SetTextXY(6, 8, "You have chosen to create a new partition in the unused disk space.");
-  SetTextXY(6, 9, "Please enter the size of the new partition in megabytes.");
+  if (PartitionList == NULL ||
+      PartitionList->CurrentDisk == NULL ||
+      PartitionList->CurrentPartition == NULL)
+    {
+      /* FIXME: show an error dialog */
+      return QUIT_PAGE;
+    }
 
 
-  SetStatusText("   Please wait...");
+  DiskEntry = PartitionList->CurrentDisk;
+  PartEntry = PartitionList->CurrentPartition;
 
 
-  GetScreenSize(&xScreen, &yScreen);
+  SetStatusText ("   Please wait...");
 
 
-  PartList = CurrentPartitionList;
+  GetScreenSize (&xScreen, &yScreen);
 
 
-  SetStatusText("   ENTER = Continue   ESC = Cancel   F3 = Quit");
+  SetTextXY (6, 8, "You have chosen to create a new partition on");
 
 
-  PartEntry = &PartList->DiskArray[PartList->CurrentDisk].PartArray[PartList->CurrentPartition];
+#if 0
+  if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */
+    {
+      DiskSize = (DiskEntry->DiskSize + (1 << 29)) >> 30;
+      Unit = "GB";
+    }
+  else
+#endif
+    {
+      DiskSize = (DiskEntry->DiskSize + (1 << 19)) >> 20;
+      if (DiskSize == 0)
+       DiskSize = 1;
+      Unit = "MB";
+    }
+
+  if (DiskEntry->DriverName.Length > 0)
+    {
+      PrintTextXY (6, 10,
+                  "%I64u %s  Harddisk %lu  (Port=%hu, Bus=%hu, Id=%hu) on %wZ.",
+                  DiskSize,
+                  Unit,
+                  DiskEntry->DiskNumber,
+                  DiskEntry->Port,
+                  DiskEntry->Bus,
+                  DiskEntry->Id,
+                  &DiskEntry->DriverName);
+    }
+  else
+    {
+      PrintTextXY (6, 10,
+                  "%I64u %s  Harddisk %lu  (Port=%hu, Bus=%hu, Id=%hu).",
+                  DiskSize,
+                  Unit,
+                  DiskEntry->DiskNumber,
+                  DiskEntry->Port,
+                  DiskEntry->Bus,
+                  DiskEntry->Id);
+    }
+
+
+  SetTextXY (6, 12, "Please enter the size of the new partition in megabytes.");
+
+#if 0
+  PrintTextXY (8, 10, "Maximum size of the new partition is %I64u MB",
+              PartitionList->CurrentPartition->UnpartitionedLength / (1024*1024));
+#endif
+
+  SetStatusText ("   ENTER = Create Partition   ESC = Cancel   F3 = Quit");
+
+  PartEntry = PartitionList->CurrentPartition;
   while (TRUE)
     {
   while (TRUE)
     {
-      MaxSize = PartEntry->PartSize;
-      ShowPartitionSizeInputBox(MaxSize, InputBuffer, &Quit, &Cancel);
+      MaxSize = (PartEntry->UnpartitionedLength + (1 << 19)) >> 20;  /* in MBytes (rounded) */
+      ShowPartitionSizeInputBox (12, 14, xScreen - 12, 17, /* left, top, right, bottom */
+                                MaxSize, InputBuffer, &Quit, &Cancel);
       if (Quit == TRUE)
       if (Quit == TRUE)
-        {
-         if (ConfirmQuit(Ir) == TRUE)
-           {
-             DestroyPartitionList(PartList);
-             return(QUIT_PAGE);
-           }
-        }
+       {
+         if (ConfirmQuit (Ir) == TRUE)
+           {
+             return QUIT_PAGE;
+           }
+       }
       else if (Cancel == TRUE)
       else if (Cancel == TRUE)
-        {
-          break;
-        }
+       {
+         return SELECT_PARTITION_PAGE;
+       }
       else
       else
-        {
-          PartSize = atoi(InputBuffer);
-          if (PartSize < 1)
-            {
-              // Too small
-              continue;
-            }
-          /* Convert to bytes */
-          PartSize *= 1024 * 1024;
-
-          if (PartSize > PartEntry->PartSize)
-            {
-              // Too large
-              continue;
-            }
-
-          assert(PartEntry->Unpartitioned == TRUE);
-          PartEntry->PartType = PARTITION_ENTRY_UNUSED;
-          PartEntry->Used = TRUE;
-
-         PartDataValid = GetSelectedPartition(PartList,
-                                              &PartData);
-          if (PartDataValid)
-            {
-              PartData.CreatePartition = TRUE;
-              PartData.NewPartSize = PartSize;
-
-                 ActivePartitionValid = GetActiveBootPartition(PartList,
-                                                               &ActivePartition);
-
-                 RtlFreeUnicodeString(&DestinationRootPath);
-                 swprintf(PathBuffer,
-                          L"\\Device\\Harddisk%lu\\Partition%lu",
-                          PartData.DiskNumber,
-                          PartData.PartNumber);
-                 RtlCreateUnicodeString(&DestinationRootPath,
-                                        PathBuffer);
-
-                 RtlFreeUnicodeString(&SystemRootPath);
-
-              if (ActivePartitionValid)
-                {
-                     swprintf(PathBuffer,
-                           L"\\Device\\Harddisk%lu\\Partition%lu",
-                           ActivePartition.DiskNumber,
-                           ActivePartition.PartNumber);
-                }
-              else
-                {
-                  /* We mark the selected partition as bootable */
-                     swprintf(PathBuffer,
-                           L"\\Device\\Harddisk%lu\\Partition%lu",
-                           PartData.DiskNumber,
-                           PartData.PartNumber);
-                }
-                 RtlCreateUnicodeString(&SystemRootPath,
-                                        PathBuffer);
-
-                 return(SELECT_FILE_SYSTEM_PAGE);
-            }
-          else
-            {
-              /* FIXME: show an error dialog */
-              return(SELECT_PARTITION_PAGE);
-            }
-        }
-    }
+       {
+         PartSize = atoi (InputBuffer);
+         if (PartSize < 1)
+           {
+             /* Too small */
+             continue;
+           }
 
 
-  return(SELECT_PARTITION_PAGE);
-}
+         if (PartSize > MaxSize)
+           {
+             /* Too large */
+             continue;
+           }
 
 
+         /* Convert to bytes */
+         if (PartSize == MaxSize)
+           {
+             /* Use all of the unpartitioned disk space */
+             PartSize = PartEntry->UnpartitionedLength;
+           }
+         else
+           {
+             /* Round-up by cylinder size */
+             PartSize = ROUND_UP (PartSize * 1024 * 1024,
+                                  DiskEntry->CylinderSize);
 
 
-static PFILE_SYSTEM_LIST
-CreateFileSystemList(SHORT Left,
-  SHORT Top,
-  BOOLEAN ForceFormat,
-  FILE_SYSTEM ForceFileSystem)
-{
-  PFILE_SYSTEM_LIST List;
+             /* But never get larger than the unpartitioned disk space */
+             if (PartSize > PartEntry->UnpartitionedLength)
+               PartSize = PartEntry->UnpartitionedLength;
+           }
 
 
-  List = (PFILE_SYSTEM_LIST)RtlAllocateHeap(ProcessHeap, 0, sizeof(FILE_SYSTEM_LIST));
-  if (List == NULL)
-    return(NULL);
+         DPRINT ("Partition size: %I64u bytes\n", PartSize);
 
 
-  List->Left = Left;
-  List->Top = Top;
+         CreateNewPartition (PartitionList,
+                             PartSize,
+                             FALSE);
 
 
-#ifdef ENABLE_FORMAT
-  List->FileSystemCount = 1;
-#else
-  List->FileSystemCount = 0;
-#endif
-  if (ForceFormat)
-    {
-      List->CurrentFileSystem = ForceFileSystem;
-    }
-  else
-    {
-      List->FileSystemCount++;
-      List->CurrentFileSystem = FsKeep;
+         return SELECT_PARTITION_PAGE;
+       }
     }
     }
-  return(List);
+
+  return CREATE_PARTITION_PAGE;
 }
 
 
 }
 
 
-static VOID
-DestroyFileSystemList(PFILE_SYSTEM_LIST List)
+static PAGE_NUMBER
+DeletePartitionPage (PINPUT_RECORD Ir)
 {
 {
-  RtlFreeHeap(ProcessHeap, 0, List);
-}
+  PDISKENTRY DiskEntry;
+  PPARTENTRY PartEntry;
+  ULONGLONG DiskSize;
+  ULONGLONG PartSize;
+  PCHAR Unit;
+  PCHAR PartType;
 
 
+  if (PartitionList == NULL ||
+      PartitionList->CurrentDisk == NULL ||
+      PartitionList->CurrentPartition == NULL)
+    {
+      /* FIXME: show an error dialog */
+      return QUIT_PAGE;
+    }
 
 
-static VOID
-DrawFileSystemList(PFILE_SYSTEM_LIST List)
-{
-  COORD coPos;
-  ULONG Written;
-  ULONG index;
+  DiskEntry = PartitionList->CurrentDisk;
+  PartEntry = PartitionList->CurrentPartition;
 
 
-  index = 0;
+  SetTextXY (6, 8, "You have chosen to delete the partition");
 
 
-#ifdef ENABLE_FORMAT
-  coPos.X = List->Left;
-  coPos.Y = List->Top + index;
-  FillConsoleOutputAttribute(0x17,
-                            50,
-                            coPos,
-                            &Written);
-  FillConsoleOutputCharacter(' ',
-                            50,
-                            coPos,
-                            &Written);
+  /* Determine partition type */
+  PartType = NULL;
+  if (PartEntry->New == TRUE)
+    {
+      PartType = "New (Unformatted)";
+    }
+  else if (PartEntry->Unpartitioned == FALSE)
+    {
+      if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_12) ||
+         (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_16) ||
+         (PartEntry->PartInfo[0].PartitionType == PARTITION_HUGE) ||
+         (PartEntry->PartInfo[0].PartitionType == PARTITION_XINT13))
+       {
+         PartType = "FAT";
+       }
+      else if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32) ||
+              (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13))
+       {
+         PartType = "FAT32";
+       }
+      else if (PartEntry->PartInfo[0].PartitionType == PARTITION_IFS)
+       {
+         PartType = "NTFS"; /* FIXME: Not quite correct! */
+       }
+    }
 
 
-  if (List->CurrentFileSystem == FsFat)
+#if 0
+  if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0x280000000ULL) /* 10 GB */
     {
     {
-      SetInvertedTextXY(List->Left, List->Top + index, " Format partition as FAT file system ");
+      PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 29)) >> 30;
+      Unit = "GB";
     }
   else
     }
   else
+#endif
+  if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0xA00000ULL) /* 10 MB */
     {
     {
-      SetTextXY(List->Left, List->Top + index, " Format partition as FAT file system ");
+      PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 19)) >> 20;
+      Unit = "MB";
+    }
+  else
+    {
+      PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 9)) >> 10;
+      Unit = "KB";
     }
     }
-  index++;
-#endif
-
-  coPos.X = List->Left;
-  coPos.Y = List->Top + index;
-  FillConsoleOutputAttribute(0x17,
-                            50,
-                            coPos,
-                            &Written);
-  FillConsoleOutputCharacter(' ',
-                            50,
-                            coPos,
-                            &Written);
 
 
-  if (List->CurrentFileSystem == FsKeep)
+  if (PartType == NULL)
     {
     {
-      SetInvertedTextXY(List->Left, List->Top + index, " Keep current file system (no changes) ");
+      PrintTextXY (6, 10,
+                  "   %c%c  Type %lu    %I64u %s",
+                  (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
+                  (PartEntry->DriveLetter == 0) ? '-' : ':',
+                  PartEntry->PartInfo[0].PartitionType,
+                  PartSize,
+                  Unit);
     }
   else
     {
     }
   else
     {
-      SetTextXY(List->Left, List->Top + index, " Keep current file system (no changes) ");
+      PrintTextXY (6, 10,
+                  "   %c%c  %s    %I64u %s",
+                  (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
+                  (PartEntry->DriveLetter == 0) ? '-' : ':',
+                  PartType,
+                  PartSize,
+                  Unit);
     }
     }
-}
 
 
+#if 0
+  if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */
+    {
+      DiskSize = (DiskEntry->DiskSize + (1 << 29)) >> 30;
+      Unit = "GB";
+    }
+  else
+#endif
+    {
+      DiskSize = (DiskEntry->DiskSize + (1 << 19)) >> 20;
+      if (DiskSize == 0)
+       DiskSize = 1;
+      Unit = "MB";
+    }
 
 
-static VOID
-ScrollDownFileSystemList(PFILE_SYSTEM_LIST List)
-{
-  if ((ULONG) List->CurrentFileSystem < List->FileSystemCount - 1)
+  if (DiskEntry->DriverName.Length > 0)
     {
     {
-      (ULONG) List->CurrentFileSystem++;
-      DrawFileSystemList(List);
+      PrintTextXY (6, 12,
+                  "on %I64u %s  Harddisk %lu  (Port=%hu, Bus=%hu, Id=%hu) on %wZ.",
+                  DiskSize,
+                  Unit,
+                  DiskEntry->DiskNumber,
+                  DiskEntry->Port,
+                  DiskEntry->Bus,
+                  DiskEntry->Id,
+                  &DiskEntry->DriverName);
+    }
+  else
+    {
+      PrintTextXY (6, 12,
+                  "on %I64u %s  Harddisk %lu  (Port=%hu, Bus=%hu, Id=%hu).",
+                  DiskSize,
+                  Unit,
+                  DiskEntry->DiskNumber,
+                  DiskEntry->Port,
+                  DiskEntry->Bus,
+                  DiskEntry->Id);
     }
     }
-}
 
 
+  SetTextXY (8, 18, "\x07  Press D to delete the partition.");
+  SetTextXY (11, 19, "WARNING: All data on this partition will be lost!");
 
 
-static VOID
-ScrollUpFileSystemList(PFILE_SYSTEM_LIST List)
-{
-  if ((ULONG) List->CurrentFileSystem > 0)
+  SetTextXY (8, 21, "\x07  Press ESC to cancel.");
+
+  SetStatusText ("   D = Delete Partition   ESC = Cancel   F3 = Quit");
+
+  while (TRUE)
     {
     {
-      (ULONG) List->CurrentFileSystem--;
-      DrawFileSystemList(List);
+      ConInKey (Ir);
+
+      if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
+       {
+         if (ConfirmQuit (Ir) == TRUE)
+           {
+             return QUIT_PAGE;
+           }
+         break;
+       }
+      else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)  /* ESC */
+       {
+         return SELECT_PARTITION_PAGE;
+       }
+      else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_D) /* D */
+       {
+         DeleteCurrentPartition (PartitionList);
+
+         return SELECT_PARTITION_PAGE;
+       }
     }
     }
+
+  return DELETE_PARTITION_PAGE;
 }
 
 
 static PAGE_NUMBER
 }
 
 
 static PAGE_NUMBER
-SelectFileSystemPage(PINPUT_RECORD Ir)
+SelectFileSystemPage (PINPUT_RECORD Ir)
 {
 {
-  PFILE_SYSTEM_LIST FileSystemList;
+  PDISKENTRY DiskEntry;
+  PPARTENTRY PartEntry;
   ULONGLONG DiskSize;
   ULONGLONG PartSize;
   PCHAR DiskUnit;
   PCHAR PartUnit;
   PCHAR PartType;
 
   ULONGLONG DiskSize;
   ULONGLONG PartSize;
   PCHAR DiskUnit;
   PCHAR PartUnit;
   PCHAR PartType;
 
-  if (PartDataValid == FALSE)
+  if (PartitionList == NULL ||
+      PartitionList->CurrentDisk == NULL ||
+      PartitionList->CurrentPartition == NULL)
     {
       /* FIXME: show an error dialog */
     {
       /* FIXME: show an error dialog */
-      return(QUIT_PAGE);
+      return QUIT_PAGE;
     }
 
     }
 
+  DiskEntry = PartitionList->CurrentDisk;
+  PartEntry = PartitionList->CurrentPartition;
+
   /* adjust disk size */
   /* adjust disk size */
-  if (PartData.DiskSize >= 0x280000000ULL) /* 10 GB */
+  if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */
     {
     {
-      DiskSize = (PartData.DiskSize + (1 << 29)) >> 30;
+      DiskSize = (DiskEntry->DiskSize + (1 << 29)) >> 30;
       DiskUnit = "GB";
     }
   else
     {
       DiskUnit = "GB";
     }
   else
     {
-      DiskSize = (PartData.DiskSize + (1 << 19)) >> 20;
+      DiskSize = (DiskEntry->DiskSize + (1 << 19)) >> 20;
       DiskUnit = "MB";
     }
 
   /* adjust partition size */
       DiskUnit = "MB";
     }
 
   /* adjust partition size */
-  if (PartData.PartSize >= 0x280000000ULL) /* 10 GB */
+  if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0x280000000ULL) /* 10 GB */
     {
     {
-      PartSize = (PartData.PartSize + (1 << 29)) >> 30;
+      PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 29)) >> 30;
       PartUnit = "GB";
     }
   else
     {
       PartUnit = "GB";
     }
   else
     {
-      PartSize = (PartData.PartSize + (1 << 19)) >> 20;
+      PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 19)) >> 20;
       PartUnit = "MB";
     }
 
   /* adjust partition type */
       PartUnit = "MB";
     }
 
   /* adjust partition type */
-  if ((PartData.PartType == PARTITION_FAT_12) ||
-      (PartData.PartType == PARTITION_FAT_16) ||
-      (PartData.PartType == PARTITION_HUGE) ||
-      (PartData.PartType == PARTITION_XINT13))
+  if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_12) ||
+      (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_16) ||
+      (PartEntry->PartInfo[0].PartitionType == PARTITION_HUGE) ||
+      (PartEntry->PartInfo[0].PartitionType == PARTITION_XINT13))
     {
       PartType = "FAT";
     }
     {
       PartType = "FAT";
     }
-  else if ((PartData.PartType == PARTITION_FAT32) ||
-          (PartData.PartType == PARTITION_FAT32_XINT13))
+  else if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32) ||
+          (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13))
     {
       PartType = "FAT32";
     }
     {
       PartType = "FAT32";
     }
-  else if (PartData.PartType == PARTITION_IFS)
+  else if (PartEntry->PartInfo[0].PartitionType == PARTITION_IFS)
     {
       PartType = "NTFS"; /* FIXME: Not quite correct! */
     }
     {
       PartType = "NTFS"; /* FIXME: Not quite correct! */
     }
-  else if (PartData.PartType == PARTITION_ENTRY_UNUSED)
+  else if (PartEntry->PartInfo[0].PartitionType == PARTITION_ENTRY_UNUSED)
     {
       PartType = "Unused";
     }
     {
       PartType = "Unused";
     }
@@ -1277,166 +1396,408 @@ SelectFileSystemPage(PINPUT_RECORD Ir)
       PartType = "Unknown";
     }
 
       PartType = "Unknown";
     }
 
-  SetTextXY(6, 8, "Setup will install ReactOS on");
+  if (PartEntry->AutoCreate == TRUE)
+    {
+      SetTextXY(6, 8, "Setup created a new partition on");
 
 
+#if 0
   PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
   PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
-             PartData.PartNumber,
+             PartEntry->PartInfo[0].PartitionNumber,
              PartSize,
              PartUnit,
              PartType);
              PartSize,
              PartUnit,
              PartType);
+#endif
 
 
-  PrintTextXY(8, 12, "Harddisk %lu (%I64u %s), Port=%hu, Bus=%hu, Id=%hu (%wZ).",
-             PartData.DiskNumber,
+  PrintTextXY(8, 10, "Harddisk %lu (%I64u %s), Port=%hu, Bus=%hu, Id=%hu (%wZ).",
+             DiskEntry->DiskNumber,
              DiskSize,
              DiskUnit,
              DiskSize,
              DiskUnit,
-             PartData.Port,
-             PartData.Bus,
-             PartData.Id,
-             &PartData.DriverName);
+             DiskEntry->Port,
+             DiskEntry->Bus,
+             DiskEntry->Id,
+             &DiskEntry->DriverName);
+
+      SetTextXY(6, 12, "This Partition will be formatted next.");
+
+
+      PartEntry->AutoCreate = FALSE;
+    }
+  else if (PartEntry->New == TRUE)
+    {
+      SetTextXY(6, 8, "You chose to install ReactOS on a new or unformatted Partition.");
+      SetTextXY(6, 10, "This Partition will be formatted next.");
+    }
+  else
+    {
+      SetTextXY(6, 8, "Setup install ReactOS onto Partition");
+
+      if (PartType == NULL)
+       {
+         PrintTextXY (8, 10,
+                      "%c%c  Type %lu    %I64u %s",
+                      (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
+                      (PartEntry->DriveLetter == 0) ? '-' : ':',
+                      PartEntry->PartInfo[0].PartitionType,
+                      PartSize,
+                      PartUnit);
+       }
+      else
+       {
+         PrintTextXY (8, 10,
+                      "%c%c  %s    %I64u %s",
+                      (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
+                      (PartEntry->DriveLetter == 0) ? '-' : ':',
+                      PartType,
+                      PartSize,
+                      PartUnit);
+       }
+
+      PrintTextXY(6, 12, "on Harddisk %lu (%I64u %s), Port=%hu, Bus=%hu, Id=%hu (%wZ).",
+                 DiskEntry->DiskNumber,
+                 DiskSize,
+                 DiskUnit,
+                 DiskEntry->Port,
+                 DiskEntry->Bus,
+                 DiskEntry->Id,
+                 &DiskEntry->DriverName);
+    }
 
 
 
 
-  SetTextXY(6, 17, "Select a file system for the partition from the list below.");
+  SetTextXY(6, 17, "Select a file system from the list below.");
 
 
-  SetTextXY(8, 19, "\xfa  Press UP or DOWN to select a file system.");
-  SetTextXY(8, 21, "\xfa  Press ENTER to format the partition.");
-  SetTextXY(8, 23, "\xfa  Press ESC to select another partition.");
+  SetTextXY(8, 19, "\x07  Press UP or DOWN to select a file system.");
+  SetTextXY(8, 21, "\x07  Press ENTER to format the partition.");
+  SetTextXY(8, 23, "\x07  Press ESC to select another partition.");
 
 
-  FileSystemList = CreateFileSystemList(6, 26, FALSE, FsKeep);
   if (FileSystemList == NULL)
     {
   if (FileSystemList == NULL)
     {
-      /* FIXME: show an error dialog */
-      return(QUIT_PAGE);
+      FileSystemList = CreateFileSystemList (6, 26, PartEntry->New, FsFat);
+      if (FileSystemList == NULL)
+       {
+         /* FIXME: show an error dialog */
+         return QUIT_PAGE;
+       }
+
+      /* FIXME: Add file systems to list */
     }
     }
+  DrawFileSystemList (FileSystemList);
 
 
-  CurrentFileSystemList = FileSystemList;
+  SetStatusText ("   ENTER = Continue   ESC = Cancel   F3 = Quit");
 
 
-  DrawFileSystemList(FileSystemList);
+  while (TRUE)
+    {
+      ConInKey (Ir);
 
 
-  SetStatusText("   ENTER = Continue   ESC = Cancel   F3 = Quit");
+      if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
+       {
+         if (ConfirmQuit (Ir) == TRUE)
+           {
+             return QUIT_PAGE;
+           }
+         break;
+       }
+      else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+              (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */
+       {
+         return SELECT_PARTITION_PAGE;
+       }
+      else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+              (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
+       {
+         ScrollDownFileSystemList (FileSystemList);
+       }
+      else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+              (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
+       {
+         ScrollUpFileSystemList (FileSystemList);
+       }
+      else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
+       {
+         if (FileSystemList->CurrentFileSystem == FsKeep)
+           {
+             return CHECK_FILE_SYSTEM_PAGE;
+           }
+         else
+           {
+             return FORMAT_PARTITION_PAGE;
+           }
+       }
+    }
+
+  return SELECT_FILE_SYSTEM_PAGE;
+}
+
+
+static ULONG
+FormatPartitionPage (PINPUT_RECORD Ir)
+{
+  WCHAR PathBuffer[MAX_PATH];
+  PDISKENTRY DiskEntry;
+  PPARTENTRY PartEntry;
+  PLIST_ENTRY Entry;
+  NTSTATUS Status;
+
+//#ifndef NDEBUG
+  ULONG Line;
+  ULONG i;
+//#endif
+
+
+  SetTextXY(6, 8, "Format partition");
+
+  SetTextXY(6, 10, "Setup will now format the partition. Press ENTER to continue.");
+
+  SetStatusText("   ENTER = Continue   F3 = Quit");
+
+
+  if (PartitionList == NULL ||
+      PartitionList->CurrentDisk == NULL ||
+      PartitionList->CurrentPartition == NULL)
+    {
+      /* FIXME: show an error dialog */
+      return QUIT_PAGE;
+    }
+
+  DiskEntry = PartitionList->CurrentDisk;
+  PartEntry = PartitionList->CurrentPartition;
 
   while(TRUE)
     {
       ConInKey(Ir);
 
 
   while(TRUE)
     {
       ConInKey(Ir);
 
-      if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
-         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
-       {
-         if (ConfirmQuit(Ir) == TRUE)
-           return(QUIT_PAGE);
-         break;
-       }
-      else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
-              (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */
-       {
-    DestroyFileSystemList(FileSystemList);
-         return(SELECT_PARTITION_PAGE);
-       }
-      else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
-              (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
-       {
-         ScrollDownFileSystemList(FileSystemList);
-       }
-      else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
-              (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
-       {
-         ScrollUpFileSystemList(FileSystemList);
-       }
-      else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
-       {
-    if (FileSystemList->CurrentFileSystem == FsKeep)
-      {
-        return(CHECK_FILE_SYSTEM_PAGE);
-      }
-    else
-      {
-        return(FORMAT_PARTITION_PAGE);
-      }
-       }
-    }
-}
+      if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
+       {
+         if (ConfirmQuit (Ir) == TRUE)
+           {
+             return QUIT_PAGE;
+           }
+         break;
+       }
+      else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
+       {
+         SetStatusText ("   Please wait ...");
+
+         if (PartEntry->PartInfo[0].PartitionType == PARTITION_ENTRY_UNUSED)
+           {
+             switch (FileSystemList->CurrentFileSystem)
+               {
+                 case FsFat:
+                   if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (4200ULL * 1024ULL))
+                     {
+                       /* FAT12 CHS partition (disk is smaller than 4.1MB) */
+                       PartEntry->PartInfo[0].PartitionType = PARTITION_FAT_12;
+                     }
+                   else if (PartEntry->PartInfo[0].StartingOffset.QuadPart < (1024ULL * 255ULL * 63ULL * 512ULL))
+                     {
+                       /* Partition starts below the 8.4GB boundary ==> CHS partition */
+
+                       if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (32ULL * 1024ULL * 1024ULL))
+                         {
+                           /* FAT16 CHS partition (partiton size < 32MB) */
+                           PartEntry->PartInfo[0].PartitionType = PARTITION_FAT_16;
+                         }
+                       else if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (512ULL * 1024ULL * 1024ULL))
+                         {
+                           /* FAT16 CHS partition (partition size < 512MB) */
+                           PartEntry->PartInfo[0].PartitionType = PARTITION_HUGE;
+                         }
+                       else
+                         {
+                           /* FAT32 CHS partition (partition size >= 512MB) */
+                           PartEntry->PartInfo[0].PartitionType = PARTITION_FAT32;
+                         }
+                     }
+                   else
+                     {
+                       /* Partition starts above the 8.4GB boundary ==> LBA partition */
+
+                       if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (512ULL * 1024ULL * 1024ULL))
+                         {
+                           /* FAT16 LBA partition (partition size < 512MB) */
+                           PartEntry->PartInfo[0].PartitionType = PARTITION_XINT13;
+                         }
+                       else
+                         {
+                           /* FAT32 LBA partition (partition size >= 512MB) */
+                           PartEntry->PartInfo[0].PartitionType = PARTITION_FAT32_XINT13;
+                         }
+                     }
+                   break;
+
+                 case FsKeep:
+                   break;
+
+                 default:
+                   return QUIT_PAGE;
+               }
+           }
+
+         CheckActiveBootPartition (PartitionList);
+
+//#ifndef NDEBUG
+         PrintTextXY (6, 12,
+                      "Disk: %I64u  Cylinder: %I64u  Track: %I64u",
+                      DiskEntry->DiskSize,
+                      DiskEntry->CylinderSize,
+                      DiskEntry->TrackSize);
+
+         Line = 13;
+         DiskEntry = PartitionList->CurrentDisk;
+         Entry = DiskEntry->PartListHead.Flink;
+         while (Entry != &DiskEntry->PartListHead)
+           {
+             PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
+
+             if (PartEntry->Unpartitioned == FALSE)
+               {
+
+                 for (i = 0; i < 4; i++)
+                   {
+                     PrintTextXY (6, Line,
+                                  "%2u:  %2u  %c  %12I64u  %12I64u  %2u  %c",
+                                  i,
+                                  PartEntry->PartInfo[i].PartitionNumber,
+                                  PartEntry->PartInfo[i].BootIndicator ? 'A' : '-',
+                                  PartEntry->PartInfo[i].StartingOffset.QuadPart,
+                                  PartEntry->PartInfo[i].PartitionLength.QuadPart,
+                                  PartEntry->PartInfo[i].PartitionType,
+                                  PartEntry->PartInfo[i].RewritePartition ? '*' : ' ');
+
+                     Line++;
+                   }
+
+                 Line++;
+               }
+
+             Entry = Entry->Flink;
+           }
+
+         /* Restore the old entry */
+         PartEntry = PartitionList->CurrentPartition;
+//#endif
+
+         if (WritePartitionsToDisk (PartitionList) == FALSE)
+           {
+             DPRINT ("WritePartitionsToDisk() failed\n");
+
+             PopupError ("Setup failed to write partition tables.\n",
+                         "ENTER = Reboot computer");
+
+             while (TRUE)
+               {
+                 ConInKey (Ir);
+
+                 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+                   {
+                     return QUIT_PAGE;
+                   }
+               }
+           }
+
+
+         /* Set DestinationRootPath */
+         RtlFreeUnicodeString (&DestinationRootPath);
+         swprintf (PathBuffer,
+                   L"\\Device\\Harddisk%lu\\Partition%lu",
+                   PartitionList->CurrentDisk->DiskNumber,
+                   PartitionList->CurrentPartition->PartInfo[0].PartitionNumber);
+         RtlCreateUnicodeString (&DestinationRootPath,
+                                 PathBuffer);
+         DPRINT ("DestinationRootPath: %wZ\n", &DestinationRootPath);
 
 
-static ULONG
-FormatPartitionPage(PINPUT_RECORD Ir)
-{
-  NTSTATUS Status;
-  ULONG PartType;
-  BOOLEAN Valid;
 
 
-  SetTextXY(6, 8, "Format partition");
+         /* Set SystemRootPath */
+         RtlFreeUnicodeString (&SystemRootPath);
+         swprintf (PathBuffer,
+                   L"\\Device\\Harddisk%lu\\Partition%lu",
+                   PartitionList->ActiveBootDisk->DiskNumber,
+                   PartitionList->ActiveBootPartition->PartInfo[0].PartitionNumber);
+         RtlCreateUnicodeString (&SystemRootPath,
+                                 PathBuffer);
+         DPRINT ("SystemRootPath: %wZ\n", &SystemRootPath);
 
 
-  SetTextXY(6, 10, "Setup will now format the partition. Press ENTER to continue.");
 
 
-  SetStatusText("   ENTER = Continue   F3 = Quit");
+         switch (FileSystemList->CurrentFileSystem)
+           {
+             case FsFat:
+               Status = FormatPartition (&DestinationRootPath);
+               if (!NT_SUCCESS (Status))
+                 {
+                   DPRINT1 ("FormatPartition() failed with status 0x%.08x\n", Status);
+                   /* FIXME: show an error dialog */
+                   return QUIT_PAGE;
+                 }
 
 
-  while(TRUE)
-    {
-      ConInKey(Ir);
+               PartEntry->New = FALSE;
+               if (FileSystemList != NULL)
+                 {
+                   DestroyFileSystemList (FileSystemList);
+                   FileSystemList = NULL;
+                 }
 
 
-      if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
-         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
-       {
-         if (ConfirmQuit(Ir) == TRUE)
-      {
-             return(QUIT_PAGE);
-      }
-         break;
-       }
-      else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
-       {
-    SetStatusText("   Please wait ...");
+               CheckActiveBootPartition (PartitionList);
 
 
-    switch (CurrentFileSystemList->CurrentFileSystem)
-      {
-#ifdef ENABLE_FORMAT
-        case FsFat:
-          PartType = PARTITION_FAT32_XINT13;
-          break;
-#endif
-        case FsKeep:
-          break;
-        default:
-          return QUIT_PAGE;
-      }
+               /* FIXME: Install boot code. This is a hack! */
+               if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13) ||
+                   (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32))
+                 {
+                   wcscpy (PathBuffer, SourceRootPath.Buffer);
+                   wcscat (PathBuffer, L"\\loader\\fat32.bin");
+
+                   DPRINT1 ("Install FAT32 bootcode: %S ==> %S\n", PathBuffer,
+                            DestinationRootPath.Buffer);
+                   Status = InstallFat32BootCodeToDisk (PathBuffer,
+                                                        DestinationRootPath.Buffer);
+                   if (!NT_SUCCESS (Status))
+                     {
+                       DPRINT1 ("InstallFat32BootCodeToDisk() failed with status 0x%.08x\n", Status);
+                       /* FIXME: show an error dialog */
+                       return QUIT_PAGE;
+                     }
+                 }
+               else
+                 {
+                   wcscpy (PathBuffer, SourceRootPath.Buffer);
+                   wcscat (PathBuffer, L"\\loader\\fat.bin");
+
+                   DPRINT1 ("Install FAT bootcode: %S ==> %S\n", PathBuffer,
+                            DestinationRootPath.Buffer);
+                   Status = InstallFat16BootCodeToDisk (PathBuffer,
+                                                        DestinationRootPath.Buffer);
+                   if (!NT_SUCCESS (Status))
+                     {
+                       DPRINT1 ("InstallFat16BootCodeToDisk() failed with status 0x%.08x\n", Status);
+                       /* FIXME: show an error dialog */
+                       return QUIT_PAGE;
+                     }
+                 }
+               break;
 
 
-    if (PartData.CreatePartition)
-      {
-         Valid = CreateSelectedPartition(CurrentPartitionList, PartType, PartData.NewPartSize);
-        if (!Valid)
-          {
-            DPRINT("CreateSelectedPartition() failed\n");
-            /* FIXME: show an error dialog */
-            return(QUIT_PAGE);
-          }
-      }
+             case FsKeep:
+               break;
 
 
-    switch (CurrentFileSystemList->CurrentFileSystem)
-      {
-#ifdef ENABLE_FORMAT
-        case FsFat:
-          Status = FormatPartition(&DestinationRootPath);
-          if (!NT_SUCCESS(Status))
-            {
-              DPRINT1("FormatPartition() failed with status 0x%.08x\n", Status);
-              /* FIXME: show an error dialog */
-              return(QUIT_PAGE);
-            }
-          break;
-#endif
-        case FsKeep:
-          break;
-        default:
-          return QUIT_PAGE;
-      }
-    return(INSTALL_DIRECTORY_PAGE);
+             default:
+               return QUIT_PAGE;
+           }
+
+         SetStatusText ("   Done.  Press any key ...");
+         ConInKey(Ir);
+
+         return INSTALL_DIRECTORY_PAGE;
        }
     }
 
        }
     }
 
-  return(INSTALL_DIRECTORY_PAGE);
+  return FORMAT_PARTITION_PAGE;
 }
 
 }
 
+
 static ULONG
 CheckFileSystemPage(PINPUT_RECORD Ir)
 {
 static ULONG
 CheckFileSystemPage(PINPUT_RECORD Ir)
 {
+  WCHAR PathBuffer[MAX_PATH];
+
   SetTextXY(6, 8, "Check file system");
 
   SetTextXY(6, 10, "At present, ReactOS can not check file systems.");
   SetTextXY(6, 8, "Check file system");
 
   SetTextXY(6, 10, "At present, ReactOS can not check file systems.");
@@ -1446,6 +1807,28 @@ CheckFileSystemPage(PINPUT_RECORD Ir)
 
   SetStatusText("   ENTER = Continue   F3 = Quit");
 
 
   SetStatusText("   ENTER = Continue   F3 = Quit");
 
+
+  /* Set DestinationRootPath */
+  RtlFreeUnicodeString (&DestinationRootPath);
+  swprintf (PathBuffer,
+           L"\\Device\\Harddisk%lu\\Partition%lu",
+           PartitionList->CurrentDisk->DiskNumber,
+           PartitionList->CurrentPartition->PartInfo[0].PartitionNumber);
+  RtlCreateUnicodeString (&DestinationRootPath,
+                         PathBuffer);
+  DPRINT ("DestinationRootPath: %wZ\n", &DestinationRootPath);
+
+  /* Set SystemRootPath */
+  RtlFreeUnicodeString (&SystemRootPath);
+  swprintf (PathBuffer,
+           L"\\Device\\Harddisk%lu\\Partition%lu",
+           PartitionList->ActiveBootDisk->DiskNumber,
+           PartitionList->ActiveBootPartition->PartInfo[0].PartitionNumber);
+  RtlCreateUnicodeString (&SystemRootPath,
+                         PathBuffer);
+  DPRINT ("SystemRootPath: %wZ\n", &SystemRootPath);
+
+
   while(TRUE)
     {
       ConInKey(Ir);
   while(TRUE)
     {
       ConInKey(Ir);
@@ -1470,6 +1853,8 @@ CheckFileSystemPage(PINPUT_RECORD Ir)
 static PAGE_NUMBER
 InstallDirectoryPage(PINPUT_RECORD Ir)
 {
 static PAGE_NUMBER
 InstallDirectoryPage(PINPUT_RECORD Ir)
 {
+  PDISKENTRY DiskEntry;
+  PPARTENTRY PartEntry;
   WCHAR PathBuffer[MAX_PATH];
   WCHAR InstallDir[51];
   PWCHAR DefaultPath;
   WCHAR PathBuffer[MAX_PATH];
   WCHAR InstallDir[51];
   PWCHAR DefaultPath;
@@ -1477,6 +1862,17 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
   ULONG Length;
   NTSTATUS Status;
 
   ULONG Length;
   NTSTATUS Status;
 
+  if (PartitionList == NULL ||
+      PartitionList->CurrentDisk == NULL ||
+      PartitionList->CurrentPartition == NULL)
+    {
+      /* FIXME: show an error dialog */
+      return QUIT_PAGE;
+    }
+
+  DiskEntry = PartitionList->CurrentDisk;
+  PartEntry = PartitionList->CurrentPartition;
+
   /* Search for 'DefaultPath' in the 'SetupData' section */
   if (!InfFindFirstLine (SetupInf, L"SetupData", L"DefaultPath", &Context))
     {
   /* Search for 'DefaultPath' in the 'SetupData' section */
   if (!InfFindFirstLine (SetupInf, L"SetupData", L"DefaultPath", &Context))
     {
@@ -1484,13 +1880,13 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
                 "in TXTSETUP.SIF.\n",
                 "ENTER = Reboot computer");
 
                 "in TXTSETUP.SIF.\n",
                 "ENTER = Reboot computer");
 
-      while(TRUE)
+      while (TRUE)
        {
        {
-         ConInKey(Ir);
+         ConInKey (Ir);
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
-             return(QUIT_PAGE);
+             return QUIT_PAGE;
            }
        }
     }
            }
        }
     }
@@ -1550,8 +1946,8 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
          RtlFreeUnicodeString(&DestinationArcPath);
          swprintf(PathBuffer,
                   L"multi(0)disk(0)rdisk(%lu)partition(%lu)",
          RtlFreeUnicodeString(&DestinationArcPath);
          swprintf(PathBuffer,
                   L"multi(0)disk(0)rdisk(%lu)partition(%lu)",
-                  PartData.DiskNumber,
-                  PartData.PartNumber);
+                  DiskEntry->DiskNumber,
+                  PartEntry->PartInfo[0].PartitionNumber);
          if (InstallDir[0] != L'\\')
            wcscat(PathBuffer,
                   L"\\");
          if (InstallDir[0] != L'\\')
            wcscat(PathBuffer,
                   L"\\");
@@ -1586,8 +1982,8 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
 }
 
 
 }
 
 
-static PAGE_NUMBER
-PrepareCopyPage(PINPUT_RECORD Ir)
+static BOOLEAN
+PrepareCopyPageInfFile(HINF InfFile, PWCHAR SourceCabinet, PINPUT_RECORD Ir)
 {
   WCHAR PathBuffer[MAX_PATH];
   INFCONTEXT FilesContext;
 {
   WCHAR PathBuffer[MAX_PATH];
   INFCONTEXT FilesContext;
@@ -1596,53 +1992,16 @@ PrepareCopyPage(PINPUT_RECORD Ir)
   PWCHAR KeyValue;
   ULONG Length;
   NTSTATUS Status;
   PWCHAR KeyValue;
   ULONG Length;
   NTSTATUS Status;
-
   PWCHAR FileKeyName;
   PWCHAR FileKeyValue;
   PWCHAR DirKeyName;
   PWCHAR DirKeyValue;
 
   PWCHAR FileKeyName;
   PWCHAR FileKeyValue;
   PWCHAR DirKeyName;
   PWCHAR DirKeyValue;
 
-  SetTextXY(6, 8, "Setup prepares your computer for copying the ReactOS files. ");
-
-
-//  SetTextXY(8, 12, "Build file copy list");
-
-//  SetTextXY(8, 14, "Create directories");
-
-//  SetStatusText("   Please wait...");
-
-  /*
-   * Build the file copy list
-   */
-  SetStatusText("   Building the file copy list...");
-//  SetInvertedTextXY(8, 12, "Build file copy list");
-
-
-
   /* Search for the 'SourceFiles' section */
   /* Search for the 'SourceFiles' section */
-  if (!InfFindFirstLine (SetupInf, L"SourceFiles", NULL, &FilesContext))
+  if (!InfFindFirstLine (InfFile, L"SourceFiles", NULL, &FilesContext))
     {
       PopupError("Setup failed to find the 'SourceFiles' section\n"
     {
       PopupError("Setup failed to find the 'SourceFiles' section\n"
-                "in TXTSETUP.SIF.\n",
-                "ENTER = Reboot computer");
-
-      while(TRUE)
-       {
-         ConInKey(Ir);
-
-         if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
-           {
-             return(QUIT_PAGE);
-           }
-       }
-    }
-
-
-  /* Create the file queue */
-  SetupFileQueue = SetupOpenFileQueue();
-  if (SetupFileQueue == NULL)
-    {
-      PopupError("Setup failed to open the copy file queue.\n",
+                "in TXTSETUP.SIF.\n",  // FIXME
                 "ENTER = Reboot computer");
 
       while(TRUE)
                 "ENTER = Reboot computer");
 
       while(TRUE)
@@ -1651,7 +2010,7 @@ PrepareCopyPage(PINPUT_RECORD Ir)
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
-             return(QUIT_PAGE);
+             return(FALSE);
            }
        }
     }
            }
        }
     }
@@ -1663,12 +2022,15 @@ PrepareCopyPage(PINPUT_RECORD Ir)
   do
     {
       if (!InfGetData (&FilesContext, &FileKeyName, &FileKeyValue))
   do
     {
       if (!InfGetData (&FilesContext, &FileKeyName, &FileKeyValue))
-       break;
+        {
+          DPRINT("break\n");
+               break;
+        }
 
 
-      DPRINT1("FileKeyName: '%S'  FileKeyValue: '%S'\n", FileKeyName, FileKeyValue);
+      DPRINT ("FileKeyName: '%S'  FileKeyValue: '%S'\n", FileKeyName, FileKeyValue);
 
       /* Lookup target directory */
 
       /* Lookup target directory */
-      if (!InfFindFirstLine (SetupInf, L"Directories", FileKeyValue, &DirContext))
+      if (!InfFindFirstLine (InfFile, L"Directories", FileKeyValue, &DirContext))
        {
          /* FIXME: Handle error! */
          DPRINT1("InfFindFirstLine() failed\n");
        {
          /* FIXME: Handle error! */
          DPRINT1("InfFindFirstLine() failed\n");
@@ -1683,8 +2045,9 @@ PrepareCopyPage(PINPUT_RECORD Ir)
        }
 
       if (!SetupQueueCopy(SetupFileQueue,
        }
 
       if (!SetupQueueCopy(SetupFileQueue,
+        SourceCabinet,
                          SourceRootPath.Buffer,
                          SourceRootPath.Buffer,
-                         L"\\install",
+                         L"\\reactos",
                          FileKeyName,
                          DirKeyValue,
                          NULL))
                          FileKeyName,
                          DirKeyValue,
                          NULL))
@@ -1697,7 +2060,6 @@ PrepareCopyPage(PINPUT_RECORD Ir)
 
 
   /* Create directories */
 
 
   /* Create directories */
-  SetStatusText("   Creating directories...");
 
   /*
    * FIXME:
 
   /*
    * FIXME:
@@ -1728,18 +2090,25 @@ PrepareCopyPage(PINPUT_RECORD Ir)
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
-             return(QUIT_PAGE);
+             return(FALSE);
            }
        }
     }
 
 
   /* Search for the 'Directories' section */
            }
        }
     }
 
 
   /* Search for the 'Directories' section */
-  if (!InfFindFirstLine(SetupInf, L"Directories", NULL, &DirContext))
+  if (!InfFindFirstLine(InfFile, L"Directories", NULL, &DirContext))
     {
     {
-      PopupError("Setup failed to find the 'Directories' section\n"
-                "in TXTSETUP.SIF.\n",
-                "ENTER = Reboot computer");
+      if (SourceCabinet)
+        {
+          PopupError("Setup failed to find the 'Directories' section\n"
+                   "in the cabinet.\n", "ENTER = Reboot computer");
+        }
+      else
+        {
+          PopupError("Setup failed to find the 'Directories' section\n"
+                   "in TXTSETUP.SIF.\n", "ENTER = Reboot computer");
+        }
 
       while(TRUE)
        {
 
       while(TRUE)
        {
@@ -1747,7 +2116,7 @@ PrepareCopyPage(PINPUT_RECORD Ir)
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
-             return(QUIT_PAGE);
+             return(FALSE);
            }
        }
     }
            }
        }
     }
@@ -1756,7 +2125,10 @@ PrepareCopyPage(PINPUT_RECORD Ir)
   do
     {
       if (!InfGetData (&DirContext, NULL, &KeyValue))
   do
     {
       if (!InfGetData (&DirContext, NULL, &KeyValue))
-       break;
+        {
+          DPRINT1("break\n");
+               break;
+        }
 
       if (KeyValue[0] == L'\\' && KeyValue[1] != 0)
        {
 
       if (KeyValue[0] == L'\\' && KeyValue[1] != 0)
        {
@@ -1789,7 +2161,7 @@ PrepareCopyPage(PINPUT_RECORD Ir)
 
                  if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
                    {
 
                  if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
                    {
-                     return(QUIT_PAGE);
+                     return(FALSE);
                    }
                }
            }
                    }
                }
            }
@@ -1797,6 +2169,159 @@ PrepareCopyPage(PINPUT_RECORD Ir)
     }
   while (InfFindNextLine (&DirContext, &DirContext));
 
     }
   while (InfFindNextLine (&DirContext, &DirContext));
 
+  return(TRUE);
+}
+
+
+static PAGE_NUMBER
+PrepareCopyPage(PINPUT_RECORD Ir)
+{
+  INT CabStatus;
+  HINF InfHandle;
+  WCHAR PathBuffer[MAX_PATH];
+  INFCONTEXT CabinetsContext;
+  ULONG InfFileSize;
+  PWCHAR KeyValue;
+  NTSTATUS Status;
+  ULONG ErrorLine;
+  PVOID InfFileData;
+
+  SetTextXY(6, 8, "Setup prepares your computer for copying the ReactOS files. ");
+
+
+  /*
+   * Build the file copy list
+   */
+  SetStatusText("   Building the file copy list...");
+
+  /* Create the file queue */
+  SetupFileQueue = SetupOpenFileQueue();
+  if (SetupFileQueue == NULL)
+    {
+      PopupError("Setup failed to open the copy file queue.\n",
+                "ENTER = Reboot computer");
+
+      while(TRUE)
+       {
+         ConInKey(Ir);
+
+         if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
+           {
+             return(QUIT_PAGE);
+           }
+       }
+    }
+
+
+  if (!PrepareCopyPageInfFile(SetupInf, NULL, Ir))
+    {
+      return(QUIT_PAGE);
+    }
+
+
+  /* Search for the 'Cabinets' section */
+  if (!InfFindFirstLine (SetupInf, L"Cabinets", NULL, &CabinetsContext))
+    {
+      PopupError("Setup failed to find the 'Cabinets' section\n"
+                "in TXTSETUP.SIF.\n",
+                "ENTER = Reboot computer");
+
+      while(TRUE)
+       {
+         ConInKey(Ir);
+
+         if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
+           {
+             return(QUIT_PAGE);
+           }
+       }
+    }
+
+
+  /*
+   * Enumerate the directory values in the 'Cabinets'
+   * section and parse their inf files.
+   */
+  do
+    {
+      if (!InfGetData (&CabinetsContext, NULL, &KeyValue))
+    break;
+
+         wcscpy(PathBuffer, SourcePath.Buffer);
+         wcscat(PathBuffer, L"\\");
+         wcscat(PathBuffer, KeyValue);
+
+    CabinetInitialize();
+    CabinetSetEventHandlers(NULL, NULL, NULL);
+    CabinetSetCabinetName(PathBuffer);
+
+    if (CabinetOpen() == CAB_STATUS_SUCCESS)
+      {
+        DPRINT("Cabinet %S\n", CabinetGetCabinetName());
+
+        InfFileData = CabinetGetCabinetReservedArea(&InfFileSize);
+        if (InfFileData == NULL)
+          {
+            PopupError("Cabinet has no setup script.\n",
+                   "ENTER = Reboot computer");
+
+            while(TRUE)
+               {
+                 ConInKey(Ir);
+            
+                 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
+                   {
+                     return(QUIT_PAGE);
+                   }
+               }
+          }
+      }
+    else
+      {
+        DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
+
+        PopupError("Cabinet not found.\n", "ENTER = Reboot computer");
+  
+        while(TRUE)
+               {
+                 ConInKey(Ir);
+        
+                 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
+                   {
+                     return(QUIT_PAGE);
+                   }
+               }
+      }
+
+    Status = InfOpenBufferedFile(&InfHandle,
+           InfFileData,
+      InfFileSize,
+           &ErrorLine);
+    if (!NT_SUCCESS(Status))
+      {
+        PopupError("Cabinet has no valid inf file.\n",
+                "ENTER = Reboot computer");
+  
+        while(TRUE)
+       {
+         ConInKey(Ir);
+  
+         if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
+           {
+             return(QUIT_PAGE);
+           }
+       }
+      }
+
+      CabinetCleanup();
+
+      if (!PrepareCopyPageInfFile(InfHandle, KeyValue, Ir))
+        {
+          return(QUIT_PAGE);
+        }
+    }
+  while (InfFindNextLine (&CabinetsContext, &CabinetsContext));
+
   return(FILE_COPY_PAGE);
 }
 
   return(FILE_COPY_PAGE);
 }
 
@@ -2001,74 +2526,12 @@ BootLoaderPage(PINPUT_RECORD Ir)
   PINICACHE IniCache;
   PINICACHESECTION IniSection;
   NTSTATUS Status;
   PINICACHE IniCache;
   PINICACHESECTION IniSection;
   NTSTATUS Status;
-  BOOLEAN InstallMBR = FALSE;
 
   SetTextXY(6, 8, "Installing the boot loader");
 
   SetStatusText("   Please wait...");
 
 
   SetTextXY(6, 8, "Installing the boot loader");
 
   SetStatusText("   Please wait...");
 
-  if (ActivePartitionValid == FALSE)
-    {
-      /* Mark the chosen partition as active since there is no active
-         partition now */
-     
-               if (!MarkPartitionActive(PartData.DiskNumber,
-                       PartData.PartNumber, &ActivePartition))
-               {
-                     PopupError("Setup could not mark the system partiton active\n",
-                                "ENTER = Reboot computer");
-               
-                     while(TRUE)
-                       {
-                         ConInKey(Ir);
-               
-                         if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
-                           {
-                             return(QUIT_PAGE);
-                           }
-                       }
-               }
-        InstallMBR = TRUE;
-    }
-
-  if (InstallMBR)
-    {
-          WCHAR PathBuffer[MAX_PATH];
-             UNICODE_STRING SystemRootMBRPath;
-       
-                 RtlFreeUnicodeString(&SystemRootMBRPath);
-                 swprintf(PathBuffer,
-                          L"\\Device\\Harddisk%lu\\Partition0",
-                          PartData.DiskNumber);
-                 RtlCreateUnicodeString(&SystemRootMBRPath,
-                                        PathBuffer);
-
-                 /* Install MBR bootcode */
-                 wcscpy(SrcPath, SourceRootPath.Buffer);
-                 wcscat(SrcPath, L"\\loader\\dosmbr.bin");
-       
-                 DPRINT1("Install MBR bootcode: %S ==> %S\n", SrcPath, SystemRootMBRPath.Buffer);
-                 Status = InstallMBRBootCodeToDisk(SrcPath,
-                                                     SystemRootMBRPath.Buffer);
-                 if (!NT_SUCCESS(Status))
-                 {
-                   DPRINT1("InstallMBRBootCodeToDisk() failed (Status %lx)\n", Status);
-                   PopupError("Setup failed to install the MBR bootcode.",
-                              "ENTER = Reboot computer");
-       
-                   while(TRUE)
-                   {
-                     ConInKey(Ir);
-       
-                     if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)   /* ENTER */
-                     {
-                       return(QUIT_PAGE);
-                     }
-                   }
-                 }
-    }
-
-  if (ActivePartition.PartType == PARTITION_ENTRY_UNUSED)
+  if (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_ENTRY_UNUSED)
     {
       DPRINT1("Error: active partition invalid (unused)\n");
       PopupError("The active partition is unused (invalid).\n",
     {
       DPRINT1("Error: active partition invalid (unused)\n");
       PopupError("The active partition is unused (invalid).\n",
@@ -2084,8 +2547,7 @@ BootLoaderPage(PINPUT_RECORD Ir)
            }
        }
     }
            }
        }
     }
-
-  if (ActivePartition.PartType == 0x0A)
+  if (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == 0x0A)
     {
       /* OS/2 boot manager partition */
       DPRINT1("Found OS/2 boot manager partition\n");
     {
       /* OS/2 boot manager partition */
       DPRINT1("Found OS/2 boot manager partition\n");
@@ -2103,7 +2565,7 @@ BootLoaderPage(PINPUT_RECORD Ir)
            }
        }
     }
            }
        }
     }
-  else if (ActivePartition.PartType == 0x83)
+  else if (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == 0x83)
     {
       /* Linux ext2 partition */
       DPRINT1("Found Linux ext2 partition\n");
     {
       /* Linux ext2 partition */
       DPRINT1("Found Linux ext2 partition\n");
@@ -2121,7 +2583,7 @@ BootLoaderPage(PINPUT_RECORD Ir)
            }
        }
     }
            }
        }
     }
-  else if (ActivePartition.PartType == PARTITION_IFS)
+  else if (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_IFS)
     {
       /* NTFS partition */
       DPRINT1("Found NTFS partition\n");
     {
       /* NTFS partition */
       DPRINT1("Found NTFS partition\n");
@@ -2139,12 +2601,12 @@ BootLoaderPage(PINPUT_RECORD Ir)
            }
        }
     }
            }
        }
     }
-  else if ((ActivePartition.PartType == PARTITION_FAT_12) ||
-          (ActivePartition.PartType == PARTITION_FAT_16) ||
-          (ActivePartition.PartType == PARTITION_HUGE) ||
-          (ActivePartition.PartType == PARTITION_XINT13) ||
-          (ActivePartition.PartType == PARTITION_FAT32) ||
-          (ActivePartition.PartType == PARTITION_FAT32_XINT13))
+  else if ((PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_FAT_12) ||
+          (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_FAT_16) ||
+          (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_HUGE) ||
+          (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_XINT13) ||
+          (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_FAT32) ||
+          (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13))
   {
     /* FAT or FAT32 partition */
     DPRINT1("System path: '%wZ'\n", &SystemRootPath);
   {
     /* FAT or FAT32 partition */
     DPRINT1("System path: '%wZ'\n", &SystemRootPath);
@@ -2208,8 +2670,8 @@ BootLoaderPage(PINPUT_RECORD Ir)
        }
 
        /* Install new bootcode */
        }
 
        /* Install new bootcode */
-       if ((ActivePartition.PartType == PARTITION_FAT32) ||
-           (ActivePartition.PartType == PARTITION_FAT32_XINT13))
+       if ((PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_FAT32) ||
+           (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13))
        {
          /* Install FAT32 bootcode */
          wcscpy(SrcPath, SourceRootPath.Buffer);
        {
          /* Install FAT32 bootcode */
          wcscpy(SrcPath, SourceRootPath.Buffer);
@@ -2404,8 +2866,8 @@ BootLoaderPage(PINPUT_RECORD Ir)
        }
 
        /* Install new bootsector */
        }
 
        /* Install new bootsector */
-       if ((ActivePartition.PartType == PARTITION_FAT32) ||
-           (ActivePartition.PartType == PARTITION_FAT32_XINT13))
+       if ((PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_FAT32) ||
+           (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13))
        {
          wcscpy(SrcPath, SourceRootPath.Buffer);
          wcscat(SrcPath, L"\\loader\\fat32.bin");
        {
          wcscpy(SrcPath, SourceRootPath.Buffer);
          wcscat(SrcPath, L"\\loader\\fat32.bin");
@@ -2565,8 +3027,8 @@ BootLoaderPage(PINPUT_RECORD Ir)
        }
 
        /* Install new bootsector */
        }
 
        /* Install new bootsector */
-       if ((ActivePartition.PartType == PARTITION_FAT32) ||
-           (ActivePartition.PartType == PARTITION_FAT32_XINT13))
+       if ((PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_FAT32) ||
+           (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13))
        {
          wcscpy(SrcPath, SourceRootPath.Buffer);
          wcscat(SrcPath, L"\\loader\\fat32.bin");
        {
          wcscpy(SrcPath, SourceRootPath.Buffer);
          wcscat(SrcPath, L"\\loader\\fat32.bin");
@@ -2678,6 +3140,22 @@ QuitPage(PINPUT_RECORD Ir)
 
   SetTextXY(10, 11, "Press ENTER to reboot your computer.");
 
 
   SetTextXY(10, 11, "Press ENTER to reboot your computer.");
 
+  SetStatusText("   Please wait ...");
+
+  /* Destroy partition list */
+  if (PartitionList != NULL)
+    {
+      DestroyPartitionList (PartitionList);
+      PartitionList = NULL;
+    }
+
+  /* Destroy filesystem list */
+  if (FileSystemList != NULL)
+    {
+      DestroyFileSystemList (FileSystemList);
+      FileSystemList = NULL;
+    }
+
   SetStatusText("   ENTER = Reboot computer");
 
   while(TRUE)
   SetStatusText("   ENTER = Reboot computer");
 
   while(TRUE)
@@ -2737,7 +3215,6 @@ NtProcessStartup(PPEB Peb)
                       0,0,0,0,0);
     }
 
                       0,0,0,0,0);
     }
 
-  PartDataValid = FALSE;
 
   /* Initialize global unicode strings */
   RtlInitUnicodeString(&SourcePath, NULL);
 
   /* Initialize global unicode strings */
   RtlInitUnicodeString(&SourcePath, NULL);
@@ -2791,6 +3268,10 @@ NtProcessStartup(PPEB Peb)
            Page = CreatePartitionPage(&Ir);
            break;
 
            Page = CreatePartitionPage(&Ir);
            break;
 
+         case DELETE_PARTITION_PAGE:
+           Page = DeletePartitionPage(&Ir);
+           break;
+
          case SELECT_FILE_SYSTEM_PAGE:
            Page = SelectFileSystemPage(&Ir);
            break;
          case SELECT_FILE_SYSTEM_PAGE:
            Page = SelectFileSystemPage(&Ir);
            break;
@@ -2830,6 +3311,12 @@ NtProcessStartup(PPEB Peb)
            break;
 
 
            break;
 
 
+         /* Emergency pages */
+         case EMERGENCY_INTRO_PAGE:
+           Page = EmergencyIntroPage(&Ir);
+           break;
+
+
          case SUCCESS_PAGE:
            Page = SuccessPage(&Ir);
            break;
          case SUCCESS_PAGE:
            Page = SuccessPage(&Ir);
            break;