xref: /reactos/base/system/diskpart/detail.c (revision 09dde2cf)
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
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
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
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
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
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