|
12 | 12 | #include <debug.h> |
13 | 13 |
|
14 | 14 |
|
| 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 | + |
15 | 205 | BOOL |
16 | 206 | CreateExtendedPartition( |
17 | 207 | _In_ INT argc, |
@@ -417,6 +607,196 @@ CreateLogicalPartition( |
417 | 607 | } |
418 | 608 |
|
419 | 609 |
|
| 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 | + |
420 | 800 | static |
421 | 801 | VOID |
422 | 802 | CreatePrimaryMbrPartition( |
|
0 commit comments