https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4838d7bd56f3fa241d8ab…
commit 4838d7bd56f3fa241d8ab9a0daa20f81c7045ca1
Author: Adam Słaboń <asaillen(a)protonmail.com>
AuthorDate: Sat Mar 2 23:48:33 2024 +0100
Commit: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito(a)reactos.org>
CommitDate: Mon Oct 7 11:16:03 2024 +0200
[SDK][FMIFS] Partially implement QueryDeviceInformation
On Windows, QueryDeviceInformation leverages the ifsutil.dll's API.
This is a standalone implementation that mimics Vista behaviour.
---
dll/win32/fmifs/fmifs.spec | 2 +-
dll/win32/fmifs/query.c | 158 +++++++++++++++++++++++++++++++++
sdk/include/reactos/libs/fmifs/fmifs.h | 23 ++++-
3 files changed, 178 insertions(+), 5 deletions(-)
diff --git a/dll/win32/fmifs/fmifs.spec b/dll/win32/fmifs/fmifs.spec
index 6969e36d8c4..2e038e7b209 100644
--- a/dll/win32/fmifs/fmifs.spec
+++ b/dll/win32/fmifs/fmifs.spec
@@ -8,7 +8,7 @@
@ stdcall FormatEx(wstr ptr wstr wstr long long ptr)
@ stub FormatEx2
@ stdcall QueryAvailableFileSystemFormat(long wstr str str ptr)
-@ stub QueryDeviceInformation
+@ stdcall QueryDeviceInformation(wstr ptr long)
@ stub QueryDeviceInformationByHandle
@ stub QueryFileSystemName
@ stub QueryLatestFileSystemVersion
diff --git a/dll/win32/fmifs/query.c b/dll/win32/fmifs/query.c
index 9903275fcac..c05e3fc65f7 100644
--- a/dll/win32/fmifs/query.c
+++ b/dll/win32/fmifs/query.c
@@ -8,6 +8,12 @@
*/
#include "precomp.h"
+#include <ntddstor.h>
+#include <ntstrsafe.h>
+
+#define NTOS_MODE_USER
+#include <ndk/iofuncs.h>
+#include <ndk/obfuncs.h>
BOOLEAN
NTAPI
@@ -43,3 +49,155 @@ QueryAvailableFileSystemFormat(
return TRUE;
}
+
+/**
+ * @brief
+ * Retrieves disk device information.
+ *
+ * @param[in] DriveRoot
+ * String which contains a DOS device name,
+ *
+ * @param[in,out] DeviceInformation
+ * Pointer to buffer with DEVICE_INFORMATION structure which will receive data.
+ *
+ * @param[in] BufferSize
+ * Size of buffer in bytes.
+ *
+ * @return
+ * TRUE if the buffer was large enough and was filled with
+ * the requested information, FALSE otherwise.
+ *
+ * @remarks
+ * The returned information is mostly related to Sony Memory Stick devices.
+ * On Vista+ the returned information is disk sector size and volume length in sectors,
+ * regardless of the type of disk.
+ * ReactOS implementation returns DEVICE_HOTPLUG flag if inspected device is a hotplug
device
+ * as well as sector size and volume length of disk device.
+ */
+BOOL
+NTAPI
+QueryDeviceInformation(
+ _In_ PWCHAR DriveRoot,
+ _Out_ PVOID DeviceInformation,
+ _In_ ULONG BufferSize)
+{
+ PDEVICE_INFORMATION DeviceInfo = DeviceInformation;
+ IO_STATUS_BLOCK Iosb;
+ DISK_GEOMETRY DiskGeometry;
+ STORAGE_HOTPLUG_INFO HotplugInfo;
+ GET_LENGTH_INFORMATION LengthInformation;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING DeviceName;
+ HANDLE FileHandle;
+ NTSTATUS Status;
+ WCHAR DiskDevice[MAX_PATH];
+ WCHAR DriveName[MAX_PATH];
+
+ /* Buffer should be able to at least hold DeviceFlags */
+ if (BufferSize < sizeof(ULONG) ||
+ !NT_SUCCESS(RtlStringCchCopyW(DriveName, ARRAYSIZE(DriveName), DriveRoot)))
+ {
+ return FALSE;
+ }
+
+ if (DriveName[wcslen(DriveName) - 1] != L'\\')
+ {
+ /* Append the trailing backslash for GetVolumeNameForVolumeMountPointW */
+ if (!NT_SUCCESS(RtlStringCchCatW(DriveName, ARRAYSIZE(DriveName),
L"\\")))
+ return FALSE;
+ }
+
+ if (!GetVolumeNameForVolumeMountPointW(DriveName, DiskDevice, ARRAYSIZE(DiskDevice))
||
+ !RtlDosPathNameToNtPathName_U(DiskDevice, &DeviceName, NULL, NULL))
+ {
+ /* Disk has no volume GUID, fallback to QueryDosDevice */
+ DriveName[wcslen(DriveName) - 1] = UNICODE_NULL;
+ if (!QueryDosDeviceW(DriveName, DiskDevice, ARRAYSIZE(DiskDevice)))
+ return FALSE;
+ RtlInitUnicodeString(&DeviceName, DiskDevice);
+ }
+ else
+ {
+ /* Trim the trailing backslash since we will work with a device object */
+ DeviceName.Length -= sizeof(WCHAR);
+ }
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &DeviceName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ Status = NtOpenFile(&FileHandle,
+ FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
+ &ObjectAttributes,
+ &Iosb,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_SYNCHRONOUS_IO_NONALERT);
+ if (!NT_SUCCESS(Status))
+ return FALSE;
+
+ Status = NtDeviceIoControlFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ IOCTL_STORAGE_GET_HOTPLUG_INFO,
+ NULL,
+ 0,
+ &HotplugInfo,
+ sizeof(HotplugInfo));
+ if (!NT_SUCCESS(Status))
+ goto Quit;
+
+ DeviceInfo->DeviceFlags = 0;
+ if (HotplugInfo.MediaHotplug || HotplugInfo.DeviceHotplug)
+ {
+ /* This is a hotplug device */
+ DeviceInfo->DeviceFlags |= DEVICE_HOTPLUG;
+ }
+
+ /* Other flags that would be set here are related to Sony "Memory Stick"
+ * type of devices which we do not have any special support for */
+
+ if (BufferSize >= sizeof(DEVICE_INFORMATION))
+ {
+ /* This is the Vista+ version of the structure.
+ * We need to also provide disk sector size and volume length in sectors. */
+ Status = NtDeviceIoControlFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ IOCTL_DISK_GET_DRIVE_GEOMETRY,
+ NULL,
+ 0,
+ &DiskGeometry,
+ sizeof(DiskGeometry));
+ if (!NT_SUCCESS(Status))
+ goto Quit;
+
+ Status = NtDeviceIoControlFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ IOCTL_DISK_GET_LENGTH_INFO,
+ NULL,
+ 0,
+ &LengthInformation,
+ sizeof(LengthInformation));
+ if (!NT_SUCCESS(Status))
+ goto Quit;
+
+ LengthInformation.Length.QuadPart /= DiskGeometry.BytesPerSector;
+ DeviceInfo->SectorSize = DiskGeometry.BytesPerSector;
+ DeviceInfo->SectorCount = LengthInformation.Length;
+ }
+
+ Status = STATUS_SUCCESS;
+
+Quit:
+ NtClose(FileHandle);
+ return NT_SUCCESS(Status);
+}
diff --git a/sdk/include/reactos/libs/fmifs/fmifs.h
b/sdk/include/reactos/libs/fmifs/fmifs.h
index 482b3b02457..27e3950239e 100644
--- a/sdk/include/reactos/libs/fmifs/fmifs.h
+++ b/sdk/include/reactos/libs/fmifs/fmifs.h
@@ -33,6 +33,20 @@ typedef struct
PCHAR Output;
} TEXTOUTPUT, *PTEXTOUTPUT;
+/* Device information */
+typedef struct _DEVICE_INFORMATION
+{
+ ULONG DeviceFlags;
+ ULONG SectorSize;
+ LARGE_INTEGER SectorCount;
+} DEVICE_INFORMATION, *PDEVICE_INFORMATION;
+
+/* Device information flags */
+#define MEMORYSTICK_FORMAT_CAPABLE 0x10
+#define MEMORYSTICK_SUPPORTS_PROGRESS_BAR 0x20
+#define DEVICE_HOTPLUG 0x40
+#define DEVICE_MEMORYSTICK 0x41
+
/* media flags */
typedef enum
{
@@ -163,11 +177,12 @@ QueryAvailableFileSystemFormat(
OUT UCHAR* Minor,
OUT BOOLEAN* LatestVersion);
-BOOL NTAPI
+BOOL
+NTAPI
QueryDeviceInformation(
- IN PWCHAR DriveRoot,
- OUT ULONG* Buffer, /* That is probably some 4-bytes structure */
- IN ULONG BufferSize); /* 4 */
+ _In_ PWCHAR DriveRoot,
+ _Out_ PVOID DeviceInformation,
+ _In_ ULONG BufferSize);
BOOL NTAPI
QueryFileSystemName(