msi [1/6]: Add support for remote handles

James Hawkins truiken at gmail.com
Tue Jun 19 13:56:23 CDT 2007


Hi,

The following set of patches adds infrastructure support for running
custom actions remotely.  This is required by the Adobe installers,
which rely on a bug in the remote version of MsiGetProperty.  Remoting
custom actions will not be enabled until the last patch in the entire
series (which is not one of these 6), because all APIs that call
msihandle2msiinfo(MSIHANDLETYPE_PACAKGE) must have handling for remote
interfaces, or the APIs that don't have that handling will fail.  I'm
very interested in any comments or suggestions about these patches.

Changelog:
* Add support for remote handles.

 dlls/msi/handle.c |  131 ++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 104 insertions(+), 27 deletions(-)

-- 
James Hawkins
-------------- next part --------------
diff --git a/dlls/msi/handle.c b/dlls/msi/handle.c
index 6af3c41..57b6e29 100644
--- a/dlls/msi/handle.c
+++ b/dlls/msi/handle.c
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#define COBJMACROS
+
 #include <stdarg.h>
 
 #include "windef.h"
@@ -53,7 +55,11 @@ static CRITICAL_SECTION MSI_object_cs = 
 
 typedef struct msi_handle_info_t
 {
-    MSIOBJECTHDR *obj;
+    BOOL remote;
+    union {
+        MSIOBJECTHDR *obj;
+        IUnknown *unk;
+    } u;
     DWORD dwThreadId;
 } msi_handle_info;
 
@@ -67,16 +73,13 @@ void msi_free_handle_table(void)
     msihandletable_size = 0;
 }
 
-MSIHANDLE alloc_msihandle( MSIOBJECTHDR *obj )
+static MSIHANDLE alloc_handle_table_entry(void)
 {
-    MSIHANDLE ret = 0;
     UINT i;
 
-    EnterCriticalSection( &MSI_handle_cs );
-
     /* find a slot */
     for(i=0; i<msihandletable_size; i++)
-        if( !msihandletable[i].obj )
+        if( !msihandletable[i].u.obj )
             break;
     if( i==msihandletable_size )
     {
@@ -94,19 +97,58 @@ MSIHANDLE alloc_msihandle( MSIOBJECTHDR 
                             newsize*sizeof(msi_handle_info));
         }
         if (!p)
-            goto out;
+            return 0;
         msihandletable = p;
         msihandletable_size = newsize;
     }
+    return i + 1;
+}
+
+MSIHANDLE alloc_msihandle( MSIOBJECTHDR *obj )
+{
+    msi_handle_info *entry;
+    MSIHANDLE ret;
+
+    EnterCriticalSection( &MSI_handle_cs );
+
+    ret = alloc_handle_table_entry();
+    if (ret)
+    {
+        entry = &msihandletable[ ret - 1 ];
+        msiobj_addref( obj );
+        entry->u.obj = obj;
+        entry->dwThreadId = GetCurrentThreadId();
+        entry->remote = FALSE;
+    }
+
+    LeaveCriticalSection( &MSI_handle_cs );
 
-    msiobj_addref( obj );
-    msihandletable[i].obj = obj;
-    msihandletable[i].dwThreadId = GetCurrentThreadId();
-    ret = (MSIHANDLE) (i+1);
-out:
     TRACE("%p -> %ld\n", obj, ret );
 
+    return ret;
+}
+
+MSIHANDLE alloc_msi_remote_handle( IUnknown *unk )
+{
+    msi_handle_info *entry;
+    MSIHANDLE ret;
+
+    EnterCriticalSection( &MSI_handle_cs );
+
+    ret = alloc_handle_table_entry();
+    if (ret)
+    {
+        entry = &msihandletable[ ret - 1 ];
+        IUnknown_AddRef( unk );
+        entry->u.unk = unk;
+        entry->dwThreadId = GetCurrentThreadId();
+        entry->remote = TRUE;
+    }
+
     LeaveCriticalSection( &MSI_handle_cs );
+
+    TRACE("%p -> %ld\n", unk, ret);
+
     return ret;
 }
 
@@ -118,15 +160,17 @@ void *msihandle2msiinfo(MSIHANDLE handle
     handle--;
     if( handle<0 )
         goto out;
-    if( handle>=msihandletable_size )
+    if( handle >= msihandletable_size )
+        goto out;
+    if( msihandletable[handle].remote)
         goto out;
-    if( !msihandletable[handle].obj )
+    if( !msihandletable[handle].u.obj )
         goto out;
-    if( msihandletable[handle].obj->magic != MSIHANDLE_MAGIC )
+    if( msihandletable[handle].u.obj->magic != MSIHANDLE_MAGIC )
         goto out;
-    if( type && (msihandletable[handle].obj->type != type) )
+    if( type && (msihandletable[handle].u.obj->type != type) )
         goto out;
-    ret = msihandletable[handle].obj;
+    ret = msihandletable[handle].u.obj;
     msiobj_addref( ret );
 
 out:
@@ -135,6 +179,28 @@ out:
     return (void*) ret;
 }
 
+IUnknown *msi_get_remote( MSIHANDLE handle )
+{
+    IUnknown *unk = NULL;
+
+    EnterCriticalSection( &MSI_handle_cs );
+    handle--;
+    if( handle<0 )
+        goto out;
+    if( handle>=msihandletable_size )
+        goto out;
+    if( !msihandletable[handle].remote)
+        goto out;
+    unk = msihandletable[handle].u.unk;
+    if( unk )
+        IUnknown_AddRef( unk );
+
+out:
+    LeaveCriticalSection( &MSI_handle_cs );
+
+    return unk;
+}
+
 void *alloc_msiobject(UINT type, UINT size, msihandledestructor destroy )
 {
     MSIOBJECTHDR *info;
@@ -205,8 +271,9 @@ int msiobj_release( MSIOBJECTHDR *info )
  */
 UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
 {
-    MSIOBJECTHDR *info;
+    MSIOBJECTHDR *info = NULL;
     UINT ret = ERROR_INVALID_HANDLE;
+    IUnknown *unk;
 
     TRACE("%lx\n",handle);
 
@@ -215,18 +282,28 @@ UINT WINAPI MsiCloseHandle(MSIHANDLE han
 
     EnterCriticalSection( &MSI_handle_cs );
 
-    info = msihandle2msiinfo(handle, 0);
-    if( !info )
-        goto out;
-
-    if( info->magic != MSIHANDLE_MAGIC )
+    unk = msi_get_remote( handle );
+    if (unk)
+        IUnknown_Release( unk );
+    else
     {
-        ERR("Invalid handle!\n");
-        goto out;
+        info = msihandle2msiinfo(handle, 0);
+        if( !info )
+            goto out;
+
+        if( info->magic != MSIHANDLE_MAGIC )
+        {
+            ERR("Invalid handle!\n");
+            goto out;
+        }
+
+        msiobj_release( info );
     }
 
-    msiobj_release( info );
-    msihandletable[handle-1].obj = NULL;
+    msihandletable[handle-1].u.obj = NULL;
+    msihandletable[handle-1].remote = 0;
+    msihandletable[handle-1].dwThreadId = 0;
+
     ret = ERROR_SUCCESS;
 
     TRACE("handle %lx Destroyed\n", handle);
-- 
1.4.1


More information about the wine-patches mailing list