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 14 static 15 BOOL 16 IsKnownPartition( 17 _In_ PPARTENTRY PartEntry) 18 { 19 if (IsRecognizedPartition(PartEntry->PartitionType) || 20 IsContainerPartition(PartEntry->PartitionType)) 21 return TRUE; 22 23 return FALSE; 24 } 25 26 27 BOOL 28 DeleteDisk( 29 _In_ INT argc, 30 _In_ PWSTR *argv) 31 { 32 return TRUE; 33 } 34 35 36 BOOL 37 DeletePartition( 38 _In_ INT argc, 39 _In_ PWSTR *argv) 40 { 41 PPARTENTRY PrevPartEntry; 42 PPARTENTRY NextPartEntry; 43 PPARTENTRY LogicalPartEntry; 44 PLIST_ENTRY Entry; 45 INT i; 46 BOOL bOverride = FALSE; 47 NTSTATUS Status; 48 49 DPRINT("DeletePartition()\n"); 50 51 if (CurrentDisk == NULL) 52 { 53 ConResPuts(StdOut, IDS_SELECT_NO_DISK); 54 return TRUE; 55 } 56 57 if (CurrentPartition == NULL) 58 { 59 ConResPuts(StdOut, IDS_SELECT_NO_PARTITION); 60 return TRUE; 61 } 62 63 ASSERT(CurrentPartition->PartitionType != PARTITION_ENTRY_UNUSED); 64 65 for (i = 2; i < argc; i++) 66 { 67 if (_wcsicmp(argv[i], L"noerr") == 0) 68 { 69 /* noerr */ 70 DPRINT("NOERR\n"); 71 ConPuts(StdOut, L"The NOERR option is not supported yet!\n"); 72 #if 0 73 bNoErr = TRUE; 74 #endif 75 } 76 else if (_wcsicmp(argv[i], L"override") == 0) 77 { 78 /* noerr */ 79 DPRINT("OVERRIDE\n"); 80 bOverride = TRUE; 81 } 82 else 83 { 84 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS); 85 return TRUE; 86 } 87 } 88 89 90 /* Clear the system partition if it is being deleted */ 91 #if 0 92 if (List->SystemPartition == PartEntry) 93 { 94 ASSERT(List->SystemPartition); 95 List->SystemPartition = NULL; 96 } 97 #endif 98 99 if ((bOverride == FALSE) && (IsKnownPartition(CurrentPartition) == FALSE)) 100 { 101 ConResPuts(StdOut, IDS_DELETE_PARTITION_FAIL); 102 return FALSE; 103 } 104 105 /* Check which type of partition (primary/logical or extended) is being deleted */ 106 if (CurrentDisk->ExtendedPartition == CurrentPartition) 107 { 108 /* An extended partition is being deleted: delete all logical partition entries */ 109 while (!IsListEmpty(&CurrentDisk->LogicalPartListHead)) 110 { 111 Entry = RemoveHeadList(&CurrentDisk->LogicalPartListHead); 112 LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); 113 114 /* Dismount the logical partition */ 115 DismountVolume(LogicalPartEntry); 116 117 /* Delete it */ 118 RtlFreeHeap(RtlGetProcessHeap(), 0, LogicalPartEntry); 119 } 120 121 CurrentDisk->ExtendedPartition = NULL; 122 } 123 else 124 { 125 /* A primary partition is being deleted: dismount it */ 126 DismountVolume(CurrentPartition); 127 } 128 129 /* Adjust the unpartitioned disk space entries */ 130 131 /* Get pointer to previous and next unpartitioned entries */ 132 PrevPartEntry = GetPrevUnpartitionedEntry(CurrentPartition); 133 NextPartEntry = GetNextUnpartitionedEntry(CurrentPartition); 134 135 if (PrevPartEntry != NULL && NextPartEntry != NULL) 136 { 137 /* Merge the previous, current and next unpartitioned entries */ 138 139 /* Adjust the previous entry length */ 140 PrevPartEntry->SectorCount.QuadPart += (CurrentPartition->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart); 141 142 /* Remove the current and next entries */ 143 RemoveEntryList(&CurrentPartition->ListEntry); 144 RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentPartition); 145 RemoveEntryList(&NextPartEntry->ListEntry); 146 RtlFreeHeap(RtlGetProcessHeap(), 0, NextPartEntry); 147 } 148 else if (PrevPartEntry != NULL && NextPartEntry == NULL) 149 { 150 /* Merge the current and the previous unpartitioned entries */ 151 152 /* Adjust the previous entry length */ 153 PrevPartEntry->SectorCount.QuadPart += CurrentPartition->SectorCount.QuadPart; 154 155 /* Remove the current entry */ 156 RemoveEntryList(&CurrentPartition->ListEntry); 157 RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentPartition); 158 } 159 else if (PrevPartEntry == NULL && NextPartEntry != NULL) 160 { 161 /* Merge the current and the next unpartitioned entries */ 162 163 /* Adjust the next entry offset and length */ 164 NextPartEntry->StartSector.QuadPart = CurrentPartition->StartSector.QuadPart; 165 NextPartEntry->SectorCount.QuadPart += CurrentPartition->SectorCount.QuadPart; 166 167 /* Remove the current entry */ 168 RemoveEntryList(&CurrentPartition->ListEntry); 169 RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentPartition); 170 } 171 else 172 { 173 /* Nothing to merge but change the current entry */ 174 CurrentPartition->IsPartitioned = FALSE; 175 CurrentPartition->OnDiskPartitionNumber = 0; 176 CurrentPartition->PartitionNumber = 0; 177 // CurrentPartition->PartitionIndex = 0; 178 CurrentPartition->BootIndicator = FALSE; 179 CurrentPartition->PartitionType = PARTITION_ENTRY_UNUSED; 180 CurrentPartition->FormatState = Unformatted; 181 CurrentPartition->FileSystemName[0] = L'\0'; 182 CurrentPartition->DriveLetter = 0; 183 RtlZeroMemory(CurrentPartition->VolumeLabel, sizeof(CurrentPartition->VolumeLabel)); 184 } 185 186 CurrentPartition = NULL; 187 188 UpdateDiskLayout(CurrentDisk); 189 Status = WritePartitions(CurrentDisk); 190 if (!NT_SUCCESS(Status)) 191 { 192 ConResPuts(StdOut, IDS_DELETE_PARTITION_FAIL); 193 return TRUE; 194 } 195 196 ConResPuts(StdOut, IDS_DELETE_PARTITION_SUCCESS); 197 198 return TRUE; 199 } 200 201 202 BOOL 203 DeleteVolume( 204 _In_ INT argc, 205 _In_ PWSTR *argv) 206 { 207 return TRUE; 208 } 209