[USETUP] Additions for the PartList code.

- Document more some of the fields in the PARTENTRY, DISKETNRY and PARTLIST structures;
- Remove the redundant members "SystemDisk", "OriginalSystemDisk" and "TempDisk" in PARTLIST as these can be consistently deduced from the corresponding (Original)(System)(Temp)Partition members
  (note that we however keep "CurrentDisk" alongside "CurrentPartition", see the comment in the code why we do it so).
- Adjust the rest of the code to take the removal of the redundant members into account. The 2nd parameter of GetNextUnformattedPartition() and GetNextUncheckedPartition() is now really optional.
- Introduce a SetPartitionType() helper to simplify the code that sets the partition type, which also automatically adjusts other internal variables of said partition in accordance.
- "Mounted" logical drives can have assigned letters too, registered in \DosDevices\.

svn path=/branches/setup_improvements/; revision=74532
This commit is contained in:
Hermès Bélusca-Maïto 2017-05-13 16:40:30 +00:00
parent eaf7d6ebbe
commit 2521d3c478
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
3 changed files with 176 additions and 98 deletions

View file

@ -700,10 +700,28 @@ AddPartitionToDisk(
if (IsContainerPartition(PartEntry->PartitionType)) if (IsContainerPartition(PartEntry->PartitionType))
{ {
PartEntry->FormatState = Unformatted; PartEntry->FormatState = Unformatted;
PartEntry->FileSystem = NULL;
if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL) if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
DiskEntry->ExtendedPartition = PartEntry; DiskEntry->ExtendedPartition = PartEntry;
} }
#if 0
else if (IsRecognizedPartition(PartEntry->PartitionType))
{
// FIXME FIXME! We should completely rework how we get this 'FileSystemList' available...
PartEntry->FileSystem = GetFileSystem(FileSystemList, PartEntry);
if (!PartEntry->FileSystem)
PartEntry->FormatState = Preformatted;
else
PartEntry->FormatState = Unformatted;
// PartEntry->FormatState = UnknownFormat;
}
else
{
/* Unknown partition, so unknown partition format (may or may not be actually formatted) */
PartEntry->FormatState = UnknownFormat;
}
#endif
else if ((PartEntry->PartitionType == PARTITION_FAT_12) || else if ((PartEntry->PartitionType == PARTITION_FAT_12) ||
(PartEntry->PartitionType == PARTITION_FAT_16) || (PartEntry->PartitionType == PARTITION_FAT_16) ||
(PartEntry->PartitionType == PARTITION_HUGE) || (PartEntry->PartitionType == PARTITION_HUGE) ||
@ -806,6 +824,7 @@ ScanForUnpartitionedDiskSpace(
DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
NewPartEntry->FormatState = Unformatted; NewPartEntry->FormatState = Unformatted;
NewPartEntry->FileSystem = NULL;
InsertTailList(&DiskEntry->PrimaryPartListHead, InsertTailList(&DiskEntry->PrimaryPartListHead,
&NewPartEntry->ListEntry); &NewPartEntry->ListEntry);
@ -852,6 +871,7 @@ ScanForUnpartitionedDiskSpace(
DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
NewPartEntry->FormatState = Unformatted; NewPartEntry->FormatState = Unformatted;
NewPartEntry->FileSystem = NULL;
/* Insert the table into the list */ /* Insert the table into the list */
InsertTailList(&PartEntry->ListEntry, InsertTailList(&PartEntry->ListEntry,
@ -892,6 +912,7 @@ ScanForUnpartitionedDiskSpace(
DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
NewPartEntry->FormatState = Unformatted; NewPartEntry->FormatState = Unformatted;
NewPartEntry->FileSystem = NULL;
/* Append the table to the list */ /* Append the table to the list */
InsertTailList(&DiskEntry->PrimaryPartListHead, InsertTailList(&DiskEntry->PrimaryPartListHead,
@ -924,6 +945,7 @@ ScanForUnpartitionedDiskSpace(
DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
NewPartEntry->FormatState = Unformatted; NewPartEntry->FormatState = Unformatted;
NewPartEntry->FileSystem = NULL;
InsertTailList(&DiskEntry->LogicalPartListHead, InsertTailList(&DiskEntry->LogicalPartListHead,
&NewPartEntry->ListEntry); &NewPartEntry->ListEntry);
@ -971,6 +993,7 @@ ScanForUnpartitionedDiskSpace(
DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
NewPartEntry->FormatState = Unformatted; NewPartEntry->FormatState = Unformatted;
NewPartEntry->FileSystem = NULL;
/* Insert the table into the list */ /* Insert the table into the list */
InsertTailList(&PartEntry->ListEntry, InsertTailList(&PartEntry->ListEntry,
@ -1012,6 +1035,7 @@ ScanForUnpartitionedDiskSpace(
DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
NewPartEntry->FormatState = Unformatted; NewPartEntry->FormatState = Unformatted;
NewPartEntry->FileSystem = NULL;
/* Append the table to the list */ /* Append the table to the list */
InsertTailList(&DiskEntry->LogicalPartListHead, InsertTailList(&DiskEntry->LogicalPartListHead,
@ -1158,6 +1182,11 @@ AddDiskToList(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return; return;
/*
* Check whether the disk is initialized, by looking at its MBR.
* NOTE that this must be generalized to GPT disks as well!
*/
Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(ProcessHeap, Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(ProcessHeap,
0, 0,
DiskGeometry.BytesPerSector); DiskGeometry.BytesPerSector);
@ -1207,6 +1236,7 @@ AddDiskToList(
DiskEntry->BiosFound = FALSE; DiskEntry->BiosFound = FALSE;
/* Check if this disk has a valid MBR */ /* Check if this disk has a valid MBR */
// FIXME: Check for the MBR signature as well, etc...
if (Mbr->BootCode[0] == 0 && Mbr->BootCode[1] == 0) if (Mbr->BootCode[0] == 0 && Mbr->BootCode[1] == 0)
DiskEntry->NoMbr = TRUE; DiskEntry->NoMbr = TRUE;
else else
@ -1215,6 +1245,7 @@ AddDiskToList(
/* Free the MBR sector buffer */ /* Free the MBR sector buffer */
RtlFreeHeap(ProcessHeap, 0, Mbr); RtlFreeHeap(ProcessHeap, 0, Mbr);
ListEntry = List->BiosDiskListHead.Flink; ListEntry = List->BiosDiskListHead.Flink;
while (ListEntry != &List->BiosDiskListHead) while (ListEntry != &List->BiosDiskListHead)
{ {
@ -1422,12 +1453,9 @@ CreatePartitionList(
List->CurrentDisk = NULL; List->CurrentDisk = NULL;
List->CurrentPartition = NULL; List->CurrentPartition = NULL;
List->SystemDisk = NULL;
List->SystemPartition = NULL; List->SystemPartition = NULL;
List->OriginalSystemDisk = NULL;
List->OriginalSystemPartition = NULL; List->OriginalSystemPartition = NULL;
List->TempDisk = NULL;
List->TempPartition = NULL; List->TempPartition = NULL;
List->FormatState = Start; List->FormatState = Start;
@ -2739,6 +2767,7 @@ CreatePrimaryPartition(
PartEntry->IsPartitioned = TRUE; PartEntry->IsPartitioned = TRUE;
PartEntry->PartitionType = PARTITION_ENTRY_UNUSED; PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
PartEntry->FormatState = Unformatted; PartEntry->FormatState = Unformatted;
PartEntry->FileSystem = NULL;
PartEntry->AutoCreate = AutoCreate; PartEntry->AutoCreate = AutoCreate;
PartEntry->New = TRUE; PartEntry->New = TRUE;
PartEntry->BootIndicator = FALSE; PartEntry->BootIndicator = FALSE;
@ -2776,6 +2805,7 @@ CreatePrimaryPartition(
NewPartEntry->New = TRUE; NewPartEntry->New = TRUE;
NewPartEntry->FormatState = Unformatted; NewPartEntry->FormatState = Unformatted;
NewPartEntry->FileSystem = NULL;
NewPartEntry->BootIndicator = FALSE; NewPartEntry->BootIndicator = FALSE;
PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart; PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart;
@ -2818,6 +2848,7 @@ AddLogicalDiskSpace(
DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
NewPartEntry->FormatState = Unformatted; NewPartEntry->FormatState = Unformatted;
NewPartEntry->FileSystem = NULL;
InsertTailList(&DiskEntry->LogicalPartListHead, InsertTailList(&DiskEntry->LogicalPartListHead,
&NewPartEntry->ListEntry); &NewPartEntry->ListEntry);
@ -2854,7 +2885,8 @@ CreateExtendedPartition(
/* Convert current entry to 'new (unformatted)' */ /* Convert current entry to 'new (unformatted)' */
PartEntry->IsPartitioned = TRUE; PartEntry->IsPartitioned = TRUE;
PartEntry->FormatState = Formatted; PartEntry->FormatState = Formatted; // FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container)
PartEntry->FileSystem = NULL;
PartEntry->AutoCreate = FALSE; PartEntry->AutoCreate = FALSE;
PartEntry->New = FALSE; PartEntry->New = FALSE;
PartEntry->BootIndicator = FALSE; PartEntry->BootIndicator = FALSE;
@ -2899,7 +2931,8 @@ CreateExtendedPartition(
NewPartEntry->StartSector.QuadPart; NewPartEntry->StartSector.QuadPart;
NewPartEntry->New = FALSE; NewPartEntry->New = FALSE;
NewPartEntry->FormatState = Formatted; NewPartEntry->FormatState = Formatted; // FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container)
NewPartEntry->FileSystem = NULL;
NewPartEntry->BootIndicator = FALSE; NewPartEntry->BootIndicator = FALSE;
if (NewPartEntry->StartSector.QuadPart < 1450560) if (NewPartEntry->StartSector.QuadPart < 1450560)
@ -2967,6 +3000,7 @@ CreateLogicalPartition(
PartEntry->IsPartitioned = TRUE; PartEntry->IsPartitioned = TRUE;
PartEntry->PartitionType = PARTITION_ENTRY_UNUSED; PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
PartEntry->FormatState = Unformatted; PartEntry->FormatState = Unformatted;
PartEntry->FileSystem = NULL;
PartEntry->AutoCreate = FALSE; PartEntry->AutoCreate = FALSE;
PartEntry->New = TRUE; PartEntry->New = TRUE;
PartEntry->BootIndicator = FALSE; PartEntry->BootIndicator = FALSE;
@ -3005,6 +3039,7 @@ CreateLogicalPartition(
NewPartEntry->New = TRUE; NewPartEntry->New = TRUE;
NewPartEntry->FormatState = Unformatted; NewPartEntry->FormatState = Unformatted;
NewPartEntry->FileSystem = NULL;
NewPartEntry->BootIndicator = FALSE; NewPartEntry->BootIndicator = FALSE;
NewPartEntry->LogicalPartition = TRUE; NewPartEntry->LogicalPartition = TRUE;
@ -3042,7 +3077,6 @@ DeleteCurrentPartition(
/* Clear the system disk and partition pointers if the system partition is being deleted */ /* Clear the system disk and partition pointers if the system partition is being deleted */
if (List->SystemPartition == List->CurrentPartition) if (List->SystemPartition == List->CurrentPartition)
{ {
List->SystemDisk = NULL;
List->SystemPartition = NULL; List->SystemPartition = NULL;
} }
@ -3122,6 +3156,7 @@ DeleteCurrentPartition(
PartEntry->IsPartitioned = FALSE; PartEntry->IsPartitioned = FALSE;
PartEntry->PartitionType = PARTITION_ENTRY_UNUSED; PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
PartEntry->FormatState = Unformatted; PartEntry->FormatState = Unformatted;
PartEntry->FileSystem = NULL;
PartEntry->DriveLetter = 0; PartEntry->DriveLetter = 0;
} }
@ -3148,9 +3183,7 @@ CheckActiveSystemPartition(
/* Check for empty disk list */ /* Check for empty disk list */
if (IsListEmpty(&List->DiskListHead)) if (IsListEmpty(&List->DiskListHead))
{ {
List->SystemDisk = NULL;
List->SystemPartition = NULL; List->SystemPartition = NULL;
List->OriginalSystemDisk = NULL;
List->OriginalSystemPartition = NULL; List->OriginalSystemPartition = NULL;
return; return;
} }
@ -3161,35 +3194,31 @@ CheckActiveSystemPartition(
/* Check for empty partition list */ /* Check for empty partition list */
if (IsListEmpty(&DiskEntry->PrimaryPartListHead)) if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
{ {
List->SystemDisk = NULL;
List->SystemPartition = NULL; List->SystemPartition = NULL;
List->OriginalSystemDisk = NULL;
List->OriginalSystemPartition = NULL; List->OriginalSystemPartition = NULL;
return; return;
} }
if (List->SystemDisk != NULL && List->SystemPartition != NULL) if (List->SystemPartition != NULL)
{ {
/* We already have an active system partition */ /* We already have an active system partition */
DPRINT1("Use the current system partition %lu in disk %lu, drive letter %c\n", DPRINT1("Use the current system partition %lu in disk %lu, drive letter %c\n",
List->SystemPartition->PartitionNumber, List->SystemPartition->PartitionNumber,
List->SystemDisk->DiskNumber, List->SystemPartition->DiskEntry->DiskNumber,
(List->SystemPartition->DriveLetter == 0) ? '-' : List->SystemPartition->DriveLetter); (List->SystemPartition->DriveLetter == 0) ? '-' : List->SystemPartition->DriveLetter);
return; return;
} }
DPRINT1("We are here (1)!\n"); DPRINT1("We are here (1)!\n");
List->SystemDisk = NULL;
List->SystemPartition = NULL; List->SystemPartition = NULL;
List->OriginalSystemDisk = NULL;
List->OriginalSystemPartition = NULL; List->OriginalSystemPartition = NULL;
/* Retrieve the first partition of the disk */ /* Retrieve the first partition of the disk */
PartEntry = CONTAINING_RECORD(DiskEntry->PrimaryPartListHead.Flink, PartEntry = CONTAINING_RECORD(DiskEntry->PrimaryPartListHead.Flink,
PARTENTRY, PARTENTRY,
ListEntry); ListEntry);
List->SystemDisk = DiskEntry; ASSERT(DiskEntry == PartEntry->DiskEntry);
List->SystemPartition = PartEntry; List->SystemPartition = PartEntry;
// //
@ -3201,16 +3230,14 @@ CheckActiveSystemPartition(
{ {
if (PartEntry->PartitionType == PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator == FALSE) if (PartEntry->PartitionType == PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator == FALSE)
{ {
/* FIXME: Might be incorrect if partitions were created by Linux FDISK */ ASSERT(DiskEntry == PartEntry->DiskEntry);
List->SystemDisk = DiskEntry;
List->SystemPartition = PartEntry; List->SystemPartition = PartEntry;
List->OriginalSystemDisk = List->SystemDisk;
List->OriginalSystemPartition = List->SystemPartition; List->OriginalSystemPartition = List->SystemPartition;
DPRINT1("Use new first active system partition %lu in disk %lu, drive letter %c\n", DPRINT1("Use new first active system partition %lu in disk %lu, drive letter %c\n",
List->SystemPartition->PartitionNumber, List->SystemPartition->PartitionNumber,
List->SystemDisk->DiskNumber, List->SystemPartition->DiskEntry->DiskNumber,
(List->SystemPartition->DriveLetter == 0) ? '-' : List->SystemPartition->DriveLetter); (List->SystemPartition->DriveLetter == 0) ? '-' : List->SystemPartition->DriveLetter);
goto SetSystemPartition; goto SetSystemPartition;
@ -3249,22 +3276,18 @@ CheckActiveSystemPartition(
* OK we haven't encountered any used and active partition, * OK we haven't encountered any used and active partition,
* so use the first one as the system partition. * so use the first one as the system partition.
*/ */
ASSERT(DiskEntry == List->SystemPartition->DiskEntry);
/* FIXME: Might be incorrect if partitions were created by Linux FDISK */
List->OriginalSystemDisk = List->SystemDisk; // DiskEntry
List->OriginalSystemPartition = List->SystemPartition; // First PartEntry List->OriginalSystemPartition = List->SystemPartition; // First PartEntry
DPRINT1("Use first active system partition %lu in disk %lu, drive letter %c\n", DPRINT1("Use first active system partition %lu in disk %lu, drive letter %c\n",
List->SystemPartition->PartitionNumber, List->SystemPartition->PartitionNumber,
List->SystemDisk->DiskNumber, List->SystemPartition->DiskEntry->DiskNumber,
(List->SystemPartition->DriveLetter == 0) ? '-' : List->SystemPartition->DriveLetter); (List->SystemPartition->DriveLetter == 0) ? '-' : List->SystemPartition->DriveLetter);
goto SetSystemPartition; goto SetSystemPartition;
} }
List->SystemDisk = NULL;
List->SystemPartition = NULL; List->SystemPartition = NULL;
List->OriginalSystemDisk = NULL;
List->OriginalSystemPartition = NULL; List->OriginalSystemPartition = NULL;
DPRINT1("We are here (3)!\n"); DPRINT1("We are here (3)!\n");
@ -3287,7 +3310,7 @@ CheckActiveSystemPartition(
if (PartEntry->BootIndicator) if (PartEntry->BootIndicator)
{ {
/* Yes, we found it */ /* Yes, we found it */
List->SystemDisk = DiskEntry; ASSERT(DiskEntry == PartEntry->DiskEntry);
List->SystemPartition = PartEntry; List->SystemPartition = PartEntry;
DPRINT1("Found active system partition %lu in disk %lu, drive letter %c\n", DPRINT1("Found active system partition %lu in disk %lu, drive letter %c\n",
@ -3300,15 +3323,14 @@ CheckActiveSystemPartition(
} }
/* Check if we have found the system partition */ /* Check if we have found the system partition */
if (List->SystemDisk == NULL || List->SystemPartition == NULL) if (List->SystemPartition == NULL)
{ {
/* Nothing, use the alternative system partition */ /* Nothing, use the alternative system partition */
DPRINT1("No system partition found, use the alternative partition!\n"); DPRINT1("No system partition found, use the alternative partition!\n");
goto UseAlternativeSystemPartition; goto UseAlternativeSystemPartition;
} }
/* Save them */ /* Save it */
List->OriginalSystemDisk = List->SystemDisk;
List->OriginalSystemPartition = List->SystemPartition; List->OriginalSystemPartition = List->SystemPartition;
/* /*
@ -3332,7 +3354,7 @@ CheckActiveSystemPartition(
{ {
DPRINT1("System partition %lu in disk %lu with no FS?!\n", DPRINT1("System partition %lu in disk %lu with no FS?!\n",
List->OriginalSystemPartition->PartitionNumber, List->OriginalSystemPartition->PartitionNumber,
List->OriginalSystemDisk->DiskNumber); List->OriginalSystemPartition->DiskEntry->DiskNumber);
goto FindAndUseAlternativeSystemPartition; goto FindAndUseAlternativeSystemPartition;
} }
// HACK: WARNING: We cannot write on this FS yet! // HACK: WARNING: We cannot write on this FS yet!
@ -3347,7 +3369,7 @@ CheckActiveSystemPartition(
DPRINT1("Use existing active system partition %lu in disk %lu, drive letter %c\n", DPRINT1("Use existing active system partition %lu in disk %lu, drive letter %c\n",
List->SystemPartition->PartitionNumber, List->SystemPartition->PartitionNumber,
List->SystemDisk->DiskNumber, List->SystemPartition->DiskEntry->DiskNumber,
(List->SystemPartition->DriveLetter == 0) ? '-' : List->SystemPartition->DriveLetter); (List->SystemPartition->DriveLetter == 0) ? '-' : List->SystemPartition->DriveLetter);
return; return;
@ -3364,25 +3386,24 @@ FindAndUseAlternativeSystemPartition:
/* Unset the old system partition */ /* Unset the old system partition */
List->SystemPartition->BootIndicator = FALSE; List->SystemPartition->BootIndicator = FALSE;
List->SystemDisk->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].BootIndicator = FALSE; List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].BootIndicator = FALSE;
List->SystemDisk->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].RewritePartition = TRUE; List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].RewritePartition = TRUE;
List->SystemDisk->Dirty = TRUE; List->SystemPartition->DiskEntry->Dirty = TRUE;
UseAlternativeSystemPartition: UseAlternativeSystemPartition:
List->SystemDisk = List->CurrentDisk;
List->SystemPartition = List->CurrentPartition; List->SystemPartition = List->CurrentPartition;
DPRINT1("Use alternative active system partition %lu in disk %lu, drive letter %c\n", DPRINT1("Use alternative active system partition %lu in disk %lu, drive letter %c\n",
List->SystemPartition->PartitionNumber, List->SystemPartition->PartitionNumber,
List->SystemDisk->DiskNumber, List->SystemPartition->DiskEntry->DiskNumber,
(List->SystemPartition->DriveLetter == 0) ? '-' : List->SystemPartition->DriveLetter); (List->SystemPartition->DriveLetter == 0) ? '-' : List->SystemPartition->DriveLetter);
SetSystemPartition: SetSystemPartition:
/* Set the new active system partition */ /* Set the new active system partition */
List->SystemPartition->BootIndicator = TRUE; List->SystemPartition->BootIndicator = TRUE;
List->SystemDisk->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].BootIndicator = TRUE; List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].BootIndicator = TRUE;
List->SystemDisk->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].RewritePartition = TRUE; List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].RewritePartition = TRUE;
List->SystemDisk->Dirty = TRUE; List->SystemPartition->DiskEntry->Dirty = TRUE;
} }
@ -3449,6 +3470,16 @@ WritePartitions(
if (FileHandle != NULL) if (FileHandle != NULL)
NtClose(FileHandle); NtClose(FileHandle);
//
// NOTE: Originally (see r40437), we used to install here also a new MBR
// for this disk (by calling InstallMbrBootCodeToDisk), only if:
// DiskEntry->NewDisk == TRUE and DiskEntry->BiosDiskNumber == 0.
// Then after that, both DiskEntry->NewDisk and DiskEntry->NoMbr were set
// to FALSE. In the other place (in usetup.c) where InstallMbrBootCodeToDisk
// was called too, the installation test was modified by checking whether
// DiskEntry->NoMbr was TRUE (instead of NewDisk).
//
return Status; return Status;
} }
@ -3522,12 +3553,47 @@ SetMountedDeviceValues(
Entry2 = Entry2->Flink; Entry2 = Entry2->Flink;
} }
Entry2 = DiskEntry->LogicalPartListHead.Flink;
while (Entry2 != &DiskEntry->LogicalPartListHead)
{
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned)
{
/* Assign a "\DosDevices\#:" mount point to this partition */
if (PartEntry->DriveLetter)
{
StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
if (!SetMountedDeviceValue(PartEntry->DriveLetter,
DiskEntry->LayoutBuffer->Signature,
StartingOffset))
{
return FALSE;
}
}
}
Entry2 = Entry2->Flink;
}
Entry1 = Entry1->Flink; Entry1 = Entry1->Flink;
} }
return TRUE; return TRUE;
} }
VOID
SetPartitionType(
IN PPARTENTRY PartEntry,
IN UCHAR PartitionType)
{
PDISKENTRY DiskEntry = PartEntry->DiskEntry;
PartEntry->PartitionType = PartitionType;
DiskEntry->Dirty = TRUE;
DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartitionType;
DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
}
ULONG ULONG
PrimaryPartitionCreationChecks( PrimaryPartitionCreationChecks(
@ -3618,7 +3684,8 @@ GetNextUnformattedPartition(
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned && PartEntry->New) if (PartEntry->IsPartitioned && PartEntry->New)
{ {
*pDiskEntry = DiskEntry; ASSERT(DiskEntry == PartEntry->DiskEntry);
if (pDiskEntry) *pDiskEntry = DiskEntry;
*pPartEntry = PartEntry; *pPartEntry = PartEntry;
return TRUE; return TRUE;
} }
@ -3632,7 +3699,8 @@ GetNextUnformattedPartition(
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned && PartEntry->New) if (PartEntry->IsPartitioned && PartEntry->New)
{ {
*pDiskEntry = DiskEntry; ASSERT(DiskEntry == PartEntry->DiskEntry);
if (pDiskEntry) *pDiskEntry = DiskEntry;
*pPartEntry = PartEntry; *pPartEntry = PartEntry;
return TRUE; return TRUE;
} }
@ -3643,7 +3711,7 @@ GetNextUnformattedPartition(
Entry1 = Entry1->Flink; Entry1 = Entry1->Flink;
} }
*pDiskEntry = NULL; if (pDiskEntry) *pDiskEntry = NULL;
*pPartEntry = NULL; *pPartEntry = NULL;
return FALSE; return FALSE;
@ -3672,7 +3740,8 @@ GetNextUncheckedPartition(
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
if (PartEntry->NeedsCheck == TRUE) if (PartEntry->NeedsCheck == TRUE)
{ {
*pDiskEntry = DiskEntry; ASSERT(DiskEntry == PartEntry->DiskEntry);
if (pDiskEntry) *pDiskEntry = DiskEntry;
*pPartEntry = PartEntry; *pPartEntry = PartEntry;
return TRUE; return TRUE;
} }
@ -3686,7 +3755,8 @@ GetNextUncheckedPartition(
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
if (PartEntry->NeedsCheck == TRUE) if (PartEntry->NeedsCheck == TRUE)
{ {
*pDiskEntry = DiskEntry; ASSERT(DiskEntry == PartEntry->DiskEntry);
if (pDiskEntry) *pDiskEntry = DiskEntry;
*pPartEntry = PartEntry; *pPartEntry = PartEntry;
return TRUE; return TRUE;
} }
@ -3697,7 +3767,7 @@ GetNextUncheckedPartition(
Entry1 = Entry1->Flink; Entry1 = Entry1->Flink;
} }
*pDiskEntry = NULL; if (pDiskEntry) *pDiskEntry = NULL;
*pPartEntry = NULL; *pPartEntry = NULL;
return FALSE; return FALSE;

View file

@ -51,16 +51,18 @@ typedef struct _PARTENTRY
{ {
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
/* The disk this partition belongs to */
struct _DISKENTRY *DiskEntry; struct _DISKENTRY *DiskEntry;
/* Partition geometry */
ULARGE_INTEGER StartSector; ULARGE_INTEGER StartSector;
ULARGE_INTEGER SectorCount; ULARGE_INTEGER SectorCount;
BOOLEAN BootIndicator; BOOLEAN BootIndicator;
UCHAR PartitionType; UCHAR PartitionType;
ULONG HiddenSectors; ULONG HiddenSectors;
ULONG PartitionNumber; ULONG PartitionNumber; /* Enumerated partition number (primary partitions first -- excluding the extended partition container --, then the logical partitions) */
ULONG PartitionIndex; ULONG PartitionIndex; /* Index in the LayoutBuffer->PartitionEntry[] cached array of the corresponding DiskEntry */
CHAR DriveLetter; CHAR DriveLetter;
@ -75,12 +77,12 @@ typedef struct _PARTENTRY
/* Partition was created automatically */ /* Partition was created automatically */
BOOLEAN AutoCreate; BOOLEAN AutoCreate;
FORMATSTATE FormatState;
/* Partition must be checked */ /* Partition must be checked */
BOOLEAN NeedsCheck; BOOLEAN NeedsCheck;
FORMATSTATE FormatState;
struct _FILE_SYSTEM_ITEM *FileSystem; struct _FILE_SYSTEM_ITEM *FileSystem;
} PARTENTRY, *PPARTENTRY; } PARTENTRY, *PPARTENTRY;
@ -100,6 +102,8 @@ typedef struct _DISKENTRY
{ {
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
/* Disk geometry */
ULONGLONG Cylinders; ULONGLONG Cylinders;
ULONG TracksPerCylinder; ULONG TracksPerCylinder;
ULONG SectorsPerTrack; ULONG SectorsPerTrack;
@ -109,11 +113,13 @@ typedef struct _DISKENTRY
ULONG SectorAlignment; ULONG SectorAlignment;
ULONG CylinderAlignment; ULONG CylinderAlignment;
/* BIOS parameters */
BOOLEAN BiosFound; BOOLEAN BiosFound;
ULONG BiosDiskNumber; ULONG BiosDiskNumber;
// ULONG Signature; // ULONG Signature;
// ULONG Checksum; // ULONG Checksum;
/* SCSI parameters */
ULONG DiskNumber; ULONG DiskNumber;
USHORT Port; USHORT Port;
USHORT Bus; USHORT Bus;
@ -123,12 +129,17 @@ typedef struct _DISKENTRY
BOOLEAN Dirty; BOOLEAN Dirty;
BOOLEAN NewDisk; BOOLEAN NewDisk;
BOOLEAN NoMbr; /* MBR is absent */ BOOLEAN NoMbr; /* MBR is absent */ // See r40437
UNICODE_STRING DriverName; UNICODE_STRING DriverName;
PDRIVE_LAYOUT_INFORMATION LayoutBuffer; PDRIVE_LAYOUT_INFORMATION LayoutBuffer;
// TODO: When adding support for GPT disks:
// Use PDRIVE_LAYOUT_INFORMATION_EX which indicates whether
// the disk is MBR, GPT, or unknown (uninitialized).
// Depending on the style, either use the MBR or GPT partition info.
/* Pointer to the unique extended partition on this disk */
PPARTENTRY ExtendedPartition; PPARTENTRY ExtendedPartition;
LIST_ENTRY PrimaryPartListHead; LIST_ENTRY PrimaryPartListHead;
@ -139,6 +150,7 @@ typedef struct _DISKENTRY
typedef struct _PARTLIST typedef struct _PARTLIST
{ {
/* UI stuff */
SHORT Left; SHORT Left;
SHORT Top; SHORT Top;
SHORT Right; SHORT Right;
@ -147,23 +159,32 @@ typedef struct _PARTLIST
SHORT Line; SHORT Line;
SHORT Offset; SHORT Offset;
/*
* NOTE that when CurrentPartition != NULL, then CurrentPartition->DiskEntry
* must be the same as CurrentDisk. We should however keep the two members
* separated as we can have a current (selected) disk without any current
* partition, if the former does not contain any.
*/
PDISKENTRY CurrentDisk; PDISKENTRY CurrentDisk;
PPARTENTRY CurrentPartition; PPARTENTRY CurrentPartition;
/* The system disk and partition where the boot manager resides */ /*
PDISKENTRY SystemDisk; * The system partition where the boot manager resides.
* The corresponding system disk is obtained via:
* SystemPartition->DiskEntry.
*/
PPARTENTRY SystemPartition; PPARTENTRY SystemPartition;
/* /*
* The original system disk and partition in case we are redefining them * The original system partition in case we are redefining it because
* because we do not have write support on them. * we do not have write support on it.
* Please not that this is partly a HACK and MUST NEVER happen on * Please note that this is partly a HACK and MUST NEVER happen on
* architectures where real system partitions are mandatory (because then * architectures where real system partitions are mandatory (because then
* they are formatted in FAT FS and we support write operation on them). * they are formatted in FAT FS and we support write operation on them).
* The corresponding original system disk is obtained via:
* OriginalSystemPartition->DiskEntry.
*/ */
PDISKENTRY OriginalSystemDisk;
PPARTENTRY OriginalSystemPartition; PPARTENTRY OriginalSystemPartition;
PDISKENTRY TempDisk;
PPARTENTRY TempPartition; PPARTENTRY TempPartition;
FORMATMACHINESTATE FormatState; FORMATMACHINESTATE FormatState;
@ -278,6 +299,11 @@ BOOLEAN
SetMountedDeviceValues( SetMountedDeviceValues(
IN PPARTLIST List); IN PPARTLIST List);
VOID
SetPartitionType(
IN PPARTENTRY PartEntry,
IN UCHAR PartitionType);
ULONG ULONG
PrimaryPartitionCreationChecks( PrimaryPartitionCreationChecks(
IN PPARTLIST List); IN PPARTLIST List);

View file

@ -2657,9 +2657,7 @@ SelectFileSystemPage(PINPUT_RECORD Ir)
/* Find or set the active system partition */ /* Find or set the active system partition */
CheckActiveSystemPartition(PartitionList, FileSystemList); CheckActiveSystemPartition(PartitionList, FileSystemList);
if (PartitionList->SystemPartition == NULL)
if (PartitionList->SystemDisk == NULL ||
PartitionList->SystemPartition == NULL)
{ {
/* FIXME: show an error dialog */ /* FIXME: show an error dialog */
return QUIT_PAGE; return QUIT_PAGE;
@ -2671,7 +2669,6 @@ SelectFileSystemPage(PINPUT_RECORD Ir)
case Start: case Start:
if (PartitionList->CurrentPartition != PartitionList->SystemPartition) if (PartitionList->CurrentPartition != PartitionList->SystemPartition)
{ {
PartitionList->TempDisk = PartitionList->SystemDisk;
PartitionList->TempPartition = PartitionList->SystemPartition; PartitionList->TempPartition = PartitionList->SystemPartition;
PartitionList->TempPartition->NeedsCheck = TRUE; PartitionList->TempPartition->NeedsCheck = TRUE;
@ -2680,7 +2677,6 @@ SelectFileSystemPage(PINPUT_RECORD Ir)
} }
else else
{ {
PartitionList->TempDisk = PartitionList->CurrentDisk;
PartitionList->TempPartition = PartitionList->CurrentPartition; PartitionList->TempPartition = PartitionList->CurrentPartition;
PartitionList->TempPartition->NeedsCheck = TRUE; PartitionList->TempPartition->NeedsCheck = TRUE;
@ -2690,7 +2686,6 @@ SelectFileSystemPage(PINPUT_RECORD Ir)
break; break;
case FormatSystemPartition: case FormatSystemPartition:
PartitionList->TempDisk = PartitionList->CurrentDisk;
PartitionList->TempPartition = PartitionList->CurrentPartition; PartitionList->TempPartition = PartitionList->CurrentPartition;
PartitionList->TempPartition->NeedsCheck = TRUE; PartitionList->TempPartition->NeedsCheck = TRUE;
@ -2700,7 +2695,7 @@ SelectFileSystemPage(PINPUT_RECORD Ir)
case FormatInstallPartition: case FormatInstallPartition:
if (GetNextUnformattedPartition(PartitionList, if (GetNextUnformattedPartition(PartitionList,
&PartitionList->TempDisk, NULL,
&PartitionList->TempPartition)) &PartitionList->TempPartition))
{ {
PartitionList->FormatState = FormatOtherPartition; PartitionList->FormatState = FormatOtherPartition;
@ -2717,7 +2712,7 @@ SelectFileSystemPage(PINPUT_RECORD Ir)
case FormatOtherPartition: case FormatOtherPartition:
if (GetNextUnformattedPartition(PartitionList, if (GetNextUnformattedPartition(PartitionList,
&PartitionList->TempDisk, NULL,
&PartitionList->TempPartition)) &PartitionList->TempPartition))
{ {
PartitionList->FormatState = FormatOtherPartition; PartitionList->FormatState = FormatOtherPartition;
@ -2738,8 +2733,8 @@ SelectFileSystemPage(PINPUT_RECORD Ir)
return QUIT_PAGE; return QUIT_PAGE;
} }
DiskEntry = PartitionList->TempDisk;
PartEntry = PartitionList->TempPartition; PartEntry = PartitionList->TempPartition;
DiskEntry = PartEntry->DiskEntry;
/* Adjust disk size */ /* Adjust disk size */
DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
@ -2970,15 +2965,14 @@ FormatPartitionPage(PINPUT_RECORD Ir)
MUIDisplayPage(FORMAT_PARTITION_PAGE); MUIDisplayPage(FORMAT_PARTITION_PAGE);
if (PartitionList == NULL || if (PartitionList == NULL ||
PartitionList->TempDisk == NULL ||
PartitionList->TempPartition == NULL) PartitionList->TempPartition == NULL)
{ {
/* FIXME: show an error dialog */ /* FIXME: show an error dialog */
return QUIT_PAGE; return QUIT_PAGE;
} }
DiskEntry = PartitionList->TempDisk;
PartEntry = PartitionList->TempPartition; PartEntry = PartitionList->TempPartition;
DiskEntry = PartEntry->DiskEntry;
while (TRUE) while (TRUE)
{ {
@ -3004,7 +2998,7 @@ FormatPartitionPage(PINPUT_RECORD Ir)
if (PartEntry->SectorCount.QuadPart < 8192) if (PartEntry->SectorCount.QuadPart < 8192)
{ {
/* FAT12 CHS partition (disk is smaller than 4.1MB) */ /* FAT12 CHS partition (disk is smaller than 4.1MB) */
PartEntry->PartitionType = PARTITION_FAT_12; SetPartitionType(PartEntry, PARTITION_FAT_12);
} }
else if (PartEntry->StartSector.QuadPart < 1450560) else if (PartEntry->StartSector.QuadPart < 1450560)
{ {
@ -3013,17 +3007,17 @@ FormatPartitionPage(PINPUT_RECORD Ir)
if (PartEntry->SectorCount.QuadPart < 65536) if (PartEntry->SectorCount.QuadPart < 65536)
{ {
/* FAT16 CHS partition (partition size < 32MB) */ /* FAT16 CHS partition (partition size < 32MB) */
PartEntry->PartitionType = PARTITION_FAT_16; SetPartitionType(PartEntry, PARTITION_FAT_16);
} }
else if (PartEntry->SectorCount.QuadPart < 1048576) else if (PartEntry->SectorCount.QuadPart < 1048576)
{ {
/* FAT16 CHS partition (partition size < 512MB) */ /* FAT16 CHS partition (partition size < 512MB) */
PartEntry->PartitionType = PARTITION_HUGE; SetPartitionType(PartEntry, PARTITION_HUGE);
} }
else else
{ {
/* FAT32 CHS partition (partition size >= 512MB) */ /* FAT32 CHS partition (partition size >= 512MB) */
PartEntry->PartitionType = PARTITION_FAT32; SetPartitionType(PartEntry, PARTITION_FAT32);
} }
} }
else else
@ -3033,35 +3027,23 @@ FormatPartitionPage(PINPUT_RECORD Ir)
if (PartEntry->SectorCount.QuadPart < 1048576) if (PartEntry->SectorCount.QuadPart < 1048576)
{ {
/* FAT16 LBA partition (partition size < 512MB) */ /* FAT16 LBA partition (partition size < 512MB) */
PartEntry->PartitionType = PARTITION_XINT13; SetPartitionType(PartEntry, PARTITION_XINT13);
} }
else else
{ {
/* FAT32 LBA partition (partition size >= 512MB) */ /* FAT32 LBA partition (partition size >= 512MB) */
PartEntry->PartitionType = PARTITION_FAT32_XINT13; SetPartitionType(PartEntry, PARTITION_FAT32_XINT13);
} }
} }
DiskEntry->Dirty = TRUE;
DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartEntry->PartitionType;
DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
} }
#if 0 #if 0
else if (wcscmp(PartEntry->FileSystem->FileSystemName, L"EXT2") == 0) else if (wcscmp(PartEntry->FileSystem->FileSystemName, L"EXT2") == 0)
{ {
PartEntry->PartitionType = PARTITION_EXT2; SetPartitionType(PartEntry, PARTITION_EXT2);
DiskEntry->Dirty = TRUE;
DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartEntry->PartitionType;
DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
} }
else if (wcscmp(PartEntry->FileSystem->FileSystemName, L"NTFS") == 0) else if (wcscmp(PartEntry->FileSystem->FileSystemName, L"NTFS") == 0)
{ {
PartEntry->PartitionType = PARTITION_IFS; SetPartitionType(PartEntry, PARTITION_IFS);
DiskEntry->Dirty = TRUE;
DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartEntry->PartitionType;
DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
} }
#endif #endif
else if (!PartEntry->FileSystem->FormatFunc) else if (!PartEntry->FileSystem->FormatFunc)
@ -4284,7 +4266,7 @@ BootLoaderPage(PINPUT_RECORD Ir)
RtlFreeUnicodeString(&SystemRootPath); RtlFreeUnicodeString(&SystemRootPath);
swprintf(PathBuffer, swprintf(PathBuffer,
L"\\Device\\Harddisk%lu\\Partition%lu", L"\\Device\\Harddisk%lu\\Partition%lu",
PartitionList->SystemDisk->DiskNumber, PartitionList->SystemPartition->DiskEntry->DiskNumber,
PartitionList->SystemPartition->PartitionNumber); PartitionList->SystemPartition->PartitionNumber);
RtlCreateUnicodeString(&SystemRootPath, PathBuffer); RtlCreateUnicodeString(&SystemRootPath, PathBuffer);
DPRINT1("SystemRootPath: %wZ\n", &SystemRootPath); DPRINT1("SystemRootPath: %wZ\n", &SystemRootPath);
@ -4557,7 +4539,7 @@ BootLoaderHarddiskMbrPage(PINPUT_RECORD Ir)
/* Step 2: Write the MBR */ /* Step 2: Write the MBR */
swprintf(DestinationDevicePathBuffer, swprintf(DestinationDevicePathBuffer,
L"\\Device\\Harddisk%d\\Partition0", L"\\Device\\Harddisk%d\\Partition0",
PartitionList->SystemDisk->DiskNumber); PartitionList->SystemPartition->DiskEntry->DiskNumber);
wcscpy(SourceMbrPathBuffer, SourceRootPath.Buffer); wcscpy(SourceMbrPathBuffer, SourceRootPath.Buffer);
wcscat(SourceMbrPathBuffer, L"\\loader\\dosmbr.bin"); wcscat(SourceMbrPathBuffer, L"\\loader\\dosmbr.bin");