https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5a1c00c1178b79f550aed0...
commit 5a1c00c1178b79f550aed0430c8e26f4892032fa Author: Eric Kohl eric.kohl@reactos.org AuthorDate: Sun May 29 12:41:42 2022 +0200 Commit: Eric Kohl eric.kohl@reactos.org 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); }