https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1fa71cf3c5b5db76e1bb4f6eefb98a8e3cbbdadf

commit 1fa71cf3c5b5db76e1bb4f6eefb98a8e3cbbdadf
Author:     winesync <[email protected]>
AuthorDate: Sat Mar 12 23:22:07 2022 +0100
Commit:     Mark Jansen <[email protected]>
CommitDate: Sun Mar 20 19:27:57 2022 +0100

    [WINESYNC] msi: Create the custom action thread inside msiexec.exe.
    
    This patch is effectively a no-op by itself, but makes the next patch
    architecturally much simpler. We need the main thread to be non-blocking
    to allow nested custom actions to work, so creating the thread inside of
    msiexec allows the custom action thread to write the result of the action to
    the server pipe while the main thread simply reads from it.
    
    Signed-off-by: Zebediah Figura <[email protected]>
    Signed-off-by: Hans Leidekker <[email protected]>
    Signed-off-by: Alexandre Julliard <[email protected]>
    
    wine commit id 7908d6ee399f4ef556e194dfa5cdef746fc091b6 by Zebediah Figura 
<[email protected]>
---
 base/system/msiexec/msiexec.c | 21 ++++++++++++++++++-
 dll/win32/msi/custom.c        | 47 ++++++++++++++++++++++++++++++++++---------
 2 files changed, 58 insertions(+), 10 deletions(-)

diff --git a/base/system/msiexec/msiexec.c b/base/system/msiexec/msiexec.c
index 5ebfea78ebf..74f6d515b95 100644
--- a/base/system/msiexec/msiexec.c
+++ b/base/system/msiexec/msiexec.c
@@ -395,11 +395,30 @@ static DWORD DoUnregServer(void)
 
 extern UINT CDECL __wine_msi_call_dll_function(GUID *guid);
 
+static DWORD CALLBACK custom_action_thread(void *arg)
+{
+    GUID *guid = arg;
+    return __wine_msi_call_dll_function(guid);
+}
+
 static int DoEmbedding(LPCWSTR key)
 {
+    HANDLE thread;
     GUID guid;
+    UINT r;
+
+    /* We need this to unmarshal streams, and some apps expect it to be 
present. */
+    CoInitializeEx(NULL, COINIT_MULTITHREADED);
+
     CLSIDFromString(key, &guid);
-    return __wine_msi_call_dll_function(&guid);
+    thread = CreateThread(NULL, 0, custom_action_thread, &guid, 0, NULL);
+    WaitForSingleObject(thread, INFINITE);
+    GetExitCodeThread(thread, &r);
+    CloseHandle(thread);
+
+    CoUninitialize();
+
+    return r;
 }
 
 /*
diff --git a/dll/win32/msi/custom.c b/dll/win32/msi/custom.c
index ffea24278d4..216a9bece8f 100644
--- a/dll/win32/msi/custom.c
+++ b/dll/win32/msi/custom.c
@@ -485,6 +485,43 @@ static void handle_msi_break(LPCSTR target)
 static WCHAR ncalrpcW[] = {'n','c','a','l','r','p','c',0};
 static WCHAR endpoint_lrpcW[] = {'m','s','i',0};
 
+#if defined __i386__ && defined _MSC_VER
+__declspec(naked) UINT custom_proc_wrapper(MsiCustomActionEntryPoint entry, 
MSIHANDLE hinst)
+{
+    __asm
+    {
+        push ebp
+        mov ebp, esp
+        sub esp, 4
+        push [ebp+12]
+        call [ebp+8]
+        leave
+        ret
+    }
+}
+#elif defined __i386__ && defined __GNUC__
+/* wrapper for apps that don't declare the thread function correctly */
+extern UINT custom_proc_wrapper( MsiCustomActionEntryPoint entry, MSIHANDLE 
hinst );
+__ASM_GLOBAL_FUNC(custom_proc_wrapper,
+                  "pushl %ebp\n\t"
+                  __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+                  __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
+                  "movl %esp,%ebp\n\t"
+                  __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
+                  "subl $4,%esp\n\t"
+                  "pushl 12(%ebp)\n\t"
+                  "call *8(%ebp)\n\t"
+                  "leave\n\t"
+                  __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
+                  __ASM_CFI(".cfi_same_value %ebp\n\t")
+                  "ret" )
+#else
+static UINT custom_proc_wrapper( MsiCustomActionEntryPoint entry, MSIHANDLE 
hinst )
+{
+    return entry(hinst);
+}
+#endif
+
 UINT CDECL __wine_msi_call_dll_function(const GUID *guid)
 {
     MsiCustomActionEntryPoint fn;
@@ -495,7 +532,6 @@ UINT CDECL __wine_msi_call_dll_function(const GUID *guid)
     LPWSTR dll = NULL;
     LPSTR proc = NULL;
     HANDLE hModule;
-    HANDLE thread;
     INT type;
     UINT r;
 
@@ -515,9 +551,6 @@ UINT CDECL __wine_msi_call_dll_function(const GUID *guid)
     }
     RpcStringFreeW(&binding_str);
 
-    /* We need this to unmarshal streams, and some apps expect it to be 
present. */
-    CoInitializeEx(NULL, COINIT_MULTITHREADED);
-
     r = remote_GetActionInfo(guid, &type, &dll, &proc, &remote_package);
     if (r != ERROR_SUCCESS)
         return r;
@@ -540,9 +573,7 @@ UINT CDECL __wine_msi_call_dll_function(const GUID *guid)
 
             __TRY
             {
-                thread = CreateThread(NULL, 0, (void *)fn, (void *)(ULONG_PTR) 
hPackage, 0, NULL);
-                WaitForSingleObject(thread, INFINITE);
-                GetExitCodeThread(thread, &r);
+                r = custom_proc_wrapper(fn, hPackage);
             }
             __EXCEPT_PAGE_FAULT
             {
@@ -566,8 +597,6 @@ UINT CDECL __wine_msi_call_dll_function(const GUID *guid)
     midl_user_free(dll);
     midl_user_free(proc);
 
-    CoUninitialize();
-
     RpcBindingFree(&rpc_handle);
 
     return r;

Reply via email to