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