📄 partlist.c
字号:
PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize;
if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry)
{
/* Special case - previous partition is first partition */
PrevPartEntry->PartInfo[1].PartitionLength.QuadPart =
DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart;
}
else
{
PrevPartEntry->PartInfo[1].PartitionLength.QuadPart =
PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize;
}
if ((PartEntry->PartInfo[1].StartingOffset.QuadPart +
PartEntry->PartInfo[1].PartitionLength.QuadPart) <
(1024LL * 255LL * 63LL * 512LL))
{
PrevPartEntry->PartInfo[1].PartitionType = PARTITION_EXTENDED;
}
else
{
PrevPartEntry->PartInfo[1].PartitionType = PARTITION_XINT13_EXTENDED;
}
PrevPartEntry->PartInfo[1].BootIndicator = FALSE;
PrevPartEntry->PartInfo[1].RewritePartition = TRUE;
}
PartEntry->AutoCreate = AutoCreate;
PartEntry->New = TRUE;
PartEntry->Unpartitioned = FALSE;
PartEntry->UnpartitionedOffset = 0ULL;
PartEntry->UnpartitionedLength = 0ULL;
}
else
{
/* Insert an initialize a new partition entry */
NewPartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap,
0,
sizeof(PARTENTRY));
if (NewPartEntry == NULL)
return;
RtlZeroMemory (NewPartEntry,
sizeof(PARTENTRY));
/* Insert the new entry into the list */
InsertTailList (&PartEntry->ListEntry,
&NewPartEntry->ListEntry);
NewPartEntry->New = TRUE;
NewPartEntry->FormatState = Unformatted;
NewPartEntry->PartInfo[0].StartingOffset.QuadPart =
PartEntry->UnpartitionedOffset + DiskEntry->TrackSize;
NewPartEntry->PartInfo[0].PartitionLength.QuadPart =
PartitionSize - DiskEntry->TrackSize;
NewPartEntry->PartInfo[0].PartitionType = PARTITION_ENTRY_UNUSED;
NewPartEntry->PartInfo[0].BootIndicator = FALSE; /* FIXME */
NewPartEntry->PartInfo[0].RewritePartition = TRUE;
NewPartEntry->PartInfo[1].RewritePartition = TRUE;
NewPartEntry->PartInfo[2].RewritePartition = TRUE;
NewPartEntry->PartInfo[3].RewritePartition = TRUE;
/* Get previous and next partition entries */
PrevPartEntry = GetPrevPartitionedEntry (DiskEntry,
NewPartEntry);
NextPartEntry = GetNextPartitionedEntry (DiskEntry,
NewPartEntry);
if (PrevPartEntry != NULL && NextPartEntry != NULL)
{
/* Current entry is in the middle of the list */
/* Copy previous container partition data to current entry */
RtlCopyMemory (&NewPartEntry->PartInfo[1],
&PrevPartEntry->PartInfo[1],
sizeof(PARTITION_INFORMATION));
NewPartEntry->PartInfo[1].RewritePartition = TRUE;
/* Update previous container partition data */
PrevPartEntry->PartInfo[1].StartingOffset.QuadPart =
NewPartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize;
if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry)
{
/* Special case - previous partition is first partition */
PrevPartEntry->PartInfo[1].PartitionLength.QuadPart =
DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart;
}
else
{
PrevPartEntry->PartInfo[1].PartitionLength.QuadPart =
NewPartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize;
}
PrevPartEntry->PartInfo[1].RewritePartition = TRUE;
}
else if (PrevPartEntry == NULL && NextPartEntry != NULL)
{
/* Current entry is the first entry */
return;
}
else if (PrevPartEntry != NULL && NextPartEntry == NULL)
{
/* Current entry is the last entry */
PrevPartEntry->PartInfo[1].StartingOffset.QuadPart =
NewPartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize;
if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry)
{
/* Special case - previous partition is first partition */
PrevPartEntry->PartInfo[1].PartitionLength.QuadPart =
DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart;
}
else
{
PrevPartEntry->PartInfo[1].PartitionLength.QuadPart =
NewPartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize;
}
if ((PartEntry->PartInfo[1].StartingOffset.QuadPart +
PartEntry->PartInfo[1].PartitionLength.QuadPart) <
(1024LL * 255LL * 63LL * 512LL))
{
PrevPartEntry->PartInfo[1].PartitionType = PARTITION_EXTENDED;
}
else
{
PrevPartEntry->PartInfo[1].PartitionType = PARTITION_XINT13_EXTENDED;
}
PrevPartEntry->PartInfo[1].BootIndicator = FALSE;
PrevPartEntry->PartInfo[1].RewritePartition = TRUE;
}
/* Update offset and size of the remaining unpartitioned disk space */
PartEntry->UnpartitionedOffset += PartitionSize;
PartEntry->UnpartitionedLength -= PartitionSize;
}
DiskEntry->Modified = TRUE;
UpdatePartitionNumbers (DiskEntry);
AssignDriverLetters (List);
}
VOID
DeleteCurrentPartition (PPARTLIST List)
{
PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
PPARTENTRY PrevPartEntry;
PPARTENTRY NextPartEntry;
if (List == NULL ||
List->CurrentDisk == NULL ||
List->CurrentPartition == NULL ||
List->CurrentPartition->Unpartitioned == TRUE)
{
return;
}
DiskEntry = List->CurrentDisk;
PartEntry = List->CurrentPartition;
/* Adjust container partition entries */
/* Get previous and next partition entries */
PrevPartEntry = GetPrevPartitionedEntry (DiskEntry,
PartEntry);
NextPartEntry = GetNextPartitionedEntry (DiskEntry,
PartEntry);
if (PrevPartEntry != NULL && NextPartEntry != NULL)
{
/* Current entry is in the middle of the list */
/*
* The first extended partition can not be deleted
* as long as other extended partitions are present.
*/
if (PrevPartEntry->ListEntry.Blink == &DiskEntry->PartListHead)
return;
/* Copy previous container partition data to current entry */
RtlCopyMemory (&PrevPartEntry->PartInfo[1],
&PartEntry->PartInfo[1],
sizeof(PARTITION_INFORMATION));
PrevPartEntry->PartInfo[1].RewritePartition = TRUE;
}
else if (PrevPartEntry == NULL && NextPartEntry != NULL)
{
/*
* A primary partition can not be deleted as long as
* extended partitions are present.
*/
return;
}
else if (PrevPartEntry != NULL && NextPartEntry == NULL)
{
/* Current entry is the last entry */
RtlZeroMemory (&PrevPartEntry->PartInfo[1],
sizeof(PARTITION_INFORMATION));
PrevPartEntry->PartInfo[1].RewritePartition = TRUE;
}
/* Adjust unpartitioned disk space entries */
/* Get pointer to previous and next unpartitioned entries */
PrevPartEntry = GetPrevUnpartitionedEntry (DiskEntry,
PartEntry);
NextPartEntry = GetNextUnpartitionedEntry (DiskEntry,
PartEntry);
if (PrevPartEntry != NULL && NextPartEntry != NULL)
{
/* Merge previous, current and next unpartitioned entry */
/* Adjust the previous entries length */
PrevPartEntry->UnpartitionedLength +=
(PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize +
NextPartEntry->UnpartitionedLength);
/* Remove the current entry */
RemoveEntryList (&PartEntry->ListEntry);
RtlFreeHeap (ProcessHeap,
0,
PartEntry);
/* Remove the next entry */
RemoveEntryList (&NextPartEntry->ListEntry);
RtlFreeHeap (ProcessHeap,
0,
NextPartEntry);
/* Update current partition */
List->CurrentPartition = PrevPartEntry;
}
else if (PrevPartEntry != NULL && NextPartEntry == NULL)
{
/* Merge current and previous unpartitioned entry */
/* Adjust the previous entries length */
PrevPartEntry->UnpartitionedLength +=
(PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize);
/* Remove the current entry */
RemoveEntryList (&PartEntry->ListEntry);
RtlFreeHeap (ProcessHeap,
0,
PartEntry);
/* Update current partition */
List->CurrentPartition = PrevPartEntry;
}
else if (PrevPartEntry == NULL && NextPartEntry != NULL)
{
/* Merge current and next unpartitioned entry */
/* Adjust the next entries offset and length */
NextPartEntry->UnpartitionedOffset =
PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize;
NextPartEntry->UnpartitionedLength +=
(PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize);
/* Remove the current entry */
RemoveEntryList (&PartEntry->ListEntry);
RtlFreeHeap (ProcessHeap,
0,
PartEntry);
/* Update current partition */
List->CurrentPartition = NextPartEntry;
}
else
{
/* Nothing to merge but change current entry */
PartEntry->New = FALSE;
PartEntry->Unpartitioned = TRUE;
PartEntry->UnpartitionedOffset =
PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize;
PartEntry->UnpartitionedLength =
PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize;
/* Wipe the partition table */
RtlZeroMemory (&PartEntry->PartInfo,
sizeof(PartEntry->PartInfo));
}
DiskEntry->Modified = TRUE;
UpdatePartitionNumbers (DiskEntry);
AssignDriverLetters (List);
}
VOID
CheckActiveBootPartition (PPARTLIST List)
{
PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
/* Check for empty disk list */
if (IsListEmpty (&List->DiskListHead))
{
List->ActiveBootDisk = NULL;
List->ActiveBootPartition = NULL;
return;
}
#if 0
if (List->ActiveBootDisk != NULL &&
List->ActiveBootPartition != NULL)
{
/* We already have an active boot partition */
return;
}
#endif
DiskEntry = CONTAINING_RECORD (List->DiskListHead.Flink,
DISKENTRY,
ListEntry);
/* Check for empty partition list */
if (IsListEmpty (&DiskEntry->PartListHead))
{
List->ActiveBootDisk = NULL;
List->ActiveBootPartition = NULL;
return;
}
PartEntry = CONTAINING_RECORD (DiskEntry->PartListHead.Flink,
PARTENTRY,
ListEntry);
/* Set active boot partition */
if ((DiskEntry->NewDisk == TRUE) ||
(PartEntry->PartInfo[0].BootIndicator == FALSE &&
PartEntry->PartInfo[1].BootIndicator == FALSE &&
PartEntry->PartInfo[2].BootIndicator == FALSE &&
PartEntry->PartInfo[3].BootIndicator == FALSE))
{
PartEntry->PartInfo[0].BootIndicator = TRUE;
PartEntry->PartInfo[0].RewritePartition = TRUE;
DiskEntry->Modified = TRUE;
}
/* FIXME: Might be incorrect if partitions were created by Linux FDISK */
List->ActiveBootDisk = DiskEntry;
List->ActiveBootPartition = PartEntry;
}
BOOLEAN
CheckForLinuxFdiskPartitions (PPARTLIST List)
{
PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
PLIST_ENTRY Entry1;
PLIST_ENTRY Entry2;
ULONG PartitionCount;
ULONG i;
Entry1 = List->DiskListHead.Flink;
while (Entry1 != &List->DiskListHead)
{
DiskEntry = CONTAINING_RECORD (Entry1,
DISKENTRY,
ListEntry);
Entry2 = DiskEntry->PartListHead.Flink;
while (Entry2 != &DiskEntry->PartListHead)
{
PartEntry = CONTAINING_RECORD (Entry2,
PARTENTRY,
ListEntry);
if (PartEntry->Unpartitioned == FALSE)
{
PartitionCount = 0;
for (i = 0; i < 4; i++)
{
if (!IsContainerPartition (PartEntry->PartInfo[i].PartitionType) &&
PartEntry->PartInfo[i].PartitionLength.QuadPart != 0ULL)
{
PartitionCount++;
}
}
if (PartitionCount > 1)
{
return TRUE;
}
}
Entry2 = Entry2->Flink;
}
Entry1 = Entry1->Flink;
}
return FALSE;
}
BOOLEAN
WritePartitionsToDisk (PPARTLIST List)
{
PDRIVE_LAYOUT_INFORMATION DriveLayout;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK Iosb;
WCHAR SrcPath[MAX_PATH];
WCHAR DstPath[MAX_PATH];
UNICODE_STRING Name;
HANDLE FileHandle;
PDISKENTRY DiskEntry1;
PDISKENTRY DiskEntry2;
PPARTENTRY PartEntry;
PLIST_ENTRY Entry1;
PLIST_ENTRY Entry2;
ULONG PartitionCount;
ULONG DriveLayoutSize;
ULONG Index;
NTSTATUS Status;
if (List == NULL)
{
return TRUE;
}
Entry1 = List->DiskListHead.Flink;
while (Entry1 != &List->DiskListHead)
{
DiskEntry1 = CONTAINING_RECORD (Entry1,
DISKENTRY,
ListEntry);
if (DiskEntry1->Modified == TRUE)
{
/* Count partitioned entries */
PartitionCount = 0;
Entry2 = DiskEntry1->PartListHead.Flink;
while (Entry2 != &DiskEntry1->PartListHead)
{
PartEntry = CONTAINING_RECORD (Entry2,
PARTENTRY,
ListEntry);
if (PartEntry->Unpartitioned == FALSE)
{
PartitionCount += 4;
}
Entry2 = Entry2->Flink;
}
if (PartitionCount == 0)
{
DriveLayoutSize = sizeof (DRIVE_LAYOUT_INFORMATION) +
((4 - 1) * s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -