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