- CustomAction 35 should call SetTargetPath not just set the property. - TARGETDIR and SOURCEDIR may not be entries 0 in the directory tables. So when resolving the folder we need to seek them out. - When we handle SetTargetPath we need to be sure to recalculate the resulting paths as things with the now set Directory as the parent will change.
diff --git a/dlls/msi/action.c b/dlls/msi/action.c index 3cfab5d..aedf203 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c
@@ -1300,6 +1300,10 @@ rc = HANDLE_CustomType34(package,source,target,type); break; case 35: /* Directory set with formatted text. */ + deformat_string(package,target,&deformated); + MSI_SetTargetPathW(package, source, deformated); + HeapFree(GetProcessHeap(),0,deformated); + break; case 51: /* Property set with formatted text. */ deformat_string(package,target,&deformated); rc = MSI_SetPropertyW(package,source,deformated); @@ -2322,7 +2326,14 @@ MSI_SetPropertyW(package,cszTargetDir,path); } if (folder) - *folder = &(package->folders[0]); + { + for (i = 0; i < package->loaded_folders; i++) + { + if (strcmpW(package->folders[i].Directory,name)==0) + break; + } + *folder = &(package->folders[i]); + } return path; } else @@ -2339,7 +2350,14 @@ } } if (folder) - *folder = &(package->folders[0]); + { + for (i = 0; i < package->loaded_folders; i++) + { + if (strcmpW(package->folders[i].Directory,name)==0) + break; + } + *folder = &(package->folders[i]); + } return path; } } @@ -5076,6 +5094,7 @@ { DWORD i; LPWSTR path = NULL; + LPWSTR path2 = NULL; INT len; MSIFOLDER *folder; @@ -5091,9 +5110,12 @@ return ERROR_FUNCTION_FAILED; path = resolve_folder(package,szFolder,FALSE,FALSE,&folder); + if (!path) return ERROR_INVALID_PARAMETER; - HeapFree(GetProcessHeap(),0,path); + + if (folder->Property) + HeapFree(GetProcessHeap(),0,folder->Property); len = strlenW(szFolderPath); @@ -5107,15 +5129,34 @@ else folder->Property = dupstrW(szFolderPath); - for (i = 0; i < package->loaded_folders; i++) - package->folders[i].ResolvedTarget=NULL; - - for (i = 0; i < package->loaded_folders; i++) + if (strcmpiW(path, szFolderPath) == 0) { - path = resolve_folder(package, package->folders[i].Directory, FALSE, - TRUE, NULL); - HeapFree(GetProcessHeap(),0,path); + /* + * Resolved Target has not really changed, so just + * set this folder and do not recalculate everything. + */ + HeapFree(GetProcessHeap(),0,folder->ResolvedTarget); + folder->ResolvedTarget = NULL; + path2 = resolve_folder(package,szFolder,FALSE,TRUE,NULL); + HeapFree(GetProcessHeap(),0,path2); } + else + { + for (i = 0; i < package->loaded_folders; i++) + { + if (package->folders[i].ResolvedTarget) + HeapFree(GetProcessHeap(),0,package->folders[i].ResolvedTarget); + package->folders[i].ResolvedTarget=NULL; + } + + for (i = 0; i < package->loaded_folders; i++) + { + path2=resolve_folder(package, package->folders[i].Directory, FALSE, + TRUE, NULL); + HeapFree(GetProcessHeap(),0,path2); + } + } + HeapFree(GetProcessHeap(),0,path); return ERROR_SUCCESS; }