mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-26 19:33:31 +00:00
[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:
@@ -24,6 +24,7 @@ list(APPEND SOURCE
|
||||
filesystems.c
|
||||
format.c
|
||||
gpt.c
|
||||
guid.c
|
||||
help.c
|
||||
import.c
|
||||
inactive.c
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
#define INITGUID
|
||||
#include <guiddef.h>
|
||||
|
||||
#include "guid.h"
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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");
|
||||
|
||||
@@ -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
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user