Reactos
1/*
2 * PROJECT: ReactOS DiskPart
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/system/diskpart/select.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/* FUNCTIONS ******************************************************************/
15
16EXIT_CODE
17SelectDisk(
18 _In_ INT argc,
19 _In_ PWSTR *argv)
20{
21 PLIST_ENTRY Entry;
22 PDISKENTRY DiskEntry;
23 ULONG ulValue;
24
25 DPRINT("Select Disk()\n");
26
27 if (argc > 3)
28 {
29 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
30 return EXIT_SUCCESS;
31 }
32
33 if (argc == 2)
34 {
35 if (CurrentDisk == NULL)
36 ConResPuts(StdOut, IDS_SELECT_NO_DISK);
37 else
38 ConResPrintf(StdOut, IDS_SELECT_DISK, CurrentDisk->DiskNumber);
39 return EXIT_SUCCESS;
40 }
41
42 if (!_wcsicmp(argv[2], L"system"))
43 {
44 CurrentDisk = NULL;
45
46 Entry = DiskListHead.Flink;
47 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
48
49 CurrentDisk = DiskEntry;
50 CurrentPartition = NULL;
51 ConResPrintf(StdOut, IDS_SELECT_DISK, CurrentDisk->DiskNumber);
52 return EXIT_SUCCESS;
53 }
54 else if (!_wcsicmp(argv[2], L"next"))
55 {
56 if (CurrentDisk == NULL)
57 {
58 CurrentPartition = NULL;
59 ConResPuts(StdErr, IDS_SELECT_DISK_ENUM_NO_START);
60 return EXIT_SUCCESS;
61 }
62
63 if (CurrentDisk->ListEntry.Flink == &DiskListHead)
64 {
65 CurrentDisk = NULL;
66 CurrentPartition = NULL;
67 ConResPuts(StdErr, IDS_SELECT_DISK_ENUM_FINISHED);
68 return EXIT_SUCCESS;
69 }
70
71 Entry = CurrentDisk->ListEntry.Flink;
72
73 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
74
75 CurrentDisk = DiskEntry;
76 CurrentPartition = NULL;
77 ConResPrintf(StdOut, IDS_SELECT_DISK, CurrentDisk->DiskNumber);
78 return EXIT_SUCCESS;
79 }
80 else if (IsDecString(argv[2]))
81 {
82 ulValue = wcstoul(argv[2], NULL, 10);
83 if ((ulValue == 0) && (errno == ERANGE))
84 {
85 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
86 return EXIT_SUCCESS;
87 }
88
89 CurrentDisk = NULL;
90
91 Entry = DiskListHead.Flink;
92 while (Entry != &DiskListHead)
93 {
94 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
95
96 if (DiskEntry->DiskNumber == ulValue)
97 {
98 CurrentDisk = DiskEntry;
99 CurrentPartition = NULL;
100 ConResPrintf(StdOut, IDS_SELECT_DISK, CurrentDisk->DiskNumber);
101 return EXIT_SUCCESS;
102 }
103
104 Entry = Entry->Flink;
105 }
106 }
107 else
108 {
109 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
110 return EXIT_SUCCESS;
111 }
112
113 ConResPuts(StdErr, IDS_SELECT_DISK_INVALID);
114 return EXIT_SUCCESS;
115}
116
117
118EXIT_CODE
119SelectPartition(
120 _In_ INT argc,
121 _In_ PWSTR *argv)
122{
123 PLIST_ENTRY Entry;
124 PPARTENTRY PartEntry;
125 ULONG ulValue;
126 ULONG PartNumber = 1;
127
128 DPRINT("Select Partition()\n");
129
130 if (argc > 3)
131 {
132 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
133 return EXIT_SUCCESS;
134 }
135
136 if (CurrentDisk == NULL)
137 {
138 ConResPuts(StdOut, IDS_SELECT_PARTITION_NO_DISK);
139 return EXIT_SUCCESS;
140 }
141
142 if (argc == 2)
143 {
144 if (CurrentPartition == NULL)
145 ConResPuts(StdOut, IDS_SELECT_NO_PARTITION);
146 else
147 ConResPrintf(StdOut, IDS_SELECT_PARTITION, CurrentPartition);
148 return EXIT_SUCCESS;
149 }
150
151 if (!IsDecString(argv[2]))
152 {
153 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
154 return EXIT_SUCCESS;
155 }
156
157 ulValue = wcstoul(argv[2], NULL, 10);
158 if ((ulValue == 0) && (errno == ERANGE))
159 {
160 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
161 return EXIT_SUCCESS;
162 }
163
164 if (CurrentDisk->PartitionStyle == PARTITION_STYLE_MBR)
165 {
166 Entry = CurrentDisk->PrimaryPartListHead.Flink;
167 while (Entry != &CurrentDisk->PrimaryPartListHead)
168 {
169 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
170
171 if (PartEntry->Mbr.PartitionType != PARTITION_ENTRY_UNUSED)
172 {
173 if (PartNumber == ulValue)
174 {
175 CurrentPartition = PartEntry;
176 ConResPrintf(StdOut, IDS_SELECT_PARTITION, PartNumber);
177 return EXIT_SUCCESS;
178 }
179
180 PartNumber++;
181 }
182
183 Entry = Entry->Flink;
184 }
185
186 Entry = CurrentDisk->LogicalPartListHead.Flink;
187 while (Entry != &CurrentDisk->LogicalPartListHead)
188 {
189 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
190
191 if (PartEntry->Mbr.PartitionType != PARTITION_ENTRY_UNUSED)
192 {
193 if (PartNumber == ulValue)
194 {
195 CurrentPartition = PartEntry;
196 ConResPrintf(StdOut, IDS_SELECT_PARTITION, PartNumber);
197 return EXIT_SUCCESS;
198 }
199
200 PartNumber++;
201 }
202 Entry = Entry->Flink;
203 }
204 }
205 else if (CurrentDisk->PartitionStyle == PARTITION_STYLE_GPT)
206 {
207 Entry = CurrentDisk->PrimaryPartListHead.Flink;
208 while (Entry != &CurrentDisk->PrimaryPartListHead)
209 {
210 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
211
212 if (!IsEqualGUID(&PartEntry->Gpt.PartitionType, &PARTITION_ENTRY_UNUSED_GUID))
213 {
214 if (PartNumber == ulValue)
215 {
216 CurrentPartition = PartEntry;
217 ConResPrintf(StdOut, IDS_SELECT_PARTITION, PartNumber);
218 return EXIT_SUCCESS;
219 }
220
221 PartNumber++;
222 }
223
224 Entry = Entry->Flink;
225 }
226 }
227
228 ConResPuts(StdErr, IDS_SELECT_PARTITION_INVALID);
229 return EXIT_SUCCESS;
230}
231
232
233EXIT_CODE
234SelectVolume(
235 _In_ INT argc,
236 _In_ PWSTR *argv)
237{
238 PLIST_ENTRY Entry;
239 PVOLENTRY VolumeEntry;
240 ULONG ulValue;
241
242 DPRINT("SelectVolume()\n");
243
244 if (argc > 3)
245 {
246 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
247 return EXIT_SUCCESS;
248 }
249
250 if (argc == 2)
251 {
252 if (CurrentDisk == NULL)
253 ConResPuts(StdOut, IDS_SELECT_NO_VOLUME);
254 else
255 ConResPrintf(StdOut, IDS_SELECT_VOLUME, CurrentVolume->VolumeNumber);
256 return EXIT_SUCCESS;
257 }
258
259 if (!IsDecString(argv[2]))
260 {
261 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
262 return EXIT_SUCCESS;
263 }
264
265 ulValue = wcstoul(argv[2], NULL, 10);
266 if ((ulValue == 0) && (errno == ERANGE))
267 {
268 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
269 return EXIT_SUCCESS;
270 }
271
272 CurrentVolume = NULL;
273
274 Entry = VolumeListHead.Flink;
275 while (Entry != &VolumeListHead)
276 {
277 VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
278
279 if (VolumeEntry->VolumeNumber == ulValue)
280 {
281 CurrentVolume = VolumeEntry;
282 ConResPrintf(StdOut, IDS_SELECT_VOLUME, CurrentVolume->VolumeNumber);
283 return TRUE;
284 }
285
286 Entry = Entry->Flink;
287 }
288
289 ConResPuts(StdErr, IDS_SELECT_VOLUME_INVALID);
290 return EXIT_SUCCESS;
291}