Reactos
at master 352 lines 10 kB view raw
1/* 2 * PROJECT: ReactOS DiskPart 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: base/system/diskpart/delete.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 14static 15BOOL 16IsKnownPartition( 17 _In_ PPARTENTRY PartEntry) 18{ 19 if (IsRecognizedPartition(PartEntry->Mbr.PartitionType) || 20 IsContainerPartition(PartEntry->Mbr.PartitionType)) 21 return TRUE; 22 23 return FALSE; 24} 25 26 27EXIT_CODE 28DeleteDisk( 29 _In_ INT argc, 30 _In_ PWSTR *argv) 31{ 32 return EXIT_SUCCESS; 33} 34 35 36static 37VOID 38DeleteMbrPartition( 39 _In_ BOOL bOverride) 40{ 41 PPARTENTRY PrevPartEntry; 42 PPARTENTRY NextPartEntry; 43 PPARTENTRY LogicalPartEntry; 44 PLIST_ENTRY Entry; 45 NTSTATUS Status; 46 47 ASSERT(CurrentPartition->Mbr.PartitionType != PARTITION_ENTRY_UNUSED); 48 49 /* Clear the system partition if it is being deleted */ 50#if 0 51 if (List->SystemPartition == PartEntry) 52 { 53 ASSERT(List->SystemPartition); 54 List->SystemPartition = NULL; 55 } 56#endif 57 58 if ((bOverride == FALSE) && (IsKnownPartition(CurrentPartition) == FALSE)) 59 { 60 ConResPuts(StdOut, IDS_DELETE_PARTITION_FAIL); 61 return; 62 } 63 64 /* Check which type of partition (primary/logical or extended) is being deleted */ 65 if (CurrentDisk->ExtendedPartition == CurrentPartition) 66 { 67 /* An extended partition is being deleted: delete all logical partition entries */ 68 while (!IsListEmpty(&CurrentDisk->LogicalPartListHead)) 69 { 70 Entry = RemoveHeadList(&CurrentDisk->LogicalPartListHead); 71 LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); 72 73 /* Dismount the logical partition */ 74 DismountVolume(LogicalPartEntry); 75 76 /* Delete it */ 77 RtlFreeHeap(RtlGetProcessHeap(), 0, LogicalPartEntry); 78 } 79 80 CurrentDisk->ExtendedPartition = NULL; 81 } 82 else 83 { 84 /* A primary partition is being deleted: dismount it */ 85 DismountVolume(CurrentPartition); 86 } 87 88 /* Adjust the unpartitioned disk space entries */ 89 90 /* Get pointer to previous and next unpartitioned entries */ 91 PrevPartEntry = GetPrevUnpartitionedEntry(CurrentPartition); 92 NextPartEntry = GetNextUnpartitionedEntry(CurrentPartition); 93 94 if (PrevPartEntry != NULL && NextPartEntry != NULL) 95 { 96 /* Merge the previous, current and next unpartitioned entries */ 97 98 /* Adjust the previous entry length */ 99 PrevPartEntry->SectorCount.QuadPart += (CurrentPartition->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart); 100 101 /* Remove the current and next entries */ 102 RemoveEntryList(&CurrentPartition->ListEntry); 103 RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentPartition); 104 RemoveEntryList(&NextPartEntry->ListEntry); 105 RtlFreeHeap(RtlGetProcessHeap(), 0, NextPartEntry); 106 } 107 else if (PrevPartEntry != NULL && NextPartEntry == NULL) 108 { 109 /* Merge the current and the previous unpartitioned entries */ 110 111 /* Adjust the previous entry length */ 112 PrevPartEntry->SectorCount.QuadPart += CurrentPartition->SectorCount.QuadPart; 113 114 /* Remove the current entry */ 115 RemoveEntryList(&CurrentPartition->ListEntry); 116 RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentPartition); 117 } 118 else if (PrevPartEntry == NULL && NextPartEntry != NULL) 119 { 120 /* Merge the current and the next unpartitioned entries */ 121 122 /* Adjust the next entry offset and length */ 123 NextPartEntry->StartSector.QuadPart = CurrentPartition->StartSector.QuadPart; 124 NextPartEntry->SectorCount.QuadPart += CurrentPartition->SectorCount.QuadPart; 125 126 /* Remove the current entry */ 127 RemoveEntryList(&CurrentPartition->ListEntry); 128 RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentPartition); 129 } 130 else 131 { 132 /* Nothing to merge but change the current entry */ 133 CurrentPartition->IsPartitioned = FALSE; 134 CurrentPartition->OnDiskPartitionNumber = 0; 135 CurrentPartition->PartitionNumber = 0; 136 // CurrentPartition->PartitionIndex = 0; 137 CurrentPartition->Mbr.BootIndicator = FALSE; 138 CurrentPartition->Mbr.PartitionType = PARTITION_ENTRY_UNUSED; 139 CurrentPartition->FormatState = Unformatted; 140 CurrentPartition->FileSystemName[0] = L'\0'; 141 CurrentPartition->DriveLetter = 0; 142 RtlZeroMemory(CurrentPartition->VolumeLabel, sizeof(CurrentPartition->VolumeLabel)); 143 } 144 145 CurrentPartition = NULL; 146 147 UpdateMbrDiskLayout(CurrentDisk); 148 Status = WriteMbrPartitions(CurrentDisk); 149 if (!NT_SUCCESS(Status)) 150 { 151 ConResPuts(StdOut, IDS_DELETE_PARTITION_FAIL); 152 return; 153 } 154 155 ConResPuts(StdOut, IDS_DELETE_PARTITION_SUCCESS); 156} 157 158 159static 160VOID 161DeleteGptPartition( 162 _In_ BOOL bOverride) 163{ 164 PPARTENTRY PrevPartEntry; 165 PPARTENTRY NextPartEntry; 166 NTSTATUS Status; 167 168 /* Clear the system partition if it is being deleted */ 169#if 0 170 if (List->SystemPartition == PartEntry) 171 { 172 ASSERT(List->SystemPartition); 173 List->SystemPartition = NULL; 174 } 175#endif 176 177 if ((bOverride == FALSE) && 178 ((memcmp(&CurrentPartition->Gpt.PartitionType, &PARTITION_SYSTEM_GUID, sizeof(GUID)) == 0) || 179 (memcmp(&CurrentPartition->Gpt.PartitionType, &PARTITION_MSFT_RESERVED_GUID, sizeof(GUID)) == 0))) 180 { 181 ConResPuts(StdOut, IDS_DELETE_PARTITION_FAIL); 182 return; 183 } 184 185#ifdef DUMP_PARTITION_LIST 186 DumpPartitionList(CurrentDisk); 187#endif 188 189 /* Dismount the partition */ 190 DismountVolume(CurrentPartition); 191 192 /* Adjust the unpartitioned disk space entries */ 193 194 /* Get pointer to previous and next unpartitioned entries */ 195 PrevPartEntry = GetPrevUnpartitionedEntry(CurrentPartition); 196 NextPartEntry = GetNextUnpartitionedEntry(CurrentPartition); 197 198 if (PrevPartEntry != NULL && NextPartEntry != NULL) 199 { 200 /* Merge the previous, current and next unpartitioned entries */ 201 202 /* Adjust the previous entry length */ 203 PrevPartEntry->SectorCount.QuadPart += (CurrentPartition->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart); 204 205 /* Remove the current and next entries */ 206 RemoveEntryList(&CurrentPartition->ListEntry); 207 RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentPartition); 208 RemoveEntryList(&NextPartEntry->ListEntry); 209 RtlFreeHeap(RtlGetProcessHeap(), 0, NextPartEntry); 210 } 211 else if (PrevPartEntry != NULL && NextPartEntry == NULL) 212 { 213 /* Merge the current and the previous unpartitioned entries */ 214 215 /* Adjust the previous entry length */ 216 PrevPartEntry->SectorCount.QuadPart += CurrentPartition->SectorCount.QuadPart; 217 218 /* Remove the current entry */ 219 RemoveEntryList(&CurrentPartition->ListEntry); 220 RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentPartition); 221 } 222 else if (PrevPartEntry == NULL && NextPartEntry != NULL) 223 { 224 /* Merge the current and the next unpartitioned entries */ 225 226 /* Adjust the next entry offset and length */ 227 NextPartEntry->StartSector.QuadPart = CurrentPartition->StartSector.QuadPart; 228 NextPartEntry->SectorCount.QuadPart += CurrentPartition->SectorCount.QuadPart; 229 230 /* Remove the current entry */ 231 RemoveEntryList(&CurrentPartition->ListEntry); 232 RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentPartition); 233 } 234 else 235 { 236 /* Nothing to merge but change the current entry */ 237 CurrentPartition->IsPartitioned = FALSE; 238 CurrentPartition->OnDiskPartitionNumber = 0; 239 CurrentPartition->PartitionNumber = 0; 240 // CurrentPartition->PartitionIndex = 0; 241 242 ZeroMemory(&CurrentPartition->Gpt.PartitionType, sizeof(GUID)); 243 ZeroMemory(&CurrentPartition->Gpt.PartitionId, sizeof(GUID)); 244 CurrentPartition->Gpt.Attributes = 0ULL; 245 246 CurrentPartition->FormatState = Unformatted; 247 CurrentPartition->FileSystemName[0] = L'\0'; 248 CurrentPartition->DriveLetter = 0; 249 RtlZeroMemory(CurrentPartition->VolumeLabel, sizeof(CurrentPartition->VolumeLabel)); 250 } 251 252 CurrentPartition = NULL; 253 254#ifdef DUMP_PARTITION_LIST 255 DumpPartitionList(CurrentDisk); 256#endif 257 258 UpdateGptDiskLayout(CurrentDisk, TRUE); 259#ifdef DUMP_PARTITION_TABLE 260 DumpPartitionTable(CurrentDisk); 261#endif 262 Status = WriteGptPartitions(CurrentDisk); 263 if (!NT_SUCCESS(Status)) 264 { 265 ConResPuts(StdOut, IDS_DELETE_PARTITION_FAIL); 266 return; 267 } 268 269 ConResPuts(StdOut, IDS_DELETE_PARTITION_SUCCESS); 270} 271 272 273EXIT_CODE 274DeletePartition( 275 _In_ INT argc, 276 _In_ PWSTR *argv) 277{ 278 INT i; 279 BOOL bOverride = FALSE; 280 281 DPRINT("DeletePartition()\n"); 282 283 if (CurrentDisk == NULL) 284 { 285 ConResPuts(StdOut, IDS_SELECT_NO_DISK); 286 return EXIT_SUCCESS; 287 } 288 289 if (CurrentPartition == NULL) 290 { 291 ConResPuts(StdOut, IDS_SELECT_NO_PARTITION); 292 return EXIT_SUCCESS; 293 } 294 295 for (i = 2; i < argc; i++) 296 { 297 if (_wcsicmp(argv[i], L"noerr") == 0) 298 { 299 /* noerr */ 300 DPRINT("NOERR\n"); 301 ConPuts(StdOut, L"The NOERR option is not supported yet!\n"); 302#if 0 303 bNoErr = TRUE; 304#endif 305 } 306 } 307 308 for (i = 2; i < argc; i++) 309 { 310 if (_wcsicmp(argv[i], L"noerr") == 0) 311 { 312 /* noerr - Already handled above */ 313 } 314 else if (_wcsicmp(argv[i], L"override") == 0) 315 { 316 /* override */ 317 DPRINT("OVERRIDE\n"); 318 bOverride = TRUE; 319 } 320 else 321 { 322 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS); 323 return EXIT_SUCCESS; 324 } 325 } 326 327 if (CurrentPartition->IsBoot || CurrentPartition->IsSystem) 328 { 329 ConResPuts(StdOut, IDS_DELETE_PARTITION_SYSTEM); 330 return EXIT_SUCCESS; 331 } 332 333 if (CurrentDisk->PartitionStyle == PARTITION_STYLE_MBR) 334 { 335 DeleteMbrPartition(bOverride); 336 } 337 else if (CurrentDisk->PartitionStyle == PARTITION_STYLE_GPT) 338 { 339 DeleteGptPartition(bOverride); 340 } 341 342 return EXIT_SUCCESS; 343} 344 345 346EXIT_CODE 347DeleteVolume( 348 _In_ INT argc, 349 _In_ PWSTR *argv) 350{ 351 return EXIT_SUCCESS; 352}