From 82f84f5bf70cf25e0eb15b9e88ffd79297615fac Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Thu, 23 Feb 2023 12:31:01 +0000 Subject: [PATCH] sys: FspFsvolQueryInformation: FileIdInformation --- src/sys/fileinfo.c | 33 +++++++++++++++++++++++++++++++++ tst/winfsp-tests/info-test.c | 22 ++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/sys/fileinfo.c b/src/sys/fileinfo.c index c0e69b57..2cbaf119 100644 --- a/src/sys/fileinfo.c +++ b/src/sys/fileinfo.c @@ -33,6 +33,8 @@ static NTSTATUS FspFsvolQueryBasicInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolQueryEaInformation(PFILE_OBJECT FileObject, PVOID *PBuffer, PVOID BufferEnd, const FSP_FSCTL_FILE_INFO *FileInfo); +static NTSTATUS FspFsvolQueryIdInformation(PFILE_OBJECT FileObject, + PVOID *PBuffer, PVOID BufferEnd); static NTSTATUS FspFsvolQueryInternalInformation(PFILE_OBJECT FileObject, PVOID *PBuffer, PVOID BufferEnd); static NTSTATUS FspFsvolQueryNameInformation(PFILE_OBJECT FileObject, @@ -106,6 +108,7 @@ FAST_IO_QUERY_OPEN FspFastIoQueryOpen; #pragma alloc_text(PAGE, FspFsvolQueryAttributeTagInformation) #pragma alloc_text(PAGE, FspFsvolQueryBasicInformation) #pragma alloc_text(PAGE, FspFsvolQueryEaInformation) +#pragma alloc_text(PAGE, FspFsvolQueryIdInformation) #pragma alloc_text(PAGE, FspFsvolQueryInternalInformation) #pragma alloc_text(PAGE, FspFsvolQueryNameInformation) #pragma alloc_text(PAGE, FspFsvolQueryNetworkOpenInformation) @@ -288,6 +291,32 @@ static NTSTATUS FspFsvolQueryEaInformation(PFILE_OBJECT FileObject, return STATUS_SUCCESS; } +static NTSTATUS FspFsvolQueryIdInformation(PFILE_OBJECT FileObject, + PVOID *PBuffer, PVOID BufferEnd) +{ + PAGED_CODE(); + + PFILE_ID_INFORMATION Info = (PFILE_ID_INFORMATION)*PBuffer; + FSP_FILE_NODE *FileNode = FileObject->FsContext; + PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject; + FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); + union + { + UINT64 IndexNumber; + FILE_ID_128 FileId; + } FileIdBuf = { .IndexNumber = FileNode->IndexNumber }; + + if ((PVOID)(Info + 1) > BufferEnd) + return STATUS_BUFFER_TOO_SMALL; + + Info->VolumeSerialNumber = FsvolDeviceExtension->VolumeParams.VolumeSerialNumber; + Info->FileId = FileIdBuf.FileId; + + *PBuffer = (PVOID)(Info + 1); + + return STATUS_SUCCESS; +} + static NTSTATUS FspFsvolQueryInternalInformation(PFILE_OBJECT FileObject, PVOID *PBuffer, PVOID BufferEnd) { @@ -961,6 +990,10 @@ static NTSTATUS FspFsvolQueryInformation( case FileHardLinkInformation: Result = STATUS_NOT_SUPPORTED; /* no hard link support */ return Result; + case FileIdInformation: + Result = FspFsvolQueryIdInformation(FileObject, &Buffer, BufferEnd); + Irp->IoStatus.Information = (UINT_PTR)((PUINT8)Buffer - (PUINT8)Irp->AssociatedIrp.SystemBuffer); + return Result; case FileInternalInformation: Result = FspFsvolQueryInternalInformation(FileObject, &Buffer, BufferEnd); Irp->IoStatus.Information = (UINT_PTR)((PUINT8)Buffer - (PUINT8)Irp->AssociatedIrp.SystemBuffer); diff --git a/tst/winfsp-tests/info-test.c b/tst/winfsp-tests/info-test.c index 3e91d0e6..caedbe43 100644 --- a/tst/winfsp-tests/info-test.c +++ b/tst/winfsp-tests/info-test.c @@ -273,6 +273,28 @@ void getfileinfo_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout) ASSERT(0 == FileInfo.nFileSizeLow && 0 == FileInfo.nFileSizeHigh); ASSERT(1 == FileInfo.nNumberOfLinks); + if (-1 != Flags) + { + /* WinFsp file systems respond to FileIdInformation queries with the IndexNumber zero-extended */ + struct + { + /* FILE_ID_INFO is missing from old version of SDK that we are still using */ + ULONGLONG VolumeSerialNumber; + UINT8 FileId[16]; + } IdInfo; + union + { + UINT64 IndexNumber; + UINT8 FileId[16]; + } ExpectedFileId = { 0 }; + Success = GetFileInformationByHandleEx(Handle, 0x12/*FileIdInfo*/, &IdInfo, sizeof IdInfo); + if (Success) + { + ExpectedFileId.IndexNumber = ((UINT64)FileInfo.nFileIndexHigh << 32) | (UINT64)FileInfo.nFileIndexLow; + ASSERT(0 == memcmp(&ExpectedFileId.FileId, &IdInfo.FileId, sizeof IdInfo.FileId)); + } + } + CloseHandle(Handle); memfs_stop(memfs);