diff --git a/README.md b/README.md index 5bdc9b03..b637d091 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Wine. All those differences are also documented on the Included bug fixes and improvements ----------------------------------- -**Bug fixes and features included in the next upcoming release [14]:** +**Bug fixes and features included in the next upcoming release [15]:** * Add IDragSourceHelper stub interface ([Wine Bug #24699](https://bugs.winehq.org/show_bug.cgi?id=24699)) * Catch invalid memory accesses in imagehlp.CheckSumMappedFile @@ -53,6 +53,7 @@ Included bug fixes and improvements * Only set SFGAO_HASSUBFOLDER when there are really subfolders ([Wine Bug #24851](https://bugs.winehq.org/show_bug.cgi?id=24851)) * Properly implement imagehlp.ImageLoad and ImageUnload * Report correct ObjectName for NamedPipe wineserver objects +* Return STATUS_OBJECT_NAME_INVALID in wine_nt_to_unix_file_name for paths that only contain a prefix ([Wine Bug #39133](https://bugs.winehq.org/show_bug.cgi?id=39133)) * Set EOF on file which has a memory mapping should fail * Use helper function for NtWaitForMultipleObjects and NtWaitForSingleObject ([Wine Bug #39127](https://bugs.winehq.org/show_bug.cgi?id=39127)) diff --git a/debian/changelog b/debian/changelog index 28f300d0..bce6e8fa 100644 --- a/debian/changelog +++ b/debian/changelog @@ -26,6 +26,8 @@ wine-staging (1.7.50) UNRELEASED; urgency=low Bug #471). * Added patch to fix implementation of msvcrt.close when stdout == stderr (fixes Wine Staging Bug #485). + * Added patch to return STATUS_OBJECT_NAME_INVALID in + wine_nt_to_unix_file_name for paths that only contain a prefix. * Removed patch to move security cookie initialization from memory management to loader (accepted upstream). * Removed patches for stub of D3DCompileFromFile and D3DCompile2 (accepted diff --git a/patches/ntdll-Empty_Path/0001-ntdll-Return-STATUS_OBJECT_NAME_INVALID-in-wine_nt_t.patch b/patches/ntdll-Empty_Path/0001-ntdll-Return-STATUS_OBJECT_NAME_INVALID-in-wine_nt_t.patch new file mode 100644 index 00000000..cfa34893 --- /dev/null +++ b/patches/ntdll-Empty_Path/0001-ntdll-Return-STATUS_OBJECT_NAME_INVALID-in-wine_nt_t.patch @@ -0,0 +1,172 @@ +From 526502c4455016f3e42f671d7a03b9c15ce79fa9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +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 + diff --git a/patches/ntdll-Empty_Path/definition b/patches/ntdll-Empty_Path/definition new file mode 100644 index 00000000..7f6981b0 --- /dev/null +++ b/patches/ntdll-Empty_Path/definition @@ -0,0 +1 @@ +Fixes: [39133] Return STATUS_OBJECT_NAME_INVALID in wine_nt_to_unix_file_name for paths that only contain a prefix diff --git a/patches/ntdll-NtQueryEaFile/0001-ntdll-Improve-stub-of-NtQueryEaFile.patch b/patches/ntdll-NtQueryEaFile/0001-ntdll-Improve-stub-of-NtQueryEaFile.patch index 4e10fdce..1cb789ba 100644 --- a/patches/ntdll-NtQueryEaFile/0001-ntdll-Improve-stub-of-NtQueryEaFile.patch +++ b/patches/ntdll-NtQueryEaFile/0001-ntdll-Improve-stub-of-NtQueryEaFile.patch @@ -1,4 +1,4 @@ -From a735fc035bb548fb1d452fc8e1772bd4c3296097 Mon Sep 17 00:00:00 2001 +From 4a7559e041d5f83e57368a21caf0237f6a24a380 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 6 Jun 2015 07:03:33 +0800 Subject: ntdll: Improve stub of NtQueryEaFile. @@ -10,10 +10,10 @@ Based on a patch by Qian Hong. 2 files changed, 98 insertions(+), 4 deletions(-) diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index d081750..6b8f0e4 100644 +index be6b591..8c8e976 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c -@@ -3191,14 +3191,25 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, PIO_STATUS_BLOCK io +@@ -3293,14 +3293,25 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, PIO_STATUS_BLOCK io * Success: 0. Atrributes read into buffer * Failure: An NTSTATUS error code describing the error. */ @@ -44,18 +44,18 @@ index d081750..6b8f0e4 100644 diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c -index 86a4516..4bf5f23 100644 +index 70c7a55..ad27906 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, +@@ -79,6 +79,7 @@ static NTSTATUS (WINAPI *pNtQueryDirectoryFile)(HANDLE,HANDLE,PIO_APC_ROUTINE,PV 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 NTSTATUS (WINAPI *pNtQueryEaFile)(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,BOOLEAN,PVOID,ULONG,PULONG,BOOLEAN); static inline BOOL is_signaled( HANDLE obj ) { -@@ -2802,6 +2803,86 @@ static void test_read_write(void) +@@ -4161,6 +4162,86 @@ static void test_read_write(void) CloseHandle(hfile); } @@ -142,20 +142,20 @@ index 86a4516..4bf5f23 100644 START_TEST(file) { HMODULE hkernel32 = GetModuleHandleA("kernel32.dll"); -@@ -2837,6 +2918,7 @@ START_TEST(file) - pNtQueryInformationFile = (void *)GetProcAddress(hntdll, "NtQueryInformationFile"); +@@ -4197,6 +4278,7 @@ START_TEST(file) pNtQueryDirectoryFile = (void *)GetProcAddress(hntdll, "NtQueryDirectoryFile"); pNtQueryVolumeInformationFile = (void *)GetProcAddress(hntdll, "NtQueryVolumeInformationFile"); -+ pNtQueryEaFile = (void *)GetProcAddress(hntdll, "NtQueryEaFile"); + pNtQueryFullAttributesFile = (void *)GetProcAddress(hntdll, "NtQueryFullAttributesFile"); ++ pNtQueryEaFile = (void *)GetProcAddress(hntdll, "NtQueryEaFile"); test_read_write(); test_NtCreateFile(); -@@ -2856,4 +2938,5 @@ START_TEST(file) +@@ -4218,4 +4300,5 @@ START_TEST(file) test_file_disposition_information(); test_query_volume_information_file(); test_query_attribute_information_file(); + test_query_ea(); } -- -2.4.2 +2.5.0 diff --git a/patches/ntdll-NtQueryEaFile/definition b/patches/ntdll-NtQueryEaFile/definition index c3a4b643..e6a29ec6 100644 --- a/patches/ntdll-NtQueryEaFile/definition +++ b/patches/ntdll-NtQueryEaFile/definition @@ -1 +1,2 @@ Fixes: Improve stub for NtQueryEaFile +Depends: ntdll-Empty_Path diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 922c31d6..175a7085 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -167,6 +167,7 @@ patch_enable_all () enable_ntdll_Dealloc_Thread_Stack="$1" enable_ntdll_DeviceType_Systemroot="$1" enable_ntdll_DllRedirects="$1" + enable_ntdll_Empty_Path="$1" enable_ntdll_Exception="$1" enable_ntdll_FileDispositionInformation="$1" enable_ntdll_FileFsFullSizeInformation="$1" @@ -590,6 +591,9 @@ patch_enable () ntdll-DllRedirects) enable_ntdll_DllRedirects="$2" ;; + ntdll-Empty_Path) + enable_ntdll_Empty_Path="$2" + ;; ntdll-Exception) enable_ntdll_Exception="$2" ;; @@ -1780,6 +1784,13 @@ if test "$enable_ntdll_Junction_Points" -eq 1; then enable_ntdll_NtQueryEaFile=1 fi +if test "$enable_ntdll_NtQueryEaFile" -eq 1; then + if test "$enable_ntdll_Empty_Path" -gt 1; then + abort "Patchset ntdll-Empty_Path disabled, but ntdll-NtQueryEaFile depends on that." + fi + enable_ntdll_Empty_Path=1 +fi + if test "$enable_ntdll_DllRedirects" -eq 1; then if test "$enable_ntdll_Loader_Machine_Type" -gt 1; then abort "Patchset ntdll-Loader_Machine_Type disabled, but ntdll-DllRedirects depends on that." @@ -3712,6 +3723,21 @@ if test "$enable_ntdll_DllRedirects" -eq 1; then ) >> "$patchlist" fi +# Patchset ntdll-Empty_Path +# | +# | This patchset fixes the following Wine bugs: +# | * [#39133] Return STATUS_OBJECT_NAME_INVALID in wine_nt_to_unix_file_name for paths that only contain a prefix +# | +# | Modified files: +# | * dlls/kernel32/tests/file.c, dlls/ntdll/directory.c, dlls/ntdll/tests/file.c +# | +if test "$enable_ntdll_Empty_Path" -eq 1; then + patch_apply ntdll-Empty_Path/0001-ntdll-Return-STATUS_OBJECT_NAME_INVALID-in-wine_nt_t.patch + ( + echo '+ { "Michael Müller", "ntdll: Return STATUS_OBJECT_NAME_INVALID in wine_nt_to_unix_file_name for paths that only contain a prefix.", 1 },'; + ) >> "$patchlist" +fi + # Patchset ntdll-Exception # | # | Modified files: @@ -3824,6 +3850,9 @@ fi # Patchset ntdll-NtQueryEaFile # | +# | This patchset has the following (direct or indirect) dependencies: +# | * ntdll-Empty_Path +# | # | Modified files: # | * dlls/ntdll/file.c, dlls/ntdll/tests/file.c # | @@ -3837,7 +3866,7 @@ fi # Patchset ntdll-Junction_Points # | # | This patchset has the following (direct or indirect) dependencies: -# | * ntdll-Fix_Free, ntdll-NtQueryEaFile +# | * ntdll-Fix_Free, ntdll-Empty_Path, ntdll-NtQueryEaFile # | # | This patchset fixes the following Wine bugs: # | * [#12401] Support for Junction Points