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