[v4 2/3] ntdll: Implement FileIdInformation class support in NtQueryInformationFile (resend).

Jonathan Doron jond at wizery.com
Tue Feb 7 09:11:01 CST 2017


Signed-off-by: Jonathan Doron <jond at wizery.com>
---
 configure.ac            |  2 +-
 dlls/ntdll/file.c       | 28 ++++++++++++++++++++++-
 dlls/ntdll/tests/file.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/winternl.h      |  9 ++++++++
 4 files changed, 97 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index c6d63b2..f66bf44 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2262,7 +2262,7 @@ fi
 dnl **** FIXME: what about mixed cases, where we need two of them? ***
 
 dnl Check for statfs members
-AC_CHECK_MEMBERS([struct statfs.f_bfree, struct statfs.f_bavail, struct statfs.f_frsize, struct statfs.f_ffree, struct statfs.f_favail, struct statfs.f_namelen],,,
+AC_CHECK_MEMBERS([struct statfs.f_bfree, struct statfs.f_bavail, struct statfs.f_frsize, struct statfs.f_ffree, struct statfs.f_favail, struct statfs.f_namelen, struct statfs.f_fsid.__val],,,
 [#include <sys/types.h>
 #ifdef HAVE_SYS_PARAM_H
 # include <sys/param.h>
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index a6c1098..c6ff371 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -2377,7 +2377,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
         0,                                             /* FileRenameInformationBypassAccessCheck */
         0,                                             /* FileLinkInformationBypassAccessCheck */
         0,                                             /* FileVolumeNameInformation */
-        0,                                             /* FileIdInformation */
+        sizeof(FILE_ID_INFORMATION),                   /* FileIdInformation */
         0,                                             /* FileIdExtdDirectoryInformation */
         0,                                             /* FileReplaceCompletionInformation */
         0,                                             /* FileHardLinkFullIdInformation */
@@ -2619,6 +2619,32 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
             }
         }
         break;
+    case FileIdInformation:
+        {
+            FILE_ID_INFORMATION *info = ptr;
+            memset(info, 0, sizeof(*info));
+            if (fstat(fd, &st) == -1)
+            {
+                io->u.Status = FILE_GetNtStatus();
+            }
+            else
+            {
+#if defined(linux) && defined(HAVE_FSTATFS) && defined(HAVE_STRUCT_STATFS_F_FSID___VAL)
+                struct statfs volstats;
+                if (fstatfs(fd, &volstats) == -1)
+                {
+                    io->u.Status = FILE_GetNtStatus();
+                    break;
+                }
+
+                memcpy(&info->VolumeSerialNumber,
+                       &volstats.f_fsid.__val,
+                       min(sizeof(info->VolumeSerialNumber), sizeof(volstats.f_fsid.__val)));
+#endif
+                ((LARGE_INTEGER *)&info->FileId)->QuadPart = st.st_ino;
+            }
+        }
+        break;
     default:
         FIXME("Unsupported class (%d)\n", class);
         io->u.Status = STATUS_NOT_IMPLEMENTED;
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 57d7df9..00856ab 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -1444,6 +1444,65 @@ static void test_file_basic_information(void)
     CloseHandle( h );
 }
 
+static void test_file_id_information(void)
+{
+    IO_STATUS_BLOCK io;
+    FILE_ID_INFORMATION fid1, fid2;
+    HANDLE h = INVALID_HANDLE_VALUE;
+    NTSTATUS res;
+    char path[MAX_PATH], buffer[MAX_PATH];
+
+    /* Generate a temp file name */
+    GetTempPathA(MAX_PATH, path);
+    GetTempFileNameA(path, "foo", 0, buffer);
+
+    /* Create the temp file */
+    h = CreateFileA(buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+    ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
+
+    /* Query the temp file unique id */
+    memset(&fid1, 0, sizeof(fid1));
+    res = pNtQueryInformationFile(h, &io, &fid1, sizeof fid1, FileIdInformation);
+    if ((res == STATUS_NOT_IMPLEMENTED) || (res == STATUS_INVALID_INFO_CLASS))
+    {
+        CloseHandle(h);
+        DeleteFileA(buffer);
+        win_skip("FileIdInformation not supported\n");
+        return;
+    }
+
+    ok(res == STATUS_SUCCESS, "can't get fid1, res %x\n", res);
+
+    CloseHandle(h);
+
+    /* Open the file again */
+    h = CreateFileA(buffer, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+    ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
+
+    /* Query again the temp file unique id */
+    memset(&fid2, 0, sizeof(fid2));
+    res = pNtQueryInformationFile(h, &io, &fid2, sizeof fid2, FileIdInformation);
+    ok(res == STATUS_SUCCESS, "can't get fid2, res %x\n", res);
+
+    /* Verify we got the same unique id for the file */
+    ok(memcmp(&fid1, &fid2, sizeof fid1) == 0, "file id is not unique\n");
+
+    CloseHandle(h);
+
+    h = create_temp_file(0);
+    ok(h != NULL, "error creating new file %d\n", GetLastError());
+
+    memset(&fid2, 0, sizeof(fid2));
+    res = pNtQueryInformationFile(h, &io, &fid2, sizeof fid2, FileIdInformation);
+    ok(res == STATUS_SUCCESS, "can't get new fid2, res %x\n", res);
+
+    /* Verify we got the different unique id for the new file */
+    ok(memcmp(&fid1, &fid2, sizeof fid1) != 0, "file id is not unique\n");
+
+    CloseHandle(h);
+    DeleteFileA(buffer);
+}
+
 static void test_file_all_information(void)
 {
     IO_STATUS_BLOCK io;
@@ -4262,4 +4321,5 @@ START_TEST(file)
     test_file_disposition_information();
     test_query_volume_information_file();
     test_query_attribute_information_file();
+    test_file_id_information();
 }
diff --git a/include/winternl.h b/include/winternl.h
index 891b6a7..2f2ea86 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -571,6 +571,15 @@ typedef struct _FILE_INTERNAL_INFORMATION {
     LARGE_INTEGER IndexNumber;
 } FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION;
 
+typedef struct _FILE_ID_128 {
+    UCHAR Identifier[16];
+} FILE_ID_128, *PFILE_ID_128;
+
+typedef struct _FILE_ID_INFORMATION {
+    ULONGLONG VolumeSerialNumber;
+    FILE_ID_128 FileId;
+} FILE_ID_INFORMATION, *PFILE_ID_INFORMATION;
+
 typedef struct _FILE_EA_INFORMATION {
     ULONG EaSize;
 } FILE_EA_INFORMATION, *PFILE_EA_INFORMATION;
-- 
2.9.3




More information about the wine-patches mailing list