https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a8bc3902bac9f5d74b274…
commit a8bc3902bac9f5d74b274155825160c525b20868
Author:     winesync <ros-dev(a)reactos.org>
AuthorDate: Sat Mar 12 15:12:08 2022 +0100
Commit:     Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Sun Mar 20 19:27:42 2022 +0100
    [WINESYNC] msi: Execute custom actions in a separate process.
    Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
    Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
    Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
    wine commit id 85d1fb62b321e890004bc8d0ded7a0183216c42d by Zebediah Figura
<z.figura12(a)gmail.com>
---
 base/system/msiexec/msiexec.c           |   9 ++-
 dll/win32/msi/CMakeLists.txt            |  11 +++-
 dll/win32/msi/cond.y                    |   2 +-
 dll/win32/msi/custom.c                  | 103 ++++++++++++++++++++++----------
 dll/win32/msi/database.c                |   8 +--
 dll/win32/msi/format.c                  |   2 +-
 dll/win32/msi/handle.c                  |   4 +-
 dll/win32/msi/install.c                 |   2 +-
 dll/win32/msi/msi.c                     |   2 +-
 dll/win32/msi/msi.spec                  |   2 +
 dll/win32/msi/msipriv.h                 |   2 +-
 dll/win32/msi/msiquery.c                |  12 ++--
 dll/win32/msi/msvchelper.h              |  25 --------
 dll/win32/msi/package.c                 |  44 +++++++-------
 dll/win32/msi/suminfo.c                 |   2 +-
 dll/win32/msi/winemsi.idl               |   5 +-
 modules/rostests/winetests/msi/custom.c |   2 +-
 17 files changed, 132 insertions(+), 105 deletions(-)
diff --git a/base/system/msiexec/msiexec.c b/base/system/msiexec/msiexec.c
index 8dcd216380e..2ed055771f6 100644
--- a/base/system/msiexec/msiexec.c
+++ b/base/system/msiexec/msiexec.c
@@ -393,10 +393,13 @@ static DWORD DoUnregServer(void)
     return ret;
 }
-static INT DoEmbedding( LPWSTR key )
+extern UINT __wine_msi_call_dll_function(GUID *guid);
+
+static int DoEmbedding(LPCWSTR key)
 {
-       printf("Remote custom actions are not supported yet\n");
-       return 1;
+    GUID guid;
+    CLSIDFromString(key, &guid);
+    return __wine_msi_call_dll_function(&guid);
 }
 /*
diff --git a/dll/win32/msi/CMakeLists.txt b/dll/win32/msi/CMakeLists.txt
index d3eb231a0fd..60f6d8f1e1b 100644
--- a/dll/win32/msi/CMakeLists.txt
+++ b/dll/win32/msi/CMakeLists.txt
@@ -52,11 +52,18 @@ list(APPEND SOURCE
 BISON_TARGET(cond cond.y ${CMAKE_CURRENT_BINARY_DIR}/cond.tab.c COMPILE_FLAGS "-p
cond_")
 BISON_TARGET(sql sql.y ${CMAKE_CURRENT_BINARY_DIR}/sql.tab.c COMPILE_FLAGS "-p
sql_")
+set(OLD_IDL_FLAGS ${IDL_FLAGS})
+set(IDL_FLAGS ${IDL_FLAGS} --prefix-server=s_)
+add_rpc_files(client winemsi.idl)
+add_rpc_files(server winemsi.idl)
+set(IDL_FLAGS ${OLD_IDL_FLAGS})
+
 list(APPEND PCH_SKIP_SOURCE
     ${BISON_cond_OUTPUTS}
     ${BISON_sql_OUTPUTS}
     ${CMAKE_CURRENT_BINARY_DIR}/msiserver_i.c
-    ${CMAKE_CURRENT_BINARY_DIR}/winemsi_i.c
+    ${CMAKE_CURRENT_BINARY_DIR}/winemsi_c.c
+    ${CMAKE_CURRENT_BINARY_DIR}/winemsi_s.c
     ${CMAKE_CURRENT_BINARY_DIR}/msi_stubs.c)
 add_library(msi MODULE
@@ -80,7 +87,7 @@ set_module_type(msi win32dll)
 target_link_libraries(msi uuid ${PSEH_LIB} wine)
 add_dependencies(msi msi_idlheader)
 add_delay_importlibs(msi odbccp32 crypt32 wintrust)
-add_importlibs(msi advapi32 advapi32_vista cabinet comctl32 gdi32 ole32 oleaut32 shell32
shlwapi urlmon user32 version wininet mspatcha
+add_importlibs(msi advapi32 advapi32_vista cabinet comctl32 gdi32 ole32 oleaut32 shell32
shlwapi rpcrt4 urlmon user32 version wininet mspatcha
     #FIXME : should be in delayed imports
     imagehlp
     msvcrt
diff --git a/dll/win32/msi/cond.y b/dll/win32/msi/cond.y
index a8c97340db9..780ca381f93 100644
--- a/dll/win32/msi/cond.y
+++ b/dll/win32/msi/cond.y
@@ -37,7 +37,7 @@
 #include "oleauto.h"
 #include "msipriv.h"
-#include "winemsi.h"
+#include "winemsi_s.h"
 #include "wine/debug.h"
 #include "wine/unicode.h"
 #include "wine/list.h"
diff --git a/dll/win32/msi/custom.c b/dll/win32/msi/custom.c
index e5636083451..25066a70d02 100644
--- a/dll/win32/msi/custom.c
+++ b/dll/win32/msi/custom.c
@@ -35,16 +35,12 @@
 #include "oleauto.h"
 #include "msipriv.h"
-#include "winemsi.h"
+#include "winemsi_s.h"
 #include "wine/heap.h"
 #include "wine/debug.h"
 #include "wine/unicode.h"
 #include "wine/exception.h"
-#ifdef _MSC_VER
-#include "msvchelper.h"
-#endif
-
 WINE_DEFAULT_DEBUG_CHANNEL(msi);
 #define CUSTOM_ACTION_TYPE_MASK 0x3F
@@ -491,35 +487,18 @@ static void handle_msi_break(LPCSTR target)
     DebugBreak();
 }
-#ifdef __i386__
-extern UINT CUSTOMPROC_wrapper( MsiCustomActionEntryPoint proc, MSIHANDLE handle );
-__ASM_GLOBAL_FUNC( CUSTOMPROC_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"
-    "movl 8(%ebp),%eax\n\t"
-    "call *%eax\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 inline UINT CUSTOMPROC_wrapper( MsiCustomActionEntryPoint proc, MSIHANDLE handle )
-{
-    return proc(handle);
-}
-#endif
+static WCHAR ncalrpcW[] =
{'n','c','a','l','r','p','c',0};
+static WCHAR endpoint_lrpcW[] = {'m','s','i',0};
-static DWORD ACTION_CallDllFunction( const GUID *guid )
+UINT __wine_msi_call_dll_function(const GUID *guid)
 {
     MsiCustomActionEntryPoint fn;
     MSIHANDLE remote_package = 0;
+    RPC_WSTR binding_str;
     MSIHANDLE hPackage;
+    RPC_STATUS status;
     HANDLE hModule;
+    HANDLE thread;
     LPWSTR dll;
     LPSTR proc;
     INT type;
@@ -527,6 +506,23 @@ static DWORD ACTION_CallDllFunction( const GUID *guid )
     TRACE("%s\n", debugstr_guid( guid ));
+    status = RpcStringBindingComposeW(NULL, ncalrpcW, NULL, endpoint_lrpcW, NULL,
&binding_str);
+    if (status != RPC_S_OK)
+    {
+        ERR("RpcStringBindingCompose failed: %#x\n", status);
+        return status;
+    }
+    status = RpcBindingFromStringBindingW(binding_str, &rpc_handle);
+    if (status != RPC_S_OK)
+    {
+        ERR("RpcBindingFromStringBinding failed: %#x\n", status);
+        return status;
+    }
+    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;
@@ -549,7 +545,9 @@ static DWORD ACTION_CallDllFunction( const GUID *guid )
             __TRY
             {
-                r = CUSTOMPROC_wrapper( fn, hPackage );
+                thread = CreateThread(NULL, 0, (void *)fn, (void *)(ULONG_PTR) hPackage,
0, NULL);
+                WaitForSingleObject(thread, INFINITE);
+                GetExitCodeThread(thread, &r);
             }
             __EXCEPT_PAGE_FAULT
             {
@@ -573,17 +571,56 @@ static DWORD ACTION_CallDllFunction( const GUID *guid )
     midl_user_free(dll);
     midl_user_free(proc);
+    CoUninitialize();
+
+    RpcBindingFree(&rpc_handle);
+
     return r;
 }
 static DWORD WINAPI DllThread( LPVOID arg )
 {
-    LPGUID guid = arg;
-    DWORD rc = 0;
+    WCHAR buffer[64] =
{'m','s','i','e','x','e','c','.','e','x','e','
','-','E','m','b','e','d','d','i','n','g','
',0};
+    PROCESS_INFORMATION pi = {0};
+    STARTUPINFOW si = {0};
+    RPC_STATUS status;
+    GUID *guid = arg;
+    DWORD rc;
     TRACE("custom action (%x) started\n", GetCurrentThreadId() );
-    rc = ACTION_CallDllFunction( guid );
+    CoInitializeEx(NULL, COINIT_MULTITHREADED); /* needed to marshal streams */
+
+    status = RpcServerUseProtseqEpW(ncalrpcW, RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
endpoint_lrpcW, NULL);
+    if (status != RPC_S_OK)
+    {
+        ERR("RpcServerUseProtseqEp failed: %#x\n", status);
+        return status;
+    }
+
+    status = RpcServerRegisterIfEx((RPC_IF_HANDLE)s_IWineMsiRemote_v0_0_s_ifspec, NULL,
NULL,
+        RPC_IF_AUTOLISTEN, RPC_C_LISTEN_MAX_CALLS_DEFAULT, NULL);
+    if (status != RPC_S_OK)
+    {
+        ERR("RpcServerRegisterIfEx failed: %#x\n", status);
+        return status;
+    }
+
+    StringFromGUID2(guid, buffer + strlenW(buffer), 39);
+    CreateProcessW(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
+    WaitForSingleObject(pi.hProcess, INFINITE);
+    GetExitCodeProcess(pi.hProcess, &rc);
+    CloseHandle(pi.hProcess);
+    CloseHandle(pi.hThread);
+
+    status = RpcServerUnregisterIf((RPC_IF_HANDLE)s_IWineMsiRemote_v0_0_s_ifspec, NULL,
FALSE);
+    if (status != RPC_S_OK)
+    {
+        ERR("RpcServerUnregisterIf failed: %#x\n", status);
+        return status;
+    }
+
+    CoUninitialize();
     TRACE("custom action (%x) returned %i\n", GetCurrentThreadId(), rc );
@@ -1348,7 +1385,7 @@ void ACTION_FinishCustomActions(const MSIPACKAGE* package)
     LeaveCriticalSection( &msi_custom_action_cs );
 }
-UINT __cdecl remote_GetActionInfo(const GUID *guid, int *type, LPWSTR *dll, LPSTR *func,
MSIHANDLE *hinst)
+UINT __cdecl s_remote_GetActionInfo(const GUID *guid, int *type, LPWSTR *dll, LPSTR
*func, MSIHANDLE *hinst)
 {
     msi_custom_action_info *info;
diff --git a/dll/win32/msi/database.c b/dll/win32/msi/database.c
index 1657a353ba0..303667d52b8 100644
--- a/dll/win32/msi/database.c
+++ b/dll/win32/msi/database.c
@@ -2017,12 +2017,12 @@ MSIDBSTATE WINAPI MsiGetDatabaseState( MSIHANDLE handle )
     return ret;
 }
-MSICONDITION __cdecl remote_DatabaseIsTablePersistent(MSIHANDLE db, LPCWSTR table)
+MSICONDITION __cdecl s_remote_DatabaseIsTablePersistent(MSIHANDLE db, LPCWSTR table)
 {
     return MsiDatabaseIsTablePersistentW(db, table);
 }
-UINT __cdecl remote_DatabaseGetPrimaryKeys(MSIHANDLE db, LPCWSTR table, struct
wire_record **rec)
+UINT __cdecl s_remote_DatabaseGetPrimaryKeys(MSIHANDLE db, LPCWSTR table, struct
wire_record **rec)
 {
     MSIHANDLE handle;
     UINT r = MsiDatabaseGetPrimaryKeysW(db, table, &handle);
@@ -2033,12 +2033,12 @@ UINT __cdecl remote_DatabaseGetPrimaryKeys(MSIHANDLE db, LPCWSTR
table, struct w
     return r;
 }
-UINT __cdecl remote_DatabaseGetSummaryInformation(MSIHANDLE db, UINT updatecount,
MSIHANDLE *suminfo)
+UINT __cdecl s_remote_DatabaseGetSummaryInformation(MSIHANDLE db, UINT updatecount,
MSIHANDLE *suminfo)
 {
     return MsiGetSummaryInformationW(db, NULL, updatecount, suminfo);
 }
-UINT __cdecl remote_DatabaseOpenView(MSIHANDLE db, LPCWSTR query, MSIHANDLE *view)
+UINT __cdecl s_remote_DatabaseOpenView(MSIHANDLE db, LPCWSTR query, MSIHANDLE *view)
 {
     return MsiDatabaseOpenViewW(db, query, view);
 }
diff --git a/dll/win32/msi/format.c b/dll/win32/msi/format.c
index 0533cc004ce..6f187581516 100644
--- a/dll/win32/msi/format.c
+++ b/dll/win32/msi/format.c
@@ -34,7 +34,7 @@
 #include "oleauto.h"
 #include "msipriv.h"
-#include "winemsi.h"
+#include "winemsi_s.h"
 #include "wine/unicode.h"
 WINE_DEFAULT_DEBUG_CHANNEL(msi);
diff --git a/dll/win32/msi/handle.c b/dll/win32/msi/handle.c
index 1002f9d969b..d2731935a3d 100644
--- a/dll/win32/msi/handle.c
+++ b/dll/win32/msi/handle.c
@@ -31,7 +31,7 @@
 #include "msiquery.h"
 #include "msipriv.h"
-#include "winemsi.h"
+#include "winemsi_s.h"
 WINE_DEFAULT_DEBUG_CHANNEL(msi);
@@ -344,7 +344,7 @@ UINT WINAPI MsiCloseAllHandles(void)
     return n;
 }
-UINT __cdecl remote_CloseHandle(MSIHANDLE handle)
+UINT __cdecl s_remote_CloseHandle(MSIHANDLE handle)
 {
     return MsiCloseHandle(handle);
 }
diff --git a/dll/win32/msi/install.c b/dll/win32/msi/install.c
index 45c55375bfd..382f20b7aa0 100644
--- a/dll/win32/msi/install.c
+++ b/dll/win32/msi/install.c
@@ -33,7 +33,7 @@
 #include "oleauto.h"
 #include "msipriv.h"
-#include "winemsi.h"
+#include "winemsi_s.h"
 #include "wine/heap.h"
 #include "wine/debug.h"
 #include "wine/unicode.h"
diff --git a/dll/win32/msi/msi.c b/dll/win32/msi/msi.c
index 2ec94a1cfb6..b53c2241e43 100644
--- a/dll/win32/msi/msi.c
+++ b/dll/win32/msi/msi.c
@@ -41,7 +41,7 @@
 #include "softpub.h"
 #include "msipriv.h"
-#include "winemsi.h"
+#include "winemsi_s.h"
 #include "initguid.h"
 #include "msxml2.h"
diff --git a/dll/win32/msi/msi.spec b/dll/win32/msi/msi.spec
index 4288c9d408f..aecba1b1b38 100644
--- a/dll/win32/msi/msi.spec
+++ b/dll/win32/msi/msi.spec
@@ -294,3 +294,5 @@
 @ stdcall -private DllGetClassObject(ptr ptr ptr)
 @ stdcall -private DllRegisterServer()
 @ stdcall -private DllUnregisterServer()
+
+@ cdecl __wine_msi_call_dll_function(ptr)
diff --git a/dll/win32/msi/msipriv.h b/dll/win32/msi/msipriv.h
index 4a92bd0e943..f1f689e153f 100644
--- a/dll/win32/msi/msipriv.h
+++ b/dll/win32/msi/msipriv.h
@@ -39,7 +39,7 @@
 #include "wine/debug.h"
 #include "msiserver.h"
-#include "winemsi.h"
+#include "winemsi_s.h"
 static const BOOL is_64bit = sizeof(void *) > sizeof(int);
 BOOL is_wow64 DECLSPEC_HIDDEN;
diff --git a/dll/win32/msi/msiquery.c b/dll/win32/msi/msiquery.c
index 42ee8c79d02..83ec59c45dc 100644
--- a/dll/win32/msi/msiquery.c
+++ b/dll/win32/msi/msiquery.c
@@ -35,7 +35,7 @@
 #include "msipriv.h"
 #include "query.h"
-#include "winemsi.h"
+#include "winemsi_s.h"
 #include "initguid.h"
@@ -1093,12 +1093,12 @@ MSICONDITION WINAPI MsiDatabaseIsTablePersistentW(
     return r;
 }
-UINT __cdecl remote_ViewClose(MSIHANDLE view)
+UINT __cdecl s_remote_ViewClose(MSIHANDLE view)
 {
     return MsiViewClose(view);
 }
-UINT __cdecl remote_ViewExecute(MSIHANDLE view, struct wire_record *remote_rec)
+UINT __cdecl s_remote_ViewExecute(MSIHANDLE view, struct wire_record *remote_rec)
 {
     MSIHANDLE rec = 0;
     UINT r;
@@ -1112,7 +1112,7 @@ UINT __cdecl remote_ViewExecute(MSIHANDLE view, struct wire_record
*remote_rec)
     return r;
 }
-UINT __cdecl remote_ViewFetch(MSIHANDLE view, struct wire_record **rec)
+UINT __cdecl s_remote_ViewFetch(MSIHANDLE view, struct wire_record **rec)
 {
     MSIHANDLE handle;
     UINT r = MsiViewFetch(view, &handle);
@@ -1123,7 +1123,7 @@ UINT __cdecl remote_ViewFetch(MSIHANDLE view, struct wire_record
**rec)
     return r;
 }
-UINT __cdecl remote_ViewGetColumnInfo(MSIHANDLE view, MSICOLINFO info, struct wire_record
**rec)
+UINT __cdecl s_remote_ViewGetColumnInfo(MSIHANDLE view, MSICOLINFO info, struct
wire_record **rec)
 {
     MSIHANDLE handle;
     UINT r = MsiViewGetColumnInfo(view, info, &handle);
@@ -1134,7 +1134,7 @@ UINT __cdecl remote_ViewGetColumnInfo(MSIHANDLE view, MSICOLINFO
info, struct wi
     return r;
 }
-UINT __cdecl remote_ViewModify(MSIHANDLE view, MSIMODIFY mode,
+UINT __cdecl s_remote_ViewModify(MSIHANDLE view, MSIMODIFY mode,
     struct wire_record *remote_rec, struct wire_record **remote_refreshed)
 {
     MSIHANDLE handle = 0;
diff --git a/dll/win32/msi/msvchelper.h b/dll/win32/msi/msvchelper.h
deleted file mode 100644
index 0ad6d72308d..00000000000
--- a/dll/win32/msi/msvchelper.h
+++ /dev/null
@@ -1,25 +0,0 @@
-
-#ifdef __i386__
-
-typedef unsigned int (__stdcall *__MSVC__MsiCustomActionEntryPoint)(unsigned int);
-
-static
-__declspec(naked)
-unsigned int
-__cdecl
-CUSTOMPROC_wrapper(__MSVC__MsiCustomActionEntryPoint proc, unsigned int handle)
-{
-    __asm
-    {
-        push ebp
-        mov ebp, esp
-        sub esp, 4
-        push dword ptr [ebp + 12]
-        mov eax, dword ptr [ebp + 8]
-        call eax
-        leave
-        ret
-    }
-}
-
-#endif
diff --git a/dll/win32/msi/package.c b/dll/win32/msi/package.c
index 510dd43b2ad..1e4c0874d8a 100644
--- a/dll/win32/msi/package.c
+++ b/dll/win32/msi/package.c
@@ -47,7 +47,7 @@
 #include "wine/unicode.h"
 #include "msipriv.h"
-#include "winemsi.h"
+#include "winemsi_s.h"
 #include "resource.h"
 WINE_DEFAULT_DEBUG_CHANNEL(msi);
@@ -2428,12 +2428,12 @@ UINT WINAPI MsiGetPropertyW( MSIHANDLE hInstall, LPCWSTR szName,
     return MSI_GetProperty( hInstall, szName, &val, pchValueBuf );
 }
-MSIHANDLE __cdecl remote_GetActiveDatabase(MSIHANDLE hinst)
+MSIHANDLE __cdecl s_remote_GetActiveDatabase(MSIHANDLE hinst)
 {
     return MsiGetActiveDatabase(hinst);
 }
-UINT __cdecl remote_GetProperty(MSIHANDLE hinst, LPCWSTR property, LPWSTR *value, DWORD
*size)
+UINT __cdecl s_remote_GetProperty(MSIHANDLE hinst, LPCWSTR property, LPWSTR *value, DWORD
*size)
 {
     WCHAR empty[1];
     UINT r;
@@ -2451,12 +2451,12 @@ UINT __cdecl remote_GetProperty(MSIHANDLE hinst, LPCWSTR property,
LPWSTR *value
     return r;
 }
-UINT __cdecl remote_SetProperty(MSIHANDLE hinst, LPCWSTR property, LPCWSTR value)
+UINT __cdecl s_remote_SetProperty(MSIHANDLE hinst, LPCWSTR property, LPCWSTR value)
 {
     return MsiSetPropertyW(hinst, property, value);
 }
-int __cdecl remote_ProcessMessage(MSIHANDLE hinst, INSTALLMESSAGE message, struct
wire_record *remote_rec)
+int __cdecl s_remote_ProcessMessage(MSIHANDLE hinst, INSTALLMESSAGE message, struct
wire_record *remote_rec)
 {
     MSIHANDLE rec;
     int ret;
@@ -2471,17 +2471,17 @@ int __cdecl remote_ProcessMessage(MSIHANDLE hinst, INSTALLMESSAGE
message, struc
     return ret;
 }
-UINT __cdecl remote_DoAction(MSIHANDLE hinst, LPCWSTR action)
+UINT __cdecl s_remote_DoAction(MSIHANDLE hinst, LPCWSTR action)
 {
     return MsiDoActionW(hinst, action);
 }
-UINT __cdecl remote_Sequence(MSIHANDLE hinst, LPCWSTR table, int sequence)
+UINT __cdecl s_remote_Sequence(MSIHANDLE hinst, LPCWSTR table, int sequence)
 {
     return MsiSequenceW(hinst, table, sequence);
 }
-UINT __cdecl remote_GetTargetPath(MSIHANDLE hinst, LPCWSTR folder, LPWSTR *value)
+UINT __cdecl s_remote_GetTargetPath(MSIHANDLE hinst, LPCWSTR folder, LPWSTR *value)
 {
     WCHAR empty[1];
     DWORD size = 0;
@@ -2498,12 +2498,12 @@ UINT __cdecl remote_GetTargetPath(MSIHANDLE hinst, LPCWSTR folder,
LPWSTR *value
     return r;
 }
-UINT __cdecl remote_SetTargetPath(MSIHANDLE hinst, LPCWSTR folder, LPCWSTR value)
+UINT __cdecl s_remote_SetTargetPath(MSIHANDLE hinst, LPCWSTR folder, LPCWSTR value)
 {
     return MsiSetTargetPathW(hinst, folder, value);
 }
-UINT __cdecl remote_GetSourcePath(MSIHANDLE hinst, LPCWSTR folder, LPWSTR *value)
+UINT __cdecl s_remote_GetSourcePath(MSIHANDLE hinst, LPCWSTR folder, LPWSTR *value)
 {
     WCHAR empty[1];
     DWORD size = 1;
@@ -2520,49 +2520,49 @@ UINT __cdecl remote_GetSourcePath(MSIHANDLE hinst, LPCWSTR folder,
LPWSTR *value
     return r;
 }
-BOOL __cdecl remote_GetMode(MSIHANDLE hinst, MSIRUNMODE mode)
+BOOL __cdecl s_remote_GetMode(MSIHANDLE hinst, MSIRUNMODE mode)
 {
     return MsiGetMode(hinst, mode);
 }
-UINT __cdecl remote_SetMode(MSIHANDLE hinst, MSIRUNMODE mode, BOOL state)
+UINT __cdecl s_remote_SetMode(MSIHANDLE hinst, MSIRUNMODE mode, BOOL state)
 {
     return MsiSetMode(hinst, mode, state);
 }
-UINT __cdecl remote_GetFeatureState(MSIHANDLE hinst, LPCWSTR feature,
+UINT __cdecl s_remote_GetFeatureState(MSIHANDLE hinst, LPCWSTR feature,
                                     INSTALLSTATE *installed, INSTALLSTATE *action)
 {
     return MsiGetFeatureStateW(hinst, feature, installed, action);
 }
-UINT __cdecl remote_SetFeatureState(MSIHANDLE hinst, LPCWSTR feature, INSTALLSTATE state)
+UINT __cdecl s_remote_SetFeatureState(MSIHANDLE hinst, LPCWSTR feature, INSTALLSTATE
state)
 {
     return MsiSetFeatureStateW(hinst, feature, state);
 }
-UINT __cdecl remote_GetComponentState(MSIHANDLE hinst, LPCWSTR component,
+UINT __cdecl s_remote_GetComponentState(MSIHANDLE hinst, LPCWSTR component,
                                       INSTALLSTATE *installed, INSTALLSTATE *action)
 {
     return MsiGetComponentStateW(hinst, component, installed, action);
 }
-UINT __cdecl remote_SetComponentState(MSIHANDLE hinst, LPCWSTR component, INSTALLSTATE
state)
+UINT __cdecl s_remote_SetComponentState(MSIHANDLE hinst, LPCWSTR component, INSTALLSTATE
state)
 {
     return MsiSetComponentStateW(hinst, component, state);
 }
-LANGID __cdecl remote_GetLanguage(MSIHANDLE hinst)
+LANGID __cdecl s_remote_GetLanguage(MSIHANDLE hinst)
 {
     return MsiGetLanguage(hinst);
 }
-UINT __cdecl remote_SetInstallLevel(MSIHANDLE hinst, int level)
+UINT __cdecl s_remote_SetInstallLevel(MSIHANDLE hinst, int level)
 {
     return MsiSetInstallLevel(hinst, level);
 }
-UINT __cdecl remote_FormatRecord(MSIHANDLE hinst, struct wire_record *remote_rec, LPWSTR
*value)
+UINT __cdecl s_remote_FormatRecord(MSIHANDLE hinst, struct wire_record *remote_rec,
LPWSTR *value)
 {
     WCHAR empty[1];
     DWORD size = 0;
@@ -2585,18 +2585,18 @@ UINT __cdecl remote_FormatRecord(MSIHANDLE hinst, struct
wire_record *remote_rec
     return r;
 }
-MSICONDITION __cdecl remote_EvaluateCondition(MSIHANDLE hinst, LPCWSTR condition)
+MSICONDITION __cdecl s_remote_EvaluateCondition(MSIHANDLE hinst, LPCWSTR condition)
 {
     return MsiEvaluateConditionW(hinst, condition);
 }
-UINT __cdecl remote_GetFeatureCost(MSIHANDLE hinst, LPCWSTR feature,
+UINT __cdecl s_remote_GetFeatureCost(MSIHANDLE hinst, LPCWSTR feature,
     MSICOSTTREE cost_tree, INSTALLSTATE state, INT *cost)
 {
     return MsiGetFeatureCostW(hinst, feature, cost_tree, state, cost);
 }
-UINT __cdecl remote_EnumComponentCosts(MSIHANDLE hinst, LPCWSTR component,
+UINT __cdecl s_remote_EnumComponentCosts(MSIHANDLE hinst, LPCWSTR component,
     DWORD index, INSTALLSTATE state, LPWSTR drive, INT *cost, INT *temp)
 {
     DWORD size = 3;
diff --git a/dll/win32/msi/suminfo.c b/dll/win32/msi/suminfo.c
index 0268f631288..f9bdf38edf3 100644
--- a/dll/win32/msi/suminfo.c
+++ b/dll/win32/msi/suminfo.c
@@ -38,7 +38,7 @@
 #include "propvarutil.h"
 #include "msipriv.h"
-#include "winemsi.h"
+#include "winemsi_s.h"
 WINE_DEFAULT_DEBUG_CHANNEL(msi);
diff --git a/dll/win32/msi/winemsi.idl b/dll/win32/msi/winemsi.idl
index 8af175999b8..50f62fcbfd8 100644
--- a/dll/win32/msi/winemsi.idl
+++ b/dll/win32/msi/winemsi.idl
@@ -18,6 +18,8 @@
  */
 #pragma makedep header
+#pragma makedep client
+#pragma makedep server
 import "objidl.idl";
@@ -55,7 +57,8 @@ struct wire_record {
 };
 [
-    uuid(56D58B64-8780-4c22-A8BC-8B0B29E4A9F8)
+    uuid(56D58B64-8780-4c22-A8BC-8B0B29E4A9F8),
+    implicit_handle(handle_t rpc_handle)
 ]
 interface IWineMsiRemote
 {
diff --git a/modules/rostests/winetests/msi/custom.c
b/modules/rostests/winetests/msi/custom.c
index 35b3d71f52b..04946d907d3 100644
--- a/modules/rostests/winetests/msi/custom.c
+++ b/modules/rostests/winetests/msi/custom.c
@@ -993,7 +993,7 @@ UINT WINAPI main_test(MSIHANDLE hinst)
     /* Test for an MTA apartment */
     hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
&IID_IUnknown, (void **)&unk);
-    todo_wine_ok(hinst, hr == S_OK, "CoCreateInstance failed with %08x\n", hr);
+    ok(hinst, hr == S_OK, "CoCreateInstance failed with %08x\n", hr);
     if (unk) IUnknown_Release(unk);