Reactos
at master 193 lines 5.5 kB view raw
1/* 2 * PROJECT: ReactOS DiskPart 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: base/system/diskpart/convert.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 14NTSTATUS 15CreateDisk( 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 DPRINT("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 /* Free the layout buffer */ 68 if (CurrentDisk->LayoutBuffer) 69 RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentDisk->LayoutBuffer); 70 71 CurrentDisk->LayoutBuffer = NULL; 72 CurrentDisk->ExtendedPartition = NULL; 73 CurrentDisk->Dirty = FALSE; 74 CurrentDisk->NewDisk = TRUE; 75 CurrentDisk->PartitionStyle = DiskInfo->PartitionStyle; 76 77 ReadLayoutBuffer(FileHandle, CurrentDisk); 78 79done: 80 if (FileHandle) 81 NtClose(FileHandle); 82 83 return Status; 84} 85 86 87EXIT_CODE 88ConvertGPT( 89 _In_ INT argc, 90 _In_ PWSTR *argv) 91{ 92 CREATE_DISK DiskInfo; 93 NTSTATUS Status; 94 95 DPRINT("ConvertGPT()\n"); 96 97 if (CurrentDisk == NULL) 98 { 99 ConResPuts(StdOut, IDS_SELECT_NO_DISK); 100 return EXIT_SUCCESS; 101 } 102 103 if (CurrentDisk->PartitionStyle == PARTITION_STYLE_GPT) 104 { 105 ConResPuts(StdOut, IDS_CONVERT_GPT_ALREADY); 106 return EXIT_SUCCESS; 107 } 108 109 if (GetPrimaryPartitionCount(CurrentDisk) != 0) 110 { 111 ConResPuts(StdOut, IDS_CONVERT_GPT_NOT_EMPTY); 112 return EXIT_SUCCESS; 113 } 114 115#if 0 116 /* Fail if disk size is less than 128MB */ 117 if (CurrentDisk->SectorCount.QuadPart * CurrentDisk->BytesPerSector < 128ULL * 1024ULL * 1024ULL) 118 { 119 ConResPuts(StdOut, IDS_CONVERT_GPT_TOO_SMALL); 120 return EXIT_SUCCESS; 121 } 122#endif 123 124 DiskInfo.PartitionStyle = PARTITION_STYLE_GPT; 125 CreateGUID(&DiskInfo.Gpt.DiskId); 126 DiskInfo.Gpt.MaxPartitionCount = 128; 127 128 Status = CreateDisk(CurrentDisk->DiskNumber, &DiskInfo); 129 if (!NT_SUCCESS(Status)) 130 { 131 DPRINT1("CreateDisk() failed!\n"); 132 return EXIT_SUCCESS; 133 } 134 135 CurrentDisk->StartSector.QuadPart = AlignDown(CurrentDisk->LayoutBuffer->Gpt.StartingUsableOffset.QuadPart / CurrentDisk->BytesPerSector, 136 CurrentDisk->SectorAlignment) + (ULONGLONG)CurrentDisk->SectorAlignment; 137 CurrentDisk->EndSector.QuadPart = AlignDown(CurrentDisk->StartSector.QuadPart + (CurrentDisk->LayoutBuffer->Gpt.UsableLength.QuadPart / CurrentDisk->BytesPerSector) - 1, 138 CurrentDisk->SectorAlignment); 139 140 ScanForUnpartitionedGptDiskSpace(CurrentDisk); 141 ConResPuts(StdOut, IDS_CONVERT_GPT_SUCCESS); 142 143 return EXIT_SUCCESS; 144} 145 146 147EXIT_CODE 148ConvertMBR( 149 _In_ INT argc, 150 _In_ PWSTR *argv) 151{ 152 CREATE_DISK DiskInfo; 153 NTSTATUS Status; 154 155 DPRINT("ConvertMBR()\n"); 156 157 if (CurrentDisk == NULL) 158 { 159 ConResPuts(StdOut, IDS_SELECT_NO_DISK); 160 return EXIT_SUCCESS; 161 } 162 163 if ((CurrentDisk->PartitionStyle == PARTITION_STYLE_MBR) || 164 (CurrentDisk->PartitionStyle == PARTITION_STYLE_RAW)) 165 { 166 ConResPuts(StdOut, IDS_CONVERT_MBR_ALREADY); 167 return EXIT_SUCCESS; 168 } 169 170 if (GetPrimaryPartitionCount(CurrentDisk) != 0) 171 { 172 ConResPuts(StdOut, IDS_CONVERT_MBR_NOT_EMPTY); 173 return EXIT_SUCCESS; 174 } 175 176 DiskInfo.PartitionStyle = PARTITION_STYLE_MBR; 177 CreateSignature(&DiskInfo.Mbr.Signature); 178 179 Status = CreateDisk(CurrentDisk->DiskNumber, &DiskInfo); 180 if (!NT_SUCCESS(Status)) 181 { 182 DPRINT1("CreateDisk() failed!\n"); 183 return EXIT_SUCCESS; 184 } 185 186 CurrentDisk->StartSector.QuadPart = (ULONGLONG)CurrentDisk->SectorAlignment; 187 CurrentDisk->EndSector.QuadPart = min(CurrentDisk->SectorCount.QuadPart, 0x100000000) - 1; 188 189 ScanForUnpartitionedMbrDiskSpace(CurrentDisk); 190 ConResPuts(StdOut, IDS_CONVERT_MBR_SUCCESS); 191 192 return EXIT_SUCCESS; 193}