[PATCH] kernel32: properly handle FindFirstFileEx flags
Dorian Wouters
dorian at elementw.net
Thu Jan 3 17:35:57 CST 2019
- Implement FIND_FIRST_EX_CASE_SENSITIVE behaviour
- Silently ignore FIND_FIRST_EX_LARGE_FETCH as it is of no consequence
- Warn on use of unimplemented FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY
* #define its flag constant in winbase.h
- Fail with ERROR_INVALID_PARAMETER on unknown flags
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=36946
Signed-off-by: Dorian Wouters <dorian at elementw.net>
---
dlls/kernel32/file.c | 16 ++++++++++++++--
dlls/kernel32/tests/file.c | 11 ++++++++++-
include/winbase.h | 5 +++--
3 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/dlls/kernel32/file.c b/dlls/kernel32/file.c
index 3214d724cb..7ca534f59c 100644
--- a/dlls/kernel32/file.c
+++ b/dlls/kernel32/file.c
@@ -1964,9 +1964,16 @@ HANDLE WINAPI FindFirstFileExW( LPCWSTR filename, FINDEX_INFO_LEVELS level,
TRACE("%s %d %p %d %p %x\n", debugstr_w(filename), level, data, search_op, filter, flags);
- if (flags != 0)
+ if (flags & ~(FIND_FIRST_EX_CASE_SENSITIVE | FIND_FIRST_EX_LARGE_FETCH |
+ FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY))
{
FIXME("flags not implemented 0x%08x\n", flags );
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return INVALID_HANDLE_VALUE;
+ }
+ if (flags & FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY)
+ {
+ FIXME("FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY not implemented");
}
if (search_op != FindExSearchNameMatch && search_op != FindExSearchLimitToDirectories)
{
@@ -2043,7 +2050,12 @@ HANDLE WINAPI FindFirstFileExW( LPCWSTR filename, FINDEX_INFO_LEVELS level,
attr.Length = sizeof(attr);
attr.RootDirectory = 0;
- attr.Attributes = OBJ_CASE_INSENSITIVE;
+ /*
+ * FIND_FIRST_EX_CASE_SENSITIVE should only work if HKLM\SYSTEM\CurrentControlSet\
+ * Control\Session Manager\kernel\obcaseinsensitive is set to 0. Assume the application
+ * actually supports case sensitive lookups since it asked for it explicitly.
+ */
+ attr.Attributes = (flags & FIND_FIRST_EX_CASE_SENSITIVE) ? 0 : OBJ_CASE_INSENSITIVE;
attr.ObjectName = &nt_name;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c
index d1b76bb711..8da272cea3 100644
--- a/dlls/kernel32/tests/file.c
+++ b/dlls/kernel32/tests/file.c
@@ -2739,7 +2739,7 @@ static void test_FindFirstFileExA(FINDEX_INFO_LEVELS level, FINDEX_SEARCH_OPS se
_lclose(_lcreat("test-dir\\file2", 0));
CreateDirectoryA("test-dir\\dir1", NULL);
SetLastError(0xdeadbeef);
- handle = pFindFirstFileExA("test-dir\\*", level, &search_results, search_ops, NULL, flags);
+ handle = pFindFirstFileExA("Test-dir\\*", level, &search_results, search_ops, NULL, flags);
if (handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
{
win_skip("FindFirstFileExA is not implemented\n");
@@ -2759,6 +2759,15 @@ static void test_FindFirstFileExA(FINDEX_INFO_LEVELS level, FINDEX_SEARCH_OPS se
#define CHECK_NAME(fn) (strcmp((fn), "file1") == 0 || strcmp((fn), "file2") == 0 || strcmp((fn), "dir1") == 0)
#define CHECK_LEVEL(fn) (level != FindExInfoBasic || !(fn)[0])
+ if (flags & FIND_FIRST_EX_CASE_SENSITIVE)
+ {
+ ok(handle == INVALID_HANDLE_VALUE, "Case-sensitive FindFirstFile succeeded\n");
+ ok(GetLastError() == ERROR_PATH_NOT_FOUND,
+ "Case-sensitive FindFirstFile failed with non-PATH_NOT_FOUND (err=%u)\n", GetLastError());
+ SetLastError(0xdeadbeef);
+ handle = pFindFirstFileExA("test-dir\\*", level, &search_results, search_ops, NULL, flags);
+ }
+
ok(handle != INVALID_HANDLE_VALUE, "FindFirstFile failed (err=%u)\n", GetLastError());
ok(strcmp(search_results.cFileName, ".") == 0, "First entry should be '.', is %s\n", search_results.cFileName);
ok(CHECK_LEVEL(search_results.cAlternateFileName), "FindFirstFile unexpectedly returned an alternate filename\n");
diff --git a/include/winbase.h b/include/winbase.h
index 20c73af319..3f5553ef24 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -292,8 +292,9 @@ typedef enum _FINDEX_INFO_LEVELS
FindExInfoMaxInfoLevel
} FINDEX_INFO_LEVELS;
-#define FIND_FIRST_EX_CASE_SENSITIVE 1
-#define FIND_FIRST_EX_LARGE_FETCH 2
+#define FIND_FIRST_EX_CASE_SENSITIVE 1
+#define FIND_FIRST_EX_LARGE_FETCH 2
+#define FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY 4
typedef enum _FINDEX_SEARCH_OPS
{
--
2.19.2
More information about the wine-devel
mailing list