msi: Start a dummy thread to initialize an MTA.

Hans Leidekker hans at codeweavers.com
Tue Jul 7 03:15:43 CDT 2009


Based on a patch by Dan Kegel. Fixes Adobe CS3/CS4 installers.
See http://bugs.winehq.org/show_bug.cgi?id=18070

 -Hans

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index c824904..05df4bb 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -777,6 +777,59 @@ static UINT msi_set_context(MSIPACKAGE *package)
     return ERROR_SUCCESS;
 }
 
+/* Dummy thread just to initialize an MTA for the benefit of custom action DLLs */
+static HANDLE dummy_thread_sync_event = NULL;
+static HANDLE dummy_thread_stop_event = NULL;
+static HANDLE dummy_thread_handle = NULL;
+
+DWORD WINAPI dummy_thread_proc(void *arg)
+{
+    HRESULT hr;
+    DWORD dwWaitResult;
+
+    hr = CoInitializeEx(0, COINIT_MULTITHREADED);
+    if (FAILED(hr))
+        WARN("CoInitializeEx failed %u\n", hr);
+
+    SetEvent(dummy_thread_sync_event);
+    dwWaitResult = WaitForSingleObject(dummy_thread_stop_event, INFINITE);
+
+    if (dwWaitResult != WAIT_OBJECT_0)
+        ERR("WaitForSingleObject failed?\n");
+
+    CoUninitialize();
+    return 0;
+}
+
+static void start_dummy_thread(void)
+{
+    if (dummy_thread_handle) return;
+
+    dummy_thread_sync_event = CreateEventA(NULL, TRUE, FALSE, "DummyThreadUpAndRunning");
+    if (dummy_thread_sync_event == NULL)
+        ERR("Can't create dummy thread sync event\n");
+    dummy_thread_stop_event = CreateEventA(NULL, TRUE, FALSE, "DummyThreadStop");
+    if (dummy_thread_stop_event == NULL)
+        ERR("Can't create dummy thread stop event\n");
+    dummy_thread_handle = CreateThread(NULL, 0, dummy_thread_proc, NULL, 0, NULL);
+    if (dummy_thread_handle == NULL)
+        ERR("Can't create dummy thread\n");
+
+    WaitForSingleObject(dummy_thread_sync_event, INFINITE);
+}
+
+static void end_dummy_thread(void)
+{
+    SetEvent(dummy_thread_stop_event);
+    WaitForSingleObject(dummy_thread_handle, INFINITE);
+
+    CloseHandle(dummy_thread_sync_event);
+    CloseHandle(dummy_thread_stop_event);
+    CloseHandle(dummy_thread_handle);
+
+    dummy_thread_handle = NULL;
+}
+
 /****************************************************
  * TOP level entry points 
  *****************************************************/
@@ -841,6 +894,8 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
     msi_clone_properties( package );
     msi_set_context( package );
 
+    start_dummy_thread();
+
     if ( (msi_get_property_int(package, szUILevel, 0) & INSTALLUILEVEL_MASK) >= INSTALLUILEVEL_REDUCED )
     {
         package->script->InWhatSequence |= SEQUENCE_UI;
@@ -870,6 +925,8 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
 
     /* finish up running custom actions */
     ACTION_FinishCustomActions(package);
+
+    end_dummy_thread();
     
     return rc;
 }



More information about the wine-patches mailing list