[DISKPART] Implement creation and deletion of GPT partitions

- Implement creation and deletion of GPT partitions.
- Adjust the active, clean, detail, inactive, list, select, setid and uniqueid
  commands as needed.
- Add a 2^32 sector count limit for MBR partition tables.
This commit is contained in:
Eric Kohl
2025-12-13 18:42:00 +01:00
parent 1a173646d6
commit f206063280
29 changed files with 1524 additions and 450 deletions
+1
View File
@@ -24,6 +24,7 @@ list(APPEND SOURCE
filesystems.c
format.c
gpt.c
guid.c
help.c
import.c
inactive.c
+4 -4
View File
@@ -35,16 +35,16 @@ active_main(
if (CurrentDisk->PartitionStyle == PARTITION_STYLE_MBR)
{
if (CurrentPartition->BootIndicator)
if (CurrentPartition->Mbr.BootIndicator)
{
ConResPuts(StdOut, IDS_ACTIVE_ALREADY);
return TRUE;
}
CurrentPartition->BootIndicator = TRUE;
CurrentPartition->Mbr.BootIndicator = TRUE;
CurrentDisk->Dirty = TRUE;
UpdateDiskLayout(CurrentDisk);
Status = WritePartitions(CurrentDisk);
UpdateMbrDiskLayout(CurrentDisk);
Status = WriteMbrPartitions(CurrentDisk);
if (NT_SUCCESS(Status))
{
ConResPuts(StdOut, IDS_ACTIVE_SUCCESS);
+3 -3
View File
@@ -63,7 +63,7 @@ clean_main(
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
/* Dismount the logical partition */
if (PartEntry->PartitionType != 0)
if (PartEntry->Mbr.PartitionType != 0)
{
DismountVolume(PartEntry);
VolumeEntry = GetVolumeFromPartition(PartEntry);
@@ -82,8 +82,8 @@ clean_main(
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
/* Dismount the primary partition */
if ((PartEntry->PartitionType != 0) &&
(IsContainerPartition(PartEntry->PartitionType) == FALSE))
if ((PartEntry->Mbr.PartitionType != 0) &&
(IsContainerPartition(PartEntry->Mbr.PartitionType) == FALSE))
{
DismountVolume(PartEntry);
VolumeEntry = GetVolumeFromPartition(PartEntry);
+27 -25
View File
@@ -23,7 +23,7 @@ CreateDisk(
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
DPRINT1("CreateDisk(%lu %p)\n", DiskNumber, DiskInfo);
DPRINT("CreateDisk(%lu %p)\n", DiskNumber, DiskInfo);
StringCchPrintfW(DstPath, ARRAYSIZE(DstPath),
L"\\Device\\Harddisk%lu\\Partition0",
@@ -64,24 +64,18 @@ CreateDisk(
goto done;
}
CurrentDisk->PartitionStyle = DiskInfo->PartitionStyle;
/* Free the layout buffer */
if (CurrentDisk->LayoutBuffer)
{
RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentDisk->LayoutBuffer);
CurrentDisk->LayoutBuffer = NULL;
CurrentDisk->ExtendedPartition = NULL;
}
CurrentDisk->LayoutBuffer = NULL;
CurrentDisk->ExtendedPartition = NULL;
CurrentDisk->Dirty = FALSE;
CurrentDisk->NewDisk = TRUE;
CurrentDisk->PartitionStyle = DiskInfo->PartitionStyle;
ReadLayoutBuffer(FileHandle, CurrentDisk);
DPRINT1("PartitionCount: %lu\n", CurrentDisk->LayoutBuffer->PartitionCount);
#ifdef DUMP_PARTITION_TABLE
DumpPartitionTable(CurrentDisk);
#endif
done:
if (FileHandle)
NtClose(FileHandle);
@@ -112,7 +106,7 @@ ConvertGPT(
return TRUE;
}
if (CurrentDisk->LayoutBuffer->PartitionCount != 0)
if (GetPrimaryPartitionCount(CurrentDisk) != 0)
{
ConResPuts(StdOut, IDS_CONVERT_GPT_NOT_EMPTY);
return TRUE;
@@ -134,12 +128,17 @@ ConvertGPT(
Status = CreateDisk(CurrentDisk->DiskNumber, &DiskInfo);
if (!NT_SUCCESS(Status))
{
DPRINT1("CreateDisk() failed!\n");
return TRUE;
}
}
else
{
ConResPuts(StdOut, IDS_CONVERT_GPT_SUCCESS);
}
CurrentDisk->StartSector.QuadPart = AlignDown(CurrentDisk->LayoutBuffer->Gpt.StartingUsableOffset.QuadPart / CurrentDisk->BytesPerSector,
CurrentDisk->SectorAlignment) + (ULONGLONG)CurrentDisk->SectorAlignment;
CurrentDisk->EndSector.QuadPart = AlignDown(CurrentDisk->StartSector.QuadPart + (CurrentDisk->LayoutBuffer->Gpt.UsableLength.QuadPart / CurrentDisk->BytesPerSector) - 1,
CurrentDisk->SectorAlignment);
ScanForUnpartitionedGptDiskSpace(CurrentDisk);
ConResPuts(StdOut, IDS_CONVERT_GPT_SUCCESS);
return TRUE;
}
@@ -168,7 +167,7 @@ ConvertMBR(
return TRUE;
}
if (CurrentDisk->LayoutBuffer->PartitionCount != 0)
if (GetPrimaryPartitionCount(CurrentDisk) != 0)
{
ConResPuts(StdOut, IDS_CONVERT_MBR_NOT_EMPTY);
return TRUE;
@@ -180,12 +179,15 @@ ConvertMBR(
Status = CreateDisk(CurrentDisk->DiskNumber, &DiskInfo);
if (!NT_SUCCESS(Status))
{
DPRINT1("CreateDisk() failed!\n");
return TRUE;
}
}
else
{
ConResPuts(StdOut, IDS_CONVERT_MBR_SUCCESS);
}
CurrentDisk->StartSector.QuadPart = (ULONGLONG)CurrentDisk->SectorAlignment;
CurrentDisk->EndSector.QuadPart = min(CurrentDisk->SectorCount.QuadPart, 0x100000000) - 1;
ScanForUnpartitionedMbrDiskSpace(CurrentDisk);
ConResPuts(StdOut, IDS_CONVERT_MBR_SUCCESS);
return TRUE;
}
+316 -138
View File
@@ -42,8 +42,23 @@ CreateExtendedPartition(
}
else if (CurrentDisk->PartitionStyle == PARTITION_STYLE_RAW)
{
/* FIXME: Initialize disk properly! */
CurrentDisk->PartitionStyle = PARTITION_STYLE_MBR;
CREATE_DISK DiskInfo;
NTSTATUS Status;
DiskInfo.PartitionStyle = PARTITION_STYLE_MBR;
CreateSignature(&DiskInfo.Mbr.Signature);
Status = CreateDisk(CurrentDisk->DiskNumber, &DiskInfo);
if (!NT_SUCCESS(Status))
{
DPRINT1("CreateDisk() failed!\n");
return TRUE;
}
CurrentDisk->StartSector.QuadPart = (ULONGLONG)CurrentDisk->SectorAlignment;
CurrentDisk->EndSector.QuadPart = min(CurrentDisk->SectorCount.QuadPart, 0x100000000) - 1;
ScanForUnpartitionedMbrDiskSpace(CurrentDisk);
}
for (i = 3; i < argc; i++)
@@ -136,7 +151,7 @@ CreateExtendedPartition(
{
PartEntry->IsPartitioned = TRUE;
PartEntry->New = TRUE;
PartEntry->PartitionType = PARTITION_EXTENDED;
PartEntry->Mbr.PartitionType = PARTITION_EXTENDED;
PartEntry->FormatState = Unformatted;
PartEntry->FileSystemName[0] = L'\0';
@@ -149,7 +164,7 @@ CreateExtendedPartition(
{
PartEntry->IsPartitioned = TRUE;
PartEntry->New = TRUE;
PartEntry->PartitionType = PARTITION_EXTENDED;
PartEntry->Mbr.PartitionType = PARTITION_EXTENDED;
PartEntry->FormatState = Unformatted;
PartEntry->FileSystemName[0] = L'\0';
@@ -173,7 +188,7 @@ CreateExtendedPartition(
NewPartEntry->LogicalPartition = FALSE;
NewPartEntry->IsPartitioned = TRUE;
NewPartEntry->New = TRUE;
NewPartEntry->PartitionType = PARTITION_EXTENDED;
NewPartEntry->Mbr.PartitionType = PARTITION_EXTENDED;
NewPartEntry->FormatState = Unformatted;
NewPartEntry->FileSystemName[0] = L'\0';
@@ -187,8 +202,8 @@ CreateExtendedPartition(
}
}
UpdateDiskLayout(CurrentDisk);
Status = WritePartitions(CurrentDisk);
UpdateMbrDiskLayout(CurrentDisk);
Status = WriteMbrPartitions(CurrentDisk);
if (!NT_SUCCESS(Status))
{
ConResPuts(StdOut, IDS_CREATE_PARTITION_FAIL);
@@ -226,7 +241,7 @@ CreateLogicalPartition(
return TRUE;
}
if (CurrentDisk->PartitionStyle == PARTITION_STYLE_GPT)
if (CurrentDisk->PartitionStyle != PARTITION_STYLE_MBR)
{
ConResPuts(StdOut, IDS_CREATE_PARTITION_INVALID_STYLE);
return TRUE;
@@ -332,7 +347,7 @@ CreateLogicalPartition(
{
PartEntry->IsPartitioned = TRUE;
PartEntry->New = TRUE;
PartEntry->PartitionType = PartitionType;
PartEntry->Mbr.PartitionType = PartitionType;
PartEntry->FormatState = Unformatted;
PartEntry->FileSystemName[0] = L'\0';
@@ -346,7 +361,7 @@ CreateLogicalPartition(
{
PartEntry->IsPartitioned = TRUE;
PartEntry->New = TRUE;
PartEntry->PartitionType = PartitionType;
PartEntry->Mbr.PartitionType = PartitionType;
PartEntry->FormatState = Unformatted;
PartEntry->FileSystemName[0] = L'\0';
@@ -371,7 +386,7 @@ CreateLogicalPartition(
NewPartEntry->LogicalPartition = TRUE;
NewPartEntry->IsPartitioned = TRUE;
NewPartEntry->New = TRUE;
NewPartEntry->PartitionType = PartitionType;
NewPartEntry->Mbr.PartitionType = PartitionType;
NewPartEntry->FormatState = Unformatted;
NewPartEntry->FileSystemName[0] = L'\0';
@@ -387,8 +402,8 @@ CreateLogicalPartition(
}
}
UpdateDiskLayout(CurrentDisk);
Status = WritePartitions(CurrentDisk);
UpdateMbrDiskLayout(CurrentDisk);
Status = WriteMbrPartitions(CurrentDisk);
if (!NT_SUCCESS(Status))
{
ConResPuts(StdOut, IDS_CREATE_PARTITION_FAIL);
@@ -402,23 +417,280 @@ CreateLogicalPartition(
}
static
VOID
CreatePrimaryMbrPartition(
_In_ ULONGLONG ullSize,
_In_ PWSTR pszPartitionType)
{
PPARTENTRY PartEntry, NewPartEntry;
PLIST_ENTRY ListEntry;
ULONGLONG ullSectorCount;
UCHAR PartitionType;
INT length;
NTSTATUS Status;
if (pszPartitionType)
{
length = wcslen(pszPartitionType);
if ((length != 1) && (length != 2))
{
ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
return;
}
PartitionType = (UCHAR)wcstoul(pszPartitionType, NULL, 16);
if ((PartitionType == 0) && (errno == ERANGE))
{
ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
return;
}
}
else
{
PartitionType = PARTITION_HUGE;
}
if (GetPrimaryPartitionCount(CurrentDisk) >= 4)
{
ConPuts(StdOut, L"No space left for another primary partition!\n");
return;
}
if (ullSize != 0)
ullSectorCount = (ullSize * 1024 * 1024) / CurrentDisk->BytesPerSector;
else
ullSectorCount = 0;
DPRINT1("SectorCount: %I64u\n", ullSectorCount);
for (ListEntry = CurrentDisk->PrimaryPartListHead.Flink;
ListEntry != &CurrentDisk->PrimaryPartListHead;
ListEntry = ListEntry->Flink)
{
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned)
continue;
if (ullSectorCount == 0)
{
PartEntry->IsPartitioned = TRUE;
PartEntry->New = TRUE;
PartEntry->Mbr.PartitionType = PartitionType;
PartEntry->FormatState = Unformatted;
PartEntry->FileSystemName[0] = L'\0';
CurrentPartition = PartEntry;
CurrentDisk->Dirty = TRUE;
break;
}
else
{
if (PartEntry->SectorCount.QuadPart == ullSectorCount)
{
PartEntry->IsPartitioned = TRUE;
PartEntry->New = TRUE;
PartEntry->Mbr.PartitionType = PartitionType;
PartEntry->FormatState = Unformatted;
PartEntry->FileSystemName[0] = L'\0';
CurrentPartition = PartEntry;
CurrentDisk->Dirty = TRUE;
break;
}
else if (PartEntry->SectorCount.QuadPart > ullSectorCount)
{
NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PPARTENTRY));
if (NewPartEntry == NULL)
{
ConPuts(StdOut, L"Memory allocation failed!\n");
return;
}
NewPartEntry->DiskEntry = PartEntry->DiskEntry;
NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
NewPartEntry->SectorCount.QuadPart = ullSectorCount;
NewPartEntry->LogicalPartition = FALSE;
NewPartEntry->IsPartitioned = TRUE;
NewPartEntry->New = TRUE;
NewPartEntry->Mbr.PartitionType = PartitionType;
NewPartEntry->FormatState = Unformatted;
NewPartEntry->FileSystemName[0] = L'\0';
PartEntry->StartSector.QuadPart += ullSectorCount;
PartEntry->SectorCount.QuadPart -= ullSectorCount;
InsertTailList(ListEntry, &NewPartEntry->ListEntry);
CurrentPartition = NewPartEntry;
CurrentDisk->Dirty = TRUE;
break;
}
}
}
UpdateMbrDiskLayout(CurrentDisk);
Status = WriteMbrPartitions(CurrentDisk);
if (!NT_SUCCESS(Status))
{
ConResPuts(StdOut, IDS_CREATE_PARTITION_FAIL);
CurrentPartition = NULL;
return;
}
ConResPuts(StdOut, IDS_CREATE_PARTITION_SUCCESS);
}
static
VOID
CreatePrimaryGptPartition(
_In_ ULONGLONG ullSize,
_In_ PWSTR pszPartitionType)
{
PPARTENTRY PartEntry, NewPartEntry;
PLIST_ENTRY ListEntry;
ULONGLONG ullSectorCount;
GUID guidPartitionType;
NTSTATUS Status;
/* Partition Type */
if (pszPartitionType)
{
if (!StringToGUID(&guidPartitionType, pszPartitionType))
{
ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
return;
}
}
else
{
CopyMemory(&guidPartitionType, &PARTITION_BASIC_DATA_GUID, sizeof(GUID));
}
/* Size */
if (ullSize != 0)
ullSectorCount = (ullSize * 1024 * 1024) / CurrentDisk->BytesPerSector;
else
ullSectorCount = 0;
DPRINT1("SectorCount: %I64u\n", ullSectorCount);
#ifdef DUMP_PARTITION_LIST
DumpPartitionList(CurrentDisk);
#endif
for (ListEntry = CurrentDisk->PrimaryPartListHead.Flink;
ListEntry != &CurrentDisk->PrimaryPartListHead;
ListEntry = ListEntry->Flink)
{
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned)
continue;
if (ullSectorCount == 0)
{
DPRINT("Claim whole unused space!\n");
PartEntry->IsPartitioned = TRUE;
PartEntry->New = TRUE;
CopyMemory(&PartEntry->Gpt.PartitionType, &guidPartitionType, sizeof(GUID));
CreateGUID(&PartEntry->Gpt.PartitionId);
PartEntry->Gpt.Attributes = 0ULL;
PartEntry->PartitionNumber = 0;
PartEntry->FormatState = Unformatted;
PartEntry->FileSystemName[0] = L'\0';
CurrentPartition = PartEntry;
CurrentDisk->Dirty = TRUE;
break;
}
else
{
if (ullSectorCount == PartEntry->SectorCount.QuadPart)
{
DPRINT("Claim matching unused space!\n");
PartEntry->IsPartitioned = TRUE;
PartEntry->New = TRUE;
CopyMemory(&PartEntry->Gpt.PartitionType, &guidPartitionType, sizeof(GUID));
CreateGUID(&PartEntry->Gpt.PartitionId);
PartEntry->Gpt.Attributes = 0ULL;
PartEntry->PartitionNumber = 0;
PartEntry->FormatState = Unformatted;
PartEntry->FileSystemName[0] = L'\0';
CurrentPartition = PartEntry;
CurrentDisk->Dirty = TRUE;
break;
}
else if (ullSectorCount < PartEntry->SectorCount.QuadPart)
{
DPRINT("Claim part of unused space\n");
NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PPARTENTRY));
if (NewPartEntry == NULL)
{
ConPuts(StdOut, L"Memory allocation failed!\n");
return;
}
NewPartEntry->DiskEntry = PartEntry->DiskEntry;
NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
NewPartEntry->SectorCount.QuadPart = ullSectorCount;
NewPartEntry->LogicalPartition = FALSE;
NewPartEntry->IsPartitioned = TRUE;
NewPartEntry->New = TRUE;
CopyMemory(&NewPartEntry->Gpt.PartitionType, &guidPartitionType, sizeof(GUID));
CreateGUID(&NewPartEntry->Gpt.PartitionId);
NewPartEntry->Gpt.Attributes = 0ULL;
NewPartEntry->PartitionNumber = 0;
NewPartEntry->FormatState = Unformatted;
NewPartEntry->FileSystemName[0] = L'\0';
PartEntry->StartSector.QuadPart += ullSectorCount;
PartEntry->SectorCount.QuadPart -= ullSectorCount;
InsertTailList(ListEntry, &NewPartEntry->ListEntry);
CurrentPartition = NewPartEntry;
CurrentDisk->Dirty = TRUE;
break;
}
}
}
#ifdef DUMP_PARTITION_LIST
DumpPartitionList(CurrentDisk);
#endif
UpdateGptDiskLayout(CurrentDisk, FALSE);
Status = WriteGptPartitions(CurrentDisk);
if (!NT_SUCCESS(Status))
{
ConResPuts(StdOut, IDS_CREATE_PARTITION_FAIL);
CurrentPartition = NULL;
return;
}
ConResPuts(StdOut, IDS_CREATE_PARTITION_SUCCESS);
}
BOOL
CreatePrimaryPartition(
_In_ INT argc,
_In_ PWSTR *argv)
{
PPARTENTRY PartEntry, NewPartEntry;
PLIST_ENTRY ListEntry;
ULONGLONG ullSize = 0ULL;
ULONGLONG ullSectorCount;
#if 0
ULONGLONG ullOffset = 0ULL;
BOOL bNoErr = FALSE;
#endif
UCHAR PartitionType = PARTITION_HUGE;
INT i, length;
INT i;
PWSTR pszSuffix = NULL;
NTSTATUS Status;
PWSTR pszPartitionType = NULL;
if (CurrentDisk == NULL)
{
@@ -426,15 +698,25 @@ CreatePrimaryPartition(
return TRUE;
}
if (CurrentDisk->PartitionStyle == PARTITION_STYLE_GPT)
if (CurrentDisk->PartitionStyle == PARTITION_STYLE_RAW)
{
ConPuts(StdOut, L"GPT Partitions are not supported yet!\n");
return TRUE;
}
else if (CurrentDisk->PartitionStyle == PARTITION_STYLE_RAW)
{
/* FIXME: Initialize disk properly! */
CurrentDisk->PartitionStyle = PARTITION_STYLE_MBR;
CREATE_DISK DiskInfo;
NTSTATUS Status;
DiskInfo.PartitionStyle = PARTITION_STYLE_MBR;
CreateSignature(&DiskInfo.Mbr.Signature);
Status = CreateDisk(CurrentDisk->DiskNumber, &DiskInfo);
if (!NT_SUCCESS(Status))
{
DPRINT1("CreateDisk() failed!\n");
return TRUE;
}
CurrentDisk->StartSector.QuadPart = (ULONGLONG)CurrentDisk->SectorAlignment;
CurrentDisk->EndSector.QuadPart = min(CurrentDisk->SectorCount.QuadPart, 0x100000000) - 1;
ScanForUnpartitionedMbrDiskSpace(CurrentDisk);
}
for (i = 3; i < argc; i++)
@@ -469,29 +751,7 @@ CreatePrimaryPartition(
{
/* id=<Byte>|<GUID> */
DPRINT("Id : %s\n", pszSuffix);
length = wcslen(pszSuffix);
if ((length == 1) || (length == 2))
{
/* Byte */
PartitionType = (UCHAR)wcstoul(pszSuffix, NULL, 16);
if ((PartitionType == 0) && (errno == ERANGE))
{
ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
return TRUE;
}
}
#if 0
else if ()
{
/* GUID */
}
#endif
else
{
ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
return TRUE;
}
pszPartitionType = pszSuffix;
}
else if (HasPrefix(argv[i], L"align=", &pszSuffix))
{
@@ -518,102 +778,20 @@ CreatePrimaryPartition(
}
}
DPRINT1("Size: %I64u\n", ullSize);
DPRINT("Size: %I64u\n", ullSize);
#if 0
DPRINT1("Offset: %I64u\n", ullOffset);
#endif
DPRINT1("Partition Type: %hx\n", PartitionType);
if (GetPrimaryPartitionCount(CurrentDisk) >= 4)
if (CurrentDisk->PartitionStyle == PARTITION_STYLE_MBR)
{
ConPuts(StdOut, L"No space left for another primary partition!\n");
return TRUE;
DPRINT("Partition Type: %s\n", pszPartitionType);
CreatePrimaryMbrPartition(ullSize, pszPartitionType);
}
if (ullSize != 0)
ullSectorCount = (ullSize * 1024 * 1024) / CurrentDisk->BytesPerSector;
else
ullSectorCount = 0;
DPRINT1("SectorCount: %I64u\n", ullSectorCount);
for (ListEntry = CurrentDisk->PrimaryPartListHead.Flink;
ListEntry != &CurrentDisk->PrimaryPartListHead;
ListEntry = ListEntry->Flink)
else if (CurrentDisk->PartitionStyle == PARTITION_STYLE_GPT)
{
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
if (PartEntry->IsPartitioned)
continue;
if (ullSectorCount == 0)
{
PartEntry->IsPartitioned = TRUE;
PartEntry->New = TRUE;
PartEntry->PartitionType = PartitionType;
PartEntry->FormatState = Unformatted;
PartEntry->FileSystemName[0] = L'\0';
CurrentPartition = PartEntry;
CurrentDisk->Dirty = TRUE;
break;
}
else
{
if (PartEntry->SectorCount.QuadPart == ullSectorCount)
{
PartEntry->IsPartitioned = TRUE;
PartEntry->New = TRUE;
PartEntry->PartitionType = PartitionType;
PartEntry->FormatState = Unformatted;
PartEntry->FileSystemName[0] = L'\0';
CurrentPartition = PartEntry;
CurrentDisk->Dirty = TRUE;
break;
}
else if (PartEntry->SectorCount.QuadPart > ullSectorCount)
{
NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PPARTENTRY));
if (NewPartEntry == NULL)
{
ConPuts(StdOut, L"Memory allocation failed!\n");
return TRUE;
}
NewPartEntry->DiskEntry = PartEntry->DiskEntry;
NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
NewPartEntry->SectorCount.QuadPart = ullSectorCount;
NewPartEntry->LogicalPartition = FALSE;
NewPartEntry->IsPartitioned = TRUE;
NewPartEntry->New = TRUE;
NewPartEntry->PartitionType = PartitionType;
NewPartEntry->FormatState = Unformatted;
NewPartEntry->FileSystemName[0] = L'\0';
PartEntry->StartSector.QuadPart += ullSectorCount;
PartEntry->SectorCount.QuadPart -= ullSectorCount;
InsertTailList(ListEntry, &NewPartEntry->ListEntry);
CurrentPartition = NewPartEntry;
CurrentDisk->Dirty = TRUE;
break;
}
}
CreatePrimaryGptPartition(ullSize, pszPartitionType);
}
UpdateDiskLayout(CurrentDisk);
Status = WritePartitions(CurrentDisk);
if (!NT_SUCCESS(Status))
{
ConResPuts(StdOut, IDS_CREATE_PARTITION_FAIL);
CurrentPartition = NULL;
return TRUE;
}
ConResPuts(StdOut, IDS_CREATE_PARTITION_SUCCESS);
return TRUE;
}
+183 -54
View File
@@ -16,8 +16,8 @@ BOOL
IsKnownPartition(
_In_ PPARTENTRY PartEntry)
{
if (IsRecognizedPartition(PartEntry->PartitionType) ||
IsContainerPartition(PartEntry->PartitionType))
if (IsRecognizedPartition(PartEntry->Mbr.PartitionType) ||
IsContainerPartition(PartEntry->Mbr.PartitionType))
return TRUE;
return FALSE;
@@ -33,59 +33,18 @@ DeleteDisk(
}
BOOL
DeletePartition(
_In_ INT argc,
_In_ PWSTR *argv)
static
VOID
DeleteMbrPartition(
_In_ BOOL bOverride)
{
PPARTENTRY PrevPartEntry;
PPARTENTRY NextPartEntry;
PPARTENTRY LogicalPartEntry;
PLIST_ENTRY Entry;
INT i;
BOOL bOverride = FALSE;
NTSTATUS Status;
DPRINT("DeletePartition()\n");
if (CurrentDisk == NULL)
{
ConResPuts(StdOut, IDS_SELECT_NO_DISK);
return TRUE;
}
if (CurrentPartition == NULL)
{
ConResPuts(StdOut, IDS_SELECT_NO_PARTITION);
return TRUE;
}
ASSERT(CurrentPartition->PartitionType != PARTITION_ENTRY_UNUSED);
for (i = 2; i < argc; i++)
{
if (_wcsicmp(argv[i], L"noerr") == 0)
{
/* noerr */
DPRINT("NOERR\n");
ConPuts(StdOut, L"The NOERR option is not supported yet!\n");
#if 0
bNoErr = TRUE;
#endif
}
else if (_wcsicmp(argv[i], L"override") == 0)
{
/* override */
DPRINT("OVERRIDE\n");
bOverride = TRUE;
}
else
{
ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
return TRUE;
}
}
ASSERT(CurrentPartition->Mbr.PartitionType != PARTITION_ENTRY_UNUSED);
/* Clear the system partition if it is being deleted */
#if 0
@@ -99,7 +58,7 @@ DeletePartition(
if ((bOverride == FALSE) && (IsKnownPartition(CurrentPartition) == FALSE))
{
ConResPuts(StdOut, IDS_DELETE_PARTITION_FAIL);
return FALSE;
return;
}
/* Check which type of partition (primary/logical or extended) is being deleted */
@@ -175,8 +134,8 @@ DeletePartition(
CurrentPartition->OnDiskPartitionNumber = 0;
CurrentPartition->PartitionNumber = 0;
// CurrentPartition->PartitionIndex = 0;
CurrentPartition->BootIndicator = FALSE;
CurrentPartition->PartitionType = PARTITION_ENTRY_UNUSED;
CurrentPartition->Mbr.BootIndicator = FALSE;
CurrentPartition->Mbr.PartitionType = PARTITION_ENTRY_UNUSED;
CurrentPartition->FormatState = Unformatted;
CurrentPartition->FileSystemName[0] = L'\0';
CurrentPartition->DriveLetter = 0;
@@ -185,15 +144,185 @@ DeletePartition(
CurrentPartition = NULL;
UpdateDiskLayout(CurrentDisk);
Status = WritePartitions(CurrentDisk);
UpdateMbrDiskLayout(CurrentDisk);
Status = WriteMbrPartitions(CurrentDisk);
if (!NT_SUCCESS(Status))
{
ConResPuts(StdOut, IDS_DELETE_PARTITION_FAIL);
return TRUE;
return;
}
ConResPuts(StdOut, IDS_DELETE_PARTITION_SUCCESS);
}
static
VOID
DeleteGptPartition(
_In_ BOOL bOverride)
{
PPARTENTRY PrevPartEntry;
PPARTENTRY NextPartEntry;
NTSTATUS Status;
/* Clear the system partition if it is being deleted */
#if 0
if (List->SystemPartition == PartEntry)
{
ASSERT(List->SystemPartition);
List->SystemPartition = NULL;
}
#endif
#if 0
if ((bOverride == FALSE) && (IsKnownPartition(CurrentPartition) == FALSE))
{
ConResPuts(StdOut, IDS_DELETE_PARTITION_FAIL);
return;
}
#endif
#ifdef DUMP_PARTITION_LIST
DumpPartitionList(CurrentDisk);
#endif
/* Dismount the partition */
DismountVolume(CurrentPartition);
/* Adjust the unpartitioned disk space entries */
/* Get pointer to previous and next unpartitioned entries */
PrevPartEntry = GetPrevUnpartitionedEntry(CurrentPartition);
NextPartEntry = GetNextUnpartitionedEntry(CurrentPartition);
if (PrevPartEntry != NULL && NextPartEntry != NULL)
{
/* Merge the previous, current and next unpartitioned entries */
/* Adjust the previous entry length */
PrevPartEntry->SectorCount.QuadPart += (CurrentPartition->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart);
/* Remove the current and next entries */
RemoveEntryList(&CurrentPartition->ListEntry);
RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentPartition);
RemoveEntryList(&NextPartEntry->ListEntry);
RtlFreeHeap(RtlGetProcessHeap(), 0, NextPartEntry);
}
else if (PrevPartEntry != NULL && NextPartEntry == NULL)
{
/* Merge the current and the previous unpartitioned entries */
/* Adjust the previous entry length */
PrevPartEntry->SectorCount.QuadPart += CurrentPartition->SectorCount.QuadPart;
/* Remove the current entry */
RemoveEntryList(&CurrentPartition->ListEntry);
RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentPartition);
}
else if (PrevPartEntry == NULL && NextPartEntry != NULL)
{
/* Merge the current and the next unpartitioned entries */
/* Adjust the next entry offset and length */
NextPartEntry->StartSector.QuadPart = CurrentPartition->StartSector.QuadPart;
NextPartEntry->SectorCount.QuadPart += CurrentPartition->SectorCount.QuadPart;
/* Remove the current entry */
RemoveEntryList(&CurrentPartition->ListEntry);
RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentPartition);
}
else
{
/* Nothing to merge but change the current entry */
CurrentPartition->IsPartitioned = FALSE;
CurrentPartition->OnDiskPartitionNumber = 0;
CurrentPartition->PartitionNumber = 0;
// CurrentPartition->PartitionIndex = 0;
ZeroMemory(&CurrentPartition->Gpt.PartitionType, sizeof(GUID));
ZeroMemory(&CurrentPartition->Gpt.PartitionId, sizeof(GUID));
CurrentPartition->Gpt.Attributes = 0ULL;
CurrentPartition->FormatState = Unformatted;
CurrentPartition->FileSystemName[0] = L'\0';
CurrentPartition->DriveLetter = 0;
RtlZeroMemory(CurrentPartition->VolumeLabel, sizeof(CurrentPartition->VolumeLabel));
}
CurrentPartition = NULL;
#ifdef DUMP_PARTITION_LIST
DumpPartitionList(CurrentDisk);
#endif
UpdateGptDiskLayout(CurrentDisk, TRUE);
#ifdef DUMP_PARTITION_TABLE
DumpPartitionTable(CurrentDisk);
#endif
Status = WriteGptPartitions(CurrentDisk);
if (!NT_SUCCESS(Status))
{
ConResPuts(StdOut, IDS_DELETE_PARTITION_FAIL);
return;
}
ConResPuts(StdOut, IDS_DELETE_PARTITION_SUCCESS);
}
BOOL
DeletePartition(
_In_ INT argc,
_In_ PWSTR *argv)
{
INT i;
BOOL bOverride = FALSE;
DPRINT("DeletePartition()\n");
if (CurrentDisk == NULL)
{
ConResPuts(StdOut, IDS_SELECT_NO_DISK);
return TRUE;
}
if (CurrentPartition == NULL)
{
ConResPuts(StdOut, IDS_SELECT_NO_PARTITION);
return TRUE;
}
for (i = 2; i < argc; i++)
{
if (_wcsicmp(argv[i], L"noerr") == 0)
{
/* noerr */
DPRINT("NOERR\n");
ConPuts(StdOut, L"The NOERR option is not supported yet!\n");
#if 0
bNoErr = TRUE;
#endif
}
else if (_wcsicmp(argv[i], L"override") == 0)
{
/* override */
DPRINT("OVERRIDE\n");
bOverride = TRUE;
}
else
{
ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
return TRUE;
}
}
if (CurrentDisk->PartitionStyle == PARTITION_STYLE_MBR)
{
DeleteMbrPartition(bOverride);
}
else if (CurrentDisk->PartitionStyle == PARTITION_STYLE_GPT)
{
DeleteGptPartition(bOverride);
}
return TRUE;
}
+16 -3
View File
@@ -138,6 +138,7 @@ DetailPartition(
PLIST_ENTRY Entry;
PVOLENTRY VolumeEntry;
BOOL bVolumeFound = FALSE, bPrintHeader = TRUE;
WCHAR szBuffer[40];
DPRINT("DetailPartition()\n");
@@ -165,9 +166,21 @@ DetailPartition(
/* TODO: Print more partition details */
ConPuts(StdOut, L"\n");
ConResPrintf(StdOut, IDS_DETAIL_PARTITION_NUMBER, PartEntry->PartitionNumber);
ConResPrintf(StdOut, IDS_DETAIL_PARTITION_TYPE, PartEntry->PartitionType);
ConResPrintf(StdOut, IDS_DETAIL_PARTITION_HIDDEN, "");
ConResPrintf(StdOut, IDS_DETAIL_PARTITION_ACTIVE, PartEntry->BootIndicator ? L"Yes" : L"No");
if (CurrentDisk->PartitionStyle == PARTITION_STYLE_GPT)
{
PrintGUID(szBuffer, &PartEntry->Gpt.PartitionType);
ConResPrintf(StdOut, IDS_DETAIL_PARTITION_TYPE, szBuffer);
ConResPrintf(StdOut, IDS_DETAIL_PARTITION_HIDDEN, (PartEntry->Gpt.Attributes & GPT_BASIC_DATA_ATTRIBUTE_HIDDEN) ? L"Yes" : L"No");
ConResPrintf(StdOut, IDS_DETAIL_PARTITION_REQUIRED, (PartEntry->Gpt.Attributes & GPT_ATTRIBUTE_PLATFORM_REQUIRED) ? L"Yes" : L"No");
ConResPrintf(StdOut, IDS_DETAIL_PARTITION_ATTRIBUTE, PartEntry->Gpt.Attributes);
}
else if (CurrentDisk->PartitionStyle == PARTITION_STYLE_MBR)
{
swprintf(szBuffer, L"%02x", PartEntry->Mbr.PartitionType);
ConResPrintf(StdOut, IDS_DETAIL_PARTITION_TYPE, szBuffer);
ConResPrintf(StdOut, IDS_DETAIL_PARTITION_HIDDEN, "");
ConResPrintf(StdOut, IDS_DETAIL_PARTITION_ACTIVE, PartEntry->Mbr.BootIndicator ? L"Yes" : L"No");
}
ConResPrintf(StdOut, IDS_DETAIL_PARTITION_OFFSET, PartOffset);
Entry = VolumeListHead.Flink;
+55 -4
View File
@@ -50,10 +50,13 @@
#include <ndk/umfuncs.h>
#include <fmifs/fmifs.h>
#include <guiddef.h>
#include "guid.h"
#include "resource.h"
//#define DUMP_PARTITION_TABLE
//#define DUMP_PARTITION_LIST
/* DEFINES *******************************************************************/
@@ -98,6 +101,19 @@ typedef enum _VOLUME_TYPE
VOLUME_TYPE_UNKNOWN
} VOLUME_TYPE, *PVOLUME_TYPE;
typedef struct _MBR_PARTITION_DATA
{
BOOLEAN BootIndicator;
UCHAR PartitionType;
} MBR_PARTITION_DATA, *PMBR_PARTITION_DATA;
typedef struct _GPT_PARTITION_DATA
{
GUID PartitionType;
GUID PartitionId;
DWORD64 Attributes;
} GPT_PARTITION_DATA, *PGPT_PARTITION_DATA;
typedef struct _PARTENTRY
{
LIST_ENTRY ListEntry;
@@ -107,8 +123,12 @@ typedef struct _PARTENTRY
ULARGE_INTEGER StartSector;
ULARGE_INTEGER SectorCount;
BOOLEAN BootIndicator;
UCHAR PartitionType;
union
{
MBR_PARTITION_DATA Mbr;
GPT_PARTITION_DATA Gpt;
};
ULONG OnDiskPartitionNumber;
ULONG PartitionNumber;
ULONG PartitionIndex;
@@ -161,6 +181,9 @@ typedef struct _DISKENTRY
ULONG SectorAlignment;
ULONG CylinderAlignment;
ULARGE_INTEGER StartSector;
ULARGE_INTEGER EndSector;
BOOLEAN BiosFound;
ULONG BiosDiskNumber;
// ULONG Signature;
@@ -434,6 +457,11 @@ PrintGUID(
_Out_ PWSTR pszBuffer,
_In_ GUID *pGuid);
BOOL
StringToGUID(
_Out_ GUID *pGuid,
_In_ PWSTR pszString);
/* offline.c */
BOOL offline_main(INT argc, LPWSTR *argv);
@@ -447,6 +475,12 @@ DumpPartitionTable(
_In_ PDISKENTRY DiskEntry);
#endif
#ifdef DUMP_PARTITION_LIST
VOID
DumpPartitionList(
_In_ PDISKENTRY DiskEntry);
#endif
ULONGLONG
AlignDown(
_In_ ULONGLONG Value,
@@ -464,19 +498,36 @@ CreateVolumeList(VOID);
VOID
DestroyVolumeList(VOID);
VOID
ScanForUnpartitionedMbrDiskSpace(
PDISKENTRY DiskEntry);
VOID
ScanForUnpartitionedGptDiskSpace(
PDISKENTRY DiskEntry);
VOID
ReadLayoutBuffer(
_In_ HANDLE FileHandle,
_In_ PDISKENTRY DiskEntry);
NTSTATUS
WritePartitions(
WriteMbrPartitions(
_In_ PDISKENTRY DiskEntry);
NTSTATUS
WriteGptPartitions(
_In_ PDISKENTRY DiskEntry);
VOID
UpdateDiskLayout(
UpdateMbrDiskLayout(
_In_ PDISKENTRY DiskEntry);
VOID
UpdateGptDiskLayout(
_In_ PDISKENTRY DiskEntry,
_In_ BOOL DeleteEntry);
PPARTENTRY
GetPrevUnpartitionedEntry(
_In_ PPARTENTRY PartEntry);
+6
View File
@@ -0,0 +1,6 @@
#define INITGUID
#include <guiddef.h>
#include "guid.h"
+9
View File
@@ -0,0 +1,9 @@
DEFINE_GUID(PARTITION_ENTRY_UNUSED_GUID, 0x00000000L, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
DEFINE_GUID(PARTITION_SYSTEM_GUID, 0xc12a7328L, 0xf81f, 0x11d2, 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b);
DEFINE_GUID(PARTITION_MSFT_RESERVED_GUID, 0xe3c9e316L, 0x0b5c, 0x4db8, 0x81, 0x7d, 0xf9, 0x2d, 0xf0, 0x02, 0x15, 0xae);
DEFINE_GUID(PARTITION_BASIC_DATA_GUID, 0xebd0a0a2L, 0xb9e5, 0x4433, 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7);
DEFINE_GUID(PARTITION_LDM_METADATA_GUID, 0x5808c8aaL, 0x7e8f, 0x42e0, 0x85, 0xd2, 0xe1, 0xe9, 0x04, 0x34, 0xcf, 0xb3);
DEFINE_GUID(PARTITION_LDM_DATA_GUID, 0xaf9b60a0L, 0x1431, 0x4f62, 0xbc, 0x68, 0x33, 0x11, 0x71, 0x4a, 0x69, 0xad);
DEFINE_GUID(PARTITION_MSFT_RECOVERY_GUID, 0xde94bba4L, 0x06d1, 0x4d40, 0xa1, 0x6a, 0xbf, 0xd5, 0x01, 0x79, 0xd6, 0xac);
+4 -4
View File
@@ -35,16 +35,16 @@ inactive_main(
if (CurrentDisk->PartitionStyle == PARTITION_STYLE_MBR)
{
if (!CurrentPartition->BootIndicator)
if (!CurrentPartition->Mbr.BootIndicator)
{
ConResPuts(StdOut, IDS_INACTIVE_ALREADY);
return TRUE;
}
CurrentPartition->BootIndicator = FALSE;
CurrentPartition->Mbr.BootIndicator = FALSE;
CurrentDisk->Dirty = TRUE;
UpdateDiskLayout(CurrentDisk);
Status = WritePartitions(CurrentDisk);
UpdateMbrDiskLayout(CurrentDisk);
Status = WriteMbrPartitions(CurrentDisk);
if (NT_SUCCESS(Status))
{
ConResPuts(StdOut, IDS_INACTIVE_SUCCESS);
+3 -1
View File
@@ -71,10 +71,12 @@ BEGIN
IDS_DETAIL_INFO_CRASH_DSK "Crashdump Disk"
IDS_DETAIL_INFO_CLST_DSK "Clustered Disk"
IDS_DETAIL_PARTITION_NUMBER "Partition %lu\n"
IDS_DETAIL_PARTITION_TYPE "Type : %02x\n"
IDS_DETAIL_PARTITION_TYPE "Type : %s\n"
IDS_DETAIL_PARTITION_HIDDEN "Hidden : %s\n"
IDS_DETAIL_PARTITION_ACTIVE "Active : %s\n"
IDS_DETAIL_PARTITION_OFFSET "Offset in Byte: %I64u\n"
IDS_DETAIL_PARTITION_REQUIRED "Required : %s\n"
IDS_DETAIL_PARTITION_ATTRIBUTE "Attributes : %016I64x\n"
IDS_DETAIL_NO_DISKS "\nThere are no disks attached to this volume.\n"
IDS_DETAIL_NO_VOLUME "\nThere is no volume associated with this partition.\n"
END
+3 -1
View File
@@ -71,10 +71,12 @@ BEGIN
IDS_DETAIL_INFO_CRASH_DSK "Crashdump Disk"
IDS_DETAIL_INFO_CLST_DSK "Clustered Disk"
IDS_DETAIL_PARTITION_NUMBER "Partition %lu\n"
IDS_DETAIL_PARTITION_TYPE "Type : %02x\n"
IDS_DETAIL_PARTITION_TYPE "Type : %s\n"
IDS_DETAIL_PARTITION_HIDDEN "Hidden : %s\n"
IDS_DETAIL_PARTITION_ACTIVE "Active : %s\n"
IDS_DETAIL_PARTITION_OFFSET "Offset in Byte: %I64u\n"
IDS_DETAIL_PARTITION_REQUIRED "Required : %s\n"
IDS_DETAIL_PARTITION_ATTRIBUTE "Attributes : %016I64x\n"
IDS_DETAIL_NO_DISKS "\nThere are no disks attached to this volume.\n"
IDS_DETAIL_NO_VOLUME "\nThere is no volume associated with this partition.\n"
END
+3 -1
View File
@@ -78,10 +78,12 @@ BEGIN
IDS_DETAIL_INFO_CRASH_DSK "Disco di crashdump"
IDS_DETAIL_INFO_CLST_DSK "Disco clustered"
IDS_DETAIL_PARTITION_NUMBER "Partizione %lu\n"
IDS_DETAIL_PARTITION_TYPE "Tipo : %02x\n"
IDS_DETAIL_PARTITION_TYPE "Tipo : %s\n"
IDS_DETAIL_PARTITION_HIDDEN "Nascosto : %s\n"
IDS_DETAIL_PARTITION_ACTIVE "Attivo : %s\n"
IDS_DETAIL_PARTITION_OFFSET "Offset in Byte: %I64u\n"
IDS_DETAIL_PARTITION_REQUIRED "Required : %s\n"
IDS_DETAIL_PARTITION_ATTRIBUTE "Attributes : %016I64x\n"
IDS_DETAIL_NO_DISKS "\nNon ci sono dischi collegati a questo volume.\n"
IDS_DETAIL_NO_VOLUME "\nNon c'è nessun volume associato a questa partizione.\n"
END
+3 -1
View File
@@ -71,10 +71,12 @@ BEGIN
IDS_DETAIL_INFO_CRASH_DSK "Dysk zrzutu awarii systemu"
IDS_DETAIL_INFO_CLST_DSK "Dysk klastrowany"
IDS_DETAIL_PARTITION_NUMBER "Partycja %lu\n"
IDS_DETAIL_PARTITION_TYPE "Typ : %02x\n"
IDS_DETAIL_PARTITION_TYPE "Typ : %s\n"
IDS_DETAIL_PARTITION_HIDDEN "Ukryta : %s\n"
IDS_DETAIL_PARTITION_ACTIVE "Aktywna : %s\n"
IDS_DETAIL_PARTITION_OFFSET "Przesunięcie w bajtach: %I64u\n"
IDS_DETAIL_PARTITION_REQUIRED "Required : %s\n"
IDS_DETAIL_PARTITION_ATTRIBUTE "Attributes : %016I64x\n"
IDS_DETAIL_NO_DISKS "\nThere are no disks attached to this volume.\n"
IDS_DETAIL_NO_VOLUME "\nThere is no volume associated with this partition.\n"
END
+3 -1
View File
@@ -73,10 +73,12 @@ BEGIN
IDS_DETAIL_INFO_CRASH_DSK "Despejo de memória de disco"
IDS_DETAIL_INFO_CLST_DSK "Disco em cluster"
IDS_DETAIL_PARTITION_NUMBER "Partition %lu\n"
IDS_DETAIL_PARTITION_TYPE "Type : %02x\n"
IDS_DETAIL_PARTITION_TYPE "Type : %s\n"
IDS_DETAIL_PARTITION_HIDDEN "Hidden : %s\n"
IDS_DETAIL_PARTITION_ACTIVE "Active : %s\n"
IDS_DETAIL_PARTITION_OFFSET "Offset in Byte: %I64u\n"
IDS_DETAIL_PARTITION_REQUIRED "Required : %s\n"
IDS_DETAIL_PARTITION_ATTRIBUTE "Attributes : %016I64x\n"
IDS_DETAIL_NO_DISKS "\nThere are no disks attached to this volume.\n"
IDS_DETAIL_NO_VOLUME "\nThere is no volume associated with this partition.\n"
END
+3 -1
View File
@@ -79,10 +79,12 @@ BEGIN
IDS_DETAIL_INFO_CRASH_DSK "Disc cu fișier «crashdump»"
IDS_DETAIL_INFO_CLST_DSK "Disc în «cluster»"
IDS_DETAIL_PARTITION_NUMBER "Partiție %lu\n"
IDS_DETAIL_PARTITION_TYPE "Tip : %02x\n"
IDS_DETAIL_PARTITION_TYPE "Tip : %s\n"
IDS_DETAIL_PARTITION_HIDDEN "Ascuns : %s\n"
IDS_DETAIL_PARTITION_ACTIVE "Activ : %s\n"
IDS_DETAIL_PARTITION_OFFSET "Offset în octet: %I64u\n"
IDS_DETAIL_PARTITION_REQUIRED "Required : %s\n"
IDS_DETAIL_PARTITION_ATTRIBUTE "Attributes : %016I64x\n"
IDS_DETAIL_NO_DISKS "\nNu există discuri atașate acestui volum.\n"
IDS_DETAIL_NO_VOLUME "\nNu există volum asociat cu această partiție.\n"
END
+3 -1
View File
@@ -73,10 +73,12 @@ BEGIN
IDS_DETAIL_INFO_CRASH_DSK "Crashdump диск"
IDS_DETAIL_INFO_CLST_DSK "Кластерный диск"
IDS_DETAIL_PARTITION_NUMBER "Partition %lu\n"
IDS_DETAIL_PARTITION_TYPE "Type : %02x\n"
IDS_DETAIL_PARTITION_TYPE "Type : %s\n"
IDS_DETAIL_PARTITION_HIDDEN "Hidden : %s\n"
IDS_DETAIL_PARTITION_ACTIVE "Active : %s\n"
IDS_DETAIL_PARTITION_OFFSET "Offset in Byte: %I64u\n"
IDS_DETAIL_PARTITION_REQUIRED "Required : %s\n"
IDS_DETAIL_PARTITION_ATTRIBUTE "Attributes : %016I64x\n"
IDS_DETAIL_NO_DISKS "\nThere are no disks attached to this volume.\n"
IDS_DETAIL_NO_VOLUME "\nThere is no volume associated with this partition.\n"
END
+3 -1
View File
@@ -75,10 +75,12 @@ BEGIN
IDS_DETAIL_INFO_CRASH_DSK "Hedhja e te dhenave Disk"
IDS_DETAIL_INFO_CLST_DSK "Grupimet ne Disk"
IDS_DETAIL_PARTITION_NUMBER "Partition %lu\n"
IDS_DETAIL_PARTITION_TYPE "Type : %02x\n"
IDS_DETAIL_PARTITION_TYPE "Type : %s\n"
IDS_DETAIL_PARTITION_HIDDEN "Hidden : %s\n"
IDS_DETAIL_PARTITION_ACTIVE "Active : %s\n"
IDS_DETAIL_PARTITION_OFFSET "Offset in Byte: %I64u\n"
IDS_DETAIL_PARTITION_REQUIRED "Required : %s\n"
IDS_DETAIL_PARTITION_ATTRIBUTE "Attributes : %016I64x\n"
IDS_DETAIL_NO_DISKS "\nThere are no disks attached to this volume.\n"
IDS_DETAIL_NO_VOLUME "\nThere is no volume associated with this partition.\n"
END
+3 -1
View File
@@ -81,10 +81,12 @@ BEGIN
IDS_DETAIL_INFO_CRASH_DSK "Çökme Dökümü Diski"
IDS_DETAIL_INFO_CLST_DSK "Kümelenmiş Disk"
IDS_DETAIL_PARTITION_NUMBER "Bölüm %lu\n"
IDS_DETAIL_PARTITION_TYPE "Tür : %02x\n"
IDS_DETAIL_PARTITION_TYPE "Tür : %s\n"
IDS_DETAIL_PARTITION_HIDDEN "Gizli : %s\n"
IDS_DETAIL_PARTITION_ACTIVE "Etkin : %s\n"
IDS_DETAIL_PARTITION_OFFSET "Bayt cinsinden ofset: %I64u\n"
IDS_DETAIL_PARTITION_REQUIRED "Required : %s\n"
IDS_DETAIL_PARTITION_ATTRIBUTE "Attributes : %016I64x\n"
IDS_DETAIL_NO_DISKS "\nBu birime bağlı disk yok.\n"
IDS_DETAIL_NO_VOLUME "\nBu bölümle ilişkilendirilmiş bir birim yok.\n"
END
+3 -1
View File
@@ -80,10 +80,12 @@ BEGIN
IDS_DETAIL_INFO_CRASH_DSK "故障转储磁盘"
IDS_DETAIL_INFO_CLST_DSK "群集的磁盘"
IDS_DETAIL_PARTITION_NUMBER "Partition %lu\n"
IDS_DETAIL_PARTITION_TYPE "Type : %02x\n"
IDS_DETAIL_PARTITION_TYPE "Type : %s\n"
IDS_DETAIL_PARTITION_HIDDEN "Hidden : %s\n"
IDS_DETAIL_PARTITION_ACTIVE "Active : %s\n"
IDS_DETAIL_PARTITION_OFFSET "Offset in Byte: %I64u\n"
IDS_DETAIL_PARTITION_REQUIRED "Required : %s\n"
IDS_DETAIL_PARTITION_ATTRIBUTE "Attributes : %016I64x\n"
IDS_DETAIL_NO_DISKS "\nThere are no disks attached to this volume.\n"
IDS_DETAIL_NO_VOLUME "\nThere is no volume associated with this partition.\n"
END
+3 -1
View File
@@ -80,10 +80,12 @@ BEGIN
IDS_DETAIL_INFO_CRASH_DSK "損毀傾印磁碟"
IDS_DETAIL_INFO_CLST_DSK "叢集磁碟"
IDS_DETAIL_PARTITION_NUMBER "磁碟分割 %lu\n"
IDS_DETAIL_PARTITION_TYPE "類型 : %02x\n"
IDS_DETAIL_PARTITION_TYPE "類型 : %s\n"
IDS_DETAIL_PARTITION_HIDDEN "已隱藏 : %s\n"
IDS_DETAIL_PARTITION_ACTIVE "使用中 : %s\n"
IDS_DETAIL_PARTITION_OFFSET "位移 (位元組) : %I64u\n"
IDS_DETAIL_PARTITION_REQUIRED "Required : %s\n"
IDS_DETAIL_PARTITION_ATTRIBUTE "Attributes : %016I64x\n"
IDS_DETAIL_NO_DISKS "\n沒有磁碟附加到這個磁碟區。\n"
IDS_DETAIL_NO_VOLUME "\n沒有磁碟區與這個磁碟分割有關聯。\n"
END
+177 -93
View File
@@ -108,116 +108,200 @@ ListPartition(
ConResPuts(StdOut, IDS_LIST_PARTITION_HEAD);
ConResPuts(StdOut, IDS_LIST_PARTITION_LINE);
Entry = CurrentDisk->PrimaryPartListHead.Flink;
while (Entry != &CurrentDisk->PrimaryPartListHead)
if (CurrentDisk->PartitionStyle == PARTITION_STYLE_MBR)
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
if (PartEntry->PartitionType != 0)
Entry = CurrentDisk->PrimaryPartListHead.Flink;
while (Entry != &CurrentDisk->PrimaryPartListHead)
{
PartSize = PartEntry->SectorCount.QuadPart * CurrentDisk->BytesPerSector;
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
if (PartSize >= 10737418240) /* 10 GB */
if (PartEntry->Mbr.PartitionType != 0)
{
PartSize = RoundingDivide(PartSize, 1073741824);
lpSizeUnit = L"GB";
}
else if (PartSize >= 10485760) /* 10 MB */
{
PartSize = RoundingDivide(PartSize, 1048576);
lpSizeUnit = L"MB";
}
else
{
PartSize = RoundingDivide(PartSize, 1024);
lpSizeUnit = L"KB";
PartSize = PartEntry->SectorCount.QuadPart * CurrentDisk->BytesPerSector;
if (PartSize >= 10737418240) /* 10 GB */
{
PartSize = RoundingDivide(PartSize, 1073741824);
lpSizeUnit = L"GB";
}
else if (PartSize >= 10485760) /* 10 MB */
{
PartSize = RoundingDivide(PartSize, 1048576);
lpSizeUnit = L"MB";
}
else
{
PartSize = RoundingDivide(PartSize, 1024);
lpSizeUnit = L"KB";
}
PartOffset = PartEntry->StartSector.QuadPart * CurrentDisk->BytesPerSector;
if (PartOffset >= 10737418240) /* 10 GB */
{
PartOffset = RoundingDivide(PartOffset, 1073741824);
lpOffsetUnit = L"GB";
}
else if (PartOffset >= 10485760) /* 10 MB */
{
PartOffset = RoundingDivide(PartOffset, 1048576);
lpOffsetUnit = L"MB";
}
else
{
PartOffset = RoundingDivide(PartOffset, 1024);
lpOffsetUnit = L"KB";
}
ConResPrintf(StdOut, IDS_LIST_PARTITION_FORMAT,
(CurrentPartition == PartEntry) ? L'*' : L' ',
PartNumber++,
IsContainerPartition(PartEntry->Mbr.PartitionType) ? L"Extended" : L"Primary",
PartSize,
lpSizeUnit,
PartOffset,
lpOffsetUnit);
}
PartOffset = PartEntry->StartSector.QuadPart * CurrentDisk->BytesPerSector;
if (PartOffset >= 10737418240) /* 10 GB */
{
PartOffset = RoundingDivide(PartOffset, 1073741824);
lpOffsetUnit = L"GB";
}
else if (PartOffset >= 10485760) /* 10 MB */
{
PartOffset = RoundingDivide(PartOffset, 1048576);
lpOffsetUnit = L"MB";
}
else
{
PartOffset = RoundingDivide(PartOffset, 1024);
lpOffsetUnit = L"KB";
}
ConResPrintf(StdOut, IDS_LIST_PARTITION_FORMAT,
(CurrentPartition == PartEntry) ? L'*' : L' ',
PartNumber++,
IsContainerPartition(PartEntry->PartitionType) ? L"Extended" : L"Primary",
PartSize,
lpSizeUnit,
PartOffset,
lpOffsetUnit);
Entry = Entry->Flink;
}
Entry = Entry->Flink;
Entry = CurrentDisk->LogicalPartListHead.Flink;
while (Entry != &CurrentDisk->LogicalPartListHead)
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
if (PartEntry->Mbr.PartitionType != 0)
{
PartSize = PartEntry->SectorCount.QuadPart * CurrentDisk->BytesPerSector;
if (PartSize >= 10737418240) /* 10 GB */
{
PartSize = RoundingDivide(PartSize, 1073741824);
lpSizeUnit = L"GB";
}
else if (PartSize >= 10485760) /* 10 MB */
{
PartSize = RoundingDivide(PartSize, 1048576);
lpSizeUnit = L"MB";
}
else
{
PartSize = RoundingDivide(PartSize, 1024);
lpSizeUnit = L"KB";
}
PartOffset = PartEntry->StartSector.QuadPart * CurrentDisk->BytesPerSector;
if (PartOffset >= 10737418240) /* 10 GB */
{
PartOffset = RoundingDivide(PartOffset, 1073741824);
lpOffsetUnit = L"GB";
}
else if (PartOffset >= 10485760) /* 10 MB */
{
PartOffset = RoundingDivide(PartOffset, 1048576);
lpOffsetUnit = L"MB";
}
else
{
PartOffset = RoundingDivide(PartOffset, 1024);
lpOffsetUnit = L"KB";
}
ConResPrintf(StdOut, IDS_LIST_PARTITION_FORMAT,
(CurrentPartition == PartEntry) ? L'*' : L' ',
PartNumber++,
L"Logical",
PartSize,
lpSizeUnit,
PartOffset,
lpOffsetUnit);
}
Entry = Entry->Flink;
}
}
Entry = CurrentDisk->LogicalPartListHead.Flink;
while (Entry != &CurrentDisk->LogicalPartListHead)
else if (CurrentDisk->PartitionStyle == PARTITION_STYLE_GPT)
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
LPWSTR lpPartitionType;
if (PartEntry->PartitionType != 0)
Entry = CurrentDisk->PrimaryPartListHead.Flink;
while (Entry != &CurrentDisk->PrimaryPartListHead)
{
PartSize = PartEntry->SectorCount.QuadPart * CurrentDisk->BytesPerSector;
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
if (PartSize >= 10737418240) /* 10 GB */
if (!IsEqualGUID(&PartEntry->Gpt.PartitionType, &PARTITION_ENTRY_UNUSED_GUID))
{
PartSize = RoundingDivide(PartSize, 1073741824);
lpSizeUnit = L"GB";
}
else if (PartSize >= 10485760) /* 10 MB */
{
PartSize = RoundingDivide(PartSize, 1048576);
lpSizeUnit = L"MB";
}
else
{
PartSize = RoundingDivide(PartSize, 1024);
lpSizeUnit = L"KB";
PartSize = PartEntry->SectorCount.QuadPart * CurrentDisk->BytesPerSector;
if (PartSize >= 10737418240) /* 10 GB */
{
PartSize = RoundingDivide(PartSize, 1073741824);
lpSizeUnit = L"GB";
}
else if (PartSize >= 10485760) /* 10 MB */
{
PartSize = RoundingDivide(PartSize, 1048576);
lpSizeUnit = L"MB";
}
else
{
PartSize = RoundingDivide(PartSize, 1024);
lpSizeUnit = L"KB";
}
PartOffset = PartEntry->StartSector.QuadPart * CurrentDisk->BytesPerSector;
if (PartOffset >= 10737418240) /* 10 GB */
{
PartOffset = RoundingDivide(PartOffset, 1073741824);
lpOffsetUnit = L"GB";
}
else if (PartOffset >= 10485760) /* 10 MB */
{
PartOffset = RoundingDivide(PartOffset, 1048576);
lpOffsetUnit = L"MB";
}
else
{
PartOffset = RoundingDivide(PartOffset, 1024);
lpOffsetUnit = L"KB";
}
if (IsEqualGUID(&PartEntry->Gpt.PartitionType, &PARTITION_ENTRY_UNUSED_GUID))
{
lpPartitionType = L"Unused";
}
else if (IsEqualGUID(&PartEntry->Gpt.PartitionType, &PARTITION_BASIC_DATA_GUID))
{
lpPartitionType = L"Primary";
}
else if (IsEqualGUID(&PartEntry->Gpt.PartitionType, &PARTITION_SYSTEM_GUID))
{
lpPartitionType = L"System";
}
else if (IsEqualGUID(&PartEntry->Gpt.PartitionType, &PARTITION_MSFT_RESERVED_GUID))
{
lpPartitionType = L"Reserved";
}
else
{
lpPartitionType = L"Other"; /* ??? */
}
ConResPrintf(StdOut, IDS_LIST_PARTITION_FORMAT,
(CurrentPartition == PartEntry) ? L'*' : L' ',
PartNumber++,
lpPartitionType,
PartSize,
lpSizeUnit,
PartOffset,
lpOffsetUnit);
}
PartOffset = PartEntry->StartSector.QuadPart * CurrentDisk->BytesPerSector;
if (PartOffset >= 10737418240) /* 10 GB */
{
PartOffset = RoundingDivide(PartOffset, 1073741824);
lpOffsetUnit = L"GB";
}
else if (PartOffset >= 10485760) /* 10 MB */
{
PartOffset = RoundingDivide(PartOffset, 1048576);
lpOffsetUnit = L"MB";
}
else
{
PartOffset = RoundingDivide(PartOffset, 1024);
lpOffsetUnit = L"KB";
}
ConResPrintf(StdOut, IDS_LIST_PARTITION_FORMAT,
(CurrentPartition == PartEntry) ? L'*' : L' ',
PartNumber++,
L"Logical",
PartSize,
lpSizeUnit,
PartOffset,
lpOffsetUnit);
Entry = Entry->Flink;
}
Entry = Entry->Flink;
}
ConPuts(StdOut, L"\n");
+87
View File
@@ -202,3 +202,90 @@ PrintGUID(
pGuid->Data4[6],
pGuid->Data4[7]);
}
static
BYTE
CharToByte(
WCHAR Char)
{
if (iswdigit(Char))
{
return (BYTE)((INT)Char - (INT)'0');
}
else if (iswalpha(Char))
{
if (iswupper(Char))
return (INT)Char - ((INT)'A' - 10);
else
return (INT)Char - ((INT)'a' - 10);
}
return 0;
}
BOOL
StringToGUID(
_Out_ GUID *pGuid,
_In_ PWSTR pszString)
{
INT i;
if (pszString == NULL)
return FALSE;
pGuid->Data1 = 0;
for (i = 0; i < 8; i++)
{
if (!iswxdigit(pszString[i]))
return FALSE;
pGuid->Data1 = (pGuid->Data1 << 4) | CharToByte(pszString[i]);
}
if (pszString[8] != L'-')
return FALSE;
pGuid->Data2 = 0;
for (i = 9; i < 13; i++)
{
if (!iswxdigit(pszString[i]))
return FALSE;
pGuid->Data2 = (pGuid->Data2 << 4) | CharToByte(pszString[i]);
}
if (pszString[13] != L'-')
return FALSE;
pGuid->Data3 = 0;
for (i = 14; i < 18; i++)
{
if (!iswxdigit(pszString[i]))
return FALSE;
pGuid->Data3 = (pGuid->Data3 << 4) | CharToByte(pszString[i]);
}
if (pszString[18] != L'-')
return FALSE;
for (i = 19; i < 36; i += 2)
{
if (i == 23)
{
if (pszString[i] != L'-')
return FALSE;
i++;
}
if (!iswxdigit(pszString[i]) || !iswxdigit(pszString[i + 1]))
return FALSE;
pGuid->Data4[(i - 19) / 2] = CharToByte(pszString[i]) << 4 | CharToByte(pszString[i + 1]);
}
if (pszString[36] == L'\0')
return TRUE;
return FALSE;
}
+521 -76
View File
@@ -9,6 +9,7 @@
/* INCLUDES *******************************************************************/
#include "diskpart.h"
#include "guid.h"
#include <ntddscsi.h>
#define NDEBUG
@@ -131,6 +132,61 @@ DumpPartitionTable(
}
#endif
#ifdef DUMP_PARTITION_LIST
VOID
DumpPartitionList(
_In_ PDISKENTRY DiskEntry)
{
PLIST_ENTRY ListEntry;
PPARTENTRY PartEntry;
DbgPrint("\n");
if (DiskEntry->PartitionStyle == PARTITION_STYLE_GPT)
{
DbgPrint("Disk Start Disk End Disk Length \n");
DbgPrint("------------ ------------ ------------\n");
DbgPrint("%12I64u %12I64u %12I64u\n",
DiskEntry->StartSector.QuadPart,
DiskEntry->EndSector.QuadPart,
DiskEntry->EndSector.QuadPart - DiskEntry->StartSector.QuadPart + 1);
DbgPrint("\n");
DbgPrint("Start End Length Nr Type P\n");
DbgPrint("------------ ------------ ------------ --- -------- --\n");
for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
ListEntry != &DiskEntry->PrimaryPartListHead;
ListEntry = ListEntry->Flink)
{
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
DbgPrint("%12I64u %12I64u %12I64u %3lu %08lx %c\n",
PartEntry->StartSector.QuadPart,
PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1,
PartEntry->SectorCount.QuadPart,
PartEntry->PartitionNumber,
PartEntry->Gpt.PartitionType.Data1,
PartEntry->IsPartitioned ? 'Y': 'N');
}
}
else if (DiskEntry->PartitionStyle == PARTITION_STYLE_MBR)
{
DbgPrint("Disk Start Disk End Disk Length \n");
DbgPrint("------------ ------------ ------------\n");
DbgPrint("%12I64u %12I64u %12I64u\n",
DiskEntry->StartSector.QuadPart,
DiskEntry->EndSector.QuadPart,
DiskEntry->EndSector.QuadPart - DiskEntry->StartSector.QuadPart + 1);
}
DbgPrint("\n");
}
#endif
ULONGLONG
AlignDown(
_In_ ULONGLONG Value,
@@ -449,7 +505,7 @@ EnumerateBiosDiskEntries(VOID)
static
VOID
AddPartitionToDisk(
AddMbrPartitionToDisk(
ULONG DiskNumber,
PDISKENTRY DiskEntry,
ULONG PartitionIndex,
@@ -468,6 +524,7 @@ AddPartitionToDisk(
sizeof(PARTENTRY));
if (PartEntry == NULL)
{
/* TODO: Error message */
return;
}
@@ -476,27 +533,27 @@ AddPartitionToDisk(
PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
PartEntry->BootIndicator = PartitionInfo->Mbr.BootIndicator;
PartEntry->PartitionType = PartitionInfo->Mbr.PartitionType;
PartEntry->Mbr.BootIndicator = PartitionInfo->Mbr.BootIndicator;
PartEntry->Mbr.PartitionType = PartitionInfo->Mbr.PartitionType;
PartEntry->LogicalPartition = LogicalPartition;
PartEntry->IsPartitioned = TRUE;
PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
PartEntry->PartitionIndex = PartitionIndex;
if (IsContainerPartition(PartEntry->PartitionType))
if (IsContainerPartition(PartEntry->Mbr.PartitionType))
{
PartEntry->FormatState = Unformatted;
if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
DiskEntry->ExtendedPartition = PartEntry;
}
else if ((PartEntry->PartitionType == PARTITION_FAT_12) ||
(PartEntry->PartitionType == PARTITION_FAT_16) ||
(PartEntry->PartitionType == PARTITION_HUGE) ||
(PartEntry->PartitionType == PARTITION_XINT13) ||
(PartEntry->PartitionType == PARTITION_FAT32) ||
(PartEntry->PartitionType == PARTITION_FAT32_XINT13))
else if ((PartEntry->Mbr.PartitionType == PARTITION_FAT_12) ||
(PartEntry->Mbr.PartitionType == PARTITION_FAT_16) ||
(PartEntry->Mbr.PartitionType == PARTITION_HUGE) ||
(PartEntry->Mbr.PartitionType == PARTITION_XINT13) ||
(PartEntry->Mbr.PartitionType == PARTITION_FAT32) ||
(PartEntry->Mbr.PartitionType == PARTITION_FAT32_XINT13))
{
#if 0
if (CheckFatFormat())
@@ -510,7 +567,7 @@ AddPartitionToDisk(
#endif
PartEntry->FormatState = Preformatted;
}
else if (PartEntry->PartitionType == PARTITION_LINUX)
else if (PartEntry->Mbr.PartitionType == PARTITION_LINUX)
{
#if 0
if (CheckExt2Format())
@@ -524,7 +581,7 @@ AddPartitionToDisk(
#endif
PartEntry->FormatState = Preformatted;
}
else if (PartEntry->PartitionType == PARTITION_IFS)
else if (PartEntry->Mbr.PartitionType == PARTITION_IFS)
{
#if 0
if (CheckNtfsFormat())
@@ -558,9 +615,54 @@ AddPartitionToDisk(
static
VOID
ScanForUnpartitionedDiskSpace(
AddGptPartitionToDisk(
ULONG DiskNumber,
PDISKENTRY DiskEntry,
ULONG PartitionIndex)
{
PPARTITION_INFORMATION_EX PartitionInfo;
PPARTENTRY PartEntry;
PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
if (IsEqualGUID(&PartitionInfo->Gpt.PartitionType, &PARTITION_ENTRY_UNUSED_GUID))
return;
PartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(PARTENTRY));
if (PartEntry == NULL)
{
/* TODO: Error message */
return;
}
PartEntry->DiskEntry = DiskEntry;
PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
CopyMemory(&PartEntry->Gpt.PartitionType, &PartitionInfo->Gpt.PartitionType, sizeof(GUID));
CopyMemory(&PartEntry->Gpt.PartitionId, &PartitionInfo->Gpt.PartitionId, sizeof(GUID));
PartEntry->Gpt.Attributes = PartitionInfo->Gpt.Attributes;
PartEntry->LogicalPartition = FALSE;
PartEntry->IsPartitioned = TRUE;
PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
PartEntry->PartitionIndex = PartitionIndex;
/* TODO: Determine the format state */
PartEntry->FormatState = Unformatted;
InsertTailList(&DiskEntry->PrimaryPartListHead,
&PartEntry->ListEntry);
}
VOID
ScanForUnpartitionedMbrDiskSpace(
PDISKENTRY DiskEntry)
{
ULONGLONG StartSector, EndSector;
ULONGLONG LastStartSector;
ULONGLONG LastSectorCount;
ULONGLONG LastUnusedSectorCount;
@@ -568,7 +670,12 @@ ScanForUnpartitionedDiskSpace(
PPARTENTRY NewPartEntry;
PLIST_ENTRY Entry;
DPRINT("ScanForUnpartitionedDiskSpace()\n");
DPRINT("ScanForUnpartitionedMbrDiskSpace()\n");
/* Calculate the disk sector limits */
/* Limit the SectorCount to 2^32 sectors for MBR disks */
StartSector = (ULONGLONG)DiskEntry->SectorAlignment;
EndSector = min(DiskEntry->SectorCount.QuadPart, 0x100000000) - 1;
if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
{
@@ -584,8 +691,8 @@ ScanForUnpartitionedDiskSpace(
NewPartEntry->DiskEntry = DiskEntry;
NewPartEntry->IsPartitioned = FALSE;
NewPartEntry->StartSector.QuadPart = (ULONGLONG)DiskEntry->SectorAlignment;
NewPartEntry->SectorCount.QuadPart = AlignDown(DiskEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment) -
NewPartEntry->StartSector.QuadPart = StartSector;
NewPartEntry->SectorCount.QuadPart = AlignDown(EndSector + 1, DiskEntry->SectorAlignment) -
NewPartEntry->StartSector.QuadPart;
DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
@@ -600,8 +707,8 @@ ScanForUnpartitionedDiskSpace(
return;
}
/* Start partition at head 1, cylinder 0 */
LastStartSector = DiskEntry->SectorAlignment;
/* Start at the first usable sector */
LastStartSector = StartSector;
LastSectorCount = 0ULL;
LastUnusedSectorCount = 0ULL;
@@ -610,7 +717,7 @@ ScanForUnpartitionedDiskSpace(
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
if (PartEntry->Mbr.PartitionType != PARTITION_ENTRY_UNUSED ||
PartEntry->SectorCount.QuadPart != 0ULL)
{
LastUnusedSectorCount =
@@ -653,9 +760,9 @@ ScanForUnpartitionedDiskSpace(
}
/* Check for trailing unpartitioned disk space */
if ((LastStartSector + LastSectorCount) < DiskEntry->SectorCount.QuadPart)
if ((LastStartSector + LastSectorCount) < (EndSector + 1))
{
LastUnusedSectorCount = AlignDown(DiskEntry->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
LastUnusedSectorCount = AlignDown((EndSector + 1) - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
{
@@ -728,7 +835,7 @@ ScanForUnpartitionedDiskSpace(
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
if (PartEntry->Mbr.PartitionType != PARTITION_ENTRY_UNUSED ||
PartEntry->SectorCount.QuadPart != 0ULL)
{
LastUnusedSectorCount =
@@ -808,7 +915,151 @@ ScanForUnpartitionedDiskSpace(
}
}
DPRINT("ScanForUnpartitionedDiskSpace() done\n");
DPRINT("ScanForUnpartitionedMbrDiskSpace() done\n");
}
VOID
ScanForUnpartitionedGptDiskSpace(
PDISKENTRY DiskEntry)
{
ULONGLONG LastStartSector;
ULONGLONG LastSectorCount;
ULONGLONG LastUnusedSectorCount;
PPARTENTRY PartEntry;
PPARTENTRY NewPartEntry;
PLIST_ENTRY Entry;
DPRINT("ScanForUnpartitionedGptDiskSpace()\n");
#ifdef DUMP_PARTITION_LIST
DumpPartitionList(DiskEntry);
#endif
if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
{
DPRINT("No partitions!\n");
/* Create a partition table that represents the empty disk */
NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(PARTENTRY));
if (NewPartEntry == NULL)
return;
NewPartEntry->DiskEntry = DiskEntry;
NewPartEntry->IsPartitioned = FALSE;
NewPartEntry->StartSector.QuadPart = DiskEntry->StartSector.QuadPart;
NewPartEntry->SectorCount.QuadPart = DiskEntry->EndSector.QuadPart - DiskEntry->StartSector.QuadPart + 1;
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;
InsertTailList(&DiskEntry->PrimaryPartListHead,
&NewPartEntry->ListEntry);
#ifdef DUMP_PARTITION_LIST
DumpPartitionList(DiskEntry);
#endif
return;
}
/* Start at the first usable sector */
LastStartSector = DiskEntry->StartSector.QuadPart;
LastSectorCount = 0ULL;
LastUnusedSectorCount = 0ULL;
Entry = DiskEntry->PrimaryPartListHead.Flink;
while (Entry != &DiskEntry->PrimaryPartListHead)
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
if (!IsEqualGUID(&PartEntry->Gpt.PartitionType, &PARTITION_ENTRY_UNUSED_GUID) ||
PartEntry->SectorCount.QuadPart != 0ULL)
{
LastUnusedSectorCount =
PartEntry->StartSector.QuadPart - (LastStartSector + LastSectorCount);
if (PartEntry->StartSector.QuadPart > (LastStartSector + LastSectorCount) &&
LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
{
DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
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;
/* 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->EndSector.QuadPart + 1)
{
LastUnusedSectorCount = AlignDown(DiskEntry->EndSector.QuadPart + 1 - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
{
DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(PARTENTRY));
if (NewPartEntry == NULL)
return;
NewPartEntry->DiskEntry = DiskEntry;
NewPartEntry->IsPartitioned = FALSE;
NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
NewPartEntry->StartSector.QuadPart;
DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
NewPartEntry->FormatState = Unformatted;
/* Append the table to the list */
InsertTailList(&DiskEntry->PrimaryPartListHead,
&NewPartEntry->ListEntry);
}
}
#ifdef DUMP_PARTITION_LIST
DumpPartitionList(DiskEntry);
#endif
DPRINT("ScanForUnpartitionedGptDiskSpace() done\n");
}
@@ -869,6 +1120,7 @@ ReadLayoutBuffer(
DiskEntry->LayoutBuffer = NewLayoutBuffer;
}
}
@@ -1084,51 +1336,80 @@ AddDiskToList(
DumpPartitionTable(DiskEntry);
#endif
if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0 &&
DiskEntry->LayoutBuffer->PartitionEntry[0].Mbr.PartitionType != 0)
if (DiskEntry->PartitionStyle == PARTITION_STYLE_MBR)
{
if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0 &&
DiskEntry->LayoutBuffer->PartitionEntry[0].Mbr.PartitionType != 0)
{
DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
}
else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
{
DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
{
DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
}
else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
{
DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
}
else
{
DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
}
}
else
{
DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
}
}
else
{
DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
}
/* Calculate the number of usable sectors */
/* Limit the number of usable sectors to 2^32 */
DiskEntry->StartSector.QuadPart = (ULONGLONG)DiskEntry->SectorAlignment;
DiskEntry->EndSector.QuadPart = min(DiskEntry->SectorCount.QuadPart, 0x100000000) - 1;
if (DiskEntry->LayoutBuffer->PartitionCount == 0)
{
DiskEntry->NewDisk = TRUE;
DiskEntry->LayoutBuffer->PartitionCount = 4;
for (i = 0; i < 4; i++)
DiskEntry->LayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
}
else
{
for (i = 0; i < 4; i++)
if (DiskEntry->LayoutBuffer->PartitionCount == 0)
{
AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
}
DiskEntry->NewDisk = TRUE;
DiskEntry->LayoutBuffer->PartitionCount = 4;
for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
for (i = 0; i < 4; i++)
DiskEntry->LayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
}
else
{
AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
}
}
for (i = 0; i < 4; i++)
{
AddMbrPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
}
ScanForUnpartitionedDiskSpace(DiskEntry);
for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
{
AddMbrPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
}
}
ScanForUnpartitionedMbrDiskSpace(DiskEntry);
}
else if (DiskEntry->PartitionStyle == PARTITION_STYLE_GPT)
{
/* Calculate the number of usable sectors */
DiskEntry->StartSector.QuadPart = AlignDown(DiskEntry->LayoutBuffer->Gpt.StartingUsableOffset.QuadPart / DiskEntry->BytesPerSector,
DiskEntry->SectorAlignment) + (ULONGLONG)DiskEntry->SectorAlignment;
DiskEntry->EndSector.QuadPart = AlignDown(DiskEntry->StartSector.QuadPart + (DiskEntry->LayoutBuffer->Gpt.UsableLength.QuadPart / DiskEntry->BytesPerSector) - 1,
DiskEntry->SectorAlignment);
if (DiskEntry->LayoutBuffer->PartitionCount == 0)
{
DiskEntry->NewDisk = TRUE;
}
else
{
for (i = 0; i < DiskEntry->LayoutBuffer->PartitionCount; i++)
{
AddGptPartitionToDisk(DiskNumber, DiskEntry, i);
}
}
ScanForUnpartitionedGptDiskSpace(DiskEntry);
}
}
@@ -1555,7 +1836,7 @@ DestroyVolumeList(VOID)
NTSTATUS
WritePartitions(
WriteMbrPartitions(
_In_ PDISKENTRY DiskEntry)
{
NTSTATUS Status;
@@ -1570,7 +1851,7 @@ WritePartitions(
PPARTENTRY PartEntry;
WCHAR DstPath[MAX_PATH];
DPRINT("WritePartitions() Disk: %lu\n", DiskEntry->DiskNumber);
DPRINT("WriteMbrPartitions() Disk: %lu\n", DiskEntry->DiskNumber);
/* If the disk is not dirty, there is nothing to do */
if (!DiskEntry->Dirty)
@@ -1650,7 +1931,7 @@ WritePartitions(
if (PartEntry->IsPartitioned)
{
ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
ASSERT(PartEntry->Mbr.PartitionType != PARTITION_ENTRY_UNUSED);
PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
}
@@ -1665,7 +1946,7 @@ WritePartitions(
if (PartEntry->IsPartitioned)
{
ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
ASSERT(PartEntry->Mbr.PartitionType != PARTITION_ENTRY_UNUSED);
PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
}
@@ -1678,6 +1959,82 @@ WritePartitions(
}
NTSTATUS
WriteGptPartitions(
_In_ PDISKENTRY DiskEntry)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING Name;
HANDLE FileHandle;
IO_STATUS_BLOCK Iosb;
ULONG BufferSize;
WCHAR DstPath[MAX_PATH];
DPRINT("WriteGptPartitions() Disk: %lu\n", DiskEntry->DiskNumber);
/* If the disk is not dirty, there is nothing to do */
if (!DiskEntry->Dirty)
return STATUS_SUCCESS;
StringCchPrintfW(DstPath, ARRAYSIZE(DstPath),
L"\\Device\\Harddisk%lu\\Partition0",
DiskEntry->DiskNumber);
RtlInitUnicodeString(&Name, DstPath);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenFile(&FileHandle,
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
&ObjectAttributes,
&Iosb,
0,
FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
return Status;
}
//
// FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize
// the disk in MBR or GPT format in case the disk was not initialized!!
// For this we must ask the user which format to use.
//
/* Set the new disk layout and retrieve its updated version with possibly modified partition numbers */
BufferSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
((DiskEntry->LayoutBuffer->PartitionCount - 1) * sizeof(PARTITION_INFORMATION_EX));
Status = NtDeviceIoControlFile(FileHandle,
NULL,
NULL,
NULL,
&Iosb,
IOCTL_DISK_SET_DRIVE_LAYOUT_EX,
DiskEntry->LayoutBuffer,
BufferSize,
DiskEntry->LayoutBuffer,
BufferSize);
NtClose(FileHandle);
/* Check whether the IOCTL_DISK_SET_DRIVE_LAYOUT_EX call succeeded */
if (!NT_SUCCESS(Status))
{
DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT_EX failed (Status 0x%08lx)\n", Status);
return Status;
}
/* The layout has been successfully updated, the disk is not dirty anymore */
DiskEntry->Dirty = FALSE;
return Status;
}
static
BOOLEAN
IsEmptyLayoutEntry(
@@ -1807,7 +2164,7 @@ ReAllocateLayoutBuffer(
VOID
UpdateDiskLayout(
UpdateMbrDiskLayout(
_In_ PDISKENTRY DiskEntry)
{
PPARTITION_INFORMATION_EX PartitionInfo;
@@ -1818,7 +2175,7 @@ UpdateDiskLayout(
ULONG Index;
ULONG PartitionNumber = 1;
DPRINT1("UpdateDiskLayout()\n");
DPRINT("UpdateMbrDiskLayout()\n");
/* Resize the layout buffer if necessary */
if (ReAllocateLayoutBuffer(DiskEntry) == FALSE)
@@ -1839,7 +2196,7 @@ UpdateDiskLayout(
if (PartEntry->IsPartitioned)
{
ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
ASSERT(PartEntry->Mbr.PartitionType != PARTITION_ENTRY_UNUSED);
PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
PartEntry->PartitionIndex = Index;
@@ -1848,7 +2205,7 @@ UpdateDiskLayout(
if (PartEntry->New)
PartEntry->PartitionNumber = 0;
PartEntry->OnDiskPartitionNumber = (!IsContainerPartition(PartEntry->PartitionType) ? PartitionNumber : 0);
PartEntry->OnDiskPartitionNumber = (!IsContainerPartition(PartEntry->Mbr.PartitionType) ? PartitionNumber : 0);
if (!IsSamePrimaryLayoutEntry(PartitionInfo, DiskEntry, PartEntry))
{
@@ -1859,13 +2216,13 @@ UpdateDiskLayout(
PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
PartitionInfo->Mbr.HiddenSectors = PartEntry->StartSector.LowPart;
PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
PartitionInfo->Mbr.PartitionType = PartEntry->PartitionType;
PartitionInfo->Mbr.BootIndicator = PartEntry->BootIndicator;
PartitionInfo->Mbr.RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
PartitionInfo->Mbr.PartitionType = PartEntry->Mbr.PartitionType;
PartitionInfo->Mbr.BootIndicator = PartEntry->Mbr.BootIndicator;
PartitionInfo->Mbr.RecognizedPartition = IsRecognizedPartition(PartEntry->Mbr.PartitionType);
PartitionInfo->RewritePartition = TRUE;
}
if (!IsContainerPartition(PartEntry->PartitionType))
if (!IsContainerPartition(PartEntry->Mbr.PartitionType))
PartitionNumber++;
Index++;
@@ -1884,7 +2241,7 @@ UpdateDiskLayout(
if (PartEntry->IsPartitioned)
{
ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
ASSERT(PartEntry->Mbr.PartitionType != PARTITION_ENTRY_UNUSED);
PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
PartEntry->PartitionIndex = Index;
@@ -1902,9 +2259,9 @@ UpdateDiskLayout(
PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
PartitionInfo->Mbr.HiddenSectors = DiskEntry->SectorAlignment;
PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
PartitionInfo->Mbr.PartitionType = PartEntry->PartitionType;
PartitionInfo->Mbr.PartitionType = PartEntry->Mbr.PartitionType;
PartitionInfo->Mbr.BootIndicator = FALSE;
PartitionInfo->Mbr.RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
PartitionInfo->Mbr.RecognizedPartition = IsRecognizedPartition(PartEntry->Mbr.PartitionType);
PartitionInfo->RewritePartition = TRUE;
/* Fill the link entry of the previous partition entry */
@@ -1983,6 +2340,94 @@ UpdateDiskLayout(
}
VOID
UpdateGptDiskLayout(
_In_ PDISKENTRY DiskEntry,
_In_ BOOL DeleteEntry)
{
PLIST_ENTRY ListEntry;
PPARTENTRY PartEntry;
PPARTITION_INFORMATION_EX PartitionInfo;
ULONG Count, Index;
DPRINT("UpdateGptDiskLayout()\n");
/* Count used partition entries */
Count = 0;
for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
ListEntry != &DiskEntry->PrimaryPartListHead;
ListEntry = ListEntry->Flink)
{
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
if (!IsEqualGUID(&PartEntry->Gpt.PartitionType, &PARTITION_ENTRY_UNUSED_GUID))
Count++;
}
DPRINT("Used partition entries: %lu\n", Count);
if (DeleteEntry)
Count++;
/* Reallocate the layout buffer */
if (Count != DiskEntry->LayoutBuffer->PartitionCount)
{
PDRIVE_LAYOUT_INFORMATION_EX NewLayoutBuffer;
ULONG NewLayoutBufferSize;
NewLayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
((Count - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION_EX));
NewLayoutBuffer = RtlReAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
DiskEntry->LayoutBuffer,
NewLayoutBufferSize);
if (NewLayoutBuffer == NULL)
{
DPRINT1("Failed to allocate the new layout buffer (size: %lu)\n", NewLayoutBufferSize);
return;
}
NewLayoutBuffer->PartitionCount = Count;
DiskEntry->LayoutBuffer = NewLayoutBuffer;
}
/* Fill the new layout buffer */
Index = 0;
for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
ListEntry != &DiskEntry->PrimaryPartListHead;
ListEntry = ListEntry->Flink)
{
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
if (!IsEqualGUID(&PartEntry->Gpt.PartitionType, &PARTITION_ENTRY_UNUSED_GUID))
{
PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
PartEntry->PartitionIndex = Index;
DPRINT("Updating primary partition entry %lu\n", Index);
PartitionInfo->PartitionStyle = PARTITION_STYLE_GPT;
PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
PartitionInfo->PartitionNumber = Index + 1;
PartitionInfo->RewritePartition = TRUE;
CopyMemory(&PartitionInfo->Gpt.PartitionType, &PartEntry->Gpt.PartitionType, sizeof(GUID));
CopyMemory(&PartitionInfo->Gpt.PartitionId, &PartEntry->Gpt.PartitionId, sizeof(GUID));
PartitionInfo->Gpt.Attributes = PartEntry->Gpt.Attributes;
ZeroMemory(&PartitionInfo->Gpt.Name, 36 * sizeof(WCHAR)); /* ??? */
Index++;
}
}
if (DeleteEntry)
{
PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
ZeroMemory(PartitionInfo, sizeof(PARTITION_INFORMATION_EX));
PartitionInfo->RewritePartition = TRUE;
}
}
PPARTENTRY
GetPrevUnpartitionedEntry(
_In_ PPARTENTRY PartEntry)
@@ -2003,7 +2448,7 @@ GetPrevUnpartitionedEntry(
ListEntry);
if (!PrevPartEntry->IsPartitioned)
{
ASSERT(PrevPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
ASSERT(PrevPartEntry->Mbr.PartitionType == PARTITION_ENTRY_UNUSED);
return PrevPartEntry;
}
}
@@ -2032,7 +2477,7 @@ GetNextUnpartitionedEntry(
ListEntry);
if (!NextPartEntry->IsPartitioned)
{
ASSERT(NextPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
ASSERT(NextPartEntry->Mbr.PartitionType == PARTITION_ENTRY_UNUSED);
return NextPartEntry;
}
}
@@ -2055,8 +2500,8 @@ DismountVolume(
/* Check whether the partition is valid and was mounted by the system */
if (!PartEntry->IsPartitioned ||
IsContainerPartition(PartEntry->PartitionType) ||
!IsRecognizedPartition(PartEntry->PartitionType) ||
IsContainerPartition(PartEntry->Mbr.PartitionType) ||
!IsRecognizedPartition(PartEntry->Mbr.PartitionType) ||
PartEntry->FormatState == UnknownFormat ||
// NOTE: If FormatState == Unformatted but *FileSystem != 0 this means
// it has been usually mounted with RawFS and thus needs to be dismounted.
@@ -2067,7 +2512,7 @@ DismountVolume(
return STATUS_SUCCESS;
}
ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
ASSERT(PartEntry->Mbr.PartitionType != PARTITION_ENTRY_UNUSED);
/* Open the volume */
StringCchPrintfW(Buffer, ARRAYSIZE(Buffer),
+4 -3
View File
@@ -61,9 +61,10 @@
#define IDS_DETAIL_PARTITION_HIDDEN 1132
#define IDS_DETAIL_PARTITION_ACTIVE 1133
#define IDS_DETAIL_PARTITION_OFFSET 1134
#define IDS_DETAIL_NO_DISKS 1135
#define IDS_DETAIL_NO_VOLUME 1136
#define IDS_DETAIL_PARTITION_REQUIRED 1135
#define IDS_DETAIL_PARTITION_ATTRIBUTE 1136
#define IDS_DETAIL_NO_DISKS 1137
#define IDS_DETAIL_NO_VOLUME 1138
#define IDS_FILESYSTEMS_CURRENT 1180
#define IDS_FILESYSTEMS_FORMATTING 1181
+48 -23
View File
@@ -161,43 +161,68 @@ SelectPartition(
return TRUE;
}
Entry = CurrentDisk->PrimaryPartListHead.Flink;
while (Entry != &CurrentDisk->PrimaryPartListHead)
if (CurrentDisk->PartitionStyle == PARTITION_STYLE_MBR)
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
if (PartEntry->PartitionType != 0)
Entry = CurrentDisk->PrimaryPartListHead.Flink;
while (Entry != &CurrentDisk->PrimaryPartListHead)
{
if (PartNumber == ulValue)
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
if (PartEntry->Mbr.PartitionType != PARTITION_ENTRY_UNUSED)
{
CurrentPartition = PartEntry;
ConResPrintf(StdOut, IDS_SELECT_PARTITION, PartNumber);
return TRUE;
if (PartNumber == ulValue)
{
CurrentPartition = PartEntry;
ConResPrintf(StdOut, IDS_SELECT_PARTITION, PartNumber);
return TRUE;
}
PartNumber++;
}
PartNumber++;
Entry = Entry->Flink;
}
Entry = Entry->Flink;
Entry = CurrentDisk->LogicalPartListHead.Flink;
while (Entry != &CurrentDisk->LogicalPartListHead)
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
if (PartEntry->Mbr.PartitionType != PARTITION_ENTRY_UNUSED)
{
if (PartNumber == ulValue)
{
CurrentPartition = PartEntry;
ConResPrintf(StdOut, IDS_SELECT_PARTITION, PartNumber);
return TRUE;
}
PartNumber++;
}
Entry = Entry->Flink;
}
}
Entry = CurrentDisk->LogicalPartListHead.Flink;
while (Entry != &CurrentDisk->LogicalPartListHead)
else if (CurrentDisk->PartitionStyle == PARTITION_STYLE_GPT)
{
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
if (PartEntry->PartitionType != 0)
Entry = CurrentDisk->PrimaryPartListHead.Flink;
while (Entry != &CurrentDisk->PrimaryPartListHead)
{
if (PartNumber == ulValue)
PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
if (!IsEqualGUID(&PartEntry->Gpt.PartitionType, &PARTITION_ENTRY_UNUSED_GUID))
{
CurrentPartition = PartEntry;
ConResPrintf(StdOut, IDS_SELECT_PARTITION, PartNumber);
return TRUE;
if (PartNumber == ulValue)
{
CurrentPartition = PartEntry;
ConResPrintf(StdOut, IDS_SELECT_PARTITION, PartNumber);
return TRUE;
}
PartNumber++;
}
PartNumber++;
Entry = Entry->Flink;
}
Entry = Entry->Flink;
}
ConResPuts(StdErr, IDS_SELECT_PARTITION_INVALID);
+19 -6
View File
@@ -17,7 +17,6 @@ setid_main(
_In_ INT argc,
_In_ PWSTR *argv)
{
UCHAR PartitionType = 0;
INT i, length;
PWSTR pszSuffix, pszId = NULL;
NTSTATUS Status;
@@ -65,11 +64,25 @@ setid_main(
if (CurrentDisk->PartitionStyle == PARTITION_STYLE_GPT)
{
ConPuts(StdErr, L"The setid command does not support GPT disks yet!\n");
return TRUE;
if (!StringToGUID(&CurrentPartition->Gpt.PartitionType, pszId))
{
ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
return TRUE;
}
CurrentDisk->Dirty = TRUE;
UpdateGptDiskLayout(CurrentDisk, FALSE);
Status = WriteGptPartitions(CurrentDisk);
if (!NT_SUCCESS(Status))
{
ConResPuts(StdOut, IDS_SETID_FAIL);
return TRUE;
}
}
else if (CurrentDisk->PartitionStyle == PARTITION_STYLE_MBR)
{
UCHAR PartitionType = 0;
length = wcslen(pszId);
if (length == 0)
{
@@ -96,10 +109,10 @@ setid_main(
return TRUE;
}
CurrentPartition->PartitionType = PartitionType;
CurrentPartition->Mbr.PartitionType = PartitionType;
CurrentDisk->Dirty = TRUE;
UpdateDiskLayout(CurrentDisk);
Status = WritePartitions(CurrentDisk);
UpdateMbrDiskLayout(CurrentDisk);
Status = WriteMbrPartitions(CurrentDisk);
if (!NT_SUCCESS(Status))
{
ConResPuts(StdOut, IDS_SETID_FAIL);
+11 -3
View File
@@ -72,7 +72,15 @@ UniqueIdDisk(
if (CurrentDisk->PartitionStyle == PARTITION_STYLE_GPT)
{
ConPuts(StdErr, L"The uniqueid disk command does not support GPT disks yet!\n");
if (!StringToGUID(&CurrentDisk->LayoutBuffer->Gpt.DiskId, pszId))
{
ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
return TRUE;
}
CurrentDisk->Dirty = TRUE;
UpdateGptDiskLayout(CurrentDisk, FALSE);
WriteGptPartitions(CurrentDisk);
}
else if (CurrentDisk->PartitionStyle == PARTITION_STYLE_MBR)
{
@@ -94,8 +102,8 @@ UniqueIdDisk(
DPRINT("New Signature: 0x%08lx\n", ulValue);
CurrentDisk->LayoutBuffer->Mbr.Signature = ulValue;
CurrentDisk->Dirty = TRUE;
UpdateDiskLayout(CurrentDisk);
WritePartitions(CurrentDisk);
UpdateMbrDiskLayout(CurrentDisk);
WriteMbrPartitions(CurrentDisk);
}
else
{