James Hawkins : msi: Add handling for the concurrent install custom action.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Apr 16 07:08:41 CDT 2007


Module: wine
Branch: master
Commit: 98eafa870c619dbf78ae28feb8f5abc904de5cb9
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=98eafa870c619dbf78ae28feb8f5abc904de5cb9

Author: James Hawkins <truiken at gmail.com>
Date:   Sun Apr 15 03:12:23 2007 -0500

msi: Add handling for the concurrent install custom action.

---

 dlls/msi/custom.c        |   98 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/msi/tests/install.c |   11 ++---
 2 files changed, 102 insertions(+), 7 deletions(-)

diff --git a/dlls/msi/custom.c b/dlls/msi/custom.c
index c1c7e96..c38ea98 100644
--- a/dlls/msi/custom.c
+++ b/dlls/msi/custom.c
@@ -54,6 +54,8 @@ static UINT HANDLE_CustomType18(MSIPACKAGE *package, LPCWSTR source,
                                 LPCWSTR target, const INT type, LPCWSTR action);
 static UINT HANDLE_CustomType19(MSIPACKAGE *package, LPCWSTR source,
                                 LPCWSTR target, const INT type, LPCWSTR action);
+static UINT HANDLE_CustomType23(MSIPACKAGE *package, LPCWSTR source,
+                                LPCWSTR target, const INT type, LPCWSTR action);
 static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source,
                                 LPCWSTR target, const INT type, LPCWSTR action);
 static UINT HANDLE_CustomType34(MSIPACKAGE *package, LPCWSTR source,
@@ -250,6 +252,10 @@ UINT ACTION_CustomAction(MSIPACKAGE *package,LPCWSTR action, BOOL execute)
         case 17:
             rc = HANDLE_CustomType17(package,source,target,type,action);
             break;
+        case 23: /* installs another package in the source tree */
+            deformat_string(package,target,&deformated);
+            rc = HANDLE_CustomType23(package,source,deformated,type,action);
+            break;
         case 50: /*EXE file specified by a property value */
             rc = HANDLE_CustomType50(package,source,target,type,action);
             break;
@@ -548,6 +554,41 @@ static DWORD WINAPI DllThread( LPVOID arg )
     return rc;
 }
 
+static DWORD WINAPI ACTION_CAInstallPackage(const GUID *guid)
+{
+    msi_custom_action_info *info;
+    UINT r = ERROR_FUNCTION_FAILED;
+    INSTALLUILEVEL old_level;
+
+    info = find_action_by_guid(guid);
+    if (!info)
+    {
+        ERR("failed to find action %s\n", debugstr_guid(guid));
+        return r;
+    }
+
+    old_level = MsiSetInternalUI(INSTALLUILEVEL_BASIC, NULL);
+    r = MsiInstallProductW(info->source, info->target);
+    MsiSetInternalUI(old_level, NULL);
+
+    return r;
+}
+
+static DWORD WINAPI ConcurrentInstallThread(LPVOID arg)
+{
+    LPGUID guid = arg;
+    DWORD rc;
+
+    TRACE("concurrent installation (%x) started\n", GetCurrentThreadId());
+
+    rc = ACTION_CAInstallPackage(guid);
+
+    TRACE("concurrent installation (%x) returned %i\n", GetCurrentThreadId(), rc);
+
+    MsiCloseAllHandles();
+    return rc;
+}
+
 static msi_custom_action_info *do_msidbCustomActionTypeDll(
     MSIPACKAGE *package, INT type, LPCWSTR source, LPCWSTR target, LPCWSTR action )
 {
@@ -579,6 +620,63 @@ static msi_custom_action_info *do_msidbCustomActionTypeDll(
     return info;
 }
 
+static msi_custom_action_info *do_msidbCAConcurrentInstall(
+    MSIPACKAGE *package, INT type, LPCWSTR source, LPCWSTR target, LPCWSTR action)
+{
+    msi_custom_action_info *info;
+
+    info = msi_alloc( sizeof *info );
+    if (!info)
+        return NULL;
+
+    msiobj_addref( &package->hdr );
+    info->package = package;
+    info->type = type;
+    info->target = strdupW( target );
+    info->source = strdupW( source );
+    info->action = strdupW( action );
+    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, ConcurrentInstallThread, &info->guid, 0, NULL );
+    if (!info->handle)
+    {
+        free_custom_action_data( info );
+        return NULL;
+    }
+
+    return info;
+}
+
+static UINT HANDLE_CustomType23(MSIPACKAGE *package, LPCWSTR source,
+                                LPCWSTR target, const INT type, LPCWSTR action)
+{
+    msi_custom_action_info *info;
+    WCHAR package_path[MAX_PATH];
+    DWORD size;
+
+    static const WCHAR backslash[] = {'\\',0};
+
+    MSI_GetPropertyW(package, cszSourceDir, package_path, &size);
+    lstrcatW(package_path, backslash);
+    lstrcatW(package_path, source);
+
+    if (GetFileAttributesW(package_path) == INVALID_FILE_ATTRIBUTES)
+    {
+        ERR("Source package does not exist: %s\n", debugstr_w(package_path));
+        return ERROR_FUNCTION_FAILED;
+    }
+
+    TRACE("Installing package %s concurrently\n", debugstr_w(package_path));
+
+    info = do_msidbCAConcurrentInstall(package, type, package_path, target, action);
+
+    return wait_thread_handle(info);
+}
+
 static UINT HANDLE_CustomType1(MSIPACKAGE *package, LPCWSTR source,
                                LPCWSTR target, const INT type, LPCWSTR action)
 {
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c
index 6c8b078..5b7050f 100644
--- a/dlls/msi/tests/install.c
+++ b/dlls/msi/tests/install.c
@@ -1417,13 +1417,10 @@ static void test_concurrentinstall(void)
     MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
 
     r = MsiInstallProductA(msifile, NULL);
-    todo_wine
-    {
-        ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
-        ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
-        ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
-        ok(delete_pf("msitest", FALSE), "File not installed\n");
-    }
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+    ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
+    ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
+    ok(delete_pf("msitest", FALSE), "File not installed\n");
 
     DeleteFile(msifile);
 }




More information about the wine-cvs mailing list