Module: wine Branch: master Commit: 10975967dfcca8956f4e9aead47f7562d731010b URL: http://source.winehq.org/git/wine.git/?a=commit;h=10975967dfcca8956f4e9aead4...
Author: Hans Leidekker hans@codeweavers.com Date: Thu May 9 09:49:10 2013 +0200
msi: Set the PrimaryVolumePath and PrimaryVolumeSpaceAvailable properties.
---
dlls/msi/action.c | 48 ++++++++++++++++++---- dlls/msi/tests/install.c | 101 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 140 insertions(+), 9 deletions(-)
diff --git a/dlls/msi/action.c b/dlls/msi/action.c index cf03fa2..f519f4b 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -2365,14 +2365,21 @@ void msi_resolve_target_folder( MSIPACKAGE *package, const WCHAR *name, BOOL loa
static UINT ACTION_CostFinalize(MSIPACKAGE *package) { - static const WCHAR query[] = { - 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - '`','C','o','n','d','i','t','i','o','n','`',0}; - static const WCHAR szOutOfDiskSpace[] = { - 'O','u','t','O','f','D','i','s','k','S','p','a','c','e',0}; + static const WCHAR query[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + '`','C','o','n','d','i','t','i','o','n','`',0}; + static const WCHAR szOutOfDiskSpace[] = + {'O','u','t','O','f','D','i','s','k','S','p','a','c','e',0}; + static const WCHAR szPrimaryFolder[] = + {'P','R','I','M','A','R','Y','F','O','L','D','E','R',0}; + static const WCHAR szPrimaryVolumePath[] = + {'P','r','i','m','a','r','y','V','o','l','u','m','e','P','a','t','h',0}; + static const WCHAR szPrimaryVolumeSpaceAvailable[] = + {'P','r','i','m','a','r','y','V','o','l','u','m','e','S','p','a','c','e', + 'A','v','a','i','l','a','b','l','e',0}; MSICOMPONENT *comp; MSIQUERY *view; - LPWSTR level; + WCHAR *level, *primary_key, *primary_folder; UINT rc;
TRACE("Building directory properties\n"); @@ -2415,10 +2422,35 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package) msi_set_property( package->db, szCostingComplete, szOne, -1 ); /* set default run level if not set */ level = msi_dup_property( package->db, szInstallLevel ); - if (!level) - msi_set_property( package->db, szInstallLevel, szOne, -1 ); + if (!level) msi_set_property( package->db, szInstallLevel, szOne, -1 ); msi_free(level);
+ if ((primary_key = msi_dup_property( package->db, szPrimaryFolder ))) + { + if ((primary_folder = msi_dup_property( package->db, primary_key ))) + { + if (((primary_folder[0] >= 'A' && primary_folder[0] <= 'Z') || + (primary_folder[0] >= 'a' && primary_folder[0] <= 'z')) && primary_folder[1] == ':') + { + ULARGE_INTEGER free; + + primary_folder[2] = 0; + if (GetDiskFreeSpaceExW( primary_folder, &free, NULL, NULL )) + { + static const WCHAR fmtW[] = {'%','l','u',0}; + WCHAR buf[21]; + + sprintfW( buf, fmtW, free.QuadPart / 512 ); + msi_set_property( package->db, szPrimaryVolumeSpaceAvailable, buf, -1 ); + } + toupperW( primary_folder[0] ); + msi_set_property( package->db, szPrimaryVolumePath, primary_folder, 2 ); + } + msi_free( primary_folder ); + } + msi_free( primary_key ); + } + /* FIXME: check volume disk space */ msi_set_property( package->db, szOutOfDiskSpace, szZero, -1 );
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c index f343c02..e910fa0 100644 --- a/dlls/msi/tests/install.c +++ b/dlls/msi/tests/install.c @@ -158,6 +158,7 @@ static const CHAR property_dat[] = "Property\tValue\n" "InstallMode\tTypical\n" "Manufacturer\tWine\n" "PIDTemplate\t12345<###-%%%%%%%>@@@@@\n" + "PRIMARYFOLDER\tTARGETDIR\n" "ProductCode\t{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}\n" "ProductID\tnone\n" "ProductLanguage\t1033\n" @@ -1288,6 +1289,65 @@ static const char mixed_install_exec_seq_dat[] = "PublishProduct\t\t1300\n" "InstallFinalize\t\t1400\n";
+static const char vp_file_dat[] = + "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "volumeprop\tcomp\tvolumeprop.txt\t1000\t\t\t8192\t1\n"; + +static const char vp_feature_dat[] = + "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n" + "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n" + "Feature\tFeature\n" + "feature\t\t\t\t1\t2\tMSITESTDIR\t0\n"; + +static const char vp_feature_comp_dat[] = + "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "feature\tcomp\n"; + +static const char vp_component_dat[] = + "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "comp\t{24364AE7-5B7F-496C-AF5A-54893639C567}\tMSITESTDIR\t0\t\tvolumeprop\n"; + +static const char vp_custom_action_dat[] = + "Action\tType\tSource\tTarget\tISComments\n" + "s72\ti2\tS64\tS0\tS255\n" + "CustomAction\tAction\n" + "TestPrimaryVolumePath0\t19\t\tPrimaryVolumePath set before CostFinalize\t\n" + "TestPrimaryVolumeSpaceAvailable0\t19\t\tPrimaryVolumeSpaceAvailable set before CostFinalize\t\n" + "TestPrimaryVolumePath1\t19\t\tPrimaryVolumePath set before InstallValidate\t\n" + "TestPrimaryVolumeSpaceAvailable1\t19\t\tPrimaryVolumeSpaceAvailable not set before InstallValidate\t\n" + "TestPrimaryVolumePath2\t19\t\tPrimaryVolumePath not set after InstallValidate\t\n" + "TestPrimaryVolumeSpaceAvailable2\t19\t\tPrimaryVolumeSpaceAvailable not set after InstallValidate\t\n"; + +static const char vp_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t200\n" + "FileCost\t\t300\n" + "TestPrimaryVolumePath0\tPrimaryVolumePath AND NOT REMOVE\t400\n" + "TestPrimaryVolumeSpaceAvailable0\tPrimaryVolumeSpaceAvailable AND NOT REMOVE\t500\n" + "CostFinalize\t\t600\n" + "TestPrimaryVolumePath1\tPrimaryVolumePath AND NOT REMOVE\t600\n" + "TestPrimaryVolumeSpaceAvailable1\tNOT PrimaryVolumeSpaceAvailable AND NOT REMOVE\t800\n" + "InstallValidate\t\t900\n" + "TestPrimaryVolumePath2\tNOT PrimaryVolumePath AND NOT REMOVE\t1000\n" + "TestPrimaryVolumeSpaceAvailable2\tNOT PrimaryVolumeSpaceAvailable AND NOT REMOVE\t1100\n" + "InstallInitialize\t\t1200\n" + "ProcessComponents\t\t1300\n" + "RemoveFiles\t\t1400\n" + "InstallFiles\t\t1500\n" + "RegisterProduct\t\t1600\n" + "PublishFeatures\t\t1700\n" + "PublishProduct\t\t1800\n" + "InstallFinalize\t\t1900\n"; + typedef struct _msi_table { const CHAR *filename; @@ -1991,6 +2051,19 @@ static const msi_table mixed_tables[] = ADD_TABLE(property) };
+static const msi_table vp_tables[] = +{ + ADD_TABLE(directory), + ADD_TABLE(vp_file), + ADD_TABLE(vp_component), + ADD_TABLE(vp_feature), + ADD_TABLE(vp_feature_comp), + ADD_TABLE(vp_custom_action), + ADD_TABLE(vp_install_exec_seq), + ADD_TABLE(media), + ADD_TABLE(property) +}; + /* cabinet definitions */
/* make the max size large so there is only one cab file */ @@ -6293,7 +6366,32 @@ static void test_mixed_package(void)
error: DeleteFileA( msifile ); - return; +} + +static void test_volume_props(void) +{ + UINT r; + + if (is_process_limited()) + { + skip("process is limited\n"); + return; + } + CreateDirectoryA("msitest", NULL); + create_file("msitest\volumeprop.txt", 1000); + create_database(msifile, vp_tables, sizeof(vp_tables)/sizeof(msi_table)); + + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + + r = MsiInstallProductA(msifile, NULL); + ok(r == ERROR_SUCCESS, "got %u\n", r); + + r = MsiInstallProductA(msifile, "REMOVE=ALL"); + ok(r == ERROR_SUCCESS, "got %u\n", r); + + DeleteFileA("msitest\volumeprop.txt"); + RemoveDirectoryA("msitest"); + DeleteFile(msifile); }
START_TEST(install) @@ -6384,6 +6482,7 @@ START_TEST(install) test_command_line_parsing(); test_upgrade_code(); test_mixed_package(); + test_volume_props();
DeleteFileA(log_file);