[DISKPART] Implement the filesystems command

Limitations with respect to available file systems and cluster sizes are not implemented yet.
This commit is contained in:
Eric Kohl
2025-12-26 13:32:03 +01:00
parent 7c3d4a022d
commit abc2acf5a7
15 changed files with 153 additions and 134 deletions
+6
View File
@@ -229,6 +229,7 @@ typedef struct _VOLENTRY
ULONG VolumeNumber;
WCHAR VolumeName[MAX_PATH];
WCHAR DeviceName[MAX_PATH];
DWORD SerialNumber;
WCHAR DriveLetter;
@@ -237,6 +238,11 @@ typedef struct _VOLENTRY
VOLUME_TYPE VolumeType;
ULARGE_INTEGER Size;
ULARGE_INTEGER TotalAllocationUnits;
ULARGE_INTEGER AvailableAllocationUnits;
ULONG SectorsPerAllocationUnit;
ULONG BytesPerSector;
PVOLUME_DISK_EXTENTS pExtents;
} VOLENTRY, *PVOLENTRY;
+42 -111
View File
@@ -12,128 +12,56 @@
#include <debug.h>
static
BOOL
VOID
ShowFileSystemInfo(
PVOLENTRY VolumeEntry)
_In_ PVOLENTRY VolumeEntry)
{
WCHAR VolumeNameBuffer[MAX_PATH];
UNICODE_STRING VolumeName;
HANDLE VolumeHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
ULONG ulSize, ulClusterSize = 0;
FILE_FS_FULL_SIZE_INFORMATION SizeInfo;
FILE_FS_FULL_SIZE_INFORMATION FullSizeInfo;
PFILE_FS_ATTRIBUTE_INFORMATION pAttributeInfo = NULL;
NTSTATUS Status;
BOOL Result = TRUE;
wcscpy(VolumeNameBuffer, VolumeEntry->DeviceName);
wcscat(VolumeNameBuffer, L"\\");
RtlInitUnicodeString(&VolumeName, VolumeNameBuffer);
InitializeObjectAttributes(&ObjectAttributes,
&VolumeName,
0,
NULL,
NULL);
Status = NtOpenFile(&VolumeHandle,
SYNCHRONIZE,
&ObjectAttributes,
&IoStatusBlock,
0,
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT);
if (!NT_SUCCESS(Status))
{
if (Status == STATUS_NO_MEDIA_IN_DEVICE)
{
ConResPuts(StdOut, IDS_ERROR_NO_MEDIUM);
return FALSE;
}
else if (Status == STATUS_UNRECOGNIZED_VOLUME)
{
ConResPuts(StdOut, IDS_FILESYSTEMS_CURRENT);
ConPuts(StdOut, L"\n");
ConResPrintf(StdOut, IDS_FILESYSTEMS_TYPE, L"RAW");
ConResPrintf(StdOut, IDS_FILESYSTEMS_CLUSTERSIZE, 512);
}
return TRUE;
}
ulSize = sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 255 * sizeof(WCHAR);
pAttributeInfo = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
ulSize);
if (pAttributeInfo == NULL)
{
Result = FALSE;
goto done;
}
Status = NtQueryVolumeInformationFile(VolumeHandle,
&IoStatusBlock,
pAttributeInfo,
ulSize,
FileFsAttributeInformation);
if (!NT_SUCCESS(Status))
{
Result = FALSE;
goto done;
}
Status = NtQueryVolumeInformationFile(VolumeHandle,
&IoStatusBlock,
&FullSizeInfo,
sizeof(FILE_FS_FULL_SIZE_INFORMATION),
FileFsFullSizeInformation);
if (NT_SUCCESS(Status))
{
ulClusterSize = FullSizeInfo.BytesPerSector * FullSizeInfo.SectorsPerAllocationUnit;
}
else
{
Status = NtQueryVolumeInformationFile(VolumeHandle,
&IoStatusBlock,
&SizeInfo,
sizeof(FILE_FS_SIZE_INFORMATION),
FileFsSizeInformation);
if (NT_SUCCESS(Status))
{
ulClusterSize = SizeInfo.BytesPerSector * SizeInfo.SectorsPerAllocationUnit;
}
}
WCHAR szBuffer[32];
PWSTR pszSizeUnit = L"";
ULONG ulClusterSize;
ConResPuts(StdOut, IDS_FILESYSTEMS_CURRENT);
ConPuts(StdOut, L"\n");
ConResPrintf(StdOut, IDS_FILESYSTEMS_TYPE, pAttributeInfo->FileSystemName);
ConResPrintf(StdOut, IDS_FILESYSTEMS_CLUSTERSIZE, ulClusterSize);
ConResPrintf(StdOut, IDS_FILESYSTEMS_TYPE, VolumeEntry->pszFilesystem);
ulClusterSize = VolumeEntry->SectorsPerAllocationUnit * VolumeEntry->BytesPerSector;
if (ulClusterSize >= SIZE_10MB) /* 10 MB */
{
ulClusterSize = RoundingDivide(ulClusterSize, SIZE_1MB);
pszSizeUnit = L"MB";
}
else if (ulClusterSize >= SIZE_10KB) /* 10 KB */
{
ulClusterSize = RoundingDivide(ulClusterSize, SIZE_1KB);
pszSizeUnit = L"KB";
}
wsprintf(szBuffer, L"%lu %s", ulClusterSize, pszSizeUnit);
ConResPrintf(StdOut, IDS_FILESYSTEMS_CLUSTERSIZE, szBuffer);
ConResPrintf(StdOut, IDS_FILESYSTEMS_SERIAL_NUMBER, VolumeEntry->SerialNumber);
ConPuts(StdOut, L"\n");
done:
if (pAttributeInfo)
RtlFreeHeap(RtlGetProcessHeap(), 0, pAttributeInfo);
NtClose(VolumeHandle);
return Result;
}
static
VOID
ShowInstalledFileSystems(VOID)
ShowInstalledFileSystems(
_In_ PVOLENTRY VolumeEntry)
{
WCHAR szBuffer[256];
WCHAR szDefault[32];
BOOLEAN ret;
DWORD dwIndex;
UCHAR uMajor, uMinor;
BOOLEAN bLatest;
LoadStringW(GetModuleHandle(NULL),
IDS_FILESYSTEMS_DEFAULT,
szDefault, ARRAYSIZE(szDefault));
ConResPuts(StdOut, IDS_FILESYSTEMS_FORMATTING);
ConPuts(StdOut, L"\n");
for (dwIndex = 0; ; dwIndex++)
{
@@ -141,16 +69,21 @@ ShowInstalledFileSystems(VOID)
szBuffer,
&uMajor,
&uMinor,
&bLatest);
&bLatest);
if (ret == FALSE)
break;
ConPrintf(StdOut, L" %s\n", szBuffer);
}
if (wcscmp(szBuffer, L"FAT") == 0)
wcscat(szBuffer, szDefault);
ConPuts(StdOut, L"\n");
ConResPrintf(StdOut, IDS_FILESYSTEMS_TYPE, szBuffer);
wcscpy(szBuffer, L"-");
ConResPrintf(StdOut, IDS_FILESYSTEMS_CLUSTERSIZE, szBuffer);
ConPuts(StdOut, L"\n");
}
}
BOOL
filesystems_main(
_In_ INT argc,
@@ -164,10 +97,8 @@ filesystems_main(
ConPuts(StdOut, L"\n");
if (ShowFileSystemInfo(CurrentVolume))
{
ShowInstalledFileSystems();
}
ShowFileSystemInfo(CurrentVolume);
ShowInstalledFileSystems(CurrentVolume);
return TRUE;
}
+4 -2
View File
@@ -93,8 +93,10 @@ STRINGTABLE
BEGIN
IDS_FILESYSTEMS_CURRENT "Aktuelles Dateisystem\n"
IDS_FILESYSTEMS_FORMATTING "Zur Formatierung unterstützte Dateisysteme\n"
IDS_FILESYSTEMS_TYPE "Typ : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE "Größe der Zuordnungseinheit: %lu\n"
IDS_FILESYSTEMS_TYPE " Typ : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE " Größe der Zuordnungseinheit: %s\n"
IDS_FILESYSTEMS_SERIAL_NUMBER " Kennung : %08lx\n"
IDS_FILESYSTEMS_DEFAULT " (Standard)"
END
STRINGTABLE
+4 -2
View File
@@ -93,8 +93,10 @@ STRINGTABLE
BEGIN
IDS_FILESYSTEMS_CURRENT "Current Filesystem\n"
IDS_FILESYSTEMS_FORMATTING "Filesystems available for formatting\n"
IDS_FILESYSTEMS_TYPE "Type : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE "Cluster size: %lu\n"
IDS_FILESYSTEMS_TYPE " Type : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE " Cluster size : %s\n"
IDS_FILESYSTEMS_SERIAL_NUMBER " Serial number : %08lx\n"
IDS_FILESYSTEMS_DEFAULT " (Default)"
END
STRINGTABLE
+4 -2
View File
@@ -100,8 +100,10 @@ STRINGTABLE
BEGIN
IDS_FILESYSTEMS_CURRENT "Filesystem corrente\n"
IDS_FILESYSTEMS_FORMATTING "Filesystem disponibili per la formattazione\n"
IDS_FILESYSTEMS_TYPE "Tipo : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE "Dimensione cluster: %lu\n"
IDS_FILESYSTEMS_TYPE " Tipo : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE " Dimensione cluster: %s\n"
IDS_FILESYSTEMS_SERIAL_NUMBER " Serial number : %08lx\n"
IDS_FILESYSTEMS_DEFAULT " (Default)"
END
STRINGTABLE
+4 -2
View File
@@ -93,8 +93,10 @@ STRINGTABLE
BEGIN
IDS_FILESYSTEMS_CURRENT "Bieżący system plików\n"
IDS_FILESYSTEMS_FORMATTING "Systemy plików obsługiwane przy formatowaniu\n"
IDS_FILESYSTEMS_TYPE "Typ : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE "Rozmiar klastra: %lu\n"
IDS_FILESYSTEMS_TYPE " Typ : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE " Rozmiar klastra: %s\n"
IDS_FILESYSTEMS_SERIAL_NUMBER " Serial number : %08lx\n"
IDS_FILESYSTEMS_DEFAULT " (Default)"
END
STRINGTABLE
+4 -2
View File
@@ -95,8 +95,10 @@ STRINGTABLE
BEGIN
IDS_FILESYSTEMS_CURRENT "Current Filesystem\n"
IDS_FILESYSTEMS_FORMATTING "Filesystems available for formatting\n"
IDS_FILESYSTEMS_TYPE "Type : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE "Cluster size: %lu\n"
IDS_FILESYSTEMS_TYPE " Type : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE " Cluster size : %s\n"
IDS_FILESYSTEMS_SERIAL_NUMBER " Serial number: %08lx\n"
IDS_FILESYSTEMS_DEFAULT " (Default)"
END
STRINGTABLE
+4 -2
View File
@@ -101,8 +101,10 @@ STRINGTABLE
BEGIN
IDS_FILESYSTEMS_CURRENT "Fișierul de sistem curent\n"
IDS_FILESYSTEMS_FORMATTING "Fișiere de sistem disponibile pentru formatare\n"
IDS_FILESYSTEMS_TYPE "Tip : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE "Mărimea cluster-ului: %lu\n"
IDS_FILESYSTEMS_TYPE " Tip : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE " Mărimea cluster-ului: %s\n"
IDS_FILESYSTEMS_SERIAL_NUMBER " Serial number : %08lx\n"
IDS_FILESYSTEMS_DEFAULT " (Default)"
END
STRINGTABLE
+4 -2
View File
@@ -95,8 +95,10 @@ STRINGTABLE
BEGIN
IDS_FILESYSTEMS_CURRENT "Current Filesystem\n"
IDS_FILESYSTEMS_FORMATTING "Filesystems available for formatting\n"
IDS_FILESYSTEMS_TYPE "Type : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE "Cluster size: %lu\n"
IDS_FILESYSTEMS_TYPE " Type : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE " Cluster size : %s\n"
IDS_FILESYSTEMS_SERIAL_NUMBER " Serial number: %08lx\n"
IDS_FILESYSTEMS_DEFAULT " (Default)"
END
STRINGTABLE
+4 -2
View File
@@ -97,8 +97,10 @@ STRINGTABLE
BEGIN
IDS_FILESYSTEMS_CURRENT "Current Filesystem\n"
IDS_FILESYSTEMS_FORMATTING "Filesystems available for formatting\n"
IDS_FILESYSTEMS_TYPE "Type : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE "Cluster size: %lu\n"
IDS_FILESYSTEMS_TYPE " Type : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE " Cluster size : %s\n"
IDS_FILESYSTEMS_SERIAL_NUMBER " Serial number: %08lx\n"
IDS_FILESYSTEMS_DEFAULT " (Default)"
END
STRINGTABLE
+4 -2
View File
@@ -103,8 +103,10 @@ STRINGTABLE
BEGIN
IDS_FILESYSTEMS_CURRENT "Geçerli Dosya Sistemi\n"
IDS_FILESYSTEMS_FORMATTING "Biçimlendirme için kullanılabilen dosya sistemleri\n"
IDS_FILESYSTEMS_TYPE "Tür : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE "Küme boyutu : %lu\n"
IDS_FILESYSTEMS_TYPE " Tür : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE " Küme boyutu : %s\n"
IDS_FILESYSTEMS_SERIAL_NUMBER " Serial number: %08lx\n"
IDS_FILESYSTEMS_DEFAULT " (Default)"
END
STRINGTABLE
+4 -2
View File
@@ -102,8 +102,10 @@ STRINGTABLE
BEGIN
IDS_FILESYSTEMS_CURRENT "Current Filesystem\n"
IDS_FILESYSTEMS_FORMATTING "Filesystems available for formatting\n"
IDS_FILESYSTEMS_TYPE "Type : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE "Cluster size: %lu\n"
IDS_FILESYSTEMS_TYPE " Type : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE " Cluster size : %s\n"
IDS_FILESYSTEMS_SERIAL_NUMBER " Serial number: %08lx\n"
IDS_FILESYSTEMS_DEFAULT " (Default)"
END
STRINGTABLE
+4 -2
View File
@@ -102,8 +102,10 @@ STRINGTABLE
BEGIN
IDS_FILESYSTEMS_CURRENT "目前的檔案系統\n"
IDS_FILESYSTEMS_FORMATTING "可用於格式化的檔案系統\n"
IDS_FILESYSTEMS_TYPE "類型 : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE "叢集大小: %lu\n"
IDS_FILESYSTEMS_TYPE " 類型 : %s\n"
IDS_FILESYSTEMS_CLUSTERSIZE " 叢集大小: %s\n"
IDS_FILESYSTEMS_SERIAL_NUMBER " Serial number: %08lx\n"
IDS_FILESYSTEMS_DEFAULT " (Default)"
END
STRINGTABLE
+59 -1
View File
@@ -1777,6 +1777,59 @@ GetVolumeType(
}
static
VOID
GetVolumeSize(
_In_ HANDLE VolumeHandle,
_In_ PVOLENTRY VolumeEntry)
{
FILE_FS_FULL_SIZE_INFORMATION SizeInfo;
FILE_FS_FULL_SIZE_INFORMATION FullSizeInfo;
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
ZeroMemory(&FullSizeInfo, sizeof(FullSizeInfo));
Status = NtQueryVolumeInformationFile(VolumeHandle,
&IoStatusBlock,
&FullSizeInfo,
sizeof(FILE_FS_FULL_SIZE_INFORMATION),
FileFsFullSizeInformation);
if (NT_SUCCESS(Status))
{
DPRINT1("FullSizeInfo.TotalAllocationUnits %I64u\n", FullSizeInfo.TotalAllocationUnits.QuadPart);
DPRINT1("FullSizeInfo.SectorsPerAllocationUnit %lu\n", FullSizeInfo.SectorsPerAllocationUnit);
DPRINT1("FullSizeInfo.BytesPerSector %lu\n", FullSizeInfo.BytesPerSector);
VolumeEntry->TotalAllocationUnits.QuadPart = FullSizeInfo.TotalAllocationUnits.QuadPart;
VolumeEntry->SectorsPerAllocationUnit = FullSizeInfo.SectorsPerAllocationUnit;
VolumeEntry->BytesPerSector = FullSizeInfo.BytesPerSector;
}
else
{
ZeroMemory(&SizeInfo, sizeof(SizeInfo));
Status = NtQueryVolumeInformationFile(VolumeHandle,
&IoStatusBlock,
&SizeInfo,
sizeof(FILE_FS_SIZE_INFORMATION),
FileFsSizeInformation);
if (NT_SUCCESS(Status))
{
DPRINT1("SizeInfo.TotalAllocationUnits %I64u\n", SizeInfo.TotalAllocationUnits.QuadPart);
DPRINT1("SizeInfo.SectorsPerAllocationUnit %lu\n", SizeInfo.SectorsPerAllocationUnit);
DPRINT1("SizeInfo.BytesPerSector %lu\n", SizeInfo.BytesPerSector);
VolumeEntry->TotalAllocationUnits.QuadPart = SizeInfo.TotalAllocationUnits.QuadPart;
VolumeEntry->SectorsPerAllocationUnit = SizeInfo.SectorsPerAllocationUnit;
VolumeEntry->BytesPerSector = SizeInfo.BytesPerSector;
}
else
{
DPRINT1("SizeInfo failed!\n");
}
}
}
static
VOID
AddVolumeToList(
@@ -1824,6 +1877,7 @@ AddVolumeToList(
return;
}
wcscat(VolumeEntry->DeviceName, L"\\");
DPRINT("DeviceName: %S\n", VolumeEntry->DeviceName);
RtlInitUnicodeString(&Name, VolumeEntry->DeviceName);
@@ -1844,13 +1898,14 @@ AddVolumeToList(
{
GetVolumeType(VolumeHandle, VolumeEntry);
GetVolumeExtents(VolumeHandle, VolumeEntry);
GetVolumeSize(VolumeHandle, VolumeEntry);
NtClose(VolumeHandle);
}
if (GetVolumeInformationW(pszVolumeName,
szVolumeName,
MAX_PATH + 1,
NULL, // [out, optional] LPDWORD lpVolumeSerialNumber,
&VolumeEntry->SerialNumber,
NULL, // [out, optional] LPDWORD lpMaximumComponentLength,
NULL, // [out, optional] LPDWORD lpFileSystemFlags,
szFilesystem,
@@ -1878,6 +1933,9 @@ AddVolumeToList(
(3 + 1) * sizeof(WCHAR));
if (VolumeEntry->pszFilesystem)
wcscpy(VolumeEntry->pszFilesystem, L"RAW");
VolumeEntry->SerialNumber = 0;
VolumeEntry->SectorsPerAllocationUnit = 1;
VolumeEntry->BytesPerSector = 512;
}
}
+2
View File
@@ -75,6 +75,8 @@
#define IDS_FILESYSTEMS_FORMATTING 1181
#define IDS_FILESYSTEMS_TYPE 1182
#define IDS_FILESYSTEMS_CLUSTERSIZE 1183
#define IDS_FILESYSTEMS_SERIAL_NUMBER 1184
#define IDS_FILESYSTEMS_DEFAULT 1185
#define IDS_GPT_FAIL 1190
#define IDS_GPT_SUCCESS 1191