https://git.reactos.org/?p=reactos.git;a=commitdiff;h=54efd758891980351e737…
commit 54efd758891980351e73738a21432f7c9b01b223
Author:     Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Sun May 29 17:32:34 2022 +0200
Commit:     Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Sun May 29 17:32:34 2022 +0200
    [DISKPART] Improve DETAIL commands
---
 base/system/diskpart/detail.c   | 152 ++++++++++++++++++++++++++++++++--
 base/system/diskpart/diskpart.h |   8 ++
 base/system/diskpart/list.c     | 178 ++++++++++++++++++++++------------------
 3 files changed, 249 insertions(+), 89 deletions(-)
diff --git a/base/system/diskpart/detail.c b/base/system/diskpart/detail.c
index 0c0de3e262a..388cb8a45af 100644
--- a/base/system/diskpart/detail.c
+++ b/base/system/diskpart/detail.c
@@ -13,11 +13,66 @@
 /* FUNCTIONS ******************************************************************/
+static
+BOOL
+IsDiskInVolume(
+    _In_ PVOLENTRY VolumeEntry,
+    _In_ PDISKENTRY DiskEntry)
+{
+    ULONG i;
+
+    if ((VolumeEntry == NULL) ||
+        (VolumeEntry->pExtents == NULL) ||
+        (DiskEntry == NULL))
+        return FALSE;
+
+    for (i = 0; i < VolumeEntry->pExtents->NumberOfDiskExtents; i++)
+    {
+        if (VolumeEntry->pExtents->Extents[i].DiskNumber ==
DiskEntry->DiskNumber)
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
+
+static
+BOOL
+IsPartitionInVolume(
+    _In_ PVOLENTRY VolumeEntry,
+    _In_ PPARTENTRY PartEntry)
+{
+    ULONG i;
+
+    if ((VolumeEntry == NULL) ||
+        (VolumeEntry->pExtents == NULL) ||
+        (PartEntry == NULL) ||
+        (PartEntry->DiskEntry == NULL))
+        return FALSE;
+
+    for (i = 0; i < VolumeEntry->pExtents->NumberOfDiskExtents; i++)
+    {
+        if (VolumeEntry->pExtents->Extents[i].DiskNumber ==
PartEntry->DiskEntry->DiskNumber)
+        {
+            if ((VolumeEntry->pExtents->Extents[i].StartingOffset.QuadPart ==
PartEntry->StartSector.QuadPart * PartEntry->DiskEntry->BytesPerSector)
&&
+                (VolumeEntry->pExtents->Extents[i].ExtentLength.QuadPart ==
PartEntry->SectorCount.QuadPart * PartEntry->DiskEntry->BytesPerSector))
+                return TRUE;
+        }
+    }
+
+    return FALSE;
+}
+
+
 BOOL
 DetailDisk(
-    INT argc,
-    PWSTR *argv)
+    _In_ INT argc,
+    _In_ PWSTR *argv)
 {
+    PLIST_ENTRY Entry;
+    PVOLENTRY VolumeEntry;
+    BOOL bPrintHeader = TRUE;
+
     DPRINT("DetailDisk()\n");
     if (argc > 2)
@@ -38,6 +93,28 @@ DetailDisk(
     ConResPrintf(StdOut, IDS_DETAIL_INFO_PATH, CurrentDisk->PathId);
     ConResPrintf(StdOut, IDS_DETAIL_INFO_TARGET, CurrentDisk->TargetId);
     ConResPrintf(StdOut, IDS_DETAIL_INFO_LUN_ID, CurrentDisk->Lun);
+
+    Entry = VolumeListHead.Flink;
+    while (Entry != &VolumeListHead)
+    {
+        VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
+
+        if (IsDiskInVolume(VolumeEntry, CurrentDisk))
+        {
+            if (bPrintHeader)
+            {
+                ConPuts(StdOut, L"\n");
+                ConResPuts(StdOut, IDS_LIST_VOLUME_HEAD);
+                ConResPuts(StdOut, IDS_LIST_VOLUME_LINE);
+                bPrintHeader = FALSE;
+            }
+
+            PrintVolume(VolumeEntry);
+        }
+
+        Entry = Entry->Flink;
+    }
+
     ConPuts(StdOut, L"\n");
     return TRUE;
@@ -46,11 +123,14 @@ DetailDisk(
 BOOL
 DetailPartition(
-    INT argc,
-    PWSTR *argv)
+    _In_ INT argc,
+    _In_ PWSTR *argv)
 {
     PPARTENTRY PartEntry;
     ULONGLONG PartOffset;
+    PLIST_ENTRY Entry;
+    PVOLENTRY VolumeEntry;
+    BOOL bVolumeFound = FALSE, bPrintHeader = TRUE;
     DPRINT("DetailPartition()\n");
@@ -82,6 +162,32 @@ DetailPartition(
     ConResPrintf(StdOut, IDS_DETAIL_PARTITION_HIDDEN, "");
     ConResPrintf(StdOut, IDS_DETAIL_PARTITION_ACTIVE, PartEntry->BootIndicator ?
L"Yes" : L"No");
     ConResPrintf(StdOut, IDS_DETAIL_PARTITION_OFFSET, PartOffset);
+
+    Entry = VolumeListHead.Flink;
+    while (Entry != &VolumeListHead)
+    {
+        VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
+
+        if (IsPartitionInVolume(VolumeEntry, CurrentPartition))
+        {
+            if (bPrintHeader)
+            {
+                ConPuts(StdOut, L"\n");
+                ConResPuts(StdOut, IDS_LIST_VOLUME_HEAD);
+                ConResPuts(StdOut, IDS_LIST_VOLUME_LINE);
+                bPrintHeader = FALSE;
+            }
+
+            PrintVolume(VolumeEntry);
+            bVolumeFound = TRUE;
+        }
+
+        Entry = Entry->Flink;
+    }
+
+    if (bVolumeFound == FALSE)
+        ConPuts(StdOut, L"\nThere is no volume associated with this
partition.\n");
+
     ConPuts(StdOut, L"\n");
     return TRUE;
@@ -90,9 +196,13 @@ DetailPartition(
 BOOL
 DetailVolume(
-    INT argc,
-    PWSTR *argv)
+    _In_ INT argc,
+    _In_ PWSTR *argv)
 {
+    PDISKENTRY DiskEntry;
+    PLIST_ENTRY Entry;
+    BOOL bDiskFound = FALSE, bPrintHeader = TRUE;
+
     DPRINT("DetailVolume()\n");
     if (argc > 2)
@@ -107,7 +217,35 @@ DetailVolume(
         return TRUE;
     }
-    /* TODO: Print volume details */
+
+    Entry = DiskListHead.Flink;
+    while (Entry != &DiskListHead)
+    {
+        DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
+
+        if (IsDiskInVolume(CurrentVolume, DiskEntry))
+        {
+            if (bPrintHeader)
+            {
+                ConPuts(StdOut, L"\n");
+                ConResPuts(StdOut, IDS_LIST_DISK_HEAD);
+                ConResPuts(StdOut, IDS_LIST_DISK_LINE);
+                bPrintHeader = FALSE;
+            }
+
+            PrintDisk(DiskEntry);
+            bDiskFound = TRUE;
+        }
+
+        Entry = Entry->Flink;
+    }
+
+    if (bDiskFound == FALSE)
+        ConPuts(StdOut, L"\nThere are no disks attached to this volume.\n");
+
+    /* TODO: Print more volume details */
+
+    ConPuts(StdOut, L"\n");
     return TRUE;
 }
diff --git a/base/system/diskpart/diskpart.h b/base/system/diskpart/diskpart.h
index 23ea593e7b4..c4a4c2fad9e 100644
--- a/base/system/diskpart/diskpart.h
+++ b/base/system/diskpart/diskpart.h
@@ -361,6 +361,14 @@ ListVirtualDisk(
     INT argc,
     PWSTR *argv);
+VOID
+PrintDisk(
+    _In_ PDISKENTRY DiskEntry);
+
+VOID
+PrintVolume(
+    _In_ PVOLENTRY VolumeEntry);
+
 /* merge.c */
 BOOL merge_main(INT argc, LPWSTR *argv);
diff --git a/base/system/diskpart/list.c b/base/system/diskpart/list.c
index 21589c727cf..6591a7f14f1 100644
--- a/base/system/diskpart/list.c
+++ b/base/system/diskpart/list.c
@@ -13,6 +13,48 @@
 /* FUNCTIONS ******************************************************************/
+VOID
+PrintDisk(
+    _In_ PDISKENTRY DiskEntry)
+{
+    ULONGLONG DiskSize;
+    ULONGLONG FreeSize;
+    LPWSTR lpSizeUnit;
+    LPWSTR lpFreeUnit;
+
+    DiskSize = DiskEntry->SectorCount.QuadPart *
+               (ULONGLONG)DiskEntry->BytesPerSector;
+
+    if (DiskSize >= 10737418240) /* 10 GB */
+    {
+        DiskSize = RoundingDivide(DiskSize, 1073741824);
+        lpSizeUnit = L"GB";
+    }
+    else
+    {
+        DiskSize = RoundingDivide(DiskSize, 1048576);
+        if (DiskSize == 0)
+            DiskSize = 1;
+        lpSizeUnit = L"MB";
+    }
+
+    /* FIXME */
+    FreeSize = 0;
+    lpFreeUnit = L"B";
+
+    ConResPrintf(StdOut, IDS_LIST_DISK_FORMAT,
+                 (CurrentDisk == DiskEntry) ? L'*' : L' ',
+                 DiskEntry->DiskNumber,
+                 L"Online",
+                 DiskSize,
+                 lpSizeUnit,
+                 FreeSize,
+                 lpFreeUnit,
+                 L" ",
+                 L" ");
+}
+
+
 BOOL
 ListDisk(
     INT argc,
@@ -20,10 +62,6 @@ ListDisk(
 {
     PLIST_ENTRY Entry;
     PDISKENTRY DiskEntry;
-    ULONGLONG DiskSize;
-    ULONGLONG FreeSize;
-    LPWSTR lpSizeUnit;
-    LPWSTR lpFreeUnit;
     /* Header labels */
     ConPuts(StdOut, L"\n");
@@ -35,36 +73,7 @@ ListDisk(
     {
         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
-        DiskSize = DiskEntry->SectorCount.QuadPart *
-                   (ULONGLONG)DiskEntry->BytesPerSector;
-
-        if (DiskSize >= 10737418240) /* 10 GB */
-        {
-             DiskSize = RoundingDivide(DiskSize, 1073741824);
-             lpSizeUnit = L"GB";
-        }
-        else
-        {
-             DiskSize = RoundingDivide(DiskSize, 1048576);
-             if (DiskSize == 0)
-                 DiskSize = 1;
-             lpSizeUnit = L"MB";
-        }
-
-        /* FIXME */
-        FreeSize = 0;
-        lpFreeUnit = L"B";
-
-        ConResPrintf(StdOut, IDS_LIST_DISK_FORMAT,
-                     (CurrentDisk == DiskEntry) ? L'*' : L' ',
-                     DiskEntry->DiskNumber,
-                     L"Online",
-                     DiskSize,
-                     lpSizeUnit,
-                     FreeSize,
-                     lpFreeUnit,
-                     L" ",
-                     L" ");
+        PrintDisk(DiskEntry);
         Entry = Entry->Flink;
     }
@@ -217,6 +226,58 @@ ListPartition(
 }
+VOID
+PrintVolume(
+    _In_ PVOLENTRY VolumeEntry)
+{
+    ULONGLONG VolumeSize;
+    PWSTR pszSizeUnit;
+    PWSTR pszVolumeType;
+
+    VolumeSize = VolumeEntry->Size.QuadPart;
+    if (VolumeSize >= 10737418240) /* 10 GB */
+    {
+        VolumeSize = RoundingDivide(VolumeSize, 1073741824);
+        pszSizeUnit = L"GB";
+    }
+    else if (VolumeSize >= 10485760) /* 10 MB */
+    {
+        VolumeSize = RoundingDivide(VolumeSize, 1048576);
+        pszSizeUnit = L"MB";
+    }
+    else
+    {
+        VolumeSize = RoundingDivide(VolumeSize, 1024);
+        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"",
+                 pszVolumeType,
+                 VolumeSize, pszSizeUnit);
+}
+
+
 BOOL
 ListVolume(
     INT argc,
@@ -224,9 +285,6 @@ ListVolume(
 {
     PLIST_ENTRY Entry;
     PVOLENTRY VolumeEntry;
-    ULONGLONG VolumeSize;
-    PWSTR pszSizeUnit;
-    PWSTR pszVolumeType;
     ConPuts(StdOut, L"\n");
     ConResPuts(StdOut, IDS_LIST_VOLUME_HEAD);
@@ -237,51 +295,7 @@ ListVolume(
     {
         VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
-        VolumeSize = VolumeEntry->Size.QuadPart;
-        if (VolumeSize >= 10737418240) /* 10 GB */
-        {
-            VolumeSize = RoundingDivide(VolumeSize, 1073741824);
-            pszSizeUnit = L"GB";
-        }
-        else if (VolumeSize >= 10485760) /* 10 MB */
-        {
-            VolumeSize = RoundingDivide(VolumeSize, 1048576);
-            pszSizeUnit = L"MB";
-        }
-        else
-        {
-            VolumeSize = RoundingDivide(VolumeSize, 1024);
-            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"",
-                     pszVolumeType,
-                     VolumeSize, pszSizeUnit);
+        PrintVolume(VolumeEntry);
         Entry = Entry->Flink;
     }