From 8cedb218c314f444612fd3dea67a8834d2f596e9 Mon Sep 17 00:00:00 2001 From: James Hawkins Date: Thu, 29 Mar 2007 02:38:57 -0500 Subject: [PATCH] msi: Load the folder property if available and requested. --- dlls/msi/action.c | 18 +++++++------- dlls/msi/custom.c | 2 +- dlls/msi/files.c | 4 ++-- dlls/msi/format.c | 2 +- dlls/msi/helpers.c | 11 +++++++-- dlls/msi/install.c | 12 +++++----- dlls/msi/msipriv.h | 2 +- dlls/msi/tests/install.c | 52 +++++++++++++++++++++++++++++++++++++++- 8 files changed, 80 insertions(+), 23 deletions(-) diff --git a/dlls/msi/action.c b/dlls/msi/action.c index b328e5dcc91..51d827e6ae2 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -1043,7 +1043,7 @@ static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param) return ERROR_SUCCESS; } - full_path = resolve_folder(package,dir,FALSE,FALSE,&folder); + full_path = resolve_folder(package,dir,FALSE,FALSE,TRUE,&folder); if (!full_path) { ERR("Unable to resolve folder id %s\n",debugstr_w(dir)); @@ -1074,7 +1074,7 @@ static UINT msi_create_directory( MSIPACKAGE* package, LPCWSTR dir ) MSIFOLDER *folder; LPWSTR install_path; - install_path = resolve_folder(package, dir, FALSE, FALSE, &folder); + install_path = resolve_folder(package, dir, FALSE, FALSE, TRUE, &folder); if (!install_path) return ERROR_FUNCTION_FAILED; @@ -1898,7 +1898,7 @@ static UINT ITERATE_CostFinalizeDirectories(MSIRECORD *row, LPVOID param) /* This helper function now does ALL the work */ TRACE("Dir %s ...\n",debugstr_w(name)); - path = resolve_folder(package,name,FALSE,TRUE,NULL); + path = resolve_folder(package,name,FALSE,TRUE,TRUE,NULL); TRACE("resolves to %s\n",debugstr_w(path)); msi_free(path); @@ -1981,7 +1981,7 @@ static UINT msi_check_file_install_states( MSIPACKAGE *package ) comp->ForceLocalState = TRUE; /* calculate target */ - p = resolve_folder(package, comp->Directory, FALSE, FALSE, NULL); + p = resolve_folder(package, comp->Directory, FALSE, FALSE, TRUE, NULL); msi_free(file->TargetPath); @@ -2519,7 +2519,7 @@ static LPWSTR resolve_keypath( MSIPACKAGE* package, MSICOMPONENT *cmp ) { if (!cmp->KeyPath) - return resolve_folder(package,cmp->Directory,FALSE,FALSE,NULL); + return resolve_folder(package,cmp->Directory,FALSE,FALSE,TRUE,NULL); if (cmp->Attributes & msidbComponentAttributesRegistryKeyPath) { @@ -2909,7 +2909,7 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param) helpid = MSI_RecordGetString(row,6); if (helpid) - help = resolve_folder(package,helpid,FALSE,FALSE,NULL); + help = resolve_folder(package,helpid,FALSE,FALSE,TRUE,NULL); res = RegisterTypeLib(tl_struct.ptLib,tl_struct.path,help); msi_free(help); @@ -3008,7 +3008,7 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param) } buffer = MSI_RecordGetString(row,2); - target_folder = resolve_folder(package, buffer,FALSE,FALSE,NULL); + target_folder = resolve_folder(package, buffer,FALSE,FALSE,TRUE,NULL); /* may be needed because of a bug somehwere else */ create_full_pathW(target_folder); @@ -3084,7 +3084,7 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param) { LPWSTR Path; buffer = MSI_RecordGetString(row,12); - Path = resolve_folder(package, buffer, FALSE, FALSE, NULL); + Path = resolve_folder(package, buffer, FALSE, FALSE, TRUE, NULL); if (Path) IShellLinkW_SetWorkingDirectory(sl,Path); msi_free(Path); @@ -3348,7 +3348,7 @@ static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param) if (dirproperty) { - folder = resolve_folder(package, dirproperty, FALSE, FALSE, NULL); + folder = resolve_folder(package, dirproperty, FALSE, FALSE, TRUE, NULL); if (!folder) folder = msi_dup_property( package, dirproperty ); } diff --git a/dlls/msi/custom.c b/dlls/msi/custom.c index 1e3a866ed7a..48a07691c62 100644 --- a/dlls/msi/custom.c +++ b/dlls/msi/custom.c @@ -826,7 +826,7 @@ static UINT HANDLE_CustomType34(MSIPACKAGE *package, LPCWSTR source, memset(&si,0,sizeof(STARTUPINFOW)); - filename = resolve_folder(package, source, FALSE, FALSE, NULL); + filename = resolve_folder(package, source, FALSE, FALSE, TRUE, NULL); if (!filename) return ERROR_FUNCTION_FAILED; diff --git a/dlls/msi/files.c b/dlls/msi/files.c index eb5e4569a99..e9f104335bd 100644 --- a/dlls/msi/files.c +++ b/dlls/msi/files.c @@ -446,7 +446,7 @@ static VOID set_file_source(MSIPACKAGE* package, MSIFILE* file, LPCWSTR path) if (!file->IsCompressed) { LPWSTR p, path; - p = resolve_folder(package, file->Component->Directory, TRUE, FALSE, NULL); + p = resolve_folder(package, file->Component->Directory, TRUE, FALSE, TRUE, NULL); path = build_directory_name(2, p, file->ShortName); if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW( path )) { @@ -845,7 +845,7 @@ static UINT ITERATE_DuplicateFiles(MSIRECORD *row, LPVOID param) { LPCWSTR destkey; destkey = MSI_RecordGetString(row,5); - dest_path = resolve_folder(package, destkey, FALSE,FALSE,NULL); + dest_path = resolve_folder(package, destkey, FALSE, FALSE, TRUE, NULL); if (!dest_path) { /* try a Property */ diff --git a/dlls/msi/format.c b/dlls/msi/format.c index 4cb802e2135..2ea6e233805 100644 --- a/dlls/msi/format.c +++ b/dlls/msi/format.c @@ -122,7 +122,7 @@ static LPWSTR deformat_component(MSIPACKAGE* package, LPCWSTR key, DWORD* sz) comp = get_loaded_component(package,key); if (comp) { - value = resolve_folder(package, comp->Directory, FALSE, FALSE, NULL); + value = resolve_folder(package, comp->Directory, FALSE, FALSE, TRUE, NULL); *sz = (strlenW(value)) * sizeof(WCHAR); } diff --git a/dlls/msi/helpers.c b/dlls/msi/helpers.c index b2968f1c264..7357bd73c53 100644 --- a/dlls/msi/helpers.c +++ b/dlls/msi/helpers.c @@ -221,7 +221,7 @@ static void clean_spaces_from_path( LPWSTR p ) } LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, - BOOL set_prop, MSIFOLDER **folder) + BOOL set_prop, BOOL load_prop, MSIFOLDER **folder) { MSIFOLDER *f; LPWSTR p, path = NULL, parent; @@ -293,6 +293,13 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, return path; } + if (!source && load_prop && (path = msi_dup_property( package, name ))) + { + f->ResolvedTarget = strdupW( path ); + TRACE(" property set to %s\n", debugstr_w(path)); + return path; + } + if (!f->Parent) return path; @@ -300,7 +307,7 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, TRACE(" ! Parent is %s\n", debugstr_w(parent)); - p = resolve_folder(package, parent, source, set_prop, NULL); + p = resolve_folder(package, parent, source, set_prop, load_prop, NULL); if (!source) { TRACE(" TargetDefault = %s\n", debugstr_w(f->TargetDefault)); diff --git a/dlls/msi/install.c b/dlls/msi/install.c index ff6e21f37cb..b6cff6df2c6 100644 --- a/dlls/msi/install.c +++ b/dlls/msi/install.c @@ -163,7 +163,7 @@ static UINT WINAPI MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder, if (!package) return ERROR_INVALID_HANDLE; - path = resolve_folder( package, szFolder, FALSE, FALSE, NULL ); + path = resolve_folder( package, szFolder, FALSE, FALSE, TRUE, NULL ); msiobj_release( &package->hdr ); if (!path) @@ -241,7 +241,7 @@ static UINT MSI_GetSourcePath( MSIHANDLE hInstall, LPCWSTR szFolder, return ERROR_INVALID_PARAMETER; } - path = resolve_folder(package, szFolder, TRUE, FALSE, NULL); + path = resolve_folder(package, szFolder, TRUE, FALSE, TRUE, NULL); msiobj_release( &package->hdr ); TRACE("path = %s\n",debugstr_w(path)); @@ -340,7 +340,7 @@ UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder, attrib & FILE_ATTRIBUTE_READONLY)) return ERROR_FUNCTION_FAILED; - path = resolve_folder(package,szFolder,FALSE,FALSE,&folder); + path = resolve_folder(package,szFolder,FALSE,FALSE,FALSE,&folder); if (!path) return ERROR_DIRECTORY; @@ -355,7 +355,7 @@ UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder, */ msi_free(folder->ResolvedTarget); folder->ResolvedTarget = NULL; - path2 = resolve_folder(package,szFolder,FALSE,TRUE,NULL); + path2 = resolve_folder(package,szFolder,FALSE,TRUE,FALSE,NULL); msi_free(path2); } else @@ -370,7 +370,7 @@ UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder, LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry ) { - path2 = resolve_folder(package, f->Directory, FALSE, TRUE, NULL); + path2 = resolve_folder(package, f->Directory, FALSE, TRUE, FALSE, NULL); msi_free(path2); } @@ -382,7 +382,7 @@ UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder, if (!comp) continue; - p = resolve_folder(package, comp->Directory, FALSE, FALSE, NULL); + p = resolve_folder(package, comp->Directory, FALSE, FALSE, FALSE, NULL); msi_free(file->TargetPath); file->TargetPath = build_directory_name(2, p, file->FileName); diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index d61eab9cab4..55dd2fa9e6b 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -755,7 +755,7 @@ extern LPWSTR msi_dup_record_field(MSIRECORD *row, INT index); extern LPWSTR msi_dup_property(MSIPACKAGE *package, LPCWSTR prop); extern int msi_get_property_int( MSIPACKAGE *package, LPCWSTR prop, int def ); extern LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, - BOOL set_prop, MSIFOLDER **folder); + BOOL set_prop, BOOL load_prop, MSIFOLDER **folder); extern MSICOMPONENT *get_loaded_component( MSIPACKAGE* package, LPCWSTR Component ); extern MSIFEATURE *get_loaded_feature( MSIPACKAGE* package, LPCWSTR Feature ); extern MSIFILE *get_loaded_file( MSIPACKAGE* package, LPCWSTR file ); diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c index 6e42696c2ef..426e1ecb9bf 100644 --- a/dlls/msi/tests/install.c +++ b/dlls/msi/tests/install.c @@ -266,6 +266,25 @@ static const CHAR rof_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\t "Media\tDiskId\n" "1\t1\t\t\tDISK1\t\n"; +static const CHAR sdp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "AllocateRegistrySpace\tNOT Installed\t1550\n" + "CostFinalize\t\t1000\n" + "CostInitialize\t\t800\n" + "FileCost\t\t900\n" + "InstallFiles\t\t4000\n" + "InstallFinalize\t\t6600\n" + "InstallInitialize\t\t1500\n" + "InstallValidate\t\t1400\n" + "LaunchConditions\t\t100\n" + "SetDirProperty\t\t950"; + +static const CHAR sdp_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n" + "s72\ti2\tS64\tS0\tS255\n" + "CustomAction\tAction\n" + "SetDirProperty\t51\tMSITESTDIR\t[CommonFilesFolder]msitest\\\t\n"; + typedef struct _msi_table { const CHAR *filename; @@ -376,6 +395,19 @@ static const msi_table rof_tables[] = ADD_TABLE(property), }; +static const msi_table sdp_tables[] = +{ + ADD_TABLE(rof_component), + ADD_TABLE(directory), + ADD_TABLE(rof_feature), + ADD_TABLE(rof_feature_comp), + ADD_TABLE(rof_file), + ADD_TABLE(sdp_install_exec_seq), + ADD_TABLE(sdp_custom_action), + ADD_TABLE(rof_media), + ADD_TABLE(property), +}; + /* cabinet definitions */ /* make the max size large so there is only one cab file */ @@ -1195,7 +1227,6 @@ static void test_readonlyfile(void) lstrcat(path, "\\maximus"); file = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL); - if (file == INVALID_HANDLE_VALUE) printf("didn't work here: %d\n", GetLastError()); WriteFile(file, "readonlyfile", 20, &size, NULL); CloseHandle(file); @@ -1212,6 +1243,24 @@ static void test_readonlyfile(void) DeleteFile(msifile); } +static void test_setdirproperty(void) +{ + UINT r; + + CreateDirectoryA("msitest", NULL); + create_file("msitest\\maximus", 500); + create_database(msifile, sdp_tables, sizeof(sdp_tables) / sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r); + ok(delete_pf("Common Files\\msitest\\maximus", TRUE), "File not installed\n"); + ok(delete_pf("Common Files\\msitest", FALSE), "File not installed\n"); + + DeleteFile(msifile); +} + START_TEST(install) { DWORD len; @@ -1238,6 +1287,7 @@ START_TEST(install) test_samesequence(); test_uiLevelFlags(); test_readonlyfile(); + test_setdirproperty(); SetCurrentDirectoryA(prev_path); }