[PATCH v2] kernel32: properly handle FindFirstFileEx flags

Dorian Wouters dorian at elementw.net
Fri Jan 4 10:54:24 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>
---

Change test requirements related to FIND_FIRST_EX_CASE_SENSITIVE

 dlls/kernel32/file.c       | 16 ++++++++++++++--
 dlls/kernel32/tests/file.c | 10 +++++++++-
 include/winbase.h          |  5 +++--
 3 files changed, 26 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..eae62fd646 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,14 @@ 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) && handle == INVALID_HANDLE_VALUE)
+    {
+        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