* PROJECT: ReactOS Setup Library
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Partition list functions
- * COPYRIGHT: Copyright 2003-2018 Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * COPYRIGHT: Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * Copyright 2018-2019 Hermes Belusca-Maito
*/
#include "precomp.h"
Letter = L'C';
/* Assign drive letters to primary partitions */
- Entry1 = List->DiskListHead.Flink;
- while (Entry1 != &List->DiskListHead)
+ for (Entry1 = List->DiskListHead.Flink;
+ Entry1 != &List->DiskListHead;
+ Entry1 = Entry1->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
- Entry2 = DiskEntry->PrimaryPartListHead.Flink;
- while (Entry2 != &DiskEntry->PrimaryPartListHead)
+ for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
+ Entry2 != &DiskEntry->PrimaryPartListHead;
+ Entry2 = Entry2->Flink)
{
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned &&
!IsContainerPartition(PartEntry->PartitionType))
{
+ ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
+
if (IsRecognizedPartition(PartEntry->PartitionType) ||
- (PartEntry->PartitionType == PARTITION_ENTRY_UNUSED &&
- PartEntry->SectorCount.QuadPart != 0LL))
+ PartEntry->SectorCount.QuadPart != 0LL)
{
if (Letter <= L'Z')
{
}
}
}
-
- Entry2 = Entry2->Flink;
}
-
- Entry1 = Entry1->Flink;
}
/* Assign drive letters to logical drives */
- Entry1 = List->DiskListHead.Flink;
- while (Entry1 != &List->DiskListHead)
+ for (Entry1 = List->DiskListHead.Flink;
+ Entry1 != &List->DiskListHead;
+ Entry1 = Entry1->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
- Entry2 = DiskEntry->LogicalPartListHead.Flink;
- while (Entry2 != &DiskEntry->LogicalPartListHead)
+ for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
+ Entry2 != &DiskEntry->LogicalPartListHead;
+ Entry2 = Entry2->Flink)
{
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned)
{
+ ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
+
if (IsRecognizedPartition(PartEntry->PartitionType) ||
- (PartEntry->PartitionType == PARTITION_ENTRY_UNUSED &&
- PartEntry->SectorCount.QuadPart != 0LL))
+ PartEntry->SectorCount.QuadPart != 0LL)
{
if (Letter <= L'Z')
{
}
}
}
-
- Entry2 = Entry2->Flink;
}
-
- Entry1 = Entry1->Flink;
}
}
#undef ROOT_NAME
}
+
+
+/*
+ * Inserts the disk region represented by PartEntry into either the primary
+ * or the logical partition list of the given disk.
+ * The lists are kept sorted by increasing order of start sectors.
+ * Of course no disk region should overlap at all with one another.
+ */
+static
+VOID
+InsertDiskRegion(
+ IN PDISKENTRY DiskEntry,
+ IN PPARTENTRY PartEntry,
+ IN BOOLEAN LogicalPartition)
+{
+ PLIST_ENTRY List;
+ PLIST_ENTRY Entry;
+ PPARTENTRY PartEntry2;
+
+ /* Use the correct partition list */
+ if (LogicalPartition)
+ List = &DiskEntry->LogicalPartListHead;
+ else
+ List = &DiskEntry->PrimaryPartListHead;
+
+ /* Find the first disk region before which we need to insert the new one */
+ for (Entry = List->Flink; Entry != List; Entry = Entry->Flink)
+ {
+ PartEntry2 = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
+
+ /* Ignore any unused empty region */
+ if ((PartEntry2->PartitionType == PARTITION_ENTRY_UNUSED &&
+ PartEntry2->StartSector.QuadPart == 0) || PartEntry2->SectorCount.QuadPart == 0)
+ {
+ continue;
+ }
+
+ /* If the current region ends before the one to be inserted, try again */
+ if (PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1 < PartEntry->StartSector.QuadPart)
+ continue;
+
+ /*
+ * One of the disk region boundaries crosses the desired region
+ * (it starts after the desired region, or ends before the end
+ * of the desired region): this is an impossible situation because
+ * disk regions (partitions) cannot overlap!
+ * Throw an error and bail out.
+ */
+ if (max(PartEntry->StartSector.QuadPart, PartEntry2->StartSector.QuadPart)
+ <=
+ min( PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1,
+ PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1))
+ {
+ DPRINT1("Disk region overlap problem, stopping there!\n"
+ "Partition to be inserted:\n"
+ " StartSector = %I64u ; EndSector = %I64u\n"
+ "Existing disk region:\n"
+ " StartSector = %I64u ; EndSector = %I64u\n",
+ PartEntry->StartSector.QuadPart,
+ PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1,
+ PartEntry2->StartSector.QuadPart,
+ PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1);
+ return;
+ }
+
+ /* We have found the first region before which the new one has to be inserted */
+ break;
+ }
+
+ /* Insert the disk region */
+ InsertTailList(Entry, &PartEntry->ListEntry);
+}
+
+static
+PPARTENTRY
+CreateInsertBlankRegion(
+ IN PDISKENTRY DiskEntry,
+ IN OUT PLIST_ENTRY ListHead,
+ IN ULONGLONG StartSector,
+ IN ULONGLONG SectorCount,
+ IN BOOLEAN LogicalSpace)
+{
+ PPARTENTRY NewPartEntry;
+
+ NewPartEntry = RtlAllocateHeap(ProcessHeap,
+ HEAP_ZERO_MEMORY,
+ sizeof(PARTENTRY));
+ if (NewPartEntry == NULL)
+ return NULL;
+
+ NewPartEntry->DiskEntry = DiskEntry;
+
+ NewPartEntry->StartSector.QuadPart = StartSector;
+ NewPartEntry->SectorCount.QuadPart = SectorCount;
+
+ NewPartEntry->IsPartitioned = FALSE;
+ NewPartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
+ NewPartEntry->FormatState = Unformatted;
+ NewPartEntry->FileSystem[0] = L'\0';
+
+ 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);
+
+ /* Insert the new entry into the list */
+ InsertTailList(ListHead, &NewPartEntry->ListEntry);
+
+ return NewPartEntry;
+}
+
+static
+// BOOLEAN
+PPARTENTRY
+InitializePartitionEntry(
+ IN PDISKENTRY DiskEntry,
+ IN PPARTENTRY PartEntry,
+ IN ULONGLONG SectorCount,
+ IN BOOLEAN AutoCreate)
+{
+ PPARTENTRY NewPartEntry;
+
+ 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");
+
+ NewPartEntry = PartEntry;
+ NewPartEntry->AutoCreate = AutoCreate;
+ }
+ 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 NULL;
+
+ NewPartEntry->DiskEntry = DiskEntry;
+
+ NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
+ NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) -
+ NewPartEntry->StartSector.QuadPart;
+
+ PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart;
+ PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart);
+
+ /* Insert the new entry into the list */
+ InsertTailList(&PartEntry->ListEntry, &NewPartEntry->ListEntry);
+ }
+
+ /* Create entry as 'New (Unformatted)' */
+ NewPartEntry->New = TRUE;
+ NewPartEntry->IsPartitioned = TRUE;
+
+ NewPartEntry->PartitionType = FileSystemToPartitionType(L"RAW", &NewPartEntry->StartSector, &NewPartEntry->SectorCount);
+ ASSERT(NewPartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
+
+ NewPartEntry->FormatState = Unformatted;
+ NewPartEntry->FileSystem[0] = L'\0';
+ // NewPartEntry->AutoCreate = AutoCreate;
+ NewPartEntry->BootIndicator = FALSE;
+ NewPartEntry->LogicalPartition = FALSE;
+
+ 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);
+
+ return NewPartEntry;
+}
+
+
static
VOID
AddPartitionToDisk(
NTSTATUS Status;
PPARTITION_INFORMATION PartitionInfo;
PPARTENTRY PartEntry;
- HANDLE FileHandle;
+ HANDLE PartitionHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
- WCHAR Buffer[MAX_PATH];
+ WCHAR PathBuffer[MAX_PATH];
UNICODE_STRING Name;
UCHAR LabelBuffer[sizeof(FILE_FS_VOLUME_INFORMATION) + 256 * sizeof(WCHAR)];
PFILE_FS_VOLUME_INFORMATION LabelInfo = (PFILE_FS_VOLUME_INFORMATION)LabelBuffer;
PartEntry->LogicalPartition = LogicalPartition;
PartEntry->IsPartitioned = TRUE;
+ PartEntry->OnDiskPartitionNumber = PartitionInfo->PartitionNumber;
PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
PartEntry->PartitionIndex = PartitionIndex;
+ /* Specify the partition as initially unformatted */
+ PartEntry->FormatState = Unformatted;
+ PartEntry->FileSystem[0] = L'\0';
+
+ /* Initialize the partition volume label */
+ RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
+
if (IsContainerPartition(PartEntry->PartitionType))
{
PartEntry->FormatState = Unformatted;
- PartEntry->FileSystem = NULL;
if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
DiskEntry->ExtendedPartition = PartEntry;
}
else if (IsRecognizedPartition(PartEntry->PartitionType))
{
- PartEntry->FileSystem = GetFileSystem(PartEntry);
- if (PartEntry->FileSystem)
- PartEntry->FormatState = Preformatted;
- else
- PartEntry->FormatState = Unformatted;
- // PartEntry->FormatState = UnknownFormat;
- }
- else
- {
- /* Unknown partition, hence unknown partition format (may or may not be actually formatted) */
- PartEntry->FormatState = UnknownFormat;
- }
+ ASSERT(PartitionInfo->RecognizedPartition);
+ ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
- /* Initialize the partition volume label */
- RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
+ /* Open the volume, ignore any errors */
+ RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
+ L"\\Device\\Harddisk%lu\\Partition%lu",
+ DiskEntry->DiskNumber,
+ PartEntry->PartitionNumber);
+ RtlInitUnicodeString(&Name, PathBuffer);
- /* Open the volume, ignore any errors */
- RtlStringCchPrintfW(Buffer, ARRAYSIZE(Buffer),
- L"\\Device\\Harddisk%lu\\Partition%lu",
- DiskEntry->DiskNumber, PartEntry->PartitionNumber);
- RtlInitUnicodeString(&Name, Buffer);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
- InitializeObjectAttributes(&ObjectAttributes,
- &Name,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
+ PartitionHandle = NULL;
+ Status = NtOpenFile(&PartitionHandle,
+ FILE_READ_DATA | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_SYNCHRONOUS_IO_NONALERT);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtOpenFile() failed, Status 0x%08lx\n", Status);
+ }
- Status = NtOpenFile(&FileHandle,
- FILE_READ_DATA | SYNCHRONIZE,
- &ObjectAttributes,
- &IoStatusBlock,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- FILE_SYNCHRONOUS_IO_NONALERT);
- if (NT_SUCCESS(Status))
- {
- /* Retrieve the partition volume label */
- Status = NtQueryVolumeInformationFile(FileHandle,
- &IoStatusBlock,
- &LabelBuffer,
- sizeof(LabelBuffer),
- FileFsVolumeInformation);
- /* Close the handle */
- NtClose(FileHandle);
-
- /* Check for success */
- if (NT_SUCCESS(Status))
+ if (/* NT_SUCCESS(Status) && */ PartitionHandle)
{
- /* Copy the (possibly truncated) volume label and NULL-terminate it */
- RtlStringCbCopyNW(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel),
- LabelInfo->VolumeLabel, LabelInfo->VolumeLabelLength);
+ /* We don't have a FS, try to guess one */
+ Status = InferFileSystemByHandle(PartitionHandle,
+ PartEntry->PartitionType,
+ PartEntry->FileSystem,
+ sizeof(PartEntry->FileSystem));
+ if (!NT_SUCCESS(Status))
+ DPRINT1("InferFileSystemByHandle() failed, Status 0x%08lx\n", Status);
+ }
+ if (*PartEntry->FileSystem)
+ {
+ if (wcsicmp(PartEntry->FileSystem, L"RAW") == 0)
+ PartEntry->FormatState = Unformatted;
+ else
+ PartEntry->FormatState = Preformatted;
}
else
{
- DPRINT1("NtQueryVolumeInformationFile() failed, Status 0x%08lx\n", Status);
+ PartEntry->FormatState = UnknownFormat;
+ }
+
+ /* Retrieve the partition volume label */
+ if (PartitionHandle)
+ {
+ Status = NtQueryVolumeInformationFile(PartitionHandle,
+ &IoStatusBlock,
+ &LabelBuffer,
+ sizeof(LabelBuffer),
+ FileFsVolumeInformation);
+ if (NT_SUCCESS(Status))
+ {
+ /* Copy the (possibly truncated) volume label and NULL-terminate it */
+ RtlStringCbCopyNW(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel),
+ LabelInfo->VolumeLabel, LabelInfo->VolumeLabelLength);
+ }
+ else
+ {
+ DPRINT1("NtQueryVolumeInformationFile() failed, Status 0x%08lx\n", Status);
+ }
}
+
+ /* Close the partition */
+ if (PartitionHandle)
+ NtClose(PartitionHandle);
}
else
{
- DPRINT1("NtOpenFile() failed, Status 0x%08lx\n", Status);
+ /* Unknown partition, hence unknown partition format (may or may not be actually formatted) */
+ PartEntry->FormatState = UnknownFormat;
}
- if (LogicalPartition)
- InsertTailList(&DiskEntry->LogicalPartListHead,
- &PartEntry->ListEntry);
- else
- InsertTailList(&DiskEntry->PrimaryPartListHead,
- &PartEntry->ListEntry);
+ InsertDiskRegion(DiskEntry, PartEntry, LogicalPartition);
}
static
ScanForUnpartitionedDiskSpace(
IN PDISKENTRY DiskEntry)
{
+ ULONGLONG StartSector;
+ ULONGLONG SectorCount;
ULONGLONG LastStartSector;
ULONGLONG LastSectorCount;
ULONGLONG LastUnusedSectorCount;
DPRINT1("No primary partition!\n");
/* Create a partition entry 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;
-
- 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;
- NewPartEntry->FileSystem = NULL;
-
- InsertTailList(&DiskEntry->PrimaryPartListHead,
- &NewPartEntry->ListEntry);
+ if (DiskEntry->SectorAlignment < 2048)
+ StartSector = 2048ULL;
+ else
+ StartSector = (ULONGLONG)DiskEntry->SectorAlignment;
+ SectorCount = AlignDown(DiskEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment) - StartSector;
+
+ NewPartEntry = CreateInsertBlankRegion(DiskEntry,
+ &DiskEntry->PrimaryPartListHead,
+ StartSector,
+ SectorCount,
+ FALSE);
+ if (NewPartEntry == NULL)
+ DPRINT1("Failed to create a new empty region for full disk space!\n");
return;
}
/* Start partition at head 1, cylinder 0 */
- LastStartSector = DiskEntry->SectorAlignment;
+ if (DiskEntry->SectorAlignment < 2048)
+ LastStartSector = 2048ULL;
+ else
+ LastStartSector = (ULONGLONG)DiskEntry->SectorAlignment;
LastSectorCount = 0ULL;
LastUnusedSectorCount = 0ULL;
- Entry = DiskEntry->PrimaryPartListHead.Flink;
- while (Entry != &DiskEntry->PrimaryPartListHead)
+ for (Entry = DiskEntry->PrimaryPartListHead.Flink;
+ Entry != &DiskEntry->PrimaryPartListHead;
+ Entry = Entry->Flink)
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
{
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;
- NewPartEntry->FileSystem = NULL;
+ StartSector = LastStartSector + LastSectorCount;
+ SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
/* Insert the table into the list */
- InsertTailList(&PartEntry->ListEntry,
- &NewPartEntry->ListEntry);
+ NewPartEntry = CreateInsertBlankRegion(DiskEntry,
+ &PartEntry->ListEntry,
+ StartSector,
+ SectorCount,
+ FALSE);
+ if (NewPartEntry == NULL)
+ {
+ DPRINT1("Failed to create a new empty region for disk space!\n");
+ return;
+ }
}
LastStartSector = PartEntry->StartSector.QuadPart;
LastSectorCount = PartEntry->SectorCount.QuadPart;
}
-
- Entry = Entry->Flink;
}
/* Check for trailing unpartitioned disk space */
{
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;
- NewPartEntry->FileSystem = NULL;
+ StartSector = LastStartSector + LastSectorCount;
+ SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
/* Append the table to the list */
- InsertTailList(&DiskEntry->PrimaryPartListHead,
- &NewPartEntry->ListEntry);
+ NewPartEntry = CreateInsertBlankRegion(DiskEntry,
+ &DiskEntry->PrimaryPartListHead,
+ StartSector,
+ SectorCount,
+ FALSE);
+ if (NewPartEntry == NULL)
+ {
+ DPRINT1("Failed to create a new empty region for trailing disk space!\n");
+ return;
+ }
}
}
DPRINT1("No logical partition!\n");
/* Create a partition entry that represents the empty extended partition */
- NewPartEntry = RtlAllocateHeap(ProcessHeap,
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
+
+ StartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
+ SectorCount = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
+
+ NewPartEntry = CreateInsertBlankRegion(DiskEntry,
+ &DiskEntry->LogicalPartListHead,
+ StartSector,
+ SectorCount,
+ TRUE);
if (NewPartEntry == NULL)
+ {
+ DPRINT1("Failed to create a new empty region for full extended partition space!\n");
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;
- NewPartEntry->FileSystem = NULL;
-
- InsertTailList(&DiskEntry->LogicalPartListHead,
- &NewPartEntry->ListEntry);
-
return;
}
LastSectorCount = 0ULL;
LastUnusedSectorCount = 0ULL;
- Entry = DiskEntry->LogicalPartListHead.Flink;
- while (Entry != &DiskEntry->LogicalPartListHead)
+ for (Entry = DiskEntry->LogicalPartListHead.Flink;
+ Entry != &DiskEntry->LogicalPartListHead;
+ Entry = Entry->Flink)
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
{
DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
- NewPartEntry = RtlAllocateHeap(ProcessHeap,
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
+ StartSector = LastStartSector + LastSectorCount;
+ SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
+
+ /* Insert the table into the list */
+ NewPartEntry = CreateInsertBlankRegion(DiskEntry,
+ &PartEntry->ListEntry,
+ StartSector,
+ SectorCount,
+ TRUE);
if (NewPartEntry == NULL)
+ {
+ DPRINT1("Failed to create a new empty region for extended partition space!\n");
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;
- NewPartEntry->FileSystem = NULL;
-
- /* Insert the table into the list */
- InsertTailList(&PartEntry->ListEntry,
- &NewPartEntry->ListEntry);
}
LastStartSector = PartEntry->StartSector.QuadPart;
LastSectorCount = PartEntry->SectorCount.QuadPart;
}
-
- 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);
+ 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));
+ StartSector = LastStartSector + LastSectorCount;
+ SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
+
+ /* Append the table to the list */
+ NewPartEntry = CreateInsertBlankRegion(DiskEntry,
+ &DiskEntry->LogicalPartListHead,
+ StartSector,
+ SectorCount,
+ TRUE);
if (NewPartEntry == NULL)
+ {
+ DPRINT1("Failed to create a new empty region for extended partition space!\n");
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;
- NewPartEntry->FileSystem = NULL;
-
- /* Append the table to the list */
- InsertTailList(&DiskEntry->LogicalPartListHead,
- &NewPartEntry->ListEntry);
}
}
}
PDISKENTRY DiskEntry2;
PUCHAR Buffer;
+ if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ return;
+ }
+
Buffer = (PUCHAR)&DiskEntry->LayoutBuffer->Signature;
while (TRUE)
* Check also signatures from disks, which are
* not visible (bootable) by the bios.
*/
- Entry2 = List->DiskListHead.Flink;
- while (Entry2 != &List->DiskListHead)
+ for (Entry2 = List->DiskListHead.Flink;
+ Entry2 != &List->DiskListHead;
+ Entry2 = Entry2->Flink)
{
DiskEntry2 = CONTAINING_RECORD(Entry2, DISKENTRY, ListEntry);
+ if (DiskEntry2->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ continue;
+ }
+
if (DiskEntry != DiskEntry2 &&
DiskEntry->LayoutBuffer->Signature == DiskEntry2->LayoutBuffer->Signature)
break;
-
- Entry2 = Entry2->Flink;
}
if (Entry2 == &List->DiskListHead)
PLIST_ENTRY Entry;
PDISKENTRY DiskEntry;
- /* Print partition lines */
- Entry = List->DiskListHead.Flink;
- while (Entry != &List->DiskListHead)
+ /* Update each disk */
+ for (Entry = List->DiskListHead.Flink;
+ Entry != &List->DiskListHead;
+ Entry = Entry->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
+ if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ continue;
+ }
+
if (DiskEntry->LayoutBuffer &&
DiskEntry->LayoutBuffer->Signature == 0)
{
SetDiskSignature(List, DiskEntry);
DiskEntry->LayoutBuffer->PartitionEntry[0].RewritePartition = TRUE;
}
-
- Entry = Entry->Flink;
}
}
return;
}
+ DiskEntry->PartList = List;
+
// DiskEntry->Checksum = Checksum;
// DiskEntry->Signature = Signature;
DiskEntry->BiosFound = FALSE;
* Check if this disk has a valid MBR: verify its signature,
* and whether its two first bytes are a valid instruction
* (related to this, see IsThereAValidBootSector() in partlist.c).
+ *
+ * See also ntoskrnl/fstub/fstubex.c!FstubDetectPartitionStyle().
*/
- if (Mbr->Magic != 0xaa55 || (*(PUSHORT)Mbr->BootCode) == 0x0000)
- DiskEntry->NoMbr = TRUE;
- else
- DiskEntry->NoMbr = FALSE;
-
- /* Free the MBR sector buffer */
- RtlFreeHeap(ProcessHeap, 0, Mbr);
+ // DiskEntry->NoMbr = (Mbr->Magic != PARTITION_MAGIC || (*(PUSHORT)Mbr->BootCode) == 0x0000);
- ListEntry = List->BiosDiskListHead.Flink;
- while (ListEntry != &List->BiosDiskListHead)
+ /* If we have not the 0xAA55 then it's raw partition */
+ if (Mbr->Magic != PARTITION_MAGIC)
{
- BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
- /* FIXME:
- * Compare the size from bios and the reported size from driver.
+ DiskEntry->DiskStyle = PARTITION_STYLE_RAW;
+ }
+ /* Check partitions types: if first is 0xEE and all the others 0, we have GPT */
+ else if (Mbr->Partition[0].PartitionType == EFI_PMBR_OSTYPE_EFI &&
+ Mbr->Partition[1].PartitionType == 0 &&
+ Mbr->Partition[2].PartitionType == 0 &&
+ Mbr->Partition[3].PartitionType == 0)
+ {
+ DiskEntry->DiskStyle = PARTITION_STYLE_GPT;
+ }
+ /* Otherwise, partition table is in MBR */
+ else
+ {
+ DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
+ }
+
+ /* Free the MBR sector buffer */
+ RtlFreeHeap(ProcessHeap, 0, Mbr);
+
+
+ for (ListEntry = List->BiosDiskListHead.Flink;
+ ListEntry != &List->BiosDiskListHead;
+ ListEntry = ListEntry->Flink)
+ {
+ 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 signature
* we must create new signatures and reboot. After the reboot,
* it is possible to identify the disks.
// FIXME: What to do?
}
}
- ListEntry = ListEntry->Flink;
}
if (!DiskEntry->BiosFound)
* We now retrieve the disk partition layout
*/
+ /*
+ * Stop there now if the disk is GPT-partitioned,
+ * since we currently do not support such disks.
+ */
+ if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ return;
+ }
+
/* Allocate a layout buffer with 4 partition entries first */
LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
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
{
+ /* Enumerate and add the first four primary partitions */
for (i = 0; i < 4; i++)
{
AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
}
+ /* Enumerate and add the remaining partitions as logical ones */
for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
{
AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
if (List == NULL)
return NULL;
- List->CurrentDisk = NULL;
- List->CurrentPartition = NULL;
-
List->SystemPartition = NULL;
List->OriginalSystemPartition = NULL;
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 = NULL;
- }
- else
- {
- List->CurrentPartition = CONTAINING_RECORD(List->CurrentDisk->PrimaryPartListHead.Flink,
- PARTENTRY,
- ListEntry);
- }
- }
-
return List;
}
PLIST_ENTRY Entry;
/* Loop over the disks and find the correct one */
- Entry = List->DiskListHead.Flink;
- while (Entry != &List->DiskListHead)
+ for (Entry = List->DiskListHead.Flink;
+ Entry != &List->DiskListHead;
+ Entry = Entry->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
- Entry = Entry->Flink;
if (DiskEntry->BiosDiskNumber == BiosDiskNumber)
{
PLIST_ENTRY Entry;
/* Loop over the disks and find the correct one */
- Entry = List->DiskListHead.Flink;
- while (Entry != &List->DiskListHead)
+ for (Entry = List->DiskListHead.Flink;
+ Entry != &List->DiskListHead;
+ Entry = Entry->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
- Entry = Entry->Flink;
if (DiskEntry->DiskNumber == DiskNumber)
{
PLIST_ENTRY Entry;
/* Loop over the disks and find the correct one */
- Entry = List->DiskListHead.Flink;
- while (Entry != &List->DiskListHead)
+ for (Entry = List->DiskListHead.Flink;
+ Entry != &List->DiskListHead;
+ Entry = Entry->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
- Entry = Entry->Flink;
if (DiskEntry->Port == Port &&
DiskEntry->Bus == Bus &&
PLIST_ENTRY Entry;
/* Loop over the disks and find the correct one */
- Entry = List->DiskListHead.Flink;
- while (Entry != &List->DiskListHead)
+ for (Entry = List->DiskListHead.Flink;
+ Entry != &List->DiskListHead;
+ Entry = Entry->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
- Entry = Entry->Flink;
if (DiskEntry->LayoutBuffer->Signature == Signature)
{
PPARTENTRY PartEntry;
PLIST_ENTRY Entry;
+ if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ return NULL;
+ }
+
/* Disk found, loop over the primary partitions first... */
- Entry = DiskEntry->PrimaryPartListHead.Flink;
- while (Entry != &DiskEntry->PrimaryPartListHead)
+ for (Entry = DiskEntry->PrimaryPartListHead.Flink;
+ Entry != &DiskEntry->PrimaryPartListHead;
+ Entry = Entry->Flink)
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
- Entry = Entry->Flink;
if (PartEntry->PartitionNumber == PartitionNumber)
{
}
/* ... then over the logical partitions if needed */
- Entry = DiskEntry->LogicalPartListHead.Flink;
- while (Entry != &DiskEntry->LogicalPartListHead)
+ for (Entry = DiskEntry->LogicalPartListHead.Flink;
+ Entry != &DiskEntry->LogicalPartListHead;
+ Entry = Entry->Flink)
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
- Entry = Entry->Flink;
if (PartEntry->PartitionNumber == PartitionNumber)
{
/* If we have a partition (PartitionNumber != 0), find it */
if (PartitionNumber != 0)
{
+ if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ return FALSE;
+ }
+
PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
if (!PartEntry)
return FALSE;
//
// NOTE: Was introduced broken in r6258 by Casper
//
-BOOLEAN
+PPARTENTRY
SelectPartition(
IN PPARTLIST List,
IN ULONG DiskNumber,
DiskEntry = GetDiskByNumber(List, DiskNumber);
if (!DiskEntry)
- return FALSE;
+ return NULL;
PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
if (!PartEntry)
- return FALSE;
+ return NULL;
ASSERT(PartEntry->DiskEntry == DiskEntry);
ASSERT(DiskEntry->DiskNumber == DiskNumber);
ASSERT(PartEntry->PartitionNumber == PartitionNumber);
- List->CurrentDisk = DiskEntry;
- List->CurrentPartition = PartEntry;
- return TRUE;
+ return PartEntry;
}
PPARTENTRY
GetNextPartition(
- IN PPARTLIST List)
+ IN PPARTLIST List,
+ IN PPARTENTRY CurrentPart OPTIONAL)
{
PLIST_ENTRY DiskListEntry;
PLIST_ENTRY PartListEntry;
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
+ PDISKENTRY CurrentDisk;
/* Fail if no disks are available */
if (IsListEmpty(&List->DiskListHead))
return NULL;
- /* Check for next usable entry on current disk */
- if (List->CurrentPartition != NULL)
+ /* Check for the next usable entry on the current partition's disk */
+ if (CurrentPart != NULL)
{
- if (List->CurrentPartition->LogicalPartition)
+ CurrentDisk = CurrentPart->DiskEntry;
+
+ if (CurrentPart->LogicalPartition)
{
/* Logical partition */
- PartListEntry = List->CurrentPartition->ListEntry.Flink;
- if (PartListEntry != &List->CurrentDisk->LogicalPartListHead)
+ PartListEntry = CurrentPart->ListEntry.Flink;
+ if (PartListEntry != &CurrentDisk->LogicalPartListHead)
{
/* Next logical partition */
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
-
- List->CurrentPartition = PartEntry;
- return List->CurrentPartition;
+ CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
+ return CurrentPart;
}
else
{
- PartListEntry = List->CurrentDisk->ExtendedPartition->ListEntry.Flink;
- if (PartListEntry != &List->CurrentDisk->PrimaryPartListHead)
+ PartListEntry = CurrentDisk->ExtendedPartition->ListEntry.Flink;
+ if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
{
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
-
- List->CurrentPartition = PartEntry;
- return List->CurrentPartition;
+ CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
+ return CurrentPart;
}
}
}
{
/* Primary or extended partition */
- if ((List->CurrentPartition->IsPartitioned != FALSE) &&
- IsContainerPartition(List->CurrentPartition->PartitionType))
+ if (CurrentPart->IsPartitioned &&
+ IsContainerPartition(CurrentPart->PartitionType))
{
/* First logical partition */
- PartListEntry = List->CurrentDisk->LogicalPartListHead.Flink;
- if (PartListEntry != &List->CurrentDisk->LogicalPartListHead)
+ PartListEntry = CurrentDisk->LogicalPartListHead.Flink;
+ if (PartListEntry != &CurrentDisk->LogicalPartListHead)
{
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
-
- List->CurrentPartition = PartEntry;
- return List->CurrentPartition;
+ CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
+ return CurrentPart;
}
}
else
{
/* Next primary partition */
- PartListEntry = List->CurrentPartition->ListEntry.Flink;
- if (PartListEntry != &List->CurrentDisk->PrimaryPartListHead)
+ PartListEntry = CurrentPart->ListEntry.Flink;
+ if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
{
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
-
- List->CurrentPartition = PartEntry;
- return List->CurrentPartition;
+ CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
+ return CurrentPart;
}
}
}
}
/* Search for the first partition entry on the next disk */
- DiskListEntry = List->CurrentDisk->ListEntry.Flink;
- while (DiskListEntry != &List->DiskListHead)
+ for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Flink
+ : List->DiskListHead.Flink);
+ DiskListEntry != &List->DiskListHead;
+ DiskListEntry = DiskListEntry->Flink)
{
- DiskEntry = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
+ CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
- PartListEntry = DiskEntry->PrimaryPartListHead.Flink;
- if (PartListEntry != &DiskEntry->PrimaryPartListHead)
+ if (CurrentDisk->DiskStyle == PARTITION_STYLE_GPT)
{
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
-
- List->CurrentDisk = DiskEntry;
- List->CurrentPartition = PartEntry;
- return List->CurrentPartition;
+ DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ continue;
}
- DiskListEntry = DiskListEntry->Flink;
+ PartListEntry = CurrentDisk->PrimaryPartListHead.Flink;
+ if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
+ {
+ CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
+ return CurrentPart;
+ }
}
return NULL;
PPARTENTRY
GetPrevPartition(
- IN PPARTLIST List)
+ IN PPARTLIST List,
+ IN PPARTENTRY CurrentPart OPTIONAL)
{
PLIST_ENTRY DiskListEntry;
PLIST_ENTRY PartListEntry;
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
+ PDISKENTRY CurrentDisk;
/* Fail if no disks are available */
if (IsListEmpty(&List->DiskListHead))
return NULL;
- /* Check for previous usable entry on current disk */
- if (List->CurrentPartition != NULL)
+ /* Check for the previous usable entry on the current partition's disk */
+ if (CurrentPart != NULL)
{
- if (List->CurrentPartition->LogicalPartition)
+ CurrentDisk = CurrentPart->DiskEntry;
+
+ if (CurrentPart->LogicalPartition)
{
/* Logical partition */
- PartListEntry = List->CurrentPartition->ListEntry.Blink;
- if (PartListEntry != &List->CurrentDisk->LogicalPartListHead)
+
+ PartListEntry = CurrentPart->ListEntry.Blink;
+ if (PartListEntry != &CurrentDisk->LogicalPartListHead)
{
/* Previous logical partition */
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
+ CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
}
else
{
/* Extended partition */
- PartEntry = List->CurrentDisk->ExtendedPartition;
+ CurrentPart = CurrentDisk->ExtendedPartition;
}
-
- List->CurrentPartition = PartEntry;
- return List->CurrentPartition;
+ return CurrentPart;
}
else
{
/* Primary or extended partition */
- PartListEntry = List->CurrentPartition->ListEntry.Blink;
- if (PartListEntry != &List->CurrentDisk->PrimaryPartListHead)
+ PartListEntry = CurrentPart->ListEntry.Blink;
+ if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
{
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
+ CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
- if ((PartEntry->IsPartitioned != FALSE) &&
- IsContainerPartition(PartEntry->PartitionType))
+ if (CurrentPart->IsPartitioned &&
+ IsContainerPartition(CurrentPart->PartitionType))
{
- PartListEntry = List->CurrentDisk->LogicalPartListHead.Blink;
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
+ PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
+ CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
}
- List->CurrentPartition = PartEntry;
- return List->CurrentPartition;
+ return CurrentPart;
}
}
}
/* Search for the last partition entry on the previous disk */
- DiskListEntry = List->CurrentDisk->ListEntry.Blink;
- while (DiskListEntry != &List->DiskListHead)
+ for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Blink
+ : List->DiskListHead.Blink);
+ DiskListEntry != &List->DiskListHead;
+ DiskListEntry = DiskListEntry->Blink)
{
- DiskEntry = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
+ CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
+
+ if (CurrentDisk->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ continue;
+ }
- PartListEntry = DiskEntry->PrimaryPartListHead.Blink;
- if (PartListEntry != &DiskEntry->PrimaryPartListHead)
+ PartListEntry = CurrentDisk->PrimaryPartListHead.Blink;
+ if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
{
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
+ CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
- if ((PartEntry->IsPartitioned != FALSE) &&
- IsContainerPartition(PartEntry->PartitionType))
+ if (CurrentPart->IsPartitioned &&
+ IsContainerPartition(CurrentPart->PartitionType))
{
- PartListEntry = DiskEntry->LogicalPartListHead.Blink;
- if (PartListEntry != &DiskEntry->LogicalPartListHead)
+ PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
+ if (PartListEntry != &CurrentDisk->LogicalPartListHead)
{
- PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
-
- List->CurrentDisk = DiskEntry;
- List->CurrentPartition = PartEntry;
- return List->CurrentPartition;
+ CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
+ return CurrentPart;
}
}
else
{
- List->CurrentDisk = DiskEntry;
- List->CurrentPartition = PartEntry;
- return List->CurrentPartition;
+ return CurrentPart;
}
}
-
- DiskListEntry = DiskListEntry->Blink;
}
return NULL;
{
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;
PPARTENTRY PartEntry;
ULONG Count = 0;
- Entry = DiskEntry->PrimaryPartListHead.Flink;
- while (Entry != &DiskEntry->PrimaryPartListHead)
+ if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ return 0;
+ }
+
+ for (Entry = DiskEntry->PrimaryPartListHead.Flink;
+ Entry != &DiskEntry->PrimaryPartListHead;
+ Entry = Entry->Flink)
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned)
Count++;
-
- Entry = Entry->Flink;
}
return Count;
PPARTENTRY PartEntry;
ULONG Count = 0;
- ListEntry = DiskEntry->LogicalPartListHead.Flink;
- while (ListEntry != &DiskEntry->LogicalPartListHead)
+ if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ return 0;
+ }
+
+ for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
+ ListEntry != &DiskEntry->LogicalPartListHead;
+ ListEntry = ListEntry->Flink)
{
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned)
Count++;
-
- ListEntry = ListEntry->Flink;
}
return Count;
if (DiskEntry->LayoutBuffer)
CurrentPartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
- DPRINT1("CurrentPartitionCount: %lu NewPartitionCount: %lu\n",
+ DPRINT1("CurrentPartitionCount: %lu ; NewPartitionCount: %lu\n",
CurrentPartitionCount, NewPartitionCount);
if (CurrentPartitionCount == NewPartitionCount)
return FALSE;
}
+ NewLayoutBuffer->PartitionCount = NewPartitionCount;
+
/* 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;
}
DPRINT1("UpdateDiskLayout()\n");
+ if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ return;
+ }
+
/* Resize the layout buffer if necessary */
if (ReAllocateLayoutBuffer(DiskEntry) == FALSE)
{
/* Update the primary partition table */
Index = 0;
- ListEntry = DiskEntry->PrimaryPartListHead.Flink;
- while (ListEntry != &DiskEntry->PrimaryPartListHead)
+ for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
+ ListEntry != &DiskEntry->PrimaryPartListHead;
+ ListEntry = ListEntry->Flink)
{
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
- if (PartEntry->IsPartitioned != FALSE)
+ if (PartEntry->IsPartitioned)
{
+ ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
+
PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
+ PartEntry->PartitionIndex = Index;
+
+ /* Reset the current partition number only for newly-created (unmounted) partitions */
+ if (PartEntry->New)
+ PartEntry->PartitionNumber = 0;
+
+ PartEntry->OnDiskPartitionNumber = (!IsContainerPartition(PartEntry->PartitionType) ? PartitionNumber : 0);
if (!IsSamePrimaryLayoutEntry(PartitionInfo, DiskEntry, PartEntry))
{
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->PartitionNumber = PartEntry->PartitionNumber;
PartitionInfo->PartitionType = PartEntry->PartitionType;
PartitionInfo->BootIndicator = PartEntry->BootIndicator;
- PartitionInfo->RecognizedPartition = FALSE;
+ PartitionInfo->RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
PartitionInfo->RewritePartition = TRUE;
}
- PartEntry->PartitionNumber = (!IsContainerPartition(PartEntry->PartitionType)) ? PartitionNumber : 0;
- PartEntry->PartitionIndex = Index;
-
if (!IsContainerPartition(PartEntry->PartitionType))
PartitionNumber++;
Index++;
}
-
- ListEntry = ListEntry->Flink;
}
+ ASSERT(Index <= 4);
+
/* Update the logical partition table */
Index = 4;
- ListEntry = DiskEntry->LogicalPartListHead.Flink;
- while (ListEntry != &DiskEntry->LogicalPartListHead)
+ for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
+ ListEntry != &DiskEntry->LogicalPartListHead;
+ ListEntry = ListEntry->Flink)
{
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned)
{
+ ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
+
PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
+ PartEntry->PartitionIndex = Index;
+
+ /* Reset the current partition number only for newly-created (unmounted) partitions */
+ if (PartEntry->New)
+ PartEntry->PartitionNumber = 0;
+
+ PartEntry->OnDiskPartitionNumber = PartitionNumber;
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->PartitionNumber = PartEntry->PartitionNumber;
PartitionInfo->PartitionType = PartEntry->PartitionType;
PartitionInfo->BootIndicator = FALSE;
- PartitionInfo->RecognizedPartition = FALSE;
+ PartitionInfo->RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
PartitionInfo->RewritePartition = TRUE;
- PartEntry->PartitionNumber = PartitionNumber;
- PartEntry->PartitionIndex = Index;
-
/* Fill the link entry of the previous partition entry */
if (LinkInfo != NULL)
{
PartitionNumber++;
Index += 4;
}
-
- ListEntry = ListEntry->Flink;
}
/* Wipe unused primary partition entries */
}
}
+ DiskEntry->Dirty = TRUE;
+
#ifdef DUMP_PARTITION_TABLE
DumpPartitionTable(DiskEntry);
#endif
static
PPARTENTRY
GetPrevUnpartitionedEntry(
- IN PDISKENTRY DiskEntry,
IN PPARTENTRY PartEntry)
{
+ PDISKENTRY DiskEntry = PartEntry->DiskEntry;
PPARTENTRY PrevPartEntry;
PLIST_ENTRY ListHead;
+ if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ return NULL;
+ }
+
if (PartEntry->LogicalPartition)
ListHead = &DiskEntry->LogicalPartListHead;
else
PrevPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Blink,
PARTENTRY,
ListEntry);
- if (PrevPartEntry->IsPartitioned == FALSE)
+ if (!PrevPartEntry->IsPartitioned)
+ {
+ ASSERT(PrevPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
return PrevPartEntry;
+ }
}
return NULL;
static
PPARTENTRY
GetNextUnpartitionedEntry(
- IN PDISKENTRY DiskEntry,
IN PPARTENTRY PartEntry)
{
+ PDISKENTRY DiskEntry = PartEntry->DiskEntry;
PPARTENTRY NextPartEntry;
PLIST_ENTRY ListHead;
+ if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ return NULL;
+ }
+
if (PartEntry->LogicalPartition)
ListHead = &DiskEntry->LogicalPartListHead;
else
NextPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Flink,
PARTENTRY,
ListEntry);
- if (NextPartEntry->IsPartitioned == FALSE)
+ if (!NextPartEntry->IsPartitioned)
+ {
+ ASSERT(NextPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
return NextPartEntry;
+ }
}
return NULL;
}
-VOID
+BOOLEAN
CreatePrimaryPartition(
IN PPARTLIST List,
+ IN PPARTENTRY SelectedEntry,
IN ULONGLONG SectorCount,
IN BOOLEAN AutoCreate)
{
- PDISKENTRY DiskEntry;
+ ERROR_NUMBER Error;
PPARTENTRY PartEntry;
- PPARTENTRY NewPartEntry;
DPRINT1("CreatePrimaryPartition(%I64u)\n", SectorCount);
if (List == NULL ||
- List->CurrentDisk == NULL ||
- List->CurrentPartition == NULL ||
- List->CurrentPartition->IsPartitioned != FALSE)
+ SelectedEntry == NULL ||
+ SelectedEntry->DiskEntry == NULL ||
+ SelectedEntry->IsPartitioned)
{
- return;
+ return FALSE;
}
- 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->FileSystem = NULL;
- 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
+ Error = PrimaryPartitionCreationChecks(SelectedEntry);
+ if (Error != NOT_AN_ERROR)
{
- 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->FileSystem = NULL;
- NewPartEntry->BootIndicator = FALSE;
-
- PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart;
- PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart);
+ DPRINT1("PrimaryPartitionCreationChecks() failed with error %lu\n", Error);
+ return FALSE;
}
- UpdateDiskLayout(DiskEntry);
+ /* Convert the current entry, or insert and initialize a new partition entry */
+ PartEntry = InitializePartitionEntry(SelectedEntry->DiskEntry, SelectedEntry, SectorCount, AutoCreate);
+ if (PartEntry == NULL)
+ return FALSE;
- DiskEntry->Dirty = TRUE;
+ UpdateDiskLayout(PartEntry->DiskEntry);
AssignDriveLetters(List);
+
+ return TRUE;
}
static
AddLogicalDiskSpace(
IN PDISKENTRY DiskEntry)
{
+ ULONGLONG StartSector;
+ ULONGLONG SectorCount;
PPARTENTRY NewPartEntry;
DPRINT1("AddLogicalDiskSpace()\n");
/* Create a partition entry that represents the empty space in the container partition */
- NewPartEntry = RtlAllocateHeap(ProcessHeap,
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
+
+ StartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
+ SectorCount = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
+
+ NewPartEntry = CreateInsertBlankRegion(DiskEntry,
+ &DiskEntry->LogicalPartListHead,
+ StartSector,
+ SectorCount,
+ TRUE);
if (NewPartEntry == NULL)
+ {
+ DPRINT1("Failed to create a new empty region for extended partition space!\n");
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;
- NewPartEntry->FileSystem = NULL;
-
- InsertTailList(&DiskEntry->LogicalPartListHead,
- &NewPartEntry->ListEntry);
}
-VOID
+BOOLEAN
CreateExtendedPartition(
IN PPARTLIST List,
+ IN PPARTENTRY SelectedEntry,
IN ULONGLONG SectorCount)
{
- PDISKENTRY DiskEntry;
+ ERROR_NUMBER Error;
PPARTENTRY PartEntry;
- PPARTENTRY NewPartEntry;
DPRINT1("CreateExtendedPartition(%I64u)\n", SectorCount);
if (List == NULL ||
- List->CurrentDisk == NULL ||
- List->CurrentPartition == NULL ||
- List->CurrentPartition->IsPartitioned != FALSE)
+ SelectedEntry == NULL ||
+ SelectedEntry->DiskEntry == NULL ||
+ SelectedEntry->IsPartitioned)
{
- return;
+ return FALSE;
}
- 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)
+ Error = ExtendedPartitionCreationChecks(SelectedEntry);
+ if (Error != NOT_AN_ERROR)
{
- DPRINT1("Convert existing partition entry\n");
-
- /* Convert current entry to 'new (unformatted)' */
- PartEntry->IsPartitioned = TRUE;
- PartEntry->FormatState = Formatted; // FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container)
- PartEntry->FileSystem = NULL;
- 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;
- }
+ DPRINT1("ExtendedPartitionCreationChecks() failed with error %lu\n", Error);
+ return FALSE;
+ }
- DiskEntry->ExtendedPartition = PartEntry;
+ /* Convert the current entry, or insert and initialize a new partition entry */
+ PartEntry = InitializePartitionEntry(SelectedEntry->DiskEntry, SelectedEntry, SectorCount, FALSE);
+ if (PartEntry == NULL)
+ return 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);
+ if (PartEntry->StartSector.QuadPart < 1450560)
+ {
+ /* Partition starts below the 8.4GB boundary ==> CHS partition */
+ PartEntry->PartitionType = PARTITION_EXTENDED;
}
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; // FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container)
- NewPartEntry->FileSystem = NULL;
- 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);
+ /* Partition starts above the 8.4GB boundary ==> LBA partition */
+ PartEntry->PartitionType = PARTITION_XINT13_EXTENDED;
}
- AddLogicalDiskSpace(DiskEntry);
+ // FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container)
+ PartEntry->New = FALSE;
+ PartEntry->FormatState = Formatted;
- UpdateDiskLayout(DiskEntry);
+ PartEntry->DiskEntry->ExtendedPartition = PartEntry;
- DiskEntry->Dirty = TRUE;
+ AddLogicalDiskSpace(PartEntry->DiskEntry);
+
+ UpdateDiskLayout(PartEntry->DiskEntry);
AssignDriveLetters(List);
+
+ return TRUE;
}
-VOID
+BOOLEAN
CreateLogicalPartition(
IN PPARTLIST List,
+ IN PPARTENTRY SelectedEntry,
IN ULONGLONG SectorCount,
IN BOOLEAN AutoCreate)
{
- PDISKENTRY DiskEntry;
+ ERROR_NUMBER Error;
PPARTENTRY PartEntry;
- PPARTENTRY NewPartEntry;
DPRINT1("CreateLogicalPartition(%I64u)\n", SectorCount);
if (List == NULL ||
- List->CurrentDisk == NULL ||
- List->CurrentPartition == NULL ||
- List->CurrentPartition->IsPartitioned != FALSE)
+ SelectedEntry == NULL ||
+ SelectedEntry->DiskEntry == NULL ||
+ SelectedEntry->IsPartitioned)
{
- return;
+ return FALSE;
}
- DiskEntry = List->CurrentDisk;
- PartEntry = List->CurrentPartition;
+ Error = LogicalPartitionCreationChecks(SelectedEntry);
+ if (Error != NOT_AN_ERROR)
+ {
+ DPRINT1("LogicalPartitionCreationChecks() failed with error %lu\n", Error);
+ return FALSE;
+ }
- DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart);
+ /* Convert the current entry, or insert and initialize a new partition entry */
+ PartEntry = InitializePartitionEntry(SelectedEntry->DiskEntry, SelectedEntry, SectorCount, AutoCreate);
+ if (PartEntry == NULL)
+ return FALSE;
- if ((AutoCreate != FALSE) ||
- (AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart))
- {
- DPRINT1("Convert existing partition entry\n");
+ PartEntry->LogicalPartition = TRUE;
- /* Convert current entry to 'new (unformatted)' */
- PartEntry->IsPartitioned = TRUE;
- PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
- PartEntry->FormatState = Unformatted;
- PartEntry->FileSystem = NULL;
- PartEntry->AutoCreate = FALSE;
- PartEntry->New = TRUE;
- PartEntry->BootIndicator = FALSE;
- PartEntry->LogicalPartition = TRUE;
+ UpdateDiskLayout(PartEntry->DiskEntry);
- 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");
+ AssignDriveLetters(List);
- /* Insert and initialize a new partition entry */
- NewPartEntry = RtlAllocateHeap(ProcessHeap,
- HEAP_ZERO_MEMORY,
- sizeof(PARTENTRY));
- if (NewPartEntry == NULL)
- return;
+ return TRUE;
+}
- /* Insert the new entry into the list */
- InsertTailList(&PartEntry->ListEntry,
- &NewPartEntry->ListEntry);
+static
+NTSTATUS
+DismountVolume(
+ IN PPARTENTRY PartEntry)
+{
+ NTSTATUS Status;
+ NTSTATUS LockStatus;
+ UNICODE_STRING Name;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ HANDLE PartitionHandle;
+ WCHAR Buffer[MAX_PATH];
- NewPartEntry->DiskEntry = DiskEntry;
+ /* Check whether the partition is valid and was mounted by the system */
+ if (!PartEntry->IsPartitioned ||
+ IsContainerPartition(PartEntry->PartitionType) ||
+ !IsRecognizedPartition(PartEntry->PartitionType) ||
+ PartEntry->FormatState == Unformatted /* || PartEntry->FormatState == UnknownFormat */ ||
+ !*PartEntry->FileSystem ||
+ PartEntry->PartitionNumber == 0)
+ {
+ /* The partition is not mounted, so just return success */
+ return STATUS_SUCCESS;
+ }
- 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;
+ ASSERT(PartEntry->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);
+ /* Open the volume */
+ RtlStringCchPrintfW(Buffer, ARRAYSIZE(Buffer),
+ L"\\Device\\Harddisk%lu\\Partition%lu",
+ PartEntry->DiskEntry->DiskNumber,
+ PartEntry->PartitionNumber);
+ RtlInitUnicodeString(&Name, Buffer);
- NewPartEntry->New = TRUE;
- NewPartEntry->FormatState = Unformatted;
- NewPartEntry->FileSystem = NULL;
- NewPartEntry->BootIndicator = FALSE;
- NewPartEntry->LogicalPartition = TRUE;
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
- PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart;
- PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart);
+ Status = NtOpenFile(&PartitionHandle,
+ GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_SYNCHRONOUS_IO_NONALERT);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ERROR: Cannot open volume %wZ for dismounting! (Status 0x%lx)\n", &Name, Status);
+ return Status;
}
- UpdateDiskLayout(DiskEntry);
+ /* Lock the volume */
+ LockStatus = NtFsControlFile(PartitionHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ FSCTL_LOCK_VOLUME,
+ NULL,
+ 0,
+ NULL,
+ 0);
+ if (!NT_SUCCESS(LockStatus))
+ {
+ DPRINT1("WARNING: Failed to lock volume! Operations may fail! (Status 0x%lx)\n", LockStatus);
+ }
- DiskEntry->Dirty = TRUE;
+ /* Dismount the volume */
+ Status = NtFsControlFile(PartitionHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ FSCTL_DISMOUNT_VOLUME,
+ NULL,
+ 0,
+ NULL,
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to unmount volume (Status 0x%lx)\n", Status);
+ }
- AssignDriveLetters(List);
+ /* Unlock the volume */
+ LockStatus = NtFsControlFile(PartitionHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ FSCTL_UNLOCK_VOLUME,
+ NULL,
+ 0,
+ NULL,
+ 0);
+ if (!NT_SUCCESS(LockStatus))
+ {
+ DPRINT1("Failed to unlock volume (Status 0x%lx)\n", LockStatus);
+ }
+
+ /* Close the volume */
+ NtClose(PartitionHandle);
+
+ return Status;
}
-VOID
-DeleteCurrentPartition(
- IN PPARTLIST List)
+BOOLEAN
+DeletePartition(
+ IN PPARTLIST List,
+ IN PPARTENTRY PartEntry,
+ OUT PPARTENTRY* FreeRegion OPTIONAL)
{
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)
+ PartEntry == NULL ||
+ PartEntry->DiskEntry == NULL ||
+ PartEntry->IsPartitioned == FALSE)
{
- return;
+ return FALSE;
}
- /* Clear the system disk and partition pointers if the system partition is being deleted */
- if (List->SystemPartition == List->CurrentPartition)
+ ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
+
+ /* Clear the system partition pointers if it is being deleted */
+ if (List->SystemPartition == PartEntry)
{
+ ASSERT(List->SystemPartition);
+
+ if (List->SystemPartition == List->OriginalSystemPartition)
+ List->OriginalSystemPartition = NULL;
List->SystemPartition = NULL;
}
- DiskEntry = List->CurrentDisk;
- PartEntry = List->CurrentPartition;
+ DiskEntry = PartEntry->DiskEntry;
- /* Delete all logical partition entries if an extended partition will be deleted */
+ /* Check which type of partition (primary/logical or extended) is being deleted */
if (DiskEntry->ExtendedPartition == PartEntry)
{
+ /* An extended partition is being deleted: delete all logical partition entries */
while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
{
Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
+ /* Dismount the logical partition */
+ DismountVolume(LogicalPartEntry);
+
+ /* Delete it */
RtlFreeHeap(ProcessHeap, 0, LogicalPartEntry);
}
DiskEntry->ExtendedPartition = NULL;
}
+ else
+ {
+ /* A primary partition is being deleted: dismount it */
+ DismountVolume(PartEntry);
+ }
- /* Adjust unpartitioned disk space entries */
+ /* Adjust the unpartitioned disk space entries */
/* Get pointer to previous and next unpartitioned entries */
- PrevPartEntry = GetPrevUnpartitionedEntry(DiskEntry, PartEntry);
- NextPartEntry = GetNextUnpartitionedEntry(DiskEntry, PartEntry);
+ PrevPartEntry = GetPrevUnpartitionedEntry(PartEntry);
+ NextPartEntry = GetNextUnpartitionedEntry(PartEntry);
if (PrevPartEntry != NULL && NextPartEntry != NULL)
{
- /* Merge previous, current and next unpartitioned entry */
+ /* Merge the previous, current and next unpartitioned entries */
- /* Adjust the previous entries length */
+ /* Adjust the previous entry length */
PrevPartEntry->SectorCount.QuadPart += (PartEntry->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart);
- /* Remove the current entry */
+ /* Remove the current and next entries */
RemoveEntryList(&PartEntry->ListEntry);
RtlFreeHeap(ProcessHeap, 0, PartEntry);
-
- /* Remove the next entry */
RemoveEntryList(&NextPartEntry->ListEntry);
RtlFreeHeap(ProcessHeap, 0, NextPartEntry);
- /* Update current partition */
- List->CurrentPartition = PrevPartEntry;
+ /* Optionally return the freed region */
+ if (FreeRegion)
+ *FreeRegion = PrevPartEntry;
}
else if (PrevPartEntry != NULL && NextPartEntry == NULL)
{
- /* Merge current and previous unpartitioned entry */
+ /* Merge the current and the previous unpartitioned entries */
- /* Adjust the previous entries length */
+ /* Adjust the previous entry length */
PrevPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
/* Remove the current entry */
RemoveEntryList(&PartEntry->ListEntry);
RtlFreeHeap(ProcessHeap, 0, PartEntry);
- /* Update current partition */
- List->CurrentPartition = PrevPartEntry;
+ /* Optionally return the freed region */
+ if (FreeRegion)
+ *FreeRegion = PrevPartEntry;
}
else if (PrevPartEntry == NULL && NextPartEntry != NULL)
{
- /* Merge current and next unpartitioned entry */
+ /* Merge the current and the next unpartitioned entries */
- /* Adjust the next entries offset and length */
+ /* Adjust the next entry offset and length */
NextPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
NextPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
RemoveEntryList(&PartEntry->ListEntry);
RtlFreeHeap(ProcessHeap, 0, PartEntry);
- /* Update current partition */
- List->CurrentPartition = NextPartEntry;
+ /* Optionally return the freed region */
+ if (FreeRegion)
+ *FreeRegion = NextPartEntry;
}
else
{
- /* Nothing to merge but change current entry */
+ /* Nothing to merge but change the current entry */
PartEntry->IsPartitioned = FALSE;
PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
PartEntry->FormatState = Unformatted;
- PartEntry->FileSystem = NULL;
+ PartEntry->FileSystem[0] = L'\0';
PartEntry->DriveLetter = 0;
+ PartEntry->OnDiskPartitionNumber = 0;
+ PartEntry->PartitionNumber = 0;
+ // PartEntry->PartitionIndex = 0;
+
+ /* Optionally return the freed region */
+ if (FreeRegion)
+ *FreeRegion = PartEntry;
}
UpdateDiskLayout(DiskEntry);
- DiskEntry->Dirty = TRUE;
-
AssignDriveLetters(List);
+
+ return TRUE;
}
-VOID
-CheckActiveSystemPartition(
- IN PPARTLIST List)
+/*
+ * Retrieve the actual "active" partition of the given disk.
+ * On MBR disks, partition with the Active/Boot flag set;
+ * on GPT disks, partition with the correct GUID.
+ */
+static
+PPARTENTRY
+GetActiveDiskPartition(
+ IN PDISKENTRY DiskEntry)
{
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
PLIST_ENTRY ListEntry;
-
- PFILE_SYSTEM FileSystem;
+ PPARTENTRY PartEntry;
+ PPARTENTRY ActivePartition = NULL;
/* Check for empty disk list */
- if (IsListEmpty(&List->DiskListHead))
+ // ASSERT(DiskEntry);
+ if (!DiskEntry)
+ return NULL;
+
+ /* Check for empty partition list */
+ if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
+ return NULL;
+
+ if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
- List->SystemPartition = NULL;
- List->OriginalSystemPartition = NULL;
- return;
+ DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ return NULL;
}
- /* Choose the currently selected disk */
- DiskEntry = List->CurrentDisk;
+ /* Scan all (primary) partitions to find the active disk partition */
+ for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
+ ListEntry != &DiskEntry->PrimaryPartListHead;
+ ListEntry = ListEntry->Flink)
+ {
+ /* Retrieve the partition */
+ PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
- /* Check for empty partition list */
- if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
+ // TODO: Support for GPT disks!
+
+ /* Check if the partition is partitioned, used and active */
+ if (PartEntry->IsPartitioned &&
+ // !IsContainerPartition(PartEntry->PartitionType) &&
+ PartEntry->BootIndicator)
+ {
+ /* Yes, we found it */
+ ASSERT(DiskEntry == PartEntry->DiskEntry);
+ ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
+
+ ActivePartition = PartEntry;
+
+ DPRINT1("Found active system partition %lu in disk %lu, drive letter %C\n",
+ PartEntry->PartitionNumber, DiskEntry->DiskNumber,
+ (PartEntry->DriveLetter == 0) ? L'-' : PartEntry->DriveLetter);
+ break;
+ }
+ }
+
+ /* Check if the disk is new and if so, use its first partition as the active system partition */
+ if (DiskEntry->NewDisk && ActivePartition != NULL)
+ {
+ // FIXME: What to do??
+ DPRINT1("NewDisk TRUE but already existing active partition?\n");
+ }
+
+ /* Return the active partition found (or none) */
+ return ActivePartition;
+}
+
+static
+BOOLEAN
+IsSupportedActivePartition(
+ IN PPARTENTRY PartEntry)
+{
+ /* Check the type and the filesystem of this partition */
+
+ /*
+ * We do not support extended partition containers (on MBR disks) marked
+ * as active, and containing code inside their extended boot records.
+ */
+ if (IsContainerPartition(PartEntry->PartitionType))
+ {
+ DPRINT1("System partition %lu in disk %lu is an extended partition container?!\n",
+ PartEntry->PartitionNumber, PartEntry->DiskEntry->DiskNumber);
+ return FALSE;
+ }
+
+ /*
+ * 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.
+ */
+ if ((PartEntry->FormatState == Unformatted ) ||
+ (PartEntry->FormatState == Preformatted) ||
+ (PartEntry->FormatState == Formatted ))
+ {
+ ASSERT(*PartEntry->FileSystem);
+
+ /* NOTE: Please keep in sync with the RegisteredFileSystems list! */
+ if (wcsicmp(PartEntry->FileSystem, L"FAT") == 0 ||
+ wcsicmp(PartEntry->FileSystem, L"FAT32") == 0 ||
+ // wcsicmp(PartEntry->FileSystem, L"NTFS") == 0 ||
+ wcsicmp(PartEntry->FileSystem, L"BTRFS") == 0 ||
+ wcsicmp(PartEntry->FileSystem, L"RAW") == 0)
+ {
+ return TRUE;
+ }
+ else
+ {
+ // WARNING: We cannot write on this FS yet!
+ DPRINT1("Recognized file system '%S' that doesn't have write support yet!\n",
+ PartEntry->FileSystem);
+ return FALSE;
+ }
+ }
+ else // if (PartEntry->FormatState == UnknownFormat)
{
+ ASSERT(!*PartEntry->FileSystem);
+
+ DPRINT1("System partition %lu in disk %lu with no or unknown FS?!\n",
+ PartEntry->PartitionNumber, PartEntry->DiskEntry->DiskNumber);
+ return FALSE;
+ }
+
+ // HACK: WARNING: We cannot write on this FS yet!
+ // See fsutil.c:InferFileSystem()
+ if (PartEntry->PartitionType == PARTITION_IFS)
+ {
+ DPRINT1("Recognized file system '%S' that doesn't have write support yet!\n",
+ PartEntry->FileSystem);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+VOID
+CheckActiveSystemPartition(
+ IN PPARTLIST List,
+ IN BOOLEAN ForceSelect,
+ IN PDISKENTRY AlternateDisk OPTIONAL,
+ IN PPARTENTRY AlternatePart OPTIONAL)
+{
+ PLIST_ENTRY ListEntry;
+ PDISKENTRY DiskEntry;
+ PPARTENTRY PartEntry;
+ PPARTENTRY ActivePartition;
+ PPARTENTRY CandidatePartition = NULL;
+
+ /* Check for empty disk list */
+ if (IsListEmpty(&List->DiskListHead))
+ {
+ /* No system partition! */
List->SystemPartition = NULL;
List->OriginalSystemPartition = NULL;
- return;
+ goto NoSystemPartition;
}
if (List->SystemPartition != NULL)
return;
}
- DPRINT1("We are here (1)!\n");
-
+ /* Start fresh */
List->SystemPartition = NULL;
List->OriginalSystemPartition = NULL;
+ /* Adjust the optional alternate disk if needed */
+ if (!AlternateDisk && AlternatePart)
+ AlternateDisk = AlternatePart->DiskEntry;
+
+ /* Ensure that the alternate partition is on the alternate disk */
+ if (AlternatePart)
+ ASSERT(AlternateDisk && (AlternatePart->DiskEntry == AlternateDisk));
+
+ /* Ensure that the alternate disk is in the list */
+ if (AlternateDisk)
+ ASSERT(AlternateDisk->PartList == List);
+
+//
+// Pass == 1 : Check the first (system) disk.
+//
+
+ /*
+ * First, check whether the first disk (the one that will be booted
+ * by default by the hardware) contains an active partition. If so
+ * this should be our system partition.
+ */
+ DiskEntry = CONTAINING_RECORD(List->DiskListHead.Flink,
+ DISKENTRY, ListEntry);
+
+ if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT1("First (system) disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ goto UseAlternateDisk;
+ }
+
+ ActivePartition = GetActiveDiskPartition(DiskEntry);
+ if (ActivePartition)
+ {
+ /* Save the actual system partition */
+ List->OriginalSystemPartition = ActivePartition;
+
+ /* If we get a candidate active partition in the first disk, validate it */
+ if (IsSupportedActivePartition(ActivePartition))
+ {
+ CandidatePartition = ActivePartition;
+ goto SystemPartitionFound;
+ }
+ }
+
+ /* If this first disk is not the optional alternate disk, perform the minimal checks */
+ if (DiskEntry != AlternateDisk)
+ {
+ /*
+ * No active partition has been recognized. Enumerate all the (primary)
+ * partitions in the first disk, excluding the possible current active
+ * partition, to find a new candidate.
+ */
+ for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
+ ListEntry != &DiskEntry->PrimaryPartListHead;
+ ListEntry = ListEntry->Flink)
+ {
+ /* Retrieve the partition */
+ PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
+
+ /* Skip the current active partition */
+ if (/* ActivePartition != NULL && */ PartEntry == ActivePartition)
+ continue;
+
+ /* Check if the partition is partitioned and used */
+ if (PartEntry->IsPartitioned &&
+ !IsContainerPartition(PartEntry->PartitionType))
+ {
+ ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
+
+ /* If we get a candidate active partition in the first disk, validate it */
+ if (IsSupportedActivePartition(PartEntry))
+ {
+ CandidatePartition = PartEntry;
+ goto FindAndUseAlternativeSystemPartition;
+ }
+ }
+
+#if 0
+ /* Check if the partition is partitioned and used */
+ if (!PartEntry->IsPartitioned)
+ {
+ ASSERT(PartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
+
+ // TODO: Check for minimal size!!
+ CandidatePartition = PartEntry;
+ goto FindAndUseAlternativeSystemPartition;
+ }
+#endif
+ }
+
+ /*
+ * Still nothing, look whether there is some free space that we can use
+ * for the new system partition. We must be sure that the total number
+ * of partition is less than the maximum allowed, and that the minimal
+ * size is fine.
+ */
+//
+// TODO: Fix the handling of system partition being created in unpartitioned space!!
+// --> When to partition it? etc...
+//
+ if (GetPrimaryPartitionCount(DiskEntry) < 4)
+ {
+ for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
+ ListEntry != &DiskEntry->PrimaryPartListHead;
+ ListEntry = ListEntry->Flink)
+ {
+ /* Retrieve the partition */
+ PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
+
+ /* Skip the current active partition */
+ if (/* ActivePartition != NULL && */ PartEntry == ActivePartition)
+ continue;
+
+ /* Check for unpartitioned space */
+ if (!PartEntry->IsPartitioned)
+ {
+ ASSERT(PartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
+
+ // TODO: Check for minimal size!!
+ CandidatePartition = PartEntry;
+ goto FindAndUseAlternativeSystemPartition;
+ }
+ }
+ }
+ }
+
+
+//
+// Pass == 2 : No active partition found: Check the alternate disk if specified.
+//
+
+UseAlternateDisk:
+ if (!AlternateDisk || (!ForceSelect && (DiskEntry != AlternateDisk)))
+ goto NoSystemPartition;
+
+ if (AlternateDisk->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT1("Alternate disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ goto NoSystemPartition;
+ }
+
+ if (DiskEntry != AlternateDisk)
+ {
+ /* Choose the alternate disk */
+ DiskEntry = AlternateDisk;
+
+ ActivePartition = GetActiveDiskPartition(DiskEntry);
+ if (ActivePartition)
+ {
+ /* If we get a candidate active partition, validate it */
+ if (IsSupportedActivePartition(ActivePartition))
+ {
+ CandidatePartition = ActivePartition;
+ goto FindAndUseAlternativeSystemPartition;
+ }
+ }
+ }
+
+ /* We now may have an unsupported active partition, or none */
+
+/***
+ *** TODO: Improve the selection:
+ *** - If we want a really separate system partition from the partition where
+ *** we install, do something similar to what's done below in the code.
+ *** - Otherwise if we allow for the system partition to be also the partition
+ *** where we install, just directly fall down to using AlternatePart.
+ ***/
+
/* Retrieve the first partition of the disk */
PartEntry = CONTAINING_RECORD(DiskEntry->PrimaryPartListHead.Flink,
- PARTENTRY,
- ListEntry);
+ PARTENTRY, ListEntry);
ASSERT(DiskEntry == PartEntry->DiskEntry);
- List->SystemPartition = PartEntry;
+
+ CandidatePartition = 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)
+ // !IsContainerPartition(PartEntry->PartitionType);
+ if (!CandidatePartition->IsPartitioned || !CandidatePartition->BootIndicator) /* CandidatePartition != ActivePartition */
{
- ASSERT(DiskEntry == PartEntry->DiskEntry);
- List->SystemPartition = PartEntry;
+ ASSERT(DiskEntry == CandidatePartition->DiskEntry);
+ List->SystemPartition = CandidatePartition;
List->OriginalSystemPartition = List->SystemPartition;
DPRINT1("Use new first active system partition %lu in disk %lu, drive letter %C\n",
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)
+ for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
+ ListEntry != &DiskEntry->PrimaryPartListHead;
+ ListEntry = ListEntry->Flink)
{
- /* Retrieve the partition and go to the next one */
- PartEntry = CONTAINING_RECORD(ListEntry,
- PARTENTRY,
- ListEntry);
+ /* Retrieve the partition */
+ PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
/* Check if the partition is partitioned and is used */
- if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator != FALSE)
+ // !IsContainerPartition(PartEntry->PartitionType);
+ if (/* PartEntry->IsPartitioned && */
+ PartEntry->PartitionType != PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator)
{
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.
*/
- ASSERT(DiskEntry == List->SystemPartition->DiskEntry);
- List->OriginalSystemPartition = List->SystemPartition; // First PartEntry
+ ASSERT(DiskEntry == CandidatePartition->DiskEntry);
+ List->SystemPartition = CandidatePartition; // The first PartEntry
+ List->OriginalSystemPartition = List->SystemPartition;
DPRINT1("Use first active system partition %lu in disk %lu, drive letter %C\n",
List->SystemPartition->PartitionNumber,
goto SetSystemPartition;
}
- List->SystemPartition = 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 */
- ASSERT(DiskEntry == PartEntry->DiskEntry);
- List->SystemPartition = PartEntry;
-
- DPRINT1("Found active system partition %lu in disk %lu, drive letter %C\n",
- PartEntry->PartitionNumber,
- DiskEntry->DiskNumber,
- (PartEntry->DriveLetter == 0) ? L'-' : PartEntry->DriveLetter);
- break;
- }
- }
- }
-
- /* Check if we have found the system partition */
- if (List->SystemPartition == NULL)
- {
- /* Nothing, use the alternative system partition */
- DPRINT1("No system partition found, use the alternative partition!\n");
- goto UseAlternativeSystemPartition;
- }
-
- /* Save it */
- 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.
+ * The disk is not new, we did not find any actual active partition,
+ * or the one we found was not supported, or any possible other canditate
+ * is not supported. We then use the alternate partition if specified.
*/
- FileSystem = GetFileSystem(List->OriginalSystemPartition);
- if (FileSystem == NULL)
+ if (AlternatePart)
{
- DPRINT1("System partition %lu in disk %lu with no FS?!\n",
- List->OriginalSystemPartition->PartitionNumber,
- List->OriginalSystemPartition->DiskEntry->DiskNumber);
- goto FindAndUseAlternativeSystemPartition;
+ DPRINT1("No system partition found, use the alternative partition!\n");
+ CandidatePartition = AlternatePart;
+ goto UseAlternativeSystemPartition;
}
- // HACK: WARNING: We cannot write on this FS yet!
- // See fsutil.c:GetFileSystem()
- if (List->OriginalSystemPartition->PartitionType == PARTITION_IFS)
+ else
{
- DPRINT1("Recognized file system %S that doesn't support write support yet!\n",
- FileSystem->FileSystemName);
- goto FindAndUseAlternativeSystemPartition;
+NoSystemPartition:
+ DPRINT1("No valid or supported system partition has been found on this system!\n");
+ return;
}
+
+SystemPartitionFound:
+ ASSERT(CandidatePartition);
+ List->SystemPartition = CandidatePartition;
+
DPRINT1("Use existing active system partition %lu in disk %lu, drive letter %C\n",
List->SystemPartition->PartitionNumber,
List->SystemPartition->DiskEntry->DiskNumber,
*/
/* Unset the old system partition */
- List->SystemPartition->BootIndicator = FALSE;
- List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].BootIndicator = FALSE;
- List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].RewritePartition = TRUE;
- List->SystemPartition->DiskEntry->Dirty = TRUE;
+ if (List->OriginalSystemPartition)
+ {
+ List->OriginalSystemPartition->BootIndicator = FALSE;
+ List->OriginalSystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->OriginalSystemPartition->PartitionIndex].BootIndicator = FALSE;
+ List->OriginalSystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->OriginalSystemPartition->PartitionIndex].RewritePartition = TRUE;
+ List->OriginalSystemPartition->DiskEntry->Dirty = TRUE;
+ }
UseAlternativeSystemPartition:
- List->SystemPartition = List->CurrentPartition;
+ ASSERT(CandidatePartition);
+ List->SystemPartition = CandidatePartition;
DPRINT1("Use alternative active system partition %lu in disk %lu, drive letter %C\n",
List->SystemPartition->PartitionNumber,
List->SystemPartition->DiskEntry->Dirty = TRUE;
}
-static
NTSTATUS
WritePartitions(
- IN PPARTLIST List,
IN PDISKENTRY DiskEntry)
{
- WCHAR DstPath[MAX_PATH];
+ NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK Iosb;
UNICODE_STRING Name;
+ HANDLE FileHandle;
+ IO_STATUS_BLOCK Iosb;
ULONG BufferSize;
- HANDLE FileHandle = NULL;
- NTSTATUS Status;
+ PPARTITION_INFORMATION PartitionInfo;
+ ULONG PartitionCount;
+ PLIST_ENTRY ListEntry;
+ PPARTENTRY PartEntry;
+ WCHAR DstPath[MAX_PATH];
DPRINT("WritePartitions() Disk: %lu\n", DiskEntry->DiskNumber);
+ /* If the disk is not dirty, there is nothing to do */
+ if (!DiskEntry->Dirty)
+ return STATUS_SUCCESS;
+
RtlStringCchPrintfW(DstPath, ARRAYSIZE(DstPath),
L"\\Device\\Harddisk%lu\\Partition0",
DiskEntry->DiskNumber);
// For this we must ask the user which format to use.
//
+ /* Save the original partition count to be restored later (see comment below) */
+ PartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
+
+ /* Set the new disk layout and retrieve its updated version with possibly modified partition numbers */
BufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
- ((DiskEntry->LayoutBuffer->PartitionCount - 1) * sizeof(PARTITION_INFORMATION));
+ ((PartitionCount - 1) * sizeof(PARTITION_INFORMATION));
Status = NtDeviceIoControlFile(FileHandle,
NULL,
NULL,
IOCTL_DISK_SET_DRIVE_LAYOUT,
DiskEntry->LayoutBuffer,
BufferSize,
- NULL,
- 0);
+ DiskEntry->LayoutBuffer,
+ BufferSize);
+ NtClose(FileHandle);
+
+ /*
+ * IOCTL_DISK_SET_DRIVE_LAYOUT calls IoWritePartitionTable(), which converts
+ * DiskEntry->LayoutBuffer->PartitionCount into a partition *table* count,
+ * where such a table is expected to enumerate up to 4 partitions:
+ * partition *table* count == ROUND_UP(PartitionCount, 4) / 4 .
+ * Due to this we need to restore the original PartitionCount number.
+ */
+ DiskEntry->LayoutBuffer->PartitionCount = PartitionCount;
+
+ /* Check whether the IOCTL_DISK_SET_DRIVE_LAYOUT call succeeded */
if (!NT_SUCCESS(Status))
{
DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status);
+ return Status;
+ }
+
+#ifdef DUMP_PARTITION_TABLE
+ DumpPartitionTable(DiskEntry);
+#endif
+
+ /* Update the partition numbers */
+
+ /* Update the primary partition table */
+ for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
+ ListEntry != &DiskEntry->PrimaryPartListHead;
+ ListEntry = ListEntry->Flink)
+ {
+ PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
+
+ if (PartEntry->IsPartitioned)
+ {
+ ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
+ PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
+ PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
+ }
}
- if (FileHandle != NULL)
- NtClose(FileHandle);
+ /* Update the logical partition table */
+ for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
+ ListEntry != &DiskEntry->LogicalPartListHead;
+ ListEntry = ListEntry->Flink)
+ {
+ PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
+
+ if (PartEntry->IsPartitioned)
+ {
+ ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
+ PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
+ PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
+ }
+ }
//
// NOTE: Originally (see r40437), we used to install here also a new MBR
// DiskEntry->NoMbr was TRUE (instead of NewDisk).
//
+ /* The layout has been successfully updated, the disk is not dirty anymore */
+ DiskEntry->Dirty = FALSE;
+
return Status;
}
WritePartitionsToDisk(
IN PPARTLIST List)
{
+ NTSTATUS Status;
PLIST_ENTRY Entry;
PDISKENTRY DiskEntry;
if (List == NULL)
return TRUE;
- Entry = List->DiskListHead.Flink;
- while (Entry != &List->DiskListHead)
+ for (Entry = List->DiskListHead.Flink;
+ Entry != &List->DiskListHead;
+ Entry = Entry->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
- if (DiskEntry->Dirty != FALSE)
+ if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
{
- WritePartitions(List, DiskEntry);
- DiskEntry->Dirty = FALSE;
+ DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ continue;
}
- Entry = Entry->Flink;
+ if (DiskEntry->Dirty != FALSE)
+ {
+ Status = WritePartitions(DiskEntry);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("WritePartitionsToDisk() failed to update disk %lu, Status 0x%08lx\n",
+ DiskEntry->DiskNumber, Status);
+ }
+ }
}
return TRUE;
if (List == NULL)
return FALSE;
- Entry1 = List->DiskListHead.Flink;
- while (Entry1 != &List->DiskListHead)
+ for (Entry1 = List->DiskListHead.Flink;
+ Entry1 != &List->DiskListHead;
+ Entry1 = Entry1->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry1,
DISKENTRY,
ListEntry);
- Entry2 = DiskEntry->PrimaryPartListHead.Flink;
- while (Entry2 != &DiskEntry->PrimaryPartListHead)
+ if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ continue;
+ }
+
+ for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
+ Entry2 != &DiskEntry->PrimaryPartListHead;
+ Entry2 = Entry2->Flink)
{
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
- if (PartEntry->IsPartitioned)
+ if (PartEntry->IsPartitioned) // && !IsContainerPartition(PartEntry->PartitionType)
{
+ ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
+
/* Assign a "\DosDevices\#:" mount point to this partition */
if (PartEntry->DriveLetter)
{
}
}
}
-
- Entry2 = Entry2->Flink;
}
- Entry2 = DiskEntry->LogicalPartListHead.Flink;
- while (Entry2 != &DiskEntry->LogicalPartListHead)
+ for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
+ Entry2 != &DiskEntry->LogicalPartListHead;
+ Entry2 = Entry2->Flink)
{
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
- if (PartEntry->IsPartitioned)
+ if (PartEntry->IsPartitioned) // && !IsContainerPartition(PartEntry->PartitionType)
{
+ ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
+
/* Assign a "\DosDevices\#:" mount point to this partition */
if (PartEntry->DriveLetter)
{
}
}
}
-
- Entry2 = Entry2->Flink;
}
-
- Entry1 = Entry1->Flink;
}
return TRUE;
DiskEntry->Dirty = TRUE;
DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartitionType;
+ DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RecognizedPartition = IsRecognizedPartition(PartitionType);
DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
}
ERROR_NUMBER
PrimaryPartitionCreationChecks(
- IN PPARTLIST List)
+ IN PPARTENTRY PartEntry)
{
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
+ PDISKENTRY DiskEntry = PartEntry->DiskEntry;
- DiskEntry = List->CurrentDisk;
- PartEntry = List->CurrentPartition;
+ if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ return ERROR_WARN_PARTITION;
+ }
/* Fail if the partition is already in use */
- if (PartEntry->IsPartitioned != FALSE)
+ if (PartEntry->IsPartitioned)
return ERROR_NEW_PARTITION;
/* Fail if there are already 4 primary partitions in the list */
ERROR_NUMBER
ExtendedPartitionCreationChecks(
- IN PPARTLIST List)
+ IN PPARTENTRY PartEntry)
{
- PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
+ PDISKENTRY DiskEntry = PartEntry->DiskEntry;
- DiskEntry = List->CurrentDisk;
- PartEntry = List->CurrentPartition;
+ if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ return ERROR_WARN_PARTITION;
+ }
/* Fail if the partition is already in use */
- if (PartEntry->IsPartitioned != FALSE)
+ if (PartEntry->IsPartitioned)
return ERROR_NEW_PARTITION;
/* Fail if there are already 4 primary partitions in the list */
ERROR_NUMBER
LogicalPartitionCreationChecks(
- IN PPARTLIST List)
+ IN PPARTENTRY PartEntry)
{
-// PDISKENTRY DiskEntry;
- PPARTENTRY PartEntry;
+ PDISKENTRY DiskEntry = PartEntry->DiskEntry;
-// DiskEntry = List->CurrentDisk;
- PartEntry = List->CurrentPartition;
+ if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ return ERROR_WARN_PARTITION;
+ }
/* Fail if the partition is already in use */
- if (PartEntry->IsPartitioned != FALSE)
+ if (PartEntry->IsPartitioned)
return ERROR_NEW_PARTITION;
return ERROR_SUCCESS;
PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
- Entry1 = List->DiskListHead.Flink;
- while (Entry1 != &List->DiskListHead)
+ for (Entry1 = List->DiskListHead.Flink;
+ Entry1 != &List->DiskListHead;
+ Entry1 = Entry1->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry1,
DISKENTRY,
ListEntry);
- Entry2 = DiskEntry->PrimaryPartListHead.Flink;
- while (Entry2 != &DiskEntry->PrimaryPartListHead)
+ if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ continue;
+ }
+
+ for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
+ Entry2 != &DiskEntry->PrimaryPartListHead;
+ Entry2 = Entry2->Flink)
{
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned && PartEntry->New)
*pPartEntry = PartEntry;
return TRUE;
}
-
- Entry2 = Entry2->Flink;
}
- Entry2 = DiskEntry->LogicalPartListHead.Flink;
- while (Entry2 != &DiskEntry->LogicalPartListHead)
+ for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
+ Entry2 != &DiskEntry->LogicalPartListHead;
+ Entry2 = Entry2->Flink)
{
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned && PartEntry->New)
*pPartEntry = PartEntry;
return TRUE;
}
-
- Entry2 = Entry2->Flink;
}
-
- Entry1 = Entry1->Flink;
}
if (pDiskEntry) *pDiskEntry = NULL;
PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
- Entry1 = List->DiskListHead.Flink;
- while (Entry1 != &List->DiskListHead)
+ for (Entry1 = List->DiskListHead.Flink;
+ Entry1 != &List->DiskListHead;
+ Entry1 = Entry1->Flink)
{
DiskEntry = CONTAINING_RECORD(Entry1,
DISKENTRY,
ListEntry);
- Entry2 = DiskEntry->PrimaryPartListHead.Flink;
- while (Entry2 != &DiskEntry->PrimaryPartListHead)
+ if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
+ {
+ DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
+ continue;
+ }
+
+ for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
+ Entry2 != &DiskEntry->PrimaryPartListHead;
+ Entry2 = Entry2->Flink)
{
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
- if (PartEntry->NeedsCheck == TRUE)
+ if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
{
ASSERT(DiskEntry == PartEntry->DiskEntry);
if (pDiskEntry) *pDiskEntry = DiskEntry;
*pPartEntry = PartEntry;
return TRUE;
}
-
- Entry2 = Entry2->Flink;
}
- Entry2 = DiskEntry->LogicalPartListHead.Flink;
- while (Entry2 != &DiskEntry->LogicalPartListHead)
+ for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
+ Entry2 != &DiskEntry->LogicalPartListHead;
+ Entry2 = Entry2->Flink)
{
PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
- if (PartEntry->NeedsCheck == TRUE)
+ if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
{
ASSERT(DiskEntry == PartEntry->DiskEntry);
if (pDiskEntry) *pDiskEntry = DiskEntry;
*pPartEntry = PartEntry;
return TRUE;
}
-
- Entry2 = Entry2->Flink;
}
-
- Entry1 = Entry1->Flink;
}
if (pDiskEntry) *pDiskEntry = NULL;