[v5 1/2] ntdll: Implement FileIdInformation class support in NtQueryInformationFile.
Jonathan Doron
jond at wizery.com
Tue Feb 14 12:21:08 CST 2017
Signed-off-by: Jonathan Doron <jond at wizery.com>
---
dlls/ntdll/file.c | 29 ++++++++++++++++++++++++-
dlls/ntdll/tests/file.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++
include/winternl.h | 9 ++++++++
3 files changed, 93 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index a6c1098..182db56 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,33 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
}
}
break;
+ case FileIdInformation:
+ {
+ if (fstat(fd, &st) == -1)
+ {
+ io->u.Status = FILE_GetNtStatus();
+ }
+ else
+ {
+ FILE_ID_INFORMATION *info = ptr;
+#if defined(HAVE_FSTATFS)
+ struct statfs volstats;
+ if (fstatfs(fd, &volstats) == -1)
+ {
+ io->u.Status = FILE_GetNtStatus();
+ break;
+ }
+
+ memcpy(&info->VolumeSerialNumber,
+ &volstats.f_fsid,
+ min(sizeof(info->VolumeSerialNumber), sizeof(volstats.f_fsid)));
+#else
+ memset(&info->VolumeSerialNumber, 0, sizeof(info->VolumeSerialNumber));
+#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..926b8f8 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -1444,6 +1444,61 @@ 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];
+
+ GetTempPathA(MAX_PATH, path);
+ GetTempFileNameA(path, "foo", 0, buffer);
+
+ 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);
+
+ h = CreateFileA(buffer, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+ ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
+
+ 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 +4317,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