From 1647de570bedb0052359075367e49dbae5ecc7b6 Mon Sep 17 00:00:00 2001 From: James Hawkins Date: Thu, 5 Jul 2007 17:56:22 -0700 Subject: [PATCH] msi: Enable remote custom actions. --- dlls/msi/custom.c | 81 ++++++++++++++++++++++++++++++------------ dlls/msi/msiserver.idl | 2 +- 2 files changed, 60 insertions(+), 23 deletions(-) diff --git a/dlls/msi/custom.c b/dlls/msi/custom.c index 850db041dd..06699d2a44 100644 --- a/dlls/msi/custom.c +++ b/dlls/msi/custom.c @@ -613,41 +613,75 @@ static void handle_msi_break( LPCWSTR target ) DebugBreak(); } +static UINT get_action_info( const GUID *guid, INT *type, MSIHANDLE *handle, + BSTR *dll, BSTR *funcname, + IWineMsiRemotePackage **package ) +{ + IClassFactory *cf = NULL; + IWineMsiRemoteCustomAction *rca = NULL; + HRESULT r; + + r = DllGetClassObject( &CLSID_IWineMsiRemoteCustomAction, + &IID_IClassFactory, (LPVOID *)&cf ); + if (FAILED(r)) + { + ERR("failed to get IClassFactory interface\n"); + return ERROR_FUNCTION_FAILED; + } + + r = IClassFactory_CreateInstance( cf, NULL, &IID_IWineMsiRemoteCustomAction, (LPVOID *)&rca ); + if (FAILED(r)) + { + ERR("failed to get IWineMsiRemoteCustomAction interface\n"); + return ERROR_FUNCTION_FAILED; + } + + r = IWineMsiRemoteCustomAction_GetActionInfo( rca, guid, type, handle, dll, funcname, package ); + IWineMsiRemoteCustomAction_Release( rca ); + if (FAILED(r)) + { + ERR("GetActionInfo failed\n"); + return ERROR_FUNCTION_FAILED; + } + + return ERROR_SUCCESS; +} + static DWORD WINAPI ACTION_CallDllFunction( const GUID *guid ) { - msi_custom_action_info *info; MsiCustomActionEntryPoint fn; - MSIHANDLE hPackage; + MSIHANDLE hPackage, handle; HANDLE hModule; LPSTR proc; UINT r = ERROR_FUNCTION_FAILED; + BSTR dll = NULL, function = NULL; + INT type; + IWineMsiRemotePackage *remote_package = NULL; - info = find_action_by_guid( guid ); - if (!info) - { - ERR("failed to find action %s\n", debugstr_guid( guid) ); + TRACE("%s\n", debugstr_guid( guid )); + + r = get_action_info( guid, &type, &handle, &dll, &function, &remote_package ); + if (r != ERROR_SUCCESS) return r; - } - TRACE("%s %s\n", debugstr_w( info->source ), debugstr_w( info->target ) ); - - hModule = LoadLibraryW( info->source ); + hModule = LoadLibraryW( dll ); if (!hModule) { - ERR("failed to load dll %s\n", debugstr_w( info->source ) ); + ERR("failed to load dll %s\n", debugstr_w( dll ) ); return r; } - proc = strdupWtoA( info->target ); + proc = strdupWtoA( function ); fn = (MsiCustomActionEntryPoint) GetProcAddress( hModule, proc ); msi_free( proc ); if (fn) { - hPackage = alloc_msihandle( &info->package->hdr ); + hPackage = alloc_msi_remote_handle( (IUnknown *)remote_package ); if (hPackage) { - TRACE("calling %s\n", debugstr_w( info->target ) ); - handle_msi_break( info->target ); + IWineMsiRemotePackage_SetMsiHandle( remote_package, handle ); + TRACE("calling %s\n", debugstr_w( function ) ); + handle_msi_break( function ); __TRY { @@ -656,7 +690,7 @@ static DWORD WINAPI ACTION_CallDllFunction( const GUID *guid ) __EXCEPT_PAGE_FAULT { ERR("Custom action (%s:%s) caused a page fault: %08x\n", - debugstr_w(info->source), debugstr_w(info->target), GetExceptionCode()); + debugstr_w(dll), debugstr_w(function), GetExceptionCode()); r = ERROR_SUCCESS; } __ENDTRY; @@ -664,16 +698,17 @@ static DWORD WINAPI ACTION_CallDllFunction( const GUID *guid ) MsiCloseHandle( hPackage ); } else - ERR("failed to create handle for %p\n", info->package ); + ERR("failed to create handle for %p\n", remote_package ); } else - ERR("GetProcAddress(%s) failed\n", debugstr_w( info->target ) ); + ERR("GetProcAddress(%s) failed\n", debugstr_w( function ) ); FreeLibrary(hModule); - if (info->type & msidbCustomActionTypeAsync && - info->type & msidbCustomActionTypeContinue) - release_custom_action_data( info ); + IWineMsiRemotePackage_Release( remote_package ); + SysFreeString( dll ); + SysFreeString( function ); + MsiCloseHandle( handle ); return r; } @@ -1413,7 +1448,7 @@ static ULONG WINAPI mcr_Release( IWineMsiRemoteCustomAction *iface ) } static HRESULT WINAPI mcr_GetActionInfo( IWineMsiRemoteCustomAction *iface, LPCGUID custom_action_guid, - MSIHANDLE *handle, BSTR *dll, BSTR *func, IWineMsiRemotePackage **remote_package ) + INT *type, MSIHANDLE *handle, BSTR *dll, BSTR *func, IWineMsiRemotePackage **remote_package ) { msi_custom_action_info *info; @@ -1421,10 +1456,12 @@ static HRESULT WINAPI mcr_GetActionInfo( IWineMsiRemoteCustomAction *iface, LPCG if (!info) return E_FAIL; + *type = info->type; *handle = alloc_msihandle( &info->package->hdr ); *dll = SysAllocString( info->source ); *func = SysAllocString( info->target ); + release_custom_action_data( info ); return create_msi_remote_package( NULL, (LPVOID *)remote_package ); } diff --git a/dlls/msi/msiserver.idl b/dlls/msi/msiserver.idl index 1b162be17d..f095f6af13 100644 --- a/dlls/msi/msiserver.idl +++ b/dlls/msi/msiserver.idl @@ -66,7 +66,7 @@ interface IWineMsiRemotePackage : IUnknown ] interface IWineMsiRemoteCustomAction : IUnknown { - HRESULT GetActionInfo( [in] LPCGUID guid, [out] MSIHANDLE *handle, [out] BSTR *dllname, + HRESULT GetActionInfo( [in] LPCGUID guid, [out] INT *type, [out] MSIHANDLE *handle, [out] BSTR *dllname, [out] BSTR *function, [out] IWineMsiRemotePackage **package ); }