From 54efd758891980351e73738a21432f7c9b01b223 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 29 May 2022 17:32:34 +0200 Subject: [PATCH] [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; }