[PATCH 0/2] MR10934: kernel32/tests: Add tests for ReplaceFileW.
I ported an application using wine. But I found that it lauched successfully only the first time. I solved this bug. The application calls ReplaceFileW to move a file to a directory. The file and the directory have the same name. Wine just move the direcory to a file. When the application launced the second time, it can not create the directory because there is a file owns the same name. So it can not launch. I think this is a bug. I made a test on Windows, when replaced is a directory, Windows just do nothing and return FALSE. The last error is ERROR_ACCESS_DENIED. But in Wine, it does the replace operation and return TRUE. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10934
From: Kun Yang <yangkun@uniontech.com> This is tests for ReplaceFileW when replaced is a directory. Signed-off-by: Kun Yang <yangkun@uniontech.com> --- dlls/kernel32/tests/file.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index d66ab2efe66..c9be171121d 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -4466,6 +4466,18 @@ static void test_ReplaceFileW(void) "ReplaceFileW: unexpected error %ld\n", GetLastError()); DeleteFileW( replacement ); + ret = GetTempFileNameW(temp_path, prefix, 0, replacement); + ok(ret, "GetTempFileNameW error (replacement) %ld\n", GetLastError()); + ret = CreateDirectoryW(replaced, NULL); + ok(ret, "CreateDirectoryW error %ld\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0); + todo_wine ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError()); + ret = RemoveDirectoryW(replaced); + todo_wine ok(ret, "RemoveDirectoryW error %ld\n", GetLastError()); + DeleteFileW(replacement); + if (removeBackup) { ret = DeleteFileW(backup); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10934
From: Kun Yang <yangkun@uniontech.com> Logs: When the target replaced of ReplaceFileW is a directory, the operation should not be performed. Signed-off-by: Kun Yang <yangkun@uniontech.com> --- dlls/kernel32/tests/file.c | 4 ++-- dlls/kernelbase/file.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index c9be171121d..ed6e0606f1e 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -4472,10 +4472,10 @@ static void test_ReplaceFileW(void) ok(ret, "CreateDirectoryW error %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0); - todo_wine ok(!ret, "expected failure\n"); + ok(!ret, "expected failure\n"); ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError()); ret = RemoveDirectoryW(replaced); - todo_wine ok(ret, "RemoveDirectoryW error %ld\n", GetLastError()); + ok(ret, "RemoveDirectoryW error %ld\n", GetLastError()); DeleteFileW(replacement); if (removeBackup) diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c index 31884426143..9b66cecee6e 100644 --- a/dlls/kernelbase/file.c +++ b/dlls/kernelbase/file.c @@ -2766,7 +2766,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH ReplaceFileW( const WCHAR *replaced, const WCHAR * RtlFreeUnicodeString(&nt_replaced_name); if (!set_ntstatus( status )) return FALSE; - if (info.FileAttributes & FILE_ATTRIBUTE_READONLY) + if (info.FileAttributes & ( FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_DIRECTORY )) { SetLastError( ERROR_ACCESS_DENIED ); return FALSE; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10934
participants (2)
-
Kun Yang -
Kun Yang (@yangkun)