- Do only allow to install reactos on disks which are visible by the bios.
[reactos.git] / reactos / subsys / system / usetup / usetup.c
index 54ed334..e930201 100644 (file)
  *                  Casper S. Hornstrup (chorns@users.sourceforge.net)
  */
 
-#include <ddk/ntddk.h>
-#include <ntdll/rtl.h>
-
-#include <ntos/minmax.h>
-#include <reactos/resource.h>
-
-#include "usetup.h"
-#include "console.h"
-#include "partlist.h"
-#include "inicache.h"
-#include "infcache.h"
-#include "filequeue.h"
-#include "progress.h"
-#include "bootsup.h"
-#include "registry.h"
-#include "format.h"
-#include "fslist.h"
-#include "cabinet.h"
-#include "filesup.h"
-#include "drivesup.h"
+#include <usetup.h>
 
 #define NDEBUG
 #include <debug.h>
 
-
 typedef enum _PAGE_NUMBER
 {
   START_PAGE,
   INTRO_PAGE,
+  LICENSE_PAGE,
+  WARNING_PAGE,
   INSTALL_INTRO_PAGE,
 
+//  SCSI_CONTROLLER_PAGE,
+
   DEVICE_SETTINGS_PAGE,
   COMPUTER_SETTINGS_PAGE,
   DISPLAY_SETTINGS_PAGE,
   KEYBOARD_SETTINGS_PAGE,
   LAYOUT_SETTINGS_PAGE,
-  POINTER_SETTINGS_PAGE,
 
   SELECT_PARTITION_PAGE,
   CREATE_PARTITION_PAGE,
@@ -76,11 +59,11 @@ typedef enum _PAGE_NUMBER
   FILE_COPY_PAGE,
   REGISTRY_PAGE,
   BOOT_LOADER_PAGE,
+  BOOT_LOADER_FLOPPY_PAGE,
+  BOOT_LOADER_HARDDISK_PAGE,
 
   REPAIR_INTRO_PAGE,
 
-  EMERGENCY_INTRO_PAGE,
-
   SUCCESS_PAGE,
   QUIT_PAGE,
   FLUSH_PAGE,
@@ -129,6 +112,11 @@ static HSPFILEQ SetupFileQueue = NULL;
 
 static BOOLEAN WarnLinuxPartitions = TRUE;
 
+static PGENERIC_LIST ComputerList = NULL;
+static PGENERIC_LIST DisplayList = NULL;
+static PGENERIC_LIST KeyboardList = NULL;
+static PGENERIC_LIST LayoutList = NULL;
+
 
 /* FUNCTIONS ****************************************************************/
 
@@ -356,7 +344,7 @@ PopupError(PCHAR Text,
       coPos.Y++;
       coPos.X = xLeft + 2;
       WriteConsoleOutputCharacters(Status,
-                                  min(strlen(Status), Width - 4),
+                                  min(strlen(Status), (SIZE_T)Width - 4),
                                   coPos);
     }
 }
@@ -427,8 +415,7 @@ CheckUnattendedSetup(VOID)
   RtlInitUnicodeString(&FileName,
                       UnattendInfPath);
 
-  /* Load txtsetup.sif from install media. */
-
+  /* Load 'unattend.inf' from install media. */
   Status = InfOpenFile(&UnattendInf,
                       &FileName,
                       &ErrorLine);
@@ -523,7 +510,7 @@ CheckUnattendedSetup(VOID)
  *     Number of the next page.
  */
 static PAGE_NUMBER
-StartPage(PINPUT_RECORD Ir)
+SetupStartPage(PINPUT_RECORD Ir)
 {
   SYSTEM_DEVICE_INFORMATION Sdi;
   NTSTATUS Status;
@@ -553,7 +540,7 @@ StartPage(PINPUT_RECORD Ir)
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
-             return(QUIT_PAGE);
+             return QUIT_PAGE;
            }
        }
     }
@@ -568,7 +555,7 @@ StartPage(PINPUT_RECORD Ir)
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
-             return(QUIT_PAGE);
+             return QUIT_PAGE;
            }
        }
     }
@@ -587,7 +574,7 @@ StartPage(PINPUT_RECORD Ir)
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
-             return(QUIT_PAGE);
+             return QUIT_PAGE;
            }
        }
     }
@@ -619,7 +606,7 @@ StartPage(PINPUT_RECORD Ir)
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
-             return(QUIT_PAGE);
+             return QUIT_PAGE;
            }
        }
     }
@@ -636,7 +623,7 @@ StartPage(PINPUT_RECORD Ir)
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
-             return(QUIT_PAGE);
+             return QUIT_PAGE;
            }
        }
     }
@@ -654,7 +641,7 @@ StartPage(PINPUT_RECORD Ir)
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
-             return(QUIT_PAGE);
+             return QUIT_PAGE;
            }
        }
     }
@@ -671,14 +658,14 @@ StartPage(PINPUT_RECORD Ir)
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
-             return(QUIT_PAGE);
+             return QUIT_PAGE;
            }
        }
     }
 
   CheckUnattendedSetup();
 
-  return(INTRO_PAGE);
+  return INTRO_PAGE;
 }
 
 
@@ -696,11 +683,11 @@ IntroPage(PINPUT_RECORD Ir)
   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, 17, "\x07  Press R to repair ReactOS.");
+  SetTextXY(8, 19, "\x07  Press L to view the ReactOS Licensing Terms and Conditions");
   SetTextXY(8, 21, "\x07  Press F3 to quit without installing ReactOS.");
 
-  SetStatusText("   ENTER = Continue   F3 = Quit");
+  SetStatusText("   ENTER = Continue  R = Repair F3 = Quit");
 
   if (IsUnattendedSetup)
     {
@@ -720,55 +707,105 @@ IntroPage(PINPUT_RECORD Ir)
        }
       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;
+         return WARNING_PAGE;
+      break;
        }
       else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'R') /* R */
        {
          return REPAIR_INTRO_PAGE;
+      break;
        }
+      else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'L') /* R */
+       {
+         return LICENSE_PAGE;
+      break;
+       }   
     }
 
   return INTRO_PAGE;
 }
 
-
+/*
+ * License Page
+ * RETURNS
+ *     Back to main setup page.
+ */
 static PAGE_NUMBER
-EmergencyIntroPage(PINPUT_RECORD Ir)
+LicensePage(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.");
+  SetHighlightedTextXY(6, 8, "Licensing:");
 
-  SetTextXY(6, 12, "The emergency console is not implemented yet.");
+  SetTextXY(8, 11, "The ReactOS System is licensed under the terms of the");
+  SetTextXY(8, 12, "GNU GPL with parts containing code from other compatible");
+  SetTextXY(8, 13, "licenses such as the X11 or BSD and GNU LGPL licenses.");
+  SetTextXY(8, 14, "All software that is part of the ReactOS system is");
+  SetTextXY(8, 15, "therefore released under the GNU GPL as well as maintaining");
+  SetTextXY(8, 16, "the original license.");
 
-  SetTextXY(8, 15, "\x07  Press ESC to return to the main page.");
+  SetTextXY(8, 18, "This software comes with NO WARRANTY or restrictions on usage");
+  SetTextXY(8, 19, "save applicable local and international law. The licensing of");
+  SetTextXY(8, 20, "ReactOS only covers distribution to third parties.");
 
-  SetTextXY(8, 17, "\x07  Press ENTER to reboot your computer.");
+  SetTextXY(8, 22, "If for some reason you did not receive a copy of the");
+  SetTextXY(8, 23, "GNU General Public License with ReactOS please visit");
+  SetHighlightedTextXY(8, 25, "http://www.gnu.org/licenses/licenses.html");
 
-  SetStatusText("   ESC = Main page  ENTER = Reboot");
+  SetStatusText("   ENTER = Return");
 
-  while(TRUE)
+  while (TRUE)
     {
       ConInKey(Ir);
 
       if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+      {
+          return INTRO_PAGE;
+          break;
+      }
+    }
+
+  return LICENSE_PAGE;
+}
+
+/*
+ * Warning Page
+ * RETURNS
+ *     Continues to setup
+ */
+static PAGE_NUMBER
+WarningPage(PINPUT_RECORD Ir)
+{
+  SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Warranty Statement");
+  SetHighlightedTextXY(6, 8, "Warranty:");
+
+  SetTextXY(8, 11, "This is free software; see the source for copying conditions.");
+  SetTextXY(8, 12, "There is NO warranty; not even for MERCHANTABILITY or");
+  SetTextXY(8, 13, "FITNESS FOR A PARTICULAR PURPOSE");
+
+  SetTextXY(8, 15, "For more information on ReactOS, please visit:");
+  SetHighlightedTextXY(8, 16, "http://www.reactos.org");
+
+  SetStatusText("   F8 = Continue   ESC = Exit");
+
+  while (TRUE)
+    {
+      ConInKey(Ir);
+
+      if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F8)) /* F8 */
        {
-         return(REBOOT_PAGE);
+           return INSTALL_INTRO_PAGE;
+         break;
        }
       else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
               (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */
        {
-         return(INTRO_PAGE);
+         return QUIT_PAGE;
        }
     }
 
-  return(REPAIR_INTRO_PAGE);
+  return LICENSE_PAGE;
 }
 
-
 static PAGE_NUMBER
 RepairIntroPage(PINPUT_RECORD Ir)
 {
@@ -777,9 +814,11 @@ RepairIntroPage(PINPUT_RECORD Ir)
 
   SetTextXY(6, 12, "The repair functions are not implemented yet.");
 
-  SetTextXY(8, 15, "\x07  Press ESC to return to the main page.");
+  SetTextXY(8, 15, "\x07  Press R for the Recovery Console.");
+  
+  SetTextXY(8, 17, "\x07  Press ESC to return to the main page.");
 
-  SetTextXY(8, 17, "\x07  Press ENTER to reboot your computer.");
+  SetTextXY(8, 19, "\x07  Press ENTER to reboot your computer.");
 
   SetStatusText("   ESC = Main page  ENTER = Reboot");
 
@@ -789,22 +828,28 @@ RepairIntroPage(PINPUT_RECORD Ir)
 
       if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
        {
-         return(REBOOT_PAGE);
+         return REBOOT_PAGE;
+       }
+    else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'R') /* R */
+       {
+         return INTRO_PAGE;
        }
       else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
               (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */
        {
-         return(INTRO_PAGE);
+         return INTRO_PAGE;
        }
     }
 
-  return(REPAIR_INTRO_PAGE);
+  return REPAIR_INTRO_PAGE;
 }
 
 
 static PAGE_NUMBER
 InstallIntroPage(PINPUT_RECORD Ir)
 {
+  SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
+
   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.");
 
@@ -827,7 +872,7 @@ InstallIntroPage(PINPUT_RECORD Ir)
 
   if (IsUnattendedSetup)
     {
-      return(SELECT_PARTITION_PAGE);
+      return SELECT_PARTITION_PAGE;
     }
 
   while(TRUE)
@@ -844,6 +889,7 @@ InstallIntroPage(PINPUT_RECORD Ir)
       else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
        {
          return DEVICE_SETTINGS_PAGE;
+//       return SCSI_CONTROLLER_PAGE;
        }
     }
 
@@ -851,10 +897,98 @@ InstallIntroPage(PINPUT_RECORD Ir)
 }
 
 
+#if 0
+static PAGE_NUMBER
+ScsiControllerPage(PINPUT_RECORD Ir)
+{
+  SetTextXY(6, 8, "Setup detected the following mass storage devices:");
+
+  /* FIXME: print loaded mass storage driver descriptions */
+#if 0
+  SetTextXY(8, 10, "TEST device");
+#endif
+
+
+  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 DEVICE_SETTINGS_PAGE;
+       }
+    }
+
+  return SCSI_CONTROLLER_PAGE;
+}
+#endif
+
+
 static PAGE_NUMBER
 DeviceSettingsPage(PINPUT_RECORD Ir)
 {
-  static ULONG Line = 17;
+  static ULONG Line = 16;
+
+  /* Initialize the computer settings list */
+  if (ComputerList == NULL)
+    {
+      ComputerList = CreateComputerTypeList(SetupInf);
+      if (ComputerList == NULL)
+       {
+         /* FIXME: report error */
+       }
+    }
+
+  /* Initialize the display settings list */
+  if (DisplayList == NULL)
+    {
+      DisplayList = CreateDisplayDriverList(SetupInf);
+      if (DisplayList == NULL)
+       {
+         /* FIXME: report error */
+       }
+    }
+
+  /* Initialize the keyboard settings list */
+  if (KeyboardList == NULL)
+    {
+      KeyboardList = CreateKeyboardDriverList(SetupInf);
+      if (KeyboardList == NULL)
+       {
+         /* FIXME: report error */
+       }
+    }
+
+  /* Initialize the keyboard layout list */
+  if (LayoutList == NULL)
+    {
+      LayoutList = CreateKeyboardLayoutList(SetupInf);
+      if (LayoutList == NULL)
+       {
+         /* FIXME: report error */
+         PopupError("Setup failed to load the keyboard layout list.\n",
+                    "ENTER = Reboot computer");
+
+         while (TRUE)
+           {
+             ConInKey(Ir);
+
+             if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)   /* ENTER */
+               {
+                 return QUIT_PAGE;
+               }
+           }
+       }
+    }
 
   SetTextXY(6, 8, "The list below shows the current device settings.");
 
@@ -862,27 +996,24 @@ DeviceSettingsPage(PINPUT_RECORD Ir)
   SetTextXY(8, 12, "        Display:");
   SetTextXY(8, 13, "       Keyboard:");
   SetTextXY(8, 14, "Keyboard layout:");
-  SetTextXY(8, 15, " Pointer device:");
 
-  SetTextXY(8, 17, "         Accept:");
+  SetTextXY(8, 16, "         Accept:");
 
+  SetTextXY(25, 11, GetGenericListEntry(ComputerList)->Text);
+  SetTextXY(25, 12, GetGenericListEntry(DisplayList)->Text);
+  SetTextXY(25, 13, GetGenericListEntry(KeyboardList)->Text);
+  SetTextXY(25, 14, GetGenericListEntry(LayoutList)->Text);
 
-  SetTextXY(25, 11, "Standard-PC");
-  SetTextXY(25, 12, "Automatic detection");
-  SetTextXY(25, 13, "XT-, AT- or extended keyboard (83-105 keys)");
-  SetTextXY(25, 14, "English (USA)");
-  SetTextXY(25, 15, "PS/2 (Mouse port) mouse");
-
-  SetTextXY(25, 17, "Accept these device setings");
+  SetTextXY(25, 16, "Accept these device settings");
   InvertTextXY (24, Line, 48, 1);
 
 
-  SetTextXY(6, 20, "You can change the hardware settings by pressing the UP or DOWN keys");
-  SetTextXY(6, 21, "to select an entry. Then press the ENTER key to select alternative");
-  SetTextXY(6, 22, "settings.");
+  SetTextXY(6, 19, "You can change the hardware settings by pressing the UP or DOWN keys");
+  SetTextXY(6, 20, "to select an entry. Then press the ENTER key to select alternative");
+  SetTextXY(6, 21, "settings.");
 
-  SetTextXY(6, 24, "When all settings are correct, select \"Accept these device setings\"");
-  SetTextXY(6, 25, "and press ENTER.");
+  SetTextXY(6, 23, "When all settings are correct, select \"Accept these device settings\"");
+  SetTextXY(6, 24, "and press ENTER.");
 
   SetStatusText("   ENTER = Continue   F3 = Quit");
 
@@ -894,22 +1025,22 @@ DeviceSettingsPage(PINPUT_RECORD Ir)
          (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
        {
          NormalTextXY (24, Line, 48, 1);
-         if (Line == 15)
-           Line = 17;
-         else if (Line == 17)
+         if (Line == 14)
+           Line = 16;
+         else if (Line == 16)
            Line = 11;
          else
            Line++;
          InvertTextXY (24, Line, 48, 1);
        }
-      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 */
        {
          NormalTextXY (24, Line, 48, 1);
          if (Line == 11)
-           Line = 17;
-         else if (Line == 17)
-           Line = 15;
+           Line = 16;
+         else if (Line == 16)
+           Line = 14;
          else
            Line--;
          InvertTextXY (24, Line, 48, 1);
@@ -931,9 +1062,7 @@ DeviceSettingsPage(PINPUT_RECORD Ir)
            return KEYBOARD_SETTINGS_PAGE;
          else if (Line == 14)
            return LAYOUT_SETTINGS_PAGE;
-         else if (Line == 15)
-           return POINTER_SETTINGS_PAGE;
-         else if (Line == 17)
+         else if (Line == 16)
            return SELECT_PARTITION_PAGE;
        }
     }
@@ -945,22 +1074,56 @@ DeviceSettingsPage(PINPUT_RECORD Ir)
 static PAGE_NUMBER
 ComputerSettingsPage(PINPUT_RECORD Ir)
 {
-  SetTextXY(6, 8, "Computer settings are not implemented yet.");
+  SHORT xScreen;
+  SHORT yScreen;
 
+  SetTextXY(6, 8, "You want to change the type of computer to be installed.");
 
-  SetStatusText("   ENTER = Continue   F3 = Quit");
+  SetTextXY(8, 10, "\x07  Press the UP or DOWN key to select the desired computer type.");
+  SetTextXY(8, 11, "   Then press ENTER.");
+
+  SetTextXY(8, 13, "\x07  Press the ESC key to return to the previous page without changing");
+  SetTextXY(8, 14, "   the computer type.");
+
+  GetScreenSize(&xScreen, &yScreen);
+
+  DrawGenericList(ComputerList,
+                 2,
+                 18,
+                 xScreen - 3,
+                 yScreen - 3);
+
+  SetStatusText("   ENTER = Continue   ESC = Cancel   F3 = Quit");
+
+  SaveGenericListState(ComputerList);
 
   while(TRUE)
     {
       ConInKey(Ir);
 
       if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
-         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
+         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
+       {
+         ScrollDownGenericList (ComputerList);
+       }
+      else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
+       {
+         ScrollUpGenericList (ComputerList);
+       }
+      else 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 */
+       {
+         RestoreGenericListState(ComputerList);
+         return DEVICE_SETTINGS_PAGE;
+       }
       else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
        {
          return DEVICE_SETTINGS_PAGE;
@@ -974,22 +1137,58 @@ ComputerSettingsPage(PINPUT_RECORD Ir)
 static PAGE_NUMBER
 DisplaySettingsPage(PINPUT_RECORD Ir)
 {
-  SetTextXY(6, 8, "Display settings are not implemented yet.");
+  SHORT xScreen;
+  SHORT yScreen;
 
+  SetTextXY(6, 8, "You want to change the type of display to be installed.");
 
-  SetStatusText("   ENTER = Continue   F3 = Quit");
+  SetTextXY(8, 10, "\x07  Press the UP or DOWN key to select the desired display type.");
+  SetTextXY(8, 11, "   Then press ENTER.");
+
+  SetTextXY(8, 13, "\x07  Press the ESC key to return to the previous page without changing");
+  SetTextXY(8, 14, "   the display type.");
+
+  GetScreenSize(&xScreen, &yScreen);
+
+  DrawGenericList(DisplayList,
+                 2,
+                 18,
+                 xScreen - 3,
+                 yScreen - 3);
+
+  SetStatusText("   ENTER = Continue   ESC = Cancel   F3 = Quit");
+
+  SaveGenericListState(DisplayList);
 
   while(TRUE)
     {
       ConInKey(Ir);
 
       if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
-         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
+         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
+       {
+         ScrollDownGenericList (DisplayList);
+       }
+      else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
+       {
+         ScrollUpGenericList (DisplayList);
+       }
+      else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+              (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
        {
          if (ConfirmQuit(Ir) == TRUE)
-           return QUIT_PAGE;
+           {
+             return QUIT_PAGE;
+           }
          break;
        }
+      else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+              (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */
+       {
+         RestoreGenericListState(DisplayList);
+         return DEVICE_SETTINGS_PAGE;
+       }
       else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
        {
          return DEVICE_SETTINGS_PAGE;
@@ -1003,22 +1202,56 @@ DisplaySettingsPage(PINPUT_RECORD Ir)
 static PAGE_NUMBER
 KeyboardSettingsPage(PINPUT_RECORD Ir)
 {
-  SetTextXY(6, 8, "Keyboard settings are not implemented yet.");
+  SHORT xScreen;
+  SHORT yScreen;
 
+  SetTextXY(6, 8, "You want to change the type of keyboard to be installed.");
 
-  SetStatusText("   ENTER = Continue   F3 = Quit");
+  SetTextXY(8, 10, "\x07  Press the UP or DOWN key to select the desired keyboard type.");
+  SetTextXY(8, 11, "   Then press ENTER.");
+
+  SetTextXY(8, 13, "\x07  Press the ESC key to return to the previous page without changing");
+  SetTextXY(8, 14, "   the keyboard type.");
+
+  GetScreenSize(&xScreen, &yScreen);
+
+  DrawGenericList(KeyboardList,
+                 2,
+                 18,
+                 xScreen - 3,
+                 yScreen - 3);
+
+  SetStatusText("   ENTER = Continue   ESC = Cancel   F3 = Quit");
+
+  SaveGenericListState(KeyboardList);
 
   while(TRUE)
     {
       ConInKey(Ir);
 
       if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
-         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
+         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
+       {
+         ScrollDownGenericList (KeyboardList);
+       }
+      else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
+       {
+         ScrollUpGenericList (KeyboardList);
+       }
+      else 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 */
+       {
+         RestoreGenericListState(KeyboardList);
+         return DEVICE_SETTINGS_PAGE;
+       }
       else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
        {
          return DEVICE_SETTINGS_PAGE;
@@ -1032,51 +1265,56 @@ KeyboardSettingsPage(PINPUT_RECORD Ir)
 static PAGE_NUMBER
 LayoutSettingsPage(PINPUT_RECORD Ir)
 {
-  SetTextXY(6, 8, "Keyboard layout settings are not implemented yet.");
-
-
-  SetStatusText("   ENTER = Continue   F3 = Quit");
+  SHORT xScreen;
+  SHORT yScreen;
 
-  while(TRUE)
-    {
-      ConInKey(Ir);
+  SetTextXY(6, 8, "You want to change the keyboard layout to be installed.");
 
-      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 DEVICE_SETTINGS_PAGE;
-       }
-    }
+  SetTextXY(8, 10, "\x07  Press the UP or DOWN key to select the desired keyboard");
+  SetTextXY(8, 11, "    layout. Then press ENTER.");
 
-  return DISPLAY_SETTINGS_PAGE;
-}
+  SetTextXY(8, 13, "\x07  Press the ESC key to return to the previous page without changing");
+  SetTextXY(8, 14, "   the keyboard layout.");
 
+  GetScreenSize(&xScreen, &yScreen);
 
-static PAGE_NUMBER
-PointerSettingsPage(PINPUT_RECORD Ir)
-{
-  SetTextXY(6, 8, "Pointer settings are not implemented yet.");
+  DrawGenericList(LayoutList,
+                 2,
+                 18,
+                 xScreen - 3,
+                 yScreen - 3);
 
+  SetStatusText("   ENTER = Continue   ESC = Cancel   F3 = Quit");
 
-  SetStatusText("   ENTER = Continue   F3 = Quit");
+  SaveGenericListState(LayoutList);
 
   while(TRUE)
     {
       ConInKey(Ir);
 
       if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
-         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
+         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
+       {
+         ScrollDownGenericList (LayoutList);
+       }
+      else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
+       {
+         ScrollUpGenericList (LayoutList);
+       }
+      else 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 */
+       {
+         RestoreGenericListState(LayoutList);
+         return DEVICE_SETTINGS_PAGE;
+       }
       else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
        {
          return DEVICE_SETTINGS_PAGE;
@@ -1207,7 +1445,7 @@ SelectPartitionPage(PINPUT_RECORD Ir)
 
          return SELECT_FILE_SYSTEM_PAGE;
        }
-      else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_C) /* C */
+      else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'C') /* C */
        {
          if (PartitionList->CurrentPartition->Unpartitioned == FALSE)
            {
@@ -1223,7 +1461,7 @@ SelectPartitionPage(PINPUT_RECORD Ir)
 
          return CREATE_PARTITION_PAGE;
        }
-      else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_D) /* D */
+      else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'D') /* D */
        {
          if (PartitionList->CurrentPartition->Unpartitioned == TRUE)
            {
@@ -1375,8 +1613,8 @@ ShowPartitionSizeInputBox(SHORT Left,
                                strlen (Buffer),
                                coPos);
 
-  Buffer[0] = 0;
-  Index = 0;
+  sprintf(Buffer, "%lu", MaxSize);
+  Index = strlen(Buffer);
   DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH,
                  iLeft,
                  iTop,
@@ -1631,14 +1869,14 @@ DeletePartitionPage (PINPUT_RECORD Ir)
     }
 
 #if 0
-  if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0x280000000ULL) /* 10 GB */
+  if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0x280000000LL) /* 10 GB */
     {
       PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 29)) >> 30;
       Unit = "GB";
     }
   else
 #endif
-  if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0xA00000ULL) /* 10 MB */
+  if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0xA00000LL) /* 10 MB */
     {
       PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 19)) >> 20;
       Unit = "MB";
@@ -1733,7 +1971,7 @@ DeletePartitionPage (PINPUT_RECORD Ir)
        {
          return SELECT_PARTITION_PAGE;
        }
-      else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_D) /* D */
+      else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'D') /* D */
        {
          DeleteCurrentPartition (PartitionList);
 
@@ -1780,7 +2018,7 @@ SelectFileSystemPage (PINPUT_RECORD Ir)
     }
 
   /* adjust partition size */
-  if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0x280000000ULL) /* 10 GB */
+  if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0x280000000LL) /* 10 GB */
     {
       PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 29)) >> 30;
       PartUnit = "GB";
@@ -1966,6 +2204,7 @@ FormatPartitionPage (PINPUT_RECORD Ir)
 #ifndef NDEBUG
   ULONG Line;
   ULONG i;
+  PLIST_ENTRY Entry;
 #endif
 
 
@@ -2009,21 +2248,21 @@ FormatPartitionPage (PINPUT_RECORD Ir)
              switch (FileSystemList->CurrentFileSystem)
                {
                  case FsFat:
-                   if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (4200ULL * 1024ULL))
+                   if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (4200LL * 1024LL))
                      {
                        /* 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))
+                   else if (PartEntry->PartInfo[0].StartingOffset.QuadPart < (1024LL * 255LL * 63LL * 512LL))
                      {
                        /* Partition starts below the 8.4GB boundary ==> CHS partition */
 
-                       if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (32ULL * 1024ULL * 1024ULL))
+                       if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (32LL * 1024LL * 1024LL))
                          {
                            /* FAT16 CHS partition (partiton size < 32MB) */
                            PartEntry->PartInfo[0].PartitionType = PARTITION_FAT_16;
                          }
-                       else if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (512ULL * 1024ULL * 1024ULL))
+                       else if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (512LL * 1024LL * 1024LL))
                          {
                            /* FAT16 CHS partition (partition size < 512MB) */
                            PartEntry->PartInfo[0].PartitionType = PARTITION_HUGE;
@@ -2038,7 +2277,7 @@ FormatPartitionPage (PINPUT_RECORD Ir)
                      {
                        /* Partition starts above the 8.4GB boundary ==> LBA partition */
 
-                       if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (512ULL * 1024ULL * 1024ULL))
+                       if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (512LL * 1024LL * 1024LL))
                          {
                            /* FAT16 LBA partition (partition size < 512MB) */
                            PartEntry->PartInfo[0].PartitionType = PARTITION_XINT13;
@@ -2206,8 +2445,10 @@ FormatPartitionPage (PINPUT_RECORD Ir)
                return QUIT_PAGE;
            }
 
+#ifndef NDEBUG
          SetStatusText ("   Done.  Press any key ...");
          ConInKey(Ir);
+#endif
 
          return INSTALL_DIRECTORY_PAGE;
        }
@@ -2304,7 +2545,7 @@ InstallDirectoryPage1(PWCHAR InstallDir, PDISKENTRY DiskEntry, PPARTENTRY PartEn
   RtlFreeUnicodeString(&DestinationArcPath);
   swprintf(PathBuffer,
           L"multi(0)disk(0)rdisk(%lu)partition(%lu)",
-          DiskEntry->DiskNumber,
+          DiskEntry->BiosDiskNumber,
           PartEntry->PartInfo[0].PartitionNumber);
   if (InstallDir[0] != L'\\')
     wcscat(PathBuffer,
@@ -2396,7 +2637,7 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
        }
       else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
        {
-          return (InstallDirectoryPage1 (InstallDir, DiskEntry, PartEntry));
+         return (InstallDirectoryPage1 (InstallDir, DiskEntry, PartEntry));
        }
       else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x08) /* BACKSPACE */
        {
@@ -2424,25 +2665,24 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
 
 
 static BOOLEAN
-PrepareCopyPageInfFile(HINF InfFile, PWCHAR SourceCabinet, PINPUT_RECORD Ir)
+AddSectionToCopyQueue(HINF InfFile,
+                      PWCHAR SectionName,
+                      PWCHAR SourceCabinet,
+                      PINPUT_RECORD Ir)
 {
-  WCHAR PathBuffer[MAX_PATH];
   INFCONTEXT FilesContext;
   INFCONTEXT DirContext;
-  PWCHAR KeyValue;
-  ULONG Length;
-  NTSTATUS Status;
   PWCHAR FileKeyName;
   PWCHAR FileKeyValue;
   PWCHAR DirKeyValue;
   PWCHAR TargetFileName;
 
-  /* Search for the 'SourceFiles' section */
-  if (!InfFindFirstLine (InfFile, L"SourceFiles", NULL, &FilesContext))
+  /* Search for the SectionName section */
+  if (!InfFindFirstLine (InfFile, SectionName, NULL, &FilesContext))
     {
-      PopupError("Setup failed to find the 'SourceFiles' section\n"
-                "in TXTSETUP.SIF.\n",  // FIXME
-                "ENTER = Reboot computer");
+      char Buffer[128];
+      sprintf(Buffer, "Setup failed to find the '%S' section\nin TXTSETUP.SIF.\n", SectionName);
+      PopupError(Buffer, "ENTER = Reboot computer");
 
       while(TRUE)
        {
@@ -2456,7 +2696,7 @@ PrepareCopyPageInfFile(HINF InfFile, PWCHAR SourceCabinet, PINPUT_RECORD Ir)
     }
 
   /*
-   * Enumerate the files in the 'SourceFiles' section
+   * Enumerate the files in the section
    * and add them to the file queue.
    */
   do
@@ -2504,13 +2744,43 @@ PrepareCopyPageInfFile(HINF InfFile, PWCHAR SourceCabinet, PINPUT_RECORD Ir)
     }
   while (InfFindNextLine(&FilesContext, &FilesContext));
 
+  return TRUE;
+}
 
-  /* Create directories */
-
-  /*
-   * FIXME:
-   * Install directories like '\reactos\test' are not handled yet.
-   */
+static BOOLEAN
+PrepareCopyPageInfFile(HINF InfFile,
+                      PWCHAR SourceCabinet,
+                      PINPUT_RECORD Ir)
+{
+  WCHAR PathBuffer[MAX_PATH];
+  INFCONTEXT DirContext;
+  PWCHAR AdditionalSectionName;
+  PWCHAR KeyValue;
+  ULONG Length;
+  NTSTATUS Status;
+
+  /* Add common files */
+  if (!AddSectionToCopyQueue(InfFile, L"SourceFiles", SourceCabinet, Ir))
+    return FALSE;
+
+  /* Add specific files depending of computer type */
+  if (SourceCabinet == NULL)
+  {
+    if (!ProcessComputerFiles(InfFile, ComputerList, &AdditionalSectionName))
+      return FALSE;
+    if (AdditionalSectionName)
+    {
+      if (!AddSectionToCopyQueue(InfFile, AdditionalSectionName, SourceCabinet, Ir))
+        return FALSE;
+    }
+  }
+
+  /* Create directories */
+
+  /*
+   * FIXME:
+   * Install directories like '\reactos\test' are not handled yet.
+   */
 
   /* Get destination path */
   wcscpy(PathBuffer, DestinationPath.Buffer);
@@ -2523,7 +2793,7 @@ PrepareCopyPageInfFile(HINF InfFile, PWCHAR SourceCabinet, PINPUT_RECORD Ir)
     }
 
   /* Create the install directory */
-  Status = CreateDirectory(PathBuffer);
+  Status = SetupCreateDirectory(PathBuffer);
   if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
     {
       DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
@@ -2594,7 +2864,7 @@ PrepareCopyPageInfFile(HINF InfFile, PWCHAR SourceCabinet, PINPUT_RECORD Ir)
 
          DPRINT("FullPath: '%S'\n", PathBuffer);
 
-         Status = CreateDirectory(PathBuffer);
+         Status = SetupCreateDirectory(PathBuffer);
          if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
            {
              DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
@@ -2633,10 +2903,6 @@ PrepareCopyPage(PINPUT_RECORD Ir)
 
   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 */
@@ -2657,32 +2923,17 @@ PrepareCopyPage(PINPUT_RECORD Ir)
        }
     }
 
-
   if (!PrepareCopyPageInfFile(SetupInf, NULL, Ir))
     {
-      return(QUIT_PAGE);
+      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);
-           }
-       }
+      return FILE_COPY_PAGE;
     }
 
-
   /*
    * Enumerate the directory values in the 'Cabinets'
    * section and parse their inf files.
@@ -2716,7 +2967,7 @@ PrepareCopyPage(PINPUT_RECORD Ir)
 
                  if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
                    {
-                     return(QUIT_PAGE);
+                     return QUIT_PAGE;
                    }
                }
            }
@@ -2734,7 +2985,7 @@ PrepareCopyPage(PINPUT_RECORD Ir)
 
              if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)   /* ENTER */
                {
-                 return(QUIT_PAGE);
+                 return QUIT_PAGE;
                }
            }
        }
@@ -2754,7 +3005,7 @@ PrepareCopyPage(PINPUT_RECORD Ir)
 
              if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)   /* ENTER */
                {
-                 return(QUIT_PAGE);
+                 return QUIT_PAGE;
                }
            }
        }
@@ -2763,12 +3014,12 @@ PrepareCopyPage(PINPUT_RECORD Ir)
 
       if (!PrepareCopyPageInfFile(InfHandle, KeyValue, Ir))
         {
-          return(QUIT_PAGE);
+          return QUIT_PAGE;
         }
     }
   while (InfFindNextLine (&CabinetsContext, &CabinetsContext));
 
-  return(FILE_COPY_PAGE);
+  return FILE_COPY_PAGE;
 }
 
 
@@ -2792,11 +3043,7 @@ FileCopyCallback(PVOID Context,
 
       case SPFILENOTIFY_STARTCOPY:
        /* Display copy message */
-       PrintTextXYN(6, 16, 60, "Copying file: %S", (PWSTR)Param1);
-
-       PrintTextXYN(6, 18, 60, "File %lu of %lu",
-                    CopyContext->CompletedOperations + 1,
-                    CopyContext->TotalOperations);
+    SetStatusText("                                                   \xB3 Copying file: %S", (PWSTR)Param1);
        break;
 
       case SPFILENOTIFY_ENDCOPY:
@@ -2805,7 +3052,7 @@ FileCopyCallback(PVOID Context,
        break;
     }
 
-  return(0);
+  return 0;
 }
 
 
@@ -2816,18 +3063,20 @@ FileCopyPage(PINPUT_RECORD Ir)
   SHORT xScreen;
   SHORT yScreen;
 
-  SetStatusText("   Please wait...");
-
-  SetTextXY(6, 8, "Copying files");
+  SetStatusText("                                                           \xB3 Please wait...    ");
 
-  GetScreenSize(&xScreen, &yScreen);
+  SetTextXY(11, 12, "Please wait while ReactOS Setup copies files to your ReactOS");
+  SetTextXY(30, 13, "installation folder.");
+  SetTextXY(20, 14, "This may take several minutes to complete.");
 
+  GetScreenSize(&xScreen, &yScreen);  
   CopyContext.TotalOperations = 0;
   CopyContext.CompletedOperations = 0;
-  CopyContext.ProgressBar = CreateProgressBar(6,
-                                             yScreen - 14,
-                                             xScreen - 7,
-                                             yScreen - 10);
+  CopyContext.ProgressBar = CreateProgressBar(13,
+                                             26,
+                                             xScreen - 13,
+                                             yScreen - 20,
+                          "Setup is copying files...");
 
   SetupCommitFileQueue(SetupFileQueue,
                       DestinationRootPath.Buffer,
@@ -2839,7 +3088,7 @@ FileCopyPage(PINPUT_RECORD Ir)
 
   DestroyProgressBar(CopyContext.ProgressBar);
 
-  return(REGISTRY_PAGE);
+  return REGISTRY_PAGE;
 }
 
 
@@ -2847,13 +3096,11 @@ static PAGE_NUMBER
 RegistryPage(PINPUT_RECORD Ir)
 {
   INFCONTEXT InfContext;
-  NTSTATUS Status;
-
   PWSTR Action;
   PWSTR File;
   PWSTR Section;
   BOOLEAN Delete;
-
+  NTSTATUS Status;
 
   SetTextXY(6, 8, "Setup is updating the system configuration");
 
@@ -2871,7 +3118,7 @@ RegistryPage(PINPUT_RECORD Ir)
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
-             return(QUIT_PAGE);
+             return QUIT_PAGE;
            }
        }
     }
@@ -2890,7 +3137,7 @@ RegistryPage(PINPUT_RECORD Ir)
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
-             return(QUIT_PAGE);
+             return QUIT_PAGE;
            }
        }
     }
@@ -2910,7 +3157,7 @@ RegistryPage(PINPUT_RECORD Ir)
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
-             return(QUIT_PAGE);
+             return QUIT_PAGE;
            }
        }
     }
@@ -2921,7 +3168,7 @@ RegistryPage(PINPUT_RECORD Ir)
       InfGetDataField (&InfContext, 1, &File);
       InfGetDataField (&InfContext, 2, &Section);
 
-      DPRINT1("Action: %S  File: %S  Section %S\n", Action, File, Section);
+      DPRINT("Action: %S  File: %S  Section %S\n", Action, File, Section);
 
       if (!_wcsicmp (Action, L"AddReg"))
        {
@@ -2940,7 +3187,7 @@ RegistryPage(PINPUT_RECORD Ir)
 
       if (!ImportRegistryFile(File, Section, Delete))
        {
-         DPRINT1("Importing %S failed\n", File);
+         DPRINT("Importing %S failed\n", File);
 
          PopupError("Setup failed to import a hive file.",
                     "ENTER = Reboot computer");
@@ -2951,34 +3198,18 @@ RegistryPage(PINPUT_RECORD Ir)
 
              if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)   /* ENTER */
                {
-                 return(QUIT_PAGE);
+                 return QUIT_PAGE;
                }
            }
        }
     }
   while (InfFindNextLine (&InfContext, &InfContext));
 
-  SetStatusText("   Done...");
-
-  return(BOOT_LOADER_PAGE);
-}
-
-
-static PAGE_NUMBER
-BootLoaderPage(PINPUT_RECORD Ir)
-{
-  WCHAR SrcPath[MAX_PATH];
-  WCHAR DstPath[MAX_PATH];
-  NTSTATUS Status;
-
-  SetTextXY(6, 8, "Installing the boot loader");
-
-  SetStatusText("   Please wait...");
-
-  if (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_ENTRY_UNUSED)
+  /* Update display registry settings */
+  SetStatusText("   Updating display registry settings...");
+  if (!ProcessDisplayRegistry(SetupInf, DisplayList))
     {
-      DPRINT1("Error: active partition invalid (unused)\n");
-      PopupError("The active partition is unused (invalid).\n",
+      PopupError("Setup failed to update display registry settings.",
                 "ENTER = Reboot computer");
 
       while(TRUE)
@@ -2987,17 +3218,16 @@ BootLoaderPage(PINPUT_RECORD Ir)
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
-             return(QUIT_PAGE);
+             return QUIT_PAGE;
            }
        }
     }
 
-  if (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == 0x0A)
+  /* Update keyboard layout settings */
+  SetStatusText("   Updating keyboard layout settings...");
+  if (!ProcessKeyboardLayoutRegistry(LayoutList))
     {
-      /* OS/2 boot manager partition */
-      DPRINT1("Found OS/2 boot manager partition\n");
-      PopupError("Setup found an OS/2 boot manager partiton.\n"
-                "The OS/2 boot manager is not supported yet!",
+      PopupError("Setup failed to update keyboard layout settings.",
                 "ENTER = Reboot computer");
 
       while(TRUE)
@@ -3006,557 +3236,241 @@ BootLoaderPage(PINPUT_RECORD Ir)
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
-             return(QUIT_PAGE);
+             return QUIT_PAGE;
            }
        }
     }
-  else if (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == 0x83)
-    {
-      /* Linux ext2 partition */
-      DPRINT1("Found Linux ext2 partition\n");
-      PopupError("Setup found a Linux ext2 partiton.\n"
-                "Linux ext2 partitions are not supported yet!",
-                "ENTER = Reboot computer");
 
-      while(TRUE)
-       {
-         ConInKey(Ir);
+  /* Update the mounted devices list */
+  SetMountedDeviceValues(PartitionList);
 
-         if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
-           {
-             return(QUIT_PAGE);
-           }
-       }
+  SetStatusText("   Done...");
+
+  return BOOT_LOADER_PAGE;
+}
+
+
+static PAGE_NUMBER
+BootLoaderPage(PINPUT_RECORD Ir)
+{
+  UCHAR PartitionType;
+  BOOLEAN InstallOnFloppy;
+  USHORT Line = 12;
+
+  SetStatusText("   Please wait...");
+
+  PartitionType = PartitionList->ActiveBootPartition->PartInfo[0].PartitionType;
+
+  if (PartitionType == PARTITION_ENTRY_UNUSED)
+    {
+      DPRINT("Error: active partition invalid (unused)\n");
+      InstallOnFloppy = TRUE;
+    }
+  else if (PartitionType == 0x0A)
+    {
+      /* OS/2 boot manager partition */
+      DPRINT("Found OS/2 boot manager partition\n");
+      InstallOnFloppy = TRUE;
+    }
+  else if (PartitionType == 0x83)
+    {
+      /* Linux ext2 partition */
+      DPRINT("Found Linux ext2 partition\n");
+      InstallOnFloppy = TRUE;
     }
-  else if (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_IFS)
+  else if (PartitionType == PARTITION_IFS)
     {
       /* NTFS partition */
-      DPRINT1("Found NTFS partition\n");
-      PopupError("Setup found an NTFS partiton.\n"
-                "NTFS partitions are not supported yet!",
-                "ENTER = Reboot computer");
-
-      while(TRUE)
-       {
-         ConInKey(Ir);
-
-         if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
-           {
-             return(QUIT_PAGE);
-           }
-       }
+      DPRINT("Found NTFS partition\n");
+      InstallOnFloppy = TRUE;
     }
-  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);
-
-    if (DoesFileExist(SystemRootPath.Buffer, L"ntldr") == TRUE ||
-       DoesFileExist(SystemRootPath.Buffer, L"boot.ini") == TRUE)
+  else if ((PartitionType == PARTITION_FAT_12) ||
+          (PartitionType == PARTITION_FAT_16) ||
+          (PartitionType == PARTITION_HUGE) ||
+          (PartitionType == PARTITION_XINT13) ||
+          (PartitionType == PARTITION_FAT32) ||
+          (PartitionType == PARTITION_FAT32_XINT13))
+    {
+      DPRINT("Found FAT partition\n");
+      InstallOnFloppy = FALSE;
+    }
+  else
     {
-      /* Search root directory for 'ntldr' and 'boot.ini'. */
-      DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n");
+      /* Unknown partition */
+      DPRINT("Unknown partition found\n");
+      InstallOnFloppy = TRUE;
+    }
 
-      /* 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");
+  if (InstallOnFloppy == TRUE)
+    {
+      return BOOT_LOADER_FLOPPY_PAGE;
+    }
 
-      DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath);
-      Status = SetupCopyFile(SrcPath, DstPath);
-      if (!NT_SUCCESS(Status))
-      {
-       DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
-       PopupError("Setup failed to copy 'freeldr.sys'.",
-                  "ENTER = Reboot computer");
+  SetTextXY(6, 8, "Setup is installing the boot loader");
 
-       while(TRUE)
-       {
-         ConInKey(Ir);
+  SetTextXY(8, 12, "Install bootloader on the harddisk (MBR).");
+  SetTextXY(8, 13, "Install bootloader on a floppy disk.");
+  InvertTextXY (8, Line, 48, 1);
 
-         if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
-         {
-           return(QUIT_PAGE);
-         }
-       }
-      }
+  SetStatusText("   ENTER = Continue   F3 = Quit");
 
-      /* 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");
+  while(TRUE)
+    {
+      ConInKey(Ir);
 
-       Status = CreateFreeLoaderIniForReactos(DstPath,
-                                              DestinationArcPath.Buffer);
-       if (!NT_SUCCESS(Status))
+      if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
        {
-         DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status);
-         PopupError("Setup failed to create 'freeldr.ini'.",
-                    "ENTER = Reboot computer");
-
-         while(TRUE)
-         {
-           ConInKey(Ir);
-
-           if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)     /* ENTER */
-           {
-             return(QUIT_PAGE);
-           }
-         }
+         NormalTextXY (8, Line, 48, 1);
+         if (Line == 12)
+           Line = 13;
+         else if (Line == 13)
+           Line = 12;
+#if 0
+         else
+           Line++;
+#endif
+         InvertTextXY (8, Line, 48, 1);
        }
-
-       /* Install new bootcode */
-       if ((PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_FAT32) ||
-           (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13))
+      else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+              (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
        {
-         /* 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);
-           PopupError("Setup failed to install the FAT32 bootcode.",
-                      "ENTER = Reboot computer");
-
-           while(TRUE)
-           {
-             ConInKey(Ir);
-
-             if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)   /* ENTER */
-             {
-               return(QUIT_PAGE);
-             }
-           }
-         }
+         NormalTextXY (8, Line, 48, 1);
+         if (Line == 12)
+           Line = 13;
+         else if (Line == 13)
+           Line = 12;
+#if 0
+         else
+           Line--;
+#endif
+         InvertTextXY (8, Line, 48, 1);
        }
-       else
+      else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+              (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
        {
-         /* 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);
-           PopupError("Setup failed to install the FAT bootcode.",
-                      "ENTER = Reboot computer");
-
-           while(TRUE)
-           {
-             ConInKey(Ir);
-
-             if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)   /* ENTER */
-             {
-               return(QUIT_PAGE);
-             }
-           }
-         }
+         if (ConfirmQuit(Ir) == TRUE)
+           return QUIT_PAGE;
+         break;
        }
-
-       /* 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))
+      else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)     /* ENTER */
        {
-         DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status);
-         PopupError("Setup failed to update \'boot.ini\'.",
-                    "ENTER = Reboot computer");
-
-         while(TRUE)
-         {
-           ConInKey(Ir);
-
-           if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)     /* ENTER */
+         if (Line == 12)
            {
-             return(QUIT_PAGE);
+             return BOOT_LOADER_HARDDISK_PAGE;
            }
-         }
-       }
-      }
-      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);
-         PopupError("Setup failed to update 'freeldr.ini'.",
-                    "ENTER = Reboot computer");
-
-         while(TRUE)
-         {
-           ConInKey(Ir);
-
-           if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)     /* ENTER */
+         else if (Line == 13)
            {
-             return(QUIT_PAGE);
+             return BOOT_LOADER_FLOPPY_PAGE;
            }
-         }
+
+         return BOOT_LOADER_PAGE;
        }
-      }
-    }
-    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);
-       PopupError("Setup failed to copy 'freeldr.sys'.",
-                  "ENTER = Reboot computer");
+  return BOOT_LOADER_PAGE;
+}
 
-       while(TRUE)
-       {
-         ConInKey(Ir);
 
-         if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
-         {
-           return(QUIT_PAGE);
-         }
-       }
-      }
+static PAGE_NUMBER
+BootLoaderFloppyPage(PINPUT_RECORD Ir)
+{
+  NTSTATUS 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");
+  SetTextXY(6, 8, "Setup cannot install the bootloader on your computers");
+  SetTextXY(6, 9, "harddisk");
 
-       Status = CreateFreeLoaderIniForDos(DstPath,
-                                          DestinationArcPath.Buffer);
-       if (!NT_SUCCESS(Status))
-       {
-         DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status);
-         PopupError("Setup failed to create 'freeldr.ini'.",
-                    "ENTER = Reboot computer");
+  SetTextXY(6, 13, "Please insert a formatted floppy disk in drive A: and");
+  SetTextXY(6, 14, "press ENTER.");
 
-         while(TRUE)
-         {
-           ConInKey(Ir);
 
-           if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)     /* ENTER */
-           {
-             return(QUIT_PAGE);
-           }
-         }
-       }
+  SetStatusText("   ENTER = Continue   F3 = Quit");
+//  SetStatusText("   Please wait...");
 
-       /* Save current bootsector as 'BOOTSECT.DOS' */
-       wcscpy(SrcPath, SystemRootPath.Buffer);
-       wcscpy(DstPath, SystemRootPath.Buffer);
-       wcscat(DstPath, L"\\bootsect.dos");
+  while(TRUE)
+    {
+      ConInKey(Ir);
 
-       DPRINT1("Save bootsector: %S ==> %S\n", SrcPath, DstPath);
-       Status = SaveCurrentBootSector(SrcPath,
-                                      DstPath);
-       if (!NT_SUCCESS(Status))
+      if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+         (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
        {
-         DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status);
-         PopupError("Setup failed to save the current bootsector.",
-                    "ENTER = Reboot computer");
-
-         while(TRUE)
-         {
-           ConInKey(Ir);
-
-           if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)     /* ENTER */
-           {
-             return(QUIT_PAGE);
-           }
-         }
+         if (ConfirmQuit(Ir) == TRUE)
+           return QUIT_PAGE;
+         break;
        }
-
-       /* Install new bootsector */
-       if ((PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_FAT32) ||
-           (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13))
+      else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)     /* ENTER */
        {
-         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);
-           PopupError("Setup failed to install the FAT32 bootcode.",
-                      "ENTER = Reboot computer");
-
-           while(TRUE)
+         if (DoesFileExist(L"\\Device\\Floppy0", L"\\") == FALSE)
            {
-             ConInKey(Ir);
+             PopupError("No disk in drive A:.",
+                        "ENTER = Continue");
+             while(TRUE)
+               {
+                 ConInKey(Ir);
 
-             if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)   /* ENTER */
-             {
-               return(QUIT_PAGE);
-             }
+                 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
+                   break;
+               }
+
+             return BOOT_LOADER_FLOPPY_PAGE;
            }
-         }
-       }
-       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);
+         Status = InstallFatBootcodeToFloppy(&SourceRootPath,
+                                             &DestinationArcPath);
          if (!NT_SUCCESS(Status))
-         {
-           DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status);
-           PopupError("Setup failed to install the FAT bootcode.",
-                      "ENTER = Reboot computer");
-
-           while(TRUE)
            {
-             ConInKey(Ir);
-
-             if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)   /* ENTER */
-             {
-               return(QUIT_PAGE);
-             }
+             /* Print error message */
+             return BOOT_LOADER_FLOPPY_PAGE;
            }
-         }
-       }
-      }
-      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);
-         PopupError("Setup failed to update 'freeldr.ini'.",
-                    "ENTER = Reboot computer");
-
-         while(TRUE)
-         {
-           ConInKey(Ir);
 
-           if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)     /* ENTER */
-           {
-             return(QUIT_PAGE);
-           }
-         }
+         return SUCCESS_PAGE;
        }
-      }
     }
-    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);
-       PopupError("Setup failed to copy 'freeldr.sys'.",
-                  "ENTER = Reboot computer");
-
-       while(TRUE)
-       {
-         ConInKey(Ir);
-
-         if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
-         {
-           return(QUIT_PAGE);
-         }
-       }
-      }
 
-      /* 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);
-         PopupError("Setup failed to create \'freeldr.ini\'.",
-                    "ENTER = Reboot computer");
-
-         while(TRUE)
-         {
-           ConInKey(Ir);
+  return BOOT_LOADER_FLOPPY_PAGE;
+}
 
-           if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)     /* ENTER */
-           {
-             return(QUIT_PAGE);
-           }
-         }
-       }
 
-       /* Save current bootsector as 'BOOTSECT.OLD' */
-       wcscpy(SrcPath, SystemRootPath.Buffer);
-       wcscpy(DstPath, SystemRootPath.Buffer);
-       wcscat(DstPath, L"\\bootsect.old");
+static PAGE_NUMBER
+BootLoaderHarddiskPage(PINPUT_RECORD Ir)
+{
+  UCHAR PartitionType;
+  NTSTATUS Status;
 
-       DPRINT1("Save bootsector: %S ==> %S\n", SrcPath, DstPath);
-       Status = SaveCurrentBootSector(SrcPath,
-                                      DstPath);
-       if (!NT_SUCCESS(Status))
+  PartitionType = PartitionList->ActiveBootPartition->PartInfo[0].PartitionType;
+  if ((PartitionType == PARTITION_FAT_12) ||
+      (PartitionType == PARTITION_FAT_16) ||
+      (PartitionType == PARTITION_HUGE) ||
+      (PartitionType == PARTITION_XINT13) ||
+      (PartitionType == PARTITION_FAT32) ||
+      (PartitionType == PARTITION_FAT32_XINT13))
+    {
+      Status = InstallFatBootcodeToPartition(&SystemRootPath,
+                                            &SourceRootPath,
+                                            &DestinationArcPath,
+                                            PartitionType);
+      if (!NT_SUCCESS(Status))
        {
-         DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status);
-         PopupError("Setup failed save the current bootsector.",
+         PopupError("Setup failed to install the FAT bootcode on the system partition.",
                     "ENTER = Reboot computer");
 
          while(TRUE)
-         {
-           ConInKey(Ir);
-
-           if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)     /* ENTER */
-           {
-             return(QUIT_PAGE);
-           }
-         }
-       }
-
-       /* Install new bootsector */
-       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");
-
-         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);
-           PopupError("Setup failed to install the FAT32 bootcode.",
-                      "ENTER = Reboot computer");
-
-           while(TRUE)
-           {
-             ConInKey(Ir);
-
-             if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)   /* ENTER */
-             {
-               return(QUIT_PAGE);
-             }
-           }
-         }
-       }
-       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);
-           PopupError("Setup failed to install the FAT bootcode.",
-                      "ENTER = Reboot computer");
-
-           while(TRUE)
            {
              ConInKey(Ir);
 
              if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)   /* ENTER */
-             {
-               return(QUIT_PAGE);
-             }
+               {
+                 return QUIT_PAGE;
+               }
            }
-         }
        }
-      }
-      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);
-         PopupError("Setup failed to update 'freeldr.ini'.",
-                    "ENTER = Reboot computer");
-
-         while(TRUE)
-         {
-           ConInKey(Ir);
-
-           if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)     /* ENTER */
-           {
-             return(QUIT_PAGE);
-           }
-         }
-       }
-      }
+      return SUCCESS_PAGE;
     }
-  }
   else
     {
-      /* Unknown partition */
-      DPRINT1("Unknown partition found\n");
-      PopupError("Setup found an unknown partiton type.\n"
-                "This partition type is not supported!",
+      PopupError("failed to install FAT bootcode on the system partition.",
                 "ENTER = Reboot computer");
 
       while(TRUE)
@@ -3565,12 +3479,12 @@ BootLoaderPage(PINPUT_RECORD Ir)
 
          if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)       /* ENTER */
            {
-             return(QUIT_PAGE);
+             return QUIT_PAGE;
            }
        }
     }
 
-  return(SUCCESS_PAGE);
+  return BOOT_LOADER_HARDDISK_PAGE;
 }
 
 
@@ -3600,6 +3514,34 @@ QuitPage(PINPUT_RECORD Ir)
       FileSystemList = NULL;
     }
 
+  /* Destroy computer settings list */
+  if (ComputerList != NULL)
+    {
+      DestroyGenericList(ComputerList, TRUE);
+      ComputerList = NULL;
+    }
+
+  /* Destroy display settings list */
+  if (DisplayList != NULL)
+    {
+      DestroyGenericList(DisplayList, TRUE);
+      DisplayList = NULL;
+    }
+
+  /* Destroy keyboard settings list */
+  if (KeyboardList != NULL)
+    {
+      DestroyGenericList(KeyboardList, TRUE);
+      KeyboardList = NULL;
+    }
+
+  /* Destroy keyboard layout list */
+  if (LayoutList != NULL)
+    {
+      DestroyGenericList(LayoutList, TRUE);
+      LayoutList = NULL;
+    }
+
   SetStatusText("   ENTER = Reboot computer");
 
   while(TRUE)
@@ -3608,7 +3550,7 @@ QuitPage(PINPUT_RECORD Ir)
 
       if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
        {
-         return(FLUSH_PAGE);
+         return FLUSH_PAGE;
        }
     }
 }
@@ -3628,7 +3570,7 @@ SuccessPage(PINPUT_RECORD Ir)
 
   if (IsUnattendedSetup)
     {
-      return(FLUSH_PAGE);
+      return FLUSH_PAGE;
     }
 
   while(TRUE)
@@ -3637,7 +3579,7 @@ SuccessPage(PINPUT_RECORD Ir)
 
       if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
        {
-         return(FLUSH_PAGE);
+         return FLUSH_PAGE;
        }
     }
 }
@@ -3653,7 +3595,43 @@ FlushPage(PINPUT_RECORD Ir)
 
   SetStatusText("   Flushing cache");
 
-  return(REBOOT_PAGE);
+  return REBOOT_PAGE;
+}
+
+
+static VOID
+SignalInitEvent()
+{
+  NTSTATUS Status;
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  UNICODE_STRING UnicodeString = RTL_CONSTANT_STRING(L"\\ReactOSInitDone");
+  HANDLE ReactOSInitEvent;
+
+  InitializeObjectAttributes(&ObjectAttributes,
+    &UnicodeString,
+    0,
+    0,
+    NULL);
+  Status = NtOpenEvent(&ReactOSInitEvent,
+    EVENT_ALL_ACCESS,
+    &ObjectAttributes);
+  if (NT_SUCCESS(Status))
+    {
+      LARGE_INTEGER Timeout;
+      /* This will cause the boot screen image to go away (if displayed) */
+      NtPulseEvent(ReactOSInitEvent, NULL);
+
+      /* Wait for the display mode to be changed (if in graphics mode) */
+      Timeout.QuadPart = -50000000LL;  /* 5 second timeout */
+      NtWaitForSingleObject(ReactOSInitEvent, FALSE, &Timeout);
+
+      NtClose(ReactOSInitEvent);
+    }
+  else
+    {
+      /* We don't really care if this fails */
+      DPRINT1("USETUP: Failed to open ReactOS init notification event\n");
+    }
 }
 
 
@@ -3668,6 +3646,8 @@ NtProcessStartup(PPEB Peb)
 
   ProcessHeap = Peb->ProcessHeap;
 
+  SignalInitEvent();
+
   Status = AllocConsole();
   if (!NT_SUCCESS(Status))
     {
@@ -3702,7 +3682,17 @@ NtProcessStartup(PPEB Peb)
        {
          /* Start page */
          case START_PAGE:
-           Page = StartPage(&Ir);
+           Page = SetupStartPage(&Ir);
+           break;
+
+         /* License page */
+         case LICENSE_PAGE:
+           Page = LicensePage(&Ir);
+           break;
+        
+         /* Warning page */
+         case WARNING_PAGE:
+           Page = WarningPage(&Ir);
            break;
 
          /* Intro page */
@@ -3715,6 +3705,12 @@ NtProcessStartup(PPEB Peb)
            Page = InstallIntroPage(&Ir);
            break;
 
+#if 0
+         case SCSI_CONTROLLER_PAGE:
+           Page = ScsiControllerPage(&Ir);
+           break;
+#endif
+
 #if 0
          case OEM_DRIVER_PAGE:
            Page = OemDriverPage(&Ir);
@@ -3741,10 +3737,6 @@ NtProcessStartup(PPEB Peb)
            Page = LayoutSettingsPage(&Ir);
            break;
 
-         case POINTER_SETTINGS_PAGE:
-           Page = PointerSettingsPage(&Ir);
-           break;
-
          case SELECT_PARTITION_PAGE:
            Page = SelectPartitionPage(&Ir);
            break;
@@ -3789,19 +3781,20 @@ NtProcessStartup(PPEB Peb)
            Page = BootLoaderPage(&Ir);
            break;
 
+         case BOOT_LOADER_FLOPPY_PAGE:
+           Page = BootLoaderFloppyPage(&Ir);
+           break;
 
-         /* Repair pages */
-         case REPAIR_INTRO_PAGE:
-           Page = RepairIntroPage(&Ir);
+         case BOOT_LOADER_HARDDISK_PAGE:
+           Page = BootLoaderHarddiskPage(&Ir);
            break;
 
 
-         /* Emergency pages */
-         case EMERGENCY_INTRO_PAGE:
-           Page = EmergencyIntroPage(&Ir);
+         /* Repair pages */
+         case REPAIR_INTRO_PAGE:
+           Page = RepairIntroPage(&Ir);
            break;
 
-
          case SUCCESS_PAGE:
            Page = SuccessPage(&Ir);
            break;
@@ -3822,6 +3815,7 @@ NtProcessStartup(PPEB Peb)
   /* Reboot */
   FreeConsole();
   NtShutdownSystem(ShutdownReboot);
+  NtTerminateProcess(NtCurrentProcess(), 0);
 }
 
 /* EOF */