msi [5/5]: Enable remote custom actions

James Hawkins truiken at gmail.com
Thu Jul 5 19:56:22 CDT 2007


Hi,

Fixes bug 5348 and all adobe installers (affected by this bug).
http://bugs.winehq.org/show_bug.cgi?id=5348

Changelog:
* Enable remote custom actions.

 dlls/msi/custom.c      |   81 +++++++++++++++++++++++++++++++++++-------------
 dlls/msi/msiserver.idl |    2 +
 2 files changed, 60 insertions(+), 23 deletions(-)

-- 
James Hawkins
-------------- next part --------------
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 ta
     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_CallDllFuncti
             __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_CallDllFuncti
             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( IWineMs
 }
 
 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(
     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 : IUnkno
 ]
 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 );
 }
 
-- 
1.4.1


More information about the wine-patches mailing list