* PROJECT: ReactOS text-mode setup
* FILE: base/setup/usetup/partlist.c
* PURPOSE: Partition list functions
- * PROGRAMMER: Eric Kohl
- * Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
#include "usetup.h"
-#include <ntddscsi.h>
-
#define NDEBUG
#include <debug.h>
-//#define DUMP_PARTITION_TABLE
-
/* HELPERS FOR PARTITION TYPES **********************************************/
-typedef struct _PARTITION_TYPE
-{
- UCHAR Type;
- PCHAR Description;
-} PARTITION_TYPE, *PPARTITION_TYPE;
-
-/*
- * This partition type list was ripped off the kernelDisk.c module from:
- *
- * Visopsys Operating System
- * Copyright (C) 1998-2015 J. Andrew McLaughlin
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- *
- * See also https://en.wikipedia.org/wiki/Partition_type#List_of_partition_IDs
- * and http://www.win.tue.nl/~aeb/partitions/partition_types-1.html
- * for a complete list.
- */
-
-/* This is a table for keeping known partition type codes and descriptions */
-static PARTITION_TYPE PartitionTypes[] =
-{
- { 0x00, "(Empty)" },
- { 0x01, "FAT12" },
- { 0x02, "XENIX root" },
- { 0x03, "XENIX /usr" },
- { 0x04, "FAT16 (small)" },
- { 0x05, "Extended" },
- { 0x06, "FAT16" },
- { 0x07, "NTFS/HPFS/exFAT" },
- { 0x08, "OS/2 or AIX boot" },
- { 0x09, "AIX data" },
- { 0x0A, "OS/2 Boot Manager" },
- { 0x0B, "FAT32" },
- { 0x0C, "FAT32 (LBA)" },
- { 0x0E, "FAT16 (LBA)" },
- { 0x0F, "Extended (LBA)" },
- { 0x11, "Hidden FAT12" },
- { 0x12, "FAT diagnostic" },
- { 0x14, "Hidden FAT16 (small)" },
- { 0x16, "Hidden FAT16" },
- { 0x17, "Hidden HPFS or NTFS" },
- { 0x1B, "Hidden FAT32" },
- { 0x1C, "Hidden FAT32 (LBA)" },
- { 0x1E, "Hidden FAT16 (LBA)" },
- { 0x35, "JFS" },
- { 0x39, "Plan 9" },
- { 0x3C, "PartitionMagic" },
- { 0x3D, "Hidden Netware" },
- { 0x41, "PowerPC PReP" },
- { 0x42, "Win2K dynamic extended" },
- { 0x43, "Old Linux" },
- { 0x44, "GoBack" },
- { 0x4D, "QNX4.x" },
- { 0x4D, "QNX4.x 2nd" },
- { 0x4D, "QNX4.x 3rd" },
- { 0x50, "Ontrack R/O" },
- { 0x51, "Ontrack R/W or Novell" },
- { 0x52, "CP/M" },
- { 0x63, "GNU HURD or UNIX SysV" },
- { 0x64, "Netware 2" },
- { 0x65, "Netware 3/4" },
- { 0x66, "Netware SMS" },
- { 0x67, "Novell" },
- { 0x68, "Novell" },
- { 0x69, "Netware 5+" },
- { 0x7E, "Veritas VxVM public" },
- { 0x7F, "Veritas VxVM private" },
- { 0x80, "Minix" },
- { 0x81, "Linux or Minix" },
- { 0x82, "Linux swap or Solaris" },
- { 0x83, "Linux" },
- { 0x84, "Hibernation" },
- { 0x85, "Linux extended" },
- { 0x86, "HPFS or NTFS mirrored" },
- { 0x87, "HPFS or NTFS mirrored" },
- { 0x8E, "Linux LVM" },
- { 0x93, "Hidden Linux" },
- { 0x96, "CDFS/ISO-9660" },
- { 0x9F, "BSD/OS" },
- { 0xA0, "Laptop hibernation" },
- { 0xA1, "Laptop hibernation" },
- { 0xA5, "BSD, NetBSD, FreeBSD" },
- { 0xA6, "OpenBSD" },
- { 0xA7, "NeXTSTEP" },
- { 0xA8, "OS-X UFS" },
- { 0xA9, "NetBSD" },
- { 0xAB, "OS-X boot" },
- { 0xAF, "OS-X HFS" },
- { 0xB6, "NT corrupt mirror" },
- { 0xB7, "BSDI" },
- { 0xB8, "BSDI swap" },
- { 0xBE, "Solaris 8 boot" },
- { 0xBF, "Solaris x86" },
- { 0xC0, "NTFT" },
- { 0xC1, "DR-DOS FAT12" },
- { 0xC2, "Hidden Linux" },
- { 0xC3, "Hidden Linux swap" },
- { 0xC4, "DR-DOS FAT16 (small)" },
- { 0xC5, "DR-DOS Extended" },
- { 0xC6, "DR-DOS FAT16" },
- { 0xC7, "HPFS mirrored" },
- { 0xCB, "DR-DOS FAT32" },
- { 0xCC, "DR-DOS FAT32 (LBA)" },
- { 0xCE, "DR-DOS FAT16 (LBA)" },
- { 0xD0, "MDOS" },
- { 0xD1, "MDOS FAT12" },
- { 0xD4, "MDOS FAT16 (small)" },
- { 0xD5, "MDOS Extended" },
- { 0xD6, "MDOS FAT16" },
- { 0xD8, "CP/M-86" },
- { 0xDF, "BootIt EMBRM(FAT16/32)" },
- { 0xEB, "BeOS BFS" },
- { 0xEE, "EFI GPT protective" },
- { 0xEF, "EFI filesystem" },
- { 0xF0, "Linux/PA-RISC boot" },
- { 0xF2, "DOS 3.3+ second" },
- { 0xFA, "Bochs" },
- { 0xFB, "VmWare" },
- { 0xFC, "VmWare swap" },
- { 0xFD, "Linux RAID" },
- { 0xFE, "NT hidden" },
-};
-
VOID
GetPartTypeStringFromPartitionType(
- UCHAR partitionType,
- PCHAR strPartType,
- DWORD cchPartType)
+ IN UCHAR partitionType,
+ OUT PCHAR strPartType,
+ IN ULONG cchPartType)
{
/* Determine partition type */
if (IsContainerPartition(partitionType))
{
- StringCchCopy(strPartType, cchPartType, MUIGetString(STRING_EXTENDED_PARTITION));
+ RtlStringCchCopyA(strPartType, cchPartType, MUIGetString(STRING_EXTENDED_PARTITION));
}
else if (partitionType == PARTITION_ENTRY_UNUSED)
{
- StringCchCopy(strPartType, cchPartType, MUIGetString(STRING_FORMATUNUSED));
+ RtlStringCchCopyA(strPartType, cchPartType, MUIGetString(STRING_FORMATUNUSED));
}
else
{
{
if (partitionType == PartitionTypes[i].Type)
{
- StringCchCopy(strPartType, cchPartType, PartitionTypes[i].Description);
+ RtlStringCchCopyA(strPartType, cchPartType, PartitionTypes[i].Description);
return;
}
}
/* We are here because the partition type is unknown */
- StringCchCopy(strPartType, cchPartType, MUIGetString(STRING_FORMATUNKNOWN));
+ RtlStringCchCopyA(strPartType, cchPartType, MUIGetString(STRING_FORMATUNKNOWN));
}
}
+
/* FUNCTIONS ****************************************************************/
-#ifdef DUMP_PARTITION_TABLE
-static
VOID
-DumpPartitionTable(
- PDISKENTRY DiskEntry)
-{
- PPARTITION_INFORMATION PartitionInfo;
- ULONG i;
-
- DbgPrint("\n");
- DbgPrint("Index Start Length Hidden Nr Type Boot RW\n");
- DbgPrint("----- ------------ ------------ ---------- -- ---- ---- --\n");
-
- for (i = 0; i < DiskEntry->LayoutBuffer->PartitionCount; i++)
- {
- PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[i];
- DbgPrint(" %3lu %12I64u %12I64u %10lu %2lu %2x %c %c\n",
- i,
- PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector,
- PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector,
- PartitionInfo->HiddenSectors,
- PartitionInfo->PartitionNumber,
- PartitionInfo->PartitionType,
- PartitionInfo->BootIndicator ? '*': ' ',
- PartitionInfo->RewritePartition ? 'Y': 'N');
- }
-
- DbgPrint("\n");
-}
-#endif
-
-
-ULONGLONG
-AlignDown(
- IN ULONGLONG Value,
- IN ULONG Alignment)
-{
- ULONGLONG Temp;
-
- Temp = Value / Alignment;
-
- return Temp * Alignment;
-}
-
-
-ULONGLONG
-AlignUp(
- IN ULONGLONG Value,
- IN ULONG Alignment)
+InitPartitionListUi(
+ IN OUT PPARTLIST_UI ListUi,
+ IN PPARTLIST List,
+ IN SHORT Left,
+ IN SHORT Top,
+ IN SHORT Right,
+ IN SHORT Bottom)
{
- ULONGLONG Temp, Result;
-
- Temp = Value / Alignment;
-
- Result = Temp * Alignment;
- if (Value % Alignment)
- Result += Alignment;
+ ListUi->List = List;
+ // ListUi->FirstShown = NULL;
+ // ListUi->LastShown = NULL;
- return Result;
-}
-
-ULONGLONG
-RoundingDivide(
- IN ULONGLONG Dividend,
- IN ULONGLONG Divisor)
-{
- return (Dividend + Divisor / 2) / Divisor;
-}
+ ListUi->Left = Left;
+ ListUi->Top = Top;
+ ListUi->Right = Right;
+ ListUi->Bottom = Bottom;
+ ListUi->Line = 0;
+ ListUi->Offset = 0;
-static
-VOID
-GetDriverName(
- PDISKENTRY DiskEntry)
-{
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];
- WCHAR KeyName[32];
- NTSTATUS Status;
-
- RtlInitUnicodeString(&DiskEntry->DriverName,
- NULL);
-
- swprintf(KeyName,
- L"\\Scsi\\Scsi Port %hu",
- DiskEntry->Port);
-
- RtlZeroMemory(&QueryTable,
- sizeof(QueryTable));
-
- QueryTable[0].Name = L"Driver";
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
- QueryTable[0].EntryContext = &DiskEntry->DriverName;
-
- Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
- KeyName,
- QueryTable,
- NULL,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
- }
+ // ListUi->Redraw = TRUE;
}
-
static
VOID
-AssignDriveLetters(
- PPARTLIST List)
+PrintEmptyLine(
+ IN PPARTLIST_UI ListUi)
{
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
- PLIST_ENTRY Entry1;
- PLIST_ENTRY Entry2;
- CHAR Letter;
-
- Letter = 'C';
-
- /* Assign drive letters to primary partitions */
- Entry1 = List->DiskListHead.Flink;
- while (Entry1 != &List->DiskListHead)
- {
- DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
-
- Entry2 = DiskEntry->PrimaryPartListHead.Flink;
- while (Entry2 != &DiskEntry->PrimaryPartListHead)
- {
- PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
-
- PartEntry->DriveLetter = 0;
-
- if (PartEntry->IsPartitioned &&
- !IsContainerPartition(PartEntry->PartitionType))
- {
- if (IsRecognizedPartition(PartEntry->PartitionType) ||
- (PartEntry->PartitionType == PARTITION_ENTRY_UNUSED &&
- PartEntry->SectorCount.QuadPart != 0LL))
- {
- if (Letter <= 'Z')
- {
- PartEntry->DriveLetter = Letter;
- Letter++;
- }
- }
- }
-
- Entry2 = Entry2->Flink;
- }
-
- Entry1 = Entry1->Flink;
- }
-
- /* Assign drive letters to logical drives */
- Entry1 = List->DiskListHead.Flink;
- while (Entry1 != &List->DiskListHead)
- {
- DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
-
- Entry2 = DiskEntry->LogicalPartListHead.Flink;
- while (Entry2 != &DiskEntry->LogicalPartListHead)
- {
- PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
-
- PartEntry->DriveLetter = 0;
-
- if (PartEntry->IsPartitioned)
- {
- if (IsRecognizedPartition(PartEntry->PartitionType) ||
- (PartEntry->PartitionType == PARTITION_ENTRY_UNUSED &&
- PartEntry->SectorCount.QuadPart != 0LL))
- {
- if (Letter <= 'Z')
- {
- PartEntry->DriveLetter = Letter;
- Letter++;
- }
- }
- }
-
- Entry2 = Entry2->Flink;
- }
-
- Entry1 = Entry1->Flink;
- }
-}
+ COORD coPos;
+ ULONG Written;
+ USHORT Width;
+ USHORT Height;
+ Width = ListUi->Right - ListUi->Left - 1;
+ Height = ListUi->Bottom - ListUi->Top - 2;
-NTSTATUS
-NTAPI
-DiskIdentifierQueryRoutine(
- PWSTR ValueName,
- ULONG ValueType,
- PVOID ValueData,
- ULONG ValueLength,
- PVOID Context,
- PVOID EntryContext)
-{
- PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
- UNICODE_STRING NameU;
+ coPos.X = ListUi->Left + 1;
+ coPos.Y = ListUi->Top + 1 + ListUi->Line;
- if (ValueType == REG_SZ &&
- ValueLength == 20 * sizeof(WCHAR))
+ if (ListUi->Line >= 0 && ListUi->Line <= Height)
{
- NameU.Buffer = (PWCHAR)ValueData;
- NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR);
- RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum);
-
- NameU.Buffer = (PWCHAR)ValueData + 9;
- RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature);
+ FillConsoleOutputAttribute(StdOutput,
+ FOREGROUND_WHITE | BACKGROUND_BLUE,
+ Width,
+ coPos,
+ &Written);
- return STATUS_SUCCESS;
+ FillConsoleOutputCharacterA(StdOutput,
+ ' ',
+ Width,
+ coPos,
+ &Written);
}
- return STATUS_UNSUCCESSFUL;
+ ListUi->Line++;
}
-
-NTSTATUS
-NTAPI
-DiskConfigurationDataQueryRoutine(
- PWSTR ValueName,
- ULONG ValueType,
- PVOID ValueData,
- ULONG ValueLength,
- PVOID Context,
- PVOID EntryContext)
+static
+VOID
+PrintPartitionData(
+ IN PPARTLIST_UI ListUi,
+ IN PDISKENTRY DiskEntry,
+ IN PPARTENTRY PartEntry)
{
- PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
- PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
- PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
- ULONG i;
+ PPARTLIST List = ListUi->List;
+ CHAR LineBuffer[128];
+ COORD coPos;
+ ULONG Written;
+ USHORT Width;
+ USHORT Height;
+ LARGE_INTEGER PartSize;
+ PCHAR Unit;
+ UCHAR Attribute;
+ CHAR PartTypeString[32];
+ PCHAR PartType = PartTypeString;
- if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR ||
- ValueLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
- return STATUS_UNSUCCESSFUL;
+ Width = ListUi->Right - ListUi->Left - 1;
+ Height = ListUi->Bottom - ListUi->Top - 2;
- FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
+ coPos.X = ListUi->Left + 1;
+ coPos.Y = ListUi->Top + 1 + ListUi->Line;
- /* Hm. Version and Revision are not set on Microsoft Windows XP... */
+ /* Get the partition size */
+ PartSize.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
#if 0
- if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
- FullResourceDescriptor->PartialResourceList.Revision != 1)
- return STATUS_UNSUCCESSFUL;
-#endif
-
- for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
+ if (PartSize.QuadPart >= 10 * GB) /* 10 GB */
{
- if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific ||
- FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize != sizeof(CM_DISK_GEOMETRY_DEVICE_DATA))
- continue;
-
- DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1];
- BiosDiskEntry->DiskGeometry = *DiskGeometry;
-
- return STATUS_SUCCESS;
+ PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, GB);
+ Unit = MUIGetString(STRING_GB);
}
-
- return STATUS_UNSUCCESSFUL;
-}
-
-
-NTSTATUS
-NTAPI
-SystemConfigurationDataQueryRoutine(
- PWSTR ValueName,
- ULONG ValueType,
- PVOID ValueData,
- ULONG ValueLength,
- PVOID Context,
- PVOID EntryContext)
-{
- PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
- PCM_INT13_DRIVE_PARAMETER* Int13Drives = (PCM_INT13_DRIVE_PARAMETER*)Context;
- ULONG i;
-
- if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR ||
- ValueLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
- return STATUS_UNSUCCESSFUL;
-
- FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
-
- /* Hm. Version and Revision are not set on Microsoft Windows XP... */
-#if 0
- if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
- FullResourceDescriptor->PartialResourceList.Revision != 1)
- return STATUS_UNSUCCESSFUL;
+ else
#endif
-
- for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
+ if (PartSize.QuadPart >= 10 * MB) /* 10 MB */
{
- if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific ||
- FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize % sizeof(CM_INT13_DRIVE_PARAMETER) != 0)
- continue;
-
- *Int13Drives = (CM_INT13_DRIVE_PARAMETER*)RtlAllocateHeap(ProcessHeap, 0,
- FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
- if (*Int13Drives == NULL)
- return STATUS_NO_MEMORY;
-
- memcpy(*Int13Drives,
- &FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1],
- FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
- return STATUS_SUCCESS;
+ PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, MB);
+ Unit = MUIGetString(STRING_MB);
}
-
- return STATUS_UNSUCCESSFUL;
-}
-
-
-#define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
-
-static VOID
-EnumerateBiosDiskEntries(
- PPARTLIST PartList)
-{
- RTL_QUERY_REGISTRY_TABLE QueryTable[3];
- WCHAR Name[120];
- ULONG AdapterCount;
- ULONG DiskCount;
- NTSTATUS Status;
- PCM_INT13_DRIVE_PARAMETER Int13Drives;
- PBIOSDISKENTRY BiosDiskEntry;
-
- memset(QueryTable, 0, sizeof(QueryTable));
-
- QueryTable[1].Name = L"Configuration Data";
- QueryTable[1].QueryRoutine = SystemConfigurationDataQueryRoutine;
- Int13Drives = NULL;
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
- &QueryTable[1],
- (PVOID)&Int13Drives,
- NULL);
- if (!NT_SUCCESS(Status))
+ else
{
- DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status);
- return;
+ PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, KB);
+ Unit = MUIGetString(STRING_KB);
}
- AdapterCount = 0;
- while (1)
+ if (PartEntry->IsPartitioned == FALSE)
+ {
+ sprintf(LineBuffer,
+ MUIGetString(STRING_UNPSPACE),
+ PartEntry->LogicalPartition ? " " : "",
+ PartEntry->LogicalPartition ? "" : " ",
+ PartSize.u.LowPart,
+ Unit);
+ }
+ else
{
- swprintf(Name, L"%s\\%lu", ROOT_NAME, AdapterCount);
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- Name,
- &QueryTable[2],
- NULL,
- NULL);
- if (!NT_SUCCESS(Status))
+ /* Determine partition type */
+ PartTypeString[0] = '\0';
+ if (PartEntry->New != FALSE)
{
- break;
+ PartType = MUIGetString(STRING_UNFORMATTED);
}
-
- swprintf(Name, L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount);
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- Name,
- &QueryTable[2],
- NULL,
- NULL);
- if (NT_SUCCESS(Status))
+ else if (PartEntry->IsPartitioned != FALSE)
{
- while (1)
- {
- swprintf(Name, L"%s\\%lu\\DiskController\\0", ROOT_NAME, AdapterCount);
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- Name,
- &QueryTable[2],
- NULL,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeHeap(ProcessHeap, 0, Int13Drives);
- return;
- }
-
- swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral", ROOT_NAME, AdapterCount);
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- Name,
- &QueryTable[2],
- NULL,
- NULL);
- if (NT_SUCCESS(Status))
- {
- QueryTable[0].Name = L"Identifier";
- QueryTable[0].QueryRoutine = DiskIdentifierQueryRoutine;
- QueryTable[1].Name = L"Configuration Data";
- QueryTable[1].QueryRoutine = DiskConfigurationDataQueryRoutine;
-
- DiskCount = 0;
- while (1)
- {
- BiosDiskEntry = (BIOSDISKENTRY*)RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY));
- if (BiosDiskEntry == NULL)
- {
- break;
- }
-
- swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, DiskCount);
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- Name,
- QueryTable,
- (PVOID)BiosDiskEntry,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
- break;
- }
-
- BiosDiskEntry->DiskNumber = DiskCount;
- BiosDiskEntry->Recognized = FALSE;
-
- if (DiskCount < Int13Drives[0].NumberDrives)
- {
- BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount];
- }
- else
- {
- DPRINT1("Didn't find int13 drive datas for disk %u\n", DiskCount);
- }
-
- InsertTailList(&PartList->BiosDiskListHead, &BiosDiskEntry->ListEntry);
-
- DPRINT("DiskNumber: %lu\n", BiosDiskEntry->DiskNumber);
- DPRINT("Signature: %08lx\n", BiosDiskEntry->Signature);
- DPRINT("Checksum: %08lx\n", BiosDiskEntry->Checksum);
- DPRINT("BytesPerSector: %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector);
- DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders);
- DPRINT("NumberOfHeads: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads);
- DPRINT("DriveSelect: %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect);
- DPRINT("MaxCylinders: %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders);
- DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack);
- DPRINT("MaxHeads: %d\n", BiosDiskEntry->Int13DiskData.MaxHeads);
- DPRINT("NumberDrives: %d\n", BiosDiskEntry->Int13DiskData.NumberDrives);
-
- DiskCount++;
- }
- }
-
- RtlFreeHeap(ProcessHeap, 0, Int13Drives);
- return;
- }
+ GetPartTypeStringFromPartitionType(PartEntry->PartitionType,
+ PartTypeString,
+ ARRAYSIZE(PartTypeString));
+ PartType = PartTypeString;
}
- AdapterCount++;
- }
-
- RtlFreeHeap(ProcessHeap, 0, Int13Drives);
-}
-
-
-static
-VOID
-AddPartitionToDisk(
- ULONG DiskNumber,
- PDISKENTRY DiskEntry,
- ULONG PartitionIndex,
- BOOLEAN LogicalPartition)
-{
- PPARTITION_INFORMATION PartitionInfo;
- PPARTENTRY PartEntry;
-
- PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
- if (PartitionInfo->PartitionType == 0 ||
- ((LogicalPartition != FALSE) && IsContainerPartition(PartitionInfo->PartitionType)))
- return;
-
- PartEntry = RtlAllocateHeap(ProcessHeap,
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
- if (PartEntry == NULL)
- {
- return;
- }
-
- PartEntry->DiskEntry = DiskEntry;
-
- PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
- PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
-
- PartEntry->BootIndicator = PartitionInfo->BootIndicator;
- PartEntry->PartitionType = PartitionInfo->PartitionType;
- PartEntry->HiddenSectors = PartitionInfo->HiddenSectors;
-
- PartEntry->LogicalPartition = LogicalPartition;
- PartEntry->IsPartitioned = TRUE;
- PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
- PartEntry->PartitionIndex = PartitionIndex;
-
- if (IsContainerPartition(PartEntry->PartitionType))
- {
- PartEntry->FormatState = Unformatted;
-
- if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
- DiskEntry->ExtendedPartition = PartEntry;
- }
- else if ((PartEntry->PartitionType == PARTITION_FAT_12) ||
- (PartEntry->PartitionType == PARTITION_FAT_16) ||
- (PartEntry->PartitionType == PARTITION_HUGE) ||
- (PartEntry->PartitionType == PARTITION_XINT13) ||
- (PartEntry->PartitionType == PARTITION_FAT32) ||
- (PartEntry->PartitionType == PARTITION_FAT32_XINT13))
- {
-#if 0
- if (CheckFatFormat())
+ if (strcmp(PartType, MUIGetString(STRING_FORMATUNKNOWN)) == 0)
{
- PartEntry->FormatState = Preformatted;
+ sprintf(LineBuffer,
+ MUIGetString(STRING_HDDINFOUNK5),
+ (PartEntry->DriveLetter == 0) ? '-' : (CHAR)PartEntry->DriveLetter,
+ (PartEntry->DriveLetter == 0) ? '-' : ':',
+ PartEntry->BootIndicator ? '*' : ' ',
+ PartEntry->LogicalPartition ? " " : "",
+ PartEntry->PartitionType,
+ PartEntry->LogicalPartition ? "" : " ",
+ PartSize.u.LowPart,
+ Unit);
}
else
{
- PartEntry->FormatState = Unformatted;
+ sprintf(LineBuffer,
+ "%c%c %c %s%-24s%s %6lu %s",
+ (PartEntry->DriveLetter == 0) ? '-' : (CHAR)PartEntry->DriveLetter,
+ (PartEntry->DriveLetter == 0) ? '-' : ':',
+ PartEntry->BootIndicator ? '*' : ' ',
+ PartEntry->LogicalPartition ? " " : "",
+ PartType,
+ PartEntry->LogicalPartition ? "" : " ",
+ PartSize.u.LowPart,
+ Unit);
}
-#endif
- PartEntry->FormatState = Preformatted;
}
- else if (PartEntry->PartitionType == PARTITION_EXT2)
+
+ Attribute = (List->CurrentDisk == DiskEntry &&
+ List->CurrentPartition == PartEntry) ?
+ FOREGROUND_BLUE | BACKGROUND_WHITE :
+ FOREGROUND_WHITE | BACKGROUND_BLUE;
+
+ if (ListUi->Line >= 0 && ListUi->Line <= Height)
{
-#if 0
- if (CheckExt2Format())
- {
- PartEntry->FormatState = Preformatted;
- }
- else
- {
- PartEntry->FormatState = Unformatted;
- }
-#endif
- PartEntry->FormatState = Preformatted;
+ FillConsoleOutputCharacterA(StdOutput,
+ ' ',
+ Width,
+ coPos,
+ &Written);
}
- else if (PartEntry->PartitionType == PARTITION_IFS)
+ coPos.X += 4;
+ Width -= 8;
+ if (ListUi->Line >= 0 && ListUi->Line <= Height)
{
-#if 0
- if (CheckNtfsFormat())
- {
- PartEntry->FormatState = Preformatted;
- }
- else if (CheckHpfsFormat())
- {
- PartEntry->FormatState = Preformatted;
- }
- else
- {
- PartEntry->FormatState = Unformatted;
- }
-#endif
- PartEntry->FormatState = Preformatted;
+ FillConsoleOutputAttribute(StdOutput,
+ Attribute,
+ Width,
+ coPos,
+ &Written);
}
- else
+ coPos.X++;
+ Width -= 2;
+ if (ListUi->Line >= 0 && ListUi->Line <= Height)
{
- PartEntry->FormatState = UnknownFormat;
+ WriteConsoleOutputCharacterA(StdOutput,
+ LineBuffer,
+ min(strlen(LineBuffer), Width),
+ coPos,
+ &Written);
}
- if (LogicalPartition)
- InsertTailList(&DiskEntry->LogicalPartListHead,
- &PartEntry->ListEntry);
- else
- InsertTailList(&DiskEntry->PrimaryPartListHead,
- &PartEntry->ListEntry);
+ ListUi->Line++;
}
-
static
VOID
-ScanForUnpartitionedDiskSpace(
- PDISKENTRY DiskEntry)
+PrintDiskData(
+ IN PPARTLIST_UI ListUi,
+ IN PDISKENTRY DiskEntry)
{
- ULONGLONG LastStartSector;
- ULONGLONG LastSectorCount;
- ULONGLONG LastUnusedSectorCount;
- PPARTENTRY PartEntry;
- PPARTENTRY NewPartEntry;
- PLIST_ENTRY Entry;
+ // PPARTLIST List = ListUi->List;
+ PPARTENTRY PrimaryPartEntry, LogicalPartEntry;
+ PLIST_ENTRY PrimaryEntry, LogicalEntry;
+ CHAR LineBuffer[128];
+ COORD coPos;
+ ULONG Written;
+ USHORT Width;
+ USHORT Height;
+ ULARGE_INTEGER DiskSize;
+ PCHAR Unit;
- DPRINT("ScanForUnpartitionedDiskSpace()\n");
+ Width = ListUi->Right - ListUi->Left - 1;
+ Height = ListUi->Bottom - ListUi->Top - 2;
- if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
- {
- DPRINT1("No primary partition!\n");
-
- /* Create a partition table that represents the empty disk */
- NewPartEntry = RtlAllocateHeap(ProcessHeap,
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
- if (NewPartEntry == NULL)
- return;
-
- NewPartEntry->DiskEntry = DiskEntry;
-
- NewPartEntry->IsPartitioned = FALSE;
- NewPartEntry->StartSector.QuadPart = (ULONGLONG)DiskEntry->SectorAlignment;
- NewPartEntry->SectorCount.QuadPart = AlignDown(DiskEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment) -
- NewPartEntry->StartSector.QuadPart;
+ coPos.X = ListUi->Left + 1;
+ coPos.Y = ListUi->Top + 1 + ListUi->Line;
- 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->PrimaryPartListHead,
- &NewPartEntry->ListEntry);
-
- return;
+ DiskSize.QuadPart = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
+ if (DiskSize.QuadPart >= 10 * GB) /* 10 GB */
+ {
+ DiskSize.QuadPart = RoundingDivide(DiskSize.QuadPart, GB);
+ Unit = MUIGetString(STRING_GB);
}
-
- /* Start partition at head 1, cylinder 0 */
- LastStartSector = DiskEntry->SectorAlignment;
- LastSectorCount = 0ULL;
- LastUnusedSectorCount = 0ULL;
-
- Entry = DiskEntry->PrimaryPartListHead.Flink;
- while (Entry != &DiskEntry->PrimaryPartListHead)
+ else
{
- PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
-
- if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
- PartEntry->SectorCount.QuadPart != 0ULL)
- {
- LastUnusedSectorCount =
- PartEntry->StartSector.QuadPart - (LastStartSector + LastSectorCount);
-
- if (PartEntry->StartSector.QuadPart > (LastStartSector + LastSectorCount) &&
- LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
- {
- DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
-
- NewPartEntry = RtlAllocateHeap(ProcessHeap,
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
- if (NewPartEntry == NULL)
- return;
-
- NewPartEntry->DiskEntry = DiskEntry;
-
- NewPartEntry->IsPartitioned = FALSE;
- NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
- NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
- 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);
-
- NewPartEntry->FormatState = Unformatted;
-
- /* Insert the table into the list */
- InsertTailList(&PartEntry->ListEntry,
- &NewPartEntry->ListEntry);
- }
-
- LastStartSector = PartEntry->StartSector.QuadPart;
- LastSectorCount = PartEntry->SectorCount.QuadPart;
- }
-
- Entry = Entry->Flink;
+ DiskSize.QuadPart = RoundingDivide(DiskSize.QuadPart, MB);
+ if (DiskSize.QuadPart == 0)
+ DiskSize.QuadPart = 1;
+ Unit = MUIGetString(STRING_MB);
}
- /* Check for trailing unpartitioned disk space */
- if ((LastStartSector + LastSectorCount) < DiskEntry->SectorCount.QuadPart)
+ //
+ // FIXME: We *MUST* use TXTSETUP.SIF strings from section "DiskDriverMap" !!
+ //
+ if (DiskEntry->DriverName.Length > 0)
{
- LastUnusedSectorCount = AlignDown(DiskEntry->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
-
- if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
- {
- DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
-
- NewPartEntry = RtlAllocateHeap(ProcessHeap,
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
- if (NewPartEntry == NULL)
- return;
-
- NewPartEntry->DiskEntry = DiskEntry;
-
- NewPartEntry->IsPartitioned = FALSE;
- NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
- NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
- NewPartEntry->StartSector.QuadPart;
-
- DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
- DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
- DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
-
- NewPartEntry->FormatState = Unformatted;
-
- /* Append the table to the list */
- InsertTailList(&DiskEntry->PrimaryPartListHead,
- &NewPartEntry->ListEntry);
- }
+ sprintf(LineBuffer,
+ MUIGetString(STRING_HDINFOPARTSELECT_1),
+ DiskSize.u.LowPart,
+ Unit,
+ DiskEntry->DiskNumber,
+ DiskEntry->Port,
+ DiskEntry->Bus,
+ DiskEntry->Id,
+ &DiskEntry->DriverName,
+ DiskEntry->NoMbr ? "GPT" : "MBR");
}
-
- if (DiskEntry->ExtendedPartition != NULL)
+ else
{
- if (IsListEmpty(&DiskEntry->LogicalPartListHead))
- {
- DPRINT1("No logical partition!\n");
-
- /* Create a partition table entry that represents the empty extended partition */
- NewPartEntry = RtlAllocateHeap(ProcessHeap,
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
- if (NewPartEntry == NULL)
- return;
+ sprintf(LineBuffer,
+ MUIGetString(STRING_HDINFOPARTSELECT_2),
+ DiskSize.u.LowPart,
+ Unit,
+ DiskEntry->DiskNumber,
+ DiskEntry->Port,
+ DiskEntry->Bus,
+ DiskEntry->Id,
+ DiskEntry->NoMbr ? "GPT" : "MBR");
+ }
- NewPartEntry->DiskEntry = DiskEntry;
- NewPartEntry->LogicalPartition = TRUE;
+ if (ListUi->Line >= 0 && ListUi->Line <= Height)
+ {
+ FillConsoleOutputAttribute(StdOutput,
+ FOREGROUND_WHITE | BACKGROUND_BLUE,
+ Width,
+ coPos,
+ &Written);
- NewPartEntry->IsPartitioned = FALSE;
- NewPartEntry->StartSector.QuadPart = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
- NewPartEntry->SectorCount.QuadPart = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
+ FillConsoleOutputCharacterA(StdOutput,
+ ' ',
+ Width,
+ coPos,
+ &Written);
+ }
- 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);
+ coPos.X++;
+ if (ListUi->Line >= 0 && ListUi->Line <= Height)
+ {
+ WriteConsoleOutputCharacterA(StdOutput,
+ LineBuffer,
+ min((USHORT)strlen(LineBuffer), Width - 2),
+ coPos,
+ &Written);
+ }
- NewPartEntry->FormatState = Unformatted;
+ ListUi->Line++;
- InsertTailList(&DiskEntry->LogicalPartListHead,
- &NewPartEntry->ListEntry);
+ /* Print separator line */
+ PrintEmptyLine(ListUi);
- return;
- }
+ /* Print partition lines */
+ PrimaryEntry = DiskEntry->PrimaryPartListHead.Flink;
+ while (PrimaryEntry != &DiskEntry->PrimaryPartListHead)
+ {
+ PrimaryPartEntry = CONTAINING_RECORD(PrimaryEntry, PARTENTRY, ListEntry);
- /* Start partition at head 1, cylinder 0 */
- LastStartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
- LastSectorCount = 0ULL;
- LastUnusedSectorCount = 0ULL;
+ PrintPartitionData(ListUi,
+ DiskEntry,
+ PrimaryPartEntry);
- Entry = DiskEntry->LogicalPartListHead.Flink;
- while (Entry != &DiskEntry->LogicalPartListHead)
+ if (IsContainerPartition(PrimaryPartEntry->PartitionType))
{
- PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
-
- if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
- PartEntry->SectorCount.QuadPart != 0ULL)
+ LogicalEntry = DiskEntry->LogicalPartListHead.Flink;
+ while (LogicalEntry != &DiskEntry->LogicalPartListHead)
{
- LastUnusedSectorCount =
- PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment - (LastStartSector + LastSectorCount);
-
- if ((PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment) > (LastStartSector + LastSectorCount) &&
- LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
- {
- DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
-
- NewPartEntry = RtlAllocateHeap(ProcessHeap,
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
- if (NewPartEntry == NULL)
- return;
-
- NewPartEntry->DiskEntry = DiskEntry;
- NewPartEntry->LogicalPartition = TRUE;
-
- NewPartEntry->IsPartitioned = FALSE;
- NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
- NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
- NewPartEntry->StartSector.QuadPart;
-
- DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
- DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
- DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
-
- NewPartEntry->FormatState = Unformatted;
+ LogicalPartEntry = CONTAINING_RECORD(LogicalEntry, PARTENTRY, ListEntry);
- /* Insert the table into the list */
- InsertTailList(&PartEntry->ListEntry,
- &NewPartEntry->ListEntry);
- }
+ PrintPartitionData(ListUi,
+ DiskEntry,
+ LogicalPartEntry);
- LastStartSector = PartEntry->StartSector.QuadPart;
- LastSectorCount = PartEntry->SectorCount.QuadPart;
+ LogicalEntry = LogicalEntry->Flink;
}
-
- Entry = Entry->Flink;
}
- /* Check for trailing unpartitioned disk space */
- if ((LastStartSector + LastSectorCount) < DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart)
- {
- LastUnusedSectorCount = AlignDown(DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
-
- if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
- {
- DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
-
- NewPartEntry = RtlAllocateHeap(ProcessHeap,
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
- if (NewPartEntry == NULL)
- return;
-
- NewPartEntry->DiskEntry = DiskEntry;
- NewPartEntry->LogicalPartition = TRUE;
-
- NewPartEntry->IsPartitioned = FALSE;
- NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
- NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
- NewPartEntry->StartSector.QuadPart;
-
- DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
- DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
- DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
-
- NewPartEntry->FormatState = Unformatted;
-
- /* Append the table to the list */
- InsertTailList(&DiskEntry->LogicalPartListHead,
- &NewPartEntry->ListEntry);
- }
- }
+ PrimaryEntry = PrimaryEntry->Flink;
}
- DPRINT("ScanForUnpartitionedDiskSpace() done\n");
+ /* Print separator line */
+ PrintEmptyLine(ListUi);
}
-
-static
VOID
-SetDiskSignature(
- IN PPARTLIST List,
- IN PDISKENTRY DiskEntry)
+DrawPartitionList(
+ IN PPARTLIST_UI ListUi)
{
- LARGE_INTEGER SystemTime;
- TIME_FIELDS TimeFields;
- PLIST_ENTRY Entry2;
- PDISKENTRY DiskEntry2;
- PUCHAR Buffer;
+ PPARTLIST List = ListUi->List;
+ PLIST_ENTRY Entry, Entry2;
+ PDISKENTRY DiskEntry;
+ PPARTENTRY PartEntry = NULL;
+ COORD coPos;
+ ULONG Written;
+ SHORT i;
+ SHORT CurrentDiskLine;
+ SHORT CurrentPartLine;
+ SHORT LastLine;
+ BOOLEAN CurrentPartLineFound = FALSE;
+ BOOLEAN CurrentDiskLineFound = FALSE;
- Buffer = (PUCHAR)&DiskEntry->LayoutBuffer->Signature;
+ /* Calculate the line of the current disk and partition */
+ CurrentDiskLine = 0;
+ CurrentPartLine = 0;
+ LastLine = 0;
- while (1)
+ Entry = List->DiskListHead.Flink;
+ while (Entry != &List->DiskListHead)
{
- NtQuerySystemTime(&SystemTime);
- RtlTimeToTimeFields(&SystemTime, &TimeFields);
-
- Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF);
- Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF);
- Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF);
- Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF);
+ DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
- if (DiskEntry->LayoutBuffer->Signature == 0)
+ LastLine += 2;
+ if (CurrentPartLineFound == FALSE)
{
- continue;
+ CurrentPartLine += 2;
}
- /* check if the signature already exist */
- /* FIXME:
- * Check also signatures from disks, which are
- * not visible (bootable) by the bios.
- */
- Entry2 = List->DiskListHead.Flink;
- while (Entry2 != &List->DiskListHead)
+ Entry2 = DiskEntry->PrimaryPartListHead.Flink;
+ while (Entry2 != &DiskEntry->PrimaryPartListHead)
{
- DiskEntry2 = CONTAINING_RECORD(Entry2, DISKENTRY, ListEntry);
-
- if (DiskEntry != DiskEntry2 &&
- DiskEntry->LayoutBuffer->Signature == DiskEntry2->LayoutBuffer->Signature)
- break;
+ PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
+ if (PartEntry == List->CurrentPartition)
+ {
+ CurrentPartLineFound = TRUE;
+ }
Entry2 = Entry2->Flink;
- }
+ if (CurrentPartLineFound == FALSE)
+ {
+ CurrentPartLine++;
+ }
- if (Entry2 == &List->DiskListHead)
- break;
- }
-}
+ LastLine++;
+ }
+ if (CurrentPartLineFound == FALSE)
+ {
+ Entry2 = DiskEntry->LogicalPartListHead.Flink;
+ while (Entry2 != &DiskEntry->LogicalPartListHead)
+ {
+ PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
+ if (PartEntry == List->CurrentPartition)
+ {
+ CurrentPartLineFound = TRUE;
+ }
-static
-VOID
-UpdateDiskSignatures(
- PPARTLIST List)
-{
- PLIST_ENTRY Entry;
- PDISKENTRY DiskEntry;
+ Entry2 = Entry2->Flink;
+ if (CurrentPartLineFound == FALSE)
+ {
+ CurrentPartLine++;
+ }
- /* Print partition lines*/
- Entry = List->DiskListHead.Flink;
- while (Entry != &List->DiskListHead)
- {
- DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
+ LastLine++;
+ }
+ }
- if (DiskEntry->LayoutBuffer &&
- DiskEntry->LayoutBuffer->Signature == 0)
+ if (DiskEntry == List->CurrentDisk)
{
- SetDiskSignature(List, DiskEntry);
- DiskEntry->LayoutBuffer->PartitionEntry[0].RewritePartition = TRUE;
+ CurrentDiskLineFound = TRUE;
}
Entry = Entry->Flink;
- }
-}
-
+ if (Entry != &List->DiskListHead)
+ {
+ if (CurrentDiskLineFound == FALSE)
+ {
+ CurrentPartLine ++;
+ CurrentDiskLine = CurrentPartLine;
+ }
-static
-VOID
-AddDiskToList(
- HANDLE FileHandle,
- ULONG DiskNumber,
- PPARTLIST List)
-{
- DISK_GEOMETRY DiskGeometry;
- SCSI_ADDRESS ScsiAddress;
- PDISKENTRY DiskEntry;
- IO_STATUS_BLOCK Iosb;
- NTSTATUS Status;
- PPARTITION_SECTOR Mbr;
- PULONG Buffer;
- LARGE_INTEGER FileOffset;
- WCHAR Identifier[20];
- ULONG Checksum;
- ULONG Signature;
- ULONG i;
- PLIST_ENTRY ListEntry;
- PBIOSDISKENTRY BiosDiskEntry;
- ULONG LayoutBufferSize;
- PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
-
- Status = NtDeviceIoControlFile(FileHandle,
- NULL,
- NULL,
- NULL,
- &Iosb,
- IOCTL_DISK_GET_DRIVE_GEOMETRY,
- NULL,
- 0,
- &DiskGeometry,
- sizeof(DISK_GEOMETRY));
- if (!NT_SUCCESS(Status))
- {
- return;
+ LastLine++;
+ }
+ else
+ {
+ LastLine--;
+ }
}
- if (DiskGeometry.MediaType != FixedMedia &&
- DiskGeometry.MediaType != RemovableMedia)
+ /* If it possible, make the disk name visible */
+ if (CurrentPartLine < ListUi->Offset)
{
- return;
+ ListUi->Offset = CurrentPartLine;
}
-
- Status = NtDeviceIoControlFile(FileHandle,
- NULL,
- NULL,
- NULL,
- &Iosb,
- IOCTL_SCSI_GET_ADDRESS,
- NULL,
- 0,
- &ScsiAddress,
- sizeof(SCSI_ADDRESS));
- if (!NT_SUCCESS(Status))
+ else if (CurrentPartLine - ListUi->Offset > ListUi->Bottom - ListUi->Top - 2)
{
- return;
+ ListUi->Offset = CurrentPartLine - (ListUi->Bottom - ListUi->Top - 2);
}
- Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(ProcessHeap,
- 0,
- DiskGeometry.BytesPerSector);
- if (Mbr == NULL)
+ if (CurrentDiskLine < ListUi->Offset && CurrentPartLine - CurrentDiskLine < ListUi->Bottom - ListUi->Top - 2)
{
- return;
+ ListUi->Offset = CurrentDiskLine;
}
- FileOffset.QuadPart = 0;
- Status = NtReadFile(FileHandle,
- NULL,
- NULL,
- NULL,
- &Iosb,
- (PVOID)Mbr,
- DiskGeometry.BytesPerSector,
- &FileOffset,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeHeap(ProcessHeap, 0, Mbr);
- DPRINT1("NtReadFile failed, status=%x\n", Status);
- return;
- }
- Signature = Mbr->Signature;
+ /* Draw upper left corner */
+ coPos.X = ListUi->Left;
+ coPos.Y = ListUi->Top;
+ FillConsoleOutputCharacterA(StdOutput,
+ 0xDA, // '+',
+ 1,
+ coPos,
+ &Written);
- /* Calculate the MBR checksum */
- Checksum = 0;
- Buffer = (PULONG)Mbr;
- for (i = 0; i < 128; i++)
+ /* Draw upper edge */
+ coPos.X = ListUi->Left + 1;
+ coPos.Y = ListUi->Top;
+ if (ListUi->Offset == 0)
{
- Checksum += Buffer[i];
+ FillConsoleOutputCharacterA(StdOutput,
+ 0xC4, // '-',
+ ListUi->Right - ListUi->Left - 1,
+ coPos,
+ &Written);
}
- Checksum = ~Checksum + 1;
-
- swprintf(Identifier, L"%08x-%08x-A", Checksum, Signature);
- DPRINT("Identifier: %S\n", Identifier);
-
- DiskEntry = RtlAllocateHeap(ProcessHeap,
- HEAP_ZERO_MEMORY,
- sizeof(DISKENTRY));
- if (DiskEntry == NULL)
+ else
{
- return;
+ FillConsoleOutputCharacterA(StdOutput,
+ 0xC4, // '-',
+ ListUi->Right - ListUi->Left - 5,
+ coPos,
+ &Written);
+ coPos.X = ListUi->Right - 5;
+ WriteConsoleOutputCharacterA(StdOutput,
+ "(\x18)", // "(up)"
+ 3,
+ coPos,
+ &Written);
+ coPos.X = ListUi->Right - 2;
+ FillConsoleOutputCharacterA(StdOutput,
+ 0xC4, // '-',
+ 2,
+ coPos,
+ &Written);
}
-// DiskEntry->Checksum = Checksum;
-// DiskEntry->Signature = Signature;
- 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);
+ /* Draw upper right corner */
+ coPos.X = ListUi->Right;
+ coPos.Y = ListUi->Top;
+ FillConsoleOutputCharacterA(StdOutput,
+ 0xBF, // '+',
+ 1,
+ coPos,
+ &Written);
- ListEntry = List->BiosDiskListHead.Flink;
- while (ListEntry != &List->BiosDiskListHead)
+ /* Draw left and right edge */
+ for (i = ListUi->Top + 1; i < ListUi->Bottom; i++)
{
- BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
- /* FIXME:
- * Compare the size from bios and the reported size from driver.
- * If we have more than one disk with a zero or with the same signatur
- * we must create new signatures and reboot. After the reboot,
- * it is possible to identify the disks.
- */
- if (BiosDiskEntry->Signature == Signature &&
- BiosDiskEntry->Checksum == Checksum &&
- !BiosDiskEntry->Recognized)
- {
- if (!DiskEntry->BiosFound)
- {
- DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber;
- DiskEntry->BiosFound = TRUE;
- BiosDiskEntry->Recognized = TRUE;
- }
- else
- {
- }
- }
- ListEntry = ListEntry->Flink;
- }
-
- if (!DiskEntry->BiosFound)
- {
-#if 0
- RtlFreeHeap(ProcessHeap, 0, DiskEntry);
- return;
-#else
- DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %d is not be bootable by the BIOS!\n", DiskNumber);
-#endif
- }
-
- InitializeListHead(&DiskEntry->PrimaryPartListHead);
- InitializeListHead(&DiskEntry->LogicalPartListHead);
-
- DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
- DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
- DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
- DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
-
- DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders);
- DPRINT("TracksPerCylinder %lu\n", DiskEntry->TracksPerCylinder);
- DPRINT("SectorsPerTrack %lu\n", DiskEntry->SectorsPerTrack);
- DPRINT("BytesPerSector %lu\n", DiskEntry->BytesPerSector);
-
- DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart *
- (ULONGLONG)DiskGeometry.TracksPerCylinder *
- (ULONGLONG)DiskGeometry.SectorsPerTrack;
-
- DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
- DiskEntry->CylinderAlignment = DiskGeometry.TracksPerCylinder *
- DiskGeometry.SectorsPerTrack;
-
- DPRINT("SectorCount %I64u\n", DiskEntry->SectorCount.QuadPart);
- DPRINT("SectorAlignment %lu\n", DiskEntry->SectorAlignment);
-
- DiskEntry->DiskNumber = DiskNumber;
- DiskEntry->Port = ScsiAddress.PortNumber;
- DiskEntry->Bus = ScsiAddress.PathId;
- DiskEntry->Id = ScsiAddress.TargetId;
-
- GetDriverName(DiskEntry);
-
- InsertAscendingList(&List->DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber);
-
- /* Allocate a layout buffer with 4 partition entries first */
- LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
- ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
- DiskEntry->LayoutBuffer = RtlAllocateHeap(ProcessHeap,
- HEAP_ZERO_MEMORY,
- LayoutBufferSize);
- if (DiskEntry->LayoutBuffer == NULL)
- {
- DPRINT1("Failed to allocate the disk layout buffer!\n");
- return;
- }
-
- for (;;)
- {
- DPRINT1("Buffer size: %lu\n", LayoutBufferSize);
- Status = NtDeviceIoControlFile(FileHandle,
- NULL,
- NULL,
- NULL,
- &Iosb,
- IOCTL_DISK_GET_DRIVE_LAYOUT,
- NULL,
- 0,
- DiskEntry->LayoutBuffer,
- LayoutBufferSize);
- if (NT_SUCCESS(Status))
- break;
-
- if (Status != STATUS_BUFFER_TOO_SMALL)
- {
- DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status);
- return;
- }
-
- LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION);
- NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap,
- HEAP_ZERO_MEMORY,
- DiskEntry->LayoutBuffer,
- LayoutBufferSize);
- if (NewLayoutBuffer == NULL)
- {
- DPRINT1("Failed to reallocate the disk layout buffer!\n");
- return;
- }
-
- DiskEntry->LayoutBuffer = NewLayoutBuffer;
- }
-
- DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount);
-
-#ifdef DUMP_PARTITION_TABLE
- DumpPartitionTable(DiskEntry);
-#endif
-
- if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
- DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0 &&
- DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionType != 0)
- {
- if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
- {
- DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
- }
- else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
- {
- DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
- }
- else
- {
- DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
- }
- }
- else
- {
- DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
- }
-
-
- if (DiskEntry->LayoutBuffer->PartitionCount == 0)
- {
- DiskEntry->NewDisk = TRUE;
- DiskEntry->LayoutBuffer->PartitionCount = 4;
-
- for (i = 0; i < 4; i++)
- DiskEntry->LayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
- }
- else
- {
- for (i = 0; i < 4; i++)
- {
- AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
- }
-
- for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
- {
- AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
- }
- }
-
- ScanForUnpartitionedDiskSpace(DiskEntry);
-}
-
-
-PPARTLIST
-CreatePartitionList(
- SHORT Left,
- SHORT Top,
- SHORT Right,
- SHORT Bottom)
-{
- PPARTLIST List;
- OBJECT_ATTRIBUTES ObjectAttributes;
- SYSTEM_DEVICE_INFORMATION Sdi;
- IO_STATUS_BLOCK Iosb;
- ULONG ReturnSize;
- NTSTATUS Status;
- ULONG DiskNumber;
- WCHAR Buffer[MAX_PATH];
- UNICODE_STRING Name;
- HANDLE FileHandle;
-
- List = (PPARTLIST)RtlAllocateHeap(ProcessHeap,
- 0,
- sizeof (PARTLIST));
- if (List == NULL)
- return NULL;
-
- List->Left = Left;
- List->Top = Top;
- List->Right = Right;
- List->Bottom = Bottom;
-
- List->Line = 0;
- List->Offset = 0;
-
- List->CurrentDisk = NULL;
- List->CurrentPartition = NULL;
-
- List->SystemDisk = NULL;
- List->SystemPartition = NULL;
- List->OriginalSystemDisk = NULL;
- List->OriginalSystemPartition = NULL;
-
- List->TempDisk = NULL;
- List->TempPartition = NULL;
- List->FormatState = Start;
-
- InitializeListHead(&List->DiskListHead);
- InitializeListHead(&List->BiosDiskListHead);
-
- EnumerateBiosDiskEntries(List);
-
- Status = NtQuerySystemInformation(SystemDeviceInformation,
- &Sdi,
- sizeof(SYSTEM_DEVICE_INFORMATION),
- &ReturnSize);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeHeap(ProcessHeap, 0, List);
- return NULL;
- }
-
- for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
- {
- swprintf(Buffer,
- L"\\Device\\Harddisk%d\\Partition0",
- DiskNumber);
- RtlInitUnicodeString(&Name,
- Buffer);
-
- InitializeObjectAttributes(&ObjectAttributes,
- &Name,
- 0,
- NULL,
- NULL);
-
- Status = NtOpenFile(&FileHandle,
- FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
- &ObjectAttributes,
- &Iosb,
- FILE_SHARE_READ,
- FILE_SYNCHRONOUS_IO_NONALERT);
- if (NT_SUCCESS(Status))
- {
- AddDiskToList(FileHandle, DiskNumber, List);
-
- NtClose(FileHandle);
- }
- }
-
- UpdateDiskSignatures(List);
-
- AssignDriveLetters(List);
-
- /* Search for first usable disk and partition */
- if (IsListEmpty(&List->DiskListHead))
- {
- List->CurrentDisk = NULL;
- List->CurrentPartition = NULL;
- }
- else
- {
- List->CurrentDisk = CONTAINING_RECORD(List->DiskListHead.Flink,
- DISKENTRY,
- ListEntry);
-
- if (IsListEmpty(&List->CurrentDisk->PrimaryPartListHead))
- {
- List->CurrentPartition = 0;
- }
- else
- {
- List->CurrentPartition = CONTAINING_RECORD(List->CurrentDisk->PrimaryPartListHead.Flink,
- PARTENTRY,
- ListEntry);
- }
- }
-
- return List;
-}
-
-
-VOID
-DestroyPartitionList(
- PPARTLIST List)
-{
- PDISKENTRY DiskEntry;
- PBIOSDISKENTRY BiosDiskEntry;
- PPARTENTRY PartEntry;
- PLIST_ENTRY Entry;
-
- /* Release disk and partition info */
- while (!IsListEmpty(&List->DiskListHead))
- {
- Entry = RemoveHeadList(&List->DiskListHead);
- DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
-
- /* Release driver name */
- RtlFreeUnicodeString(&DiskEntry->DriverName);
-
- /* Release primary partition list */
- while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
- {
- Entry = RemoveHeadList(&DiskEntry->PrimaryPartListHead);
- PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
-
- RtlFreeHeap(ProcessHeap, 0, PartEntry);
- }
-
- /* Release logical partition list */
- while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
- {
- Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
- PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
-
- RtlFreeHeap(ProcessHeap, 0, PartEntry);
- }
-
- /* Release layout buffer */
- if (DiskEntry->LayoutBuffer != NULL)
- RtlFreeHeap(ProcessHeap, 0, DiskEntry->LayoutBuffer);
-
-
- /* Release disk entry */
- RtlFreeHeap(ProcessHeap, 0, DiskEntry);
- }
-
- /* Release the bios disk info */
- while (!IsListEmpty(&List->BiosDiskListHead))
- {
- Entry = RemoveHeadList(&List->BiosDiskListHead);
- BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
-
- RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
- }
-
- /* Release list head */
- RtlFreeHeap(ProcessHeap, 0, List);
-}
-
-
-static
-VOID
-PrintEmptyLine(
- PPARTLIST List)
-{
- COORD coPos;
- DWORD Written;
- USHORT Width;
- USHORT Height;
-
- Width = List->Right - List->Left - 1;
- Height = List->Bottom - List->Top - 2;
-
- coPos.X = List->Left + 1;
- coPos.Y = List->Top + 1 + List->Line;
-
- if (List->Line >= 0 && List->Line <= Height)
- {
- FillConsoleOutputAttribute(StdOutput,
- FOREGROUND_WHITE | BACKGROUND_BLUE,
- Width,
- coPos,
- &Written);
-
- FillConsoleOutputCharacterA(StdOutput,
- ' ',
- Width,
- coPos,
- &Written);
- }
-
- List->Line++;
-}
-
-
-static
-VOID
-PrintPartitionData(
- PPARTLIST List,
- PDISKENTRY DiskEntry,
- PPARTENTRY PartEntry)
-{
- CHAR LineBuffer[128];
- COORD coPos;
- DWORD Written;
- USHORT Width;
- USHORT Height;
- LARGE_INTEGER PartSize;
- PCHAR Unit;
- UCHAR Attribute;
- CHAR PartTypeString[32];
- PCHAR PartType;
- PartType = PartTypeString;
-
- Width = List->Right - List->Left - 1;
- Height = List->Bottom - List->Top - 2;
-
- coPos.X = List->Left + 1;
- coPos.Y = List->Top + 1 + List->Line;
-
- if (PartEntry->IsPartitioned == FALSE)
- {
- PartSize.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
-#if 0
- if (PartSize.QuadPart >= 10737418240) /* 10 GB */
- {
- PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1073741824);
- Unit = MUIGetString(STRING_GB);
- }
- else
-#endif
- if (PartSize.QuadPart >= 10485760) /* 10 MB */
- {
- PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1048576);
- Unit = MUIGetString(STRING_MB);
- }
- else
- {
- PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1024);
- Unit = MUIGetString(STRING_KB);
- }
-
- sprintf(LineBuffer,
- MUIGetString(STRING_UNPSPACE),
- PartEntry->LogicalPartition ? " " : "",
- PartEntry->LogicalPartition ? "" : " ",
- PartSize.u.LowPart,
- Unit);
- }
- else
- {
- /* Determine partition type */
- PartTypeString[0] = '\0';
- if (PartEntry->New != FALSE)
- {
- PartType = MUIGetString(STRING_UNFORMATTED);
- }
- else if (PartEntry->IsPartitioned != FALSE)
- {
- GetPartTypeStringFromPartitionType(PartEntry->PartitionType,
- PartTypeString,
- ARRAYSIZE(PartTypeString));
- PartType = PartTypeString;
- }
-
- PartSize.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
-#if 0
- if (PartSize.QuadPart >= 10737418240) /* 10 GB */
- {
- PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1073741824);
- Unit = MUIGetString(STRING_GB);
- }
- else
-#endif
- if (PartSize.QuadPart >= 10485760) /* 10 MB */
- {
- PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1048576);
- Unit = MUIGetString(STRING_MB);
- }
- else
- {
- PartSize.QuadPart = RoundingDivide(PartSize.QuadPart, 1024);
- Unit = MUIGetString(STRING_KB);
- }
-
- if (strcmp(PartType, MUIGetString(STRING_FORMATUNKNOWN)) == 0)
- {
- sprintf(LineBuffer,
- MUIGetString(STRING_HDDINFOUNK5),
- (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
- (PartEntry->DriveLetter == 0) ? '-' : ':',
- PartEntry->BootIndicator ? '*' : ' ',
- PartEntry->LogicalPartition ? " " : "",
- PartEntry->PartitionType,
- PartEntry->LogicalPartition ? "" : " ",
- PartSize.u.LowPart,
- Unit);
- }
- else
- {
- sprintf(LineBuffer,
- "%c%c %c %s%-24s%s %6lu %s",
- (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
- (PartEntry->DriveLetter == 0) ? '-' : ':',
- PartEntry->BootIndicator ? '*' : ' ',
- PartEntry->LogicalPartition ? " " : "",
- PartType,
- PartEntry->LogicalPartition ? "" : " ",
- PartSize.u.LowPart,
- Unit);
- }
- }
-
- Attribute = (List->CurrentDisk == DiskEntry &&
- List->CurrentPartition == PartEntry) ?
- FOREGROUND_BLUE | BACKGROUND_WHITE :
- FOREGROUND_WHITE | BACKGROUND_BLUE;
-
- if (List->Line >= 0 && List->Line <= Height)
- {
- FillConsoleOutputCharacterA(StdOutput,
- ' ',
- Width,
- coPos,
- &Written);
- }
- coPos.X += 4;
- Width -= 8;
- if (List->Line >= 0 && List->Line <= Height)
- {
- FillConsoleOutputAttribute(StdOutput,
- Attribute,
- Width,
- coPos,
- &Written);
- }
- coPos.X++;
- Width -= 2;
- if (List->Line >= 0 && List->Line <= Height)
- {
- WriteConsoleOutputCharacterA(StdOutput,
- LineBuffer,
- min(strlen(LineBuffer), Width),
- coPos,
- &Written);
- }
-
- List->Line++;
-}
-
-
-static
-VOID
-PrintDiskData(
- PPARTLIST List,
- PDISKENTRY DiskEntry)
-{
- PPARTENTRY PrimaryPartEntry, LogicalPartEntry;
- PLIST_ENTRY PrimaryEntry, LogicalEntry;
- CHAR LineBuffer[128];
- COORD coPos;
- DWORD Written;
- USHORT Width;
- USHORT Height;
- ULARGE_INTEGER DiskSize;
- PCHAR Unit;
-
- Width = List->Right - List->Left - 1;
- Height = List->Bottom - List->Top - 2;
-
- coPos.X = List->Left + 1;
- coPos.Y = List->Top + 1 + List->Line;
-
- DiskSize.QuadPart = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
- if (DiskSize.QuadPart >= 10737418240) /* 10 GB */
- {
- DiskSize.QuadPart = RoundingDivide(DiskSize.QuadPart, 1073741824);
- Unit = MUIGetString(STRING_GB);
- }
- else
- {
- DiskSize.QuadPart = RoundingDivide(DiskSize.QuadPart, 1048576);
- if (DiskSize.QuadPart == 0)
- DiskSize.QuadPart = 1;
- Unit = MUIGetString(STRING_MB);
- }
-
- if (DiskEntry->DriverName.Length > 0)
- {
- sprintf(LineBuffer,
- MUIGetString(STRING_HDINFOPARTSELECT),
- DiskSize.u.LowPart,
- Unit,
- DiskEntry->DiskNumber,
- DiskEntry->Port,
- DiskEntry->Bus,
- DiskEntry->Id,
- DiskEntry->DriverName.Buffer);
- }
- else
- {
- sprintf(LineBuffer,
- MUIGetString(STRING_HDDINFOUNK6),
- DiskSize.u.LowPart,
- Unit,
- DiskEntry->DiskNumber,
- DiskEntry->Port,
- DiskEntry->Bus,
- DiskEntry->Id);
- }
-
- if (List->Line >= 0 && List->Line <= Height)
- {
- FillConsoleOutputAttribute(StdOutput,
- FOREGROUND_WHITE | BACKGROUND_BLUE,
- Width,
- coPos,
- &Written);
-
- FillConsoleOutputCharacterA(StdOutput,
- ' ',
- Width,
- coPos,
- &Written);
- }
-
- coPos.X++;
- if (List->Line >= 0 && List->Line <= Height)
- {
- WriteConsoleOutputCharacterA(StdOutput,
- LineBuffer,
- min((USHORT)strlen(LineBuffer), Width - 2),
- coPos,
- &Written);
- }
-
- List->Line++;
-
- /* Print separator line */
- PrintEmptyLine(List);
-
- /* Print partition lines */
- PrimaryEntry = DiskEntry->PrimaryPartListHead.Flink;
- while (PrimaryEntry != &DiskEntry->PrimaryPartListHead)
- {
- PrimaryPartEntry = CONTAINING_RECORD(PrimaryEntry, PARTENTRY, ListEntry);
-
- PrintPartitionData(List,
- DiskEntry,
- PrimaryPartEntry);
-
- if (IsContainerPartition(PrimaryPartEntry->PartitionType))
- {
- LogicalEntry = DiskEntry->LogicalPartListHead.Flink;
- while (LogicalEntry != &DiskEntry->LogicalPartListHead)
- {
- LogicalPartEntry = CONTAINING_RECORD(LogicalEntry, PARTENTRY, ListEntry);
-
- PrintPartitionData(List,
- DiskEntry,
- LogicalPartEntry);
-
- LogicalEntry = LogicalEntry->Flink;
- }
- }
-
- PrimaryEntry = PrimaryEntry->Flink;
- }
-
- /* Print separator line */
- PrintEmptyLine(List);
-}
-
-
-VOID
-DrawPartitionList(
- PPARTLIST List)
-{
- PLIST_ENTRY Entry, Entry2;
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry = NULL;
- COORD coPos;
- DWORD Written;
- SHORT i;
- SHORT CurrentDiskLine;
- SHORT CurrentPartLine;
- SHORT LastLine;
- BOOL CurrentPartLineFound = FALSE;
- BOOL CurrentDiskLineFound = FALSE;
-
- /* Calculate the line of the current disk and partition */
- CurrentDiskLine = 0;
- CurrentPartLine = 0;
- LastLine = 0;
-
- Entry = List->DiskListHead.Flink;
- while (Entry != &List->DiskListHead)
- {
- DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
-
- LastLine += 2;
- if (CurrentPartLineFound == FALSE)
- {
- CurrentPartLine += 2;
- }
-
- Entry2 = DiskEntry->PrimaryPartListHead.Flink;
- while (Entry2 != &DiskEntry->PrimaryPartListHead)
- {
- PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
- if (PartEntry == List->CurrentPartition)
- {
- CurrentPartLineFound = TRUE;
- }
-
- Entry2 = Entry2->Flink;
- if (CurrentPartLineFound == FALSE)
- {
- CurrentPartLine++;
- }
-
- LastLine++;
- }
-
- if (CurrentPartLineFound == FALSE)
- {
- Entry2 = DiskEntry->LogicalPartListHead.Flink;
- while (Entry2 != &DiskEntry->LogicalPartListHead)
- {
- PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
- if (PartEntry == List->CurrentPartition)
- {
- CurrentPartLineFound = TRUE;
- }
-
- Entry2 = Entry2->Flink;
- if (CurrentPartLineFound == FALSE)
- {
- CurrentPartLine++;
- }
-
- LastLine++;
- }
- }
-
- if (DiskEntry == List->CurrentDisk)
- {
- CurrentDiskLineFound = TRUE;
- }
-
- Entry = Entry->Flink;
- if (Entry != &List->DiskListHead)
- {
- if (CurrentDiskLineFound == FALSE)
- {
- CurrentPartLine ++;
- CurrentDiskLine = CurrentPartLine;
- }
-
- LastLine++;
- }
- else
- {
- LastLine--;
- }
- }
-
- /* If it possible, make the disk name visible */
- if (CurrentPartLine < List->Offset)
- {
- List->Offset = CurrentPartLine;
- }
- else if (CurrentPartLine - List->Offset > List->Bottom - List->Top - 2)
- {
- List->Offset = CurrentPartLine - (List->Bottom - List->Top - 2);
- }
-
- if (CurrentDiskLine < List->Offset && CurrentPartLine - CurrentDiskLine < List->Bottom - List->Top - 2)
- {
- List->Offset = CurrentDiskLine;
- }
-
- /* draw upper left corner */
- coPos.X = List->Left;
- coPos.Y = List->Top;
- FillConsoleOutputCharacterA(StdOutput,
- 0xDA, // '+',
- 1,
- coPos,
- &Written);
-
- /* draw upper edge */
- coPos.X = List->Left + 1;
- coPos.Y = List->Top;
- if (List->Offset == 0)
- {
- FillConsoleOutputCharacterA(StdOutput,
- 0xC4, // '-',
- List->Right - List->Left - 1,
- coPos,
- &Written);
- }
- else
- {
- FillConsoleOutputCharacterA(StdOutput,
- 0xC4, // '-',
- List->Right - List->Left - 5,
- coPos,
- &Written);
- coPos.X = List->Right - 5;
- WriteConsoleOutputCharacterA(StdOutput,
- "(\x18)", // "(up)"
- 3,
- coPos,
- &Written);
- coPos.X = List->Right - 2;
- FillConsoleOutputCharacterA(StdOutput,
- 0xC4, // '-',
- 2,
- coPos,
- &Written);
- }
-
- /* draw upper right corner */
- coPos.X = List->Right;
- coPos.Y = List->Top;
- FillConsoleOutputCharacterA(StdOutput,
- 0xBF, // '+',
- 1,
- coPos,
- &Written);
-
- /* draw left and right edge */
- for (i = List->Top + 1; i < List->Bottom; i++)
- {
- coPos.X = List->Left;
- coPos.Y = i;
- FillConsoleOutputCharacterA(StdOutput,
- 0xB3, // '|',
- 1,
- coPos,
- &Written);
-
- coPos.X = List->Right;
- FillConsoleOutputCharacterA(StdOutput,
- 0xB3, //'|',
- 1,
- coPos,
- &Written);
- }
-
- /* draw lower left corner */
- coPos.X = List->Left;
- coPos.Y = List->Bottom;
- FillConsoleOutputCharacterA(StdOutput,
- 0xC0, // '+',
- 1,
- coPos,
- &Written);
-
- /* draw lower edge */
- coPos.X = List->Left + 1;
- coPos.Y = List->Bottom;
- if (LastLine - List->Offset <= List->Bottom - List->Top - 2)
- {
- FillConsoleOutputCharacterA(StdOutput,
- 0xC4, // '-',
- List->Right - List->Left - 1,
- coPos,
- &Written);
- }
- else
- {
- FillConsoleOutputCharacterA(StdOutput,
- 0xC4, // '-',
- List->Right - List->Left - 5,
- coPos,
- &Written);
- coPos.X = List->Right - 5;
- WriteConsoleOutputCharacterA(StdOutput,
- "(\x19)", // "(down)"
- 3,
- coPos,
- &Written);
- coPos.X = List->Right - 2;
- FillConsoleOutputCharacterA(StdOutput,
- 0xC4, // '-',
- 2,
- coPos,
- &Written);
- }
-
- /* draw lower right corner */
- coPos.X = List->Right;
- coPos.Y = List->Bottom;
- FillConsoleOutputCharacterA(StdOutput,
- 0xD9, // '+',
- 1,
- coPos,
- &Written);
-
- /* print list entries */
- List->Line = - List->Offset;
-
- Entry = List->DiskListHead.Flink;
- while (Entry != &List->DiskListHead)
- {
- DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
-
- /* Print disk entry */
- PrintDiskData(List,
- DiskEntry);
-
- Entry = Entry->Flink;
- }
-}
-
-
-DWORD
-SelectPartition(
- PPARTLIST List,
- ULONG DiskNumber,
- ULONG PartitionNumber)
-{
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
- PLIST_ENTRY Entry1;
- PLIST_ENTRY Entry2;
-
- /* Check for empty disks */
- if (IsListEmpty(&List->DiskListHead))
- return FALSE;
-
- /* Check for first usable entry on next disk */
- Entry1 = List->CurrentDisk->ListEntry.Flink;
- while (Entry1 != &List->DiskListHead)
- {
- DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
-
- if (DiskEntry->DiskNumber == DiskNumber)
- {
- Entry2 = DiskEntry->PrimaryPartListHead.Flink;
- while (Entry2 != &DiskEntry->PrimaryPartListHead)
- {
- PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
-
- if (PartEntry->PartitionNumber == PartitionNumber)
- {
- List->CurrentDisk = DiskEntry;
- List->CurrentPartition = PartEntry;
- DrawPartitionList(List);
- return TRUE;
- }
-
- Entry2 = Entry2->Flink;
- }
-
- return FALSE;
- }
-
- Entry1 = Entry1->Flink;
- }
-
- return FALSE;
-}
-
-
-BOOL
-ScrollDownPartitionList(
- PPARTLIST List)
-{
- PLIST_ENTRY DiskListEntry;
- PLIST_ENTRY PartListEntry;
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
-
- /* Fail, if no disks are available */
- if (IsListEmpty(&List->DiskListHead))
- return FALSE;
-
- /* Check for next usable entry on current disk */
- if (List->CurrentPartition != NULL)
- {
- if (List->CurrentPartition->LogicalPartition)
- {
- /* Logical partition */
-
- PartListEntry = List->CurrentPartition->ListEntry.Flink;
- if (PartListEntry != &List->CurrentDisk->LogicalPartListHead)
- {
- /* Next logical partition */
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
-
- List->CurrentPartition = PartEntry;
- return TRUE;
- }
- else
- {
- PartListEntry = List->CurrentDisk->ExtendedPartition->ListEntry.Flink;
- if (PartListEntry != &List->CurrentDisk->PrimaryPartListHead)
- {
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
-
- List->CurrentPartition = PartEntry;
- return TRUE;
- }
- }
- }
- else
- {
- /* Primary or extended partition */
-
- if ((List->CurrentPartition->IsPartitioned != FALSE) &&
- IsContainerPartition(List->CurrentPartition->PartitionType))
- {
- /* First logical partition */
- PartListEntry = List->CurrentDisk->LogicalPartListHead.Flink;
- if (PartListEntry != &List->CurrentDisk->LogicalPartListHead)
- {
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
-
- List->CurrentPartition = PartEntry;
- return TRUE;
- }
- }
- else
- {
- /* Next primary partition */
- PartListEntry = List->CurrentPartition->ListEntry.Flink;
- if (PartListEntry != &List->CurrentDisk->PrimaryPartListHead)
- {
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
-
- List->CurrentPartition = PartEntry;
- return TRUE;
- }
- }
- }
- }
-
- /* Search for the first partition entry on the next disk */
- DiskListEntry = List->CurrentDisk->ListEntry.Flink;
- while (DiskListEntry != &List->DiskListHead)
- {
- DiskEntry = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
-
- PartListEntry = DiskEntry->PrimaryPartListHead.Flink;
- if (PartListEntry != &DiskEntry->PrimaryPartListHead)
- {
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
-
- List->CurrentDisk = DiskEntry;
- List->CurrentPartition = PartEntry;
- return TRUE;
- }
-
- DiskListEntry = DiskListEntry->Flink;
- }
-
- return FALSE;
-}
-
-
-BOOL
-ScrollUpPartitionList(
- PPARTLIST List)
-{
- PLIST_ENTRY DiskListEntry;
- PLIST_ENTRY PartListEntry;
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
-
- /* Fail, if no disks are available */
- if (IsListEmpty(&List->DiskListHead))
- return FALSE;
-
- /* Check for previous usable entry on current disk */
- if (List->CurrentPartition != NULL)
- {
- if (List->CurrentPartition->LogicalPartition)
- {
- /* Logical partition */
- PartListEntry = List->CurrentPartition->ListEntry.Blink;
- if (PartListEntry != &List->CurrentDisk->LogicalPartListHead)
- {
- /* Previous logical partition */
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
- }
- else
- {
- /* Extended partition*/
- PartEntry = List->CurrentDisk->ExtendedPartition;
- }
-
- List->CurrentPartition = PartEntry;
- return TRUE;
- }
- else
- {
- /* Primary or extended partition */
-
- PartListEntry = List->CurrentPartition->ListEntry.Blink;
- if (PartListEntry != &List->CurrentDisk->PrimaryPartListHead)
- {
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
-
- if ((PartEntry->IsPartitioned != FALSE) &&
- IsContainerPartition(PartEntry->PartitionType))
- {
- PartListEntry = List->CurrentDisk->LogicalPartListHead.Blink;
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
- }
-
- List->CurrentPartition = PartEntry;
- return TRUE;
- }
-
- }
- }
-
- /* Search for the last partition entry on the previous disk */
- DiskListEntry = List->CurrentDisk->ListEntry.Blink;
- while (DiskListEntry != &List->DiskListHead)
- {
- DiskEntry = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
-
- PartListEntry = DiskEntry->PrimaryPartListHead.Blink;
- if (PartListEntry != &DiskEntry->PrimaryPartListHead)
- {
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
-
- if ((PartEntry->IsPartitioned != FALSE) &&
- IsContainerPartition(PartEntry->PartitionType))
- {
- PartListEntry = DiskEntry->LogicalPartListHead.Blink;
- if (PartListEntry != &DiskEntry->LogicalPartListHead)
- {
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
-
- List->CurrentDisk = DiskEntry;
- List->CurrentPartition = PartEntry;
- return TRUE;
- }
- }
- else
- {
- List->CurrentDisk = DiskEntry;
- List->CurrentPartition = PartEntry;
- return TRUE;
- }
- }
-
- DiskListEntry = DiskListEntry->Blink;
- }
-
- return FALSE;
-}
-
-
-static
-BOOLEAN
-IsEmptyLayoutEntry(
- PPARTITION_INFORMATION PartitionInfo)
-{
- if (PartitionInfo->StartingOffset.QuadPart == 0 &&
- PartitionInfo->PartitionLength.QuadPart == 0)
- return TRUE;
-
- return FALSE;
-}
-
-
-static
-BOOLEAN
-IsSamePrimaryLayoutEntry(
- IN PPARTITION_INFORMATION PartitionInfo,
- IN PDISKENTRY DiskEntry,
- IN PPARTENTRY PartEntry)
-{
- if (PartitionInfo->StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector &&
- PartitionInfo->PartitionLength.QuadPart == PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector)
-// PartitionInfo->PartitionNumber = PartEntry->PartitionNumber &&
-// PartitionInfo->PartitionType == PartEntry->PartitionType
- return TRUE;
-
- return FALSE;
-}
-
-
-static
-ULONG
-GetPrimaryPartitionCount(
- IN PDISKENTRY DiskEntry)
-{
- PLIST_ENTRY Entry;
- PPARTENTRY PartEntry;
- ULONG Count = 0;
-
- Entry = DiskEntry->PrimaryPartListHead.Flink;
- while (Entry != &DiskEntry->PrimaryPartListHead)
- {
- PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
- if (PartEntry->IsPartitioned == TRUE)
- Count++;
-
- Entry = Entry->Flink;
- }
-
- return Count;
-}
-
-
-static
-ULONG
-GetLogicalPartitionCount(
- PDISKENTRY DiskEntry)
-{
- PLIST_ENTRY ListEntry;
- PPARTENTRY PartEntry;
- ULONG Count = 0;
-
- ListEntry = DiskEntry->LogicalPartListHead.Flink;
- while (ListEntry != &DiskEntry->LogicalPartListHead)
- {
- PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
- if (PartEntry->IsPartitioned)
- Count++;
-
- ListEntry = ListEntry->Flink;
- }
-
- return Count;
-}
-
-
-static
-BOOL
-ReAllocateLayoutBuffer(
- PDISKENTRY DiskEntry)
-{
- PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
- ULONG NewPartitionCount;
- ULONG CurrentPartitionCount = 0;
- ULONG LayoutBufferSize;
- ULONG i;
-
- DPRINT1("ReAllocateLayoutBuffer()\n");
-
- NewPartitionCount = 4 + GetLogicalPartitionCount(DiskEntry) * 4;
-
- if (DiskEntry->LayoutBuffer)
- CurrentPartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
-
- DPRINT1("CurrentPartitionCount: %lu NewPartitionCount: %lu\n",
- CurrentPartitionCount, NewPartitionCount);
-
- if (CurrentPartitionCount == NewPartitionCount)
- return TRUE;
-
- LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
- ((NewPartitionCount - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
- NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap,
- HEAP_ZERO_MEMORY,
- DiskEntry->LayoutBuffer,
- LayoutBufferSize);
- if (NewLayoutBuffer == NULL)
- {
- DPRINT1("Failed to allocate the new layout buffer (size: %lu)\n", LayoutBufferSize);
- return FALSE;
- }
-
- /* If the layout buffer grows, make sure the new (empty) entries are written to the disk */
- if (NewPartitionCount > CurrentPartitionCount)
- {
- for (i = CurrentPartitionCount; i < NewPartitionCount; i++)
- NewLayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
- }
-
- DiskEntry->LayoutBuffer = NewLayoutBuffer;
- DiskEntry->LayoutBuffer->PartitionCount = NewPartitionCount;
-
- return TRUE;
-}
-
-
-static
-VOID
-UpdateDiskLayout(
- IN PDISKENTRY DiskEntry)
-{
- PPARTITION_INFORMATION PartitionInfo;
- PPARTITION_INFORMATION LinkInfo = NULL;
- PLIST_ENTRY ListEntry;
- PPARTENTRY PartEntry;
- LARGE_INTEGER HiddenSectors64;
- ULONG Index;
- ULONG PartitionNumber = 1;
-
- DPRINT1("UpdateDiskLayout()\n");
-
- /* Resize the layout buffer if necessary */
- if (ReAllocateLayoutBuffer(DiskEntry) == FALSE)
- {
- DPRINT("ReAllocateLayoutBuffer() failed.\n");
- return;
- }
-
- /* Update the primary partition table */
- Index = 0;
- ListEntry = DiskEntry->PrimaryPartListHead.Flink;
- while (ListEntry != &DiskEntry->PrimaryPartListHead)
- {
- PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
-
- if (PartEntry->IsPartitioned != FALSE)
- {
- PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
-
- if (!IsSamePrimaryLayoutEntry(PartitionInfo, DiskEntry, PartEntry))
- {
- DPRINT1("Updating primary partition entry %lu\n", Index);
-
- PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
- PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
- PartitionInfo->HiddenSectors = PartEntry->StartSector.LowPart;
- PartitionInfo->PartitionNumber = (!IsContainerPartition(PartEntry->PartitionType)) ? PartitionNumber : 0;
- PartitionInfo->PartitionType = PartEntry->PartitionType;
- PartitionInfo->BootIndicator = PartEntry->BootIndicator;
- PartitionInfo->RecognizedPartition = FALSE;
- PartitionInfo->RewritePartition = TRUE;
- }
-
- PartEntry->PartitionNumber = (!IsContainerPartition(PartEntry->PartitionType)) ? PartitionNumber : 0;
- PartEntry->PartitionIndex = Index;
-
- if (!IsContainerPartition(PartEntry->PartitionType))
- PartitionNumber++;
-
- Index++;
- }
-
- ListEntry = ListEntry->Flink;
- }
-
- /* Update the logical partition tables */
- Index = 4;
- ListEntry = DiskEntry->LogicalPartListHead.Flink;
- while (ListEntry != &DiskEntry->LogicalPartListHead)
- {
- PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
-
- if (PartEntry->IsPartitioned)
- {
- PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
-
- DPRINT1("Updating logical partition entry %lu\n", Index);
-
- PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
- PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
- PartitionInfo->HiddenSectors = DiskEntry->SectorAlignment;
- PartitionInfo->PartitionNumber = PartitionNumber;
- PartitionInfo->PartitionType = PartEntry->PartitionType;
- PartitionInfo->BootIndicator = FALSE;
- PartitionInfo->RecognizedPartition = FALSE;
- PartitionInfo->RewritePartition = TRUE;
-
- PartEntry->PartitionNumber = PartitionNumber;
- PartEntry->PartitionIndex = Index;
-
- /* Fill the link entry of the previous partition table */
- if (LinkInfo != NULL)
- {
- LinkInfo->StartingOffset.QuadPart = (PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
- LinkInfo->PartitionLength.QuadPart = (PartEntry->StartSector.QuadPart + DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
- HiddenSectors64.QuadPart = PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment - DiskEntry->ExtendedPartition->StartSector.QuadPart;
- LinkInfo->HiddenSectors = HiddenSectors64.LowPart;
- LinkInfo->PartitionNumber = 0;
- LinkInfo->PartitionType = PARTITION_EXTENDED;
- LinkInfo->BootIndicator = FALSE;
- LinkInfo->RecognizedPartition = FALSE;
- LinkInfo->RewritePartition = TRUE;
- }
-
- /* Save a pointer to the link entry of the current partition table */
- LinkInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index + 1];
-
- PartitionNumber++;
- Index += 4;
- }
-
- ListEntry = ListEntry->Flink;
- }
-
- /* Wipe unused primary partition table entries */
- for (Index = GetPrimaryPartitionCount(DiskEntry); Index < 4; Index++)
- {
- DPRINT1("Primary partition entry %lu\n", Index);
-
- PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
-
- if (!IsEmptyLayoutEntry(PartitionInfo))
- {
- DPRINT1("Wiping primary partition entry %lu\n", Index);
-
- PartitionInfo->StartingOffset.QuadPart = 0;
- PartitionInfo->PartitionLength.QuadPart = 0;
- PartitionInfo->HiddenSectors = 0;
- PartitionInfo->PartitionNumber = 0;
- PartitionInfo->PartitionType = PARTITION_ENTRY_UNUSED;
- PartitionInfo->BootIndicator = FALSE;
- PartitionInfo->RecognizedPartition = FALSE;
- PartitionInfo->RewritePartition = TRUE;
- }
- }
-
- /* Wipe unused logical partition table entries */
- for (Index = 4; Index < DiskEntry->LayoutBuffer->PartitionCount; Index++)
- {
- if (Index % 4 >= 2)
- {
- DPRINT1("Logical partition entry %lu\n", Index);
-
- PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
-
- if (!IsEmptyLayoutEntry(PartitionInfo))
- {
- DPRINT1("Wiping partition entry %lu\n", Index);
-
- PartitionInfo->StartingOffset.QuadPart = 0;
- PartitionInfo->PartitionLength.QuadPart = 0;
- PartitionInfo->HiddenSectors = 0;
- PartitionInfo->PartitionNumber = 0;
- PartitionInfo->PartitionType = PARTITION_ENTRY_UNUSED;
- PartitionInfo->BootIndicator = FALSE;
- PartitionInfo->RecognizedPartition = FALSE;
- PartitionInfo->RewritePartition = TRUE;
- }
- }
- }
-
-#ifdef DUMP_PARTITION_TABLE
- DumpPartitionTable(DiskEntry);
-#endif
-}
-
-
-static
-PPARTENTRY
-GetPrevUnpartitionedEntry(
- PDISKENTRY DiskEntry,
- PPARTENTRY PartEntry)
-{
- PPARTENTRY PrevPartEntry;
- PLIST_ENTRY ListHead;
-
- if (PartEntry->LogicalPartition)
- ListHead = &DiskEntry->LogicalPartListHead;
- else
- ListHead = &DiskEntry->PrimaryPartListHead;
-
- if (PartEntry->ListEntry.Blink != ListHead)
- {
- PrevPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Blink,
- PARTENTRY,
- ListEntry);
- if (PrevPartEntry->IsPartitioned == FALSE)
- return PrevPartEntry;
- }
-
- return NULL;
-}
-
-
-static
-PPARTENTRY
-GetNextUnpartitionedEntry(
- PDISKENTRY DiskEntry,
- PPARTENTRY PartEntry)
-{
- PPARTENTRY NextPartEntry;
- PLIST_ENTRY ListHead;
-
- if (PartEntry->LogicalPartition)
- ListHead = &DiskEntry->LogicalPartListHead;
- else
- ListHead = &DiskEntry->PrimaryPartListHead;
-
- if (PartEntry->ListEntry.Flink != ListHead)
- {
- NextPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Flink,
- PARTENTRY,
- ListEntry);
- if (NextPartEntry->IsPartitioned == FALSE)
- return NextPartEntry;
- }
-
- return NULL;
-}
-
-
-VOID
-CreatePrimaryPartition(
- PPARTLIST List,
- ULONGLONG SectorCount,
- BOOLEAN AutoCreate)
-{
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
- PPARTENTRY NewPartEntry;
-
- DPRINT1("CreatePrimaryPartition(%I64u)\n", SectorCount);
-
- if (List == NULL ||
- List->CurrentDisk == NULL ||
- List->CurrentPartition == NULL ||
- List->CurrentPartition->IsPartitioned != FALSE)
- {
- return;
- }
-
- DiskEntry = List->CurrentDisk;
- PartEntry = List->CurrentPartition;
-
- DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart);
-
- if ((AutoCreate != FALSE) ||
- (AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart))
- {
- DPRINT1("Convert existing partition entry\n");
-
- /* Convert current entry to 'new (unformatted)' */
- PartEntry->IsPartitioned = TRUE;
- PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
- PartEntry->FormatState = Unformatted;
- PartEntry->AutoCreate = AutoCreate;
- PartEntry->New = TRUE;
- PartEntry->BootIndicator = FALSE;
-
- DPRINT1("First Sector: %I64u\n", PartEntry->StartSector.QuadPart);
- DPRINT1("Last Sector: %I64u\n", PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1);
- DPRINT1("Total Sectors: %I64u\n", PartEntry->SectorCount.QuadPart);
- }
- else
- {
- DPRINT1("Add new partition entry\n");
-
- /* Insert and initialize a new partition entry */
- NewPartEntry = RtlAllocateHeap(ProcessHeap,
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
- if (NewPartEntry == NULL)
- return;
-
- /* Insert the new entry into the list */
- InsertTailList(&PartEntry->ListEntry,
- &NewPartEntry->ListEntry);
-
- NewPartEntry->DiskEntry = DiskEntry;
-
- NewPartEntry->IsPartitioned = TRUE;
- NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
- NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) -
- 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 = TRUE;
- NewPartEntry->FormatState = Unformatted;
- NewPartEntry->BootIndicator = FALSE;
-
- PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart;
- PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart);
- }
-
- UpdateDiskLayout(DiskEntry);
-
- DiskEntry->Dirty = TRUE;
-
- AssignDriveLetters(List);
-}
-
-
-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->SectorAlignment;
- NewPartEntry->SectorCount.QuadPart = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
-
- 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
-CreateExtendedPartition(
- PPARTLIST List,
- ULONGLONG SectorCount)
-{
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
- PPARTENTRY NewPartEntry;
-
- DPRINT1("CreateExtendedPartition(%I64u)\n", SectorCount);
-
- if (List == NULL ||
- List->CurrentDisk == NULL ||
- List->CurrentPartition == NULL ||
- (List->CurrentPartition->IsPartitioned != FALSE))
- {
- return;
- }
-
- DiskEntry = List->CurrentDisk;
- PartEntry = List->CurrentPartition;
-
- DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart);
-
- if (AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart)
- {
- DPRINT1("Convert existing partition entry\n");
-
- /* Convert current entry to 'new (unformatted)' */
- PartEntry->IsPartitioned = TRUE;
- PartEntry->FormatState = Formatted;
- PartEntry->AutoCreate = FALSE;
- PartEntry->New = FALSE;
- PartEntry->BootIndicator = FALSE;
-
- 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("Last Sector: %I64u\n", PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1);
- DPRINT1("Total Sectors: %I64u\n", PartEntry->SectorCount.QuadPart);
- }
- else
- {
- DPRINT1("Add new partition entry\n");
-
- /* Insert and initialize a new partition entry */
- NewPartEntry = RtlAllocateHeap(ProcessHeap,
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
- if (NewPartEntry == NULL)
- return;
-
- /* Insert the new entry into the list */
- InsertTailList(&PartEntry->ListEntry,
- &NewPartEntry->ListEntry);
-
- NewPartEntry->DiskEntry = DiskEntry;
-
- NewPartEntry->IsPartitioned = TRUE;
- NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
- NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) -
- NewPartEntry->StartSector.QuadPart;
-
- NewPartEntry->New = FALSE;
- NewPartEntry->FormatState = Formatted;
- NewPartEntry->BootIndicator = FALSE;
-
- 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->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);
- }
-
- AddLogicalDiskSpace(DiskEntry);
-
- UpdateDiskLayout(DiskEntry);
-
- DiskEntry->Dirty = TRUE;
-
- AssignDriveLetters(List);
-}
-
-
-VOID
-CreateLogicalPartition(
- PPARTLIST List,
- ULONGLONG SectorCount,
- BOOLEAN AutoCreate)
-{
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
- PPARTENTRY NewPartEntry;
-
- DPRINT1("CreateLogicalPartition(%I64u)\n", SectorCount);
-
- if (List == NULL ||
- List->CurrentDisk == NULL ||
- List->CurrentPartition == NULL ||
- List->CurrentPartition->IsPartitioned != FALSE)
- {
- return;
- }
-
- DiskEntry = List->CurrentDisk;
- PartEntry = List->CurrentPartition;
-
- DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart);
-
- if (AutoCreate == TRUE ||
- AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart)
- {
- DPRINT1("Convert existing partition entry\n");
-
- /* Convert current entry to 'new (unformatted)' */
- PartEntry->IsPartitioned = TRUE;
- PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
- PartEntry->FormatState = Unformatted;
- PartEntry->AutoCreate = FALSE;
- PartEntry->New = TRUE;
- PartEntry->BootIndicator = FALSE;
- PartEntry->LogicalPartition = TRUE;
-
- DPRINT1("First Sector: %I64u\n", PartEntry->StartSector.QuadPart);
- DPRINT1("Last Sector: %I64u\n", PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1);
- DPRINT1("Total Sectors: %I64u\n", PartEntry->SectorCount.QuadPart);
- }
- else
- {
- DPRINT1("Add new partition entry\n");
-
- /* Insert and initialize a new partition entry */
- NewPartEntry = RtlAllocateHeap(ProcessHeap,
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
- if (NewPartEntry == NULL)
- return;
-
- /* Insert the new entry into the list */
- InsertTailList(&PartEntry->ListEntry,
- &NewPartEntry->ListEntry);
-
- NewPartEntry->DiskEntry = DiskEntry;
-
- NewPartEntry->IsPartitioned = TRUE;
- NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
- NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) -
- 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 = TRUE;
- NewPartEntry->FormatState = Unformatted;
- NewPartEntry->BootIndicator = FALSE;
- NewPartEntry->LogicalPartition = TRUE;
-
- PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart;
- PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart);
- }
-
- UpdateDiskLayout(DiskEntry);
-
- DiskEntry->Dirty = TRUE;
-
- AssignDriveLetters(List);
-}
-
-
-VOID
-DeleteCurrentPartition(
- PPARTLIST List)
-{
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
- PPARTENTRY PrevPartEntry;
- PPARTENTRY NextPartEntry;
- PPARTENTRY LogicalPartEntry;
- PLIST_ENTRY Entry;
-
- if (List == NULL ||
- List->CurrentDisk == NULL ||
- List->CurrentPartition == NULL ||
- List->CurrentPartition->IsPartitioned == FALSE)
- {
- return;
- }
-
- /* Clear the system disk and partition pointers if the system partition will be deleted */
- if (List->SystemPartition == List->CurrentPartition)
- {
- List->SystemDisk = NULL;
- List->SystemPartition = NULL;
- }
-
- DiskEntry = List->CurrentDisk;
- PartEntry = List->CurrentPartition;
-
- /* Delete all logical partition 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 */
-
- /* Get pointer to previous and next unpartitioned entries */
- PrevPartEntry = GetPrevUnpartitionedEntry(DiskEntry, PartEntry);
- NextPartEntry = GetNextUnpartitionedEntry(DiskEntry, PartEntry);
-
- if (PrevPartEntry != NULL && NextPartEntry != NULL)
- {
- /* Merge previous, current and next unpartitioned entry */
-
- /* Adjust the previous entries length */
- PrevPartEntry->SectorCount.QuadPart += (PartEntry->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart);
-
- /* Remove the current entry */
- RemoveEntryList(&PartEntry->ListEntry);
- RtlFreeHeap(ProcessHeap, 0, PartEntry);
-
- /* Remove the next entry */
- RemoveEntryList (&NextPartEntry->ListEntry);
- RtlFreeHeap(ProcessHeap, 0, NextPartEntry);
+ coPos.X = ListUi->Left;
+ coPos.Y = i;
+ FillConsoleOutputCharacterA(StdOutput,
+ 0xB3, // '|',
+ 1,
+ coPos,
+ &Written);
- /* Update current partition */
- List->CurrentPartition = PrevPartEntry;
+ coPos.X = ListUi->Right;
+ FillConsoleOutputCharacterA(StdOutput,
+ 0xB3, //'|',
+ 1,
+ coPos,
+ &Written);
}
- else if (PrevPartEntry != NULL && NextPartEntry == NULL)
- {
- /* Merge current and previous unpartitioned entry */
- /* Adjust the previous entries length */
- PrevPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
-
- /* Remove the current entry */
- RemoveEntryList(&PartEntry->ListEntry);
- RtlFreeHeap(ProcessHeap, 0, PartEntry);
+ /* Draw lower left corner */
+ coPos.X = ListUi->Left;
+ coPos.Y = ListUi->Bottom;
+ FillConsoleOutputCharacterA(StdOutput,
+ 0xC0, // '+',
+ 1,
+ coPos,
+ &Written);
- /* Update current partition */
- List->CurrentPartition = PrevPartEntry;
- }
- else if (PrevPartEntry == NULL && NextPartEntry != NULL)
+ /* Draw lower edge */
+ coPos.X = ListUi->Left + 1;
+ coPos.Y = ListUi->Bottom;
+ if (LastLine - ListUi->Offset <= ListUi->Bottom - ListUi->Top - 2)
{
- /* Merge current and next unpartitioned entry */
-
- /* Adjust the next entries offset and length */
- NextPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
- NextPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
-
- /* Remove the current entry */
- RemoveEntryList(&PartEntry->ListEntry);
- RtlFreeHeap(ProcessHeap, 0, PartEntry);
-
- /* Update current partition */
- List->CurrentPartition = NextPartEntry;
+ FillConsoleOutputCharacterA(StdOutput,
+ 0xC4, // '-',
+ ListUi->Right - ListUi->Left - 1,
+ coPos,
+ &Written);
}
else
{
- /* Nothing to merge but change current entry */
- PartEntry->IsPartitioned = FALSE;
- PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
- PartEntry->FormatState = Unformatted;
- PartEntry->DriveLetter = 0;
- }
-
- UpdateDiskLayout(DiskEntry);
-
- DiskEntry->Dirty = TRUE;
-
- AssignDriveLetters(List);
-}
-
-
-VOID
-CheckActiveSystemPartition(
- IN PPARTLIST List,
- IN PFILE_SYSTEM_LIST FileSystemList /* Needed for checking the FS of the candidate system partition */
- )
-{
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
- PLIST_ENTRY ListEntry;
-
- PFILE_SYSTEM_ITEM FileSystem;
-
- /* Check for empty disk list */
- if (IsListEmpty(&List->DiskListHead))
- {
- List->SystemDisk = NULL;
- List->SystemPartition = NULL;
- List->OriginalSystemDisk = NULL;
- List->OriginalSystemPartition = NULL;
- return;
- }
-
- /* Choose the currently selected disk */
- DiskEntry = List->CurrentDisk;
-
- /* Check for empty partition list */
- if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
- {
- List->SystemDisk = NULL;
- List->SystemPartition = NULL;
- List->OriginalSystemDisk = NULL;
- List->OriginalSystemPartition = NULL;
- return;
- }
-
- if (List->SystemDisk != NULL && List->SystemPartition != NULL)
- {
- /* We already have an active system partition */
- DPRINT1("Use the current system partition %lu in disk %lu, drive letter %c\n",
- List->SystemPartition->PartitionNumber,
- List->SystemDisk->DiskNumber,
- (List->SystemPartition->DriveLetter == 0) ? '-' : List->SystemPartition->DriveLetter);
- return;
- }
-
- DPRINT1("We are here (1)!\n");
-
- List->SystemDisk = NULL;
- List->SystemPartition = NULL;
- List->OriginalSystemDisk = NULL;
- List->OriginalSystemPartition = NULL;
-
- /* Retrieve the first partition of the disk */
- PartEntry = CONTAINING_RECORD(DiskEntry->PrimaryPartListHead.Flink,
- PARTENTRY,
- ListEntry);
- List->SystemDisk = DiskEntry;
- List->SystemPartition = PartEntry;
-
- //
- // See: https://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/partlist.c?r1=63355&r2=63354&pathrev=63355#l2318
- //
-
- /* Check if the disk is new and if so, use its first partition as the active system partition */
- if (DiskEntry->NewDisk)
- {
- if (PartEntry->PartitionType == PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator == FALSE)
- {
- /* FIXME: Might be incorrect if partitions were created by Linux FDISK */
- List->SystemDisk = DiskEntry;
- List->SystemPartition = PartEntry;
-
- List->OriginalSystemDisk = List->SystemDisk;
- List->OriginalSystemPartition = List->SystemPartition;
-
- DPRINT1("Use new first active system partition %lu in disk %lu, drive letter %c\n",
- List->SystemPartition->PartitionNumber,
- List->SystemDisk->DiskNumber,
- (List->SystemPartition->DriveLetter == 0) ? '-' : List->SystemPartition->DriveLetter);
-
- goto SetSystemPartition;
- }
-
- // FIXME: What to do??
- DPRINT1("NewDisk TRUE but first partition is used?\n");
- }
-
- DPRINT1("We are here (2)!\n");
-
- /*
- * The disk is not new, check if any partition is initialized;
- * if not, the first one becomes the system partition.
- */
- ListEntry = DiskEntry->PrimaryPartListHead.Flink;
- while (ListEntry != &DiskEntry->PrimaryPartListHead)
- {
- /* Retrieve the partition and go to the next one */
- PartEntry = CONTAINING_RECORD(ListEntry,
- PARTENTRY,
- ListEntry);
-
- /* Check if the partition is partitioned and is used */
- if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator != FALSE)
- {
- break;
- }
-
- /* Go to the next one */
- ListEntry = ListEntry->Flink;
- }
- if (ListEntry == &DiskEntry->PrimaryPartListHead)
- {
- /*
- * OK we haven't encountered any used and active partition,
- * so use the first one as the system partition.
- */
-
- /* FIXME: Might be incorrect if partitions were created by Linux FDISK */
- List->OriginalSystemDisk = List->SystemDisk; // DiskEntry
- List->OriginalSystemPartition = List->SystemPartition; // First PartEntry
-
- DPRINT1("Use first active system partition %lu in disk %lu, drive letter %c\n",
- List->SystemPartition->PartitionNumber,
- List->SystemDisk->DiskNumber,
- (List->SystemPartition->DriveLetter == 0) ? '-' : List->SystemPartition->DriveLetter);
-
- goto SetSystemPartition;
- }
-
- List->SystemDisk = NULL;
- List->SystemPartition = NULL;
- List->OriginalSystemDisk = NULL;
- List->OriginalSystemPartition = NULL;
-
- DPRINT1("We are here (3)!\n");
-
- /* The disk is not new, scan all partitions to find the (active) system partition */
- ListEntry = DiskEntry->PrimaryPartListHead.Flink;
- while (ListEntry != &DiskEntry->PrimaryPartListHead)
- {
- /* Retrieve the partition and go to the next one */
- PartEntry = CONTAINING_RECORD(ListEntry,
- PARTENTRY,
- ListEntry);
- ListEntry = ListEntry->Flink;
-
- /* Check if the partition is partitioned and used */
- if (PartEntry->IsPartitioned &&
- PartEntry->PartitionType != PARTITION_ENTRY_UNUSED)
- {
- /* Check if the partition is active */
- if (PartEntry->BootIndicator)
- {
- /* Yes, we found it */
- List->SystemDisk = DiskEntry;
- List->SystemPartition = PartEntry;
-
- DPRINT1("Found active system partition %lu in disk %lu, drive letter %c\n",
- PartEntry->PartitionNumber,
- DiskEntry->DiskNumber,
- (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter);
- break;
- }
- }
- }
-
- /* Check if we have found the system partition */
- if (List->SystemDisk == NULL || List->SystemPartition == NULL)
- {
- /* Nothing, use the alternative system partition */
- DPRINT1("No system partition found, use the alternative partition!\n");
- goto UseAlternativeSystemPartition;
- }
-
- /* Save them */
- List->OriginalSystemDisk = List->SystemDisk;
- List->OriginalSystemPartition = List->SystemPartition;
-
- /*
- * ADDITIONAL CHECKS / BIG HACK:
- *
- * Retrieve its file system and check whether we have
- * write support for it. If that is the case we are fine
- * and we can use it directly. However if we don't have
- * write support we will need to change the active system
- * partition.
- *
- * NOTE that this is completely useless on architectures
- * where a real system partition is required, as on these
- * architectures the partition uses the FAT FS, for which
- * we do have write support.
- * NOTE also that for those architectures looking for a
- * partition boot indicator is insufficient.
- */
- FileSystem = GetFileSystem(FileSystemList, List->OriginalSystemPartition);
- if (FileSystem == NULL)
- {
- DPRINT1("System partition %lu in disk %lu with no FS?!\n",
- List->OriginalSystemPartition->PartitionNumber,
- List->OriginalSystemDisk->DiskNumber);
- goto FindAndUseAlternativeSystemPartition;
- }
- // HACK: WARNING: We cannot write on this FS yet!
- // See fslist.c:GetFileSystem()
- if (List->OriginalSystemPartition->PartitionType == PARTITION_EXT2 ||
- List->OriginalSystemPartition->PartitionType == PARTITION_IFS)
- {
- DPRINT1("Recognized file system %S that doesn't support write support yet!\n",
- FileSystem->FileSystemName);
- goto FindAndUseAlternativeSystemPartition;
- }
-
- DPRINT1("Use existing active system partition %lu in disk %lu, drive letter %c\n",
- List->SystemPartition->PartitionNumber,
- List->SystemDisk->DiskNumber,
- (List->SystemPartition->DriveLetter == 0) ? '-' : List->SystemPartition->DriveLetter);
-
- return;
-
-FindAndUseAlternativeSystemPartition:
- /*
- * We are here because we have not found any (active) candidate
- * system partition that we know how to support. What we are going
- * to do is to change the existing system partition and use the
- * partition on which we install ReactOS as the new system partition,
- * and then we will need to add in FreeLdr's entry a boot entry to boot
- * from the original system partition.
- */
-
- /* Unset the old system partition */
- List->SystemPartition->BootIndicator = FALSE;
- List->SystemDisk->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].BootIndicator = FALSE;
- List->SystemDisk->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].RewritePartition = TRUE;
- List->SystemDisk->Dirty = TRUE;
-
-UseAlternativeSystemPartition:
- List->SystemDisk = List->CurrentDisk;
- List->SystemPartition = List->CurrentPartition;
-
- DPRINT1("Use alternative active system partition %lu in disk %lu, drive letter %c\n",
- List->SystemPartition->PartitionNumber,
- List->SystemDisk->DiskNumber,
- (List->SystemPartition->DriveLetter == 0) ? '-' : List->SystemPartition->DriveLetter);
-
-SetSystemPartition:
- /* Set the new active system partition */
- List->SystemPartition->BootIndicator = TRUE;
- List->SystemDisk->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].BootIndicator = TRUE;
- List->SystemDisk->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].RewritePartition = TRUE;
- List->SystemDisk->Dirty = TRUE;
-}
-
-
-static
-NTSTATUS
-WritePartitions(
- IN PPARTLIST List,
- IN PDISKENTRY DiskEntry)
-{
- WCHAR DstPath[MAX_PATH];
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK Iosb;
- UNICODE_STRING Name;
- ULONG BufferSize;
- HANDLE FileHandle = NULL;
- NTSTATUS Status;
-
- DPRINT("WritePartitions() Disk: %lu\n", DiskEntry->DiskNumber);
-
- swprintf(DstPath,
- L"\\Device\\Harddisk%d\\Partition0",
- DiskEntry->DiskNumber);
- RtlInitUnicodeString(&Name,
- DstPath);
- InitializeObjectAttributes(&ObjectAttributes,
- &Name,
- 0,
- NULL,
- NULL);
-
- Status = NtOpenFile(&FileHandle,
- GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
- &ObjectAttributes,
- &Iosb,
- 0,
- FILE_SYNCHRONOUS_IO_NONALERT);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
- return Status;
- }
-
-#ifdef DUMP_PARTITION_TABLE
- DumpPartitionTable(DiskEntry);
-#endif
-
- BufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
- ((DiskEntry->LayoutBuffer->PartitionCount - 1) * sizeof(PARTITION_INFORMATION));
- Status = NtDeviceIoControlFile(FileHandle,
- NULL,
- NULL,
- NULL,
- &Iosb,
- IOCTL_DISK_SET_DRIVE_LAYOUT,
- DiskEntry->LayoutBuffer,
- BufferSize,
- NULL,
- 0);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status);
+ FillConsoleOutputCharacterA(StdOutput,
+ 0xC4, // '-',
+ ListUi->Right - ListUi->Left - 5,
+ coPos,
+ &Written);
+ coPos.X = ListUi->Right - 5;
+ WriteConsoleOutputCharacterA(StdOutput,
+ "(\x19)", // "(down)"
+ 3,
+ coPos,
+ &Written);
+ coPos.X = ListUi->Right - 2;
+ FillConsoleOutputCharacterA(StdOutput,
+ 0xC4, // '-',
+ 2,
+ coPos,
+ &Written);
}
- if (FileHandle != NULL)
- NtClose(FileHandle);
-
- return Status;
-}
-
-
-BOOLEAN
-WritePartitionsToDisk(
- PPARTLIST List)
-{
- PLIST_ENTRY Entry;
- PDISKENTRY DiskEntry;
+ /* Draw lower right corner */
+ coPos.X = ListUi->Right;
+ coPos.Y = ListUi->Bottom;
+ FillConsoleOutputCharacterA(StdOutput,
+ 0xD9, // '+',
+ 1,
+ coPos,
+ &Written);
- if (List == NULL)
- return TRUE;
+ /* print list entries */
+ ListUi->Line = - ListUi->Offset;
Entry = List->DiskListHead.Flink;
while (Entry != &List->DiskListHead)
{
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
- if (DiskEntry->Dirty != FALSE)
- {
- WritePartitions(List, DiskEntry);
- DiskEntry->Dirty = FALSE;
- }
+ /* Print disk entry */
+ PrintDiskData(ListUi, DiskEntry);
Entry = Entry->Flink;
}
-
- return TRUE;
-}
-
-
-BOOL
-SetMountedDeviceValues(
- PPARTLIST List)
-{
- PLIST_ENTRY Entry1, Entry2;
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
- LARGE_INTEGER StartingOffset;
-
- if (List == NULL)
- {
- return FALSE;
- }
-
- Entry1 = List->DiskListHead.Flink;
- while (Entry1 != &List->DiskListHead)
- {
- DiskEntry = CONTAINING_RECORD(Entry1,
- DISKENTRY,
- ListEntry);
-
- Entry2 = DiskEntry->PrimaryPartListHead.Flink;
- while (Entry2 != &DiskEntry->PrimaryPartListHead)
- {
- PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
- if (PartEntry->IsPartitioned)
- {
- 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;
- }
-
- return TRUE;
-}
-
-
-ULONG
-PrimaryPartitionCreationChecks(
- IN PPARTLIST List)
-{
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
-
- DiskEntry = List->CurrentDisk;
- PartEntry = List->CurrentPartition;
-
- /* Fail if partition is already in use */
- if (PartEntry->IsPartitioned != FALSE)
- return ERROR_NEW_PARTITION;
-
- /* Fail if there are already 4 primary partitions in the list */
- if (GetPrimaryPartitionCount(DiskEntry) >= 4)
- return ERROR_PARTITION_TABLE_FULL;
-
- return ERROR_SUCCESS;
-}
-
-
-ULONG
-ExtendedPartitionCreationChecks(
- IN PPARTLIST List)
-{
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
-
- DiskEntry = List->CurrentDisk;
- PartEntry = List->CurrentPartition;
-
- /* Fail if partition is already in use */
- if (PartEntry->IsPartitioned != FALSE)
- return ERROR_NEW_PARTITION;
-
- /* Fail if there are already 4 primary partitions in the list */
- if (GetPrimaryPartitionCount(DiskEntry) >= 4)
- return ERROR_PARTITION_TABLE_FULL;
-
- /* Fail if there is another extended partition in the list */
- if (DiskEntry->ExtendedPartition != NULL)
- return ERROR_ONLY_ONE_EXTENDED;
-
- return ERROR_SUCCESS;
-}
-
-
-ULONG
-LogicalPartitionCreationChecks(
- IN PPARTLIST List)
-{
-// PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
-
-// DiskEntry = List->CurrentDisk;
- PartEntry = List->CurrentPartition;
-
- /* Fail if partition is already in use */
- if (PartEntry->IsPartitioned != FALSE)
- return ERROR_NEW_PARTITION;
-
- return ERROR_SUCCESS;
}
-
-BOOL
-GetNextUnformattedPartition(
- IN PPARTLIST List,
- OUT PDISKENTRY *pDiskEntry,
- OUT PPARTENTRY *pPartEntry)
+VOID
+ScrollDownPartitionList(
+ IN PPARTLIST_UI ListUi)
{
- PLIST_ENTRY Entry1, Entry2;
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
-
- Entry1 = List->DiskListHead.Flink;
- while (Entry1 != &List->DiskListHead)
- {
- DiskEntry = CONTAINING_RECORD(Entry1,
- DISKENTRY,
- ListEntry);
-
- Entry2 = DiskEntry->PrimaryPartListHead.Flink;
- while (Entry2 != &DiskEntry->PrimaryPartListHead)
- {
- PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
- if (PartEntry->IsPartitioned && PartEntry->New)
- {
- *pDiskEntry = DiskEntry;
- *pPartEntry = PartEntry;
- return TRUE;
- }
-
- Entry2 = Entry2->Flink;
- }
-
- Entry2 = DiskEntry->LogicalPartListHead.Flink;
- while (Entry2 != &DiskEntry->LogicalPartListHead)
- {
- PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
- if (PartEntry->IsPartitioned && PartEntry->New)
- {
- *pDiskEntry = DiskEntry;
- *pPartEntry = PartEntry;
- return TRUE;
- }
-
- Entry2 = Entry2->Flink;
- }
-
- Entry1 = Entry1->Flink;
- }
-
- *pDiskEntry = NULL;
- *pPartEntry = NULL;
-
- return FALSE;
+ if (GetNextPartition(ListUi->List))
+ DrawPartitionList(ListUi);
}
-
-BOOL
-GetNextUncheckedPartition(
- IN PPARTLIST List,
- OUT PDISKENTRY *pDiskEntry,
- OUT PPARTENTRY *pPartEntry)
+VOID
+ScrollUpPartitionList(
+ IN PPARTLIST_UI ListUi)
{
- PLIST_ENTRY Entry1, Entry2;
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
-
- Entry1 = List->DiskListHead.Flink;
- while (Entry1 != &List->DiskListHead)
- {
- DiskEntry = CONTAINING_RECORD(Entry1,
- DISKENTRY,
- ListEntry);
-
- Entry2 = DiskEntry->PrimaryPartListHead.Flink;
- while (Entry2 != &DiskEntry->PrimaryPartListHead)
- {
- PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
- if (PartEntry->NeedsCheck == TRUE)
- {
- *pDiskEntry = DiskEntry;
- *pPartEntry = PartEntry;
- return TRUE;
- }
-
- Entry2 = Entry2->Flink;
- }
-
- Entry2 = DiskEntry->LogicalPartListHead.Flink;
- while (Entry2 != &DiskEntry->LogicalPartListHead)
- {
- PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
- if (PartEntry->NeedsCheck == TRUE)
- {
- *pDiskEntry = DiskEntry;
- *pPartEntry = PartEntry;
- return TRUE;
- }
-
- Entry2 = Entry2->Flink;
- }
-
- Entry1 = Entry1->Flink;
- }
-
- *pDiskEntry = NULL;
- *pPartEntry = NULL;
-
- return FALSE;
+ if (GetPrevPartition(ListUi->List))
+ DrawPartitionList(ListUi);
}
/* EOF */