diff -u ../../../../wine-1.0-rc4/dlls/msi/action.c ./action.c --- ../../../../wine-1.0-rc4/dlls/msi/action.c 2008-06-06 10:24:30.000000000 -0500 +++ ./action.c 2008-06-06 11:12:15.000000000 -0500 @@ -705,6 +705,21 @@ msi_parse_command_line( package, szCommandLine ); + { + static const WCHAR szcdcache[] = { 'C','D','C','A','C','H','E',0 }; + static const WCHAR szzero[] = { '0',0 }; + static const WCHAR szprodname[] = { 'P','r','o','d','u','c','t','N','a','m','e',0 }; + static const WCHAR szword2003[] = { + 'M','i','c','r','o','s','o','f','t',' ','O','f','f','i','c','e',' ', + 'W','o','r','d',' ','V','i','e','w','e','r',' ','2','0','0','3',0}; + LPWSTR prod; + + prod = msi_dup_property( package, szprodname ); + if (!lstrcmpW( prod, szword2003 )) + MSI_SetPropertyW( package, szcdcache, szzero ); + msi_free( prod ); + } + msi_apply_transforms( package ); msi_apply_patches( package ); @@ -4117,6 +4132,8 @@ return execute_script(package,INSTALL_SCRIPT); } +int global_deferred=0; + static UINT msi_unpublish_product(MSIPACKAGE *package) { LPWSTR remove = NULL; @@ -4182,7 +4199,11 @@ return rc; /* then handle Commit Actions */ + TRACE("setting global_deferred=1\n"); + global_deferred=1; rc = execute_script(package,COMMIT_SCRIPT); + global_deferred=0; + TRACE("setting global_deferred=0\n"); return rc; } diff -u ../../../../wine-1.0-rc4/dlls/msi/custom.c ./custom.c --- ../../../../wine-1.0-rc4/dlls/msi/custom.c 2008-06-06 10:24:30.000000000 -0500 +++ ./custom.c 2008-06-06 11:12:15.000000000 -0500 @@ -228,6 +228,7 @@ if (type & msidbCustomActionTypeInScript) { + TRACE("msidbCustomActionTypeInScript\n"); if (type & msidbCustomActionTypeNoImpersonate) WARN("msidbCustomActionTypeNoImpersonate not handled\n"); @@ -815,6 +816,8 @@ return info; } +extern int global_deferred; + static msi_custom_action_info *do_msidbCAConcurrentInstall( MSIPACKAGE *package, INT type, LPCWSTR source, LPCWSTR target, LPCWSTR action) { @@ -877,6 +880,12 @@ WCHAR tmp_file[MAX_PATH]; UINT r; + if (type & msidbCustomActionTypeInScript) + { + TRACE("setting global_deferred=1\n"); + global_deferred=1; + } + r = store_binary_to_temp(package, source, tmp_file); if (r != ERROR_SUCCESS) return r; @@ -892,7 +901,13 @@ info = do_msidbCustomActionTypeDll( package, type, tmp_file, target, action ); - return wait_thread_handle( info ); + r = wait_thread_handle( info ); + if (type & msidbCustomActionTypeInScript) + { + TRACE("setting global_deferred=0\n"); + global_deferred=0; + } + return r; } static UINT HANDLE_CustomType2(MSIPACKAGE *package, LPCWSTR source, diff -u ../../../../wine-1.0-rc4/dlls/msi/helpers.c ./helpers.c --- ../../../../wine-1.0-rc4/dlls/msi/helpers.c 2008-06-06 10:24:30.000000000 -0500 +++ ./helpers.c 2008-06-06 11:12:15.000000000 -0500 @@ -312,9 +312,26 @@ p = resolve_folder(package, parent, source, set_prop, load_prop, NULL); if (!source) { + WCHAR szShellObjectFolder[] = +{'S','H','E','L','L','_','O','B','J','E','C','T','_','F','O','L','D','E','R',0}; + TRACE(" TargetDefault = %s\n", debugstr_w(f->TargetDefault)); - path = build_directory_name( 3, p, f->TargetDefault, NULL ); + /* hack for GUPTA */ + if (f->TargetDefault && strcmpW( f->TargetDefault, szShellObjectFolder)==0) + { + LPWSTR sof = msi_dup_property(package,szShellObjectFolder); + if (sof) + { + path = build_directory_name(3, p, sof, NULL); + msi_free(sof); + } + else + path = build_directory_name(3, p, f->TargetDefault, NULL); + } + else + path = build_directory_name(3, p, f->TargetDefault, NULL); + clean_spaces_from_path( path ); f->ResolvedTarget = strdupW( path ); TRACE("target -> %s\n", debugstr_w(path)); @@ -323,6 +340,8 @@ } else { + static const WCHAR wszCatalystIntlFolder_1033[] = {'C','a','t','a','l','y','s','t','I','n','t','l','F','o','l','d','e','r','_','1','0','3','3',0}; + /* source may be in a few different places ... check each of them */ path = NULL; @@ -338,7 +357,10 @@ } /* try the short path directory */ - if (!path && f->SourceShortPath) + /* CODEWEAVERS HACK for Office2007: don't resolve short path for this + * folder since it causes it to be solved to the wrong location and + * branding.xml not to be copied. */ + if (!path && strcmpW(name, wszCatalystIntlFolder_1033) && f->SourceShortPath) { path = build_directory_name( 3, p, f->SourceShortPath, NULL ); if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW( path )) diff -u ../../../../wine-1.0-rc4/dlls/msi/install.c ./install.c --- ../../../../wine-1.0-rc4/dlls/msi/install.c 2008-06-06 10:24:30.000000000 -0500 +++ ./install.c 2008-06-06 11:12:15.000000000 -0500 @@ -656,6 +656,7 @@ * Not in the state: FALSE * */ +extern int global_deferred; BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode) { MSIPACKAGE *package; @@ -696,6 +697,7 @@ case MSIRUNMODE_SCHEDULED: r = package->scheduled_action_running; + if (global_deferred) r = TRUE; break; case MSIRUNMODE_ROLLBACK: @@ -704,6 +706,7 @@ case MSIRUNMODE_COMMIT: r = package->commit_action_running; + if (global_deferred) r = TRUE; break; default: @@ -711,6 +714,7 @@ r = TRUE; } + TRACE("%d -> %d\n", iRunMode, r); return r; } diff -u ../../../../wine-1.0-rc4/dlls/msi/msi.c ./msi.c --- ../../../../wine-1.0-rc4/dlls/msi/msi.c 2008-06-06 10:24:30.000000000 -0500 +++ ./msi.c 2008-06-06 11:12:15.000000000 -0500 @@ -1812,12 +1812,28 @@ HKEY hkey; INSTALLSTATE r; BOOL missing = FALSE; + BOOL try_oldkey = FALSE; TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature)); if (!szProduct || !szFeature) return INSTALLSTATE_INVALIDARG; + /* HACK: Pretend that the VBAFiles feature isn't present. + VBAFiles seems to depend on Internet Explorer, and displays + an error at Project startup "This feature depends on Internet Explorer..." */ + if (1) { + static const WCHAR p[] = { + '{','9','0','3','B','0','4','0','9','-', + '6','0','0','0','-','1','1','D','3','-', + '8','C','F','E','-','0','1','5','0','0', + '4','8','3','8','3','C','9','}',0}; + static const WCHAR f[] = { + 'V','B','A','F','i','l','e','s',0}; + if ( !lstrcmpW(p, szProduct) && !lstrcmpW(f, szFeature)) + return INSTALLSTATE_UNKNOWN; + } + if (!squash_guid( szProduct, squishProduct )) return INSTALLSTATE_INVALIDARG; @@ -1842,6 +1858,7 @@ if (rc != ERROR_SUCCESS) return INSTALLSTATE_ADVERTISED; +cxhack: components = msi_reg_get_val_str( hkey, szFeature ); RegCloseKey(hkey); @@ -1858,6 +1875,19 @@ break; msi_free(components); + /* CODEWEAVERS HACK: Pre-6.3 versions of MSI put incorrect data in + * the values for the User Data Features key, so try again with + * the Features key, which should have correct values */ + if (!try_oldkey) + { + FIXME("bad feature format, trying location used by pre-6.3 versions of MSI\n"); + rc = MSIREG_OpenFeaturesKey(szProduct, &hkey, FALSE); + if (rc == ERROR_SUCCESS) + { + try_oldkey = TRUE; + goto cxhack; + } + } return INSTALLSTATE_BADCONFIG; } diff -u ../../../../wine-1.0-rc4/dlls/msi/registry.c ./registry.c --- ../../../../wine-1.0-rc4/dlls/msi/registry.c 2008-06-06 10:24:30.000000000 -0500 +++ ./registry.c 2008-06-06 11:12:15.000000000 -0500 @@ -695,7 +695,32 @@ if (create) rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key); else + { rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); + /* CODEWEAVERS HACK: Pre-6.3 versions of MSI put components in a different + * path - copy them to the right location */ + if (rc == ERROR_FILE_NOT_FOUND) + { + HKEY key_src; + rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, szInstaller_Components, &key_src); + if (rc == ERROR_SUCCESS) + { + HKEY key_dst; + WCHAR keypath2[0x200]; + static const WCHAR wszBlank[] = { 0 }; + sprintfW(keypath2, szUserDataComp_fmt, usersid, wszBlank); + rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath2, &key_dst); + if (rc == ERROR_SUCCESS) + { + rc = SHCopyKeyW(key_src, NULL, key_dst, 0); + if (rc == ERROR_SUCCESS) + rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); + RegCloseKey(key_dst); + } + RegCloseKey(key_src); + } + } + } LocalFree(usersid); return rc; @@ -750,7 +775,47 @@ if (create) rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key); else + { rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); + /* CODEWEAVERS HACK: Previous versions of MSI put components in a different + * path - copy them to the right location */ + if (rc == ERROR_FILE_NOT_FOUND) + { + HKEY key_src; + rc = MSIREG_OpenUserFeaturesKey(szProduct, &key_src, FALSE); + if (rc == ERROR_SUCCESS) + { + HKEY key_dst; + static const WCHAR szFeatures[] = {'\\','F','e','a','t','u','r','e','s',0}; + WCHAR keypath2[0x209]; + strcpyW(keypath2, keypath); + strcatW(keypath2, szFeatures); + rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath2, &key_dst); + if (rc == ERROR_SUCCESS) + { + rc = SHCopyKeyW(key_src, NULL, key_dst, 0); + if (rc == ERROR_SUCCESS) + { + rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); + if (rc == ERROR_SUCCESS) + { + static const WCHAR szInstallProperties[] = {'I','n','s','t','a','l','l','P','r','o','p','e','r','t','i','e','s',0}; + HKEY key_ip; + if (RegCreateKeyW(*key, szInstallProperties, &key_ip) == ERROR_SUCCESS) + { + static const WCHAR szWindowsInstaller[] = {'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0}; + DWORD dw = 1; + RegSetValueExW(key_ip, szWindowsInstaller, 0, REG_DWORD, (const BYTE *)&dw, sizeof(dw)); + RegCloseKey(key_ip); + } + } + } + RegCloseKey(key_dst); + } + RegCloseKey(key_src); + } + } + } LocalFree(usersid); return rc; @@ -953,6 +1018,7 @@ { WCHAR squished_pc[GUID_SIZE]; WCHAR keypath[0x200]; + DWORD ret; TRACE("%s\n", debugstr_w(szComponent)); @@ -966,7 +1032,38 @@ if (create) return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key); - return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); + /* CODEWEAVERS HACK: Previous versions of MSI put components in a different + * path - copy them to the right location */ + ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); + if (ret == ERROR_FILE_NOT_FOUND) + { + static const WCHAR szInstaller_Components[] = { + 'S','o','f','t','w','a','r','e','\\', + 'M','i','c','r','o','s','o','f','t','\\', + 'W','i','n','d','o','w','s','\\', + 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', + 'I','n','s','t','a','l','l','e','r','\\', + 'C','o','m','p','o','n','e','n','t','s',0}; + static const WCHAR szInstaller_LocalSystemComponent[] = { + 'S','o','f','t','w','a','r','e','\\', + 'M','i','c','r','o','s','o','f','t','\\', + 'W','i','n','d','o','w','s','\\', + 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', + 'I','n','s','t','a','l','l','e','r','\\', + 'U','s','e','r','D','a','t','a','\\', + 'S','-','1','-','5','-','1','8','\\', + 'C','o','m','p','o','n','e','n','t','s',0}; + HKEY key_dst; + ret = RegCreateKeyW(HKEY_LOCAL_MACHINE, szInstaller_LocalSystemComponent, &key_dst); + if (ret != ERROR_SUCCESS) + return ret; + ret = SHCopyKeyW(HKEY_LOCAL_MACHINE, szInstaller_Components, key_dst, 0); + RegCloseKey(key_dst); + if (ret != ERROR_SUCCESS) + return ERROR_FILE_NOT_FOUND; + ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); + } + return ret; } UINT MSIREG_OpenLocalClassesProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create) Common subdirectories: ../../../../wine-1.0-rc4/dlls/msi/tests and ./tests