|
@ -1,80 +0,0 @@ |
|
|
--- a/dlls/msi/action.c
|
|
|
|
|
|
+++ a/dlls/msi/action.c
|
|
|
|
|
|
@@ -7862,6 +7862,59 @@ static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq)
|
|
|
|
|
|
return rc; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
+/* 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 |
|
|
|
|
|
*****************************************************/ |
|
|
|
|
|
@@ -7938,6 +7991,8 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
|
|
|
|
|
|
msi_adjust_privilege_properties( package ); |
|
|
|
|
|
msi_set_context( package ); |
|
|
|
|
|
|
|
|
|
|
|
+ start_dummy_thread();
|
|
|
|
|
|
+
|
|
|
|
|
|
productcode = msi_dup_property( package->db, szProductCode ); |
|
|
|
|
|
if (strcmpiW( productcode, package->ProductCode )) |
|
|
|
|
|
{ |
|
|
|
|
|
@@ -7985,6 +8040,8 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
|
|
|
|
|
|
|
|
|
|
|
|
/* finish up running custom actions */ |
|
|
|
|
|
ACTION_FinishCustomActions(package); |
|
|
|
|
|
+
|
|
|
|
|
|
+ end_dummy_thread();
|
|
|
|
|
|
|
|
|
|
|
|
if (package->need_rollback && !reinstall) |
|
|
|
|
|
{ |
|
|
|