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