mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-01-28 22:04:43 -08:00
Added kernel32-ReplaceFileW patchset
This commit is contained in:
parent
e20fec1c52
commit
8b930aea2f
@ -0,0 +1,100 @@
|
||||
From 679a02527fb9051d20940072ab49cc1fa3fc7319 Mon Sep 17 00:00:00 2001
|
||||
From: Brock York <twunknown@gmail.com>
|
||||
Date: Wed, 3 Apr 2019 17:00:22 +1100
|
||||
Subject: [PATCH] kernel32: Correct ReplaceFileW behaviour
|
||||
|
||||
ReplaceFileW should fail with ERROR_ACCESS_DENIED when either the replaced
|
||||
or replacement file is set to read only using SetFileAttributes.
|
||||
Testing for the return values of ReplaceFileW was performed on a
|
||||
Windows XP SP3 and Windows 10 vm.
|
||||
|
||||
Open replaced file without GENERIC_WRITE flag if a sharing violation is
|
||||
returned on the first call checking for the READ_ONLY attribute.
|
||||
ReplaceFileW should not fail when called to replace the current executable which
|
||||
is the case as tested on Windows 7, 10 and XP this is because the
|
||||
"replaced" file is opened with the GENERIC_WRITE flag.
|
||||
The MSDN also mentions that the replaced file is only opened with
|
||||
GENERIC_READ, DELETE and SYNCHRONIZE.
|
||||
|
||||
This patch will fix the following bug once it is
|
||||
merged into Wine-Staging as the WarFrame launcher
|
||||
requires patches from Wine-Staging to work.
|
||||
|
||||
Wine-Bug:https://bugs.winehq.org/show_bug.cgi?id=33845
|
||||
---
|
||||
dlls/kernel32/file.c | 15 +++++++++++++--
|
||||
dlls/kernel32/tests/file.c | 4 ++--
|
||||
2 files changed, 15 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernel32/file.c b/dlls/kernel32/file.c
|
||||
index a5c34fae12a..cc22a175fb5 100644
|
||||
--- a/dlls/kernel32/file.c
|
||||
+++ b/dlls/kernel32/file.c
|
||||
@@ -1772,7 +1772,7 @@ BOOL WINAPI ReplaceFileW(LPCWSTR lpReplacedFileName, LPCWSTR lpReplacementFileNa
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
|
||||
- /* Open the "replaced" file for reading and writing */
|
||||
+ /* Open the "replaced" file for reading and writing to check for READ_ONLY attribute */
|
||||
if (!(RtlDosPathNameToNtPathName_U(lpReplacedFileName, &nt_replaced_name, NULL, NULL)))
|
||||
{
|
||||
error = ERROR_PATH_NOT_FOUND;
|
||||
@@ -1784,6 +1784,12 @@ BOOL WINAPI ReplaceFileW(LPCWSTR lpReplacedFileName, LPCWSTR lpReplacementFileNa
|
||||
&attr, &io,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE);
|
||||
+ /*If we didn't get ACCESS_DENIED, then open the file for reading and delete ready for the replacement*/
|
||||
+ if (status == STATUS_SHARING_VIOLATION)
|
||||
+ status = NtOpenFile(&hReplaced, GENERIC_READ|DELETE|SYNCHRONIZE,
|
||||
+ &attr, &io,
|
||||
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
|
||||
+ FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE);
|
||||
if (status == STATUS_SUCCESS)
|
||||
status = wine_nt_to_unix_file_name(&nt_replaced_name, &unix_replaced_name, replaced_flags, FALSE);
|
||||
RtlFreeUnicodeString(&nt_replaced_name);
|
||||
@@ -1791,6 +1797,8 @@ BOOL WINAPI ReplaceFileW(LPCWSTR lpReplacedFileName, LPCWSTR lpReplacementFileNa
|
||||
{
|
||||
if (status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||
error = ERROR_FILE_NOT_FOUND;
|
||||
+ else if (status == STATUS_ACCESS_DENIED)
|
||||
+ error = ERROR_ACCESS_DENIED;
|
||||
else
|
||||
error = ERROR_UNABLE_TO_REMOVE_REPLACED;
|
||||
goto fail;
|
||||
@@ -1815,7 +1823,10 @@ BOOL WINAPI ReplaceFileW(LPCWSTR lpReplacedFileName, LPCWSTR lpReplacementFileNa
|
||||
RtlFreeUnicodeString(&nt_replacement_name);
|
||||
if (status != STATUS_SUCCESS)
|
||||
{
|
||||
- error = RtlNtStatusToDosError(status);
|
||||
+ if (status == STATUS_ACCESS_DENIED)
|
||||
+ error = ERROR_ACCESS_DENIED;
|
||||
+ else
|
||||
+ error = RtlNtStatusToDosError(status);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c
|
||||
index 3354bacf967..fb2440e0379 100644
|
||||
--- a/dlls/kernel32/tests/file.c
|
||||
+++ b/dlls/kernel32/tests/file.c
|
||||
@@ -3781,7 +3781,7 @@ static void test_ReplaceFileA(void)
|
||||
*/
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
|
||||
- todo_wine ok(ret == 0 && GetLastError() == ERROR_ACCESS_DENIED, "ReplaceFileA: unexpected error %d\n", GetLastError());
|
||||
+ ok(ret == 0 && GetLastError() == ERROR_ACCESS_DENIED, "ReplaceFileA: unexpected error %d\n", GetLastError());
|
||||
/* make sure that the replacement file still exists */
|
||||
hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
|
||||
ok(hReplacementFile != INVALID_HANDLE_VALUE ||
|
||||
@@ -3813,7 +3813,7 @@ static void test_ReplaceFileA(void)
|
||||
"unexpected error, replaced file should be able to be opened %d\n", GetLastError());
|
||||
/*Calling ReplaceFileA on an exe should succeed*/
|
||||
ret = pReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
|
||||
- todo_wine ok(ret, "ReplaceFileA: unexpected error %d\n", GetLastError());
|
||||
+ ok(ret, "ReplaceFileA: unexpected error %d\n", GetLastError());
|
||||
CloseHandle(hReplacedFile);
|
||||
|
||||
/* replacement file still exists, make pass w/o "replaced" */
|
||||
--
|
||||
2.20.1
|
||||
|
3
patches/kernel32-ReplaceFileW/definition
Normal file
3
patches/kernel32-ReplaceFileW/definition
Normal file
@ -0,0 +1,3 @@
|
||||
# Reference
|
||||
# https://www.winehq.org/pipermail/wine-devel/2018-October/133068.html
|
||||
Fixes: [33845] kernel32: Correct ReplaceFileW behaviour for warframe
|
@ -168,6 +168,7 @@ patch_enable_all ()
|
||||
enable_kernel32_NeedCurrentDirectoryForExePath="$1"
|
||||
enable_kernel32_PE_Loader_Fixes="$1"
|
||||
enable_kernel32_Processor_Group="$1"
|
||||
enable_kernel32_ReplaceFileW="$1"
|
||||
enable_kernel32_SCSI_Sysfs="$1"
|
||||
enable_krnl386_exe16_GDT_LDT_Emulation="$1"
|
||||
enable_krnl386_exe16_Invalid_Console_Handles="$1"
|
||||
@ -645,6 +646,9 @@ patch_enable ()
|
||||
kernel32-Processor_Group)
|
||||
enable_kernel32_Processor_Group="$2"
|
||||
;;
|
||||
kernel32-ReplaceFileW)
|
||||
enable_kernel32_ReplaceFileW="$2"
|
||||
;;
|
||||
kernel32-SCSI_Sysfs)
|
||||
enable_kernel32_SCSI_Sysfs="$2"
|
||||
;;
|
||||
@ -3873,6 +3877,21 @@ if test "$enable_kernel32_Processor_Group" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset kernel32-ReplaceFileW
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#33845] kernel32: Correct ReplaceFileW behaviour for warframe
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/kernel32/file.c, dlls/kernel32/tests/file.c
|
||||
# |
|
||||
if test "$enable_kernel32_ReplaceFileW" -eq 1; then
|
||||
patch_apply kernel32-ReplaceFileW/0001-kernel32-Correct-ReplaceFileW-behaviour.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Brock York", "kernel32: Correct ReplaceFileW behaviour.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset kernel32-SCSI_Sysfs
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
|
Loading…
x
Reference in New Issue
Block a user