Module: wine Branch: master Commit: 46158e034cb0f17f32d5c7516df96f1a5ded6093 URL: http://source.winehq.org/git/wine.git/?a=commit;h=46158e034cb0f17f32d5c7516d...
Author: James Hawkins truiken@gmail.com Date: Tue Jun 26 17:02:06 2007 -0700
msi: Add support for remote handles.
---
dlls/msi/handle.c | 135 ++++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 108 insertions(+), 27 deletions(-)
diff --git a/dlls/msi/handle.c b/dlls/msi/handle.c index 6af3c41..34ebdbf 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 = { &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<msihandletable_size; i++) - if( !msihandletable[i].obj ) + if( !msihandletable[i].u.obj && !msihandletable[i].u.unk ) break; if( i==msihandletable_size ) { @@ -94,19 +97,58 @@ MSIHANDLE alloc_msihandle( MSIOBJECTHDR *obj ) 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, 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 ); + } + + msihandletable[handle-1].u.obj = NULL; + msihandletable[handle-1].remote = 0; + msihandletable[handle-1].dwThreadId = 0;
- msiobj_release( info ); - msihandletable[handle-1].obj = NULL; ret = ERROR_SUCCESS;
TRACE("handle %lx Destroyed\n", handle);