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).
From: Paul Gofman pgofman@codeweavers.com
--- dlls/msi/media.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/dlls/msi/media.c b/dlls/msi/media.c index 6aeb948de51..6703d8d8e05 100644 --- a/dlls/msi/media.c +++ b/dlls/msi/media.c @@ -468,10 +468,13 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint, msi_free( tmppathW ); return ERROR_OUTOFMEMORY; } + + msi_disable_fs_redirection( data->package ); if (!GetTempFileNameW(tmppathW, L"msi", 0, tmpfileW)) tmpfileW[0] = 0; msi_free( tmppathW );
handle = CreateFileW(tmpfileW, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs, NULL); + msi_revert_fs_redirection( data->package );
if (handle != INVALID_HANDLE_VALUE && msi_move_file( data->package, path, NULL, MOVEFILE_DELAY_UNTIL_REBOOT ) && @@ -482,7 +485,9 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint, else { WARN( "failed to schedule rename operation %s (error %lu)\n", debugstr_w(path), GetLastError() ); + msi_disable_fs_redirection( data->package ); DeleteFileW( tmpfileW ); + msi_revert_fs_redirection( data->package ); } msi_free(tmpfileW); }
Hans Leidekker (@hans) commented about dlls/msi/media.c:
msi_free( tmppathW ); return ERROR_OUTOFMEMORY; }
msi_disable_fs_redirection( data->package ); if (!GetTempFileNameW(tmppathW, L"msi", 0, tmpfileW)) tmpfileW[0] = 0; msi_free( tmppathW ); handle = CreateFileW(tmpfileW, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs, NULL);
msi_revert_fs_redirection( data->package ); if (handle != INVALID_HANDLE_VALUE && msi_move_file( data->package, path, NULL, MOVEFILE_DELAY_UNTIL_REBOOT ) &&
There's msi_create_file() and msi_delete_file() which handle redirection, that could be reused here. Maybe add a msi_create_temp_filename() wrapper around GetTempFileNameW() for consistency.