[USETUP]
[reactos.git] / reactos / base / setup / usetup / interface / usetup.c
index 446cf48..ea1711e 100644 (file)
@@ -12,9 +12,9 @@
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 /*
  * COPYRIGHT:       See COPYING in the top level directory
@@ -45,6 +45,7 @@ LONG UnattendFormatPartition = 0;
 LONG AutoPartition = 0;
 WCHAR UnattendInstallationDirectory[MAX_PATH];
 PWCHAR SelectedLanguageId;
+WCHAR LocaleID[9];
 WCHAR DefaultLanguage[20];
 WCHAR DefaultKBLayout[20];
 BOOLEAN RepairUpdateFlag = FALSE;
@@ -78,6 +79,8 @@ static PGENERIC_LIST KeyboardList = NULL;
 static PGENERIC_LIST LayoutList = NULL;
 static PGENERIC_LIST LanguageList = NULL;
 
+static LANGID LanguageId = 0;
+
 /* FUNCTIONS ****************************************************************/
 
 static VOID
@@ -421,6 +424,7 @@ CheckUnattendedSetup(VOID)
     UnattendInf = SetupOpenInfFileW(UnattendInfPath,
                                     NULL,
                                     INF_STYLE_WIN4,
+                                    LanguageId,
                                     &ErrorLine);
 
     if (UnattendInf == INVALID_HANDLE_VALUE)
@@ -555,8 +559,16 @@ CheckUnattendedSetup(VOID)
         }
     }
 
-    SetupCloseInfFile(UnattendInf);
+       /* search for LocaleID in the 'Unattend' section*/
+       if (SetupFindFirstLineW (UnattendInf, L"Unattend", L"LocaleID", &Context)){
+               if (INF_GetData (&Context, NULL, &Value)){
+                       LONG Id = wcstol(Value, NULL, 16);
+                       swprintf(LocaleID,L"%08lx", Id);                        
+       }       
+    }
 
+       SetupCloseInfFile(UnattendInf);
+       
     DPRINT("Running unattended setup\n");
 }
 
@@ -571,6 +583,11 @@ UpdateKBLayout(VOID)
     if (LayoutList == NULL)
     {
         LayoutList = CreateKeyboardLayoutList(SetupInf, DefaultKBLayout);
+        if (LayoutList == NULL)
+        {
+            /* FIXME: Handle error! */
+            return;
+        }
     }
 
     ListEntry = GetFirstListEntry(LayoutList);
@@ -664,6 +681,8 @@ LanguagePage(PINPUT_RECORD Ir)
         {
             SelectedLanguageId = (PWCHAR)GetListEntryUserData(GetCurrentListEntry(LanguageList));
 
+            LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF);
+
             if (wcscmp(SelectedLanguageId, DefaultLanguage))
             {
                 UpdateKBLayout();
@@ -699,7 +718,8 @@ SetupStartPage(PINPUT_RECORD Ir)
     INFCONTEXT Context;
     PWCHAR Value;
     UINT ErrorLine;
-    SIZE_T ReturnSize;
+    ULONG ReturnSize;
+    PGENERIC_LIST_ENTRY ListEntry;
 
     CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT));
 
@@ -750,6 +770,7 @@ SetupStartPage(PINPUT_RECORD Ir)
     SetupInf = SetupOpenInfFileW(FileNameBuffer,
                                  NULL,
                                  INF_STYLE_WIN4,
+                                 LanguageId,
                                  &ErrorLine);
 
     if (SetupInf == INVALID_HANDLE_VALUE)
@@ -797,8 +818,43 @@ SetupStartPage(PINPUT_RECORD Ir)
         KeyboardList = CreateKeyboardDriverList(SetupInf);
         LayoutList = CreateKeyboardLayoutList(SetupInf, DefaultKBLayout);
         LanguageList = CreateLanguageList(SetupInf, DefaultLanguage);
-
-        return INSTALL_INTRO_PAGE;
+               
+               /* new part */
+               
+               wcscpy(SelectedLanguageId,LocaleID);
+               
+                               
+               /* first we hack LanguageList */
+               ListEntry = GetFirstListEntry(LanguageList);
+
+               while (ListEntry != NULL)
+               {
+                       if (!wcscmp(LocaleID, GetListEntryUserData(ListEntry)))
+                       {
+                               DPRINT("found %S in LanguageList\n",GetListEntryUserData(ListEntry));
+                               SetCurrentListEntry(LanguageList, ListEntry);
+                               break;
+                       }
+
+                       ListEntry = GetNextListEntry(ListEntry);
+               }
+               /* now LayoutList */
+               ListEntry = GetFirstListEntry(LayoutList);
+
+               while (ListEntry != NULL)
+               {
+                       if (!wcscmp(LocaleID, GetListEntryUserData(ListEntry)))
+                       {
+                               DPRINT("found %S in LayoutList\n",GetListEntryUserData(ListEntry));
+                               SetCurrentListEntry(LayoutList, ListEntry);
+                               break;
+                       }
+
+                       ListEntry = GetNextListEntry(ListEntry);
+               }
+               SetConsoleCodePage();
+
+               return INSTALL_INTRO_PAGE;
     }
 
     return LANGUAGE_PAGE;
@@ -1494,6 +1550,8 @@ DrawInputField(ULONG FieldLength,
 
 
 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
+/* Restriction for MaxSize: pow(10, PARTITION_SIZE_INPUT_FIELD_LENGTH)-1 */
+#define PARTITION_MAXSIZE 999999
 
 static VOID
 ShowPartitionSizeInputBox(SHORT Left,
@@ -1692,6 +1750,9 @@ CreatePartitionPage (PINPUT_RECORD Ir)
     while (TRUE)
     {
         MaxSize = (PartEntry->UnpartitionedLength + (1 << 19)) >> 20;  /* in MBytes (rounded) */
+
+        if (MaxSize > PARTITION_MAXSIZE) MaxSize = PARTITION_MAXSIZE;
+
         ShowPartitionSizeInputBox (12, 14, xScreen - 12, 17, /* left, top, right, bottom */
                                    MaxSize, InputBuffer, &Quit, &Cancel);
 
@@ -1731,8 +1792,8 @@ CreatePartitionPage (PINPUT_RECORD Ir)
             else
             {
                 /* Round-up by cylinder size */
-                PartSize = ROUND_UP (PartSize * 1024 * 1024,
-                                     DiskEntry->CylinderSize);
+                PartSize = (PartSize * 1024 * 1024 + DiskEntry->CylinderSize - 1) /
+                           DiskEntry->CylinderSize * DiskEntry->CylinderSize;
 
                 /* But never get larger than the unpartitioned disk space */
                 if (PartSize > PartEntry->UnpartitionedLength)
@@ -1762,6 +1823,7 @@ DeletePartitionPage (PINPUT_RECORD Ir)
     ULONGLONG PartSize;
     PCHAR Unit;
     PCHAR PartType;
+    UCHAR PartNumber;
 
     if (PartitionList == NULL ||
         PartitionList->CurrentDisk == NULL ||
@@ -1773,6 +1835,7 @@ DeletePartitionPage (PINPUT_RECORD Ir)
 
     DiskEntry = PartitionList->CurrentDisk;
     PartEntry = PartitionList->CurrentPartition;
+    PartNumber = PartitionList->CurrentPartitionNumber;
 
     MUIDisplayPage(DELETE_PARTITION_PAGE);
 
@@ -1784,44 +1847,44 @@ DeletePartitionPage (PINPUT_RECORD Ir)
     }
     else if (PartEntry->Unpartitioned == FALSE)
     {
-        if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_12) ||
-            (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_16) ||
-            (PartEntry->PartInfo[0].PartitionType == PARTITION_HUGE) ||
-            (PartEntry->PartInfo[0].PartitionType == PARTITION_XINT13))
+        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))
         {
             PartType = "FAT";
         }
-        else if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32) ||
-                 (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13))
+        else if ((PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32) ||
+                 (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32_XINT13))
         {
             PartType = "FAT32";
         }
-        else if (PartEntry->PartInfo[0].PartitionType == PARTITION_EXT2)
+        else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_EXT2)
         {
             PartType = "EXT2";
         }
-        else if (PartEntry->PartInfo[0].PartitionType == PARTITION_IFS)
+        else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_IFS)
         {
             PartType = "NTFS"; /* FIXME: Not quite correct! */
         }
     }
 
 #if 0
-    if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0x280000000LL) /* 10 GB */
+    if (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart >= 0x280000000LL) /* 10 GB */
     {
-        PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 29)) >> 30;
+        PartSize = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 29)) >> 30;
         Unit = MUIGetString(STRING_GB);
     }
     else
 #endif
-    if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0xA00000LL) /* 10 MB */
+    if (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart >= 0xA00000LL) /* 10 MB */
     {
-        PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 19)) >> 20;
+        PartSize = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 19)) >> 20;
         Unit = MUIGetString(STRING_MB);
     }
     else
     {
-        PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 9)) >> 10;
+        PartSize = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 9)) >> 10;
         Unit = MUIGetString(STRING_KB);
     }
 
@@ -1829,9 +1892,9 @@ DeletePartitionPage (PINPUT_RECORD Ir)
     {
         CONSOLE_PrintTextXY(6, 10,
                              MUIGetString(STRING_HDDINFOUNK2),
-                             (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
-                             (PartEntry->DriveLetter == 0) ? '-' : ':',
-                             PartEntry->PartInfo[0].PartitionType,
+                             (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber],
+                             (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':',
+                             PartEntry->PartInfo[PartNumber].PartitionType,
                              PartSize,
                              Unit);
     }
@@ -1839,8 +1902,8 @@ DeletePartitionPage (PINPUT_RECORD Ir)
     {
         CONSOLE_PrintTextXY(6, 10,
                              "   %c%c  %s    %I64u %s",
-                             (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
-                             (PartEntry->DriveLetter == 0) ? '-' : ':',
+                             (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber],
+                             (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':',
                              PartType,
                              PartSize,
                              Unit);
@@ -1922,6 +1985,7 @@ SelectFileSystemPage (PINPUT_RECORD Ir)
 {
     PDISKENTRY DiskEntry;
     PPARTENTRY PartEntry;
+    UCHAR      PartNumber;
     ULONGLONG DiskSize;
     ULONGLONG PartSize;
     PCHAR DiskUnit;
@@ -1938,6 +2002,7 @@ SelectFileSystemPage (PINPUT_RECORD Ir)
 
     DiskEntry = PartitionList->CurrentDisk;
     PartEntry = PartitionList->CurrentPartition;
+    PartNumber = PartitionList->CurrentPartitionNumber;
 
     /* adjust disk size */
     if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */
@@ -1952,39 +2017,39 @@ SelectFileSystemPage (PINPUT_RECORD Ir)
     }
 
     /* adjust partition size */
-    if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0x280000000LL) /* 10 GB */
+    if (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart >= 0x280000000LL) /* 10 GB */
     {
-        PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 29)) >> 30;
+        PartSize = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 29)) >> 30;
         PartUnit = MUIGetString(STRING_GB);
     }
     else
     {
-        PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 19)) >> 20;
+        PartSize = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 19)) >> 20;
         PartUnit = MUIGetString(STRING_MB);
     }
 
     /* adjust partition type */
-    if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_12) ||
-        (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_16) ||
-        (PartEntry->PartInfo[0].PartitionType == PARTITION_HUGE) ||
-        (PartEntry->PartInfo[0].PartitionType == PARTITION_XINT13))
+    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))
     {
         PartType = "FAT";
     }
-    else if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32) ||
-             (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13))
+    else if ((PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32) ||
+             (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32_XINT13))
     {
         PartType = "FAT32";
     }
-    else if (PartEntry->PartInfo[0].PartitionType == PARTITION_EXT2)
+    else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_EXT2)
     {
         PartType = "EXT2";
     }
-    else if (PartEntry->PartInfo[0].PartitionType == PARTITION_IFS)
+    else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_IFS)
     {
         PartType = "NTFS"; /* FIXME: Not quite correct! */
     }
-    else if (PartEntry->PartInfo[0].PartitionType == PARTITION_ENTRY_UNUSED)
+    else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_ENTRY_UNUSED)
     {
         PartType = MUIGetString(STRING_FORMATUNUSED);
     }
@@ -1999,7 +2064,7 @@ SelectFileSystemPage (PINPUT_RECORD Ir)
 
 #if 0
         CONSOLE_PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
-                            PartEntry->PartInfo[0].PartitionNumber,
+                            PartEntry->PartInfo[PartNumber].PartitionNumber,
                             PartSize,
                             PartUnit,
                             PartType);
@@ -2032,9 +2097,9 @@ SelectFileSystemPage (PINPUT_RECORD Ir)
         {
             CONSOLE_PrintTextXY(8, 10,
                                  MUIGetString(STRING_HDDINFOUNK4),
-                                 (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
-                                 (PartEntry->DriveLetter == 0) ? '-' : ':',
-                                 PartEntry->PartInfo[0].PartitionType,
+                                 (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber],
+                                 (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':',
+                                 PartEntry->PartInfo[PartNumber].PartitionType,
                                  PartSize,
                                  PartUnit);
         }
@@ -2042,8 +2107,8 @@ SelectFileSystemPage (PINPUT_RECORD Ir)
         {
             CONSOLE_PrintTextXY(8, 10,
                                  "%c%c  %s    %I64u %s",
-                                (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
-                                (PartEntry->DriveLetter == 0) ? '-' : ':',
+                                (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber],
+                                (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':',
                                 PartType,
                                 PartSize,
                                 PartUnit);
@@ -2142,6 +2207,7 @@ FormatPartitionPage (PINPUT_RECORD Ir)
     WCHAR PathBuffer[MAX_PATH];
     PDISKENTRY DiskEntry;
     PPARTENTRY PartEntry;
+    UCHAR PartNum;
     NTSTATUS Status;
 
 #ifndef NDEBUG
@@ -2162,6 +2228,7 @@ FormatPartitionPage (PINPUT_RECORD Ir)
 
     DiskEntry = PartitionList->CurrentDisk;
     PartEntry = PartitionList->CurrentPartition;
+    PartNum = PartitionList->CurrentPartitionNumber;
 
     while(TRUE)
     {
@@ -2184,53 +2251,53 @@ FormatPartitionPage (PINPUT_RECORD Ir)
         {
             CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT));
 
-            if (PartEntry->PartInfo[0].PartitionType == PARTITION_ENTRY_UNUSED)
+            if (PartEntry->PartInfo[PartNum].PartitionType == PARTITION_ENTRY_UNUSED)
             {
                 if (wcscmp(FileSystemList->Selected->FileSystem, L"FAT") == 0)
                 {
-                    if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (4200LL * 1024LL))
+                    if (PartEntry->PartInfo[PartNum].PartitionLength.QuadPart < (4200LL * 1024LL))
                     {
                         /* FAT12 CHS partition (disk is smaller than 4.1MB) */
-                        PartEntry->PartInfo[0].PartitionType = PARTITION_FAT_12;
+                        PartEntry->PartInfo[PartNum].PartitionType = PARTITION_FAT_12;
                     }
-                    else if (PartEntry->PartInfo[0].StartingOffset.QuadPart < (1024LL * 255LL * 63LL * 512LL))
+                    else if (PartEntry->PartInfo[PartNum].StartingOffset.QuadPart < (1024LL * 255LL * 63LL * 512LL))
                     {
                         /* Partition starts below the 8.4GB boundary ==> CHS partition */
 
-                        if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (32LL * 1024LL * 1024LL))
+                        if (PartEntry->PartInfo[PartNum].PartitionLength.QuadPart < (32LL * 1024LL * 1024LL))
                         {
                             /* FAT16 CHS partition (partiton size < 32MB) */
-                            PartEntry->PartInfo[0].PartitionType = PARTITION_FAT_16;
+                            PartEntry->PartInfo[PartNum].PartitionType = PARTITION_FAT_16;
                         }
-                        else if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (512LL * 1024LL * 1024LL))
+                        else if (PartEntry->PartInfo[PartNum].PartitionLength.QuadPart < (512LL * 1024LL * 1024LL))
                         {
                             /* FAT16 CHS partition (partition size < 512MB) */
-                            PartEntry->PartInfo[0].PartitionType = PARTITION_HUGE;
+                            PartEntry->PartInfo[PartNum].PartitionType = PARTITION_HUGE;
                         }
                         else
                         {
                             /* FAT32 CHS partition (partition size >= 512MB) */
-                            PartEntry->PartInfo[0].PartitionType = PARTITION_FAT32;
+                            PartEntry->PartInfo[PartNum].PartitionType = PARTITION_FAT32;
                         }
                     }
                     else
                     {
                         /* Partition starts above the 8.4GB boundary ==> LBA partition */
 
-                        if (PartEntry->PartInfo[0].PartitionLength.QuadPart < (512LL * 1024LL * 1024LL))
+                        if (PartEntry->PartInfo[PartNum].PartitionLength.QuadPart < (512LL * 1024LL * 1024LL))
                         {
                             /* FAT16 LBA partition (partition size < 512MB) */
-                            PartEntry->PartInfo[0].PartitionType = PARTITION_XINT13;
+                            PartEntry->PartInfo[PartNum].PartitionType = PARTITION_XINT13;
                         }
                         else
                         {
                             /* FAT32 LBA partition (partition size >= 512MB) */
-                            PartEntry->PartInfo[0].PartitionType = PARTITION_FAT32_XINT13;
+                            PartEntry->PartInfo[PartNum].PartitionType = PARTITION_FAT32_XINT13;
                         }
                     }
                 }
                 else if (wcscmp(FileSystemList->Selected->FileSystem, L"EXT2") == 0)
-                    PartEntry->PartInfo[0].PartitionType = PARTITION_EXT2;
+                    PartEntry->PartInfo[PartNum].PartitionType = PARTITION_EXT2;
                 else if (!FileSystemList->Selected->FormatFunc)
                     return QUIT_PAGE;
             }
@@ -2291,7 +2358,7 @@ FormatPartitionPage (PINPUT_RECORD Ir)
             swprintf (PathBuffer,
                       L"\\Device\\Harddisk%lu\\Partition%lu",
                       PartitionList->CurrentDisk->DiskNumber,
-                      PartitionList->CurrentPartition->PartInfo[0].PartitionNumber);
+                      PartitionList->CurrentPartition->PartInfo[PartNum].PartitionNumber);
             RtlCreateUnicodeString (&DestinationRootPath,
                                     PathBuffer);
             DPRINT ("DestinationRootPath: %wZ\n", &DestinationRootPath);
@@ -2302,7 +2369,8 @@ FormatPartitionPage (PINPUT_RECORD Ir)
             swprintf (PathBuffer,
                       L"\\Device\\Harddisk%lu\\Partition%lu",
                       PartitionList->ActiveBootDisk->DiskNumber,
-                      PartitionList->ActiveBootPartition->PartInfo[0].PartitionNumber);
+                      PartitionList->ActiveBootPartition->
+                        PartInfo[PartitionList->ActiveBootPartitionNumber].PartitionNumber);
             RtlCreateUnicodeString (&SystemRootPath,
                                     PathBuffer);
             DPRINT ("SystemRootPath: %wZ\n", &SystemRootPath);
@@ -2323,11 +2391,33 @@ FormatPartitionPage (PINPUT_RECORD Ir)
                 CheckActiveBootPartition(PartitionList);
             }
 
+            /* Install MBR if necessary */
+            if (DiskEntry->NoMbr &&
+                DiskEntry->BiosDiskNumber == 0)
+            {
+                wcscpy(PathBuffer, SourceRootPath.Buffer);
+                wcscat(PathBuffer, L"\\loader\\dosmbr.bin");
+
+                DPRINT("Install MBR bootcode: %S ==> %S\n",
+                    PathBuffer, DestinationRootPath.Buffer);
+
+                /* Install MBR bootcode */
+                Status = InstallMbrBootCodeToDisk(PathBuffer, DestinationRootPath.Buffer);
+                if (!NT_SUCCESS (Status))
+                {
+                    DPRINT1("InstallMbrBootCodeToDisk() failed (Status %lx)\n",
+                        Status);
+                    return FALSE;
+                }
+
+                DiskEntry->NoMbr = FALSE;
+            }
+
             if (wcscmp(FileSystemList->Selected->FileSystem, L"FAT") == 0)
             {
                 /* FIXME: Install boot code. This is a hack! */
-                if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13) ||
-                    (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32))
+                if ((PartEntry->PartInfo[PartNum].PartitionType == PARTITION_FAT32_XINT13) ||
+                    (PartEntry->PartInfo[PartNum].PartitionType == PARTITION_FAT32))
                 {
                     wcscpy(PathBuffer, SourceRootPath.Buffer);
                     wcscat(PathBuffer, L"\\loader\\fat32.bin");
@@ -2414,6 +2504,7 @@ 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 */
@@ -2421,7 +2512,7 @@ CheckFileSystemPage(PINPUT_RECORD Ir)
     swprintf(PathBuffer,
              L"\\Device\\Harddisk%lu\\Partition%lu",
     PartitionList->CurrentDisk->DiskNumber,
-    PartitionList->CurrentPartition->PartInfo[0].PartitionNumber);
+    PartitionList->CurrentPartition->PartInfo[PartNum].PartitionNumber);
     RtlCreateUnicodeString(&DestinationRootPath, PathBuffer);
     DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath);
 
@@ -2430,7 +2521,7 @@ CheckFileSystemPage(PINPUT_RECORD Ir)
     swprintf(PathBuffer,
              L"\\Device\\Harddisk%lu\\Partition%lu",
     PartitionList->ActiveBootDisk->DiskNumber,
-    PartitionList->ActiveBootPartition->PartInfo[0].PartitionNumber);
+    PartitionList->ActiveBootPartition->PartInfo[PartNum].PartitionNumber);
     RtlCreateUnicodeString(&SystemRootPath, PathBuffer);
     DPRINT("SystemRootPath: %wZ\n", &SystemRootPath);
 
@@ -2494,7 +2585,7 @@ CheckFileSystemPage(PINPUT_RECORD Ir)
 
 
 static PAGE_NUMBER
-InstallDirectoryPage1(PWCHAR InstallDir, PDISKENTRY DiskEntry, PPARTENTRY PartEntry)
+InstallDirectoryPage1(PWCHAR InstallDir, PDISKENTRY DiskEntry, PPARTENTRY PartEntry, UCHAR PartNum)
 {
     WCHAR PathBuffer[MAX_PATH];
 
@@ -2518,7 +2609,7 @@ InstallDirectoryPage1(PWCHAR InstallDir, PDISKENTRY DiskEntry, PPARTENTRY PartEn
     swprintf(PathBuffer,
              L"multi(0)disk(0)rdisk(%lu)partition(%lu)",
              DiskEntry->BiosDiskNumber,
-             PartEntry->PartInfo[0].PartitionNumber);
+             PartEntry->PartInfo[PartNum].PartitionNumber);
 
     if (InstallDir[0] != L'\\')
         wcscat(PathBuffer, L"\\");
@@ -2574,7 +2665,7 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
 
     if (IsUnattendedSetup)
     {
-        return(InstallDirectoryPage1 (InstallDir, DiskEntry, PartEntry));
+        return(InstallDirectoryPage1 (InstallDir, DiskEntry, PartEntry, PartitionList->CurrentPartitionNumber));
     }
 
     while(TRUE)
@@ -2591,7 +2682,7 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
         }
         else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
         {
-            return (InstallDirectoryPage1 (InstallDir, DiskEntry, PartEntry));
+            return (InstallDirectoryPage1 (InstallDir, DiskEntry, PartEntry, PartitionList->CurrentPartitionNumber));
         }
         else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x08) /* BACKSPACE */
         {
@@ -2960,6 +3051,7 @@ PrepareCopyPage(PINPUT_RECORD Ir)
                                           InfFileSize,
                                           (const CHAR*) NULL,
                                           INF_STYLE_WIN4,
+                                          LanguageId,
                                           &ErrorLine);
 
         if (InfHandle == INVALID_HANDLE_VALUE)
@@ -3003,18 +3095,9 @@ SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext,
     }
 
     /* Set current values */
-    ProgressSetStep(CopyContext->MemoryBars[0], PerfInfo.PagedPoolPages);
-    ProgressSetStep(CopyContext->MemoryBars[1], PerfInfo.NonPagedPoolPages);
+    ProgressSetStep(CopyContext->MemoryBars[0], PerfInfo.PagedPoolPages + PerfInfo.NonPagedPoolPages);
+    ProgressSetStep(CopyContext->MemoryBars[1], PerfInfo.ResidentSystemCachePage);
     ProgressSetStep(CopyContext->MemoryBars[2], PerfInfo.AvailablePages);
-
-    /* Check if memory dropped below 40%! */
-    if (CopyContext->MemoryBars[2]->Percent <= 40)
-    {
-        /* Wait a while until Mm does its thing */
-        LARGE_INTEGER Interval;
-        Interval.QuadPart = -1 * 15 * 1000 * 100;
-        NtDelayExecution(FALSE, &Interval);
-    }
 }
 
 static UINT CALLBACK
@@ -3057,6 +3140,7 @@ PAGE_NUMBER
 FileCopyPage(PINPUT_RECORD Ir)
 {
     COPYCONTEXT CopyContext;
+    unsigned int mem_bar_width;
 
     MUIDisplayPage(FILE_COPY_PAGE);
 
@@ -3076,35 +3160,39 @@ FileCopyPage(PINPUT_RECORD Ir)
                                                 TRUE,
                                                 MUIGetString(STRING_SETUPCOPYINGFILES));
 
+    // fit memory bars to screen width, distribute them uniform
+    mem_bar_width = (xScreen - 26) / 5;
+    mem_bar_width -= mem_bar_width % 2;  // make even
+    /* ATTENTION: The following progress bars are debug stuff, which should not be translated!! */
     /* Create the paged pool progress bar */
     CopyContext.MemoryBars[0] = CreateProgressBar(13,
                                                   40,
-                                                  18,
+                                                 13 + mem_bar_width,
                                                   43,
-                                                  10,
+                                                 13,
                                                   44,
                                                   FALSE,
-                                                  MUIGetString(STRING_PAGEDMEM));
+                                                  "Kernel Pool");
 
     /* Create the non paged pool progress bar */
-    CopyContext.MemoryBars[1] = CreateProgressBar(28,
+    CopyContext.MemoryBars[1] = CreateProgressBar((xScreen / 2)- (mem_bar_width / 2),
                                                   40,
-                                                  33,
+                                                 (xScreen / 2) + (mem_bar_width / 2),
                                                   43,
-                                                  24,
+                                                  (xScreen / 2)- (mem_bar_width / 2),
                                                   44,
                                                   FALSE,
-                                                  MUIGetString(STRING_NONPAGEDMEM));
+                                                  "Kernel Cache");
 
     /* Create the global memory progress bar */
-    CopyContext.MemoryBars[2] = CreateProgressBar(43,
+    CopyContext.MemoryBars[2] = CreateProgressBar(xScreen - 13 - mem_bar_width,
                                                   40,
-                                                  48,
+                                                 xScreen - 13,
                                                   43,
-                                                  40,
+                                                 xScreen - 13 - mem_bar_width,
                                                   44,
                                                   FALSE,
-                                                  MUIGetString(STRING_FREEMEM));
+                                                  "Free Memory");
 
     /* Do the file copying */
     SetupCommitFileQueueW(NULL,
@@ -3193,7 +3281,7 @@ RegistryPage(PINPUT_RECORD Ir)
 
         CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE), File);
 
-        if (!ImportRegistryFile(File, Section, Delete))
+        if (!ImportRegistryFile(File, Section, LanguageId, Delete))
         {
             DPRINT("Importing %S failed\n", File);
 
@@ -3226,14 +3314,24 @@ RegistryPage(PINPUT_RECORD Ir)
         return QUIT_PAGE;
     }
 
-    /* Update keyboard layout settings */
-    CONSOLE_SetStatusText(MUIGetString(STRING_KEYBOARDSETTINGSUPDATE));
-    if (!ProcessKeyboardLayoutRegistry(LayoutList))
+    /* Set GeoID */
+
+    if (!SetGeoID(MUIGetGeoID()))
     {
-        MUIDisplayError(ERROR_UPDATE_KBSETTINGS, Ir, POPUP_WAIT_ENTER);
+        MUIDisplayError(ERROR_UPDATE_GEOID, Ir, POPUP_WAIT_ENTER);
         return QUIT_PAGE;
     }
 
+    if (!IsUnattendedSetup){
+        
+       /* Update keyboard layout settings */
+       CONSOLE_SetStatusText(MUIGetString(STRING_KEYBOARDSETTINGSUPDATE));
+       if (!ProcessKeyboardLayoutRegistry(LayoutList))
+       {
+           MUIDisplayError(ERROR_UPDATE_KBSETTINGS, Ir, POPUP_WAIT_ENTER);
+           return QUIT_PAGE;
+       }
+    }
     /* Add codepage information to registry */
     CONSOLE_SetStatusText(MUIGetString(STRING_CODEPAGEINFOUPDATE));
     if (!AddCodePage())
@@ -3260,7 +3358,20 @@ BootLoaderPage(PINPUT_RECORD Ir)
 
     CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT));
 
-    PartitionType = PartitionList->ActiveBootPartition->PartInfo[0].PartitionType;
+    PartitionType = PartitionList->ActiveBootPartition->
+        PartInfo[PartitionList->ActiveBootPartitionNumber].PartitionType;
+
+    if (IsUnattendedSetup)
+    {
+        if (UnattendMBRInstallType == 0) /* skip MBR installation */
+        {
+            return SUCCESS_PAGE;
+        }
+        else if (UnattendMBRInstallType == 1) /* install on floppy */
+        {
+            return BOOT_LOADER_FLOPPY_PAGE;
+        }
+    }
 
     if (PartitionType == PARTITION_ENTRY_UNUSED)
     {
@@ -3307,20 +3418,10 @@ BootLoaderPage(PINPUT_RECORD Ir)
         return BOOT_LOADER_FLOPPY_PAGE;
     }
 
-    if (IsUnattendedSetup)
+    /* Unattended install on hdd? */
+    if (IsUnattendedSetup && UnattendMBRInstallType == 2)
     {
-        if (UnattendMBRInstallType == 0) /* skip MBR installation */
-        {
-            return SUCCESS_PAGE;
-        }
-        else if (UnattendMBRInstallType == 1) /* install on floppy */
-        {
-            return BOOT_LOADER_FLOPPY_PAGE;
-        }
-        else if (UnattendMBRInstallType == 2) /* install on hdd */
-        {
-            return BOOT_LOADER_HARDDISK_PAGE;
-        }
+        return BOOT_LOADER_HARDDISK_PAGE;
     }
 
     MUIDisplayPage(BOOT_LOADER_PAGE);
@@ -3372,7 +3473,7 @@ BootLoaderPage(PINPUT_RECORD Ir)
             }
             else if (Line == 14)
             {
-                return SUCCESS_PAGE;;
+                return SUCCESS_PAGE;
             }
 
             return BOOT_LOADER_PAGE;
@@ -3433,7 +3534,8 @@ BootLoaderHarddiskPage(PINPUT_RECORD Ir)
     UCHAR PartitionType;
     NTSTATUS Status;
 
-    PartitionType = PartitionList->ActiveBootPartition->PartInfo[0].PartitionType;
+    PartitionType = PartitionList->ActiveBootPartition->
+        PartInfo[PartitionList->ActiveBootPartitionNumber].PartitionType;
     if ((PartitionType == PARTITION_FAT_12) ||
         (PartitionType == PARTITION_FAT_16) ||
         (PartitionType == PARTITION_HUGE) ||
@@ -3743,10 +3845,6 @@ RunUSetup(VOID)
         }
     }
 
-    /// THE FOLLOWING DPRINT IS FOR THE SYSTEM REGRESSION TOOL
-    /// DO NOT REMOVE!!!
-    DPRINT1("SYSREG_CHECKPOINT:USETUP_COMPLETE\n");
-
     FreeConsole();
 
     /* Avoid bugcheck */