Commit a8ef2614 authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

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

parent 0125ef6d
...@@ -2120,15 +2120,6 @@ static int read_directory_stat( int fd, IO_STATUS_BLOCK *io, void *buffer, ULONG ...@@ -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 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 else
{ {
ret = -1; ret = -1;
...@@ -2214,11 +2205,6 @@ static int read_directory_getattrlist( int fd, IO_STATUS_BLOCK *io, void *buffer ...@@ -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 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; else ret = -1;
......
...@@ -60,6 +60,7 @@ static struct testfile_s { ...@@ -60,6 +60,7 @@ static struct testfile_s {
int nfound; /* How many were found (expect 1) */ int nfound; /* How many were found (expect 1) */
WCHAR nameW[20]; /* unicode version of name (filled in later) */ WCHAR nameW[20]; /* unicode version of name (filled in later) */
} testfiles[] = { } testfiles[] = {
{ 0, 0, FILE_ATTRIBUTE_NORMAL, "longfilename.tmp", NULL, "normal" },
{ 0, 0, FILE_ATTRIBUTE_NORMAL, "n.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_HIDDEN, "h.tmp", NULL, "hidden" },
{ 1, 0, FILE_ATTRIBUTE_SYSTEM, "s.tmp", NULL, "system" }, { 1, 0, FILE_ATTRIBUTE_SYSTEM, "s.tmp", NULL, "system" },
...@@ -234,10 +235,17 @@ static void test_flags_NtQueryDirectoryFile(OBJECT_ATTRIBUTES *attr, const char ...@@ -234,10 +235,17 @@ static void test_flags_NtQueryDirectoryFile(OBJECT_ATTRIBUTES *attr, const char
static void test_NtQueryDirectoryFile(void) static void test_NtQueryDirectoryFile(void)
{ {
OBJECT_ATTRIBUTES attr; OBJECT_ATTRIBUTES attr;
UNICODE_STRING ntdirname; UNICODE_STRING ntdirname, mask;
char testdirA[MAX_PATH]; char testdirA[MAX_PATH];
WCHAR testdirW[MAX_PATH]; WCHAR testdirW[MAX_PATH];
int i; 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 */ /* Clean up from prior aborted run, if any, then set up test files */
ok(GetTempPathA(MAX_PATH, testdirA), "couldn't get temp dir\n"); ok(GetTempPathA(MAX_PATH, testdirA), "couldn't get temp dir\n");
...@@ -260,8 +268,6 @@ static void test_NtQueryDirectoryFile(void) ...@@ -260,8 +268,6 @@ static void test_NtQueryDirectoryFile(void)
for (i = 0; testfiles[i].name; i++) for (i = 0; testfiles[i].name; i++)
{ {
UNICODE_STRING mask;
if (testfiles[i].nameW[0] == '.') continue; /* . and .. as masks are broken on Windows */ if (testfiles[i].nameW[0] == '.') continue; /* . and .. as masks are broken on Windows */
mask.Buffer = testfiles[i].nameW; mask.Buffer = testfiles[i].nameW;
mask.Length = mask.MaximumLength = lstrlenW(testfiles[i].nameW) * sizeof(WCHAR); mask.Length = mask.MaximumLength = lstrlenW(testfiles[i].nameW) * sizeof(WCHAR);
...@@ -271,6 +277,35 @@ static void test_NtQueryDirectoryFile(void) ...@@ -271,6 +277,35 @@ static void test_NtQueryDirectoryFile(void)
test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, TRUE, FALSE); 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: done:
tear_down_attribute_test(testdirA); tear_down_attribute_test(testdirA);
pRtlFreeUnicodeString(&ntdirname); pRtlFreeUnicodeString(&ntdirname);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment