James Hawkins : msi: Add support for remote handles.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Jun 27 09:11:34 CDT 2007
Module: wine
Branch: master
Commit: 46158e034cb0f17f32d5c7516df96f1a5ded6093
URL: http://source.winehq.org/git/wine.git/?a=commit;h=46158e034cb0f17f32d5c7516df96f1a5ded6093
Author: James Hawkins <truiken at 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);
More information about the wine-cvs
mailing list