xref: /reactos/base/system/diskpart/list.c (revision 8a978a17)
1 /*
2  * PROJECT:         ReactOS DiskPart
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * FILE:            base/system/diskpart/list.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 ULONGLONG
18 RoundingDivide(
19    IN ULONGLONG Dividend,
20    IN ULONGLONG Divisor)
21 {
22     return (Dividend + Divisor / 2) / Divisor;
23 }
24 
25 
26 static
27 VOID
28 ListDisk(VOID)
29 {
30     PLIST_ENTRY Entry;
31     PDISKENTRY DiskEntry;
32     ULONGLONG DiskSize;
33     ULONGLONG FreeSize;
34     LPWSTR lpSizeUnit;
35     LPWSTR lpFreeUnit;
36 
37     /* Header labels */
38     ConResPuts(StdOut, IDS_LIST_DISK_HEAD);
39     ConResPuts(StdOut, IDS_LIST_DISK_LINE);
40 
41     Entry = DiskListHead.Flink;
42     while (Entry != &DiskListHead)
43     {
44         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
45 
46         DiskSize = DiskEntry->SectorCount.QuadPart *
47                    (ULONGLONG)DiskEntry->BytesPerSector;
48 
49         if (DiskSize >= 10737418240) /* 10 GB */
50         {
51              DiskSize = RoundingDivide(DiskSize, 1073741824);
52              lpSizeUnit = L"GB";
53         }
54         else
55         {
56              DiskSize = RoundingDivide(DiskSize, 1048576);
57              if (DiskSize == 0)
58                  DiskSize = 1;
59              lpSizeUnit = L"MB";
60         }
61 
62         /* FIXME */
63         FreeSize = 0;
64         lpFreeUnit = L"B";
65 
66         ConResPrintf(StdOut, IDS_LIST_DISK_FORMAT,
67                      (CurrentDisk == DiskEntry) ? L'*': ' ',
68                      DiskEntry->DiskNumber,
69                      L"Online",
70                      DiskSize,
71                      lpSizeUnit,
72                      FreeSize,
73                      lpFreeUnit,
74                      L" ",
75                      L" ");
76 
77         Entry = Entry->Flink;
78     }
79 
80     ConPuts(StdOut, L"\n\n");
81 }
82 
83 static
84 VOID
85 ListPartition(VOID)
86 {
87     PLIST_ENTRY Entry;
88     PPARTENTRY PartEntry;
89     ULONGLONG PartSize;
90     ULONGLONG PartOffset;
91     LPWSTR lpSizeUnit;
92     LPWSTR lpOffsetUnit;
93     ULONG PartNumber = 1;
94 
95     if (CurrentDisk == NULL)
96     {
97         ConResPuts(StdOut, IDS_LIST_PARTITION_NO_DISK);
98         return;
99     }
100 
101     /* Header labels */
102     ConResPuts(StdOut, IDS_LIST_PARTITION_HEAD);
103     ConResPuts(StdOut, IDS_LIST_PARTITION_LINE);
104 
105     Entry = CurrentDisk->PrimaryPartListHead.Flink;
106     while (Entry != &CurrentDisk->PrimaryPartListHead)
107     {
108         PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
109 
110         if (PartEntry->PartitionType != 0)
111         {
112             PartSize = PartEntry->SectorCount.QuadPart * CurrentDisk->BytesPerSector;
113 
114             if (PartSize >= 10737418240) /* 10 GB */
115             {
116                 PartSize = RoundingDivide(PartSize, 1073741824);
117                 lpSizeUnit = L"GB";
118             }
119             else if (PartSize >= 10485760) /* 10 MB */
120             {
121                 PartSize = RoundingDivide(PartSize, 1048576);
122                 lpSizeUnit = L"MB";
123             }
124             else
125             {
126                 PartSize = RoundingDivide(PartSize, 1024);
127                 lpSizeUnit = L"KB";
128             }
129 
130             PartOffset = PartEntry->StartSector.QuadPart * CurrentDisk->BytesPerSector;
131 
132             if (PartOffset >= 10737418240) /* 10 GB */
133             {
134                 PartOffset = RoundingDivide(PartOffset, 1073741824);
135                 lpOffsetUnit = L"GB";
136             }
137             else if (PartOffset >= 10485760) /* 10 MB */
138             {
139                 PartOffset = RoundingDivide(PartOffset, 1048576);
140                 lpOffsetUnit = L"MB";
141             }
142             else
143             {
144                 PartOffset = RoundingDivide(PartOffset, 1024);
145                 lpOffsetUnit = L"KB";
146             }
147 
148             ConResPrintf(StdOut, IDS_LIST_PARTITION_FORMAT,
149                          (CurrentPartition == PartEntry) ? L'*': ' ',
150                          PartNumber++,
151                          IsContainerPartition(PartEntry->PartitionType) ? L"Extended" : L"Primary",
152                          PartSize,
153                          lpSizeUnit,
154                          PartOffset,
155                          lpOffsetUnit);
156         }
157 
158         Entry = Entry->Flink;
159     }
160 
161     Entry = CurrentDisk->LogicalPartListHead.Flink;
162     while (Entry != &CurrentDisk->LogicalPartListHead)
163     {
164         PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
165 
166         if (PartEntry->PartitionType != 0)
167         {
168             PartSize = PartEntry->SectorCount.QuadPart * CurrentDisk->BytesPerSector;
169 
170             if (PartSize >= 10737418240) /* 10 GB */
171             {
172                 PartSize = RoundingDivide(PartSize, 1073741824);
173                 lpSizeUnit = L"GB";
174             }
175             else if (PartSize >= 10485760) /* 10 MB */
176             {
177                 PartSize = RoundingDivide(PartSize, 1048576);
178                 lpSizeUnit = L"MB";
179             }
180             else
181             {
182                 PartSize = RoundingDivide(PartSize, 1024);
183                 lpSizeUnit = L"KB";
184             }
185 
186             PartOffset = PartEntry->StartSector.QuadPart * CurrentDisk->BytesPerSector;
187 
188             if (PartOffset >= 10737418240) /* 10 GB */
189             {
190                 PartOffset = RoundingDivide(PartOffset, 1073741824);
191                 lpOffsetUnit = L"GB";
192             }
193             else if (PartOffset >= 10485760) /* 10 MB */
194             {
195                 PartOffset = RoundingDivide(PartOffset, 1048576);
196                 lpOffsetUnit = L"MB";
197             }
198             else
199             {
200                 PartOffset = RoundingDivide(PartOffset, 1024);
201                 lpOffsetUnit = L"KB";
202             }
203 
204             ConResPrintf(StdOut, IDS_LIST_PARTITION_FORMAT,
205                          (CurrentPartition == PartEntry) ? L'*': ' ',
206                          PartNumber++,
207                          L"Logical",
208                          PartSize,
209                          lpSizeUnit,
210                          PartOffset,
211                          lpOffsetUnit);
212         }
213 
214         Entry = Entry->Flink;
215     }
216 
217     ConPuts(StdOut, L"\n");
218 }
219 
220 static
221 VOID
222 ListVolume(VOID)
223 {
224     ConResPuts(StdOut, IDS_LIST_VOLUME_HEAD);
225 }
226 
227 static
228 VOID
229 ListVdisk(VOID)
230 {
231     ConPuts(StdOut, L"List VDisk!!\n");
232 }
233 
234 BOOL
235 list_main(
236     INT argc,
237     LPWSTR *argv)
238 {
239     /* gets the first word from the string */
240     if (argc == 1)
241     {
242         ConResPuts(StdOut, IDS_HELP_CMD_LIST);
243         return TRUE;
244     }
245 
246     /* determines which to list (disk, partition, etc.) */
247     if (!wcsicmp(argv[1], L"disk"))
248         ListDisk();
249     else if (!wcsicmp(argv[1], L"partition"))
250         ListPartition();
251     else if (!wcsicmp(argv[1], L"volume"))
252         ListVolume();
253     else if (!wcsicmp(argv[1], L"vdisk"))
254         ListVdisk();
255     else
256         ConResPuts(StdOut, IDS_HELP_CMD_LIST);
257 
258     return TRUE;
259 }
260