From 46158e034cb0f17f32d5c7516df96f1a5ded6093 Mon Sep 17 00:00:00 2001 From: James Hawkins Date: Tue, 26 Jun 2007 17:02:06 -0700 Subject: [PATCH] msi: Add support for remote handles. --- dlls/msi/handle.c | 137 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 109 insertions(+), 28 deletions(-) diff --git a/dlls/msi/handle.c b/dlls/msi/handle.c index 6af3c4110f5..34ebdbf47f9 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 #include "windef.h" @@ -53,7 +55,11 @@ static CRITICAL_SECTION MSI_object_cs = { &MSI_object_cs_debug, -1, 0, 0, 0, 0 } 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 %ld\n", obj, ret ); +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 ); + + 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, UINT type) handle--; if( handle<0 ) goto out; - if( handle>=msihandletable_size ) + if( handle >= msihandletable_size ) goto out; - if( !msihandletable[handle].obj ) + if( msihandletable[handle].remote) goto out; - if( msihandletable[handle].obj->magic != MSIHANDLE_MAGIC ) + if( !msihandletable[handle].u.obj ) goto out; - if( type && (msihandletable[handle].obj->type != type) ) + if( msihandletable[handle].u.obj->magic != MSIHANDLE_MAGIC ) goto out; - ret = msihandletable[handle].obj; + if( type && (msihandletable[handle].u.obj->type != type) ) + goto out; + 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,32 @@ UINT WINAPI MsiCloseHandle(MSIHANDLE handle) EnterCriticalSection( &MSI_handle_cs ); - info = msihandle2msiinfo(handle, 0); - if( !info ) - goto out; - - if( info->magic != MSIHANDLE_MAGIC ) + unk = msi_get_remote( handle ); + if (unk) { - ERR("Invalid handle!\n"); - goto out; + /* release once for handle, once for table entry */ + IUnknown_Release( unk ); + IUnknown_Release( unk ); + } + else + { + 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);