msi: Set the PrimaryVolumePath and PrimaryVolumeSpaceAvailable properties.

Hans Leidekker hans at codeweavers.com
Thu May 9 02:49:10 CDT 2013


---
 dlls/msi/action.c        |   48 +++++++++++++++++----
 dlls/msi/tests/install.c |  103 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 142 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..9fd5597 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,34 @@ static void test_mixed_package(void)
 
 error:
     DeleteFileA( msifile );
-    return;
+}
+
+static void test_volume_props(void)
+{
+    UINT r;
+    LONG res;
+    HKEY hkey;
+
+    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 +6484,7 @@ START_TEST(install)
     test_command_line_parsing();
     test_upgrade_code();
     test_mixed_package();
+    test_volume_props();
 
     DeleteFileA(log_file);
 
-- 
1.7.10.4






More information about the wine-patches mailing list