diff --git a/dlls/msi/Makefile.in b/dlls/msi/Makefile.in index 37c9a7ad4e0..1a17d7e518a 100644 --- a/dlls/msi/Makefile.in +++ b/dlls/msi/Makefile.in @@ -1,8 +1,10 @@ MODULE = msi.dll IMPORTLIB = msi -IMPORTS = uuid urlmon wininet comctl32 shell32 shlwapi cabinet oleaut32 ole32 version user32 gdi32 advapi32 +IMPORTS = uuid urlmon wininet comctl32 shell32 shlwapi cabinet oleaut32 ole32 version user32 gdi32 advapi32 rpcrt4 DELAYIMPORTS = odbccp32 wintrust crypt32 imagehlp mspatcha +EXTRAIDLFLAGS = --prefix-server=s_ + C_SRCS = \ action.c \ alter.c \ diff --git a/dlls/msi/custom.c b/dlls/msi/custom.c index f9976a04aee..12fe53ead10 100644 --- a/dlls/msi/custom.c +++ b/dlls/msi/custom.c @@ -486,35 +486,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; @@ -522,6 +505,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; @@ -544,7 +544,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 { @@ -568,17 +570,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(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(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 ); @@ -1343,7 +1384,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/dlls/msi/database.c b/dlls/msi/database.c index 4a0559366dc..ef0221d2b85 100644 --- a/dlls/msi/database.c +++ b/dlls/msi/database.c @@ -1906,12 +1906,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); @@ -1922,12 +1922,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/dlls/msi/handle.c b/dlls/msi/handle.c index 1002f9d969b..0881833ff68 100644 --- a/dlls/msi/handle.c +++ b/dlls/msi/handle.c @@ -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/dlls/msi/msi.spec b/dlls/msi/msi.spec index 4288c9d408f..aecba1b1b38 100644 --- a/dlls/msi/msi.spec +++ b/dlls/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/dlls/msi/msiquery.c b/dlls/msi/msiquery.c index 42ee8c79d02..7dcfa7fbfd8 100644 --- a/dlls/msi/msiquery.c +++ b/dlls/msi/msiquery.c @@ -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/dlls/msi/package.c b/dlls/msi/package.c index 067e5711bf5..a2fa785e50a 100644 --- a/dlls/msi/package.c +++ b/dlls/msi/package.c @@ -2421,12 +2421,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; @@ -2444,12 +2444,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; @@ -2464,17 +2464,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; @@ -2491,12 +2491,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; @@ -2513,49 +2513,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; @@ -2578,18 +2578,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/dlls/msi/tests/custom.c b/dlls/msi/tests/custom.c index 35b3d71f52b..04946d907d3 100644 --- a/dlls/msi/tests/custom.c +++ b/dlls/msi/tests/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); diff --git a/dlls/msi/winemsi.idl b/dlls/msi/winemsi.idl index 8af175999b8..50f62fcbfd8 100644 --- a/dlls/msi/winemsi.idl +++ b/dlls/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/programs/msiexec/msiexec.c b/programs/msiexec/msiexec.c index 8dcd216380e..2ed055771f6 100644 --- a/programs/msiexec/msiexec.c +++ b/programs/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); } /*