Replaced partition arrays by a doubly-linked lists.

Display unpartitioned disk space correctly.

svn path=/trunk/; revision=5392
This commit is contained in:
Eric Kohl 2003-08-03 12:20:22 +00:00
parent 922496846f
commit 94880f6c27
2 changed files with 406 additions and 275 deletions

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: partlist.c,v 1.11 2003/08/02 16:49:36 ekohl Exp $ /* $Id: partlist.c,v 1.12 2003/08/03 12:20:22 ekohl Exp $
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup * PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/partlist.c * FILE: subsys/system/usetup/partlist.c
@ -80,120 +80,154 @@ AddPartitionToList (ULONG DiskNumber,
{ {
PPARTENTRY PartEntry; PPARTENTRY PartEntry;
ULONG i; ULONG i;
ULONG EntryCount; ULONG j;
BOOLEAN LastEntryWasUnused;
for (i = 0; i < LayoutBuffer->PartitionCount; i += 4)
{
PartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap,
0,
sizeof(PARTENTRY));
if (PartEntry == NULL)
{
return;
}
RtlZeroMemory (PartEntry,
sizeof(PARTENTRY));
PartEntry->DriveLetter = GetDriveLetter(DiskNumber,
LayoutBuffer->PartitionEntry[i].PartitionNumber);
PartEntry->Unpartitioned = FALSE;
for (j = 0; j < 4; j++)
{
RtlCopyMemory (&PartEntry->PartInfo[j],
&LayoutBuffer->PartitionEntry[i+j],
sizeof(PARTITION_INFORMATION));
}
InsertTailList (&DiskEntry->PartListHead,
&PartEntry->ListEntry);
}
}
static VOID
ScanForUnpartitionedDiskSpace (PDISKENTRY DiskEntry)
{
ULONGLONG LastStartingOffset; ULONGLONG LastStartingOffset;
ULONGLONG LastPartitionSize; ULONGLONG LastPartitionLength;
ULONGLONG LastUnusedPartitionSize; ULONGLONG LastUnusedPartitionLength;
ULONG LastUnusedEntry; PPARTENTRY PartEntry;
PPARTENTRY NewPartEntry;
PLIST_ENTRY Entry;
ULONG i;
ULONG j;
/* if (IsListEmpty (&DiskEntry->PartListHead))
* FIXME:
* Determine required number of partiton entries.
* This must include entries for unused disk space.
*/
/* Check for unpartitioned disk */
if (LayoutBuffer->PartitionCount == 0)
{ {
EntryCount = 1; /* Create a partition table that represents the empty disk */
} PartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap,
else 0,
{ sizeof(PARTENTRY));
EntryCount = LayoutBuffer->PartitionCount; if (PartEntry == NULL)
} return;
RtlZeroMemory (PartEntry,
DiskEntry->PartArray = (PPARTENTRY)RtlAllocateHeap(ProcessHeap, sizeof(PARTENTRY));
0,
EntryCount * sizeof(PARTENTRY));
DiskEntry->PartCount = EntryCount;
RtlZeroMemory(DiskEntry->PartArray,
EntryCount * sizeof(PARTENTRY));
if (LayoutBuffer->PartitionCount == 0)
{
/* Initialize an 'Unpartitioned space' entry */
PartEntry = &DiskEntry->PartArray[0];
PartEntry->Unpartitioned = TRUE; PartEntry->Unpartitioned = TRUE;
// Start partition at head 1, cylinder 0 PartEntry->UnpartitionedOffset = 0ULL;
PartEntry->StartingOffset = DiskEntry->SectorsPerTrack * DiskEntry->BytesPerSector; PartEntry->UnpartitionedLength = DiskEntry->DiskSize;
PartEntry->PartSize = DiskEntry->DiskSize - PartEntry->StartingOffset;
PartEntry->Used = FALSE; InsertTailList (&DiskEntry->PartListHead,
PartEntry->HidePartEntry = FALSE; &PartEntry->ListEntry);
PartEntry->PartNumber = 1;
} }
else else
{ {
LastEntryWasUnused = FALSE; /* Start partition at head 1, cylinder 0 */
// Start partition at head 1, cylinder 0 LastStartingOffset = DiskEntry->TrackSize;
LastStartingOffset = DiskEntry->SectorsPerTrack * DiskEntry->BytesPerSector; LastPartitionLength = 0ULL;
LastPartitionSize = 0; LastUnusedPartitionLength = 0ULL;
LastUnusedEntry = -1;
LastUnusedPartitionSize = 0; i = 0;
for (i = 0; i < LayoutBuffer->PartitionCount; i++) Entry = DiskEntry->PartListHead.Flink;
while (Entry != &DiskEntry->PartListHead)
{ {
PartEntry = &DiskEntry->PartArray[i]; PartEntry = CONTAINING_RECORD (Entry, PARTENTRY, ListEntry);
if ((LayoutBuffer->PartitionEntry[i].PartitionType != PARTITION_ENTRY_UNUSED) && for (j = 0; j < 4; j++)
(!IsContainerPartition(LayoutBuffer->PartitionEntry[i].PartitionType)))
{ {
LastUnusedPartitionSize = LayoutBuffer->PartitionEntry[i].StartingOffset.QuadPart if ((!IsContainerPartition(PartEntry->PartInfo[j].PartitionType)) &&
- (LastStartingOffset + LastPartitionSize); (PartEntry->PartInfo[j].PartitionType != PARTITION_ENTRY_UNUSED ||
if (LastUnusedEntry != -1) PartEntry->PartInfo[j].PartitionLength.QuadPart != 0LL))
{ {
DiskEntry->PartArray[LastUnusedEntry].StartingOffset = LastStartingOffset + LastPartitionSize; LastUnusedPartitionLength =
DiskEntry->PartArray[LastUnusedEntry].PartSize = LastUnusedPartitionSize; PartEntry->PartInfo[j].StartingOffset.QuadPart -
DiskEntry->PartArray[LastUnusedEntry].PartNumber = LastUnusedEntry + 1; /* FIXME: Is this always correct? */ (LastStartingOffset + LastPartitionLength);
}
LastStartingOffset = LayoutBuffer->PartitionEntry[i].StartingOffset.QuadPart;
LastPartitionSize = LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart;
PartEntry->StartingOffset = LayoutBuffer->PartitionEntry[i].StartingOffset.QuadPart; if (LastUnusedPartitionLength >= DiskEntry->CylinderSize)
PartEntry->PartSize = LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart; {
PartEntry->PartNumber = LayoutBuffer->PartitionEntry[i].PartitionNumber, DPRINT ("Unpartitioned disk space %I64u\n", LastUnusedPartitionLength);
PartEntry->PartType = LayoutBuffer->PartitionEntry[i].PartitionType;
PartEntry->Active = LayoutBuffer->PartitionEntry[i].BootIndicator;
PartEntry->DriveLetter = GetDriveLetter(DiskNumber, NewPartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap,
LayoutBuffer->PartitionEntry[i].PartitionNumber); 0,
sizeof(PARTENTRY));
if (NewPartEntry == NULL)
return;
PartEntry->Unpartitioned = FALSE; RtlZeroMemory (NewPartEntry,
sizeof(PARTENTRY));
PartEntry->Used = TRUE; NewPartEntry->Unpartitioned = TRUE;
PartEntry->HidePartEntry = FALSE; NewPartEntry->UnpartitionedOffset = LastStartingOffset + LastPartitionLength;
LastEntryWasUnused = FALSE; NewPartEntry->UnpartitionedLength = LastUnusedPartitionLength;
LastUnusedEntry = -1; if (j == 0)
NewPartEntry->UnpartitionedLength -= DiskEntry->TrackSize;
/* Insert the table into the list */
InsertTailList (&PartEntry->ListEntry,
&NewPartEntry->ListEntry);
}
LastStartingOffset = PartEntry->PartInfo[j].StartingOffset.QuadPart;
LastPartitionLength = PartEntry->PartInfo[j].PartitionLength.QuadPart;
}
} }
else
i += 4;
Entry = Entry->Flink;
}
/* Check for trailing unpartitioned disk space */
if (DiskEntry->DiskSize > (LastStartingOffset + LastPartitionLength))
{
LastUnusedPartitionLength =
DiskEntry->DiskSize - (LastStartingOffset + LastPartitionLength);
if (LastUnusedPartitionLength >= DiskEntry->CylinderSize)
{ {
if (LastEntryWasUnused) DPRINT ("Unpartitioned disk space %I64u\n", LastUnusedPartitionLength);
{
/* Group unused entries into one unpartitioned disk space area */
PartEntry->HidePartEntry = TRUE;
PartEntry->PartSize = 0;
}
else
{
LastUnusedEntry = i;
}
PartEntry->Unpartitioned = TRUE; NewPartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap,
0,
sizeof(PARTENTRY));
if (NewPartEntry == NULL)
return;
PartEntry->Used = FALSE; RtlZeroMemory (NewPartEntry,
LastEntryWasUnused = TRUE; sizeof(PARTENTRY));
NewPartEntry->Unpartitioned = TRUE;
NewPartEntry->UnpartitionedOffset = LastStartingOffset + LastPartitionLength;
NewPartEntry->UnpartitionedLength = LastUnusedPartitionLength;
/* Append the table to the list */
InsertTailList (&DiskEntry->PartListHead,
&NewPartEntry->ListEntry);
} }
} }
LastUnusedPartitionSize = DiskEntry->DiskSize
- (LastStartingOffset + LastPartitionSize);
if (LastUnusedEntry != -1)
{
DiskEntry->PartArray[LastUnusedEntry].StartingOffset = LastStartingOffset + LastPartitionSize;
DiskEntry->PartArray[LastUnusedEntry].PartSize = LastUnusedPartitionSize;
DiskEntry->PartArray[LastUnusedEntry].PartNumber = LastUnusedEntry + 1; /* FIXME: Is this always correct? */
}
} }
} }
@ -253,6 +287,8 @@ AddDiskToList (HANDLE FileHandle,
return; return;
} }
InitializeListHead (&DiskEntry->PartListHead);
DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart; DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder; DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack; DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
@ -263,11 +299,19 @@ AddDiskToList (HANDLE FileHandle,
DPRINT("SectorsPerTrack %d\n", DiskEntry->SectorsPerTrack); DPRINT("SectorsPerTrack %d\n", DiskEntry->SectorsPerTrack);
DPRINT("BytesPerSector %d\n", DiskEntry->BytesPerSector); DPRINT("BytesPerSector %d\n", DiskEntry->BytesPerSector);
DiskEntry->DiskSize = DiskEntry->DiskSize =
DiskGeometry.Cylinders.QuadPart * DiskGeometry.Cylinders.QuadPart *
(ULONGLONG)DiskGeometry.TracksPerCylinder * (ULONGLONG)DiskGeometry.TracksPerCylinder *
(ULONGLONG)DiskGeometry.SectorsPerTrack * (ULONGLONG)DiskGeometry.SectorsPerTrack *
(ULONGLONG)DiskGeometry.BytesPerSector; (ULONGLONG)DiskGeometry.BytesPerSector;
DiskEntry->CylinderSize =
(ULONGLONG)DiskGeometry.TracksPerCylinder *
(ULONGLONG)DiskGeometry.SectorsPerTrack *
(ULONGLONG)DiskGeometry.BytesPerSector;
DiskEntry->TrackSize =
(ULONGLONG)DiskGeometry.SectorsPerTrack *
(ULONGLONG)DiskGeometry.BytesPerSector;
DiskEntry->DiskNumber = DiskNumber; DiskEntry->DiskNumber = DiskNumber;
DiskEntry->Port = ScsiAddress.PortNumber; DiskEntry->Port = ScsiAddress.PortNumber;
DiskEntry->Bus = ScsiAddress.PathId; DiskEntry->Bus = ScsiAddress.PathId;
@ -275,7 +319,8 @@ AddDiskToList (HANDLE FileHandle,
GetDriverName (DiskEntry); GetDriverName (DiskEntry);
InsertTailList (&List->DiskList, &DiskEntry->ListEntry); InsertTailList (&List->DiskListHead,
&DiskEntry->ListEntry);
LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap (ProcessHeap, LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap (ProcessHeap,
0, 0,
@ -300,6 +345,8 @@ AddDiskToList (HANDLE FileHandle,
AddPartitionToList (DiskNumber, AddPartitionToList (DiskNumber,
DiskEntry, DiskEntry,
LayoutBuffer); LayoutBuffer);
ScanForUnpartitionedDiskSpace (DiskEntry);
} }
RtlFreeHeap (ProcessHeap, RtlFreeHeap (ProcessHeap,
@ -338,9 +385,9 @@ InitializePartitionList(VOID)
List->TopPartition = (ULONG)-1; List->TopPartition = (ULONG)-1;
List->CurrentDisk = NULL; List->CurrentDisk = NULL;
List->CurrentPartition = (ULONG)-1; List->CurrentPartition = NULL;
InitializeListHead (&List->DiskList); InitializeListHead (&List->DiskListHead);
Status = NtQuerySystemInformation(SystemDeviceInformation, Status = NtQuerySystemInformation(SystemDeviceInformation,
&Sdi, &Sdi,
@ -386,15 +433,23 @@ InitializePartitionList(VOID)
List->TopPartition = 0; List->TopPartition = 0;
/* Search for first usable disk and partition */ /* Search for first usable disk and partition */
if (IsListEmpty (&List->DiskList)) if (IsListEmpty (&List->DiskListHead))
{ {
List->CurrentDisk = NULL; List->CurrentDisk = NULL;
List->CurrentPartition = (ULONG)-1; List->CurrentPartition = NULL;
} }
else else
{ {
List->CurrentDisk = CONTAINING_RECORD(List->DiskList.Flink, DISKENTRY, ListEntry); List->CurrentDisk = CONTAINING_RECORD(List->DiskListHead.Flink, DISKENTRY, ListEntry);
List->CurrentPartition = 0;
if (IsListEmpty (&List->CurrentDisk->PartListHead))
{
List->CurrentPartition = 0;
}
else
{
List->CurrentPartition = CONTAINING_RECORD(List->CurrentDisk->PartListHead.Flink, PARTENTRY, ListEntry);
}
} }
return(List); return(List);
@ -433,7 +488,7 @@ GetPartitionInformation(PPARTLIST List,
PPARTENTRY PartEntry; PPARTENTRY PartEntry;
ULONG i; ULONG i;
if (IsListEmpty(&List->DiskList)) if (IsListEmpty(&List->DiskListHead))
{ {
return NULL; return NULL;
} }
@ -471,8 +526,9 @@ GetPartitionInformation(PPARTLIST List,
VOID VOID
DestroyPartitionList(PPARTLIST List) DestroyPartitionList(PPARTLIST List)
{ {
PLIST_ENTRY Entry;
PDISKENTRY DiskEntry; PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
PLIST_ENTRY Entry;
#if 0 #if 0
COORD coPos; COORD coPos;
USHORT Width; USHORT Width;
@ -495,18 +551,23 @@ DestroyPartitionList(PPARTLIST List)
#endif #endif
/* Release disk and partition info */ /* Release disk and partition info */
while (!IsListEmpty (&List->DiskList)) while (!IsListEmpty (&List->DiskListHead))
{ {
Entry = RemoveHeadList (&List->DiskList); Entry = RemoveHeadList (&List->DiskListHead);
DiskEntry = CONTAINING_RECORD (Entry, DISKENTRY, ListEntry); DiskEntry = CONTAINING_RECORD (Entry, DISKENTRY, ListEntry);
/* Release driver name */ /* Release driver name */
RtlFreeUnicodeString(&DiskEntry->DriverName); RtlFreeUnicodeString(&DiskEntry->DriverName);
/* Release partition array */ /* Release partition array */
if (DiskEntry->PartArray != NULL) while (!IsListEmpty (&DiskEntry->PartListHead))
{ {
RtlFreeHeap(ProcessHeap, 0, DiskEntry->PartArray); Entry = RemoveHeadList (&DiskEntry->PartListHead);
PartEntry = CONTAINING_RECORD (Entry, PARTENTRY, ListEntry);
RtlFreeHeap (ProcessHeap,
0,
PartEntry);
} }
/* Release disk entry */ /* Release disk entry */
@ -552,9 +613,8 @@ PrintEmptyLine(PPARTLIST List)
static VOID static VOID
PrintPartitionData(PPARTLIST List, PrintPartitionData(PPARTLIST List,
PDISKENTRY DiskEntry, PDISKENTRY DiskEntry,
SHORT PartIndex) PPARTENTRY PartEntry)
{ {
PPARTENTRY PartEntry;
CHAR LineBuffer[128]; CHAR LineBuffer[128];
COORD coPos; COORD coPos;
ULONG Written; ULONG Written;
@ -575,91 +635,112 @@ PrintPartitionData(PPARTLIST List,
coPos.X = List->Left + 1; coPos.X = List->Left + 1;
coPos.Y = List->Top + 1 + List->Line; coPos.Y = List->Top + 1 + List->Line;
PartEntry = &DiskEntry->PartArray[PartIndex];
/* Determine partition type */
PartType = NULL;
if (PartEntry->Unpartitioned == FALSE)
{
if ((PartEntry->PartType == PARTITION_FAT_12) ||
(PartEntry->PartType == PARTITION_FAT_16) ||
(PartEntry->PartType == PARTITION_HUGE) ||
(PartEntry->PartType == PARTITION_XINT13))
{
PartType = "FAT";
}
else if ((PartEntry->PartType == PARTITION_FAT32) ||
(PartEntry->PartType == PARTITION_FAT32_XINT13))
{
PartType = "FAT32";
}
else if (PartEntry->PartType == PARTITION_IFS)
{
PartType = "NTFS"; /* FIXME: Not quite correct! */
}
}
#if 0
if (PartEntry->PartSize >= 0x280000000ULL) /* 10 GB */
{
PartSize = (PartEntry->PartSize + (1 << 29)) >> 30;
Unit = "GB";
}
else
#endif
if (PartEntry->PartSize >= 0xA00000ULL) /* 10 MB */
{
PartSize = (PartEntry->PartSize + (1 << 19)) >> 20;
Unit = "MB";
}
else
{
PartSize = (PartEntry->PartSize + (1 << 9)) >> 10;
Unit = "KB";
}
if (PartEntry->Unpartitioned == TRUE) if (PartEntry->Unpartitioned == TRUE)
{ {
#if 0
if (PartEntry->UnpartitionledLength >= 0x280000000ULL) /* 10 GB */
{
PartSize = (PartEntry->UnpartitionedLength + (1 << 29)) >> 30;
Unit = "GB";
}
else
#endif
if (PartEntry->UnpartitionedLength >= 0xA00000ULL) /* 10 MB */
{
PartSize = (PartEntry->UnpartitionedLength + (1 << 19)) >> 20;
Unit = "MB";
}
else
{
PartSize = (PartEntry->UnpartitionedLength + (1 << 9)) >> 10;
Unit = "KB";
}
sprintf(LineBuffer, sprintf(LineBuffer,
" Unpartitioned space %I64u %s", " Unpartitioned space %6I64u %s",
PartSize, PartSize,
Unit); Unit);
} }
else if (PartEntry->DriveLetter != (CHAR)0) else
{ {
if (PartType == NULL)
/* Determine partition type */
PartType = NULL;
if (PartEntry->Unpartitioned == FALSE)
{ {
sprintf(LineBuffer, if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_12) ||
"%c: Type %-3lu %I64u %s", (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_16) ||
PartEntry->DriveLetter, (PartEntry->PartInfo[0].PartitionType == PARTITION_HUGE) ||
PartEntry->PartType, (PartEntry->PartInfo[0].PartitionType == PARTITION_XINT13))
PartSize, {
Unit); PartType = "FAT";
}
else if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32) ||
(PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13))
{
PartType = "FAT32";
}
else if (PartEntry->PartInfo[0].PartitionType == PARTITION_IFS)
{
PartType = "NTFS"; /* FIXME: Not quite correct! */
}
}
#if 0
if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0x280000000ULL) /* 10 GB */
{
PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 29)) >> 30;
Unit = "GB";
}
else
#endif
if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0xA00000ULL) /* 10 MB */
{
PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 19)) >> 20;
Unit = "MB";
}
else
{
PartSize = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 9)) >> 10;
Unit = "KB";
}
if (PartEntry->DriveLetter != (CHAR)0)
{
if (PartType == NULL)
{
sprintf(LineBuffer,
"%c: Type %-3lu %6I64u %s",
PartEntry->DriveLetter,
PartEntry->PartInfo[0].PartitionType,
PartSize,
Unit);
}
else
{
sprintf(LineBuffer,
"%c: %-8s %6I64u %s",
PartEntry->DriveLetter,
PartType,
PartSize,
Unit);
}
} }
else else
{ {
sprintf(LineBuffer, sprintf(LineBuffer,
"%c: %s %I64u %s", "-- %-8s Type %-3lu %6I64u %s",
PartEntry->DriveLetter, PartEntry->FileSystemName,
PartType, PartEntry->PartInfo[0].PartitionType,
PartSize, PartSize,
Unit); Unit);
} }
} }
else
{
sprintf(LineBuffer,
"-- %s Type -3lu %I64u %s",
PartEntry->FileSystemName,
PartEntry->PartType,
PartSize,
Unit);
}
Attribute = (List->CurrentDisk == DiskEntry && Attribute = (List->CurrentDisk == DiskEntry &&
List->CurrentPartition == PartIndex) ? 0x71 : 0x17; List->CurrentPartition == PartEntry) ? 0x71 : 0x17;
FillConsoleOutputCharacter(' ', FillConsoleOutputCharacter(' ',
Width, Width,
@ -687,6 +768,8 @@ static VOID
PrintDiskData(PPARTLIST List, PrintDiskData(PPARTLIST List,
PDISKENTRY DiskEntry) PDISKENTRY DiskEntry)
{ {
PPARTENTRY PartEntry;
PLIST_ENTRY Entry;
CHAR LineBuffer[128]; CHAR LineBuffer[128];
COORD coPos; COORD coPos;
ULONG Written; ULONG Written;
@ -765,14 +848,17 @@ PrintDiskData(PPARTLIST List,
PrintEmptyLine(List); PrintEmptyLine(List);
/* Print partition lines*/ /* Print partition lines*/
for (PartIndex = 0; PartIndex < DiskEntry->PartCount; PartIndex++) Entry = DiskEntry->PartListHead.Flink;
while (Entry != &DiskEntry->PartListHead)
{ {
if (!DiskEntry->PartArray[PartIndex].HidePartEntry) PartEntry = CONTAINING_RECORD (Entry, PARTENTRY, ListEntry);
{
PrintPartitionData(List, /* Print disk entry */
DiskEntry, PrintPartitionData (List,
PartIndex); DiskEntry,
} PartEntry);
Entry = Entry->Flink;
} }
/* Print separator line */ /* Print separator line */
@ -859,8 +945,8 @@ DrawPartitionList(PPARTLIST List)
/* print list entries */ /* print list entries */
List->Line = 0; List->Line = 0;
Entry = List->DiskList.Flink; Entry = List->DiskListHead.Flink;
while (Entry != &List->DiskList) while (Entry != &List->DiskListHead)
{ {
DiskEntry = CONTAINING_RECORD (Entry, DISKENTRY, ListEntry); DiskEntry = CONTAINING_RECORD (Entry, DISKENTRY, ListEntry);
@ -876,41 +962,59 @@ DrawPartitionList(PPARTLIST List)
VOID VOID
ScrollDownPartitionList(PPARTLIST List) ScrollDownPartitionList(PPARTLIST List)
{ {
PLIST_ENTRY Entry;
PDISKENTRY DiskEntry; PDISKENTRY DiskEntry;
ULONG i; PPARTENTRY PartEntry;
PLIST_ENTRY Entry1;
PLIST_ENTRY Entry2;
/* Check for empty disks */ /* Check for empty disks */
if (IsListEmpty (&List->DiskList)) if (IsListEmpty (&List->DiskListHead))
return; return;
/* check for next usable entry on current disk */ /* Check for next usable entry on current disk */
for (i = List->CurrentPartition + 1; i < List->CurrentDisk->PartCount; i++) if (List->CurrentPartition != NULL)
{ {
if (List->CurrentDisk->PartArray[i].HidePartEntry == FALSE) Entry2 = List->CurrentPartition->ListEntry.Flink;
while (Entry2 != &List->CurrentDisk->PartListHead)
{ {
List->CurrentPartition = i; PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry);
DrawPartitionList(List);
return; // if (PartEntry->HidePartEntry == FALSE)
{
List->CurrentPartition = PartEntry;
DrawPartitionList (List);
return;
}
Entry2 = Entry2->Flink;
} }
} }
/* check for first usable entry on next disk */ /* Check for first usable entry on next disk */
Entry = List->CurrentDisk->ListEntry.Flink; if (List->CurrentDisk != NULL)
while (Entry != &List->DiskList)
{ {
DiskEntry = CONTAINING_RECORD (Entry, DISKENTRY, ListEntry); Entry1 = List->CurrentDisk->ListEntry.Flink;
for (i = 0; i < DiskEntry->PartCount; i++) while (Entry1 != &List->DiskListHead)
{ {
if (DiskEntry->PartArray[i].HidePartEntry == FALSE) DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry);
Entry2 = DiskEntry->PartListHead.Flink;
while (Entry2 != &DiskEntry->PartListHead)
{ {
List->CurrentDisk = DiskEntry; PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry);
List->CurrentPartition = i;
DrawPartitionList(List); // if (PartEntry->HidePartEntry == FALSE)
return; {
List->CurrentDisk = DiskEntry;
List->CurrentPartition = PartEntry;
DrawPartitionList (List);
return;
}
Entry2 = Entry2->Flink;
} }
Entry1 = Entry1->Flink;
} }
Entry = Entry->Flink;
} }
} }
@ -918,41 +1022,61 @@ ScrollDownPartitionList(PPARTLIST List)
VOID VOID
ScrollUpPartitionList(PPARTLIST List) ScrollUpPartitionList(PPARTLIST List)
{ {
PLIST_ENTRY Entry;
PDISKENTRY DiskEntry; PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
PLIST_ENTRY Entry1;
PLIST_ENTRY Entry2;
ULONG i; ULONG i;
/* Check for empty disks */ /* Check for empty disks */
if (IsListEmpty (&List->DiskList)) if (IsListEmpty (&List->DiskListHead))
return; return;
/* check for previous usable entry on current disk */ /* check for previous usable entry on current disk */
for (i = List->CurrentPartition - 1; i != (ULONG)-1; i--) if (List->CurrentPartition != NULL)
{ {
if (List->CurrentDisk->PartArray[i].HidePartEntry == FALSE) Entry2 = List->CurrentPartition->ListEntry.Blink;
while (Entry2 != &List->CurrentDisk->PartListHead)
{ {
List->CurrentPartition = i; PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry);
DrawPartitionList(List);
return; // if (PartEntry->HidePartEntry == FALSE)
{
List->CurrentPartition = PartEntry;
DrawPartitionList (List);
return;
}
Entry2 = Entry2->Blink;
} }
} }
/* check for last usable entry on previous disk */ /* check for last usable entry on previous disk */
Entry = List->CurrentDisk->ListEntry.Blink; if (List->CurrentDisk != NULL)
while (Entry != &List->DiskList)
{ {
DiskEntry = CONTAINING_RECORD (Entry, DISKENTRY, ListEntry); Entry1 = List->CurrentDisk->ListEntry.Blink;
for (i = DiskEntry->PartCount - 1; i != (ULONG)-1; i--) while (Entry1 != &List->DiskListHead)
{ {
if (DiskEntry->PartArray[i].HidePartEntry == FALSE) DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry);
Entry2 = DiskEntry->PartListHead.Blink;
while (Entry2 != &DiskEntry->PartListHead)
{ {
List->CurrentDisk = DiskEntry; PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry);
List->CurrentPartition = i;
DrawPartitionList(List); // if (PartEntry->HidePartEntry == FALSE)
return; {
List->CurrentDisk = DiskEntry;
List->CurrentPartition = PartEntry;
DrawPartitionList (List);
return;
}
Entry2 = Entry2->Blink;
} }
Entry1 = Entry1->Blink;
} }
Entry = Entry->Blink;
} }
} }
@ -969,15 +1093,10 @@ GetSelectedPartition(PPARTLIST List,
DiskEntry = List->CurrentDisk; DiskEntry = List->CurrentDisk;
if (List->CurrentPartition >= DiskEntry->PartCount) if (List->CurrentPartition == NULL)
return(FALSE); return FALSE;
PartEntry = &DiskEntry->PartArray[List->CurrentPartition]; PartEntry = List->CurrentPartition;
if (PartEntry->Used == FALSE)
{
return(FALSE);
}
/* Copy disk-specific data */ /* Copy disk-specific data */
Data->DiskSize = DiskEntry->DiskSize; Data->DiskSize = DiskEntry->DiskSize;
@ -1007,12 +1126,12 @@ GetSelectedPartition(PPARTLIST List,
/* Copy partition-specific data */ /* Copy partition-specific data */
Data->CreatePartition = FALSE; Data->CreatePartition = FALSE;
Data->NewPartSize = 0; Data->NewPartSize = 0;
Data->PartSize = PartEntry->PartSize; Data->PartSize = PartEntry->PartInfo[0].PartitionLength.QuadPart;
Data->PartNumber = PartEntry->PartNumber; Data->PartNumber = PartEntry->PartInfo[0].PartitionNumber;
Data->PartType = PartEntry->PartType; Data->PartType = PartEntry->PartInfo[0].PartitionType;
Data->DriveLetter = PartEntry->DriveLetter; Data->DriveLetter = PartEntry->DriveLetter;
return(TRUE); return TRUE;
} }
@ -1022,24 +1141,23 @@ GetActiveBootPartition(PPARTLIST List,
{ {
PDISKENTRY DiskEntry; PDISKENTRY DiskEntry;
PPARTENTRY PartEntry; PPARTENTRY PartEntry;
PLIST_ENTRY Entry;
ULONG i; ULONG i;
if (List->CurrentDisk == NULL) if (IsListEmpty (&List->DiskListHead))
return FALSE; return FALSE;
DiskEntry = List->CurrentDisk; /* Get first disk entry from the disk list */
Entry = List->DiskListHead.Flink;
DiskEntry = CONTAINING_RECORD (Entry, DISKENTRY, ListEntry);
for (i = 0; i < DiskEntry->PartCount; i++) Entry = DiskEntry->PartListHead.Flink;
while (Entry != &DiskEntry->PartListHead)
{ {
if (DiskEntry->PartArray[i].Active) PartEntry = CONTAINING_RECORD (Entry, PARTENTRY, ListEntry);
if (PartEntry->PartInfo[0].BootIndicator)
{ {
PartEntry = &DiskEntry->PartArray[i];
if (PartEntry->Used == FALSE)
{
return(FALSE);
}
/* Copy disk-specific data */ /* Copy disk-specific data */
Data->DiskSize = DiskEntry->DiskSize; Data->DiskSize = DiskEntry->DiskSize;
Data->DiskNumber = DiskEntry->DiskNumber; Data->DiskNumber = DiskEntry->DiskNumber;
@ -1066,16 +1184,18 @@ GetActiveBootPartition(PPARTLIST List,
} }
/* Copy partition-specific data */ /* Copy partition-specific data */
Data->PartSize = PartEntry->PartSize; Data->PartSize = PartEntry->PartInfo[0].PartitionLength.QuadPart;
Data->PartNumber = PartEntry->PartNumber; Data->PartNumber = PartEntry->PartInfo[0].PartitionNumber;
Data->PartType = PartEntry->PartType; Data->PartType = PartEntry->PartInfo[0].PartitionType;
Data->DriveLetter = PartEntry->DriveLetter; Data->DriveLetter = PartEntry->DriveLetter;
return(TRUE); return TRUE;
} }
Entry = Entry->Flink;
} }
return(FALSE); return FALSE;
} }
@ -1084,6 +1204,7 @@ CreateSelectedPartition(PPARTLIST List,
ULONG PartType, ULONG PartType,
ULONGLONG NewPartSize) ULONGLONG NewPartSize)
{ {
#if 0
PDISKENTRY DiskEntry; PDISKENTRY DiskEntry;
PPARTENTRY PartEntry; PPARTENTRY PartEntry;
ULONG PartEntryNumber; ULONG PartEntryNumber;
@ -1097,7 +1218,8 @@ CreateSelectedPartition(PPARTLIST List,
LARGE_INTEGER li; LARGE_INTEGER li;
DiskEntry = List->CurrentDisk; DiskEntry = List->CurrentDisk;
PartEntry = &DiskEntry->PartArray[List->CurrentPartition]; PartEntry = List->CurrentPartition;
PartEntry->PartType = PartType; PartEntry->PartType = PartType;
PartEntryNumber = List->CurrentPartition; PartEntryNumber = List->CurrentPartition;
@ -1186,6 +1308,7 @@ CreateSelectedPartition(PPARTLIST List,
NtClose(FileHandle); NtClose(FileHandle);
RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
#endif
return TRUE; return TRUE;
} }
@ -1194,9 +1317,10 @@ CreateSelectedPartition(PPARTLIST List,
BOOLEAN BOOLEAN
DeleteSelectedPartition(PPARTLIST List) DeleteSelectedPartition(PPARTLIST List)
{ {
#if 0
PDISKENTRY DiskEntry; PDISKENTRY DiskEntry;
PPARTENTRY PartEntry; PPARTENTRY PartEntry;
ULONG PartEntryNumber; // ULONG PartEntryNumber;
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
DRIVE_LAYOUT_INFORMATION *LayoutBuffer; DRIVE_LAYOUT_INFORMATION *LayoutBuffer;
IO_STATUS_BLOCK Iosb; IO_STATUS_BLOCK Iosb;
@ -1207,9 +1331,10 @@ DeleteSelectedPartition(PPARTLIST List)
LARGE_INTEGER li; LARGE_INTEGER li;
DiskEntry = List->CurrentDisk; DiskEntry = List->CurrentDisk;
PartEntry = &DiskEntry->PartArray[List->CurrentPartition]; PartEntry = List->CurrentPartition;
PartEntry->PartType = PARTITION_ENTRY_UNUSED; PartEntry->PartType = PARTITION_ENTRY_UNUSED;
PartEntryNumber = List->CurrentPartition;
// PartEntryNumber = List->CurrentPartition;
DPRINT1("DeleteSelectedPartition(PartEntryNumber = %d)\n", PartEntryNumber); DPRINT1("DeleteSelectedPartition(PartEntryNumber = %d)\n", PartEntryNumber);
DPRINT1("PartEntry->StartingOffset %d\n", PartEntry->StartingOffset); DPRINT1("PartEntry->StartingOffset %d\n", PartEntry->StartingOffset);
@ -1240,15 +1365,15 @@ DeleteSelectedPartition(PPARTLIST List)
LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap(ProcessHeap, 0, 8192); LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap(ProcessHeap, 0, 8192);
Status = NtDeviceIoControlFile(FileHandle, Status = NtDeviceIoControlFile(FileHandle,
NULL, NULL,
NULL, NULL,
NULL, NULL,
&Iosb, &Iosb,
IOCTL_DISK_GET_DRIVE_LAYOUT, IOCTL_DISK_GET_DRIVE_LAYOUT,
NULL, NULL,
0, 0,
LayoutBuffer, LayoutBuffer,
8192); 8192);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("IOCTL_DISK_GET_DRIVE_LAYOUT failed() 0x%.08x\n", Status); DPRINT("IOCTL_DISK_GET_DRIVE_LAYOUT failed() 0x%.08x\n", Status);
@ -1294,6 +1419,7 @@ DeleteSelectedPartition(PPARTLIST List)
NtClose(FileHandle); NtClose(FileHandle);
RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
#endif
return TRUE; return TRUE;
} }

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: partlist.h,v 1.11 2003/08/02 16:49:36 ekohl Exp $ /* $Id: partlist.h,v 1.12 2003/08/03 12:20:22 ekohl Exp $
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup * PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/partlist.h * FILE: subsys/system/usetup/partlist.h
@ -49,21 +49,23 @@ typedef struct _PARTDATA
typedef struct _PARTENTRY typedef struct _PARTENTRY
{ {
ULONGLONG StartingOffset; LIST_ENTRY ListEntry;
ULONGLONG PartSize;
ULONG PartNumber;
ULONG PartType;
BOOLEAN Active;
CHAR DriveLetter; CHAR DriveLetter;
CHAR VolumeLabel[17]; CHAR VolumeLabel[17];
CHAR FileSystemName[9]; CHAR FileSystemName[9];
BOOL Unpartitioned; BOOLEAN Unpartitioned;
BOOL Used; /*
* Raw offset and length of the unpartitioned disk space.
* Includes the leading, not yet existing, partition table.
*/
ULONGLONG UnpartitionedOffset;
ULONGLONG UnpartitionedLength;
PARTITION_INFORMATION PartInfo[4];
BOOLEAN HidePartEntry;
} PARTENTRY, *PPARTENTRY; } PARTENTRY, *PPARTENTRY;
@ -71,11 +73,15 @@ typedef struct _DISKENTRY
{ {
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
ULONGLONG DiskSize;
ULONGLONG Cylinders; ULONGLONG Cylinders;
ULONGLONG TracksPerCylinder; ULONGLONG TracksPerCylinder;
ULONGLONG SectorsPerTrack; ULONGLONG SectorsPerTrack;
ULONGLONG BytesPerSector; ULONGLONG BytesPerSector;
ULONGLONG DiskSize;
ULONGLONG CylinderSize;
ULONGLONG TrackSize;
ULONG DiskNumber; ULONG DiskNumber;
USHORT Port; USHORT Port;
USHORT Bus; USHORT Bus;
@ -83,8 +89,7 @@ typedef struct _DISKENTRY
UNICODE_STRING DriverName; UNICODE_STRING DriverName;
ULONG PartCount; LIST_ENTRY PartListHead;
PPARTENTRY PartArray;
} DISKENTRY, *PDISKENTRY; } DISKENTRY, *PDISKENTRY;
@ -102,9 +107,9 @@ typedef struct _PARTLIST
ULONG TopPartition; ULONG TopPartition;
PDISKENTRY CurrentDisk; PDISKENTRY CurrentDisk;
ULONG CurrentPartition; PPARTENTRY CurrentPartition;
LIST_ENTRY DiskList; LIST_ENTRY DiskListHead;
} PARTLIST, *PPARTLIST; } PARTLIST, *PPARTLIST;