[USETUP]
[reactos.git] / reactos / base / setup / usetup / interface / usetup.c
index 4e55143..7bc2564 100644 (file)
  *                  HervĂ© Poussineau (hpoussin@reactos.org)
  */
 
-#include "usetup.h"
+#include <usetup.h>
+
+#include "bootsup.h"
+#include "chkdsk.h"
+#include "format.h"
+#include "drivesup.h"
+#include "settings.h"
 
 #define NDEBUG
 #include <debug.h>
@@ -64,6 +70,8 @@ static UNICODE_STRING DestinationPath;
 static UNICODE_STRING DestinationArcPath;
 static UNICODE_STRING DestinationRootPath;
 
+static WCHAR DestinationDriveLetter;
+
 /* Path to the active partition (boot manager) */
 static UNICODE_STRING SystemRootPath;
 
@@ -506,10 +514,10 @@ CheckUnattendedSetup(VOID)
 
     UnattendDestinationPartitionNumber = IntValue;
 
-    /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
-    if (!SetupFindFirstLineW(UnattendInf, L"Unattend", L"DestinationPartitionNumber", &Context))
+    /* Search for 'InstallationDirectory' in the 'Unattend' section */
+    if (!SetupFindFirstLineW(UnattendInf, L"Unattend", L"InstallationDirectory", &Context))
     {
-        DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
+        DPRINT("SetupFindFirstLine() failed for key 'InstallationDirectory'\n");
         SetupCloseInfFile(UnattendInf);
         return;
     }
@@ -608,6 +616,9 @@ UpdateKBLayout(VOID)
 static PAGE_NUMBER
 LanguagePage(PINPUT_RECORD Ir)
 {
+    PWCHAR NewLanguageId;
+    BOOL RefreshPage = FALSE;
+
     /* Initialize the computer settings list */
     if (LanguageList == NULL)
     {
@@ -620,6 +631,10 @@ LanguagePage(PINPUT_RECORD Ir)
         }
     }
 
+    /* Load the font */
+    SelectedLanguageId = DefaultLanguage;
+    SetConsoleCodePage();
+
     DrawGenericList(LanguageList,
                     2,
                     18,
@@ -637,42 +652,34 @@ LanguagePage(PINPUT_RECORD Ir)
         if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
             (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN))  /* DOWN */
         {
-#if 0
-            SelectedLanguageId = (PWCHAR)GetListEntryUserData(GetCurrentListEntry(LanguageList));
-
-            /* Redraw language selection page in native language */
-            MUIDisplayPage(LANGUAGE_PAGE);
-#endif
-
             ScrollDownGenericList (LanguageList);
+            RefreshPage = TRUE;
         }
         else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
                  (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP))  /* UP */
         {
-#if 0
-            SelectedLanguageId = (PWCHAR)GetListEntryUserData(GetCurrentListEntry(LanguageList));
-
-            /* Redraw language selection page in native language */
-            MUIDisplayPage(LANGUAGE_PAGE);
-#endif
-
             ScrollUpGenericList(LanguageList);
+            RefreshPage = TRUE;
         }
         if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
             (Ir->Event.KeyEvent.wVirtualKeyCode == VK_NEXT))  /* PAGE DOWN */
         {
             ScrollPageDownGenericList(LanguageList);
+            RefreshPage = TRUE;
         }
         else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
                  (Ir->Event.KeyEvent.wVirtualKeyCode == VK_PRIOR))  /* PAGE UP */
         {
             ScrollPageUpGenericList(LanguageList);
+            RefreshPage = TRUE;
         }
         else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
                  (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3))  /* F3 */
         {
             if (ConfirmQuit(Ir) == TRUE)
                 return QUIT_PAGE;
+            else
+                RedrawGenericList(LanguageList);
         }
         else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D)  /* ENTER */
         {
@@ -685,7 +692,7 @@ LanguagePage(PINPUT_RECORD Ir)
                 UpdateKBLayout();
             }
 
-            // Load the font
+            /* Load the font */
             SetConsoleCodePage();
 
             return INTRO_PAGE;
@@ -694,6 +701,28 @@ LanguagePage(PINPUT_RECORD Ir)
         {
             /* a-z */
             GenericListKeyPress (LanguageList, Ir->Event.KeyEvent.uChar.AsciiChar);
+            RefreshPage = TRUE;
+        }
+
+        if (RefreshPage)
+        {
+            NewLanguageId = (PWCHAR)GetListEntryUserData(GetCurrentListEntry(LanguageList));
+
+            if (SelectedLanguageId != NewLanguageId)
+            {
+                /* Clear the language page */
+                MUIClearPage(LANGUAGE_PAGE);
+
+                SelectedLanguageId = NewLanguageId;
+
+                /* Load the font */
+                SetConsoleCodePage();
+
+                /* Redraw language selection page in native language */
+                MUIDisplayPage(LANGUAGE_PAGE);
+            }
+
+            RefreshPage = FALSE;
         }
     }
 
@@ -709,19 +738,19 @@ LanguagePage(PINPUT_RECORD Ir)
 static PAGE_NUMBER
 SetupStartPage(PINPUT_RECORD Ir)
 {
-    SYSTEM_DEVICE_INFORMATION Sdi;
+    //SYSTEM_DEVICE_INFORMATION Sdi;
     NTSTATUS Status;
     WCHAR FileNameBuffer[MAX_PATH];
     INFCONTEXT Context;
     PWCHAR Value;
     UINT ErrorLine;
-    ULONG ReturnSize;
+    //ULONG ReturnSize;
     PGENERIC_LIST_ENTRY ListEntry;
     INT IntValue;
 
     CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT));
 
-
+#if 0
     /* Check whether a harddisk is available */
     Status = NtQuerySystemInformation(SystemDeviceInformation,
                                       &Sdi,
@@ -740,6 +769,7 @@ SetupStartPage(PINPUT_RECORD Ir)
         MUIDisplayError(ERROR_NO_HDD, Ir, POPUP_WAIT_ENTER);
         return QUIT_PAGE;
     }
+#endif
 
     /* Get the source path and source root path */
     Status = GetSourcePaths(&SourcePath,
@@ -1328,7 +1358,7 @@ KeyboardSettingsPage(PINPUT_RECORD Ir)
         }
     }
 
-    return DISPLAY_SETTINGS_PAGE;
+    return KEYBOARD_SETTINGS_PAGE;
 }
 
 
@@ -1394,10 +1424,11 @@ LayoutSettingsPage(PINPUT_RECORD Ir)
         }
     }
 
-    return DISPLAY_SETTINGS_PAGE;
+    return LAYOUT_SETTINGS_PAGE;
 }
 
 
+#if 0
 static BOOL
 IsDiskSizeValid(PPARTENTRY PartEntry)
 {
@@ -1426,17 +1457,20 @@ IsDiskSizeValid(PPARTENTRY PartEntry)
         return TRUE;
     }
 }
+#endif
 
 
 static PAGE_NUMBER
 SelectPartitionPage(PINPUT_RECORD Ir)
 {
+    ULONG Error;
+
     MUIDisplayPage(SELECT_PARTITION_PAGE);
 
     if (PartitionList == NULL)
     {
         PartitionList = CreatePartitionList(2,
-                                            19,
+                                            21,
                                             xScreen - 3,
                                             yScreen - 3);
         if (PartitionList == NULL)
@@ -1444,10 +1478,13 @@ SelectPartitionPage(PINPUT_RECORD Ir)
             /* FIXME: show an error dialog */
             return QUIT_PAGE;
         }
+        else if (IsListEmpty (&PartitionList->DiskListHead))
+        {
+            MUIDisplayError(ERROR_NO_HDD, Ir, POPUP_WAIT_ENTER);
+            return QUIT_PAGE;
+        }
     }
 
-    CheckActiveBootPartition(PartitionList);
-
     DrawPartitionList(PartitionList);
 
     /* Warn about partitions created by Linux Fdisk */
@@ -1479,28 +1516,32 @@ SelectPartitionPage(PINPUT_RECORD Ir)
         {
             if (AutoPartition)
             {
-                PPARTENTRY PartEntry = PartitionList->CurrentPartition;
-                ULONG MaxSize = (PartEntry->UnpartitionedLength + (1 << 19)) >> 20;  /* in MBytes (rounded) */
-                if(!IsDiskSizeValid(PartitionList->CurrentPartition))
+#if 0
+                if (!IsDiskSizeValid(PartitionList->CurrentPartition))
                 {
                     MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE, Ir, POPUP_WAIT_ANY_KEY);
                     return SELECT_PARTITION_PAGE; /* let the user select another partition */
                 }
+#endif
+                CreatePrimaryPartition(PartitionList,
+                                       PartitionList->CurrentPartition->SectorCount.QuadPart,
+                                       TRUE);
 
-                CreateNewPartition(PartitionList,
-                                   MaxSize,
-                                   TRUE);
+                DestinationDriveLetter = (WCHAR)PartitionList->CurrentPartition->DriveLetter;
 
                 return SELECT_FILE_SYSTEM_PAGE;
             }
         }
         else
         {
-            if(!IsDiskSizeValid(PartitionList->CurrentPartition))
+#if 0
+            if (!IsDiskSizeValid(PartitionList->CurrentPartition))
             {
                 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE, Ir, POPUP_WAIT_ANY_KEY);
                 return SELECT_PARTITION_PAGE; /* let the user select another partition */
             }
+#endif
+            DestinationDriveLetter = (WCHAR)PartitionList->CurrentPartition->DriveLetter;
 
             return SELECT_FILE_SYSTEM_PAGE;
         }
@@ -1510,10 +1551,14 @@ SelectPartitionPage(PINPUT_RECORD Ir)
     {
         /* Update status text */
         if (PartitionList->CurrentPartition == NULL ||
-            PartitionList->CurrentPartition->Unpartitioned == TRUE)
+            PartitionList->CurrentPartition->IsPartitioned == FALSE)
         {
             CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATEPARTITION));
         }
+        else if (IsContainerPartition(PartitionList->CurrentPartition->PartitionType))
+        {
+            CONSOLE_SetStatusText(MUIGetString(STRING_DELETEPARTITION));
+        }
         else
         {
             CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLDELETEPARTITION));
@@ -1536,43 +1581,64 @@ SelectPartitionPage(PINPUT_RECORD Ir)
         else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
                  (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN))  /* DOWN */
         {
-            ScrollDownPartitionList(PartitionList);
+            if (ScrollDownPartitionList(PartitionList))
+                DrawPartitionList(PartitionList);
         }
         else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
                  (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP))  /* UP */
         {
-            ScrollUpPartitionList(PartitionList);
+            if (ScrollUpPartitionList(PartitionList))
+                DrawPartitionList(PartitionList);
         }
         else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN)  /* ENTER */
         {
-            if(!IsDiskSizeValid(PartitionList->CurrentPartition))
+#if 0
+            if (!IsDiskSizeValid(PartitionList->CurrentPartition))
             {
                 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE, Ir, POPUP_WAIT_ANY_KEY);
                 return SELECT_PARTITION_PAGE; /* let the user select another partition */
             }
+#endif
+            if (IsContainerPartition(PartitionList->CurrentPartition->PartitionType))
+                continue; //return SELECT_PARTITION_PAGE;
+
             if (PartitionList->CurrentPartition == NULL ||
-                PartitionList->CurrentPartition->Unpartitioned == TRUE)
+                PartitionList->CurrentPartition->IsPartitioned == FALSE)
             {
-                CreateNewPartition(PartitionList,
-                                   0ULL,
-                                   TRUE);
+                CreatePrimaryPartition(PartitionList,
+                                       0ULL,
+                                       TRUE);
             }
 
+            DestinationDriveLetter = (WCHAR)PartitionList->CurrentPartition->DriveLetter;
+
             return SELECT_FILE_SYSTEM_PAGE;
         }
-        else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'C')  /* C */
+        else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'P')  /* P */
         {
-            if (PartitionList->CurrentPartition->Unpartitioned == FALSE)
+            Error = PrimaryPartitionCreationChecks(PartitionList);
+            if (Error != NOT_AN_ERROR)
             {
-                MUIDisplayError(ERROR_NEW_PARTITION, Ir, POPUP_WAIT_ANY_KEY);
+                MUIDisplayError(Error, Ir, POPUP_WAIT_ANY_KEY);
                 return SELECT_PARTITION_PAGE;
             }
 
-            return CREATE_PARTITION_PAGE;
+            return CREATE_PRIMARY_PARTITION_PAGE;
+        }
+        else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'E')  /* E */
+        {
+            Error = ExtendedPartitionCreationChecks(PartitionList);
+            if (Error != NOT_AN_ERROR)
+            {
+                MUIDisplayError(Error, Ir, POPUP_WAIT_ANY_KEY);
+                return SELECT_PARTITION_PAGE;
+            }
+
+            return CREATE_EXTENDED_PARTITION_PAGE;
         }
         else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'D')  /* D */
         {
-            if (PartitionList->CurrentPartition->Unpartitioned == TRUE)
+            if (PartitionList->CurrentPartition->IsPartitioned == FALSE)
             {
                 MUIDisplayError(ERROR_DELETE_SPACE, Ir, POPUP_WAIT_ANY_KEY);
                 return SELECT_PARTITION_PAGE;
@@ -1730,7 +1796,7 @@ ShowPartitionSizeInputBox(SHORT Left,
 
 
 static PAGE_NUMBER
-CreatePartitionPage(PINPUT_RECORD Ir)
+CreatePrimaryPartitionPage(PINPUT_RECORD Ir)
 {
     PDISKENTRY DiskEntry;
     PPARTENTRY PartEntry;
@@ -1740,6 +1806,7 @@ CreatePartitionPage(PINPUT_RECORD Ir)
     ULONG MaxSize;
     ULONGLONG PartSize;
     ULONGLONG DiskSize;
+    ULONGLONG SectorCount;
     PCHAR Unit;
 
     if (PartitionList == NULL ||
@@ -1757,17 +1824,164 @@ CreatePartitionPage(PINPUT_RECORD Ir)
 
     CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSENEWPARTITION));
 
+    DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
 #if 0
-    if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */
+    if (DiskSize >= 10737418240) /* 10 GB */
     {
-        DiskSize = (DiskEntry->DiskSize + (1 << 29)) >> 30;
+        DiskSize = DiskSize / 1073741824;
         Unit = MUIGetString(STRING_GB);
     }
     else
 #endif
     {
-        DiskSize = (DiskEntry->DiskSize + (1 << 19)) >> 20;
+        DiskSize = DiskSize / 1048576;
+        if (DiskSize == 0)
+            DiskSize = 1;
 
+        Unit = MUIGetString(STRING_MB);
+    }
+
+    if (DiskEntry->DriverName.Length > 0)
+    {
+        CONSOLE_PrintTextXY(6, 10,
+                            MUIGetString(STRING_HDINFOPARTCREATE),
+                            DiskSize,
+                            Unit,
+                            DiskEntry->DiskNumber,
+                            DiskEntry->Port,
+                            DiskEntry->Bus,
+                            DiskEntry->Id,
+                            &DiskEntry->DriverName);
+    }
+    else
+    {
+        CONSOLE_PrintTextXY(6, 10,
+                            MUIGetString(STRING_HDDINFOUNK1),
+                            DiskSize,
+                            Unit,
+                            DiskEntry->DiskNumber,
+                            DiskEntry->Port,
+                            DiskEntry->Bus,
+                            DiskEntry->Id);
+    }
+
+    CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE));
+
+#if 0
+    CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
+                        PartitionList->CurrentPartition->SectorCount * DiskEntry->BytesPerSector / 1048576);
+#endif
+
+    CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION));
+
+    PartEntry = PartitionList->CurrentPartition;
+    while (TRUE)
+    {
+        MaxSize = (PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) / 1048576;  /* in MBytes (rounded) */
+
+        if (MaxSize > PARTITION_MAXSIZE)
+            MaxSize = PARTITION_MAXSIZE;
+
+        ShowPartitionSizeInputBox(12, 14, xScreen - 12, 17, /* left, top, right, bottom */
+                                  MaxSize, InputBuffer, &Quit, &Cancel);
+
+        if (Quit == TRUE)
+        {
+            if (ConfirmQuit (Ir) == TRUE)
+            {
+                return QUIT_PAGE;
+            }
+        }
+        else if (Cancel == TRUE)
+        {
+            return SELECT_PARTITION_PAGE;
+        }
+        else
+        {
+            PartSize = atoi(InputBuffer);
+
+            if (PartSize < 1)
+            {
+                /* Too small */
+                continue;
+            }
+
+            if (PartSize > MaxSize)
+            {
+                /* Too large */
+                continue;
+            }
+
+            /* Convert to bytes */
+            if (PartSize == MaxSize)
+            {
+                /* Use all of the unpartitioned disk space */
+                SectorCount = PartEntry->SectorCount.QuadPart;
+            }
+            else
+            {
+                /* Calculate the sector count from the size in MB */
+                SectorCount = PartSize * 1048576 / DiskEntry->BytesPerSector;
+
+                /* But never get larger than the unpartitioned disk space */
+                if (SectorCount > PartEntry->SectorCount.QuadPart)
+                    SectorCount = PartEntry->SectorCount.QuadPart;
+            }
+
+            DPRINT ("Partition size: %I64u bytes\n", PartSize);
+
+            CreatePrimaryPartition(PartitionList,
+                                   SectorCount,
+                                   FALSE);
+
+            return SELECT_PARTITION_PAGE;
+        }
+    }
+
+    return CREATE_PRIMARY_PARTITION_PAGE;
+}
+
+
+static PAGE_NUMBER
+CreateExtendedPartitionPage(PINPUT_RECORD Ir)
+{
+    PDISKENTRY DiskEntry;
+    PPARTENTRY PartEntry;
+    BOOLEAN Quit;
+    BOOLEAN Cancel;
+    CHAR InputBuffer[50];
+    ULONG MaxSize;
+    ULONGLONG PartSize;
+    ULONGLONG DiskSize;
+    ULONGLONG SectorCount;
+    PCHAR Unit;
+
+    if (PartitionList == NULL ||
+        PartitionList->CurrentDisk == NULL ||
+        PartitionList->CurrentPartition == NULL)
+    {
+        /* FIXME: show an error dialog */
+        return QUIT_PAGE;
+    }
+
+    DiskEntry = PartitionList->CurrentDisk;
+    PartEntry = PartitionList->CurrentPartition;
+
+    CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT));
+
+    CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSE_NEW_EXTENDED_PARTITION));
+
+    DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
+#if 0
+    if (DiskSize >= 10737418240) /* 10 GB */
+    {
+        DiskSize = DiskSize / 1073741824;
+        Unit = MUIGetString(STRING_GB);
+    }
+    else
+#endif
+    {
+        DiskSize = DiskSize / 1048576;
         if (DiskSize == 0)
             DiskSize = 1;
 
@@ -1802,7 +2016,7 @@ CreatePartitionPage(PINPUT_RECORD Ir)
 
 #if 0
     CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
-                        PartitionList->CurrentPartition->UnpartitionedLength / (1024*1024));
+                        PartitionList->CurrentPartition->SectorCount * DiskEntry->BytesPerSector / 1048576);
 #endif
 
     CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION));
@@ -1810,9 +2024,10 @@ CreatePartitionPage(PINPUT_RECORD Ir)
     PartEntry = PartitionList->CurrentPartition;
     while (TRUE)
     {
-        MaxSize = (PartEntry->UnpartitionedLength + (1 << 19)) >> 20;  /* in MBytes (rounded) */
+        MaxSize = (PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) / 1048576;  /* in MBytes (rounded) */
 
-        if (MaxSize > PARTITION_MAXSIZE) MaxSize = PARTITION_MAXSIZE;
+        if (MaxSize > PARTITION_MAXSIZE)
+            MaxSize = PARTITION_MAXSIZE;
 
         ShowPartitionSizeInputBox(12, 14, xScreen - 12, 17, /* left, top, right, bottom */
                                   MaxSize, InputBuffer, &Quit, &Cancel);
@@ -1848,30 +2063,28 @@ CreatePartitionPage(PINPUT_RECORD Ir)
             if (PartSize == MaxSize)
             {
                 /* Use all of the unpartitioned disk space */
-                PartSize = PartEntry->UnpartitionedLength;
+                SectorCount = PartEntry->SectorCount.QuadPart;
             }
             else
             {
-                /* Round-up by cylinder size */
-                PartSize = (PartSize * 1024 * 1024 + DiskEntry->CylinderSize - 1) /
-                           DiskEntry->CylinderSize * DiskEntry->CylinderSize;
+                /* Calculate the sector count from the size in MB */
+                SectorCount = PartSize * 1048576 / DiskEntry->BytesPerSector;
 
                 /* But never get larger than the unpartitioned disk space */
-                if (PartSize > PartEntry->UnpartitionedLength)
-                    PartSize = PartEntry->UnpartitionedLength;
+                if (SectorCount > PartEntry->SectorCount.QuadPart)
+                    SectorCount = PartEntry->SectorCount.QuadPart;
             }
 
             DPRINT ("Partition size: %I64u bytes\n", PartSize);
 
-            CreateNewPartition(PartitionList,
-                               PartSize,
-                               FALSE);
+            CreateExtendedPartition(PartitionList,
+                                    SectorCount);
 
             return SELECT_PARTITION_PAGE;
         }
     }
 
-    return CREATE_PARTITION_PAGE;
+    return CREATE_EXTENDED_PARTITION_PAGE;
 }
 
 
@@ -1884,7 +2097,6 @@ DeletePartitionPage(PINPUT_RECORD Ir)
     ULONGLONG PartSize;
     PCHAR Unit;
     PCHAR PartType;
-    UCHAR PartNumber;
 
     if (PartitionList == NULL ||
         PartitionList->CurrentDisk == NULL ||
@@ -1896,7 +2108,6 @@ DeletePartitionPage(PINPUT_RECORD Ir)
 
     DiskEntry = PartitionList->CurrentDisk;
     PartEntry = PartitionList->CurrentPartition;
-    PartNumber = PartitionList->CurrentPartitionNumber;
 
     MUIDisplayPage(DELETE_PARTITION_PAGE);
 
@@ -1906,46 +2117,51 @@ DeletePartitionPage(PINPUT_RECORD Ir)
     {
         PartType = MUIGetString(STRING_UNFORMATTED);
     }
-    else if (PartEntry->Unpartitioned == FALSE)
+    else if (PartEntry->IsPartitioned == TRUE)
     {
-        if ((PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT_12) ||
-            (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT_16) ||
-            (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_HUGE) ||
-            (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_XINT13))
+        if ((PartEntry->PartitionType == PARTITION_FAT_12) ||
+            (PartEntry->PartitionType == PARTITION_FAT_16) ||
+            (PartEntry->PartitionType == PARTITION_HUGE) ||
+            (PartEntry->PartitionType == PARTITION_XINT13))
         {
             PartType = "FAT";
         }
-        else if ((PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32) ||
-                 (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32_XINT13))
+        else if ((PartEntry->PartitionType == PARTITION_FAT32) ||
+                 (PartEntry->PartitionType == PARTITION_FAT32_XINT13))
         {
             PartType = "FAT32";
         }
-        else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_EXT2)
+        else if (PartEntry->PartitionType == PARTITION_EXT2)
         {
             PartType = "EXT2";
         }
-        else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_IFS)
+        else if (PartEntry->PartitionType == PARTITION_IFS)
         {
             PartType = "NTFS"; /* FIXME: Not quite correct! */
         }
+        else if (IsContainerPartition(PartEntry->PartitionType))
+        {
+            PartType = MUIGetString(STRING_EXTENDED_PARTITION);
+        }
     }
 
+    PartSize = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
 #if 0
-    if (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart >= 0x280000000LL) /* 10 GB */
+    if (PartSize >= 10737418240) /* 10 GB */
     {
-        PartSize = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 29)) >> 30;
+        PartSize = PartSize / 1073741824;
         Unit = MUIGetString(STRING_GB);
     }
     else
 #endif
-    if (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart >= 0xA00000LL) /* 10 MB */
+    if (PartSize >= 10485760) /* 10 MB */
     {
-        PartSize = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 19)) >> 20;
+        PartSize = PartSize / 1048576;
         Unit = MUIGetString(STRING_MB);
     }
     else
     {
-        PartSize = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 9)) >> 10;
+        PartSize = PartSize / 1024;
         Unit = MUIGetString(STRING_KB);
     }
 
@@ -1953,9 +2169,9 @@ DeletePartitionPage(PINPUT_RECORD Ir)
     {
         CONSOLE_PrintTextXY(6, 10,
                             MUIGetString(STRING_HDDINFOUNK2),
-                            (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber],
-                            (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':',
-                            PartEntry->PartInfo[PartNumber].PartitionType,
+                            (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
+                            (PartEntry->DriveLetter == 0) ? '-' : ':',
+                            PartEntry->PartitionType,
                             PartSize,
                             Unit);
     }
@@ -1963,24 +2179,24 @@ DeletePartitionPage(PINPUT_RECORD Ir)
     {
         CONSOLE_PrintTextXY(6, 10,
                             "   %c%c  %s    %I64u %s",
-                            (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber],
-                            (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':',
+                            (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
+                            (PartEntry->DriveLetter == 0) ? '-' : ':',
                             PartType,
                             PartSize,
                             Unit);
     }
 
+    DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
 #if 0
-    if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */
+    if (DiskSize >= 10737418240) /* 10 GB */
     {
-        DiskSize = (DiskEntry->DiskSize + (1 << 29)) >> 30;
+        DiskSize = DiskSize / 1073741824;
         Unit = MUIGetString(STRING_GB);
     }
     else
 #endif
     {
-        DiskSize = (DiskEntry->DiskSize + (1 << 19)) >> 20;
-
+        DiskSize = DiskSize / 1048576;
         if (DiskSize == 0)
             DiskSize = 1;
 
@@ -2046,7 +2262,6 @@ SelectFileSystemPage(PINPUT_RECORD Ir)
 {
     PDISKENTRY DiskEntry;
     PPARTENTRY PartEntry;
-    UCHAR      PartNumber;
     ULONGLONG DiskSize;
     ULONGLONG PartSize;
     PCHAR DiskUnit;
@@ -2063,54 +2278,55 @@ SelectFileSystemPage(PINPUT_RECORD Ir)
 
     DiskEntry = PartitionList->CurrentDisk;
     PartEntry = PartitionList->CurrentPartition;
-    PartNumber = PartitionList->CurrentPartitionNumber;
 
     /* adjust disk size */
-    if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */
+    DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
+    if (DiskSize >= 10737418240) /* 10 GB */
     {
-        DiskSize = (DiskEntry->DiskSize + (1 << 29)) >> 30;
+        DiskSize = DiskSize / 1073741824;
         DiskUnit = MUIGetString(STRING_GB);
     }
     else
     {
-        DiskSize = (DiskEntry->DiskSize + (1 << 19)) >> 20;
+        DiskSize = DiskSize / 1048576;
         DiskUnit = MUIGetString(STRING_MB);
     }
 
     /* adjust partition size */
-    if (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart >= 0x280000000LL) /* 10 GB */
+    PartSize = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
+    if (PartSize >= 10737418240) /* 10 GB */
     {
-        PartSize = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 29)) >> 30;
+        PartSize = PartSize / 1073741824;
         PartUnit = MUIGetString(STRING_GB);
     }
     else
     {
-        PartSize = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 19)) >> 20;
+        PartSize = PartSize / 1048576;
         PartUnit = MUIGetString(STRING_MB);
     }
 
     /* adjust partition type */
-    if ((PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT_12) ||
-        (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT_16) ||
-        (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_HUGE) ||
-        (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_XINT13))
+    if ((PartEntry->PartitionType == PARTITION_FAT_12) ||
+        (PartEntry->PartitionType == PARTITION_FAT_16) ||
+        (PartEntry->PartitionType == PARTITION_HUGE) ||
+        (PartEntry->PartitionType == PARTITION_XINT13))
     {
         PartType = "FAT";
     }
-    else if ((PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32) ||
-             (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32_XINT13))
+    else if ((PartEntry->PartitionType == PARTITION_FAT32) ||
+             (PartEntry->PartitionType == PARTITION_FAT32_XINT13))
     {
         PartType = "FAT32";
     }
-    else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_EXT2)
+    else if (PartEntry->PartitionType == PARTITION_EXT2)
     {
         PartType = "EXT2";
     }
-    else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_IFS)
+    else if (PartEntry->PartitionType == PARTITION_IFS)
     {
         PartType = "NTFS"; /* FIXME: Not quite correct! */
     }
-    else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_ENTRY_UNUSED)
+    else if (PartEntry->PartitionType == PARTITION_ENTRY_UNUSED)
     {
         PartType = MUIGetString(STRING_FORMATUNUSED);
     }
@@ -2125,7 +2341,7 @@ SelectFileSystemPage(PINPUT_RECORD Ir)
 
 #if 0
         CONSOLE_PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
-                            PartEntry->PartInfo[PartNumber].PartitionNumber,
+                            PartEntry->PartitionNumber,
                             PartSize,
                             PartUnit,
                             PartType);
@@ -2158,9 +2374,9 @@ SelectFileSystemPage(PINPUT_RECORD Ir)
         {
             CONSOLE_PrintTextXY(8, 10,
                                 MUIGetString(STRING_HDDINFOUNK4),
-                                (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber],
-                                (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':',
-                                PartEntry->PartInfo[PartNumber].PartitionType,
+                                (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
+                                (PartEntry->DriveLetter == 0) ? '-' : ':',
+                                PartEntry->PartitionType,
                                 PartSize,
                                 PartUnit);
         }
@@ -2168,8 +2384,8 @@ SelectFileSystemPage(PINPUT_RECORD Ir)
         {
             CONSOLE_PrintTextXY(8, 10,
                                 "%c%c  %s    %I64u %s",
-                                (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber],
-                                (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':',
+                                (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
+                                (PartEntry->DriveLetter == 0) ? '-' : ':',
                                 PartType,
                                 PartSize,
                                 PartUnit);
@@ -2198,6 +2414,7 @@ SelectFileSystemPage(PINPUT_RECORD Ir)
 
         /* FIXME: Add file systems to list */
     }
+
     DrawFileSystemList(FileSystemList);
 
     if (RepairUpdateFlag)
@@ -2268,7 +2485,6 @@ FormatPartitionPage(PINPUT_RECORD Ir)
     WCHAR PathBuffer[MAX_PATH];
     PDISKENTRY DiskEntry;
     PPARTENTRY PartEntry;
-    UCHAR PartNum;
     NTSTATUS Status;
 
 #ifndef NDEBUG
@@ -2289,7 +2505,6 @@ FormatPartitionPage(PINPUT_RECORD Ir)
 
     DiskEntry = PartitionList->CurrentDisk;
     PartEntry = PartitionList->CurrentPartition;
-    PartNum = PartitionList->CurrentPartitionNumber;
 
     while (TRUE)
     {
@@ -2314,54 +2529,59 @@ FormatPartitionPage(PINPUT_RECORD Ir)
 
             if (wcscmp(FileSystemList->Selected->FileSystem, L"FAT") == 0)
             {
-                if (PartEntry->PartInfo[PartNum].PartitionLength.QuadPart < (4200LL * 1024LL))
+                if (PartEntry->SectorCount.QuadPart < 8192)
                 {
                     /* FAT12 CHS partition (disk is smaller than 4.1MB) */
-                    PartEntry->PartInfo[PartNum].PartitionType = PARTITION_FAT_12;
+                    PartEntry->PartitionType = PARTITION_FAT_12;
                 }
-                else if (PartEntry->PartInfo[PartNum].StartingOffset.QuadPart < (1024LL * 255LL * 63LL * 512LL))
+                else if (PartEntry->StartSector.QuadPart < 1450560)
                 {
                     /* Partition starts below the 8.4GB boundary ==> CHS partition */
 
-                    if (PartEntry->PartInfo[PartNum].PartitionLength.QuadPart < (32LL * 1024LL * 1024LL))
+                    if (PartEntry->SectorCount.QuadPart < 65536)
                     {
                         /* FAT16 CHS partition (partiton size < 32MB) */
-                        PartEntry->PartInfo[PartNum].PartitionType = PARTITION_FAT_16;
+                        PartEntry->PartitionType = PARTITION_FAT_16;
                     }
-                    else if (PartEntry->PartInfo[PartNum].PartitionLength.QuadPart < (512LL * 1024LL * 1024LL))
+                    else if (PartEntry->SectorCount.QuadPart < 1048576)
                     {
                         /* FAT16 CHS partition (partition size < 512MB) */
-                        PartEntry->PartInfo[PartNum].PartitionType = PARTITION_HUGE;
+                        PartEntry->PartitionType = PARTITION_HUGE;
                     }
                     else
                     {
                         /* FAT32 CHS partition (partition size >= 512MB) */
-                        PartEntry->PartInfo[PartNum].PartitionType = PARTITION_FAT32;
+                        PartEntry->PartitionType = PARTITION_FAT32;
                     }
                 }
                 else
                 {
                     /* Partition starts above the 8.4GB boundary ==> LBA partition */
 
-                    if (PartEntry->PartInfo[PartNum].PartitionLength.QuadPart < (512LL * 1024LL * 1024LL))
+                    if (PartEntry->SectorCount.QuadPart < 1048576)
                     {
                         /* FAT16 LBA partition (partition size < 512MB) */
-                        PartEntry->PartInfo[PartNum].PartitionType = PARTITION_XINT13;
+                        PartEntry->PartitionType = PARTITION_XINT13;
                     }
                     else
                     {
                         /* FAT32 LBA partition (partition size >= 512MB) */
-                        PartEntry->PartInfo[PartNum].PartitionType = PARTITION_FAT32_XINT13;
+                        PartEntry->PartitionType = PARTITION_FAT32_XINT13;
                     }
                 }
+
+                DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartEntry->PartitionType;
             }
+#if 0
             else if (wcscmp(FileSystemList->Selected->FileSystem, L"EXT2") == 0)
+            {
                 PartEntry->PartInfo[PartNum].PartitionType = PARTITION_EXT2;
+                DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartEntry->PartitionType;
+            }
+#endif
             else if (!FileSystemList->Selected->FormatFunc)
                 return QUIT_PAGE;
 
-            CheckActiveBootPartition(PartitionList);
-
 #ifndef NDEBUG
             CONSOLE_PrintTextXY(6, 12,
                                 "Disk: %I64u  Cylinder: %I64u  Track: %I64u",
@@ -2373,27 +2593,21 @@ FormatPartitionPage(PINPUT_RECORD Ir)
             DiskEntry = PartitionList->CurrentDisk;
             Entry = DiskEntry->PartListHead.Flink;
 
-            while (Entry != &DiskEntry->PartListHead)
+            while (Entry != &DiskEntry->PrimaryPartListHead)
             {
                 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
 
-                if (PartEntry->Unpartitioned == FALSE)
+                if (PartEntry->IsPartitioned == TRUE)
                 {
-                    for (i = 0; i < 4; i++)
-                    {
-                        CONSOLE_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++;
-                    }
-
+                    CONSOLE_PrintTextXY(6, Line,
+                                        "%2u:  %2u  %c  %12I64u  %12I64u  %2u  %c",
+                                        i,
+                                        PartEntry->PartitionNumber,
+                                        PartEntry->BootIndicator ? 'A' : '-',
+                                        PartEntry->StartSector.QuadPart,
+                                        PartEntry->SectorCount.QuadPart,
+                                        PartEntry->PartitionType,
+                                        PartEntry->Dirty ? '*' : ' ');
                     Line++;
                 }
 
@@ -2404,6 +2618,8 @@ FormatPartitionPage(PINPUT_RECORD Ir)
             PartEntry = PartitionList->CurrentPartition;
 #endif
 
+            CheckActiveBootPartition(PartitionList);
+
             if (WritePartitionsToDisk(PartitionList) == FALSE)
             {
                 DPRINT("WritePartitionsToDisk() failed\n");
@@ -2416,24 +2632,11 @@ FormatPartitionPage(PINPUT_RECORD Ir)
             swprintf(PathBuffer,
                      L"\\Device\\Harddisk%lu\\Partition%lu",
                      PartitionList->CurrentDisk->DiskNumber,
-                     PartitionList->CurrentPartition->PartInfo[PartNum].PartitionNumber);
+                     PartitionList->CurrentPartition->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[PartitionList->ActiveBootPartitionNumber].PartitionNumber);
-            RtlCreateUnicodeString(&SystemRootPath,
-                                   PathBuffer);
-            DPRINT("SystemRootPath: %wZ\n", &SystemRootPath);
-
-
             if (FileSystemList->Selected->FormatFunc)
             {
                 Status = FormatPartition(&DestinationRootPath,
@@ -2447,7 +2650,6 @@ FormatPartitionPage(PINPUT_RECORD Ir)
 
                 PartEntry->New = FALSE;
 
-                CheckActiveBootPartition(PartitionList);
             }
 
 #ifndef NDEBUG
@@ -2472,7 +2674,6 @@ CheckFileSystemPage(PINPUT_RECORD Ir)
     WCHAR PathBuffer[MAX_PATH];
     CHAR Buffer[MAX_PATH];
     NTSTATUS Status;
-    UCHAR PartNum = PartitionList->CurrentPartitionNumber;
 
     /* FIXME: code duplicated in FormatPartitionPage */
     /* Set DestinationRootPath */
@@ -2480,19 +2681,10 @@ CheckFileSystemPage(PINPUT_RECORD Ir)
     swprintf(PathBuffer,
              L"\\Device\\Harddisk%lu\\Partition%lu",
     PartitionList->CurrentDisk->DiskNumber,
-    PartitionList->CurrentPartition->PartInfo[PartNum].PartitionNumber);
+    PartitionList->CurrentPartition->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[PartNum].PartitionNumber);
-    RtlCreateUnicodeString(&SystemRootPath, PathBuffer);
-    DPRINT("SystemRootPath: %wZ\n", &SystemRootPath);
-
     CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHECKINGPART));
 
     CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT));
@@ -2555,8 +2747,7 @@ CheckFileSystemPage(PINPUT_RECORD Ir)
 static PAGE_NUMBER
 InstallDirectoryPage1(PWCHAR InstallDir,
                       PDISKENTRY DiskEntry,
-                      PPARTENTRY PartEntry,
-                      UCHAR PartNum)
+                      PPARTENTRY PartEntry)
 {
     WCHAR PathBuffer[MAX_PATH];
 
@@ -2580,7 +2771,7 @@ InstallDirectoryPage1(PWCHAR InstallDir,
     swprintf(PathBuffer,
              L"multi(0)disk(0)rdisk(%lu)partition(%lu)",
              DiskEntry->BiosDiskNumber,
-             PartEntry->PartInfo[PartNum].PartitionNumber);
+             PartEntry->PartitionNumber);
 
     if (InstallDir[0] != L'\\')
         wcscat(PathBuffer, L"\\");
@@ -2598,8 +2789,6 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
     PDISKENTRY DiskEntry;
     PPARTENTRY PartEntry;
     WCHAR InstallDir[51];
-    PWCHAR DefaultPath;
-    INFCONTEXT Context;
     ULONG Length;
 
     if (PartitionList == NULL ||
@@ -2613,22 +2802,10 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
     DiskEntry = PartitionList->CurrentDisk;
     PartEntry = PartitionList->CurrentPartition;
 
-    /* Search for 'DefaultPath' in the 'SetupData' section */
-    if (!SetupFindFirstLineW(SetupInf, L"SetupData", L"DefaultPath", &Context))
-    {
-        MUIDisplayError(ERROR_FIND_SETUPDATA, Ir, POPUP_WAIT_ENTER);
-        return QUIT_PAGE;
-    }
-
-    /* Read the 'DefaultPath' data */
-    if (INF_GetData(&Context, NULL, &DefaultPath))
-    {
-        wcscpy(InstallDir, DefaultPath);
-    }
+    if (IsUnattendedSetup)
+        wcscpy(InstallDir, UnattendInstallationDirectory);
     else
-    {
         wcscpy(InstallDir, L"\\ReactOS");
-    }
 
     Length = wcslen(InstallDir);
     CONSOLE_SetInputTextXY(8, 11, 51, InstallDir);
@@ -2638,8 +2815,7 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
     {
         return InstallDirectoryPage1(InstallDir,
                                      DiskEntry,
-                                     PartEntry,
-                                     PartitionList->CurrentPartitionNumber);
+                                     PartEntry);
     }
 
     while (TRUE)
@@ -2658,8 +2834,7 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
         {
             return InstallDirectoryPage1(InstallDir,
                                          DiskEntry,
-                                         PartEntry,
-                                         PartitionList->CurrentPartitionNumber);
+                                         PartEntry);
         }
         else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x08) /* BACKSPACE */
         {
@@ -3116,6 +3291,11 @@ FileCopyCallback(PVOID Context,
 
         case SPFILENOTIFY_ENDCOPY:
             CopyContext->CompletedOperations++;
+
+            /* SYSREG checkpoint */
+            if (CopyContext->TotalOperations >> 1 == CopyContext->CompletedOperations)
+                DPRINT1("CHECKPOINT:HALF_COPIED\n");
+
             ProgressNextStep(CopyContext->ProgressBar);
             SetupUpdateMemoryInfo(CopyContext, FALSE);
             break;
@@ -3335,6 +3515,9 @@ RegistryPage(PINPUT_RECORD Ir)
         return QUIT_PAGE;
     }
 
+    /* Set the default pagefile entry */
+    SetDefaultPagefile(DestinationDriveLetter);
+
     /* Update the mounted devices list */
     SetMountedDeviceValues(PartitionList);
 
@@ -3350,11 +3533,31 @@ BootLoaderPage(PINPUT_RECORD Ir)
     UCHAR PartitionType;
     BOOLEAN InstallOnFloppy;
     USHORT Line = 12;
+    WCHAR PathBuffer[MAX_PATH];
 
     CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT));
 
-    PartitionType = PartitionList->ActiveBootPartition->
-        PartInfo[PartitionList->ActiveBootPartitionNumber].PartitionType;
+    /* Find or set the active partition */
+    CheckActiveBootPartition(PartitionList);
+
+    /* Update the partition table because we may have changed the active partition */
+    if (WritePartitionsToDisk(PartitionList) == FALSE)
+    {
+        DPRINT("WritePartitionsToDisk() failed\n");
+        MUIDisplayError(ERROR_WRITE_PTABLE, Ir, POPUP_WAIT_ENTER);
+        return QUIT_PAGE;
+    }
+
+    RtlFreeUnicodeString(&SystemRootPath);
+    swprintf(PathBuffer,
+             L"\\Device\\Harddisk%lu\\Partition%lu",
+             PartitionList->ActiveBootDisk->DiskNumber,
+             PartitionList->ActiveBootPartition->PartitionNumber);
+    RtlCreateUnicodeString(&SystemRootPath,
+                           PathBuffer);
+    DPRINT("SystemRootPath: %wZ\n", &SystemRootPath);
+
+    PartitionType = PartitionList->ActiveBootPartition->PartitionType;
 
     if (IsUnattendedSetup)
     {
@@ -3538,8 +3741,7 @@ BootLoaderHarddiskVbrPage(PINPUT_RECORD Ir)
     UCHAR PartitionType;
     NTSTATUS Status;
 
-    PartitionType = PartitionList->ActiveBootPartition->
-                    PartInfo[PartitionList->ActiveBootPartitionNumber].PartitionType;
+    PartitionType = PartitionList->ActiveBootPartition->PartitionType;
 
     Status = InstallVBRToPartition(&SystemRootPath,
                                    &SourceRootPath,
@@ -3563,8 +3765,7 @@ BootLoaderHarddiskMbrPage(PINPUT_RECORD Ir)
     WCHAR SourceMbrPathBuffer[MAX_PATH];
 
     /* Step 1: Write the VBR */
-    PartitionType = PartitionList->ActiveBootPartition->
-        PartInfo[PartitionList->ActiveBootPartitionNumber].PartitionType;
+    PartitionType = PartitionList->ActiveBootPartition->PartitionType;
 
     Status = InstallVBRToPartition(&SystemRootPath,
                                    &SourceRootPath,
@@ -3820,8 +4021,12 @@ RunUSetup(VOID)
                 Page = SelectPartitionPage(&Ir);
                 break;
 
-            case CREATE_PARTITION_PAGE:
-                Page = CreatePartitionPage(&Ir);
+            case CREATE_PRIMARY_PARTITION_PAGE:
+                Page = CreatePrimaryPartitionPage(&Ir);
+                break;
+
+            case CREATE_EXTENDED_PARTITION_PAGE:
+                Page = CreateExtendedPartitionPage(&Ir);
                 break;
 
             case DELETE_PARTITION_PAGE: