ReactOS 0.4.16-dev-2104-gb84fa49
create.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS DiskPart
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/system/diskpart/create.c
5 * PURPOSE: Manages all the partitions of the OS in an interactive way.
6 * PROGRAMMERS: Lee Schroeder
7 */
8
9#include "diskpart.h"
10
11#define NDEBUG
12#include <debug.h>
13
14
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;
31
32 DPRINT1("CreateEfiPartition()\n");
33
34 if (CurrentDisk == NULL)
35 {
37 return EXIT_SUCCESS;
38 }
39
41 {
43 return EXIT_SUCCESS;
44 }
45
46 for (i = 3; i < argc; i++)
47 {
48 if (_wcsicmp(argv[i], L"noerr") == 0)
49 {
50 /* noerr */
51 DPRINT("NoErr\n", pszSuffix);
52 ConPuts(StdOut, L"The NOERR option is not supported yet!\n");
53#if 0
54 bNoErr = TRUE;
55#endif
56 }
57 }
58
59 for (i = 3; i < argc; i++)
60 {
61 if (HasPrefix(argv[i], L"size=", &pszSuffix))
62 {
63 /* size=<N> (MB) */
64 DPRINT("Size : %s\n", pszSuffix);
65
66 ullSize = _wcstoui64(pszSuffix, NULL, 10);
67 if ((ullSize == 0) && (errno == ERANGE))
68 {
70 return EXIT_SUCCESS;
71 }
72 }
73 else if (HasPrefix(argv[i], L"offset=", &pszSuffix))
74 {
75 /* offset=<N> (KB) */
76 DPRINT("Offset : %s\n", pszSuffix);
77 ConPuts(StdOut, L"The OFFSET option is not supported yet!\n");
78#if 0
79 ullOffset = _wcstoui64(pszSuffix, NULL, 10);
80 if ((ullOffset == 0) && (errno == ERANGE))
81 {
83 return TRUE;
84 }
85#endif
86 }
87 else if (_wcsicmp(argv[i], L"noerr") == 0)
88 {
89 /* noerr - Already handled above */
90 }
91 else
92 {
94 return EXIT_SUCCESS;
95 }
96 }
97
98 DPRINT1("Size: %I64u\n", ullSize);
99#if 0
100 DPRINT1("Offset: %I64u\n", ullOffset);
101#endif
102
103 /* Size */
104 if (ullSize != 0)
105 ullSectorCount = (ullSize * 1024 * 1024) / CurrentDisk->BytesPerSector;
106 else
107 ullSectorCount = 0;
108
109 DPRINT1("SectorCount: %I64u\n", ullSectorCount);
110
111#ifdef DUMP_PARTITION_LIST
112 DumpPartitionList(CurrentDisk);
113#endif
114
115 for (ListEntry = CurrentDisk->PrimaryPartListHead.Flink;
116 ListEntry != &CurrentDisk->PrimaryPartListHead;
117 ListEntry = ListEntry->Flink)
118 {
119 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
120 if (PartEntry->IsPartitioned)
121 continue;
122
123 if (ullSectorCount == 0)
124 {
125 DPRINT("Claim whole unused space!\n");
126 PartEntry->IsPartitioned = TRUE;
127 PartEntry->New = TRUE;
128 CopyMemory(&PartEntry->Gpt.PartitionType, &PARTITION_SYSTEM_GUID, sizeof(GUID));
129 CreateGUID(&PartEntry->Gpt.PartitionId);
130 PartEntry->Gpt.Attributes = 0ULL;
131 PartEntry->PartitionNumber = 0;
132 PartEntry->FormatState = Unformatted;
133 PartEntry->FileSystemName[0] = L'\0';
134
135 CurrentPartition = PartEntry;
137 break;
138 }
139 else
140 {
141 if (ullSectorCount == PartEntry->SectorCount.QuadPart)
142 {
143 DPRINT("Claim matching unused space!\n");
144 PartEntry->IsPartitioned = TRUE;
145 PartEntry->New = TRUE;
146 CopyMemory(&PartEntry->Gpt.PartitionType, &PARTITION_SYSTEM_GUID, sizeof(GUID));
147 CreateGUID(&PartEntry->Gpt.PartitionId);
148 PartEntry->Gpt.Attributes = 0ULL;
149 PartEntry->PartitionNumber = 0;
150 PartEntry->FormatState = Unformatted;
151 PartEntry->FileSystemName[0] = L'\0';
152
153 CurrentPartition = PartEntry;
155 break;
156 }
157 else if (ullSectorCount < PartEntry->SectorCount.QuadPart)
158 {
159 DPRINT("Claim part of unused space\n");
160 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PPARTENTRY));
161 if (NewPartEntry == NULL)
162 {
163 ConPuts(StdOut, L"Memory allocation failed!\n");
164 return TRUE;
165 }
166
167 NewPartEntry->DiskEntry = PartEntry->DiskEntry;
168
169 NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
170 NewPartEntry->SectorCount.QuadPart = ullSectorCount;
171
172 NewPartEntry->LogicalPartition = FALSE;
173 NewPartEntry->IsPartitioned = TRUE;
174 NewPartEntry->New = TRUE;
175 CopyMemory(&NewPartEntry->Gpt.PartitionType, &PARTITION_SYSTEM_GUID, sizeof(GUID));
176 CreateGUID(&NewPartEntry->Gpt.PartitionId);
177 NewPartEntry->Gpt.Attributes = 0ULL;
178 NewPartEntry->PartitionNumber = 0;
179 NewPartEntry->FormatState = Unformatted;
180 NewPartEntry->FileSystemName[0] = L'\0';
181
182 PartEntry->StartSector.QuadPart += ullSectorCount;
183 PartEntry->SectorCount.QuadPart -= ullSectorCount;
184
185 InsertTailList(ListEntry, &NewPartEntry->ListEntry);
186
187 CurrentPartition = NewPartEntry;
189 break;
190 }
191 }
192 }
193
194#ifdef DUMP_PARTITION_LIST
195 DumpPartitionList(CurrentDisk);
196#endif
197
200 if (!NT_SUCCESS(Status))
201 {
204 return EXIT_SUCCESS;
205 }
206
208
209 return EXIT_SUCCESS;
210}
211
212
215 _In_ INT argc,
216 _In_ PWSTR *argv)
217{
218 PPARTENTRY PartEntry, NewPartEntry;
219 PLIST_ENTRY ListEntry;
220 ULONGLONG ullSize = 0ULL;
221 ULONGLONG ullSectorCount;
222#if 0
223 ULONGLONG ullOffset = 0ULL;
224 BOOL bNoErr = FALSE;
225#endif
226 INT i;
227 PWSTR pszSuffix = NULL;
229
230 if (CurrentDisk == NULL)
231 {
233 return EXIT_SUCCESS;
234 }
235
237 {
239 return EXIT_SUCCESS;
240 }
241 else if (CurrentDisk->PartitionStyle == PARTITION_STYLE_RAW)
242 {
243 CREATE_DISK DiskInfo;
245
246 DiskInfo.PartitionStyle = PARTITION_STYLE_MBR;
247 CreateSignature(&DiskInfo.Mbr.Signature);
248
250 if (!NT_SUCCESS(Status))
251 {
252 DPRINT1("CreateDisk() failed!\n");
253 return EXIT_SUCCESS;
254 }
255
258
260 }
261
262 for (i = 3; i < argc; i++)
263 {
264 if (_wcsicmp(argv[i], L"noerr") == 0)
265 {
266 /* noerr */
267 DPRINT("NoErr\n", pszSuffix);
268 ConPuts(StdOut, L"The NOERR option is not supported yet!\n");
269#if 0
270 bNoErr = TRUE;
271#endif
272 }
273 }
274
275 for (i = 3; i < argc; i++)
276 {
277 if (HasPrefix(argv[i], L"size=", &pszSuffix))
278 {
279 /* size=<N> (MB) */
280 DPRINT("Size : %s\n", pszSuffix);
281
282 ullSize = _wcstoui64(pszSuffix, NULL, 10);
283 if ((ullSize == 0) && (errno == ERANGE))
284 {
286 return EXIT_SUCCESS;
287 }
288 }
289 else if (HasPrefix(argv[i], L"offset=", &pszSuffix))
290 {
291 /* offset=<N> (KB) */
292 DPRINT("Offset : %s\n", pszSuffix);
293 ConPuts(StdOut, L"The OFFSET option is not supported yet!\n");
294#if 0
295 ullOffset = _wcstoui64(pszSuffix, NULL, 10);
296 if ((ullOffset == 0) && (errno == ERANGE))
297 {
299 return EXIT_SUCCESS;
300 }
301#endif
302 }
303 else if (HasPrefix(argv[i], L"align=", &pszSuffix))
304 {
305 /* align=<N> */
306 DPRINT("Align : %s\n", pszSuffix);
307 ConPuts(StdOut, L"The ALIGN option is not supported yet!\n");
308#if 0
309 bAlign = TRUE;
310#endif
311 }
312 else if (_wcsicmp(argv[i], L"noerr") == 0)
313 {
314 /* noerr - Already handled above */
315 }
316 else
317 {
319 return EXIT_SUCCESS;
320 }
321 }
322
323 DPRINT1("Size: %I64u\n", ullSize);
324#if 0
325 DPRINT1("Offset: %I64u\n", ullOffset);
326#endif
327
329 {
330 ConPuts(StdOut, L"No space left for an extended partition!\n");
331 return EXIT_SUCCESS;
332 }
333
335 {
336 ConPuts(StdOut, L"We already have an extended partition on this disk!\n");
337 return EXIT_SUCCESS;
338 }
339
340 if (ullSize != 0)
341 ullSectorCount = (ullSize * 1024 * 1024) / CurrentDisk->BytesPerSector;
342 else
343 ullSectorCount = 0;
344
345 DPRINT1("SectorCount: %I64u\n", ullSectorCount);
346
348
349 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
350 if (PartEntry->IsPartitioned)
351 {
352 ConPuts(StdOut, L"No disk space left for an extended partition!\n");
353 return EXIT_SUCCESS;
354 }
355
356 if (ullSectorCount == 0)
357 {
358 PartEntry->IsPartitioned = TRUE;
359 PartEntry->New = TRUE;
361 PartEntry->FormatState = Unformatted;
362 PartEntry->FileSystemName[0] = L'\0';
363
364 CurrentPartition = PartEntry;
366 }
367 else
368 {
369 if (PartEntry->SectorCount.QuadPart == ullSectorCount)
370 {
371 PartEntry->IsPartitioned = TRUE;
372 PartEntry->New = TRUE;
374 PartEntry->FormatState = Unformatted;
375 PartEntry->FileSystemName[0] = L'\0';
376
377 CurrentPartition = PartEntry;
379 }
380 else if (PartEntry->SectorCount.QuadPart > ullSectorCount)
381 {
382 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PPARTENTRY));
383 if (NewPartEntry == NULL)
384 {
385 ConPuts(StdOut, L"Memory allocation failed!\n");
386 return TRUE;
387 }
388
389 NewPartEntry->DiskEntry = PartEntry->DiskEntry;
390
391 NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
392 NewPartEntry->SectorCount.QuadPart = ullSectorCount;
393
394 NewPartEntry->LogicalPartition = FALSE;
395 NewPartEntry->IsPartitioned = TRUE;
396 NewPartEntry->New = TRUE;
397 NewPartEntry->Mbr.PartitionType = PARTITION_EXTENDED;
398 NewPartEntry->FormatState = Unformatted;
399 NewPartEntry->FileSystemName[0] = L'\0';
400
401 PartEntry->StartSector.QuadPart += ullSectorCount;
402 PartEntry->SectorCount.QuadPart -= ullSectorCount;
403
404 InsertTailList(ListEntry, &NewPartEntry->ListEntry);
405
406 CurrentPartition = NewPartEntry;
408 }
409 }
410
413 if (!NT_SUCCESS(Status))
414 {
417 return EXIT_SUCCESS;
418 }
419
421
422 return EXIT_SUCCESS;
423}
424
425
428 _In_ INT argc,
429 _In_ PWSTR *argv)
430{
431 PPARTENTRY PartEntry, NewPartEntry;
432 PLIST_ENTRY ListEntry;
433 ULONGLONG ullSize = 0ULL;
434 ULONGLONG ullSectorCount;
435#if 0
436 ULONGLONG ullOffset = 0ULL;
437 BOOL bNoErr = FALSE;
438#endif
440 INT i, length;
441 PWSTR pszSuffix = NULL;
443
444 if (CurrentDisk == NULL)
445 {
447 return EXIT_SUCCESS;
448 }
449
451 {
453 return EXIT_SUCCESS;
454 }
455
456 for (i = 3; i < argc; i++)
457 {
458 if (_wcsicmp(argv[i], L"noerr") == 0)
459 {
460 /* noerr */
461 DPRINT("NoErr\n", pszSuffix);
462 ConPuts(StdOut, L"The NOERR option is not supported yet!\n");
463#if 0
464 bNoErr = TRUE;
465#endif
466 }
467 }
468
469 for (i = 3; i < argc; i++)
470 {
471 if (HasPrefix(argv[i], L"size=", &pszSuffix))
472 {
473 /* size=<N> (MB) */
474 DPRINT("Size : %s\n", pszSuffix);
475
476 ullSize = _wcstoui64(pszSuffix, NULL, 10);
477 if ((ullSize == 0) && (errno == ERANGE))
478 {
480 return EXIT_SUCCESS;
481 }
482 }
483 else if (HasPrefix(argv[i], L"offset=", &pszSuffix))
484 {
485 /* offset=<N> (KB) */
486 DPRINT("Offset : %s\n", pszSuffix);
487 ConPuts(StdOut, L"The OFFSET option is not supported yet!\n");
488#if 0
489 ullOffset = _wcstoui64(pszSuffix, NULL, 10);
490 if ((ullOffset == 0) && (errno == ERANGE))
491 {
493 return EXIT_SUCCESS;
494 }
495#endif
496 }
497 else if (HasPrefix(argv[i], L"id=", &pszSuffix))
498 {
499 /* id=<Byte> */
500 DPRINT("Id : %s\n", pszSuffix);
501
502 length = wcslen(pszSuffix);
503 if ((length == 1) || (length == 2))
504 {
505 /* Byte */
506 PartitionType = (UCHAR)wcstoul(pszSuffix, NULL, 16);
507 if ((PartitionType == 0) && (errno == ERANGE))
508 {
510 return EXIT_SUCCESS;
511 }
512 }
513 else
514 {
516 return EXIT_SUCCESS;
517 }
518 }
519 else if (HasPrefix(argv[i], L"align=", &pszSuffix))
520 {
521 /* align=<N> */
522 DPRINT("Align : %s\n", pszSuffix);
523 ConPuts(StdOut, L"The ALIGN option is not supported yet!\n");
524#if 0
525 bAlign = TRUE;
526#endif
527 }
528 else if (_wcsicmp(argv[i], L"noerr") == 0)
529 {
530 /* noerr - Already handled above */
531 }
532 else
533 {
535 return EXIT_SUCCESS;
536 }
537 }
538
539 DPRINT1("Size: %I64u\n", ullSize);
540#if 0
541 DPRINT1("Offset: %I64u\n", ullOffset);
542#endif
543 DPRINT1("Partition Type: %hx\n", PartitionType);
544
545 if (ullSize != 0)
546 ullSectorCount = (ullSize * 1024 * 1024) / CurrentDisk->BytesPerSector;
547 else
548 ullSectorCount = 0;
549
550 DPRINT1("SectorCount: %I64u\n", ullSectorCount);
551
552 for (ListEntry = CurrentDisk->LogicalPartListHead.Flink;
553 ListEntry != &CurrentDisk->LogicalPartListHead;
554 ListEntry = ListEntry->Flink)
555 {
556 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
557 if (PartEntry->IsPartitioned)
558 continue;
559
560 if (ullSectorCount == 0)
561 {
562 PartEntry->IsPartitioned = TRUE;
563 PartEntry->New = TRUE;
564 PartEntry->Mbr.PartitionType = PartitionType;
565 PartEntry->FormatState = Unformatted;
566 PartEntry->FileSystemName[0] = L'\0';
567
568 CurrentPartition = PartEntry;
570 break;
571 }
572 else
573 {
574 if (PartEntry->SectorCount.QuadPart == ullSectorCount)
575 {
576 PartEntry->IsPartitioned = TRUE;
577 PartEntry->New = TRUE;
578 PartEntry->Mbr.PartitionType = PartitionType;
579 PartEntry->FormatState = Unformatted;
580 PartEntry->FileSystemName[0] = L'\0';
581
582 CurrentPartition = PartEntry;
584 break;
585 }
586 else if (PartEntry->SectorCount.QuadPart > ullSectorCount)
587 {
588 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PPARTENTRY));
589 if (NewPartEntry == NULL)
590 {
591 ConPuts(StdOut, L"Memory allocation failed!\n");
592 return TRUE;
593 }
594
595 NewPartEntry->DiskEntry = PartEntry->DiskEntry;
596
597 NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
598 NewPartEntry->SectorCount.QuadPart = ullSectorCount;
599
600 NewPartEntry->LogicalPartition = TRUE;
601 NewPartEntry->IsPartitioned = TRUE;
602 NewPartEntry->New = TRUE;
603 NewPartEntry->Mbr.PartitionType = PartitionType;
604 NewPartEntry->FormatState = Unformatted;
605 NewPartEntry->FileSystemName[0] = L'\0';
606
607 PartEntry->StartSector.QuadPart += ullSectorCount;
608 PartEntry->SectorCount.QuadPart -= ullSectorCount;
609
610 InsertTailList(ListEntry, &NewPartEntry->ListEntry);
611
612 CurrentPartition = NewPartEntry;
614 break;
615 }
616 }
617 }
618
621 if (!NT_SUCCESS(Status))
622 {
625 return EXIT_SUCCESS;
626 }
627
629
630 return EXIT_SUCCESS;
631}
632
633
636 _In_ INT argc,
637 _In_ PWSTR *argv)
638{
639 PPARTENTRY PartEntry, NewPartEntry;
640 PLIST_ENTRY ListEntry;
641 ULONGLONG ullSize = 0ULL;
642 ULONGLONG ullSectorCount;
643#if 0
644 ULONGLONG ullOffset = 0ULL;
645 BOOL bNoErr = FALSE;
646#endif
647 INT i;
648 PWSTR pszSuffix = NULL;
650
651 DPRINT1("CreateMsrPartition()\n");
652
653 if (CurrentDisk == NULL)
654 {
656 return EXIT_SUCCESS;
657 }
658
660 {
662 return EXIT_SUCCESS;
663 }
664
665 for (i = 3; i < argc; i++)
666 {
667 if (_wcsicmp(argv[i], L"noerr") == 0)
668 {
669 /* noerr */
670 DPRINT("NoErr\n", pszSuffix);
671 ConPuts(StdOut, L"The NOERR option is not supported yet!\n");
672#if 0
673 bNoErr = TRUE;
674#endif
675 }
676 }
677
678 for (i = 3; i < argc; i++)
679 {
680 if (HasPrefix(argv[i], L"size=", &pszSuffix))
681 {
682 /* size=<N> (MB) */
683 DPRINT("Size : %s\n", pszSuffix);
684
685 ullSize = _wcstoui64(pszSuffix, NULL, 10);
686 if ((ullSize == 0) && (errno == ERANGE))
687 {
689 return EXIT_SUCCESS;
690 }
691 }
692 else if (HasPrefix(argv[i], L"offset=", &pszSuffix))
693 {
694 /* offset=<N> (KB) */
695 DPRINT("Offset : %s\n", pszSuffix);
696 ConPuts(StdOut, L"The OFFSET option is not supported yet!\n");
697#if 0
698 ullOffset = _wcstoui64(pszSuffix, NULL, 10);
699 if ((ullOffset == 0) && (errno == ERANGE))
700 {
702 return EXIT_SUCCESS;
703 }
704#endif
705 }
706 else if (_wcsicmp(argv[i], L"noerr") == 0)
707 {
708 /* noerr - Already handled above */
709 }
710 else
711 {
713 return EXIT_SUCCESS;
714 }
715 }
716
717 DPRINT1("Size: %I64u\n", ullSize);
718#if 0
719 DPRINT1("Offset: %I64u\n", ullOffset);
720#endif
721
722 /* Size */
723 if (ullSize != 0)
724 ullSectorCount = (ullSize * 1024 * 1024) / CurrentDisk->BytesPerSector;
725 else
726 ullSectorCount = 0;
727
728 DPRINT1("SectorCount: %I64u\n", ullSectorCount);
729
730#ifdef DUMP_PARTITION_LIST
731 DumpPartitionList(CurrentDisk);
732#endif
733
734 for (ListEntry = CurrentDisk->PrimaryPartListHead.Flink;
735 ListEntry != &CurrentDisk->PrimaryPartListHead;
736 ListEntry = ListEntry->Flink)
737 {
738 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
739 if (PartEntry->IsPartitioned)
740 continue;
741
742 if (ullSectorCount == 0)
743 {
744 DPRINT("Claim whole unused space!\n");
745 PartEntry->IsPartitioned = TRUE;
746 PartEntry->New = TRUE;
747 CopyMemory(&PartEntry->Gpt.PartitionType, &PARTITION_MSFT_RESERVED_GUID, sizeof(GUID));
748 CreateGUID(&PartEntry->Gpt.PartitionId);
749 PartEntry->Gpt.Attributes = 0ULL;
750 PartEntry->PartitionNumber = 0;
751 PartEntry->FormatState = Unformatted;
752 PartEntry->FileSystemName[0] = L'\0';
753
754 CurrentPartition = PartEntry;
756 break;
757 }
758 else
759 {
760 if (ullSectorCount == PartEntry->SectorCount.QuadPart)
761 {
762 DPRINT("Claim matching unused space!\n");
763 PartEntry->IsPartitioned = TRUE;
764 PartEntry->New = TRUE;
765 CopyMemory(&PartEntry->Gpt.PartitionType, &PARTITION_MSFT_RESERVED_GUID, sizeof(GUID));
766 CreateGUID(&PartEntry->Gpt.PartitionId);
767 PartEntry->Gpt.Attributes = 0ULL;
768 PartEntry->PartitionNumber = 0;
769 PartEntry->FormatState = Unformatted;
770 PartEntry->FileSystemName[0] = L'\0';
771
772 CurrentPartition = PartEntry;
774 break;
775 }
776 else if (ullSectorCount < PartEntry->SectorCount.QuadPart)
777 {
778 DPRINT("Claim part of unused space\n");
779 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PPARTENTRY));
780 if (NewPartEntry == NULL)
781 {
782 ConPuts(StdOut, L"Memory allocation failed!\n");
783 return TRUE;
784 }
785
786 NewPartEntry->DiskEntry = PartEntry->DiskEntry;
787
788 NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
789 NewPartEntry->SectorCount.QuadPart = ullSectorCount;
790
791 NewPartEntry->LogicalPartition = FALSE;
792 NewPartEntry->IsPartitioned = TRUE;
793 NewPartEntry->New = TRUE;
794 CopyMemory(&NewPartEntry->Gpt.PartitionType, &PARTITION_MSFT_RESERVED_GUID, sizeof(GUID));
795 CreateGUID(&NewPartEntry->Gpt.PartitionId);
796 NewPartEntry->Gpt.Attributes = 0ULL;
797 NewPartEntry->PartitionNumber = 0;
798 NewPartEntry->FormatState = Unformatted;
799 NewPartEntry->FileSystemName[0] = L'\0';
800
801 PartEntry->StartSector.QuadPart += ullSectorCount;
802 PartEntry->SectorCount.QuadPart -= ullSectorCount;
803
804 InsertTailList(ListEntry, &NewPartEntry->ListEntry);
805
806 CurrentPartition = NewPartEntry;
808 break;
809 }
810 }
811 }
812
813#ifdef DUMP_PARTITION_LIST
814 DumpPartitionList(CurrentDisk);
815#endif
816
819 if (!NT_SUCCESS(Status))
820 {
823 return EXIT_SUCCESS;
824 }
825
827
828 return EXIT_SUCCESS;
829}
830
831
832static
833VOID
835 _In_ ULONGLONG ullSize,
836 _In_ PWSTR pszPartitionType)
837{
838 PPARTENTRY PartEntry, NewPartEntry;
839 PLIST_ENTRY ListEntry;
840 ULONGLONG ullSectorCount;
842 INT length;
844
845 if (pszPartitionType)
846 {
847 length = wcslen(pszPartitionType);
848 if ((length != 1) && (length != 2))
849 {
851 return;
852 }
853
854 PartitionType = (UCHAR)wcstoul(pszPartitionType, NULL, 16);
855 if ((PartitionType == 0) && (errno == ERANGE))
856 {
858 return;
859 }
860 }
861 else
862 {
864 }
865
867 {
868 ConPuts(StdOut, L"No space left for another primary partition!\n");
869 return;
870 }
871
872 if (ullSize != 0)
873 ullSectorCount = (ullSize * 1024 * 1024) / CurrentDisk->BytesPerSector;
874 else
875 ullSectorCount = 0;
876
877 DPRINT1("SectorCount: %I64u\n", ullSectorCount);
878
879 for (ListEntry = CurrentDisk->PrimaryPartListHead.Flink;
880 ListEntry != &CurrentDisk->PrimaryPartListHead;
881 ListEntry = ListEntry->Flink)
882 {
883 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
884 if (PartEntry->IsPartitioned)
885 continue;
886
887 if (ullSectorCount == 0)
888 {
889 PartEntry->IsPartitioned = TRUE;
890 PartEntry->New = TRUE;
891 PartEntry->Mbr.PartitionType = PartitionType;
892 PartEntry->FormatState = Unformatted;
893 PartEntry->FileSystemName[0] = L'\0';
894
895 CurrentPartition = PartEntry;
897 break;
898 }
899 else
900 {
901 if (PartEntry->SectorCount.QuadPart == ullSectorCount)
902 {
903 PartEntry->IsPartitioned = TRUE;
904 PartEntry->New = TRUE;
905 PartEntry->Mbr.PartitionType = PartitionType;
906 PartEntry->FormatState = Unformatted;
907 PartEntry->FileSystemName[0] = L'\0';
908
909 CurrentPartition = PartEntry;
911 break;
912 }
913 else if (PartEntry->SectorCount.QuadPart > ullSectorCount)
914 {
915 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PPARTENTRY));
916 if (NewPartEntry == NULL)
917 {
918 ConPuts(StdOut, L"Memory allocation failed!\n");
919 return;
920 }
921
922 NewPartEntry->DiskEntry = PartEntry->DiskEntry;
923
924 NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
925 NewPartEntry->SectorCount.QuadPart = ullSectorCount;
926
927 NewPartEntry->LogicalPartition = FALSE;
928 NewPartEntry->IsPartitioned = TRUE;
929 NewPartEntry->New = TRUE;
930 NewPartEntry->Mbr.PartitionType = PartitionType;
931 NewPartEntry->FormatState = Unformatted;
932 NewPartEntry->FileSystemName[0] = L'\0';
933
934 PartEntry->StartSector.QuadPart += ullSectorCount;
935 PartEntry->SectorCount.QuadPart -= ullSectorCount;
936
937 InsertTailList(ListEntry, &NewPartEntry->ListEntry);
938
939 CurrentPartition = NewPartEntry;
941 break;
942 }
943 }
944 }
945
948 if (!NT_SUCCESS(Status))
949 {
952 return;
953 }
954
956}
957
958
959static
960VOID
962 _In_ ULONGLONG ullSize,
963 _In_ PWSTR pszPartitionType)
964{
965 PPARTENTRY PartEntry, NewPartEntry;
966 PLIST_ENTRY ListEntry;
967 ULONGLONG ullSectorCount;
968 GUID guidPartitionType;
970
971 /* Partition Type */
972 if (pszPartitionType)
973 {
974 if (!StringToGUID(&guidPartitionType, pszPartitionType))
975 {
977 return;
978 }
979 }
980 else
981 {
982 CopyMemory(&guidPartitionType, &PARTITION_BASIC_DATA_GUID, sizeof(GUID));
983 }
984
985 /* Size */
986 if (ullSize != 0)
987 ullSectorCount = (ullSize * 1024 * 1024) / CurrentDisk->BytesPerSector;
988 else
989 ullSectorCount = 0;
990
991 DPRINT1("SectorCount: %I64u\n", ullSectorCount);
992
993#ifdef DUMP_PARTITION_LIST
994 DumpPartitionList(CurrentDisk);
995#endif
996
997 for (ListEntry = CurrentDisk->PrimaryPartListHead.Flink;
998 ListEntry != &CurrentDisk->PrimaryPartListHead;
999 ListEntry = ListEntry->Flink)
1000 {
1001 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1002 if (PartEntry->IsPartitioned)
1003 continue;
1004
1005 if (ullSectorCount == 0)
1006 {
1007 DPRINT("Claim whole unused space!\n");
1008 PartEntry->IsPartitioned = TRUE;
1009 PartEntry->New = TRUE;
1010 CopyMemory(&PartEntry->Gpt.PartitionType, &guidPartitionType, sizeof(GUID));
1011 CreateGUID(&PartEntry->Gpt.PartitionId);
1012 PartEntry->Gpt.Attributes = 0ULL;
1013 PartEntry->PartitionNumber = 0;
1014 PartEntry->FormatState = Unformatted;
1015 PartEntry->FileSystemName[0] = L'\0';
1016
1017 CurrentPartition = PartEntry;
1019 break;
1020 }
1021 else
1022 {
1023 if (ullSectorCount == PartEntry->SectorCount.QuadPart)
1024 {
1025 DPRINT("Claim matching unused space!\n");
1026 PartEntry->IsPartitioned = TRUE;
1027 PartEntry->New = TRUE;
1028 CopyMemory(&PartEntry->Gpt.PartitionType, &guidPartitionType, sizeof(GUID));
1029 CreateGUID(&PartEntry->Gpt.PartitionId);
1030 PartEntry->Gpt.Attributes = 0ULL;
1031 PartEntry->PartitionNumber = 0;
1032 PartEntry->FormatState = Unformatted;
1033 PartEntry->FileSystemName[0] = L'\0';
1034
1035 CurrentPartition = PartEntry;
1037 break;
1038 }
1039 else if (ullSectorCount < PartEntry->SectorCount.QuadPart)
1040 {
1041 DPRINT("Claim part of unused space\n");
1042 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PPARTENTRY));
1043 if (NewPartEntry == NULL)
1044 {
1045 ConPuts(StdOut, L"Memory allocation failed!\n");
1046 return;
1047 }
1048
1049 NewPartEntry->DiskEntry = PartEntry->DiskEntry;
1050
1051 NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
1052 NewPartEntry->SectorCount.QuadPart = ullSectorCount;
1053
1054 NewPartEntry->LogicalPartition = FALSE;
1055 NewPartEntry->IsPartitioned = TRUE;
1056 NewPartEntry->New = TRUE;
1057 CopyMemory(&NewPartEntry->Gpt.PartitionType, &guidPartitionType, sizeof(GUID));
1058 CreateGUID(&NewPartEntry->Gpt.PartitionId);
1059 NewPartEntry->Gpt.Attributes = 0ULL;
1060 NewPartEntry->PartitionNumber = 0;
1061 NewPartEntry->FormatState = Unformatted;
1062 NewPartEntry->FileSystemName[0] = L'\0';
1063
1064 PartEntry->StartSector.QuadPart += ullSectorCount;
1065 PartEntry->SectorCount.QuadPart -= ullSectorCount;
1066
1067 InsertTailList(ListEntry, &NewPartEntry->ListEntry);
1068
1069 CurrentPartition = NewPartEntry;
1071 break;
1072 }
1073 }
1074 }
1075
1076#ifdef DUMP_PARTITION_LIST
1077 DumpPartitionList(CurrentDisk);
1078#endif
1079
1082 if (!NT_SUCCESS(Status))
1083 {
1086 return;
1087 }
1088
1090}
1091
1092
1095 _In_ INT argc,
1096 _In_ PWSTR *argv)
1097{
1098 ULONGLONG ullSize = 0ULL;
1099#if 0
1100 ULONGLONG ullOffset = 0ULL;
1101 BOOL bNoErr = FALSE;
1102#endif
1103 INT i;
1104 PWSTR pszSuffix = NULL;
1105 PWSTR pszPartitionType = NULL;
1106
1107 if (CurrentDisk == NULL)
1108 {
1110 return EXIT_SUCCESS;
1111 }
1112
1113 if (CurrentDisk->PartitionStyle == PARTITION_STYLE_RAW)
1114 {
1115 CREATE_DISK DiskInfo;
1117
1118 DiskInfo.PartitionStyle = PARTITION_STYLE_MBR;
1119 CreateSignature(&DiskInfo.Mbr.Signature);
1120
1121 Status = CreateDisk(CurrentDisk->DiskNumber, &DiskInfo);
1122 if (!NT_SUCCESS(Status))
1123 {
1124 DPRINT1("CreateDisk() failed!\n");
1125 return EXIT_SUCCESS;
1126 }
1127
1130
1132 }
1133
1134 for (i = 3; i < argc; i++)
1135 {
1136 if (_wcsicmp(argv[i], L"noerr") == 0)
1137 {
1138 /* noerr */
1139 DPRINT("NoErr\n", pszSuffix);
1140 ConPuts(StdOut, L"The NOERR option is not supported yet!\n");
1141#if 0
1142 bNoErr = TRUE;
1143#endif
1144 }
1145 }
1146
1147 for (i = 3; i < argc; i++)
1148 {
1149 if (HasPrefix(argv[i], L"size=", &pszSuffix))
1150 {
1151 /* size=<N> (MB) */
1152 DPRINT("Size : %s\n", pszSuffix);
1153
1154 ullSize = _wcstoui64(pszSuffix, NULL, 10);
1155 if ((ullSize == 0) && (errno == ERANGE))
1156 {
1158 return EXIT_SUCCESS;
1159 }
1160 }
1161 else if (HasPrefix(argv[i], L"offset=", &pszSuffix))
1162 {
1163 /* offset=<N> (KB) */
1164 DPRINT("Offset : %s\n", pszSuffix);
1165 ConPuts(StdOut, L"The OFFSET option is not supported yet!\n");
1166#if 0
1167 ullOffset = _wcstoui64(pszSuffix, NULL, 10);
1168 if ((ullOffset == 0) && (errno == ERANGE))
1169 {
1171 return EXIT_SUCCESS;
1172 }
1173#endif
1174 }
1175 else if (HasPrefix(argv[i], L"id=", &pszSuffix))
1176 {
1177 /* id=<Byte>|<GUID> */
1178 DPRINT("Id : %s\n", pszSuffix);
1179 pszPartitionType = pszSuffix;
1180 }
1181 else if (HasPrefix(argv[i], L"align=", &pszSuffix))
1182 {
1183 /* align=<N> */
1184 DPRINT("Align : %s\n", pszSuffix);
1185 ConPuts(StdOut, L"The ALIGN option is not supported yet!\n");
1186#if 0
1187 bAlign = TRUE;
1188#endif
1189 }
1190 else if (_wcsicmp(argv[i], L"noerr") == 0)
1191 {
1192 /* noerr - Alread handled above */
1193 }
1194 else
1195 {
1197 return EXIT_SUCCESS;
1198 }
1199 }
1200
1201 DPRINT("Size: %I64u\n", ullSize);
1202#if 0
1203 DPRINT1("Offset: %I64u\n", ullOffset);
1204#endif
1205
1207 {
1208 DPRINT("Partition Type: %s\n", pszPartitionType);
1209 CreatePrimaryMbrPartition(ullSize, pszPartitionType);
1210 }
1212 {
1213 CreatePrimaryGptPartition(ullSize, pszPartitionType);
1214 }
1215
1216 return EXIT_SUCCESS;
1217}
static int argc
Definition: ServiceArgs.c:12
void ConPuts(FILE *fp, LPCWSTR psz)
Definition: fc.c:16
#define StdOut
Definition: fc.c:14
#define StdErr
Definition: fc.c:15
void ConResPuts(FILE *fp, UINT nID)
Definition: fc.c:27
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
static VOID CreatePrimaryGptPartition(_In_ ULONGLONG ullSize, _In_ PWSTR pszPartitionType)
Definition: create.c:961
EXIT_CODE CreateMsrPartition(_In_ INT argc, _In_ PWSTR *argv)
Definition: create.c:635
EXIT_CODE CreatePrimaryPartition(_In_ INT argc, _In_ PWSTR *argv)
Definition: create.c:1094
EXIT_CODE CreateEfiPartition(_In_ INT argc, _In_ PWSTR *argv)
Definition: create.c:16
EXIT_CODE CreateExtendedPartition(_In_ INT argc, _In_ PWSTR *argv)
Definition: create.c:214
static VOID CreatePrimaryMbrPartition(_In_ ULONGLONG ullSize, _In_ PWSTR pszPartitionType)
Definition: create.c:834
EXIT_CODE CreateLogicalPartition(_In_ INT argc, _In_ PWSTR *argv)
Definition: create.c:427
#define IDS_CREATE_PARTITION_INVALID_STYLE
Definition: resource.h:49
#define IDS_CREATE_PARTITION_FAIL
Definition: resource.h:47
#define IDS_ERROR_INVALID_ARGS
Definition: resource.h:229
#define IDS_SELECT_NO_DISK
Definition: resource.h:121
#define IDS_CREATE_PARTITION_SUCCESS
Definition: resource.h:48
#define PARTITION_EXTENDED
Definition: disk.h:76
#define PARTITION_HUGE
Definition: disk.h:77
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
VOID UpdateMbrDiskLayout(_In_ PDISKENTRY DiskEntry)
Definition: partlist.c:2362
VOID CreateGUID(_Out_ GUID *pGuid)
Definition: misc.c:152
BOOL HasPrefix(_In_ PWSTR pszString, _In_ PWSTR pszPrefix, _Out_opt_ PWSTR *pszSuffix)
Definition: misc.c:58
enum _EXIT_CODE EXIT_CODE
VOID UpdateGptDiskLayout(_In_ PDISKENTRY DiskEntry, _In_ BOOL DeleteEntry)
Definition: partlist.c:2539
PDISKENTRY CurrentDisk
Definition: partlist.c:75
NTSTATUS WriteMbrPartitions(_In_ PDISKENTRY DiskEntry)
Definition: partlist.c:2034
VOID ScanForUnpartitionedMbrDiskSpace(PDISKENTRY DiskEntry)
Definition: partlist.c:660
NTSTATUS WriteGptPartitions(_In_ PDISKENTRY DiskEntry)
Definition: partlist.c:2158
VOID CreateSignature(_Out_ PDWORD pSignature)
Definition: misc.c:168
BOOL StringToGUID(_Out_ GUID *pGuid, _In_ PWSTR pszString)
Definition: misc.c:227
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
_ACRTIMP __msvcrt_ulong __cdecl wcstoul(const wchar_t *, wchar_t **, int)
Definition: wcs.c:2912
_ACRTIMP unsigned __int64 __cdecl _wcstoui64(const wchar_t *, wchar_t **, int)
Definition: wcs.c:2885
_ACRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:159
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
#define ERANGE
Definition: errno.h:55
#define errno
Definition: errno.h:120
#define L(x)
Definition: resources.c:13
#define InsertTailList(ListHead, Entry)
unsigned int BOOL
Definition: ntddk_ex.h:94
Status
Definition: gdiplustypes.h:25
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
@ Unformatted
Definition: partlist.h:34
#define CopyMemory
Definition: minwinbase.h:29
@ PARTITION_STYLE_GPT
Definition: imports.h:202
@ PARTITION_STYLE_MBR
Definition: imports.h:201
#define ULL(a, b)
Definition: format_msg.c:27
#define min(a, b)
Definition: monoChain.cc:55
#define argv
Definition: mplay32.c:18
#define _In_
Definition: no_sal2.h:158
ULONG SectorCount
Definition: part_xbox.c:31
CHAR PartitionType
Definition: part_xbox.c:32
#define EXIT_SUCCESS
Definition: rdjpgcom.c:55
#define GetPrimaryPartitionCount(DiskEntry)
Definition: partlist.c:2527
#define DPRINT
Definition: sndvol32.h:73
ULARGE_INTEGER EndSector
Definition: diskpart.h:202
ULONG SectorAlignment
Definition: partlist.h:116
ULARGE_INTEGER SectorCount
Definition: partlist.h:115
PPARTENTRY ExtendedPartition
Definition: partlist.h:153
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:150
ULONG DiskNumber
Definition: partlist.h:129
ULONG BytesPerSector
Definition: partlist.h:113
BOOLEAN Dirty
Definition: partlist.h:136
ULARGE_INTEGER StartSector
Definition: diskpart.h:201
DWORD PartitionStyle
Definition: diskpart.h:219
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:149
DWORD64 Attributes
Definition: diskpart.h:127
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
BOOLEAN IsPartitioned
Definition: partlist.h:82
BOOLEAN New
Definition: partlist.h:85
ULARGE_INTEGER SectorCount
Definition: partlist.h:70
struct _DISKENTRY * DiskEntry
Definition: partlist.h:66
BOOLEAN LogicalPartition
Definition: partlist.h:79
MBR_PARTITION_DATA Mbr
Definition: diskpart.h:141
FORMATSTATE FormatState
Definition: diskpart.h:152
GPT_PARTITION_DATA Gpt
Definition: diskpart.h:142
LIST_ENTRY ListEntry
Definition: partlist.h:63
ULONG PartitionNumber
Definition: partlist.h:75
ULARGE_INTEGER StartSector
Definition: partlist.h:69
CHAR FileSystemName[9]
Definition: diskpart.h:151
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
NTSTATUS CreateDisk(_In_ ULONG DiskNumber, _In_ PCREATE_DISK DiskInfo)
Definition: convert.c:15
uint16_t * PWSTR
Definition: typedefs.h:56
int32_t INT
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint64_t ULONGLONG
Definition: typedefs.h:67
static PPARTENTRY CurrentPartition
Definition: usetup.c:78
unsigned char UCHAR
Definition: xmlstorage.h:181