1 /*
2 * PROJECT: ReactOS DiskPart
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/system/diskpart/detail.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
16 static
17 BOOL
IsDiskInVolume(_In_ PVOLENTRY VolumeEntry,_In_ PDISKENTRY DiskEntry)18 IsDiskInVolume(
19 _In_ PVOLENTRY VolumeEntry,
20 _In_ PDISKENTRY DiskEntry)
21 {
22 ULONG i;
23
24 if ((VolumeEntry == NULL) ||
25 (VolumeEntry->pExtents == NULL) ||
26 (DiskEntry == NULL))
27 return FALSE;
28
29 for (i = 0; i < VolumeEntry->pExtents->NumberOfDiskExtents; i++)
30 {
31 if (VolumeEntry->pExtents->Extents[i].DiskNumber == DiskEntry->DiskNumber)
32 return TRUE;
33 }
34
35 return FALSE;
36 }
37
38
39 static
40 BOOL
IsPartitionInVolume(_In_ PVOLENTRY VolumeEntry,_In_ PPARTENTRY PartEntry)41 IsPartitionInVolume(
42 _In_ PVOLENTRY VolumeEntry,
43 _In_ PPARTENTRY PartEntry)
44 {
45 ULONG i;
46
47 if ((VolumeEntry == NULL) ||
48 (VolumeEntry->pExtents == NULL) ||
49 (PartEntry == NULL) ||
50 (PartEntry->DiskEntry == NULL))
51 return FALSE;
52
53 for (i = 0; i < VolumeEntry->pExtents->NumberOfDiskExtents; i++)
54 {
55 if (VolumeEntry->pExtents->Extents[i].DiskNumber == PartEntry->DiskEntry->DiskNumber)
56 {
57 if ((VolumeEntry->pExtents->Extents[i].StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * PartEntry->DiskEntry->BytesPerSector) &&
58 (VolumeEntry->pExtents->Extents[i].ExtentLength.QuadPart == PartEntry->SectorCount.QuadPart * PartEntry->DiskEntry->BytesPerSector))
59 return TRUE;
60 }
61 }
62
63 return FALSE;
64 }
65
66
67 BOOL
DetailDisk(_In_ INT argc,_In_ PWSTR * argv)68 DetailDisk(
69 _In_ INT argc,
70 _In_ PWSTR *argv)
71 {
72 PLIST_ENTRY Entry;
73 PVOLENTRY VolumeEntry;
74 BOOL bPrintHeader = TRUE;
75
76 DPRINT("DetailDisk()\n");
77
78 if (argc > 2)
79 {
80 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
81 return TRUE;
82 }
83
84 if (CurrentDisk == NULL)
85 {
86 ConResPuts(StdOut, IDS_SELECT_NO_DISK);
87 return TRUE;
88 }
89
90 /* TODO: Print more disk details */
91 ConPuts(StdOut, L"\n");
92 ConResPrintf(StdOut, IDS_DETAIL_INFO_DISK_ID, CurrentDisk->LayoutBuffer->Signature);
93 ConResPrintf(StdOut, IDS_DETAIL_INFO_PATH, CurrentDisk->PathId);
94 ConResPrintf(StdOut, IDS_DETAIL_INFO_TARGET, CurrentDisk->TargetId);
95 ConResPrintf(StdOut, IDS_DETAIL_INFO_LUN_ID, CurrentDisk->Lun);
96
97 Entry = VolumeListHead.Flink;
98 while (Entry != &VolumeListHead)
99 {
100 VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
101
102 if (IsDiskInVolume(VolumeEntry, CurrentDisk))
103 {
104 if (bPrintHeader)
105 {
106 ConPuts(StdOut, L"\n");
107 ConResPuts(StdOut, IDS_LIST_VOLUME_HEAD);
108 ConResPuts(StdOut, IDS_LIST_VOLUME_LINE);
109 bPrintHeader = FALSE;
110 }
111
112 PrintVolume(VolumeEntry);
113 }
114
115 Entry = Entry->Flink;
116 }
117
118 ConPuts(StdOut, L"\n");
119
120 return TRUE;
121 }
122
123
124 BOOL
DetailPartition(_In_ INT argc,_In_ PWSTR * argv)125 DetailPartition(
126 _In_ INT argc,
127 _In_ PWSTR *argv)
128 {
129 PPARTENTRY PartEntry;
130 ULONGLONG PartOffset;
131 PLIST_ENTRY Entry;
132 PVOLENTRY VolumeEntry;
133 BOOL bVolumeFound = FALSE, bPrintHeader = TRUE;
134
135 DPRINT("DetailPartition()\n");
136
137 if (argc > 2)
138 {
139 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
140 return TRUE;
141 }
142
143 if (CurrentDisk == NULL)
144 {
145 ConResPuts(StdOut, IDS_SELECT_PARTITION_NO_DISK);
146 return TRUE;
147 }
148
149 if (CurrentPartition == NULL)
150 {
151 ConResPuts(StdOut, IDS_SELECT_NO_PARTITION);
152 return TRUE;
153 }
154
155 PartEntry = CurrentPartition;
156 PartOffset = PartEntry->StartSector.QuadPart * CurrentDisk->BytesPerSector;
157
158 /* TODO: Print more partition details */
159 ConPuts(StdOut, L"\n");
160 ConResPrintf(StdOut, IDS_DETAIL_PARTITION_NUMBER, PartEntry->PartitionNumber);
161 ConResPrintf(StdOut, IDS_DETAIL_PARTITION_TYPE, PartEntry->PartitionType);
162 ConResPrintf(StdOut, IDS_DETAIL_PARTITION_HIDDEN, "");
163 ConResPrintf(StdOut, IDS_DETAIL_PARTITION_ACTIVE, PartEntry->BootIndicator ? L"Yes" : L"No");
164 ConResPrintf(StdOut, IDS_DETAIL_PARTITION_OFFSET, PartOffset);
165
166 Entry = VolumeListHead.Flink;
167 while (Entry != &VolumeListHead)
168 {
169 VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
170
171 if (IsPartitionInVolume(VolumeEntry, CurrentPartition))
172 {
173 if (bPrintHeader)
174 {
175 ConPuts(StdOut, L"\n");
176 ConResPuts(StdOut, IDS_LIST_VOLUME_HEAD);
177 ConResPuts(StdOut, IDS_LIST_VOLUME_LINE);
178 bPrintHeader = FALSE;
179 }
180
181 PrintVolume(VolumeEntry);
182 bVolumeFound = TRUE;
183 }
184
185 Entry = Entry->Flink;
186 }
187
188 if (bVolumeFound == FALSE)
189 ConResPuts(StdOut, IDS_DETAIL_NO_VOLUME);
190
191 ConPuts(StdOut, L"\n");
192
193 return TRUE;
194 }
195
196
197 BOOL
DetailVolume(_In_ INT argc,_In_ PWSTR * argv)198 DetailVolume(
199 _In_ INT argc,
200 _In_ PWSTR *argv)
201 {
202 PDISKENTRY DiskEntry;
203 PLIST_ENTRY Entry;
204 BOOL bDiskFound = FALSE, bPrintHeader = TRUE;
205
206 DPRINT("DetailVolume()\n");
207
208 if (argc > 2)
209 {
210 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
211 return TRUE;
212 }
213
214 if (CurrentVolume == NULL)
215 {
216 ConResPuts(StdOut, IDS_SELECT_NO_VOLUME);
217 return TRUE;
218 }
219
220
221 Entry = DiskListHead.Flink;
222 while (Entry != &DiskListHead)
223 {
224 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
225
226 if (IsDiskInVolume(CurrentVolume, DiskEntry))
227 {
228 if (bPrintHeader)
229 {
230 ConPuts(StdOut, L"\n");
231 ConResPuts(StdOut, IDS_LIST_DISK_HEAD);
232 ConResPuts(StdOut, IDS_LIST_DISK_LINE);
233 bPrintHeader = FALSE;
234 }
235
236 PrintDisk(DiskEntry);
237 bDiskFound = TRUE;
238 }
239
240 Entry = Entry->Flink;
241 }
242
243 if (bDiskFound == FALSE)
244 ConResPuts(StdOut, IDS_DETAIL_NO_DISKS);
245
246 /* TODO: Print more volume details */
247
248 ConPuts(StdOut, L"\n");
249
250 return TRUE;
251 }
252