diff --git a/patches/msi-Dummy_Thread/0001-msi-Create-dummy-thread-to-initialize-COM-for-custom.patch b/patches/msi-Dummy_Thread/0001-msi-Create-dummy-thread-to-initialize-COM-for-custom.patch new file mode 100644 index 00000000..0b531021 --- /dev/null +++ b/patches/msi-Dummy_Thread/0001-msi-Create-dummy-thread-to-initialize-COM-for-custom.patch @@ -0,0 +1,99 @@ +From 0763c73423ae069023b54e669b0c9bd648e1f27e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Mon, 26 Jun 2017 16:18:09 +0200 +Subject: msi: Create dummy thread to initialize COM for custom actions. + +--- + dlls/msi/action.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 48 insertions(+) + +diff --git a/dlls/msi/action.c b/dlls/msi/action.c +index 16652000ee5..62f01044bf1 100644 +--- a/dlls/msi/action.c ++++ b/dlls/msi/action.c +@@ -156,6 +156,13 @@ static const WCHAR szValidateProductID[] = + static const WCHAR szWriteEnvironmentStrings[] = + {'W','r','i','t','e','E','n','v','i','r','o','n','m','e','n','t','S','t','r','i','n','g','s',0}; + ++struct dummy_thread ++{ ++ HANDLE started; ++ HANDLE stopped; ++ HANDLE thread; ++}; ++ + static void ui_actionstart(MSIPACKAGE *package, LPCWSTR action) + { + static const WCHAR Query_t[] = +@@ -7912,6 +7919,42 @@ static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq) + return rc; + } + ++DWORD WINAPI dummy_thread_proc(void *arg) ++{ ++ struct dummy_thread *info = arg; ++ HRESULT hr; ++ ++ hr = CoInitializeEx(0, COINIT_MULTITHREADED); ++ if (FAILED(hr)) ERR("CoInitializeEx failed %08x\n", hr); ++ ++ SetEvent(info->started); ++ WaitForSingleObject(info->stopped, INFINITE); ++ ++ CoUninitialize(); ++ return 0; ++} ++ ++static void start_dummy_thread(struct dummy_thread *info) ++{ ++ if (!(info->started = CreateEventA(NULL, TRUE, FALSE, NULL))) return; ++ if (!(info->stopped = CreateEventA(NULL, TRUE, FALSE, NULL))) return; ++ if (!(info->thread = CreateThread(NULL, 0, dummy_thread_proc, info, 0, NULL))) return; ++ ++ WaitForSingleObject(info->started, INFINITE); ++} ++ ++static void stop_dummy_thread(struct dummy_thread *info) ++{ ++ if (info->thread) ++ { ++ SetEvent(info->stopped); ++ WaitForSingleObject(info->thread, INFINITE); ++ CloseHandle(info->thread); ++ } ++ if (info->started) CloseHandle(info->started); ++ if (info->stopped) CloseHandle(info->stopped); ++} ++ + /**************************************************** + * TOP level entry points + *****************************************************/ +@@ -7923,6 +7966,7 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, + static const WCHAR szAction[] = {'A','C','T','I','O','N',0}; + static const WCHAR szInstall[] = {'I','N','S','T','A','L','L',0}; + WCHAR *reinstall, *remove, *patch, *productcode; ++ struct dummy_thread thread_info = {NULL, NULL, NULL}; + BOOL ui_exists; + UINT rc; + +@@ -7988,6 +8032,8 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, + msi_adjust_privilege_properties( package ); + msi_set_context( package ); + ++ start_dummy_thread(&thread_info); ++ + productcode = msi_dup_property( package->db, szProductCode ); + if (strcmpiW( productcode, package->ProductCode )) + { +@@ -8036,6 +8082,8 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, + /* finish up running custom actions */ + ACTION_FinishCustomActions(package); + ++ stop_dummy_thread(&thread_info); ++ + if (package->need_rollback && !reinstall) + { + WARN("installation failed, running rollback script\n"); +-- +2.13.1 + diff --git a/patches/msi-Dummy_Thread/definition b/patches/msi-Dummy_Thread/definition new file mode 100644 index 00000000..6d431ecb --- /dev/null +++ b/patches/msi-Dummy_Thread/definition @@ -0,0 +1 @@ +Fixes: [!18070] Workaround COM/MTA issues due to lack of separate msi custom action process diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index d4dc29c7..5bfe4b1f 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -213,6 +213,7 @@ patch_enable_all () enable_mpr_WNetGetUniversalNameW="$1" enable_mscoree_CorValidateImage="$1" enable_mshtml_HTMLLocation_put_hash="$1" + enable_msi_Dummy_Thread="$1" enable_msi_MsiGetDatabaseState="$1" enable_msi_msi_vcl_get_cost="$1" enable_msidb_Implementation="$1" @@ -885,6 +886,9 @@ patch_enable () mshtml-HTMLLocation_put_hash) enable_mshtml_HTMLLocation_put_hash="$2" ;; + msi-Dummy_Thread) + enable_msi_Dummy_Thread="$2" + ;; msi-MsiGetDatabaseState) enable_msi_MsiGetDatabaseState="$2" ;; @@ -5237,6 +5241,21 @@ if test "$enable_mshtml_HTMLLocation_put_hash" -eq 1; then ) >> "$patchlist" fi +# Patchset msi-Dummy_Thread +# | +# | This patchset fixes the following Wine bugs: +# | * [#18070] Workaround COM/MTA issues due to lack of separate msi custom action process +# | +# | Modified files: +# | * dlls/msi/action.c +# | +if test "$enable_msi_Dummy_Thread" -eq 1; then + patch_apply msi-Dummy_Thread/0001-msi-Create-dummy-thread-to-initialize-COM-for-custom.patch + ( + printf '%s\n' '+ { "Michael Müller", "msi: Create dummy thread to initialize COM for custom actions.", 1 },'; + ) >> "$patchlist" +fi + # Patchset ntdll-NtAllocateUuids # | # | This patchset fixes the following Wine bugs: