When the destination file cannot be copied in 32 bit installer of 64 bit dlls (going to system32) temporary file attempted at system32 (as that is the destination directory) currently ends up in syswow64. When wineboot is later processing PendingFileRenameOperations the redirection of the source file is not performed (and there is no way to guess that the file was redirected).
-- v2: msi: Disable FS redirection for temporary file in cabinet_copy_file().
From: Paul Gofman pgofman@codeweavers.com
--- dlls/msi/files.c | 9 +++++++++ dlls/msi/media.c | 6 +++--- dlls/msi/msipriv.h | 1 + 3 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/dlls/msi/files.c b/dlls/msi/files.c index 1b8e4fd7d90..94c733fca8f 100644 --- a/dlls/msi/files.c +++ b/dlls/msi/files.c @@ -48,6 +48,15 @@
WINE_DEFAULT_DEBUG_CHANNEL(msi);
+BOOL msi_get_temp_file_name( MSIPACKAGE *package, const WCHAR *tmp_path, const WCHAR *prefix, WCHAR *tmp_filename ) +{ + BOOL ret; + msi_disable_fs_redirection( package ); + ret = GetTempFileNameW( tmp_path, prefix, 0, tmp_filename ); + msi_revert_fs_redirection( package ); + return ret; +} + HANDLE msi_create_file( MSIPACKAGE *package, const WCHAR *filename, DWORD access, DWORD sharing, DWORD creation, DWORD flags ) { diff --git a/dlls/msi/media.c b/dlls/msi/media.c index 6aeb948de51..db65a282b93 100644 --- a/dlls/msi/media.c +++ b/dlls/msi/media.c @@ -468,10 +468,10 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint, msi_free( tmppathW ); return ERROR_OUTOFMEMORY; } - if (!GetTempFileNameW(tmppathW, L"msi", 0, tmpfileW)) tmpfileW[0] = 0; + if (!msi_get_temp_file_name( data->package, tmppathW, L"msi", tmpfileW )) tmpfileW[0] = 0; msi_free( tmppathW );
- handle = CreateFileW(tmpfileW, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs, NULL); + handle = msi_create_file( data->package, tmpfileW, GENERIC_READ | GENERIC_WRITE, 0, CREATE_ALWAYS, attrs );
if (handle != INVALID_HANDLE_VALUE && msi_move_file( data->package, path, NULL, MOVEFILE_DELAY_UNTIL_REBOOT ) && @@ -482,7 +482,7 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint, else { WARN( "failed to schedule rename operation %s (error %lu)\n", debugstr_w(path), GetLastError() ); - DeleteFileW( tmpfileW ); + msi_delete_file( data->package, tmpfileW ); } msi_free(tmpfileW); } diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index b5838bad6fe..d63c6f244ff 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -1073,6 +1073,7 @@ static inline void msi_revert_fs_redirection( MSIPACKAGE *package ) { if (is_wow64 && package->platform == PLATFORM_X64) Wow64RevertWow64FsRedirection( package->cookie ); } +extern BOOL msi_get_temp_file_name( MSIPACKAGE *, const WCHAR *, const WCHAR *, WCHAR * ) DECLSPEC_HIDDEN; extern HANDLE msi_create_file( MSIPACKAGE *, const WCHAR *, DWORD, DWORD, DWORD, DWORD ) DECLSPEC_HIDDEN; extern BOOL msi_delete_file( MSIPACKAGE *, const WCHAR * ) DECLSPEC_HIDDEN; extern BOOL msi_remove_directory( MSIPACKAGE *, const WCHAR * ) DECLSPEC_HIDDEN;
v2: - use msi_create_file() and msi_delete_file(); - add msi_get_temp_file_name() and use that. GetTempFileNameW() attempts files creation to check uniqueness, so wrapping it with redirection disablement also looks necessary.
This merge request was approved by Hans Leidekker.