From: Roman Pišl rpisl@seznam.cz
PathRemoveFileSpecW keeps only the drive if the path contains all forward slashes as shown in tests.
But then the temporary file is created in the root folder which fails for drive Z:. --- dlls/kernel32/tests/file.c | 1 - dlls/kernelbase/file.c | 12 ++++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index 69c06c7b0c2..e6787f9c323 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -4219,7 +4219,6 @@ static void test_ReplaceFileW(void) ret = GetTempFileNameW(temp_path, prefix, 0, replacement); ok(ret, "GetTempFileNameW error (replacement) %ld\n", GetLastError()); ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0); - todo_wine ok(ret, "ReplaceFileW: error %ld\n", GetLastError());
DeleteFileW(replaced); diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c index f0dedfe3b14..53286f1331a 100644 --- a/dlls/kernelbase/file.c +++ b/dlls/kernelbase/file.c @@ -2717,8 +2717,16 @@ BOOL WINAPI DECLSPEC_HOTPATCH ReplaceFileW( const WCHAR *replaced, const WCHAR * * it out of the way first. */ WCHAR temp_path[MAX_PATH], temp_file[MAX_PATH];
- lstrcpynW( temp_path, replaced, ARRAY_SIZE( temp_path ) ); - PathRemoveFileSpecW( temp_path ); + WCHAR* filePart; + DWORD cnt = GetFullPathNameW(replaced, ARRAY_SIZE( temp_path ), temp_path, &filePart); + if (!cnt) return FALSE; + if (cnt >= ARRAY_SIZE( temp_path ) || !filePart) + { + SetLastError( ERROR_PATH_NOT_FOUND ); + return FALSE; + } + *filePart = 0; + if (!GetTempFileNameW( temp_path, L"rf", 0, temp_file ) || !MoveFileExW( replaced, temp_file, MOVEFILE_REPLACE_EXISTING )) return FALSE;