PPARTENTRY PartEntry;
PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
- if (PartitionInfo->PartitionType == 0)
+ if (PartitionInfo->PartitionType == 0 ||
+ (LogicalPartition == TRUE && IsContainerPartition(PartitionInfo->PartitionType)))
return;
PartEntry = RtlAllocateHeap(ProcessHeap,
}
}
+ if (DiskEntry->ExtendedPartition != NULL)
+ {
+ if (IsListEmpty(&DiskEntry->LogicalPartListHead))
+ {
+ DPRINT1("No logical partition!\n");
+
+ /* Create a partition table entry that represents the empty extended partition */
+ NewPartEntry = RtlAllocateHeap(ProcessHeap,
+ HEAP_ZERO_MEMORY,
+ sizeof(PARTENTRY));
+ if (NewPartEntry == NULL)
+ return;
+
+ NewPartEntry->DiskEntry = DiskEntry;
+ NewPartEntry->LogicalPartition = TRUE;
+
+ NewPartEntry->IsPartitioned = FALSE;
+ NewPartEntry->StartSector.QuadPart = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorsPerTrack;
+ NewPartEntry->SectorCount.QuadPart = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorsPerTrack;
+
+ DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
+ DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
+ DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
+
+ NewPartEntry->FormatState = Unformatted;
+
+ InsertTailList(&DiskEntry->LogicalPartListHead,
+ &NewPartEntry->ListEntry);
+
+ return;
+ }
+
+ /* Start partition at head 1, cylinder 0 */
+ LastStartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorsPerTrack;
+ LastSectorCount = 0ULL;
+ LastUnusedSectorCount = 0ULL;
+
+ Entry = DiskEntry->LogicalPartListHead.Flink;
+ while (Entry != &DiskEntry->LogicalPartListHead)
+ {
+ PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
+
+ if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
+ PartEntry->SectorCount.QuadPart != 0ULL)
+ {
+ LastUnusedSectorCount =
+ PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorsPerTrack - (LastStartSector + LastSectorCount);
+
+ if ((PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorsPerTrack) > (LastStartSector + LastSectorCount) &&
+ LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
+ {
+ DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
+
+ NewPartEntry = RtlAllocateHeap(ProcessHeap,
+ HEAP_ZERO_MEMORY,
+ sizeof(PARTENTRY));
+ if (NewPartEntry == NULL)
+ return;
+
+ NewPartEntry->DiskEntry = DiskEntry;
+ NewPartEntry->LogicalPartition = TRUE;
+
+ NewPartEntry->IsPartitioned = FALSE;
+ NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
+ NewPartEntry->SectorCount.QuadPart = Align(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
+ NewPartEntry->StartSector.QuadPart;
+DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
+DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
+DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
+
+ NewPartEntry->FormatState = Unformatted;
+
+ /* Insert the table into the list */
+ InsertTailList(&PartEntry->ListEntry,
+ &NewPartEntry->ListEntry);
+ }
+
+ LastStartSector = PartEntry->StartSector.QuadPart;
+ LastSectorCount = PartEntry->SectorCount.QuadPart;
+ }
+
+ Entry = Entry->Flink;
+ }
+
+ /* Check for trailing unpartitioned disk space */
+ if ((LastStartSector + LastSectorCount) < DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart)
+ {
+ LastUnusedSectorCount = Align(DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
+
+ if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
+ {
+ DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
+
+ NewPartEntry = RtlAllocateHeap(ProcessHeap,
+ HEAP_ZERO_MEMORY,
+ sizeof(PARTENTRY));
+ if (NewPartEntry == NULL)
+ return;
+
+ NewPartEntry->DiskEntry = DiskEntry;
+ NewPartEntry->LogicalPartition = TRUE;
+
+ NewPartEntry->IsPartitioned = FALSE;
+ NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
+ NewPartEntry->SectorCount.QuadPart = Align(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;
+
+ /* Append the table to the list */
+ InsertTailList(&DiskEntry->LogicalPartListHead,
+ &NewPartEntry->ListEntry);
+ }
+ }
+ }
+
DPRINT1("ScanForUnpartitionedDiskSpace() done\n");
}
DumpPartitionTable(DiskEntry);
#endif
+ if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
+ DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0 &&
+ DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionType != 0)
+ {
+ if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
+ {
+ DPRINT1("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
+ }
+ else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % 1048756 == 0)
+ {
+ DPRINT1("Use megabyte (%lu Sectors) alignment!\n", 1048756 / DiskEntry->BytesPerSector);
+ }
+ else
+ {
+ DPRINT1("No matching aligment found! Partiton 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
+ }
+ }
+ else
+ {
+ DPRINT1("No valid partiton table found! Use megabyte (%lu Sectors) alignment!\n", 1048756 / DiskEntry->BytesPerSector);
+ }
+
+
if (DiskEntry->LayoutBuffer->PartitionCount == 0)
{
DiskEntry->NewDisk = TRUE;
}
-VOID
+BOOL
ScrollDownPartitionList(
PPARTLIST List)
{
-// PDISKENTRY DiskEntry;
+ PLIST_ENTRY DiskListEntry;
+ PLIST_ENTRY PartListEntry;
+ PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
-// PLIST_ENTRY Entry1;
- PLIST_ENTRY Entry2;
- /* Check for empty disks */
+ /* Fail, if no disks are available */
if (IsListEmpty(&List->DiskListHead))
- return;
+ return FALSE;
/* Check for next usable entry on current disk */
if (List->CurrentPartition != NULL)
{
- Entry2 = List->CurrentPartition->ListEntry.Flink;
- if (Entry2 != &List->CurrentDisk->PrimaryPartListHead)
+ if (List->CurrentPartition->LogicalPartition)
{
- PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
+ /* Logical partition */
- List->CurrentPartition = PartEntry;
- DrawPartitionList(List);
- return;
- }
- }
+ PartListEntry = List->CurrentPartition->ListEntry.Flink;
+ if (PartListEntry != &List->CurrentDisk->LogicalPartListHead)
+ {
+ /* Next logical partition */
+ PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
-#if 0
- /* Check for first usable entry on next disk */
- if (List->CurrentDisk != NULL)
- {
- Entry1 = List->CurrentDisk->ListEntry.Flink;
- while (Entry1 != &List->DiskListHead)
+ List->CurrentPartition = PartEntry;
+ return TRUE;
+ }
+ else
+ {
+ PartListEntry = List->CurrentDisk->ExtendedPartition->ListEntry.Flink;
+ if (PartListEntry != &List->CurrentDisk->PrimaryPartListHead)
+ {
+ PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
+
+ List->CurrentPartition = PartEntry;
+ return TRUE;
+ }
+ }
+ }
+ else
{
- DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
+ /* Primary or extended partition */
- Entry2 = DiskEntry->PartListHead.Flink;
- if (Entry2 != &DiskEntry->PartListHead)
+ if (IsContainerPartition(List->CurrentPartition->PartitionType))
{
- PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
+ /* First logical partition */
+ PartListEntry = List->CurrentDisk->LogicalPartListHead.Flink;
+ if (PartListEntry != &List->CurrentDisk->LogicalPartListHead)
+ {
+ PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
- List->CurrentDisk = DiskEntry;
- List->CurrentPartition = PartEntry;
- DrawPartitionList(List);
- return;
+ List->CurrentPartition = PartEntry;
+ return TRUE;
+ }
+ }
+ else
+ {
+ /* Next primary partition */
+ PartListEntry = List->CurrentPartition->ListEntry.Flink;
+ if (PartListEntry != &List->CurrentDisk->PrimaryPartListHead)
+ {
+ PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
+
+ List->CurrentPartition = PartEntry;
+ return TRUE;
+ }
}
+ }
+ }
+
+ /* Search for the first partition entry on the next disk */
+ DiskListEntry = List->CurrentDisk->ListEntry.Flink;
+ while (DiskListEntry != &List->DiskListHead)
+ {
+ DiskEntry = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
+
+ PartListEntry = DiskEntry->PrimaryPartListHead.Flink;
+ if (PartListEntry != &DiskEntry->PrimaryPartListHead)
+ {
+ PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
- Entry1 = Entry1->Flink;
+ List->CurrentDisk = DiskEntry;
+ List->CurrentPartition = PartEntry;
+ return TRUE;
}
+
+ DiskListEntry = DiskListEntry->Flink;
}
-#endif
+
+ return FALSE;
}
-VOID
+BOOL
ScrollUpPartitionList(
PPARTLIST List)
{
-// PDISKENTRY DiskEntry;
+ PLIST_ENTRY DiskListEntry;
+ PLIST_ENTRY PartListEntry;
+ PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
-// PLIST_ENTRY Entry1;
- PLIST_ENTRY Entry2;
- /* Check for empty disks */
+ /* Fail, if no disks are available */
if (IsListEmpty(&List->DiskListHead))
- return;
+ return FALSE;
- /* check for previous usable entry on current disk */
+ /* Check for previous usable entry on current disk */
if (List->CurrentPartition != NULL)
{
- Entry2 = List->CurrentPartition->ListEntry.Blink;
- if (Entry2 != &List->CurrentDisk->PrimaryPartListHead)
+ if (List->CurrentPartition->LogicalPartition)
{
- PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
+ /* Logical partition */
+ PartListEntry = List->CurrentPartition->ListEntry.Blink;
+ if (PartListEntry != &List->CurrentDisk->LogicalPartListHead)
+ {
+ /* Previous logical partition */
+ PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
+ }
+ else
+ {
+ /* Extended partition*/
+ PartEntry = List->CurrentDisk->ExtendedPartition;
+ }
List->CurrentPartition = PartEntry;
+ return TRUE;
+ }
+ else
+ {
+ /* Primary or extended partition */
+
+ PartListEntry = List->CurrentPartition->ListEntry.Blink;
+ if (PartListEntry != &List->CurrentDisk->PrimaryPartListHead)
+ {
+ PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
+
+ if (IsContainerPartition(PartEntry->PartitionType))
+ {
+ PartListEntry = List->CurrentDisk->LogicalPartListHead.Blink;
+ PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
+ }
+
+ List->CurrentPartition = PartEntry;
+ return TRUE;
+ }
- /* Draw partition list and return */
- DrawPartitionList(List);
- return;
}
}
-#if 0
- /* check for last usable entry on previous disk */
- if (List->CurrentDisk != NULL)
+ /* Search for the last partition entry on the previous disk */
+ DiskListEntry = List->CurrentDisk->ListEntry.Blink;
+ while (DiskListEntry != &List->DiskListHead)
{
- Entry1 = List->CurrentDisk->ListEntry.Blink;
- while (Entry1 != &List->DiskListHead)
+ DiskEntry = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
+
+ PartListEntry = DiskEntry->PrimaryPartListHead.Blink;
+ if (PartListEntry != &DiskEntry->PrimaryPartListHead)
{
- DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
+ PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
- Entry2 = DiskEntry->PrimaryPartListHead.Blink;
- if (Entry2 != &DiskEntry->PrimaryPartListHead)
+ if (IsContainerPartition(PartEntry->PartitionType))
{
- PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
+ PartListEntry = DiskEntry->LogicalPartListHead.Blink;
+ if (PartListEntry != &DiskEntry->LogicalPartListHead)
+ {
+ PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
+ List->CurrentDisk = DiskEntry;
+ List->CurrentPartition = PartEntry;
+ return TRUE;
+ }
+ }
+ else
+ {
List->CurrentDisk = DiskEntry;
List->CurrentPartition = PartEntry;
-
- /* Draw partition list and return */
- DrawPartitionList(List);
- return;
+ return TRUE;
}
-
- Entry1 = Entry1->Blink;
}
+
+ DiskListEntry = DiskListEntry->Blink;
}
-#endif
+
+ return FALSE;
}
}
+VOID
+CreateLogicalPartition(
+ PPARTLIST List,
+ ULONGLONG SectorCount)
+{
+// PDISKENTRY DiskEntry;
+ PPARTENTRY PartEntry;
+// PPARTENTRY NewPartEntry;
+
+ DPRINT1("CreateLogicalPartition(%I64u)\n", SectorCount);
+
+ if (List == NULL ||
+ List->CurrentDisk == NULL ||
+ List->CurrentPartition == NULL ||
+ List->CurrentPartition->IsPartitioned == TRUE)
+ {
+ return;
+ }
+
+// DiskEntry = List->CurrentDisk;
+ PartEntry = List->CurrentPartition;
+
+ DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart);
+}
+
+
VOID
DeleteCurrentPartition(
PPARTLIST List)
return ERROR_SUCCESS;
}
+
+ULONG
+LogicalPartitionCreationChecks(
+ IN PPARTLIST List)
+{
+// PDISKENTRY DiskEntry;
+ PPARTENTRY PartEntry;
+
+// DiskEntry = List->CurrentDisk;
+ PartEntry = List->CurrentPartition;
+
+ /* Fail if partition is already in use */
+ if (PartEntry->IsPartitioned == TRUE)
+ return ERROR_NEW_PARTITION;
+
+ return ERROR_SUCCESS;
+}
+
/* EOF */