[PATCH] kernelbase: Implement GetFileInformationByHandleEx(FileFullDirectoryInfo).
Paul Gofman
pgofman at codeweavers.com
Wed Feb 9 08:28:11 CST 2022
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
dlls/kernel32/tests/file.c | 60 ++++++++++++++++++++++++++++++++++----
dlls/kernelbase/file.c | 12 ++++++--
include/winbase.h | 15 ++++++++++
3 files changed, 80 insertions(+), 7 deletions(-)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c
index f8e49491a7d..0d178306648 100644
--- a/dlls/kernel32/tests/file.c
+++ b/dlls/kernel32/tests/file.c
@@ -4181,11 +4181,13 @@ todo_wine_if (i == 1)
static void test_GetFileInformationByHandleEx(void)
{
int i;
- char tempPath[MAX_PATH], tempFileName[MAX_PATH], buffer[1024], *strPtr;
- BOOL ret;
+ char tempPath[MAX_PATH], tempFileName[MAX_PATH], buffer[1024], buffer2[1024], *strPtr;
+ BOOL first, ret;
DWORD ret2, written;
+ unsigned int count, count2, size;
HANDLE directory, file;
FILE_ID_BOTH_DIR_INFO *bothDirInfo;
+ FILE_FULL_DIR_INFO *full_dir_info;
FILE_BASIC_INFO *basicInfo;
FILE_STANDARD_INFO *standardInfo;
FILE_NAME_INFO *nameInfo;
@@ -4205,7 +4207,11 @@ static void test_GetFileInformationByHandleEx(void)
{0xdeadbeef, NULL, 0, ERROR_INVALID_PARAMETER},
{FileIdBothDirectoryInfo, NULL, 0, ERROR_BAD_LENGTH},
{FileIdBothDirectoryInfo, NULL, sizeof(buffer), ERROR_NOACCESS},
- {FileIdBothDirectoryInfo, buffer, 0, ERROR_BAD_LENGTH}};
+ {FileIdBothDirectoryInfo, buffer, 0, ERROR_BAD_LENGTH},
+ {FileFullDirectoryInfo, NULL, 0, ERROR_BAD_LENGTH},
+ {FileFullDirectoryInfo, NULL, sizeof(buffer), ERROR_NOACCESS},
+ {FileFullDirectoryInfo, buffer, 0, ERROR_BAD_LENGTH},
+ };
if (!pGetFileInformationByHandleEx)
{
@@ -4236,6 +4242,7 @@ static void test_GetFileInformationByHandleEx(void)
"got %u.\n", checks[i].errorCode, GetLastError());
}
+ first = TRUE;
while (TRUE)
{
memset(buffer, 0xff, sizeof(buffer));
@@ -4243,8 +4250,51 @@ static void test_GetFileInformationByHandleEx(void)
if (!ret && GetLastError() == ERROR_NO_MORE_FILES)
break;
ok(ret, "GetFileInformationByHandleEx: failed to query for FileIdBothDirectoryInfo, got error %u.\n", GetLastError());
- if (!ret)
- break;
+
+ if (first)
+ {
+ count = 1;
+ bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
+ while (bothDirInfo->NextEntryOffset)
+ {
+ ++count;
+ size = offsetof(FILE_ID_BOTH_DIR_INFO, FileName[bothDirInfo->FileNameLength / 2]);
+ size = (size + 7) & ~7;
+ ok(bothDirInfo->NextEntryOffset == size,
+ "Got unexpected structure size, NextEntryOffset %u (%u).\n", bothDirInfo->NextEntryOffset,
+ size);
+ bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)(((char *)bothDirInfo) + bothDirInfo->NextEntryOffset);
+ }
+ size = offsetof(FILE_FULL_DIR_INFO, FileName[bothDirInfo->FileNameLength / 2]);
+ ret = pGetFileInformationByHandleEx(directory, FileFullDirectoryRestartInfo, buffer2, sizeof(buffer2));
+ ok(ret, "failed to query for FileIdBothDirectoryInfo, got error %u.\n", GetLastError());
+
+ count2 = 0;
+ bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
+ full_dir_info = (FILE_FULL_DIR_INFO *)buffer2;
+ while (1)
+ {
+ ++count2;
+ ok(bothDirInfo->FileNameLength == full_dir_info->FileNameLength,
+ "FileNameLength does not match, count2 %u.\n", count2);
+ ok(!memcmp(bothDirInfo->FileName, full_dir_info->FileName, full_dir_info->FileNameLength),
+ "FileName does not match, count %u.\n", count2);
+
+ if (!full_dir_info->NextEntryOffset || !bothDirInfo->NextEntryOffset)
+ break;
+
+ size = offsetof(FILE_FULL_DIR_INFO, FileName[full_dir_info->FileNameLength / 2]);
+ size = (size + 7) & ~7;
+ ok(full_dir_info->NextEntryOffset == size,
+ "Got unexpected structure size, NextEntryOffset %u (%u).\n", bothDirInfo->NextEntryOffset,
+ size);
+ full_dir_info = (FILE_FULL_DIR_INFO *)(((char *)full_dir_info) + full_dir_info->NextEntryOffset);
+ bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)(((char *)bothDirInfo) + bothDirInfo->NextEntryOffset);
+ }
+ ok(count2 == count, "Got unexpected count2 %u, count %u.\n", count2, count);
+ first = FALSE;
+ }
+
bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
while (TRUE)
{
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c
index 576e03eb62b..c1d9401f5c2 100644
--- a/dlls/kernelbase/file.c
+++ b/dlls/kernelbase/file.c
@@ -2954,13 +2954,13 @@ BOOL WINAPI DECLSPEC_HOTPATCH GetFileInformationByHandleEx( HANDLE handle, FILE_
NTSTATUS status;
IO_STATUS_BLOCK io;
+ TRACE( "%p, %u, %p, %u.\n", handle, class, info, size );
+
switch (class)
{
case FileStreamInfo:
case FileCompressionInfo:
case FileRemoteProtocolInfo:
- case FileFullDirectoryInfo:
- case FileFullDirectoryRestartInfo:
case FileStorageInfo:
case FileAlignmentInfo:
case FileIdExtdDirectoryInfo:
@@ -2969,6 +2969,13 @@ BOOL WINAPI DECLSPEC_HOTPATCH GetFileInformationByHandleEx( HANDLE handle, FILE_
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
return FALSE;
+ case FileFullDirectoryRestartInfo:
+ case FileFullDirectoryInfo:
+ status = NtQueryDirectoryFile( handle, NULL, NULL, NULL, &io, info, size,
+ FileFullDirectoryInformation, FALSE, NULL,
+ (class == FileFullDirectoryRestartInfo) );
+ break;
+
case FileAttributeTagInfo:
status = NtQueryInformationFile( handle, &io, info, size, FileAttributeTagInformation );
break;
@@ -3002,6 +3009,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH GetFileInformationByHandleEx( HANDLE handle, FILE_
case FileIoPriorityHintInfo:
case FileEndOfFileInfo:
default:
+ WARN( "class %u is not supported.\n", class );
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
diff --git a/include/winbase.h b/include/winbase.h
index 0a0bfde9d10..b2d5ca68d42 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -823,6 +823,21 @@ typedef struct _FILE_ID_BOTH_DIR_INFO {
WCHAR FileName[1];
} FILE_ID_BOTH_DIR_INFO, *PFILE_ID_BOTH_DIR_INFO;
+typedef struct _FILE_FULL_DIR_INFO {
+ ULONG NextEntryOffset;
+ ULONG FileIndex;
+ LARGE_INTEGER CreationTime;
+ LARGE_INTEGER LastAccessTime;
+ LARGE_INTEGER LastWriteTime;
+ LARGE_INTEGER ChangeTime;
+ LARGE_INTEGER EndOfFile;
+ LARGE_INTEGER AllocationSize;
+ ULONG FileAttributes;
+ ULONG FileNameLength;
+ ULONG EaSize;
+ WCHAR FileName[1];
+} FILE_FULL_DIR_INFO, *PFILE_FULL_DIR_INFO;
+
typedef struct _FILE_BASIC_INFO {
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
--
2.34.1
More information about the wine-devel
mailing list