Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: FileIdInformation support #494

Open
billziss-gh opened this issue Feb 23, 2023 · 2 comments
Open

Enhancement: FileIdInformation support #494

billziss-gh opened this issue Feb 23, 2023 · 2 comments

Comments

@billziss-gh
Copy link
Collaborator

See #486 and pvt-idinfo branch.

@billziss-gh
Copy link
Collaborator Author

billziss-gh commented Feb 23, 2023

Patch:

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);

AppVeyor build. Fails on VS2015 and VS2017 with compilation errors on this line. Builds on VS2022.

1>..\..\src\sys\fileinfo.c(307): error C2220: warning treated as error - no 'object' file generated
1>..\..\src\sys\fileinfo.c(307): warning C4204: nonstandard extension used: non-constant aggregate initializer

@billziss-gh
Copy link
Collaborator Author

FYI @CFSworks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

1 participant