msi: Reference count the custom action data to avoid freeing the
data by another thread
James Hawkins
truiken at gmail.com
Mon Jun 25 17:56:21 CDT 2007
Hi,
Fixes bug 7869. http://bugs.winehq.org/show_bug.cgi?id=7869
Changelog:
* Reference count the custom action data to avoid freeing the data by
another thread (based on a patch by Rob Shearman).
dlls/msi/custom.c | 55 ++++++++++++++++++++++++++++++++++++++---------------
1 files changed, 39 insertions(+), 16 deletions(-)
--
James Hawkins
-------------- next part --------------
diff --git a/dlls/msi/custom.c b/dlls/msi/custom.c
index af9c8dc..d9b7956 100644
--- a/dlls/msi/custom.c
+++ b/dlls/msi/custom.c
@@ -475,6 +475,7 @@ static UINT wait_process_handle(MSIPACKA
typedef struct _msi_custom_action_info {
struct list entry;
+ LONG refs;
MSIPACKAGE *package;
LPWSTR source;
LPWSTR target;
@@ -484,20 +485,31 @@ typedef struct _msi_custom_action_info {
GUID guid;
} msi_custom_action_info;
-static void free_custom_action_data( msi_custom_action_info *info )
+static void release_custom_action_data( msi_custom_action_info *info )
{
EnterCriticalSection( &msi_custom_action_cs );
- list_remove( &info->entry );
+
+ if (!--info->refs)
+ {
+ list_remove( &info->entry );
+ if (info->handle)
+ CloseHandle( info->handle );
+ msi_free( info->action );
+ msi_free( info->source );
+ msi_free( info->target );
+ msiobj_release( &info->package->hdr );
+ msi_free( info );
+ }
+
LeaveCriticalSection( &msi_custom_action_cs );
- if (info->handle)
- CloseHandle( info->handle );
- msi_free( info->action );
- msi_free( info->source );
- msi_free( info->target );
- msiobj_release( &info->package->hdr );
- msi_free( info );
}
+/* must be called inside msi_custom_action_cs if info is in the pending custom actions list */
+static void addref_custom_action_data( msi_custom_action_info *info )
+{
+ info->refs++;
+ }
+
static UINT wait_thread_handle( msi_custom_action_info *info )
{
UINT rc = ERROR_SUCCESS;
@@ -511,7 +523,7 @@ static UINT wait_thread_handle( msi_cust
if (!(info->type & msidbCustomActionTypeContinue))
rc = custom_get_thread_return( info->package, info->handle );
- free_custom_action_data( info );
+ release_custom_action_data( info );
}
else
{
@@ -532,6 +544,7 @@ static msi_custom_action_info *find_acti
{
if (IsEqualGUID( &info->guid, guid ))
{
+ addref_custom_action_data( info );
found = TRUE;
break;
}
@@ -639,7 +652,7 @@ static DWORD WINAPI ACTION_CallDllFuncti
if (info->type & msidbCustomActionTypeAsync &&
info->type & msidbCustomActionTypeContinue)
- free_custom_action_data( info );
+ release_custom_action_data( info );
return r;
}
@@ -676,6 +689,8 @@ static DWORD WINAPI ACTION_CAInstallPack
r = MsiInstallProductW(info->source, info->target);
MsiSetInternalUI(old_level, NULL);
+ release_custom_action_data(info);
+
return r;
}
@@ -704,6 +719,7 @@ static msi_custom_action_info *do_msidbC
return NULL;
msiobj_addref( &package->hdr );
+ info->refs = 2; /* 1 for our caller and 1 for thread we created */
info->package = package;
info->type = type;
info->target = strdupW( target );
@@ -718,7 +734,9 @@ static msi_custom_action_info *do_msidbC
info->handle = CreateThread( NULL, 0, DllThread, &info->guid, 0, NULL );
if (!info->handle)
{
- free_custom_action_data( info );
+ /* release both references */
+ release_custom_action_data( info );
+ release_custom_action_data( info );
return NULL;
}
@@ -735,6 +753,7 @@ static msi_custom_action_info *do_msidbC
return NULL;
msiobj_addref( &package->hdr );
+ info->refs = 2; /* 1 for our caller and 1 for thread we created */
info->package = package;
info->type = type;
info->target = strdupW( target );
@@ -749,7 +768,9 @@ static msi_custom_action_info *do_msidbC
info->handle = CreateThread( NULL, 0, ConcurrentInstallThread, &info->guid, 0, NULL );
if (!info->handle)
{
- free_custom_action_data( info );
+ /* release both references */
+ release_custom_action_data( info );
+ release_custom_action_data( info );
return NULL;
}
@@ -1085,7 +1106,7 @@ static DWORD WINAPI ACTION_CallScript( c
if (info->type & msidbCustomActionTypeAsync &&
info->type & msidbCustomActionTypeContinue)
- free_custom_action_data( info );
+ release_custom_action_data( info );
return S_OK;
}
@@ -1115,6 +1136,7 @@ static msi_custom_action_info *do_msidbC
return NULL;
msiobj_addref( &package->hdr );
+ info->refs = 2; /* 1 for our caller and 1 for thread we created */
info->package = package;
info->type = type;
info->target = strdupW( function );
@@ -1129,7 +1151,9 @@ static msi_custom_action_info *do_msidbC
info->handle = CreateThread( NULL, 0, ScriptThread, &info->guid, 0, NULL );
if (!info->handle)
{
- free_custom_action_data( info );
+ /* release both references */
+ release_custom_action_data( info );
+ release_custom_action_data( info );
return NULL;
}
@@ -1311,7 +1335,6 @@ void ACTION_FinishCustomActions(const MS
{
if (DuplicateHandle(GetCurrentProcess(), info->handle, GetCurrentProcess(), &wait_handles[handle_count], SYNCHRONIZE, FALSE, 0))
handle_count++;
- free_custom_action_data( info );
}
}
--
1.4.1
More information about the wine-patches
mailing list