xref: /reactos/base/system/diskpart/delete.c (revision 89724481)
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
IsKnownPartition(_In_ PPARTENTRY PartEntry)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
DeleteDisk(_In_ INT argc,_In_ PWSTR * argv)28 DeleteDisk(
29     _In_ INT argc,
30     _In_ PWSTR *argv)
31 {
32     return TRUE;
33 }
34 
35 
36 BOOL
DeletePartition(_In_ INT argc,_In_ PWSTR * argv)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             /* override */
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
DeleteVolume(_In_ INT argc,_In_ PWSTR * argv)203 DeleteVolume(
204     _In_ INT argc,
205     _In_ PWSTR *argv)
206 {
207     return TRUE;
208 }
209