James Hawkins : msi: Enable remote custom actions.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Jul 6 12:59:05 CDT 2007
Module: wine
Branch: master
Commit: 1647de570bedb0052359075367e49dbae5ecc7b6
URL: http://source.winehq.org/git/wine.git/?a=commit;h=1647de570bedb0052359075367e49dbae5ecc7b6
Author: James Hawkins <truiken at gmail.com>
Date: Thu Jul 5 17:56:22 2007 -0700
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 850db04..06699d2 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) );
- return r;
- }
+ TRACE("%s\n", debugstr_guid( guid ));
- TRACE("%s %s\n", debugstr_w( info->source ), debugstr_w( info->target ) );
+ r = get_action_info( guid, &type, &handle, &dll, &function, &remote_package );
+ if (r != ERROR_SUCCESS)
+ return r;
- 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 1b162be..f095f6a 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 );
}
More information about the wine-cvs
mailing list