[PATCH v2] kernel32/tests: Test FindFirstFile etc. with wildcards.

Lauri Kenttä lauri.kentta at gmail.com
Sat Dec 3 14:27:19 CST 2016


Inspired by bug 7961.

v2: Apparently Windows has much more strict limits for file names on
native file systems (compared to VirtualBox shared folders), so this
version of the patch leaves out some of the more problematic ones.
Tested on Windows 2003 Server with NTFS.

Signed-off-by: Lauri Kenttä <lauri.kentta at gmail.com>
---
 dlls/kernel32/tests/file.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 98 insertions(+)

diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c
index f039cf9..fa21a14 100644
--- a/dlls/kernel32/tests/file.c
+++ b/dlls/kernel32/tests/file.c
@@ -2812,6 +2812,103 @@ cleanup:
     RemoveDirectoryA("test-dir");
 }
 
+static void test_FindFirstFile_wildcards(void)
+{
+    WIN32_FIND_DATAA find_data;
+    HANDLE handle;
+    int i, j, k;
+    static const char* files[] = {
+        "..a", "..a..a", "..a..a..a", "..a.a", "..a.a..a", "..a.a.a",
+        ".a", ".a..a", ".a..a..a", ".a.a", ".a.a..a", ".a.a.a", ".aa", ".aaa",
+        "a", "a..a", "a..a..a", "a..a.a", "a.a", "a.a..a", "a.a.a",
+        "a.aa", "aa", "aa.a", "aaa", "aaaa"
+    };
+    static const struct {
+        int todo;
+        const char *pattern, *result;
+    } tests[] = {
+        {0, "*.*.*", "'.', '..', '..a', '..a..a', '..a..a..a', '..a.a', '..a.a..a', '..a.a.a', '.a', '.a..a', '.a..a..a', '.a.a', '.a.a..a', '.a.a.a', '.aa', '.aaa', 'a', 'a..a', 'a..a..a', 'a..a.a', 'a.a', 'a.a..a', 'a.a.a', 'a.aa', 'aa', 'aa.a', 'aaa', 'aaaa'"},
+        {0, "*.*.", "'.', '..', '..a', '..a..a', '..a..a..a', '..a.a', '..a.a..a', '..a.a.a', '.a', '.a..a', '.a..a..a', '.a.a', '.a.a..a', '.a.a.a', '.aa', '.aaa', 'a', 'a..a', 'a..a..a', 'a..a.a', 'a.a', 'a.a..a', 'a.a.a', 'a.aa', 'aa', 'aa.a', 'aaa', 'aaaa'"},
+        {0, ".*.*", "'.', '..', '..a', '..a..a', '..a..a..a', '..a.a', '..a.a..a', '..a.a.a', '.a', '.a..a', '.a..a..a', '.a.a', '.a.a..a', '.a.a.a', '.aa', '.aaa'"},
+        {0, "*.*", "'.', '..', '..a', '..a..a', '..a..a..a', '..a.a', '..a.a..a', '..a.a.a', '.a', '.a..a', '.a..a..a', '.a.a', '.a.a..a', '.a.a.a', '.aa', '.aaa', 'a', 'a..a', 'a..a..a', 'a..a.a', 'a.a', 'a.a..a', 'a.a.a', 'a.aa', 'aa', 'aa.a', 'aaa', 'aaaa'"},
+        {0, ".*", "'.', '..', '..a', '..a..a', '..a..a..a', '..a.a', '..a.a..a', '..a.a.a', '.a', '.a..a', '.a..a..a', '.a.a', '.a.a..a', '.a.a.a', '.aa', '.aaa'"},
+        {1, "*.", "'.', '..', 'a', '.a', '..a', 'aa', '.aa', 'aaa', 'aaaa', '.aaa'"},
+        {0, "*", "'.', '..', '..a', '..a..a', '..a..a..a', '..a.a', '..a.a..a', '..a.a.a', '.a', '.a..a', '.a..a..a', '.a.a', '.a.a..a', '.a.a.a', '.aa', '.aaa', 'a', 'a..a', 'a..a..a', 'a..a.a', 'a.a', 'a.a..a', 'a.a.a', 'a.aa', 'aa', 'aa.a', 'aaa', 'aaaa'"},
+        {1, "*..*", "'.', '..', '..a', '..a..a', '..a..a..a', '..a.a', '..a.a..a', '..a.a.a', '.a..a', '.a..a..a', '.a.a..a', 'a..a', 'a..a..a', 'a..a.a', 'a.a..a'"},
+        {1, "*..", "'.', '..', 'a', '.a', '..a', 'aa', '.aa', 'aaa', 'aaaa', '.aaa'"},
+        {1, ".*.", "'.', '..', '.a', '.aa', '.aaa'"},
+        {0, "..*", "'.', '..', '..a', '..a..a', '..a..a..a', '..a.a', '..a.a..a', '..a.a.a'"},
+        {0, "**", "'.', '..', '..a', '..a..a', '..a..a..a', '..a.a', '..a.a..a', '..a.a.a', '.a', '.a..a', '.a..a..a', '.a.a', '.a.a..a', '.a.a.a', '.aa', '.aaa', 'a', 'a..a', 'a..a..a', 'a..a.a', 'a.a', 'a.a..a', 'a.a.a', 'a.aa', 'aa', 'aa.a', 'aaa', 'aaaa'"},
+        {0, "**.", "'.', '..', '..a', '..a..a', '..a..a..a', '..a.a', '..a.a..a', '..a.a.a', '.a', '.a..a', '.a..a..a', '.a.a', '.a.a..a', '.a.a.a', '.aa', '.aaa', 'a', 'a..a', 'a..a..a', 'a..a.a', 'a.a', 'a.a..a', 'a.a.a', 'a.aa', 'aa', 'aa.a', 'aaa', 'aaaa'"},
+        {0, "*. ", "'.', '..', '..a', '..a..a', '..a..a..a', '..a.a', '..a.a..a', '..a.a.a', '.a', '.a..a', '.a..a..a', '.a.a', '.a.a..a', '.a.a.a', '.aa', '.aaa', 'a', 'a..a', 'a..a..a', 'a..a.a', 'a.a', 'a.a..a', 'a.a.a', 'a.aa', 'aa', 'aa.a', 'aaa', 'aaaa'"},
+        {1, "* .", "'.', '..', 'a', '.a', '..a', 'aa', '.aa', 'aaa', 'aaaa', '.aaa'"},
+        {0, "* . ", "'.', '..', '..a', '..a..a', '..a..a..a', '..a.a', '..a.a..a', '..a.a.a', '.a', '.a..a', '.a..a..a', '.a.a', '.a.a..a', '.a.a.a', '.aa', '.aaa', 'a', 'a..a', 'a..a..a', 'a..a.a', 'a.a', 'a.a..a', 'a.a.a', 'a.aa', 'aa', 'aa.a', 'aaa', 'aaaa'"},
+        {0, "*.. ", "'.', '..', '..a', '..a..a', '..a..a..a', '..a.a', '..a.a..a', '..a.a.a', '.a', '.a..a', '.a..a..a', '.a.a', '.a.a..a', '.a.a.a', '.aa', '.aaa', 'a', 'a..a', 'a..a..a', 'a..a.a', 'a.a', 'a.a..a', 'a.a.a', 'a.aa', 'aa', 'aa.a', 'aaa', 'aaaa'"},
+        {1, "*. .", "'.', '..', 'a', '.a', '..a', 'aa', '.aa', 'aaa', 'aaaa', '.aaa'"},
+        {1, "* ..", "'.', '..', 'a', '.a', '..a', 'aa', '.aa', 'aaa', 'aaaa', '.aaa'"},
+        {1, " *..", "'.aaa'"},
+        {0, "..* ", "'.', '..', '..a', '..a..a', '..a..a..a', '..a.a', '..a.a..a', '..a.a.a'"},
+        {1, "?", "'.', '..', 'a'"},
+        {1, "?.", "'.', '..', 'a'"},
+        {1, "?. ", "'.', '..', 'a'"},
+        {1, "??.", "'.', '..', 'a', 'aa'"},
+        {1, "??. ", "'.', '..', 'a', 'aa'"},
+        {1, "???.", "'.', '..', 'a', 'aa', 'aaa'"},
+        {1, "?.??.", "'.', '..', '.a', '.aa', 'a', 'a.a', 'a.aa'"}
+    };
+
+    CreateDirectoryA("test-dir", NULL);
+    SetCurrentDirectoryA("test-dir");
+    for (i = 0; i < sizeof(files) / sizeof(files[0]); ++i)
+        _lclose(_lcreat(files[i], 0));
+
+    for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
+    {
+        char correct[512] = "";
+        char incorrect[512] = "";
+        char missed[512];
+        strcpy(missed, tests[i].result);
+
+        handle = FindFirstFileA(tests[i].pattern, &find_data);
+        if (handle) do {
+            char quoted[16] = "'";
+            char* ptr;
+            strcat(quoted, find_data.cFileName);
+            strcat(quoted, "'");
+
+            /* Format results nicely. */
+            if (strstr(tests[i].result, quoted))
+                strcat(correct, ", "), strcat(correct, quoted);
+            else
+                strcat(incorrect, ", "), strcat(incorrect, quoted);
+            if ((ptr = strstr(missed, quoted)))
+            {
+                while ((*ptr++ = ' ') && *ptr && *ptr != ' ');
+                while (ptr != missed && ptr[-1] != '\'') *--ptr = ' ';
+            }
+        } while (FindNextFileA(handle, &find_data));
+        FindClose(handle);
+
+        /* Format results nicely. */
+        for (j = 0; missed[j] && missed[j] == ' '; ++j);
+        for (k = 0; (missed[k] = missed[j]) != 0; ++k)
+            for (++j; missed[j] && missed[j] == ' '; ++j);
+
+        todo_wine_if (tests[i].todo)
+        ok(missed[0] == 0 && incorrect[0] == 0,
+           "FindFirstFile with '%s' found correctly %s, found incorrectly %s, and missed %s\n",
+           tests[i].pattern,
+           correct[0] ? correct+2 : "none",
+           incorrect[0] ? incorrect+2 : "none",
+           missed[0] ? missed : "none");
+    }
+
+    for (i = 0; i < sizeof(files) / sizeof(files[0]); ++i)
+        DeleteFileA(files[i]);
+    SetCurrentDirectoryA("..");
+    RemoveDirectoryA("test-dir");
+}
+
 static int test_Mapfile_createtemp(HANDLE *handle)
 {
     SetFileAttributesA(filename,FILE_ATTRIBUTE_NORMAL);
@@ -4740,6 +4837,7 @@ START_TEST(file)
     test_MoveFileW();
     test_FindFirstFileA();
     test_FindNextFileA();
+    test_FindFirstFile_wildcards();
     test_FindFirstFileExA(FindExInfoStandard, 0, 0);
     test_FindFirstFileExA(FindExInfoStandard, 0, FIND_FIRST_EX_CASE_SENSITIVE);
     test_FindFirstFileExA(FindExInfoStandard, 0, FIND_FIRST_EX_LARGE_FETCH);
-- 
2.10.2




More information about the wine-patches mailing list