- Fix a failed partition type assignment, when unpartitioned disk space is converted to an extended partition.
- Rename the extended partition list to logical partition list. 
- Add a pointer to an extended partition to the disk entries. And keep it up-to-date when the primary partition list is built or modified.
- Add the 'Unpartitioned space' partiton entry to the logical partition list when an extended partition has been created.
- Remove all logical partition entries when the coresponding extended partition will be deleted.

svn path=/trunk/; revision=63411
This commit is contained in:
Eric Kohl 2014-05-22 14:55:04 +00:00
parent e849ca97bc
commit f537d6e8e4
2 changed files with 114 additions and 70 deletions

View file

@ -524,7 +524,7 @@ AddPartitionToDisk(
ULONG DiskNumber, ULONG DiskNumber,
PDISKENTRY DiskEntry, PDISKENTRY DiskEntry,
ULONG PartitionIndex, ULONG PartitionIndex,
BOOLEAN ExtendedPartition) BOOLEAN LogicalPartition)
{ {
PPARTITION_INFORMATION PartitionInfo; PPARTITION_INFORMATION PartitionInfo;
PPARTENTRY PartEntry; PPARTENTRY PartEntry;
@ -548,7 +548,7 @@ AddPartitionToDisk(
PartEntry->PartitionType = PartitionInfo->PartitionType; PartEntry->PartitionType = PartitionInfo->PartitionType;
PartEntry->HiddenSectors = PartitionInfo->HiddenSectors; PartEntry->HiddenSectors = PartitionInfo->HiddenSectors;
PartEntry->ExtendedPartition = ExtendedPartition; PartEntry->LogicalPartition = LogicalPartition;
PartEntry->IsPartitioned = TRUE; PartEntry->IsPartitioned = TRUE;
PartEntry->PartitionNumber = PartitionInfo->PartitionNumber; PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
PartEntry->PartitionIndex = PartitionIndex; PartEntry->PartitionIndex = PartitionIndex;
@ -556,6 +556,9 @@ AddPartitionToDisk(
if (IsContainerPartition(PartEntry->PartitionType)) if (IsContainerPartition(PartEntry->PartitionType))
{ {
PartEntry->FormatState = Unformatted; PartEntry->FormatState = Unformatted;
if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
DiskEntry->ExtendedPartition = PartEntry;
} }
else if ((PartEntry->PartitionType == PARTITION_FAT_12) || else if ((PartEntry->PartitionType == PARTITION_FAT_12) ||
(PartEntry->PartitionType == PARTITION_FAT_16) || (PartEntry->PartitionType == PARTITION_FAT_16) ||
@ -613,8 +616,8 @@ AddPartitionToDisk(
PartEntry->FormatState = UnknownFormat; PartEntry->FormatState = UnknownFormat;
} }
if (ExtendedPartition) if (LogicalPartition)
InsertTailList(&DiskEntry->ExtendedPartListHead, InsertTailList(&DiskEntry->LogicalPartListHead,
&PartEntry->ListEntry); &PartEntry->ListEntry);
else else
InsertTailList(&DiskEntry->PrimaryPartListHead, InsertTailList(&DiskEntry->PrimaryPartListHead,
@ -991,7 +994,7 @@ AddDiskToList(
} }
InitializeListHead(&DiskEntry->PrimaryPartListHead); InitializeListHead(&DiskEntry->PrimaryPartListHead);
InitializeListHead(&DiskEntry->ExtendedPartListHead); InitializeListHead(&DiskEntry->LogicalPartListHead);
DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart; DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder; DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
@ -1009,8 +1012,8 @@ AddDiskToList(
DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack; DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
DPRINT("SectorCount %I64u\n", DiskEntry->SectorCount); DPRINT1("SectorCount %I64u\n", DiskEntry->SectorCount);
DPRINT("SectorAlignment %lu\n", DiskEntry->SectorAlignment); DPRINT1("SectorAlignment %lu\n", DiskEntry->SectorAlignment);
DiskEntry->DiskNumber = DiskNumber; DiskEntry->DiskNumber = DiskNumber;
DiskEntry->Port = ScsiAddress.PortNumber; DiskEntry->Port = ScsiAddress.PortNumber;
@ -1228,10 +1231,10 @@ DestroyPartitionList(
RtlFreeHeap(ProcessHeap, 0, PartEntry); RtlFreeHeap(ProcessHeap, 0, PartEntry);
} }
/* Release extended partition list */ /* Release logical partition list */
while (!IsListEmpty(&DiskEntry->ExtendedPartListHead)) while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
{ {
Entry = RemoveHeadList(&DiskEntry->ExtendedPartListHead); Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
RtlFreeHeap(ProcessHeap, 0, PartEntry); RtlFreeHeap(ProcessHeap, 0, PartEntry);
@ -1342,8 +1345,8 @@ PrintPartitionData(
sprintf(LineBuffer, sprintf(LineBuffer,
MUIGetString(STRING_UNPSPACE), MUIGetString(STRING_UNPSPACE),
PartEntry->ExtendedPartition ? " " : "", PartEntry->LogicalPartition ? " " : "",
PartEntry->ExtendedPartition ? "" : " ", PartEntry->LogicalPartition ? "" : " ",
PartSize.u.LowPart, PartSize.u.LowPart,
Unit); Unit);
} }
@ -1410,9 +1413,9 @@ PrintPartitionData(
MUIGetString(STRING_HDDINFOUNK5), MUIGetString(STRING_HDDINFOUNK5),
(PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter, (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
(PartEntry->DriveLetter == 0) ? '-' : ':', (PartEntry->DriveLetter == 0) ? '-' : ':',
PartEntry->ExtendedPartition ? " " : "", PartEntry->LogicalPartition ? " " : "",
PartEntry->PartitionType, PartEntry->PartitionType,
PartEntry->ExtendedPartition ? "" : " ", PartEntry->LogicalPartition ? "" : " ",
PartSize.u.LowPart, PartSize.u.LowPart,
Unit); Unit);
} }
@ -1422,9 +1425,9 @@ PrintPartitionData(
"%c%c %s%-24s%s %6lu %s", "%c%c %s%-24s%s %6lu %s",
(PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter, (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
(PartEntry->DriveLetter == 0) ? '-' : ':', (PartEntry->DriveLetter == 0) ? '-' : ':',
PartEntry->ExtendedPartition ? " " : "", PartEntry->LogicalPartition ? " " : "",
PartType, PartType,
PartEntry->ExtendedPartition ? "" : " ", PartEntry->LogicalPartition ? "" : " ",
PartSize.u.LowPart, PartSize.u.LowPart,
Unit); Unit);
} }
@ -1474,8 +1477,8 @@ PrintDiskData(
PPARTLIST List, PPARTLIST List,
PDISKENTRY DiskEntry) PDISKENTRY DiskEntry)
{ {
PPARTENTRY PrimaryPartEntry, ExtendedPartEntry; PPARTENTRY PrimaryPartEntry, LogicalPartEntry;
PLIST_ENTRY PrimaryEntry, ExtendedEntry; PLIST_ENTRY PrimaryEntry, LogicalEntry;
CHAR LineBuffer[128]; CHAR LineBuffer[128];
COORD coPos; COORD coPos;
DWORD Written; DWORD Written;
@ -1570,16 +1573,16 @@ PrintDiskData(
if (IsContainerPartition(PrimaryPartEntry->PartitionType)) if (IsContainerPartition(PrimaryPartEntry->PartitionType))
{ {
ExtendedEntry = DiskEntry->ExtendedPartListHead.Flink; LogicalEntry = DiskEntry->LogicalPartListHead.Flink;
while (ExtendedEntry != &DiskEntry->ExtendedPartListHead) while (LogicalEntry != &DiskEntry->LogicalPartListHead)
{ {
ExtendedPartEntry = CONTAINING_RECORD(ExtendedEntry, PARTENTRY, ListEntry); LogicalPartEntry = CONTAINING_RECORD(LogicalEntry, PARTENTRY, ListEntry);
PrintPartitionData(List, PrintPartitionData(List,
DiskEntry, DiskEntry,
ExtendedPartEntry); LogicalPartEntry);
ExtendedEntry = ExtendedEntry->Flink; LogicalEntry = LogicalEntry->Flink;
} }
} }
@ -2208,6 +2211,40 @@ DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
} }
static
VOID
AddLogicalDiskSpace(
PDISKENTRY DiskEntry)
{
PPARTENTRY NewPartEntry;
DPRINT1("AddLogicalDiskSpace()\n");
/* Create a partition table entry that represents the empty space in the container partition */
NewPartEntry = RtlAllocateHeap(ProcessHeap,
HEAP_ZERO_MEMORY,
sizeof(PARTENTRY));
if (NewPartEntry == NULL)
return;
NewPartEntry->DiskEntry = DiskEntry;
NewPartEntry->LogicalPartition = TRUE;
NewPartEntry->IsPartitioned = FALSE;
NewPartEntry->StartSector.QuadPart = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorsPerTrack;
NewPartEntry->SectorCount.QuadPart = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorsPerTrack;
DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
NewPartEntry->FormatState = Unformatted;
InsertTailList(&DiskEntry->LogicalPartListHead,
&NewPartEntry->ListEntry);
}
VOID VOID
CreateExtendedPartition( CreateExtendedPartition(
PPARTLIST List, PPARTLIST List,
@ -2217,7 +2254,7 @@ CreateExtendedPartition(
PPARTENTRY PartEntry; PPARTENTRY PartEntry;
PPARTENTRY NewPartEntry; PPARTENTRY NewPartEntry;
DPRINT1("CreatePrimaryPartition(%I64u)\n", SectorCount); DPRINT1("CreateExtendedPartition(%I64u)\n", SectorCount);
if (List == NULL || if (List == NULL ||
List->CurrentDisk == NULL || List->CurrentDisk == NULL ||
@ -2237,12 +2274,24 @@ DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPa
DPRINT1("Convert existing partition entry\n"); DPRINT1("Convert existing partition entry\n");
/* Convert current entry to 'new (unformatted)' */ /* Convert current entry to 'new (unformatted)' */
PartEntry->IsPartitioned = TRUE; PartEntry->IsPartitioned = TRUE;
// PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
PartEntry->FormatState = Formatted; PartEntry->FormatState = Formatted;
PartEntry->AutoCreate = FALSE; PartEntry->AutoCreate = FALSE;
PartEntry->New = FALSE; PartEntry->New = FALSE;
PartEntry->BootIndicator = FALSE; /* FIXME */ PartEntry->BootIndicator = FALSE; /* FIXME */
if (PartEntry->StartSector.QuadPart < 1450560)
{
/* Partition starts below the 8.4GB boundary ==> CHS partition */
PartEntry->PartitionType = PARTITION_EXTENDED;
}
else
{
/* Partition starts above the 8.4GB boundary ==> LBA partition */
PartEntry->PartitionType = PARTITION_XINT13_EXTENDED;
}
DiskEntry->ExtendedPartition = PartEntry;
DPRINT1("First Sector: %I64u\n", PartEntry->StartSector.QuadPart); DPRINT1("First Sector: %I64u\n", PartEntry->StartSector.QuadPart);
DPRINT1("Last Sector: %I64u\n", PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1); DPRINT1("Last Sector: %I64u\n", PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1);
DPRINT1("Total Sectors: %I64u\n", PartEntry->SectorCount.QuadPart); DPRINT1("Total Sectors: %I64u\n", PartEntry->SectorCount.QuadPart);
@ -2269,30 +2318,32 @@ DPRINT1("Add new partition entry\n");
NewPartEntry->SectorCount.QuadPart = Align(NewPartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - NewPartEntry->SectorCount.QuadPart = Align(NewPartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) -
NewPartEntry->StartSector.QuadPart; NewPartEntry->StartSector.QuadPart;
// NewPartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
NewPartEntry->New = FALSE; NewPartEntry->New = FALSE;
NewPartEntry->FormatState = Formatted; NewPartEntry->FormatState = Formatted;
NewPartEntry->BootIndicator = FALSE; /* FIXME */ NewPartEntry->BootIndicator = FALSE; /* FIXME */
if (NewPartEntry->StartSector.QuadPart < 1450560)
{
/* Partition starts below the 8.4GB boundary ==> CHS partition */
NewPartEntry->PartitionType = PARTITION_EXTENDED;
}
else
{
/* Partition starts above the 8.4GB boundary ==> LBA partition */
NewPartEntry->PartitionType = PARTITION_XINT13_EXTENDED;
}
DiskEntry->ExtendedPartition = NewPartEntry;
PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart; PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart;
PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart); PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart);
DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
} }
if (NewPartEntry->StartSector.QuadPart < 1450560) AddLogicalDiskSpace(DiskEntry);
{
/* Partition starts below the 8.4GB boundary ==> CHS partition */
NewPartEntry->PartitionType = PARTITION_EXTENDED;
}
else
{
/* Partition starts above the 8.4GB boundary ==> LBA partition */
NewPartEntry->PartitionType = PARTITION_XINT13_EXTENDED;
}
UpdateDiskLayout(DiskEntry); UpdateDiskLayout(DiskEntry);
@ -2312,6 +2363,8 @@ DeleteCurrentPartition(
PPARTENTRY PartEntry; PPARTENTRY PartEntry;
PPARTENTRY PrevPartEntry; PPARTENTRY PrevPartEntry;
PPARTENTRY NextPartEntry; PPARTENTRY NextPartEntry;
PPARTENTRY LogicalPartEntry;
PLIST_ENTRY Entry;
if (List == NULL || if (List == NULL ||
List->CurrentDisk == NULL || List->CurrentDisk == NULL ||
@ -2324,6 +2377,20 @@ DeleteCurrentPartition(
DiskEntry = List->CurrentDisk; DiskEntry = List->CurrentDisk;
PartEntry = List->CurrentPartition; PartEntry = List->CurrentPartition;
/* Delete all logical partiton entries if an extended partition will be deleted */
if (DiskEntry->ExtendedPartition == PartEntry)
{
while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
{
Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
RtlFreeHeap(ProcessHeap, 0, LogicalPartEntry);
}
DiskEntry->ExtendedPartition = NULL;
}
/* Adjust unpartitioned disk space entries */ /* Adjust unpartitioned disk space entries */
/* Get pointer to previous and next unpartitioned entries */ /* Get pointer to previous and next unpartitioned entries */
@ -2744,30 +2811,6 @@ GetPrimaryPartitionCount(
} }
static
ULONG
GetExtendedPartitionCount(
IN PDISKENTRY DiskEntry)
{
PLIST_ENTRY Entry;
PPARTENTRY PartEntry;
UINT nCount = 0;
Entry = DiskEntry->PrimaryPartListHead.Flink;
while (Entry != &DiskEntry->PrimaryPartListHead)
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned == TRUE &&
IsContainerPartition(PartEntry->PartitionType))
nCount++;
Entry = Entry->Flink;
}
return nCount;
}
ULONG ULONG
PrimaryPartitionCreationChecks( PrimaryPartitionCreationChecks(
IN PPARTLIST List) IN PPARTLIST List)
@ -2786,7 +2829,7 @@ PrimaryPartitionCreationChecks(
if (GetPrimaryPartitionCount(DiskEntry) > 4) if (GetPrimaryPartitionCount(DiskEntry) > 4)
return ERROR_PARTITION_TABLE_FULL; return ERROR_PARTITION_TABLE_FULL;
/* FIXME: Fail if this partiton is located behind an extended partition */ /* Fail if this partiton is located behind an extended partition */
if (IsPreviousPartitionExtended(PartEntry, DiskEntry)) if (IsPreviousPartitionExtended(PartEntry, DiskEntry))
return ERROR_NOT_BEHIND_EXTENDED; return ERROR_NOT_BEHIND_EXTENDED;
@ -2813,7 +2856,7 @@ ExtendedPartitionCreationChecks(
return ERROR_PARTITION_TABLE_FULL; return ERROR_PARTITION_TABLE_FULL;
/* Fail if there is another extended partition in the list */ /* Fail if there is another extended partition in the list */
if (GetExtendedPartitionCount(DiskEntry) != 0) if (DiskEntry->ExtendedPartition != NULL)
return ERROR_ONLY_ONE_EXTENDED; return ERROR_ONLY_ONE_EXTENDED;
/* Fail if the partition is not the last list entry */ /* Fail if the partition is not the last list entry */
@ -2823,5 +2866,4 @@ ExtendedPartitionCreationChecks(
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
/* EOF */ /* EOF */

View file

@ -57,7 +57,7 @@ typedef struct _PARTENTRY
CHAR VolumeLabel[17]; CHAR VolumeLabel[17];
CHAR FileSystemName[9]; CHAR FileSystemName[9];
BOOLEAN ExtendedPartition; BOOLEAN LogicalPartition;
/* Partition is partitioned disk space */ /* Partition is partitioned disk space */
BOOLEAN IsPartitioned; BOOLEAN IsPartitioned;
@ -117,8 +117,10 @@ typedef struct _DISKENTRY
PDRIVE_LAYOUT_INFORMATION LayoutBuffer; PDRIVE_LAYOUT_INFORMATION LayoutBuffer;
PPARTENTRY ExtendedPartition;
LIST_ENTRY PrimaryPartListHead; LIST_ENTRY PrimaryPartListHead;
LIST_ENTRY ExtendedPartListHead; LIST_ENTRY LogicalPartListHead;
} DISKENTRY, *PDISKENTRY; } DISKENTRY, *PDISKENTRY;