msi: Remove the product reference when a shared component is unregistered.

Hans Leidekker hans at codeweavers.com
Mon Mar 3 03:50:34 CST 2014


---
 dlls/msi/action.c        |  24 ++++++-
 dlls/msi/tests/install.c | 159 ++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 173 insertions(+), 10 deletions(-)

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index faf462e..0d9fb69 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -3564,9 +3564,29 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
             if (comp->num_clients <= 0)
             {
                 if (package->Context == MSIINSTALLCONTEXT_MACHINE)
-                    MSIREG_DeleteUserDataComponentKey( comp->ComponentId, szLocalSid );
+                    rc = MSIREG_DeleteUserDataComponentKey( comp->ComponentId, szLocalSid );
                 else
-                    MSIREG_DeleteUserDataComponentKey( comp->ComponentId, NULL );
+                    rc = MSIREG_DeleteUserDataComponentKey( comp->ComponentId, NULL );
+
+                if (rc != ERROR_SUCCESS) WARN( "failed to delete component key %u\n", rc );
+            }
+            else
+            {
+                LONG res;
+
+                if (package->Context == MSIINSTALLCONTEXT_MACHINE)
+                    rc = MSIREG_OpenUserDataComponentKey( comp->ComponentId, szLocalSid, &hkey, FALSE );
+                else
+                    rc = MSIREG_OpenUserDataComponentKey( comp->ComponentId, NULL, &hkey, FALSE );
+
+                if (rc != ERROR_SUCCESS)
+                {
+                    WARN( "failed to open component key %u\n", rc );
+                    continue;
+                }
+                res = RegDeleteValueW( hkey, squished_pc );
+                RegCloseKey(hkey);
+                if (res) WARN( "failed to delete component value %d\n", res );
             }
         }
 
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c
index 45c6a5f..3068c12 100644
--- a/dlls/msi/tests/install.c
+++ b/dlls/msi/tests/install.c
@@ -1167,6 +1167,75 @@ static const char vp_install_exec_seq_dat[] =
     "PublishProduct\t\t1800\n"
     "InstallFinalize\t\t1900\n";
 
+static const char shc_property_dat[] =
+    "Property\tValue\n"
+    "s72\tl0\n"
+    "Property\tProperty\n"
+    "INSTALLLEVEL\t3\n"
+    "ProductCode\t{5CD99CD0-69C7-409B-9905-82DD743CC840}\n"
+    "ProductName\tMSITEST\n"
+    "ProductVersion\t1.1.1\n"
+    "MSIFASTINSTALL\t1\n";
+
+static const char shc2_property_dat[] =
+    "Property\tValue\n"
+    "s72\tl0\n"
+    "Property\tProperty\n"
+    "INSTALLLEVEL\t3\n"
+    "ProductCode\t{4CEFADE5-DAFB-4C21-8EF2-4ED4F139F340}\n"
+    "ProductName\tMSITEST2\n"
+    "ProductVersion\t1.1.1\n"
+    "MSIFASTINSTALL\t1\n";
+
+static const char shc_file_dat[] =
+    "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
+    "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
+    "File\tFile\n"
+    "sharedcomponent\tsharedcomponent\tsharedcomponent.txt\t1000\t\t\t8192\t1\n";
+
+static const char shc_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 shc_feature_comp_dat[] =
+    "Feature_\tComponent_\n"
+    "s38\ts72\n"
+    "FeatureComponents\tFeature_\tComponent_\n"
+    "feature\tsharedcomponent\n";
+
+static const char shc_component_dat[] =
+    "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
+    "s72\tS38\ts72\ti2\tS255\tS72\n"
+    "Component\tComponent\n"
+    "sharedcomponent\t{900A4ACB-DC6F-4795-A04B-81B530183D41}\tMSITESTDIR\t0\t\tsharedcomponent\n";
+
+static const char shc_custom_action_dat[] =
+    "Action\tType\tSource\tTarget\tISComments\n"
+    "s72\ti2\tS64\tS0\tS255\n"
+    "CustomAction\tAction\n"
+    "TestComponentAction\t19\t\twrong component action on install\t\n";
+
+static const char shc_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"
+    "CostFinalize\t\t600\n"
+    "InstallValidate\t\t900\n"
+    "InstallInitialize\t\t1200\n"
+    "ProcessComponents\t\t1300\n"
+    "RemoveFiles\t\t1400\n"
+    "InstallFiles\t\t1500\n"
+    "TestComponentAction\tNOT REMOVE AND ($sharedcomponent <> 3)\t1600\n"
+    "RegisterProduct\t\t1700\n"
+    "PublishFeatures\t\t1800\n"
+    "PublishProduct\t\t1900\n"
+    "InstallFinalize\t\t2000\n";
+
 typedef struct _msi_table
 {
     const CHAR *filename;
@@ -1806,6 +1875,32 @@ static const msi_table vp_tables[] =
     ADD_TABLE(property)
 };
 
+static const msi_table shc_tables[] =
+{
+    ADD_TABLE(media),
+    ADD_TABLE(directory),
+    ADD_TABLE(shc_file),
+    ADD_TABLE(shc_component),
+    ADD_TABLE(shc_feature),
+    ADD_TABLE(shc_feature_comp),
+    ADD_TABLE(shc_custom_action),
+    ADD_TABLE(shc_install_exec_seq),
+    ADD_TABLE(shc_property)
+};
+
+static const msi_table shc2_tables[] =
+{
+    ADD_TABLE(media),
+    ADD_TABLE(directory),
+    ADD_TABLE(shc_file),
+    ADD_TABLE(shc_component),
+    ADD_TABLE(shc_feature),
+    ADD_TABLE(shc_feature_comp),
+    ADD_TABLE(shc_custom_action),
+    ADD_TABLE(shc_install_exec_seq),
+    ADD_TABLE(shc2_property)
+};
+
 /* cabinet definitions */
 
 /* make the max size large so there is only one cab file */
@@ -2263,7 +2358,8 @@ static void write_file(const CHAR *filename, const char *data, int data_size)
     CloseHandle(hf);
 }
 
-static void write_msi_summary_info(MSIHANDLE db, INT version, INT wordcount, const char *template)
+static void write_msi_summary_info(MSIHANDLE db, INT version, INT wordcount,
+                                   const char *template, const char *packagecode)
 {
     MSIHANDLE summary;
     UINT r;
@@ -2274,8 +2370,7 @@ static void write_msi_summary_info(MSIHANDLE db, INT version, INT wordcount, con
     r = MsiSummaryInfoSetPropertyA(summary, PID_TEMPLATE, VT_LPSTR, 0, NULL, template);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
 
-    r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL,
-                                   "{004757CA-5092-49C2-AD20-28E1CE0DF5F2}");
+    r = MsiSummaryInfoSetPropertyA(summary, PID_REVNUMBER, VT_LPSTR, 0, NULL, packagecode);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
 
     r = MsiSummaryInfoSetPropertyA(summary, PID_PAGECOUNT, VT_I4, version, NULL, NULL);
@@ -2295,14 +2390,16 @@ static void write_msi_summary_info(MSIHANDLE db, INT version, INT wordcount, con
 }
 
 #define create_database(name, tables, num_tables) \
-    create_database_wordcount(name, tables, num_tables, 100, 0, ";1033");
+    create_database_wordcount(name, tables, num_tables, 100, 0, ";1033", \
+                              "{004757CA-5092-49C2-AD20-28E1CE0DF5F2}");
 
 #define create_database_template(name, tables, num_tables, version, template) \
-    create_database_wordcount(name, tables, num_tables, version, 0, template);
+    create_database_wordcount(name, tables, num_tables, version, 0, template, \
+                              "{004757CA-5092-49C2-AD20-28E1CE0DF5F2}");
 
 static void create_database_wordcount(const CHAR *name, const msi_table *tables,
                                       int num_tables, INT version, INT wordcount,
-                                      const char *template)
+                                      const char *template, const char *packagecode)
 {
     MSIHANDLE db;
     UINT r;
@@ -2329,7 +2426,7 @@ static void create_database_wordcount(const CHAR *name, const msi_table *tables,
         DeleteFileA(table->filename);
     }
 
-    write_msi_summary_info(db, version, wordcount, template);
+    write_msi_summary_info(db, version, wordcount, template, packagecode);
 
     r = MsiDatabaseCommit(db);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
@@ -4547,7 +4644,8 @@ static void test_adminimage(void)
 
     create_database_wordcount(msifile, ai_tables,
                               sizeof(ai_tables) / sizeof(msi_table),
-                              100, msidbSumInfoSourceTypeAdminImage, ";1033");
+                              100, msidbSumInfoSourceTypeAdminImage, ";1033",
+                              "{004757CA-5092-49C2-AD20-28E1CE0DF5F2}");
 
     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
 
@@ -5659,6 +5757,50 @@ static void test_volume_props(void)
     DeleteFileA(msifile);
 }
 
+static void test_shared_component(void)
+{
+    UINT r;
+
+    if (is_process_limited())
+    {
+        skip("process is limited\n");
+        return;
+    }
+    CreateDirectoryA("msitest", NULL);
+    create_file("msitest\\sharedcomponent.txt", 1000);
+    create_database_wordcount(msifile, shc_tables, sizeof(shc_tables)/sizeof(shc_tables[0]),
+                              100, 0, ";", "{A8826420-FD72-4E61-9E15-C1944CF4CBE1}");
+    create_database_wordcount(msifile2, shc2_tables, sizeof(shc2_tables)/sizeof(shc2_tables[0]),
+                              100, 0, ";", "{A8B50B30-0E8A-4ACD-B3CF-1A5DC58B2739}");
+
+    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+    r = MsiInstallProductA(msifile, NULL);
+    ok(r == ERROR_SUCCESS, "got %u\n", r);
+
+    ok(pf_exists("msitest\\sharedcomponent.txt"), "file not installed\n");
+
+    r = MsiInstallProductA(msifile2, NULL);
+    ok(r == ERROR_SUCCESS, "got %u\n", r);
+
+    ok(pf_exists("msitest\\sharedcomponent.txt"), "file not installed\n");
+
+    r = MsiInstallProductA(msifile, "REMOVE=ALL");
+    ok(r == ERROR_SUCCESS, "got %u\n", r);
+
+    ok(pf_exists("msitest\\sharedcomponent.txt"), "file removed\n");
+
+    r = MsiInstallProductA(msifile2, "REMOVE=ALL");
+    ok(r == ERROR_SUCCESS, "got %u\n", r);
+
+    ok(!pf_exists("msitest\\sharedcomponent.txt"), "file not removed\n");
+
+    DeleteFileA("msitest\\sharedcomponent.txt");
+    RemoveDirectoryA("msitest");
+    DeleteFileA(msifile);
+    DeleteFileA(msifile2);
+}
+
 START_TEST(install)
 {
     DWORD len;
@@ -5743,6 +5885,7 @@ START_TEST(install)
     test_upgrade_code();
     test_mixed_package();
     test_volume_props();
+    test_shared_component();
 
     DeleteFileA(log_file);
 
-- 
1.9.0






More information about the wine-patches mailing list