https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2ba6b097543d7ede44c12…
commit 2ba6b097543d7ede44c12e7942a94ebbec3a6293
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Sat Mar 26 15:18:08 2022 +0100
Commit: Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Sat Mar 26 15:18:08 2022 +0100
[DISKPART] Add volume support
Add the 'list volume' and 'select volume' commands
---
base/system/diskpart/diskpart.c | 2 +
base/system/diskpart/diskpart.h | 24 +++++++
base/system/diskpart/lang/en-US.rc | 5 +-
base/system/diskpart/lang/pl-PL.rc | 5 +-
base/system/diskpart/lang/pt-PT.rc | 5 +-
base/system/diskpart/lang/ro-RO.rc | 5 +-
base/system/diskpart/lang/ru-RU.rc | 5 +-
base/system/diskpart/lang/sq-AL.rc | 5 +-
base/system/diskpart/lang/tr-TR.rc | 5 +-
base/system/diskpart/lang/zh-CN.rc | 5 +-
base/system/diskpart/lang/zh-TW.rc | 5 +-
base/system/diskpart/list.c | 41 +++++++++++
base/system/diskpart/partlist.c | 135 +++++++++++++++++++++++++++++++++++++
base/system/diskpart/rescan.c | 2 +
base/system/diskpart/resource.h | 3 +
base/system/diskpart/select.c | 59 ++++++++++++++++
16 files changed, 302 insertions(+), 9 deletions(-)
diff --git a/base/system/diskpart/diskpart.c b/base/system/diskpart/diskpart.c
index 30b7da20f35..5f678a556d7 100644
--- a/base/system/diskpart/diskpart.c
+++ b/base/system/diskpart/diskpart.c
@@ -94,6 +94,7 @@ int wmain(int argc, const LPWSTR argv[])
timeout = 0;
CreatePartitionList();
+ CreateVolumeList();
/* If there are no command arguments, then go straight to the interpreter */
if (argc < 2)
@@ -190,6 +191,7 @@ int wmain(int argc, const LPWSTR argv[])
ConResPuts(StdOut, IDS_APP_LEAVING);
done:
+ DestroyVolumeList();
DestroyPartitionList();
return result;
diff --git a/base/system/diskpart/diskpart.h b/base/system/diskpart/diskpart.h
index abfc2213c74..751c3ff6aaf 100644
--- a/base/system/diskpart/diskpart.h
+++ b/base/system/diskpart/diskpart.h
@@ -170,14 +170,32 @@ typedef struct _DISKENTRY
} DISKENTRY, *PDISKENTRY;
+typedef struct _VOLENTRY
+{
+ LIST_ENTRY ListEntry;
+
+ ULONG VolumeNumber;
+ WCHAR VolumeName[MAX_PATH];
+
+ WCHAR DriveLetter;
+
+ PWSTR pszLabel;
+ PWSTR pszFilesystem;
+ UINT DriveType;
+ ULARGE_INTEGER Size;
+
+} VOLENTRY, *PVOLENTRY;
+
/* GLOBAL VARIABLES ***********************************************************/
extern LIST_ENTRY DiskListHead;
extern LIST_ENTRY BiosDiskListHead;
+extern LIST_ENTRY VolumeListHead;
extern PDISKENTRY CurrentDisk;
extern PPARTENTRY CurrentPartition;
+extern PVOLENTRY CurrentVolume;
/* PROTOTYPES *****************************************************************/
@@ -282,6 +300,12 @@ CreatePartitionList(VOID);
VOID
DestroyPartitionList(VOID);
+NTSTATUS
+CreateVolumeList(VOID);
+
+VOID
+DestroyVolumeList(VOID);
+
/* recover.c */
BOOL recover_main(INT argc, LPWSTR *argv);
diff --git a/base/system/diskpart/lang/en-US.rc b/base/system/diskpart/lang/en-US.rc
index 0137f34f10c..f23a5cc13e0 100644
--- a/base/system/diskpart/lang/en-US.rc
+++ b/base/system/diskpart/lang/en-US.rc
@@ -44,7 +44,9 @@ BEGIN
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\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 %-11s %-5s %10u %4I64u
%-2s\n"
END
/* RESCAN command string */
@@ -66,6 +68,7 @@ BEGIN
IDS_SELECT_PARTITION_INVALID "\nInvalid partition.\n\n"
IDS_SELECT_NO_VOLUME "\nThere is no volume currently selected.\nPlease select a
disk and try again.\n\n"
IDS_SELECT_VOLUME "\nVolume %lu is now the selected volume.\n\n"
+ IDS_SELECT_VOLUME_INVALID "\nInvalid volume.\n\n"
END
/* Disk Status */
diff --git a/base/system/diskpart/lang/pl-PL.rc b/base/system/diskpart/lang/pl-PL.rc
index 8078bed8715..2656950d8b7 100644
--- a/base/system/diskpart/lang/pl-PL.rc
+++ b/base/system/diskpart/lang/pl-PL.rc
@@ -44,7 +44,9 @@ BEGIN
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\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 %-11s %-5s %10u %4I64u
%-2s\n"
END
/* RESCAN command string */
@@ -66,6 +68,7 @@ BEGIN
IDS_SELECT_PARTITION_INVALID "\nNieprawidłowa partycja.\n\n"
IDS_SELECT_NO_VOLUME "\nNie wybrano woluminu.\nWybierz dysk i spróbuj
ponownie.\n\n"
IDS_SELECT_VOLUME "\nObecnie wybranym woluminem jest wolumin %lu.\n\n"
+ IDS_SELECT_VOLUME_INVALID "\nInvalid volume.\n\n"
END
/* Disk Status */
diff --git a/base/system/diskpart/lang/pt-PT.rc b/base/system/diskpart/lang/pt-PT.rc
index 9ce8e6ac0a1..f3321412c72 100644
--- a/base/system/diskpart/lang/pt-PT.rc
+++ b/base/system/diskpart/lang/pt-PT.rc
@@ -46,7 +46,9 @@ BEGIN
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\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 %-11s %-5s %10u %4I64u
%-2s\n"
END
/* RESCAN command string */
@@ -68,6 +70,7 @@ BEGIN
IDS_SELECT_PARTITION_INVALID "\nInvalid partition.\n\n"
IDS_SELECT_NO_VOLUME "\nNenhum volume actualmente seleccionado.\nPor favor
seleccione um disco e tente novamente.\n\n"
IDS_SELECT_VOLUME "\nVolume %lu é agora o volume seleccionado.\n\n"
+ IDS_SELECT_VOLUME_INVALID "\nInvalid volume.\n\n"
END
/* Disk Status */
diff --git a/base/system/diskpart/lang/ro-RO.rc b/base/system/diskpart/lang/ro-RO.rc
index 0e75e449ac2..99c311a7800 100644
--- a/base/system/diskpart/lang/ro-RO.rc
+++ b/base/system/diskpart/lang/ro-RO.rc
@@ -46,7 +46,9 @@ BEGIN
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 "Volum ###\tLtr\tEtichetă\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 %-11s %-5s %10u %4I64u
%-2s\n"
END
/* RESCAN command string */
@@ -68,6 +70,7 @@ BEGIN
IDS_SELECT_PARTITION_INVALID "\nPartiție nevalidă.\n\n"
IDS_SELECT_NO_VOLUME "\nMomentan nu există niciun volum selectat.\nSelectați un
disc apoi reîncercați.\n\n"
IDS_SELECT_VOLUME "\nVolumul %lu este selectat acum.\n\n"
+ IDS_SELECT_VOLUME_INVALID "\nInvalid volume.\n\n"
END
/* Disk Status */
diff --git a/base/system/diskpart/lang/ru-RU.rc b/base/system/diskpart/lang/ru-RU.rc
index b3bd8015dfe..ad20e840a0c 100644
--- a/base/system/diskpart/lang/ru-RU.rc
+++ b/base/system/diskpart/lang/ru-RU.rc
@@ -46,7 +46,9 @@ BEGIN
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 "Том ###\tИмя\tМетка\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 %-11s %-5s %10u %4I64u
%-2s\n"
END
/* RESCAN command string */
@@ -68,6 +70,7 @@ BEGIN
IDS_SELECT_PARTITION_INVALID "\nОшибка в разметке диска.\n\n"
IDS_SELECT_NO_VOLUME "\nТом на диске не указан.\nВыберите том диска и
повторите.\n\n"
IDS_SELECT_VOLUME "\nВыбран текущим %lu том диска.\n\n"
+ IDS_SELECT_VOLUME_INVALID "\nInvalid volume.\n\n"
END
/* Disk Status */
diff --git a/base/system/diskpart/lang/sq-AL.rc b/base/system/diskpart/lang/sq-AL.rc
index 87ad6659c59..2238218d669 100644
--- a/base/system/diskpart/lang/sq-AL.rc
+++ b/base/system/diskpart/lang/sq-AL.rc
@@ -48,7 +48,9 @@ BEGIN
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 ###\tLtr\tLabel\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 %-11s %-5s %10u %4I64u
%-2s\n"
END
/* RESCAN command string */
@@ -70,6 +72,7 @@ BEGIN
IDS_SELECT_PARTITION_INVALID "\nInvalid partition.\n\n"
IDS_SELECT_NO_VOLUME "\nThere is no volume currently selected.\nPlease select a
disk and try again.\n\n"
IDS_SELECT_VOLUME "\nVolume %lu is now the selected volume.\n\n"
+ IDS_SELECT_VOLUME_INVALID "\nInvalid volume.\n\n"
END
/* Disk Status */
diff --git a/base/system/diskpart/lang/tr-TR.rc b/base/system/diskpart/lang/tr-TR.rc
index 4788477ea59..193502965c6 100644
--- a/base/system/diskpart/lang/tr-TR.rc
+++ b/base/system/diskpart/lang/tr-TR.rc
@@ -46,7 +46,9 @@ BEGIN
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 "Birim ###\tHarf\tEtiket\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 %-11s %-5s %10u %4I64u
%-2s\n"
END
/* RESCAN command string */
@@ -68,6 +70,7 @@ BEGIN
IDS_SELECT_PARTITION_INVALID "\nGeçersiz bölüm.\n\n"
IDS_SELECT_NO_VOLUME "\nŞimdilik bir birim seçilmemiş.\nLütfen bir disk seçiniz
ve yeniden deneyiniz.\n\n"
IDS_SELECT_VOLUME "\nBirim %lu şimdi seçilen birimdir.\n\n"
+ IDS_SELECT_VOLUME_INVALID "\nInvalid volume.\n\n"
END
/* Disk Status */
diff --git a/base/system/diskpart/lang/zh-CN.rc b/base/system/diskpart/lang/zh-CN.rc
index 1a9fd494bb4..e04d919004c 100644
--- a/base/system/diskpart/lang/zh-CN.rc
+++ b/base/system/diskpart/lang/zh-CN.rc
@@ -47,7 +47,9 @@ BEGIN
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 " 卷 ### Ltr 标签\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 %-11s %-5s %10u %4I64u
%-2s\n"
END
/* RESCAN command string */
@@ -69,6 +71,7 @@ BEGIN
IDS_SELECT_PARTITION_INVALID "\n无效的分区。\n\n"
IDS_SELECT_NO_VOLUME "\n没有当前所选的卷。\n请选择一个磁盘,再试一次。\n\n"
IDS_SELECT_VOLUME "\n卷 %lu 现在是所选的卷。\n\n"
+ IDS_SELECT_VOLUME_INVALID "\nInvalid volume.\n\n"
END
/* Disk Status */
diff --git a/base/system/diskpart/lang/zh-TW.rc b/base/system/diskpart/lang/zh-TW.rc
index 21be6d0cd81..15a26899024 100644
--- a/base/system/diskpart/lang/zh-TW.rc
+++ b/base/system/diskpart/lang/zh-TW.rc
@@ -47,7 +47,9 @@ BEGIN
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 " 磁碟區 ### Ltr 標籤\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 %-11s %-5s %10u %4I64u
%-2s\n"
END
/* RESCAN command string */
@@ -69,6 +71,7 @@ BEGIN
IDS_SELECT_PARTITION_INVALID "\n無效的磁碟分割。\n\n"
IDS_SELECT_NO_VOLUME "\n目前沒有選擇磁碟區。\n請選擇一個磁碟,然後再試一次。\n\n"
IDS_SELECT_VOLUME "\n磁碟區 %lu 現在是所選的磁碟區。\n\n"
+ IDS_SELECT_VOLUME_INVALID "\nInvalid volume.\n\n"
END
/* Disk Status */
diff --git a/base/system/diskpart/list.c b/base/system/diskpart/list.c
index dd7e54c8f38..714f5e3c257 100644
--- a/base/system/diskpart/list.c
+++ b/base/system/diskpart/list.c
@@ -220,7 +220,48 @@ static
VOID
ListVolume(VOID)
{
+ PLIST_ENTRY Entry;
+ PVOLENTRY VolumeEntry;
+ ULONGLONG VolumeSize;
+ LPWSTR lpSizeUnit;
+
ConResPuts(StdOut, IDS_LIST_VOLUME_HEAD);
+ ConResPuts(StdOut, IDS_LIST_VOLUME_LINE);
+
+ Entry = VolumeListHead.Flink;
+ while (Entry != &VolumeListHead)
+ {
+ VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
+
+ VolumeSize = VolumeEntry->Size.QuadPart;
+ if (VolumeSize >= 10737418240) /* 10 GB */
+ {
+ VolumeSize = RoundingDivide(VolumeSize, 1073741824);
+ lpSizeUnit = L"GB";
+ }
+ else if (VolumeSize >= 10485760) /* 10 MB */
+ {
+ VolumeSize = RoundingDivide(VolumeSize, 1048576);
+ lpSizeUnit = L"MB";
+ }
+ else
+ {
+ VolumeSize = RoundingDivide(VolumeSize, 1024);
+ lpSizeUnit = L"KB";
+ }
+
+ ConResPrintf(StdOut, IDS_LIST_VOLUME_FORMAT,
+ VolumeEntry->VolumeNumber,
+ VolumeEntry->DriveLetter,
+ (VolumeEntry->pszLabel) ? VolumeEntry->pszLabel :
L"",
+ (VolumeEntry->pszFilesystem) ? VolumeEntry->pszFilesystem :
L"",
+ VolumeEntry->DriveType,
+ VolumeSize, lpSizeUnit);
+
+ Entry = Entry->Flink;
+ }
+
+ ConPuts(StdOut, L"\n\n");
}
static
diff --git a/base/system/diskpart/partlist.c b/base/system/diskpart/partlist.c
index 6202eb0439c..2113373ce83 100644
--- a/base/system/diskpart/partlist.c
+++ b/base/system/diskpart/partlist.c
@@ -69,9 +69,11 @@ typedef struct _PARTITION_SECTOR
LIST_ENTRY DiskListHead;
LIST_ENTRY BiosDiskListHead;
+LIST_ENTRY VolumeListHead;
PDISKENTRY CurrentDisk = NULL;
PPARTENTRY CurrentPartition = NULL;
+PVOLENTRY CurrentVolume = NULL;
/* FUNCTIONS ******************************************************************/
@@ -1173,4 +1175,137 @@ DestroyPartitionList(VOID)
}
}
+
+static
+VOID
+AddVolumeToList(
+ ULONG ulVolumeNumber,
+ PWSTR pszVolumeName)
+{
+ PVOLENTRY VolumeEntry;
+
+ WCHAR szPathNames[256];
+ DWORD dwLength;
+ WCHAR szVolumeName[MAX_PATH + 1];
+ WCHAR szFilesystem[MAX_PATH + 1];
+
+
+ VolumeEntry = RtlAllocateHeap(RtlGetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(VOLENTRY));
+ if (VolumeEntry == NULL)
+ {
+ return;
+ }
+
+
+ if (GetVolumePathNamesForVolumeNameW(pszVolumeName,
+ szPathNames,
+ 256,
+ &dwLength))
+ {
+ VolumeEntry->DriveLetter = szPathNames[0];
+
+ if (GetVolumeInformationW(szPathNames,
+ szVolumeName,
+ MAX_PATH + 1,
+ NULL, // [out, optional] LPDWORD lpVolumeSerialNumber,
+ NULL, // [out, optional] LPDWORD
lpMaximumComponentLength,
+ 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->pszFilesystem = RtlAllocateHeap(RtlGetProcessHeap(),
+ 0,
+ (wcslen(szFilesystem) + 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
+ );
+ }
+ }
+
+ VolumeEntry->VolumeNumber = ulVolumeNumber;
+ wcscpy(VolumeEntry->VolumeName, pszVolumeName);
+
+ InsertTailList(&VolumeListHead,
+ &VolumeEntry->ListEntry);
+}
+
+
+NTSTATUS
+CreateVolumeList(VOID)
+{
+ HANDLE hVolume = INVALID_HANDLE_VALUE;
+ WCHAR szVolumeName[MAX_PATH];
+ ULONG ulVolumeNumber = 0;
+ BOOL Success;
+
+ CurrentVolume = NULL;
+
+ InitializeListHead(&VolumeListHead);
+
+ hVolume = FindFirstVolumeW(szVolumeName, ARRAYSIZE(szVolumeName));
+ if (hVolume == INVALID_HANDLE_VALUE)
+ {
+
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ AddVolumeToList(ulVolumeNumber++, szVolumeName);
+
+ for (;;)
+ {
+ Success = FindNextVolumeW(hVolume, szVolumeName, ARRAYSIZE(szVolumeName));
+ if (!Success)
+ {
+ break;
+ }
+
+ AddVolumeToList(ulVolumeNumber++, szVolumeName);
+ }
+
+ FindVolumeClose(hVolume);
+
+ return STATUS_SUCCESS;
+}
+
+
+VOID
+DestroyVolumeList(VOID)
+{
+ PLIST_ENTRY Entry;
+ PVOLENTRY VolumeEntry;
+
+ CurrentVolume = NULL;
+
+ /* Release disk and partition info */
+ while (!IsListEmpty(&VolumeListHead))
+ {
+ Entry = RemoveHeadList(&VolumeListHead);
+ VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
+
+ if (VolumeEntry->pszLabel)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszLabel);
+
+ if (VolumeEntry->pszFilesystem)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszFilesystem);
+
+ /* Release disk entry */
+ RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry);
+ }
+}
+
/* EOF */
diff --git a/base/system/diskpart/rescan.c b/base/system/diskpart/rescan.c
index cf4e461a0f2..29371861f01 100644
--- a/base/system/diskpart/rescan.c
+++ b/base/system/diskpart/rescan.c
@@ -11,8 +11,10 @@
BOOL rescan_main(INT argc, LPWSTR *argv)
{
ConResPuts(StdOut, IDS_RESCAN_START);
+ DestroyVolumeList();
DestroyPartitionList();
CreatePartitionList();
+ CreateVolumeList();
ConResPuts(StdOut, IDS_RESCAN_END);
return TRUE;
diff --git a/base/system/diskpart/resource.h b/base/system/diskpart/resource.h
index 4e2b35f9e24..34924947a98 100644
--- a/base/system/diskpart/resource.h
+++ b/base/system/diskpart/resource.h
@@ -40,6 +40,8 @@
#define IDS_LIST_PARTITION_FORMAT 3305
#define IDS_LIST_PARTITION_NO_DISK 3306
#define IDS_LIST_VOLUME_HEAD 3307
+#define IDS_LIST_VOLUME_LINE 3308
+#define IDS_LIST_VOLUME_FORMAT 3309
#define IDS_RESCAN_START 4100
#define IDS_RESCAN_END 4101
@@ -53,6 +55,7 @@
#define IDS_SELECT_PARTITION_INVALID 4406
#define IDS_SELECT_NO_VOLUME 4407
#define IDS_SELECT_VOLUME 4408
+#define IDS_SELECT_VOLUME_INVALID 4409
#define IDS_STATUS_YES 31
#define IDS_STATUS_NO 32
diff --git a/base/system/diskpart/select.c b/base/system/diskpart/select.c
index bebdbadde5a..4a1804ebbfd 100644
--- a/base/system/diskpart/select.c
+++ b/base/system/diskpart/select.c
@@ -157,6 +157,63 @@ SelectPartition(
}
+static
+VOID
+SelectVolume(
+ INT argc,
+ LPWSTR *argv)
+{
+ PLIST_ENTRY Entry;
+ PVOLENTRY VolumeEntry;
+ LONG lValue;
+ LPWSTR endptr = NULL;
+
+ DPRINT("SelectVolume()\n");
+
+ if (argc > 3)
+ {
+ ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
+ return;
+ }
+
+ if (argc == 2)
+ {
+ if (CurrentDisk == NULL)
+ ConResPuts(StdOut, IDS_SELECT_NO_VOLUME);
+ else
+ ConResPrintf(StdOut, IDS_SELECT_VOLUME, CurrentVolume->VolumeNumber);
+ return;
+ }
+
+ lValue = wcstol(argv[2], &endptr, 10);
+ if (((lValue == 0) && (endptr == argv[2])) ||
+ (lValue < 0))
+ {
+ ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
+ return;
+ }
+
+ CurrentVolume = NULL;
+
+ Entry = VolumeListHead.Flink;
+ while (Entry != &VolumeListHead)
+ {
+ VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
+
+ if (VolumeEntry->VolumeNumber == (ULONG)lValue)
+ {
+ CurrentVolume = VolumeEntry;
+ ConResPrintf(StdOut, IDS_SELECT_VOLUME, CurrentVolume->VolumeNumber);
+ return;
+ }
+
+ Entry = Entry->Flink;
+ }
+
+ ConResPuts(StdErr, IDS_SELECT_VOLUME_INVALID);
+}
+
+
BOOL
select_main(
INT argc,
@@ -174,6 +231,8 @@ select_main(
SelectDisk(argc, argv);
else if (!wcsicmp(argv[1], L"partition"))
SelectPartition(argc, argv);
+ else if (!wcsicmp(argv[1], L"volume"))
+ SelectVolume(argc, argv);
else
ConResPuts(StdOut, IDS_HELP_CMD_SELECT);