Piotr Caban : ntdll: Fix NtQueryDirectoryFile behavior on short file names on case insensitive file systems.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Feb 3 07:40:00 CST 2016


Module: wine
Branch: stable
Commit: 360c56a361fa93ee675fadc0a39368e51cf6ca02
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=360c56a361fa93ee675fadc0a39368e51cf6ca02

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon Dec 21 18:42:04 2015 +0100

ntdll: Fix NtQueryDirectoryFile behavior on short file names on case insensitive file systems.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Ken Thomases <ken at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit a8ef26149308f577151f14a2d359868754c7ea20)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>

---

 dlls/ntdll/directory.c       | 14 --------------
 dlls/ntdll/tests/directory.c | 41 ++++++++++++++++++++++++++++++++++++++---
 2 files changed, 38 insertions(+), 17 deletions(-)

diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index 4faafe9..23ebf48 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -2120,15 +2120,6 @@ static int read_directory_stat( int fd, IO_STATUS_BLOCK *io, void *buffer, ULONG
             }
             else io->u.Status = restart_scan ? STATUS_NO_SUCH_FILE : STATUS_NO_MORE_FILES;
         }
-        else if (!case_sensitive && ret && (errno == ENOENT || errno == ENOTDIR))
-        {
-            /* If the file does not exist, return that info.
-             * If the file DOES exist, return failure and fallback to the next
-             * read_directory_* function (we need to return the case-preserved
-             * filename stored on the filesystem). */
-            ret = 0;
-            io->u.Status = restart_scan ? STATUS_NO_SUCH_FILE : STATUS_NO_MORE_FILES;
-        }
         else
         {
             ret = -1;
@@ -2214,11 +2205,6 @@ static int read_directory_getattrlist( int fd, IO_STATUS_BLOCK *io, void *buffer
             }
             else io->u.Status = restart_scan ? STATUS_NO_SUCH_FILE : STATUS_NO_MORE_FILES;
         }
-        else if ((errno == ENOENT || errno == ENOTDIR) && !get_dir_case_sensitivity("."))
-        {
-            io->u.Status = restart_scan ? STATUS_NO_SUCH_FILE : STATUS_NO_MORE_FILES;
-            ret = 0;
-        }
     }
     else ret = -1;
 
diff --git a/dlls/ntdll/tests/directory.c b/dlls/ntdll/tests/directory.c
index 730b0f1..7b1002a 100644
--- a/dlls/ntdll/tests/directory.c
+++ b/dlls/ntdll/tests/directory.c
@@ -60,6 +60,7 @@ static struct testfile_s {
     int nfound;               /* How many were found (expect 1) */
     WCHAR nameW[20];          /* unicode version of name (filled in later) */
 } testfiles[] = {
+    { 0, 0, FILE_ATTRIBUTE_NORMAL,    "longfilename.tmp", NULL, "normal" },
     { 0, 0, FILE_ATTRIBUTE_NORMAL,    "n.tmp", NULL, "normal" },
     { 1, 0, FILE_ATTRIBUTE_HIDDEN,    "h.tmp", NULL, "hidden" },
     { 1, 0, FILE_ATTRIBUTE_SYSTEM,    "s.tmp", NULL, "system" },
@@ -234,10 +235,17 @@ static void test_flags_NtQueryDirectoryFile(OBJECT_ATTRIBUTES *attr, const char
 static void test_NtQueryDirectoryFile(void)
 {
     OBJECT_ATTRIBUTES attr;
-    UNICODE_STRING ntdirname;
+    UNICODE_STRING ntdirname, mask;
     char testdirA[MAX_PATH];
     WCHAR testdirW[MAX_PATH];
     int i;
+    IO_STATUS_BLOCK io;
+    WCHAR short_name[12];
+    UINT data_size;
+    BYTE data[8192];
+    FILE_BOTH_DIRECTORY_INFORMATION *fbdi = (FILE_BOTH_DIRECTORY_INFORMATION*)data;
+    DWORD status;
+    HANDLE dirh;
 
     /* Clean up from prior aborted run, if any, then set up test files */
     ok(GetTempPathA(MAX_PATH, testdirA), "couldn't get temp dir\n");
@@ -260,8 +268,6 @@ static void test_NtQueryDirectoryFile(void)
 
     for (i = 0; testfiles[i].name; i++)
     {
-        UNICODE_STRING mask;
-
         if (testfiles[i].nameW[0] == '.') continue;  /* . and .. as masks are broken on Windows */
         mask.Buffer = testfiles[i].nameW;
         mask.Length = mask.MaximumLength = lstrlenW(testfiles[i].nameW) * sizeof(WCHAR);
@@ -271,6 +277,35 @@ static void test_NtQueryDirectoryFile(void)
         test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, TRUE, FALSE);
     }
 
+    /* short path passed as mask */
+    status = pNtOpenFile(&dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ,
+            FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE);
+    ok(status == STATUS_SUCCESS, "failed to open dir '%s'\n", testdirA);
+    if (status != STATUS_SUCCESS) {
+        skip("can't test if we can't open the directory\n");
+        return;
+    }
+    mask.Buffer = testfiles[0].nameW;
+    mask.Length = mask.MaximumLength = lstrlenW(testfiles[0].nameW) * sizeof(WCHAR);
+    data_size = offsetof(FILE_BOTH_DIRECTORY_INFORMATION, FileName[256]);
+    pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
+            FileBothDirectoryInformation, TRUE, &mask, FALSE);
+    ok(U(io).Status == STATUS_SUCCESS, "failed to query directory; status %x\n", U(io).Status);
+    ok(fbdi->ShortName[0], "ShortName is empty\n");
+
+    mask.Length = mask.MaximumLength = fbdi->ShortNameLength;
+    memcpy(short_name, fbdi->ShortName, mask.Length);
+    mask.Buffer = short_name;
+    pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
+            FileBothDirectoryInformation, TRUE, &mask, TRUE);
+    ok(U(io).Status == STATUS_SUCCESS, "failed to query directory status %x\n", U(io).Status);
+    ok(fbdi->FileNameLength == strlen(testfiles[0].name)*sizeof(WCHAR) &&
+            !memcmp(fbdi->FileName, testfiles[0].nameW, fbdi->FileNameLength),
+            "incorrect long file name: %s\n", wine_dbgstr_wn(fbdi->FileName,
+                fbdi->FileNameLength/sizeof(WCHAR)));
+
+    pNtClose(dirh);
+
 done:
     tear_down_attribute_test(testdirA);
     pRtlFreeUnicodeString(&ntdirname);




More information about the wine-cvs mailing list