Skip to content

Commit 9201535

Browse files
committed
[DISKPART] Implement the 'convert mbr' and 'convert gpt' commands
- Show Disk UUIDs in the 'detail disk' and 'uniqueid disk' commands.
1 parent 1f3f733 commit 9201535

File tree

20 files changed

+1047
-138
lines changed

20 files changed

+1047
-138
lines changed

base/system/diskpart/convert.c

Lines changed: 178 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,184 @@
88

99
#include "diskpart.h"
1010

11-
BOOL convert_main(INT argc, LPWSTR *argv)
11+
#define NDEBUG
12+
#include <debug.h>
13+
14+
NTSTATUS
15+
CreateDisk(
16+
_In_ ULONG DiskNumber,
17+
_In_ PCREATE_DISK DiskInfo)
18+
{
19+
WCHAR DstPath[MAX_PATH];
20+
OBJECT_ATTRIBUTES ObjectAttributes;
21+
UNICODE_STRING Name;
22+
HANDLE FileHandle = NULL;
23+
IO_STATUS_BLOCK Iosb;
24+
NTSTATUS Status;
25+
26+
DPRINT1("CreateDisk(%lu %p)\n", DiskNumber, DiskInfo);
27+
28+
StringCchPrintfW(DstPath, ARRAYSIZE(DstPath),
29+
L"\\Device\\Harddisk%lu\\Partition0",
30+
CurrentDisk->DiskNumber);
31+
RtlInitUnicodeString(&Name, DstPath);
32+
33+
InitializeObjectAttributes(&ObjectAttributes,
34+
&Name,
35+
OBJ_CASE_INSENSITIVE,
36+
NULL,
37+
NULL);
38+
39+
Status = NtOpenFile(&FileHandle,
40+
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
41+
&ObjectAttributes,
42+
&Iosb,
43+
0,
44+
FILE_SYNCHRONOUS_IO_NONALERT);
45+
if (!NT_SUCCESS(Status))
46+
{
47+
DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
48+
goto done;
49+
}
50+
51+
Status = NtDeviceIoControlFile(FileHandle,
52+
NULL,
53+
NULL,
54+
NULL,
55+
&Iosb,
56+
IOCTL_DISK_CREATE_DISK,
57+
DiskInfo,
58+
sizeof(*DiskInfo),
59+
NULL,
60+
0);
61+
if (!NT_SUCCESS(Status))
62+
{
63+
DPRINT1("NtDeviceIoControlFile() failed (Status %lx)\n", Status);
64+
goto done;
65+
}
66+
67+
CurrentDisk->PartitionStyle = DiskInfo->PartitionStyle;
68+
69+
/* Free the layout buffer */
70+
if (CurrentDisk->LayoutBuffer)
71+
{
72+
RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentDisk->LayoutBuffer);
73+
CurrentDisk->LayoutBuffer = NULL;
74+
CurrentDisk->ExtendedPartition = NULL;
75+
}
76+
77+
ReadLayoutBuffer(FileHandle, CurrentDisk);
78+
79+
DPRINT1("PartitionCount: %lu\n", CurrentDisk->LayoutBuffer->PartitionCount);
80+
81+
#ifdef DUMP_PARTITION_TABLE
82+
DumpPartitionTable(CurrentDisk);
83+
#endif
84+
85+
done:
86+
if (FileHandle)
87+
NtClose(FileHandle);
88+
89+
return Status;
90+
}
91+
92+
93+
BOOL
94+
ConvertGPT(
95+
_In_ INT argc,
96+
_In_ PWSTR *argv)
1297
{
98+
CREATE_DISK DiskInfo;
99+
NTSTATUS Status;
100+
101+
DPRINT("ConvertGPT()\n");
102+
103+
if (CurrentDisk == NULL)
104+
{
105+
ConResPuts(StdOut, IDS_SELECT_NO_DISK);
106+
return TRUE;
107+
}
108+
109+
if (CurrentDisk->PartitionStyle == PARTITION_STYLE_GPT)
110+
{
111+
ConResPuts(StdOut, IDS_CONVERT_GPT_ALREADY);
112+
return TRUE;
113+
}
114+
115+
if (CurrentDisk->LayoutBuffer->PartitionCount != 0)
116+
{
117+
ConResPuts(StdOut, IDS_CONVERT_GPT_NOT_EMPTY);
118+
return TRUE;
119+
}
120+
121+
#if 0
122+
/* Fail if disk size is less than 128MB */
123+
if (CurrentDisk->SectorCount.QuadPart * CurrentDisk->BytesPerSector < 128ULL * 1024ULL * 1024ULL)
124+
{
125+
ConResPuts(StdOut, IDS_CONVERT_GPT_TOO_SMALL);
126+
return TRUE;
127+
}
128+
#endif
129+
130+
DiskInfo.PartitionStyle = PARTITION_STYLE_GPT;
131+
CreateGUID(&DiskInfo.Gpt.DiskId);
132+
DiskInfo.Gpt.MaxPartitionCount = 128;
133+
134+
Status = CreateDisk(CurrentDisk->DiskNumber, &DiskInfo);
135+
if (!NT_SUCCESS(Status))
136+
{
137+
138+
}
139+
else
140+
{
141+
ConResPuts(StdOut, IDS_CONVERT_GPT_SUCCESS);
142+
}
143+
144+
return TRUE;
145+
}
146+
147+
148+
BOOL
149+
ConvertMBR(
150+
_In_ INT argc,
151+
_In_ PWSTR *argv)
152+
{
153+
CREATE_DISK DiskInfo;
154+
NTSTATUS Status;
155+
156+
DPRINT("ConvertMBR()\n");
157+
158+
if (CurrentDisk == NULL)
159+
{
160+
ConResPuts(StdOut, IDS_SELECT_NO_DISK);
161+
return TRUE;
162+
}
163+
164+
if ((CurrentDisk->PartitionStyle == PARTITION_STYLE_MBR) ||
165+
(CurrentDisk->PartitionStyle == PARTITION_STYLE_RAW))
166+
{
167+
ConResPuts(StdOut, IDS_CONVERT_MBR_ALREADY);
168+
return TRUE;
169+
}
170+
171+
if (CurrentDisk->LayoutBuffer->PartitionCount != 0)
172+
{
173+
ConResPuts(StdOut, IDS_CONVERT_MBR_NOT_EMPTY);
174+
return TRUE;
175+
}
176+
177+
DiskInfo.PartitionStyle = PARTITION_STYLE_MBR;
178+
CreateSignature(&DiskInfo.Mbr.Signature);
179+
180+
Status = CreateDisk(CurrentDisk->DiskNumber, &DiskInfo);
181+
if (!NT_SUCCESS(Status))
182+
{
183+
184+
}
185+
else
186+
{
187+
ConResPuts(StdOut, IDS_CONVERT_MBR_SUCCESS);
188+
}
189+
13190
return TRUE;
14191
}

base/system/diskpart/detail.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ DetailDisk(
7272
PLIST_ENTRY Entry;
7373
PVOLENTRY VolumeEntry;
7474
BOOL bPrintHeader = TRUE;
75+
WCHAR szBuffer[40];
7576

7677
DPRINT("DetailDisk()\n");
7778

@@ -89,7 +90,13 @@ DetailDisk(
8990

9091
/* TODO: Print more disk details */
9192
ConPuts(StdOut, L"\n");
92-
ConResPrintf(StdOut, IDS_DETAIL_INFO_DISK_ID, CurrentDisk->LayoutBuffer->Mbr.Signature);
93+
if (CurrentDisk->LayoutBuffer->PartitionStyle == PARTITION_STYLE_GPT)
94+
PrintGUID(szBuffer, &CurrentDisk->LayoutBuffer->Gpt.DiskId);
95+
else if (CurrentDisk->LayoutBuffer->PartitionStyle == PARTITION_STYLE_MBR)
96+
swprintf(szBuffer, L"%08lx", CurrentDisk->LayoutBuffer->Mbr.Signature);
97+
else
98+
wcscpy(szBuffer, L"00000000");
99+
ConResPrintf(StdOut, IDS_DETAIL_INFO_DISK_ID, szBuffer);
93100
ConResPrintf(StdOut, IDS_DETAIL_INFO_PATH, CurrentDisk->PathId);
94101
ConResPrintf(StdOut, IDS_DETAIL_INFO_TARGET, CurrentDisk->TargetId);
95102
ConResPrintf(StdOut, IDS_DETAIL_INFO_LUN_ID, CurrentDisk->Lun);

base/system/diskpart/diskpart.h

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <winreg.h>
2121
#include <wincon.h>
2222
#include <winioctl.h>
23+
#include <ntsecapi.h>
2324

2425
#include <errno.h>
2526
#include <strsafe.h>
@@ -52,6 +53,8 @@
5253

5354
#include "resource.h"
5455

56+
//#define DUMP_PARTITION_TABLE
57+
5558
/* DEFINES *******************************************************************/
5659

5760
typedef struct _COMMAND
@@ -246,7 +249,20 @@ BOOL clean_main(INT argc, LPWSTR *argv);
246249
BOOL compact_main(INT argc, LPWSTR *argv);
247250

248251
/* convert.c */
249-
BOOL convert_main(INT argc, LPWSTR *argv);
252+
NTSTATUS
253+
CreateDisk(
254+
_In_ ULONG DiskNumber,
255+
_In_ PCREATE_DISK DiskInfo);
256+
257+
BOOL
258+
ConvertGPT(
259+
_In_ INT argc,
260+
_In_ PWSTR *argv);
261+
262+
BOOL
263+
ConvertMBR(
264+
_In_ INT argc,
265+
_In_ PWSTR *argv);
250266

251267
/* create.c */
252268
BOOL
@@ -405,13 +421,32 @@ PWSTR
405421
DuplicateString(
406422
_In_ PWSTR pszInString);
407423

424+
VOID
425+
CreateGUID(
426+
_Out_ GUID *pGuid);
427+
428+
VOID
429+
CreateSignature(
430+
_Out_ PDWORD pSignature);
431+
432+
VOID
433+
PrintGUID(
434+
_Out_ PWSTR pszBuffer,
435+
_In_ GUID *pGuid);
436+
408437
/* offline.c */
409438
BOOL offline_main(INT argc, LPWSTR *argv);
410439

411440
/* online.c */
412441
BOOL online_main(INT argc, LPWSTR *argv);
413442

414443
/* partlist.c */
444+
#ifdef DUMP_PARTITION_TABLE
445+
VOID
446+
DumpPartitionTable(
447+
_In_ PDISKENTRY DiskEntry);
448+
#endif
449+
415450
ULONGLONG
416451
AlignDown(
417452
_In_ ULONGLONG Value,
@@ -429,6 +464,11 @@ CreateVolumeList(VOID);
429464
VOID
430465
DestroyVolumeList(VOID);
431466

467+
VOID
468+
ReadLayoutBuffer(
469+
_In_ HANDLE FileHandle,
470+
_In_ PDISKENTRY DiskEntry);
471+
432472
NTSTATUS
433473
WritePartitions(
434474
_In_ PDISKENTRY DiskEntry);

0 commit comments

Comments
 (0)