Mike McCormack : msi: Find pending custom actions by GUID.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Feb 14 09:25:56 CST 2007
Module: wine
Branch: master
Commit: d50c62884a4bbd5835f0ab9aaaa1598fa13cf022
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d50c62884a4bbd5835f0ab9aaaa1598fa13cf022
Author: Mike McCormack <mike at codeweavers.com>
Date: Tue Feb 13 22:48:05 2007 +0900
msi: Find pending custom actions by GUID.
---
dlls/msi/custom.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++-----
dlls/msi/msipriv.h | 1 -
dlls/msi/package.c | 1 -
3 files changed, 74 insertions(+), 11 deletions(-)
diff --git a/dlls/msi/custom.c b/dlls/msi/custom.c
index 4fc1ea9..ba5c825 100644
--- a/dlls/msi/custom.c
+++ b/dlls/msi/custom.c
@@ -61,12 +61,24 @@ static UINT HANDLE_CustomType34(MSIPACKAGE *package, LPCWSTR source,
typedef UINT (WINAPI *MsiCustomActionEntryPoint)( MSIHANDLE );
+static CRITICAL_SECTION msi_custom_action_cs;
+static CRITICAL_SECTION_DEBUG msi_custom_action_cs_debug =
+{
+ 0, 0, &msi_custom_action_cs,
+ { &msi_custom_action_cs_debug.ProcessLocksList,
+ &msi_custom_action_cs_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": msi_custom_action_cs") }
+};
+static CRITICAL_SECTION msi_custom_action_cs = { &msi_custom_action_cs_debug, -1, 0, 0, 0, 0 };
+
+static struct list msi_pending_custom_actions = LIST_INIT( msi_pending_custom_actions );
+
static BOOL check_execution_scheduling_options(MSIPACKAGE *package, LPCWSTR action, UINT options)
{
if (!package->script)
return TRUE;
- if ((options & msidbCustomActionTypeClientRepeat) ==
+ if ((options & msidbCustomActionTypeClientRepeat) ==
msidbCustomActionTypeClientRepeat)
{
if (!(package->script->InWhatSequence & SEQUENCE_UI &&
@@ -405,11 +417,14 @@ typedef struct _msi_custom_action_info {
HANDLE handle;
LPWSTR action;
INT type;
+ GUID guid;
} msi_custom_action_info;
static void free_custom_action_data( msi_custom_action_info *info )
{
+ EnterCriticalSection( &msi_custom_action_cs );
list_remove( &info->entry );
+ LeaveCriticalSection( &msi_custom_action_cs );
if (info->handle)
CloseHandle( info->handle );
msi_free( info->action );
@@ -445,15 +460,46 @@ static UINT wait_thread_handle( msi_custom_action_info *info )
return rc;
}
+static msi_custom_action_info *find_action_by_guid( const LPGUID guid )
+{
+ msi_custom_action_info *info;
+ BOOL found = FALSE;
+
+ EnterCriticalSection( &msi_custom_action_cs );
+
+ LIST_FOR_EACH_ENTRY( info, &msi_pending_custom_actions, msi_custom_action_info, entry )
+ {
+ if (IsEqualGUID( &info->guid, guid ))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+
+ LeaveCriticalSection( &msi_custom_action_cs );
+
+ if (!found)
+ return NULL;
+
+ return info;
+}
-static DWORD WINAPI ACTION_CallDllFunction( msi_custom_action_info *info )
+static DWORD WINAPI ACTION_CallDllFunction( const LPGUID guid )
{
+ msi_custom_action_info *info;
MsiCustomActionEntryPoint fn;
MSIHANDLE hPackage;
HANDLE hModule;
LPSTR proc;
UINT r = ERROR_FUNCTION_FAILED;
+ info = find_action_by_guid( guid );
+ if (!info)
+ {
+ ERR("failed to find action %s\n", debugstr_guid( guid) );
+ return r;
+ }
+
TRACE("%s %s\n", debugstr_w( info->dllname ), debugstr_w( info->function ) );
hModule = LoadLibraryW( info->dllname );
@@ -488,12 +534,12 @@ static DWORD WINAPI ACTION_CallDllFunction( msi_custom_action_info *info )
static DWORD WINAPI DllThread( LPVOID arg )
{
- msi_custom_action_info *info = arg;
+ LPGUID guid = arg;
DWORD rc = 0;
TRACE("custom action (%x) started\n", GetCurrentThreadId() );
- rc = ACTION_CallDllFunction( info );
+ rc = ACTION_CallDllFunction( guid );
TRACE("custom action (%x) returned %i\n", GetCurrentThreadId(), rc );
@@ -516,9 +562,13 @@ static msi_custom_action_info *do_msidbCustomActionTypeDll(
info->function = strdupW( function );
info->dllname = strdupW( dllname );
info->action = strdupW( action );
- list_add_tail( &package->pending_custom_actions, &info->entry );
+ CoCreateGuid( &info->guid );
+
+ EnterCriticalSection( &msi_custom_action_cs );
+ list_add_tail( &msi_pending_custom_actions, &info->entry );
+ LeaveCriticalSection( &msi_custom_action_cs );
- info->handle = CreateThread( NULL, 0, DllThread, info, 0, NULL );
+ info->handle = CreateThread( NULL, 0, DllThread, &info->guid, 0, NULL );
if (!info->handle)
{
free_custom_action_data( info );
@@ -823,12 +873,27 @@ void ACTION_FinishCustomActions(MSIPACKAGE* package)
msi_free( action );
}
- while ((item = list_head( &package->pending_custom_actions )))
+ while (1)
{
+ HANDLE handle;
msi_custom_action_info *info;
+ EnterCriticalSection( &msi_custom_action_cs );
+ item = list_head( &msi_pending_custom_actions );
info = LIST_ENTRY( item, msi_custom_action_info, entry );
- msi_dialog_check_messages( info->handle );
- free_custom_action_data( info );
+
+ if (item && info->package == package )
+ {
+ handle = info->handle;
+ free_custom_action_data( info );
+ }
+ else
+ handle = NULL;
+ LeaveCriticalSection( &msi_custom_action_cs );
+
+ if (!item)
+ break;
+
+ msi_dialog_check_messages( handle );
}
}
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 09a3e55..b01bb27 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -230,7 +230,6 @@ typedef struct tagMSIPACKAGE
struct tagMSISCRIPT *script;
struct list RunningActions;
- struct list pending_custom_actions;
LPWSTR BaseURL;
LPWSTR PackagePath;
diff --git a/dlls/msi/package.c b/dlls/msi/package.c
index f0163c4..b78910d 100644
--- a/dlls/msi/package.c
+++ b/dlls/msi/package.c
@@ -490,7 +490,6 @@ static MSIPACKAGE *msi_alloc_package( void )
list_init( &package->extensions );
list_init( &package->progids );
list_init( &package->RunningActions );
- list_init( &package->pending_custom_actions );
for (i=0; i<PROPERTY_HASH_SIZE; i++)
list_init( &package->props[i] );
More information about the wine-cvs
mailing list