* Sync with recent trunk (r52637).
[reactos.git] / base / setup / usetup / partlist.c
index c78597e..5109caf 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
  * PROJECT:         ReactOS text-mode setup
@@ -70,8 +70,9 @@ AssignDriverLetters (PPARTLIST List)
   PDISKENTRY DiskEntry;
   PPARTENTRY PartEntry;
   PLIST_ENTRY Entry1;
-  PLIST_ENTRY Entry2;
+  //PLIST_ENTRY Entry2;
   CHAR Letter;
+  UCHAR i;
 
   Letter = 'C';
 
@@ -87,19 +88,25 @@ AssignDriverLetters (PPARTLIST List)
                                      PARTENTRY,
                                      ListEntry);
 
-      PartEntry->DriveLetter = 0;
+      for (i=0; i<3; i++)
+        PartEntry->DriveLetter[i] = 0;
 
-      if (PartEntry->Unpartitioned == FALSE &&
-        !IsContainerPartition (PartEntry->PartInfo[0].PartitionType))
+      if (PartEntry->Unpartitioned == FALSE)
       {
-        if (IsRecognizedPartition (PartEntry->PartInfo[0].PartitionType) ||
-           (PartEntry->PartInfo[0].PartitionType == PARTITION_ENTRY_UNUSED &&
-           PartEntry->PartInfo[0].PartitionLength.QuadPart != 0LL))
+        for (i=0; i<3; i++)
         {
-          if (Letter <= 'Z')
+          if (IsContainerPartition (PartEntry->PartInfo[i].PartitionType))
+            continue;
+
+          if (IsRecognizedPartition (PartEntry->PartInfo[i].PartitionType) ||
+             (PartEntry->PartInfo[i].PartitionType == PARTITION_ENTRY_UNUSED &&
+             PartEntry->PartInfo[i].PartitionLength.QuadPart != 0LL))
           {
-            PartEntry->DriveLetter = Letter;
-            Letter++;
+            if (Letter <= 'Z')
+            {
+              PartEntry->DriveLetter[i] = Letter;
+              Letter++;
+            }
           }
         }
       }
@@ -108,8 +115,8 @@ AssignDriverLetters (PPARTLIST List)
     Entry1 = Entry1->Flink;
   }
 
-
   /* Assign drive letters to logical drives */
+#if 0
   Entry1 = List->DiskListHead.Flink;
   while (Entry1 != &List->DiskListHead)
   {
@@ -148,6 +155,7 @@ AssignDriverLetters (PPARTLIST List)
 
     Entry1 = Entry1->Flink;
   }
+#endif
 }
 
 
@@ -693,6 +701,7 @@ AddDiskToList (HANDLE FileHandle,
   ULONG i;
   PLIST_ENTRY ListEntry;
   PBIOSDISKENTRY BiosDiskEntry;
+  ULONG LayoutBufferSize;
 
   Status = NtDeviceIoControlFile (FileHandle,
                                   NULL,
@@ -767,10 +776,6 @@ AddDiskToList (HANDLE FileHandle,
   }
   Checksum = ~Checksum + 1;
 
-  RtlFreeHeap (ProcessHeap,
-               0,
-               Mbr);
-
   swprintf(Identifier, L"%08x-%08x-A", Checksum, Signature);
   DPRINT("Identifier: %S\n", Identifier);
 
@@ -791,6 +796,17 @@ AddDiskToList (HANDLE FileHandle,
   }
   DiskEntry->BiosFound = FALSE;
 
+  /* Check if this disk has a valid MBR */
+  if (Mbr->BootCode[0] == 0 && Mbr->BootCode[1] == 0)
+    DiskEntry->NoMbr = TRUE;
+  else
+    DiskEntry->NoMbr = FALSE;
+
+  /* Free Mbr sector buffer */
+  RtlFreeHeap (ProcessHeap,
+               0,
+               Mbr);
+
   ListEntry = List->BiosDiskListHead.Flink;
   while(ListEntry != &List->BiosDiskListHead)
   {
@@ -831,23 +847,20 @@ AddDiskToList (HANDLE FileHandle,
   DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
   DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
 
-  DPRINT ("Cylinders %d\n", DiskEntry->Cylinders);
-  DPRINT ("TracksPerCylinder %d\n", DiskEntry->TracksPerCylinder);
-  DPRINT ("SectorsPerTrack %d\n", DiskEntry->SectorsPerTrack);
-  DPRINT ("BytesPerSector %d\n", DiskEntry->BytesPerSector);
+  DPRINT ("Cylinders %I64u\n", DiskEntry->Cylinders);
+  DPRINT ("TracksPerCylinder %I64u\n", DiskEntry->TracksPerCylinder);
+  DPRINT ("SectorsPerTrack %I64u\n", DiskEntry->SectorsPerTrack);
+  DPRINT ("BytesPerSector %I64u\n", DiskEntry->BytesPerSector);
 
-  DiskEntry->DiskSize =
-    DiskGeometry.Cylinders.QuadPart *
-    (ULONGLONG)DiskGeometry.TracksPerCylinder *
+  DiskEntry->TrackSize =
     (ULONGLONG)DiskGeometry.SectorsPerTrack *
     (ULONGLONG)DiskGeometry.BytesPerSector;
   DiskEntry->CylinderSize =
     (ULONGLONG)DiskGeometry.TracksPerCylinder *
-    (ULONGLONG)DiskGeometry.SectorsPerTrack *
-    (ULONGLONG)DiskGeometry.BytesPerSector;
-  DiskEntry->TrackSize =
-    (ULONGLONG)DiskGeometry.SectorsPerTrack *
-    (ULONGLONG)DiskGeometry.BytesPerSector;
+    DiskEntry->TrackSize;
+  DiskEntry->DiskSize =
+    DiskGeometry.Cylinders.QuadPart *
+    DiskEntry->CylinderSize;
 
   DiskEntry->DiskNumber = DiskNumber;
   DiskEntry->Port = ScsiAddress.PortNumber;
@@ -858,9 +871,15 @@ AddDiskToList (HANDLE FileHandle,
 
   InsertAscendingList(&List->DiskListHead, DiskEntry, DISKENTRY, ListEntry, BiosDiskNumber);
 
+  /*
+   * Allocate a buffer for 26 logical drives (2 entries each == 52) 
+   * plus the main partiton table (4 entries). Total 56 entries.
+   */
+  LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
+                     ((56 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
   LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap (ProcessHeap,
                   0,
-                  8192);
+                  LayoutBufferSize);
   if (LayoutBuffer == NULL)
   {
     return;
@@ -875,7 +894,7 @@ AddDiskToList (HANDLE FileHandle,
                                   NULL,
                                   0,
                                   LayoutBuffer,
-                                  8192);
+                                  LayoutBufferSize);
   if (NT_SUCCESS (Status))
   {
     if (LayoutBuffer->PartitionCount == 0)
@@ -906,7 +925,7 @@ CreatePartitionList (SHORT Left,
   OBJECT_ATTRIBUTES ObjectAttributes;
   SYSTEM_DEVICE_INFORMATION Sdi;
   IO_STATUS_BLOCK Iosb;
-  SIZE_T ReturnSize;
+  ULONG ReturnSize;
   NTSTATUS Status;
   ULONG DiskNumber;
   WCHAR Buffer[MAX_PATH];
@@ -925,12 +944,14 @@ CreatePartitionList (SHORT Left,
   List->Bottom = Bottom;
 
   List->Line = 0;
+  List->Offset = 0;
 
   List->TopDisk = (ULONG)-1;
   List->TopPartition = (ULONG)-1;
 
   List->CurrentDisk = NULL;
   List->CurrentPartition = NULL;
+  List->CurrentPartitionNumber = 0;
 
   InitializeListHead (&List->DiskListHead);
   InitializeListHead (&List->BiosDiskListHead);
@@ -987,6 +1008,7 @@ CreatePartitionList (SHORT Left,
   {
     List->CurrentDisk = NULL;
     List->CurrentPartition = NULL;
+    List->CurrentPartitionNumber = 0;
   }
   else
   {
@@ -998,6 +1020,7 @@ CreatePartitionList (SHORT Left,
     if (IsListEmpty (&List->CurrentDisk->PartListHead))
     {
       List->CurrentPartition = 0;
+      List->CurrentPartitionNumber = 0;
     }
     else
     {
@@ -1005,6 +1028,7 @@ CreatePartitionList (SHORT Left,
         CONTAINING_RECORD (List->CurrentDisk->PartListHead.Flink,
                            PARTENTRY,
                            ListEntry);
+      List->CurrentPartitionNumber = 0;
     }
   }
 
@@ -1094,7 +1118,8 @@ PrintEmptyLine (PPARTLIST List)
 static VOID
 PrintPartitionData (PPARTLIST List,
                     PDISKENTRY DiskEntry,
-                    PPARTENTRY PartEntry)
+                    PPARTENTRY PartEntry,
+                    ULONG PartNumber)
 {
   CHAR LineBuffer[128];
   COORD coPos;
@@ -1150,44 +1175,44 @@ PrintPartitionData (PPARTLIST List,
     }
     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.QuadPart = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 29)) >> 30;
+      PartSize.QuadPart = (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.QuadPart = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 19)) >> 20;
+      PartSize.QuadPart = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 19)) >> 20;
       Unit = MUIGetString(STRING_MB);
     }
     else
     {
-      PartSize.QuadPart = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 9)) >> 10;
+      PartSize.QuadPart = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 9)) >> 10;
       Unit = MUIGetString(STRING_KB);
     }
 
@@ -1195,9 +1220,9 @@ PrintPartitionData (PPARTLIST List,
     {
       sprintf (LineBuffer,
                MUIGetString(STRING_HDDINFOUNK5),
-               (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.u.LowPart,
                Unit);
     }
@@ -1205,8 +1230,8 @@ PrintPartitionData (PPARTLIST List,
     {
       sprintf (LineBuffer,
                "%c%c  %-24s         %6lu %s",
-               (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
-               (PartEntry->DriveLetter == 0) ? '-' : ':',
+               (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber],
+               (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':',
                PartType,
                PartSize.u.LowPart,
                Unit);
@@ -1214,7 +1239,8 @@ PrintPartitionData (PPARTLIST List,
   }
 
   Attribute = (List->CurrentDisk == DiskEntry &&
-               List->CurrentPartition == PartEntry) ?
+               List->CurrentPartition == PartEntry &&
+               List->CurrentPartitionNumber == PartNumber) ?
                FOREGROUND_BLUE | BACKGROUND_WHITE :
                FOREGROUND_WHITE | BACKGROUND_BLUE;
 
@@ -1262,6 +1288,7 @@ PrintDiskData (PPARTLIST List,
   USHORT Height;
   ULARGE_INTEGER DiskSize;
   PCHAR Unit;
+  ULONG i;
 
   Width = List->Right - List->Left - 1;
   Height = List->Bottom - List->Top - 2;
@@ -1341,9 +1368,27 @@ PrintDiskData (PPARTLIST List,
   LIST_FOR_EACH(PartEntry, &DiskEntry->PartListHead, PARTENTRY, ListEntry)
   {
     /* Print disk entry */
-    PrintPartitionData (List,
-                        DiskEntry,
-                        PartEntry);
+    for (i=0; i<4; i++)
+    {
+      if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED ||
+          PartEntry->PartInfo[i].PartitionLength.QuadPart != 0ULL)
+      {
+        PrintPartitionData (List,
+                            DiskEntry,
+                            PartEntry,
+                            i);
+      }
+    }
+
+    /* Print unpartitioned entry */
+    if (PartEntry->Unpartitioned)
+    {
+        PrintPartitionData (List,
+                            DiskEntry,
+                            PartEntry,
+                            0);
+    }
+
   }
 
   /* Print separator line */
@@ -1567,7 +1612,7 @@ SelectPartition(PPARTLIST List, ULONG DiskNumber, ULONG PartitionNumber)
   PPARTENTRY PartEntry;
   PLIST_ENTRY Entry1;
   PLIST_ENTRY Entry2;
-  ULONG i;
+  UCHAR i;
 
   /* Check for empty disks */
   if (IsListEmpty (&List->DiskListHead))
@@ -1592,6 +1637,7 @@ SelectPartition(PPARTLIST List, ULONG DiskNumber, ULONG PartitionNumber)
           {
             List->CurrentDisk = DiskEntry;
             List->CurrentPartition = PartEntry;
+            List->CurrentPartitionNumber = i;
             DrawPartitionList (List);
             return TRUE;
           }
@@ -1613,6 +1659,7 @@ ScrollDownPartitionList (PPARTLIST List)
   PPARTENTRY PartEntry;
   PLIST_ENTRY Entry1;
   PLIST_ENTRY Entry2;
+  UCHAR i;
 
   /* Check for empty disks */
   if (IsListEmpty (&List->DiskListHead))
@@ -1621,7 +1668,30 @@ ScrollDownPartitionList (PPARTLIST List)
   /* Check for next usable entry on current disk */
   if (List->CurrentPartition != NULL)
   {
-    Entry2 = List->CurrentPartition->ListEntry.Flink;
+    Entry2 = &List->CurrentPartition->ListEntry;
+    PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry);
+
+    /* Check if we can move inside primary partitions */
+    for (i = List->CurrentPartitionNumber + 1; i < 4; i++)
+    {
+        if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED)
+            break;
+    }
+
+    if (i == 4)
+    {
+        /* We're out of partitions in the current partition table.
+           Try to move to the next one if possible. */
+        Entry2 = Entry2->Flink;
+    }
+    else
+    {
+        /* Just advance to the next partition */
+        List->CurrentPartitionNumber = i;
+        DrawPartitionList (List);
+        return;
+    }
+
     while (Entry2 != &List->CurrentDisk->PartListHead)
     {
       PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry);
@@ -1629,6 +1699,7 @@ ScrollDownPartitionList (PPARTLIST List)
 //       if (PartEntry->HidePartEntry == FALSE)
       {
         List->CurrentPartition = PartEntry;
+        List->CurrentPartitionNumber = 0;
         DrawPartitionList (List);
         return;
       }
@@ -1653,6 +1724,7 @@ ScrollDownPartitionList (PPARTLIST List)
         {
           List->CurrentDisk = DiskEntry;
           List->CurrentPartition = PartEntry;
+          List->CurrentPartitionNumber = 0;
           DrawPartitionList (List);
           return;
         }
@@ -1673,6 +1745,7 @@ ScrollUpPartitionList (PPARTLIST List)
   PPARTENTRY PartEntry;
   PLIST_ENTRY Entry1;
   PLIST_ENTRY Entry2;
+  UCHAR i;
 
   /* Check for empty disks */
   if (IsListEmpty (&List->DiskListHead))
@@ -1681,7 +1754,28 @@ ScrollUpPartitionList (PPARTLIST List)
   /* check for previous usable entry on current disk */
   if (List->CurrentPartition != NULL)
   {
-    Entry2 = List->CurrentPartition->ListEntry.Blink;
+    Entry2 = &List->CurrentPartition->ListEntry;
+    PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry);
+
+    /* Check if we can move inside primary partitions */
+    if (List->CurrentPartitionNumber > 0)
+    {
+        /* Find a previous partition */
+        for (i = List->CurrentPartitionNumber - 1; i > 0; i--)
+        {
+            if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED)
+                break;
+        }
+
+        /* Move to it and return */
+        List->CurrentPartitionNumber = i;
+        DrawPartitionList (List);
+        return;
+    }
+
+    /* Move to the previous entry */
+    Entry2 = Entry2->Blink;
+
     while (Entry2 != &List->CurrentDisk->PartListHead)
     {
       PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry);
@@ -1689,6 +1783,18 @@ ScrollUpPartitionList (PPARTLIST List)
 //       if (PartEntry->HidePartEntry == FALSE)
       {
         List->CurrentPartition = PartEntry;
+
+        /* Find last existing partition in the table */
+        for (i = 3; i > 0; i--)
+        {
+            if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED)
+                break;
+        }
+
+        /* Move to it */
+        List->CurrentPartitionNumber = i;
+
+        /* Draw partition list and return */
         DrawPartitionList (List);
         return;
       }
@@ -1714,6 +1820,18 @@ ScrollUpPartitionList (PPARTLIST List)
         {
           List->CurrentDisk = DiskEntry;
           List->CurrentPartition = PartEntry;
+
+          /* Find last existing partition in the table */
+          for (i = 3; i > 0; i--)
+          {
+            if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED)
+              break;
+          }
+
+          /* Move to it */
+          List->CurrentPartitionNumber = i;
+
+          /* Draw partition list and return */
           DrawPartitionList (List);
           return;
         }
@@ -1846,6 +1964,8 @@ CreateNewPartition (PPARTLIST List,
     PartEntry->FormatState = Unformatted;
     PartEntry->PartInfo[0].StartingOffset.QuadPart =
       PartEntry->UnpartitionedOffset + DiskEntry->TrackSize;
+    PartEntry->PartInfo[0].HiddenSectors = 
+      (ULONG)(PartEntry->PartInfo[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector);
     PartEntry->PartInfo[0].PartitionLength.QuadPart =
       PartEntry->UnpartitionedLength - DiskEntry->TrackSize;
     PartEntry->PartInfo[0].PartitionType = PARTITION_ENTRY_UNUSED;
@@ -1875,6 +1995,8 @@ CreateNewPartition (PPARTLIST List,
 
       PrevPartEntry->PartInfo[1].StartingOffset.QuadPart =
         PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize;
+      PrevPartEntry->PartInfo[1].HiddenSectors = 
+        (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector);
 
       if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry)
       {
@@ -1901,6 +2023,8 @@ CreateNewPartition (PPARTLIST List,
 
       PrevPartEntry->PartInfo[1].StartingOffset.QuadPart =
         PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize;
+      PrevPartEntry->PartInfo[1].HiddenSectors = 
+        (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector);
 
       if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry)
       {
@@ -1956,6 +2080,8 @@ CreateNewPartition (PPARTLIST List,
     NewPartEntry->FormatState = Unformatted;
     NewPartEntry->PartInfo[0].StartingOffset.QuadPart =
       PartEntry->UnpartitionedOffset + DiskEntry->TrackSize;
+    NewPartEntry->PartInfo[0].HiddenSectors = 
+      (ULONG)(NewPartEntry->PartInfo[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector);
     NewPartEntry->PartInfo[0].PartitionLength.QuadPart =
       PartitionSize - DiskEntry->TrackSize;
     NewPartEntry->PartInfo[0].PartitionType = PARTITION_ENTRY_UNUSED;
@@ -1985,6 +2111,8 @@ CreateNewPartition (PPARTLIST List,
 
       PrevPartEntry->PartInfo[1].StartingOffset.QuadPart =
         NewPartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize;
+      PrevPartEntry->PartInfo[1].HiddenSectors = 
+        (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector);
 
       if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry)
       {
@@ -2011,6 +2139,8 @@ CreateNewPartition (PPARTLIST List,
 
       PrevPartEntry->PartInfo[1].StartingOffset.QuadPart =
         NewPartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize;
+      PrevPartEntry->PartInfo[1].HiddenSectors = 
+        (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector);
 
       if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry)
       {
@@ -2210,12 +2340,15 @@ CheckActiveBootPartition (PPARTLIST List)
 {
   PDISKENTRY DiskEntry;
   PPARTENTRY PartEntry;
+  PLIST_ENTRY ListEntry;
+  UCHAR i;
 
   /* Check for empty disk list */
   if (IsListEmpty (&List->DiskListHead))
   {
     List->ActiveBootDisk = NULL;
     List->ActiveBootPartition = NULL;
+    List->ActiveBootPartitionNumber = 0;
     return;
   }
 
@@ -2237,6 +2370,7 @@ CheckActiveBootPartition (PPARTLIST List)
   {
     List->ActiveBootDisk = NULL;
     List->ActiveBootPartition = NULL;
+    List->ActiveBootPartitionNumber = 0;
     return;
   }
 
@@ -2254,11 +2388,51 @@ CheckActiveBootPartition (PPARTLIST List)
     PartEntry->PartInfo[0].BootIndicator = TRUE;
     PartEntry->PartInfo[0].RewritePartition = TRUE;
     DiskEntry->Modified = TRUE;
+
+    /* FIXME: Might be incorrect if partitions were created by Linux FDISK */
+    List->ActiveBootDisk = DiskEntry;
+    List->ActiveBootPartition = PartEntry;
+    List->ActiveBootPartitionNumber = 0;
+
+    return;
   }
 
-  /* FIXME: Might be incorrect if partitions were created by Linux FDISK */
-  List->ActiveBootDisk = DiskEntry;
-  List->ActiveBootPartition = PartEntry;
+  /* Disk is not new, scan all partitions to find a bootable one */
+  List->ActiveBootDisk = NULL;
+  List->ActiveBootPartition = NULL;
+  List->ActiveBootPartitionNumber = 0;
+
+  ListEntry = DiskEntry->PartListHead.Flink;
+  while (ListEntry != &DiskEntry->PartListHead)
+  {
+    PartEntry = CONTAINING_RECORD(ListEntry,
+                                  PARTENTRY,
+                                  ListEntry);
+
+    /* Check if it's partitioned */
+    if (!PartEntry->Unpartitioned)
+    {
+      /* Go through all of its 4 partitions */
+      for (i=0; i<4; i++)
+      {
+        if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED &&
+            PartEntry->PartInfo[i].BootIndicator)
+        {
+          /* Yes, we found it */
+          List->ActiveBootDisk = DiskEntry;
+          List->ActiveBootPartition = PartEntry;
+          List->ActiveBootPartitionNumber = i;
+
+          DPRINT("Found bootable partition disk %d, drive letter %c\n",
+              DiskEntry->BiosDiskNumber, PartEntry->DriveLetter[i]);
+
+          break;
+        }
+      }
+    }
+    /* Go to the next one */
+    ListEntry = ListEntry->Flink;
+  }
 }
 
 
@@ -2321,7 +2495,6 @@ WritePartitionsToDisk (PPARTLIST List)
   PDRIVE_LAYOUT_INFORMATION DriveLayout;
   OBJECT_ATTRIBUTES ObjectAttributes;
   IO_STATUS_BLOCK Iosb;
-  WCHAR SrcPath[MAX_PATH];
   WCHAR DstPath[MAX_PATH];
   UNICODE_STRING Name;
   HANDLE FileHandle;
@@ -2515,29 +2688,6 @@ WritePartitionsToDisk (PPARTLIST List)
                    DriveLayout);
 
       NtClose (FileHandle);
-
-      /* Install MBR code if the disk is new */
-      if (DiskEntry1->NewDisk == TRUE &&
-          DiskEntry1->BiosDiskNumber == 0)
-      {
-        wcscpy (SrcPath, SourceRootPath.Buffer);
-        wcscat (SrcPath, L"\\loader\\dosmbr.bin");
-
-        DPRINT ("Install MBR bootcode: %S ==> %S\n",
-                SrcPath, DstPath);
-
-        /* Install MBR bootcode */
-        Status = InstallMbrBootCodeToDisk (SrcPath,
-                                           DstPath);
-        if (!NT_SUCCESS (Status))
-        {
-          DPRINT1 ("InstallMbrBootCodeToDisk() failed (Status %lx)\n",
-                   Status);
-          return FALSE;
-        }
-
-        DiskEntry1->NewDisk = FALSE;
-      }
     }
 
     Entry1 = Entry1->Flink;
@@ -2551,6 +2701,7 @@ BOOL SetMountedDeviceValues(PPARTLIST List)
   PLIST_ENTRY Entry1, Entry2;
   PDISKENTRY DiskEntry;
   PPARTENTRY PartEntry;
+  UCHAR i;
 
   if (List == NULL)
   {
@@ -2568,11 +2719,17 @@ BOOL SetMountedDeviceValues(PPARTLIST List)
     while (Entry2 != &DiskEntry->PartListHead)
     {
       PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
-      if (!PartEntry->Unpartitioned && PartEntry->DriveLetter)
+      if (!PartEntry->Unpartitioned)
       {
-        if (!SetMountedDeviceValue(PartEntry->DriveLetter, DiskEntry->Signature, PartEntry->PartInfo[0].StartingOffset))
+        for (i=0; i<4; i++)
         {
-          return FALSE;
+          if (PartEntry->DriveLetter[i])
+          {
+            if (!SetMountedDeviceValue(PartEntry->DriveLetter[i], DiskEntry->Signature, PartEntry->PartInfo[i].StartingOffset))
+            {
+              return FALSE;
+            }
+          }
         }
       }
       Entry2 = Entry2->Flink;