https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5a1c00c1178b79f550aed0430c8e26f4892032fa

commit 5a1c00c1178b79f550aed0430c8e26f4892032fa
Author:     Eric Kohl <[email protected]>
AuthorDate: Sun May 29 12:41:42 2022 +0200
Commit:     Eric Kohl <[email protected]>
CommitDate: Sun May 29 12:41:42 2022 +0200

    [DISKPART] Improve the LIST VOLUME command
---
 base/system/diskpart/diskpart.h    |  12 ++-
 base/system/diskpart/lang/en-US.rc |   6 +-
 base/system/diskpart/lang/pl-PL.rc |   6 +-
 base/system/diskpart/lang/pt-PT.rc |   6 +-
 base/system/diskpart/lang/ro-RO.rc |   6 +-
 base/system/diskpart/lang/ru-RU.rc |   6 +-
 base/system/diskpart/lang/sq-AL.rc |   6 +-
 base/system/diskpart/lang/tr-TR.rc |   6 +-
 base/system/diskpart/lang/zh-CN.rc |   6 +-
 base/system/diskpart/lang/zh-TW.rc |   6 +-
 base/system/diskpart/list.c        |  45 ++++++--
 base/system/diskpart/partlist.c    | 211 ++++++++++++++++++++++++++++++++-----
 12 files changed, 258 insertions(+), 64 deletions(-)

diff --git a/base/system/diskpart/diskpart.h b/base/system/diskpart/diskpart.h
index 218b6030a17..23ea593e7b4 100644
--- a/base/system/diskpart/diskpart.h
+++ b/base/system/diskpart/diskpart.h
@@ -83,6 +83,14 @@ typedef enum _FORMATSTATE
     Formatted
 } FORMATSTATE, *PFORMATSTATE;
 
+typedef enum _VOLUME_TYPE
+{
+    VOLUME_TYPE_CDROM,
+    VOLUME_TYPE_PARTITION,
+    VOLUME_TYPE_REMOVABLE,
+    VOLUME_TYPE_UNKNOWN
+} VOLUME_TYPE, *PVOLUME_TYPE;
+
 typedef struct _PARTENTRY
 {
     LIST_ENTRY ListEntry;
@@ -185,9 +193,11 @@ typedef struct _VOLENTRY
 
     PWSTR pszLabel;
     PWSTR pszFilesystem;
-    UINT DriveType;
+    VOLUME_TYPE VolumeType;
     ULARGE_INTEGER Size;
 
+    PVOLUME_DISK_EXTENTS pExtents;
+
 } VOLENTRY, *PVOLENTRY;
 
 
diff --git a/base/system/diskpart/lang/en-US.rc 
b/base/system/diskpart/lang/en-US.rc
index 7289cb2d159..4eeadf4066a 100644
--- a/base/system/diskpart/lang/en-US.rc
+++ b/base/system/diskpart/lang/en-US.rc
@@ -47,16 +47,16 @@ END
 /* Detail header titles */
 STRINGTABLE
 BEGIN
-    IDS_LIST_DISK_HEAD "\n  Disk ###  Status      Size     Free     Dyn  Gpt\n"
+    IDS_LIST_DISK_HEAD "  Disk ###  Status      Size     Free     Dyn  Gpt\n"
     IDS_LIST_DISK_LINE "  --------  ----------  -------  -------  ---  ---\n"
     IDS_LIST_DISK_FORMAT "%c %7lu   %-10s  %4I64u %-2s  %4I64u %-2s   %1s    
%1s\n"
-    IDS_LIST_PARTITION_HEAD "\n  Partition      Type              Size     
Offset\n"
+    IDS_LIST_PARTITION_HEAD "  Partition      Type              Size     
Offset\n"
     IDS_LIST_PARTITION_LINE "  -------------  ----------------  -------  
-------\n"
     IDS_LIST_PARTITION_FORMAT "%c Partition %2lu   %-16s  %4I64u %-2s  %4I64u 
%-2s\n"
     IDS_LIST_PARTITION_NO_DISK "\nThere is no disk to list partitions.\nPlease 
select a disk and try again.\n\n"
     IDS_LIST_VOLUME_HEAD "  Volume ###  Ltr  Label        FS     Type        
Size     Status   Info\n"
     IDS_LIST_VOLUME_LINE "  ----------  ---  -----------  -----  ----------  
-------  -------  --------\n"
-    IDS_LIST_VOLUME_FORMAT "  Volume %-3lu   %c   %-11.11s  %-5s  %10u  %4I64u 
%-2s\n"
+    IDS_LIST_VOLUME_FORMAT "%c Volume %-3lu   %c   %-11.11s  %-5s  %-10.10s  
%4I64u %-2s\n"
 END
 
 /* RESCAN command string */
diff --git a/base/system/diskpart/lang/pl-PL.rc 
b/base/system/diskpart/lang/pl-PL.rc
index 426c948519d..69de3471d20 100644
--- a/base/system/diskpart/lang/pl-PL.rc
+++ b/base/system/diskpart/lang/pl-PL.rc
@@ -47,16 +47,16 @@ END
 /* Detail header titles */
 STRINGTABLE
 BEGIN
-    IDS_LIST_DISK_HEAD "\nDysk ###  Stan        Rozmiar  Wolne    Dyn  Gpt\n"
+    IDS_LIST_DISK_HEAD "  Dysk ###  Stan        Rozmiar  Wolne    Dyn  Gpt\n"
     IDS_LIST_DISK_LINE "  --------  ----------  -------  -------  ---  ---\n"
     IDS_LIST_DISK_FORMAT "%c %7lu   %-10s  %4I64u %-2s  %4I64u %-2s   %1s    
%1s\n"
-    IDS_LIST_PARTITION_HEAD "\nPartycja       Typ               Rozmiar  
Przesunięcie\n"
+    IDS_LIST_PARTITION_HEAD "  Partycja       Typ               Rozmiar  
Przesunięcie\n"
     IDS_LIST_PARTITION_LINE "  -------------  ----------------  -------  
------------\n"
     IDS_LIST_PARTITION_FORMAT "%c Partycja    %2lu   %-16s  %4I64u %-2s  
%4I64u %-2s\n"
     IDS_LIST_PARTITION_NO_DISK "\nNie wybrano dysku do wyświetlenia 
partycji.\nWybierz dysk i spróbuj ponownie.\n\n"
     IDS_LIST_VOLUME_HEAD "  Wolumin ###  Lit  Etykieta     FS     Typ         
Rozmiar  Stan     Info\n"
     IDS_LIST_VOLUME_LINE "  -----------  ---  -----------  -----  ----------  
-------  -------  --------\n"
-    IDS_LIST_VOLUME_FORMAT "  Wolumin %-3lu   %c   %-11.11s  %-5s  %10u  
%4I64u %-2s\n"
+    IDS_LIST_VOLUME_FORMAT "%c Wolumin %-3lu   %c   %-11.11s  %-5s  %-10.10s  
%4I64u %-2s\n"
 END
 
 /* RESCAN command string */
diff --git a/base/system/diskpart/lang/pt-PT.rc 
b/base/system/diskpart/lang/pt-PT.rc
index 86ec0a9c6e1..0edee6239c9 100644
--- a/base/system/diskpart/lang/pt-PT.rc
+++ b/base/system/diskpart/lang/pt-PT.rc
@@ -44,16 +44,16 @@ END
 /* Detail header titles */
 STRINGTABLE
 BEGIN
-    IDS_LIST_DISK_HEAD "\n Disco  ##  Estado     Tamanho    Livre   Dyn  Gpt\n"
+    IDS_LIST_DISK_HEAD "  Disco ##  Estado      Tamanho    Livre    Dyn  Gpt\n"
     IDS_LIST_DISK_LINE "  --------  ----------  ---------  -------  ---  ---\n"
     IDS_LIST_DISK_FORMAT "%c %7lu   %-10s  %4I64u %-2s  %4I64u %-2s   %1s    
%1s\n"
-    IDS_LIST_PARTITION_HEAD "\n  Partição      Tipo     Tamanho     
deslocamento\n"
+    IDS_LIST_PARTITION_HEAD "  Partição       Tipo     Tamanho    
deslocamento\n"
     IDS_LIST_PARTITION_LINE "  -------------  -------  ---------  -------\n"
     IDS_LIST_PARTITION_FORMAT "%c Partição %2lu   %-16s  %4I64u %-2s  %4I64u 
%-2s\n"
     IDS_LIST_PARTITION_NO_DISK "\nSem discos para listar Partições.\nPor favor 
seleccione um disco e tente novamente.\n\n"
     IDS_LIST_VOLUME_HEAD "  Volume ###  Ltr  Label        FS     Type        
Size     Status   Info\n"
     IDS_LIST_VOLUME_LINE "  ----------  ---  -----------  -----  ----------  
-------  -------  --------\n"
-    IDS_LIST_VOLUME_FORMAT "  Volume %-3lu   %c   %-11.11s  %-5s  %10u  %4I64u 
%-2s\n"
+    IDS_LIST_VOLUME_FORMAT "%c Volume %-3lu   %c   %-11.11s  %-5s  %-10.10s  
%4I64u %-2s\n"
 END
 
 STRINGTABLE
diff --git a/base/system/diskpart/lang/ro-RO.rc 
b/base/system/diskpart/lang/ro-RO.rc
index add736038ea..7f69919ca93 100644
--- a/base/system/diskpart/lang/ro-RO.rc
+++ b/base/system/diskpart/lang/ro-RO.rc
@@ -44,16 +44,16 @@ END
 /* Detail header titles */
 STRINGTABLE
 BEGIN
-    IDS_LIST_DISK_HEAD "\n  Disc ###  Stare       Dimensiune  Liber    Dyn  
Gpt\n"
+    IDS_LIST_DISK_HEAD "  Disc ###  Stare       Dimensiune  Liber    Dyn  
Gpt\n"
     IDS_LIST_DISK_LINE "  --------  ----------  ----------  -------  ---  
---\n"
     IDS_LIST_DISK_FORMAT "%c %7lu   %-10s  %4I64u %-2s  %4I64u %-2s   %1s    
%1s\n"
-    IDS_LIST_PARTITION_HEAD "\n  Partiție       Tip               Dim.     
Depl.\n"
+    IDS_LIST_PARTITION_HEAD "  Partiție       Tip               Dim.     
Depl.\n"
     IDS_LIST_PARTITION_LINE "  -------------  ----------------  -------  
-------\n"
     IDS_LIST_PARTITION_FORMAT "%c Partiție  %2lu   %-16s  %4I64u %-2s  %4I64u 
%-2s\n"
     IDS_LIST_PARTITION_NO_DISK "\nNu există niciun disc pentru a afișa 
partiții.\nSelectați un disc apoi reîncercați.\n\n"
     IDS_LIST_VOLUME_HEAD "  Volume ###  Ltr  Label        FS     Type        
Size     Status   Info\n"
     IDS_LIST_VOLUME_LINE "  ----------  ---  -----------  -----  ----------  
-------  -------  --------\n"
-    IDS_LIST_VOLUME_FORMAT "  Volume %-3lu   %c   %-11.11s  %-5s  %10u  %4I64u 
%-2s\n"
+    IDS_LIST_VOLUME_FORMAT "%c  Volume %-3lu   %c   %-11.11s  %-5s  %-10.10s  
%4I64u %-2s\n"
 END
 
 STRINGTABLE
diff --git a/base/system/diskpart/lang/ru-RU.rc 
b/base/system/diskpart/lang/ru-RU.rc
index 41867204039..3ecfe9122bf 100644
--- a/base/system/diskpart/lang/ru-RU.rc
+++ b/base/system/diskpart/lang/ru-RU.rc
@@ -44,16 +44,16 @@ END
 /* Detail header titles */
 STRINGTABLE
 BEGIN
-    IDS_LIST_DISK_HEAD "\n  Диск ###  Состояние   Размер   Свободно  Дин  
GPT\n"
+    IDS_LIST_DISK_HEAD "  Диск ###  Состояние   Размер   Свободно  Дин  GPT\n"
     IDS_LIST_DISK_LINE "  --------  ----------  -------  --------  ---  ---\n"
     IDS_LIST_DISK_FORMAT "%c %7lu   %-10s  %4I64u %-2s  %4I64u %-2s   %1s    
%1s\n"
-    IDS_LIST_PARTITION_HEAD "\n  Разметка       Тип              Размер    
Отступ\n"
+    IDS_LIST_PARTITION_HEAD "  Разметка       Тип              Размер    
Отступ\n"
     IDS_LIST_PARTITION_LINE "  -------------  ----------------  -------  
-------\n"
     IDS_LIST_PARTITION_FORMAT "%c Раздел %2lu   %-16s  %4I64u %-2s  %4I64u 
%-2s\n"
     IDS_LIST_PARTITION_NO_DISK "\nДиск с разметкой элементов не 
выбран.\nУкажите диск и повторите попытку.\n\n"
     IDS_LIST_VOLUME_HEAD "  Volume ###  Ltr  Label        FS     Type        
Size     Status   Info\n"
     IDS_LIST_VOLUME_LINE "  ----------  ---  -----------  -----  ----------  
-------  -------  --------\n"
-    IDS_LIST_VOLUME_FORMAT "  Volume %-3lu   %c   %-11.11s  %-5s  %10u  %4I64u 
%-2s\n"
+    IDS_LIST_VOLUME_FORMAT "%c Volume %-3lu   %c   %-11.11s  %-5s  %-10.10s  
%4I64u %-2s\n"
 END
 
 STRINGTABLE
diff --git a/base/system/diskpart/lang/sq-AL.rc 
b/base/system/diskpart/lang/sq-AL.rc
index 1f75c1588bf..49e7ea9ff34 100644
--- a/base/system/diskpart/lang/sq-AL.rc
+++ b/base/system/diskpart/lang/sq-AL.rc
@@ -46,16 +46,16 @@ END
 /* Detail header titles */
 STRINGTABLE
 BEGIN
-    IDS_LIST_DISK_HEAD "\n  Disk ###  Status      Size     Free     Dyn  Gpt\n"
+    IDS_LIST_DISK_HEAD "  Disk ###  Status      Size     Free     Dyn  Gpt\n"
     IDS_LIST_DISK_LINE "  --------  ----------  -------  -------  ---  ---\n"
     IDS_LIST_DISK_FORMAT "%c %7lu   %-10s  %4I64u %-2s  %4I64u %-2s   %1s    
%1s\n"
-    IDS_LIST_PARTITION_HEAD "\n  Partition      Type              Size     
Offset\n"
+    IDS_LIST_PARTITION_HEAD "  Partition      Type              Size     
Offset\n"
     IDS_LIST_PARTITION_LINE "%c -------------  ----------------  -------  
-------\n"
     IDS_LIST_PARTITION_FORMAT "  Partition %2lu   %-16s  %4I64u %-2s  %4I64u 
%-2s\n"
     IDS_LIST_PARTITION_NO_DISK "\nThere is no disk to list partitions.\nPlease 
select a disk and try again.\n\n"
     IDS_LIST_VOLUME_HEAD "  Volume ###  Ltr  Label        FS     Type        
Size     Status   Info\n"
     IDS_LIST_VOLUME_LINE "  ----------  ---  -----------  -----  ----------  
-------  -------  --------\n"
-    IDS_LIST_VOLUME_FORMAT "  Volume %-3lu   %c   %-11.11s  %-5s  %10u  %4I64u 
%-2s\n"
+    IDS_LIST_VOLUME_FORMAT "%c Volume %-3lu   %c   %-11.11s  %-5s  %-10.10s  
%4I64u %-2s\n"
 END
 
 STRINGTABLE
diff --git a/base/system/diskpart/lang/tr-TR.rc 
b/base/system/diskpart/lang/tr-TR.rc
index 1daaf0e90e4..bb106bccd82 100644
--- a/base/system/diskpart/lang/tr-TR.rc
+++ b/base/system/diskpart/lang/tr-TR.rc
@@ -44,16 +44,16 @@ END
 /* Detail header titles */
 STRINGTABLE
 BEGIN
-    IDS_LIST_DISK_HEAD "\n  Disk ###    Durum      Boyut     Boş     Dev  
Gpt\n"
+    IDS_LIST_DISK_HEAD "  Disk ###    Durum      Boyut     Boş     Dev  Gpt\n"
     IDS_LIST_DISK_LINE "  --------  ----------  -------  -------  ---  ---\n"
     IDS_LIST_DISK_FORMAT "%c %7lu   %-10s  %4I64u %-2s   %4I64u %-2s  %1s   
%1s\n"
-    IDS_LIST_PARTITION_HEAD "\n      Bölüm              Tür        Boyut    
Ofset\n"
+    IDS_LIST_PARTITION_HEAD "      Bölüm              Tür        Boyut    
Ofset\n"
     IDS_LIST_PARTITION_LINE "  -------------  ----------------  -------  
-------\n"
     IDS_LIST_PARTITION_FORMAT "%c Bölüm %2lu       %-16s  %4I64u %-2s  %4I64u 
%-2s\n"
     IDS_LIST_PARTITION_NO_DISK "\nBölümleri listelemek için bir disk 
yok.\nLütfen bir disk seçiniz ve yeniden deneyiniz.\n\n"
     IDS_LIST_VOLUME_HEAD "  Volume ###  Ltr  Label        FS     Type        
Size     Status   Info\n"
     IDS_LIST_VOLUME_LINE "  ----------  ---  -----------  -----  ----------  
-------  -------  --------\n"
-    IDS_LIST_VOLUME_FORMAT "  Volume %-3lu   %c   %-11.11s  %-5s  %10u  %4I64u 
%-2s\n"
+    IDS_LIST_VOLUME_FORMAT "%c Volume %-3lu   %c   %-11.11s  %-5s  %-10.10s  
%4I64u %-2s\n"
 END
 
 STRINGTABLE
diff --git a/base/system/diskpart/lang/zh-CN.rc 
b/base/system/diskpart/lang/zh-CN.rc
index e698bc05167..1a23e12d8cd 100644
--- a/base/system/diskpart/lang/zh-CN.rc
+++ b/base/system/diskpart/lang/zh-CN.rc
@@ -51,16 +51,16 @@ END
 /* Detail header titles */
 STRINGTABLE
 BEGIN
-    IDS_LIST_DISK_HEAD "\n  磁盘 ###   状态      大小     可用    活动 Gpt\n"
+    IDS_LIST_DISK_HEAD "  磁盘 ###   状态      大小     可用    活动 Gpt\n"
     IDS_LIST_DISK_LINE "  --------  ----------  -------  -------  ---  ---\n"
     IDS_LIST_DISK_FORMAT "%c %7lu   %-10s  %4I64u %-2s  %4I64u %-2s   %1s    
%1s\n"
-    IDS_LIST_PARTITION_HEAD "\n     分区           类型          大小     偏移量\n"
+    IDS_LIST_PARTITION_HEAD "     分区           类型          大小     偏移量\n"
     IDS_LIST_PARTITION_LINE "  -------------  ----------------  -------  
-------\n"
     IDS_LIST_PARTITION_FORMAT "%c Partition %2lu   %-16s  %4I64u %-2s  %4I64u 
%-2s\n"
     IDS_LIST_PARTITION_NO_DISK "\n这里没有要列出分区的磁盘。\n请选择一个磁盘,再试一次。\n\n"
     IDS_LIST_VOLUME_HEAD "  Volume ###  Ltr  Label        FS     Type        
Size     Status   Info\n"
     IDS_LIST_VOLUME_LINE "  ----------  ---  -----------  -----  ----------  
-------  -------  --------\n"
-    IDS_LIST_VOLUME_FORMAT "  Volume %-3lu   %c   %-11.11s  %-5s  %10u  %4I64u 
%-2s\n"
+    IDS_LIST_VOLUME_FORMAT "%c  Volume %-3lu   %c   %-11.11s  %-5s  %-10.10s  
%4I64u %-2s\n"
 END
 
 STRINGTABLE
diff --git a/base/system/diskpart/lang/zh-TW.rc 
b/base/system/diskpart/lang/zh-TW.rc
index 87dad569f01..6f931d2e0dd 100644
--- a/base/system/diskpart/lang/zh-TW.rc
+++ b/base/system/diskpart/lang/zh-TW.rc
@@ -45,16 +45,16 @@ END
 /* Detail header titles */
 STRINGTABLE
 BEGIN
-    IDS_LIST_DISK_HEAD "\n  磁碟 ###   狀態      大小     可用    Dyn  Gpt\n"
+    IDS_LIST_DISK_HEAD "  磁碟 ###   狀態      大小     可用    Dyn  Gpt\n"
     IDS_LIST_DISK_LINE "  --------  ----------  -------  -------  ---  ---\n"
     IDS_LIST_DISK_FORMAT "%c %7lu   %-10s  %4I64u %-2s  %4I64u %-2s   %1s    
%1s\n"
-    IDS_LIST_PARTITION_HEAD "\n     分區           類型          大小     偏移量\n"
+    IDS_LIST_PARTITION_HEAD "     分區           類型          大小     偏移量\n"
     IDS_LIST_PARTITION_LINE "  -------------  ----------------  -------  
-------\n"
     IDS_LIST_PARTITION_FORMAT "%c 磁碟分割 %2lu   %-16s  %4I64u %-2s  %4I64u 
%-2s\n"
     IDS_LIST_PARTITION_NO_DISK "\n沒有可列出分區的磁碟。\n請選擇一個磁碟,再試一次。\n\n"
     IDS_LIST_VOLUME_HEAD "  Volume ###  Ltr  Label        FS     Type        
Size     Status   Info\n"
     IDS_LIST_VOLUME_LINE "  ----------  ---  -----------  -----  ----------  
-------  -------  --------\n"
-    IDS_LIST_VOLUME_FORMAT "  Volume %-3lu   %c   %-11.11s  %-5s  %10u  %4I64u 
%-2s\n"
+    IDS_LIST_VOLUME_FORMAT "%c Volume %-3lu   %c   %-11.11s  %-5s  %-10.10s  
%4I64u %-2s\n"
 END
 
 STRINGTABLE
diff --git a/base/system/diskpart/list.c b/base/system/diskpart/list.c
index 4eb1d8fb823..21589c727cf 100644
--- a/base/system/diskpart/list.c
+++ b/base/system/diskpart/list.c
@@ -26,6 +26,7 @@ ListDisk(
     LPWSTR lpFreeUnit;
 
     /* Header labels */
+    ConPuts(StdOut, L"\n");
     ConResPuts(StdOut, IDS_LIST_DISK_HEAD);
     ConResPuts(StdOut, IDS_LIST_DISK_LINE);
 
@@ -55,7 +56,7 @@ ListDisk(
         lpFreeUnit = L"B";
 
         ConResPrintf(StdOut, IDS_LIST_DISK_FORMAT,
-                     (CurrentDisk == DiskEntry) ? L'*': ' ',
+                     (CurrentDisk == DiskEntry) ? L'*' : L' ',
                      DiskEntry->DiskNumber,
                      L"Online",
                      DiskSize,
@@ -94,6 +95,7 @@ ListPartition(
     }
 
     /* Header labels */
+    ConPuts(StdOut, L"\n");
     ConResPuts(StdOut, IDS_LIST_PARTITION_HEAD);
     ConResPuts(StdOut, IDS_LIST_PARTITION_LINE);
 
@@ -141,7 +143,7 @@ ListPartition(
             }
 
             ConResPrintf(StdOut, IDS_LIST_PARTITION_FORMAT,
-                         (CurrentPartition == PartEntry) ? L'*': ' ',
+                         (CurrentPartition == PartEntry) ? L'*' : L' ',
                          PartNumber++,
                          IsContainerPartition(PartEntry->PartitionType) ? 
L"Extended" : L"Primary",
                          PartSize,
@@ -197,7 +199,7 @@ ListPartition(
             }
 
             ConResPrintf(StdOut, IDS_LIST_PARTITION_FORMAT,
-                         (CurrentPartition == PartEntry) ? L'*': ' ',
+                         (CurrentPartition == PartEntry) ? L'*' : L' ',
                          PartNumber++,
                          L"Logical",
                          PartSize,
@@ -223,8 +225,10 @@ ListVolume(
     PLIST_ENTRY Entry;
     PVOLENTRY VolumeEntry;
     ULONGLONG VolumeSize;
-    LPWSTR lpSizeUnit;
+    PWSTR pszSizeUnit;
+    PWSTR pszVolumeType;
 
+    ConPuts(StdOut, L"\n");
     ConResPuts(StdOut, IDS_LIST_VOLUME_HEAD);
     ConResPuts(StdOut, IDS_LIST_VOLUME_LINE);
 
@@ -237,31 +241,52 @@ ListVolume(
         if (VolumeSize >= 10737418240) /* 10 GB */
         {
             VolumeSize = RoundingDivide(VolumeSize, 1073741824);
-            lpSizeUnit = L"GB";
+            pszSizeUnit = L"GB";
         }
         else if (VolumeSize >= 10485760) /* 10 MB */
         {
             VolumeSize = RoundingDivide(VolumeSize, 1048576);
-            lpSizeUnit = L"MB";
+            pszSizeUnit = L"MB";
         }
         else
         {
             VolumeSize = RoundingDivide(VolumeSize, 1024);
-            lpSizeUnit = L"KB";
+            pszSizeUnit = L"KB";
+        }
+
+        switch (VolumeEntry->VolumeType)
+        {
+            case VOLUME_TYPE_CDROM:
+                pszVolumeType = L"DVD";
+                break;
+
+            case VOLUME_TYPE_PARTITION:
+                pszVolumeType = L"Partition";
+                break;
+
+            case VOLUME_TYPE_REMOVABLE:
+                pszVolumeType = L"Removable";
+                break;
+
+            case VOLUME_TYPE_UNKNOWN:
+            default:
+                pszVolumeType = L"Unknown";
+                break;
         }
 
         ConResPrintf(StdOut, IDS_LIST_VOLUME_FORMAT,
+                     (CurrentVolume == VolumeEntry) ? L'*' : L' ',
                      VolumeEntry->VolumeNumber,
                      VolumeEntry->DriveLetter,
                      (VolumeEntry->pszLabel) ? VolumeEntry->pszLabel : L"",
                      (VolumeEntry->pszFilesystem) ? VolumeEntry->pszFilesystem 
: L"",
-                     VolumeEntry->DriveType,
-                     VolumeSize, lpSizeUnit);
+                     pszVolumeType,
+                     VolumeSize, pszSizeUnit);
 
         Entry = Entry->Flink;
     }
 
-    ConPuts(StdOut, L"\n\n");
+    ConPuts(StdOut, L"\n");
 
     return TRUE;
 }
diff --git a/base/system/diskpart/partlist.c b/base/system/diskpart/partlist.c
index 568f902ea38..038557a4133 100644
--- a/base/system/diskpart/partlist.c
+++ b/base/system/diskpart/partlist.c
@@ -1186,6 +1186,112 @@ DestroyPartitionList(VOID)
 }
 
 
+static
+VOID
+GetVolumeExtents(
+    _In_ HANDLE VolumeHandle,
+    _In_ PVOLENTRY VolumeEntry)
+{
+    DWORD dwBytesReturned = 0, dwLength, i;
+    PVOLUME_DISK_EXTENTS pExtents;
+    BOOL bResult;
+    DWORD dwError;
+
+    dwLength = sizeof(VOLUME_DISK_EXTENTS);
+    pExtents = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, 
dwLength);
+    if (pExtents == NULL)
+        return;
+
+    bResult = DeviceIoControl(VolumeHandle,
+                              IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
+                              NULL,
+                              0,
+                              pExtents,
+                              dwLength,
+                              &dwBytesReturned,
+                              NULL);
+    if (!bResult)
+    {
+        dwError = GetLastError();
+
+        if (dwError != ERROR_MORE_DATA)
+        {
+            RtlFreeHeap(RtlGetProcessHeap(), 0, pExtents);
+            return;
+        }
+        else
+        {
+            dwLength = sizeof(VOLUME_DISK_EXTENTS) + 
((pExtents->NumberOfDiskExtents - 1) * sizeof(DISK_EXTENT));
+            RtlFreeHeap(RtlGetProcessHeap(), 0, pExtents);
+            pExtents = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, 
dwLength);
+            if (pExtents == NULL)
+            {
+                return;
+            }
+
+            bResult = DeviceIoControl(VolumeHandle,
+                                      IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
+                                      NULL,
+                                      0,
+                                      pExtents,
+                                      dwLength,
+                                      &dwBytesReturned,
+                                      NULL);
+            if (!bResult)
+            {
+                RtlFreeHeap(RtlGetProcessHeap(), 0, pExtents);
+                return;
+            }
+        }
+    }
+
+    for (i = 0; i < pExtents->NumberOfDiskExtents; i++)
+        VolumeEntry->Size.QuadPart += 
pExtents->Extents[i].ExtentLength.QuadPart;
+
+    VolumeEntry->pExtents = pExtents;
+}
+
+
+static
+VOID
+GetVolumeType(
+    HANDLE VolumeHandle,
+    _In_ PVOLENTRY VolumeEntry)
+{
+    FILE_FS_DEVICE_INFORMATION DeviceInfo;
+    IO_STATUS_BLOCK IoStatusBlock;
+    NTSTATUS Status;
+
+    Status = NtQueryVolumeInformationFile(VolumeHandle,
+                                          &IoStatusBlock,
+                                          &DeviceInfo,
+                                          sizeof(FILE_FS_DEVICE_INFORMATION),
+                                          FileFsDeviceInformation);
+    if (!NT_SUCCESS(Status))
+        return;
+
+    switch (DeviceInfo.DeviceType)
+    {
+        case FILE_DEVICE_CD_ROM:
+        case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
+            VolumeEntry->VolumeType = VOLUME_TYPE_CDROM;
+            break;
+
+        case FILE_DEVICE_DISK:
+        case FILE_DEVICE_DISK_FILE_SYSTEM:
+            if (DeviceInfo.Characteristics & FILE_REMOVABLE_MEDIA)
+                VolumeEntry->VolumeType = VOLUME_TYPE_REMOVABLE;
+            else
+                VolumeEntry->VolumeType = VOLUME_TYPE_PARTITION;
+            break;
+
+        default:
+            VolumeEntry->VolumeType = VOLUME_TYPE_UNKNOWN;
+            break;
+    }
+}
+
+
 static
 VOID
 AddVolumeToList(
@@ -1193,30 +1299,72 @@ AddVolumeToList(
     PWSTR pszVolumeName)
 {
     PVOLENTRY VolumeEntry;
+    HANDLE VolumeHandle;
 
-    WCHAR szPathNames[256];
-    DWORD dwLength;
+    DWORD dwError, dwLength;
+    WCHAR szPathNames[MAX_PATH + 1];
     WCHAR szVolumeName[MAX_PATH + 1];
     WCHAR szFilesystem[MAX_PATH + 1];
 
+    DWORD  CharCount            = 0;
+    WCHAR  DeviceName[MAX_PATH] = L"";
+    size_t Index                = 0;
+
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING Name;
+    IO_STATUS_BLOCK Iosb;
+    NTSTATUS Status;
+
+
+    ConPrintf(StdOut, L"AddVolumeToList(%s)\n", pszVolumeName);
 
     VolumeEntry = RtlAllocateHeap(RtlGetProcessHeap(),
                                   HEAP_ZERO_MEMORY,
                                   sizeof(VOLENTRY));
     if (VolumeEntry == NULL)
+        return;
+
+    VolumeEntry->VolumeNumber = ulVolumeNumber;
+    wcscpy(VolumeEntry->VolumeName, pszVolumeName);
+
+    Index = wcslen(pszVolumeName) - 1;
+
+    pszVolumeName[Index] = L'\0';
+
+    CharCount = QueryDosDeviceW(&pszVolumeName[4], DeviceName, 
ARRAYSIZE(DeviceName)); 
+
+    pszVolumeName[Index] = L'\\';
+
+    if (CharCount == 0)
     {
+        RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry);
         return;
     }
 
+    DPRINT("DeviceName: %S\n", DeviceName);
 
-    if (GetVolumePathNamesForVolumeNameW(pszVolumeName,
-                                     szPathNames,
-                                     256,
-                                     &dwLength))
+    RtlInitUnicodeString(&Name, DeviceName);
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &Name,
+                               0,
+                               NULL,
+                               NULL);
+
+    Status = NtOpenFile(&VolumeHandle,
+                        SYNCHRONIZE,
+                        &ObjectAttributes,
+                        &Iosb,
+                        0,
+                        FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | 
FILE_OPEN_FOR_BACKUP_INTENT);
+    if (NT_SUCCESS(Status))
     {
-        VolumeEntry->DriveLetter = szPathNames[0];
+        GetVolumeType(VolumeHandle, VolumeEntry);
+        GetVolumeExtents(VolumeHandle, VolumeEntry);
+        NtClose(VolumeHandle);
+    }
 
-        if (GetVolumeInformationW(szPathNames,
+    if (GetVolumeInformationW(pszVolumeName,
                               szVolumeName,
                               MAX_PATH + 1,
                               NULL, //  [out, optional] LPDWORD 
lpVolumeSerialNumber,
@@ -1224,31 +1372,39 @@ AddVolumeToList(
                               NULL, //  [out, optional] LPDWORD 
lpFileSystemFlags,
                               szFilesystem,
                               MAX_PATH + 1))
-        {
-            VolumeEntry->pszLabel = RtlAllocateHeap(RtlGetProcessHeap(),
-                                                    0,
-                                                    (wcslen(szVolumeName) + 1) 
* sizeof(WCHAR));
-            if (VolumeEntry->pszLabel)
-                wcscpy(VolumeEntry->pszLabel, szVolumeName);
+    {
+        VolumeEntry->pszLabel = RtlAllocateHeap(RtlGetProcessHeap(),
+                                                0,
+                                                (wcslen(szVolumeName) + 1) * 
sizeof(WCHAR));
+        if (VolumeEntry->pszLabel)
+            wcscpy(VolumeEntry->pszLabel, szVolumeName);
 
+        VolumeEntry->pszFilesystem = RtlAllocateHeap(RtlGetProcessHeap(),
+                                                     0,
+                                                     (wcslen(szFilesystem) + 
1) * sizeof(WCHAR));
+        if (VolumeEntry->pszFilesystem)
+            wcscpy(VolumeEntry->pszFilesystem, szFilesystem);
+    }
+    else
+    {
+        dwError = GetLastError();
+        if (dwError == ERROR_UNRECOGNIZED_VOLUME)
+        {
             VolumeEntry->pszFilesystem = RtlAllocateHeap(RtlGetProcessHeap(),
                                                          0,
-                                                         (wcslen(szFilesystem) 
+ 1) * sizeof(WCHAR));
+                                                         (3 + 1) * 
sizeof(WCHAR));
             if (VolumeEntry->pszFilesystem)
-                wcscpy(VolumeEntry->pszFilesystem, szFilesystem);
-
-            VolumeEntry->DriveType = GetDriveType(szPathNames);
-
-            GetDiskFreeSpaceExW(szPathNames,
-                                NULL, //  [out, optional] PULARGE_INTEGER 
lpFreeBytesAvailableToCaller,
-                                &VolumeEntry->Size, //  [out, optional] 
PULARGE_INTEGER lpTotalNumberOfBytes,
-                                NULL //    [out, optional] PULARGE_INTEGER 
lpTotalNumberOfFreeBytes
-                                );
+                wcscpy(VolumeEntry->pszFilesystem, L"RAW");
         }
     }
 
-    VolumeEntry->VolumeNumber = ulVolumeNumber;
-    wcscpy(VolumeEntry->VolumeName, pszVolumeName);
+    if (GetVolumePathNamesForVolumeNameW(pszVolumeName,
+                                         szPathNames,
+                                         ARRAYSIZE(szPathNames),
+                                         &dwLength))
+    {
+        VolumeEntry->DriveLetter = szPathNames[0];
+    }
 
     InsertTailList(&VolumeListHead,
                    &VolumeEntry->ListEntry);
@@ -1313,6 +1469,9 @@ DestroyVolumeList(VOID)
         if (VolumeEntry->pszFilesystem)
             RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszFilesystem);
 
+        if (VolumeEntry->pExtents)
+            RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pExtents);
+
         /* Release disk entry */
         RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry);
     }

Reply via email to