Hans Leidekker : msi: Execute concurrent installers in a separate process.

Alexandre Julliard julliard at winehq.org
Mon Jan 21 13:52:24 CST 2013


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

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Mon Jan 21 16:24:59 2013 +0100

msi: Execute concurrent installers in a separate process.

---

 dlls/msi/custom.c |  133 +++++++++++++++++-----------------------------------
 1 files changed, 44 insertions(+), 89 deletions(-)

diff --git a/dlls/msi/custom.c b/dlls/msi/custom.c
index a33f19d..4366409 100644
--- a/dlls/msi/custom.c
+++ b/dlls/msi/custom.c
@@ -619,43 +619,6 @@ static DWORD WINAPI DllThread( LPVOID arg )
     return rc;
 }
 
-static DWORD 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);
-
-    release_custom_action_data(info);
-
-    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 )
 {
@@ -690,58 +653,6 @@ 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->refs = 2; /* 1 for our caller and 1 for thread we created */
-    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)
-    {
-        /* release both references */
-        release_custom_action_data( info );
-        release_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;
-
-    size = MAX_PATH;
-    msi_get_property(package->db, szSourceDir, package_path, &size);
-    lstrcatW(package_path, szBackSlash);
-    lstrcatW(package_path, source);
-
-    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)
 {
@@ -911,6 +822,50 @@ static UINT HANDLE_CustomType19(MSIPACKAGE *package, LPCWSTR source,
     return ERROR_INSTALL_FAILURE;
 }
 
+static UINT HANDLE_CustomType23(MSIPACKAGE *package, LPCWSTR source,
+                                LPCWSTR target, const INT type, LPCWSTR action)
+{
+    static const WCHAR msiexecW[] = {'m','s','i','e','x','e','c',0};
+    static const WCHAR paramsW[] = {'/','q','b',' ','/','i',' '};
+    WCHAR *dir, *arg, *p;
+    UINT len_src, len_dir, len_tgt, len = sizeof(paramsW)/sizeof(paramsW[0]);
+    HANDLE handle;
+
+    if (!(dir = msi_dup_property( package->db, szOriginalDatabase ))) return ERROR_OUTOFMEMORY;
+    if (!(p = strrchrW( dir, '\\' )) && !(p = strrchrW( dir, '/' )))
+    {
+        msi_free( dir );
+        return ERROR_FUNCTION_FAILED;
+    }
+    *p = 0;
+    len_dir = p - dir;
+    len_src = strlenW( source );
+    len_tgt = strlenW( target );
+    if (!(arg = msi_alloc( (len + len_dir + len_src + len_tgt + 5) * sizeof(WCHAR) )))
+    {
+        msi_free( dir );
+        return ERROR_OUTOFMEMORY;
+    }
+    memcpy( arg, paramsW, sizeof(paramsW) );
+    arg[len++] = '"';
+    memcpy( arg + len, dir, len_dir * sizeof(WCHAR) );
+    len += len_dir;
+    arg[len++] = '\\';
+    memcpy( arg + len, source, len_src * sizeof(WCHAR) );
+    len += len_src;
+    arg[len++] = '"';
+    arg[len++] = ' ';
+    strcpyW( arg + len, target );
+
+    TRACE("installing %s concurrently\n", debugstr_w(source));
+
+    handle = execute_command( msiexecW, arg, dir );
+    msi_free( dir );
+    msi_free( arg );
+    if (handle == INVALID_HANDLE_VALUE) return ERROR_SUCCESS;
+    return wait_process_handle( package, type, handle, action );
+}
+
 static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source,
                                 LPCWSTR target, const INT type, LPCWSTR action)
 {




More information about the wine-cvs mailing list