Module: wine Branch: master Commit: 98eafa870c619dbf78ae28feb8f5abc904de5cb9 URL: http://source.winehq.org/git/wine.git/?a=commit;h=98eafa870c619dbf78ae28feb8...
Author: James Hawkins truiken@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); }