Added patch to return STATUS_OBJECT_NAME_INVALID in wine_nt_to_unix_file_name for paths that only contain a prefix.

This commit is contained in:
Sebastian Lackner
2015-08-22 10:00:16 +02:00
parent afb16555cd
commit 6022983803
7 changed files with 220 additions and 14 deletions

View File

@@ -0,0 +1,172 @@
From 526502c4455016f3e42f671d7a03b9c15ce79fa9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 22 Aug 2015 03:19:18 +0200
Subject: ntdll: Return STATUS_OBJECT_NAME_INVALID in wine_nt_to_unix_file_name
for paths that only contain a prefix.
---
dlls/kernel32/tests/file.c | 22 ++++++++++++++++++++++
dlls/ntdll/directory.c | 22 ++++++++++++++--------
dlls/ntdll/tests/file.c | 39 +++++++++++++++++++++++++++++++++++++++
3 files changed, 75 insertions(+), 8 deletions(-)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c
index dd64c91..fbe2ddd 100644
--- a/dlls/kernel32/tests/file.c
+++ b/dlls/kernel32/tests/file.c
@@ -4650,6 +4650,27 @@ todo_wine
CloseHandle(file);
}
+static void test_GetFileAttributesExW(void)
+{
+ static const WCHAR path1[] = {'\\','\\','?','\\',0};
+ static const WCHAR path2[] = {'\\','?','?','\\',0};
+ static const WCHAR path3[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0};
+ WIN32_FILE_ATTRIBUTE_DATA info;
+ BOOL ret;
+
+ ret = GetFileAttributesExW(path1, GetFileExInfoStandard, &info);
+ ok(!ret, "GetFileAttributesExW succeeded\n");
+ ok(GetLastError() == ERROR_INVALID_NAME, "Expected error ERROR_INVALID_NAME, got %d\n", GetLastError());
+
+ ret = GetFileAttributesExW(path2, GetFileExInfoStandard, &info);
+ ok(!ret, "GetFileAttributesExW succeeded\n");
+ ok(GetLastError() == ERROR_INVALID_NAME, "Expected error ERROR_INVALID_NAME, got %d\n", GetLastError());
+
+ ret = GetFileAttributesExW(path3, GetFileExInfoStandard, &info);
+ ok(!ret, "GetFileAttributesExW succeeded\n");
+ ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected error ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
+}
+
START_TEST(file)
{
InitFunctionPointers();
@@ -4706,4 +4727,5 @@ START_TEST(file)
test_GetFinalPathNameByHandleA();
test_GetFinalPathNameByHandleW();
test_SetFileInformationByHandle();
+ test_GetFileAttributesExW();
}
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index 0e02f2e..d1f66e0 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -2757,20 +2757,26 @@ static NTSTATUS get_dos_device( const WCHAR *name, UINT name_len, ANSI_STRING *u
/* return the length of the DOS namespace prefix if any */
-static inline int get_dos_prefix_len( const UNICODE_STRING *name )
+static inline NTSTATUS get_dos_prefix_len( const UNICODE_STRING *name, int *prefix_len )
{
static const WCHAR nt_prefixW[] = {'\\','?','?','\\'};
static const WCHAR dosdev_prefixW[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\'};
- if (name->Length > sizeof(nt_prefixW) &&
+ if (name->Length >= sizeof(nt_prefixW) &&
!memcmp( name->Buffer, nt_prefixW, sizeof(nt_prefixW) ))
- return sizeof(nt_prefixW) / sizeof(WCHAR);
+ {
+ *prefix_len = sizeof(nt_prefixW) / sizeof(WCHAR);
+ return (name->Length == sizeof(nt_prefixW)) ? STATUS_OBJECT_NAME_INVALID : STATUS_SUCCESS;
+ }
- if (name->Length > sizeof(dosdev_prefixW) &&
+ if (name->Length >= sizeof(dosdev_prefixW) &&
!memicmpW( name->Buffer, dosdev_prefixW, sizeof(dosdev_prefixW)/sizeof(WCHAR) ))
- return sizeof(dosdev_prefixW) / sizeof(WCHAR);
+ {
+ *prefix_len = sizeof(dosdev_prefixW) / sizeof(WCHAR);
+ return (name->Length == sizeof(dosdev_prefixW)) ? STATUS_OBJECT_NAME_INVALID : STATUS_SUCCESS;
+ }
- return 0;
+ return STATUS_BAD_DEVICE_TYPE;
}
@@ -3126,8 +3132,8 @@ NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRI
if (!name_len || !IS_SEPARATOR(name[0])) return STATUS_OBJECT_PATH_SYNTAX_BAD;
- if (!(pos = get_dos_prefix_len( nameW )))
- return STATUS_BAD_DEVICE_TYPE; /* no DOS prefix, assume NT native name */
+ if ((status = get_dos_prefix_len( nameW, &pos )))
+ return status; /* no DOS prefix, assume NT native name */
name += pos;
name_len -= pos;
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index d68be15..70c7a55 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -78,6 +78,7 @@ static NTSTATUS (WINAPI *pNtQueryInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOI
static NTSTATUS (WINAPI *pNtQueryDirectoryFile)(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,
PVOID,ULONG,FILE_INFORMATION_CLASS,BOOLEAN,PUNICODE_STRING,BOOLEAN);
static NTSTATUS (WINAPI *pNtQueryVolumeInformationFile)(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,FS_INFORMATION_CLASS);
+static NTSTATUS (WINAPI *pNtQueryFullAttributesFile)(POBJECT_ATTRIBUTES, PFILE_NETWORK_OPEN_INFORMATION);
static inline BOOL is_signaled( HANDLE obj )
{
@@ -173,6 +174,10 @@ static void create_file_test(void)
'\\','f','a','i','l','i','n','g',0};
static const WCHAR questionmarkInvalidNameW[] = {'a','f','i','l','e','?',0};
static const WCHAR pipeInvalidNameW[] = {'a','|','b',0};
+ static const WCHAR pathInvalidDosW[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0};
+ static const WCHAR pathInvalidNtW[] = {'\\','\\','?','\\',0};
+ static const WCHAR pathInvalidNt2W[] = {'\\','?','?','\\',0};
+ FILE_NETWORK_OPEN_INFORMATION info;
NTSTATUS status;
HANDLE dir, file;
WCHAR path[MAX_PATH];
@@ -293,6 +298,39 @@ static void create_file_test(void)
ok(status == STATUS_OBJECT_NAME_INVALID,
"open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status);
pRtlFreeUnicodeString(&nameW);
+
+ pRtlInitUnicodeString( &nameW, pathInvalidNtW );
+ status = pNtCreateFile(&dir, GENERIC_READ|SYNCHRONIZE, &attr, &io, NULL, 0,
+ FILE_SHARE_READ, FILE_CREATE,
+ FILE_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
+ ok(status == STATUS_OBJECT_NAME_INVALID,
+ "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status);
+
+ status = pNtQueryFullAttributesFile(&attr, &info);
+ todo_wine ok(status == STATUS_OBJECT_NAME_INVALID,
+ "query %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status);
+
+ pRtlInitUnicodeString( &nameW, pathInvalidNt2W );
+ status = pNtCreateFile(&dir, GENERIC_READ|SYNCHRONIZE, &attr, &io, NULL, 0,
+ FILE_SHARE_READ, FILE_CREATE,
+ FILE_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
+ ok(status == STATUS_OBJECT_NAME_INVALID,
+ "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status);
+
+ status = pNtQueryFullAttributesFile(&attr, &info);
+ ok(status == STATUS_OBJECT_NAME_INVALID,
+ "query %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status);
+
+ pRtlInitUnicodeString( &nameW, pathInvalidDosW );
+ status = pNtCreateFile(&dir, GENERIC_READ|SYNCHRONIZE, &attr, &io, NULL, 0,
+ FILE_SHARE_READ, FILE_CREATE,
+ FILE_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
+ ok(status == STATUS_OBJECT_NAME_INVALID,
+ "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status);
+
+ status = pNtQueryFullAttributesFile(&attr, &info);
+ ok(status == STATUS_OBJECT_NAME_INVALID,
+ "query %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status);
}
static void open_file_test(void)
@@ -4158,6 +4196,7 @@ START_TEST(file)
pNtQueryInformationFile = (void *)GetProcAddress(hntdll, "NtQueryInformationFile");
pNtQueryDirectoryFile = (void *)GetProcAddress(hntdll, "NtQueryDirectoryFile");
pNtQueryVolumeInformationFile = (void *)GetProcAddress(hntdll, "NtQueryVolumeInformationFile");
+ pNtQueryFullAttributesFile = (void *)GetProcAddress(hntdll, "NtQueryFullAttributesFile");
test_read_write();
test_NtCreateFile();
--
2.5.0

View File

@@ -0,0 +1 @@
Fixes: [39133] Return STATUS_OBJECT_NAME_INVALID in wine_nt_to_unix_file_name for paths that only contain a prefix