Skip to content

Commit bf8741d

Browse files
committed
[DISKPART] Implement the 'create partition efi' and 'create partition msr' commands
1 parent 74999e6 commit bf8741d

4 files changed

Lines changed: 1029 additions & 22 deletions

File tree

base/system/diskpart/create.c

Lines changed: 380 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,196 @@
1212
#include <debug.h>
1313

1414

15+
BOOL
16+
CreateEfiPartition(
17+
_In_ INT argc,
18+
_In_ PWSTR *argv)
19+
{
20+
PPARTENTRY PartEntry, NewPartEntry;
21+
PLIST_ENTRY ListEntry;
22+
ULONGLONG ullSize = 0ULL;
23+
ULONGLONG ullSectorCount;
24+
#if 0
25+
ULONGLONG ullOffset = 0ULL;
26+
BOOL bNoErr = FALSE;
27+
#endif
28+
INT i;
29+
PWSTR pszSuffix = NULL;
30+
NTSTATUS Status;
31+
32+
DPRINT1("CreateEfiPartition()\n");
33+
34+
if (CurrentDisk == NULL)
35+
{
36+
ConResPuts(StdOut, IDS_SELECT_NO_DISK);
37+
return TRUE;
38+
}
39+
40+
if (CurrentDisk->PartitionStyle != PARTITION_STYLE_GPT)
41+
{
42+
ConResPuts(StdOut, IDS_CREATE_PARTITION_INVALID_STYLE);
43+
return TRUE;
44+
}
45+
46+
for (i = 3; i < argc; i++)
47+
{
48+
if (HasPrefix(argv[i], L"size=", &pszSuffix))
49+
{
50+
/* size=<N> (MB) */
51+
DPRINT("Size : %s\n", pszSuffix);
52+
53+
ullSize = _wcstoui64(pszSuffix, NULL, 10);
54+
if ((ullSize == 0) && (errno == ERANGE))
55+
{
56+
ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
57+
return TRUE;
58+
}
59+
}
60+
else if (HasPrefix(argv[i], L"offset=", &pszSuffix))
61+
{
62+
/* offset=<N> (KB) */
63+
DPRINT("Offset : %s\n", pszSuffix);
64+
ConPuts(StdOut, L"The OFFSET option is not supported yet!\n");
65+
#if 0
66+
ullOffset = _wcstoui64(pszSuffix, NULL, 10);
67+
if ((ullOffset == 0) && (errno == ERANGE))
68+
{
69+
ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
70+
return TRUE;
71+
}
72+
#endif
73+
}
74+
else if (_wcsicmp(argv[i], L"noerr") == 0)
75+
{
76+
/* noerr */
77+
DPRINT("NoErr\n", pszSuffix);
78+
ConPuts(StdOut, L"The NOERR option is not supported yet!\n");
79+
#if 0
80+
bNoErr = TRUE;
81+
#endif
82+
}
83+
else
84+
{
85+
ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
86+
return TRUE;
87+
}
88+
}
89+
90+
DPRINT1("Size: %I64u\n", ullSize);
91+
#if 0
92+
DPRINT1("Offset: %I64u\n", ullOffset);
93+
#endif
94+
95+
/* Size */
96+
if (ullSize != 0)
97+
ullSectorCount = (ullSize * 1024 * 1024) / CurrentDisk->BytesPerSector;
98+
else
99+
ullSectorCount = 0;
100+
101+
DPRINT1("SectorCount: %I64u\n", ullSectorCount);
102+
103+
#ifdef DUMP_PARTITION_LIST
104+
DumpPartitionList(CurrentDisk);
105+
#endif
106+
107+
for (ListEntry = CurrentDisk->PrimaryPartListHead.Flink;
108+
ListEntry != &CurrentDisk->PrimaryPartListHead;
109+
ListEntry = ListEntry->Flink)
110+
{
111+
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
112+
if (PartEntry->IsPartitioned)
113+
continue;
114+
115+
if (ullSectorCount == 0)
116+
{
117+
DPRINT("Claim whole unused space!\n");
118+
PartEntry->IsPartitioned = TRUE;
119+
PartEntry->New = TRUE;
120+
CopyMemory(&PartEntry->Gpt.PartitionType, &PARTITION_SYSTEM_GUID, sizeof(GUID));
121+
CreateGUID(&PartEntry->Gpt.PartitionId);
122+
PartEntry->Gpt.Attributes = 0ULL;
123+
PartEntry->PartitionNumber = 0;
124+
PartEntry->FormatState = Unformatted;
125+
PartEntry->FileSystemName[0] = L'\0';
126+
127+
CurrentPartition = PartEntry;
128+
CurrentDisk->Dirty = TRUE;
129+
break;
130+
}
131+
else
132+
{
133+
if (ullSectorCount == PartEntry->SectorCount.QuadPart)
134+
{
135+
DPRINT("Claim matching unused space!\n");
136+
PartEntry->IsPartitioned = TRUE;
137+
PartEntry->New = TRUE;
138+
CopyMemory(&PartEntry->Gpt.PartitionType, &PARTITION_SYSTEM_GUID, sizeof(GUID));
139+
CreateGUID(&PartEntry->Gpt.PartitionId);
140+
PartEntry->Gpt.Attributes = 0ULL;
141+
PartEntry->PartitionNumber = 0;
142+
PartEntry->FormatState = Unformatted;
143+
PartEntry->FileSystemName[0] = L'\0';
144+
145+
CurrentPartition = PartEntry;
146+
CurrentDisk->Dirty = TRUE;
147+
break;
148+
}
149+
else if (ullSectorCount < PartEntry->SectorCount.QuadPart)
150+
{
151+
DPRINT("Claim part of unused space\n");
152+
NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PPARTENTRY));
153+
if (NewPartEntry == NULL)
154+
{
155+
ConPuts(StdOut, L"Memory allocation failed!\n");
156+
return TRUE;
157+
}
158+
159+
NewPartEntry->DiskEntry = PartEntry->DiskEntry;
160+
161+
NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
162+
NewPartEntry->SectorCount.QuadPart = ullSectorCount;
163+
164+
NewPartEntry->LogicalPartition = FALSE;
165+
NewPartEntry->IsPartitioned = TRUE;
166+
NewPartEntry->New = TRUE;
167+
CopyMemory(&NewPartEntry->Gpt.PartitionType, &PARTITION_SYSTEM_GUID, sizeof(GUID));
168+
CreateGUID(&NewPartEntry->Gpt.PartitionId);
169+
NewPartEntry->Gpt.Attributes = 0ULL;
170+
NewPartEntry->PartitionNumber = 0;
171+
NewPartEntry->FormatState = Unformatted;
172+
NewPartEntry->FileSystemName[0] = L'\0';
173+
174+
PartEntry->StartSector.QuadPart += ullSectorCount;
175+
PartEntry->SectorCount.QuadPart -= ullSectorCount;
176+
177+
InsertTailList(ListEntry, &NewPartEntry->ListEntry);
178+
179+
CurrentPartition = NewPartEntry;
180+
CurrentDisk->Dirty = TRUE;
181+
break;
182+
}
183+
}
184+
}
185+
186+
#ifdef DUMP_PARTITION_LIST
187+
DumpPartitionList(CurrentDisk);
188+
#endif
189+
190+
UpdateGptDiskLayout(CurrentDisk, FALSE);
191+
Status = WriteGptPartitions(CurrentDisk);
192+
if (!NT_SUCCESS(Status))
193+
{
194+
ConResPuts(StdOut, IDS_CREATE_PARTITION_FAIL);
195+
CurrentPartition = NULL;
196+
return TRUE;
197+
}
198+
199+
ConResPuts(StdOut, IDS_CREATE_PARTITION_SUCCESS);
200+
201+
return TRUE;
202+
}
203+
204+
15205
BOOL
16206
CreateExtendedPartition(
17207
_In_ INT argc,
@@ -417,6 +607,196 @@ CreateLogicalPartition(
417607
}
418608

419609

610+
BOOL
611+
CreateMsrPartition(
612+
_In_ INT argc,
613+
_In_ PWSTR *argv)
614+
{
615+
PPARTENTRY PartEntry, NewPartEntry;
616+
PLIST_ENTRY ListEntry;
617+
ULONGLONG ullSize = 0ULL;
618+
ULONGLONG ullSectorCount;
619+
#if 0
620+
ULONGLONG ullOffset = 0ULL;
621+
BOOL bNoErr = FALSE;
622+
#endif
623+
INT i;
624+
PWSTR pszSuffix = NULL;
625+
NTSTATUS Status;
626+
627+
DPRINT1("CreateMsrPartition()\n");
628+
629+
if (CurrentDisk == NULL)
630+
{
631+
ConResPuts(StdOut, IDS_SELECT_NO_DISK);
632+
return TRUE;
633+
}
634+
635+
if (CurrentDisk->PartitionStyle != PARTITION_STYLE_GPT)
636+
{
637+
ConResPuts(StdOut, IDS_CREATE_PARTITION_INVALID_STYLE);
638+
return TRUE;
639+
}
640+
641+
for (i = 3; i < argc; i++)
642+
{
643+
if (HasPrefix(argv[i], L"size=", &pszSuffix))
644+
{
645+
/* size=<N> (MB) */
646+
DPRINT("Size : %s\n", pszSuffix);
647+
648+
ullSize = _wcstoui64(pszSuffix, NULL, 10);
649+
if ((ullSize == 0) && (errno == ERANGE))
650+
{
651+
ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
652+
return TRUE;
653+
}
654+
}
655+
else if (HasPrefix(argv[i], L"offset=", &pszSuffix))
656+
{
657+
/* offset=<N> (KB) */
658+
DPRINT("Offset : %s\n", pszSuffix);
659+
ConPuts(StdOut, L"The OFFSET option is not supported yet!\n");
660+
#if 0
661+
ullOffset = _wcstoui64(pszSuffix, NULL, 10);
662+
if ((ullOffset == 0) && (errno == ERANGE))
663+
{
664+
ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
665+
return TRUE;
666+
}
667+
#endif
668+
}
669+
else if (_wcsicmp(argv[i], L"noerr") == 0)
670+
{
671+
/* noerr */
672+
DPRINT("NoErr\n", pszSuffix);
673+
ConPuts(StdOut, L"The NOERR option is not supported yet!\n");
674+
#if 0
675+
bNoErr = TRUE;
676+
#endif
677+
}
678+
else
679+
{
680+
ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
681+
return TRUE;
682+
}
683+
}
684+
685+
DPRINT1("Size: %I64u\n", ullSize);
686+
#if 0
687+
DPRINT1("Offset: %I64u\n", ullOffset);
688+
#endif
689+
690+
/* Size */
691+
if (ullSize != 0)
692+
ullSectorCount = (ullSize * 1024 * 1024) / CurrentDisk->BytesPerSector;
693+
else
694+
ullSectorCount = 0;
695+
696+
DPRINT1("SectorCount: %I64u\n", ullSectorCount);
697+
698+
#ifdef DUMP_PARTITION_LIST
699+
DumpPartitionList(CurrentDisk);
700+
#endif
701+
702+
for (ListEntry = CurrentDisk->PrimaryPartListHead.Flink;
703+
ListEntry != &CurrentDisk->PrimaryPartListHead;
704+
ListEntry = ListEntry->Flink)
705+
{
706+
PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
707+
if (PartEntry->IsPartitioned)
708+
continue;
709+
710+
if (ullSectorCount == 0)
711+
{
712+
DPRINT("Claim whole unused space!\n");
713+
PartEntry->IsPartitioned = TRUE;
714+
PartEntry->New = TRUE;
715+
CopyMemory(&PartEntry->Gpt.PartitionType, &PARTITION_MSFT_RESERVED_GUID, sizeof(GUID));
716+
CreateGUID(&PartEntry->Gpt.PartitionId);
717+
PartEntry->Gpt.Attributes = 0ULL;
718+
PartEntry->PartitionNumber = 0;
719+
PartEntry->FormatState = Unformatted;
720+
PartEntry->FileSystemName[0] = L'\0';
721+
722+
CurrentPartition = PartEntry;
723+
CurrentDisk->Dirty = TRUE;
724+
break;
725+
}
726+
else
727+
{
728+
if (ullSectorCount == PartEntry->SectorCount.QuadPart)
729+
{
730+
DPRINT("Claim matching unused space!\n");
731+
PartEntry->IsPartitioned = TRUE;
732+
PartEntry->New = TRUE;
733+
CopyMemory(&PartEntry->Gpt.PartitionType, &PARTITION_MSFT_RESERVED_GUID, sizeof(GUID));
734+
CreateGUID(&PartEntry->Gpt.PartitionId);
735+
PartEntry->Gpt.Attributes = 0ULL;
736+
PartEntry->PartitionNumber = 0;
737+
PartEntry->FormatState = Unformatted;
738+
PartEntry->FileSystemName[0] = L'\0';
739+
740+
CurrentPartition = PartEntry;
741+
CurrentDisk->Dirty = TRUE;
742+
break;
743+
}
744+
else if (ullSectorCount < PartEntry->SectorCount.QuadPart)
745+
{
746+
DPRINT("Claim part of unused space\n");
747+
NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PPARTENTRY));
748+
if (NewPartEntry == NULL)
749+
{
750+
ConPuts(StdOut, L"Memory allocation failed!\n");
751+
return TRUE;
752+
}
753+
754+
NewPartEntry->DiskEntry = PartEntry->DiskEntry;
755+
756+
NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
757+
NewPartEntry->SectorCount.QuadPart = ullSectorCount;
758+
759+
NewPartEntry->LogicalPartition = FALSE;
760+
NewPartEntry->IsPartitioned = TRUE;
761+
NewPartEntry->New = TRUE;
762+
CopyMemory(&NewPartEntry->Gpt.PartitionType, &PARTITION_MSFT_RESERVED_GUID, sizeof(GUID));
763+
CreateGUID(&NewPartEntry->Gpt.PartitionId);
764+
NewPartEntry->Gpt.Attributes = 0ULL;
765+
NewPartEntry->PartitionNumber = 0;
766+
NewPartEntry->FormatState = Unformatted;
767+
NewPartEntry->FileSystemName[0] = L'\0';
768+
769+
PartEntry->StartSector.QuadPart += ullSectorCount;
770+
PartEntry->SectorCount.QuadPart -= ullSectorCount;
771+
772+
InsertTailList(ListEntry, &NewPartEntry->ListEntry);
773+
774+
CurrentPartition = NewPartEntry;
775+
CurrentDisk->Dirty = TRUE;
776+
break;
777+
}
778+
}
779+
}
780+
781+
#ifdef DUMP_PARTITION_LIST
782+
DumpPartitionList(CurrentDisk);
783+
#endif
784+
785+
UpdateGptDiskLayout(CurrentDisk, FALSE);
786+
Status = WriteGptPartitions(CurrentDisk);
787+
if (!NT_SUCCESS(Status))
788+
{
789+
ConResPuts(StdOut, IDS_CREATE_PARTITION_FAIL);
790+
CurrentPartition = NULL;
791+
return TRUE;
792+
}
793+
794+
ConResPuts(StdOut, IDS_CREATE_PARTITION_SUCCESS);
795+
796+
return TRUE;
797+
}
798+
799+
420800
static
421801
VOID
422802
CreatePrimaryMbrPartition(

0 commit comments

Comments
 (0)