msi: Add support for remote handles.

This commit is contained in:
James Hawkins 2007-06-26 17:02:06 -07:00 committed by Alexandre Julliard
parent dcef0bbf71
commit 46158e034c

View File

@ -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
{
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 );
msihandletable[i].obj = obj;
msihandletable[i].dwThreadId = GetCurrentThreadId();
ret = (MSIHANDLE) (i+1);
out:
TRACE("%p -> %ld\n", obj, ret );
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,6 +282,15 @@ UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
EnterCriticalSection( &MSI_handle_cs );
unk = msi_get_remote( handle );
if (unk)
{
/* release once for handle, once for table entry */
IUnknown_Release( unk );
IUnknown_Release( unk );
}
else
{
info = msihandle2msiinfo(handle, 0);
if( !info )
goto out;
@ -226,7 +302,12 @@ UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
}
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);