msi [6/13]: Unpublish the product when it is entirely removed
James Hawkins
truiken at gmail.com
Mon Jul 2 22:20:54 CDT 2007
Hi,
Changelog:
* Unpublish the product when it is entirely removed.
dlls/msi/action.c | 50 +++++++++++++++++++++++++++++++++++++++++++
dlls/msi/msipriv.h | 3 +++
dlls/msi/registry.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++
dlls/msi/tests/install.c | 40 +++++++----------------------------
4 files changed, 114 insertions(+), 32 deletions(-)
--
James Hawkins
-------------- next part --------------
diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index c9d4fa8..0911a29 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -3885,10 +3885,60 @@ static UINT ACTION_InstallExecute(MSIPAC
return execute_script(package,INSTALL_SCRIPT);
}
+static UINT msi_unpublish_product(MSIPACKAGE *package)
+{
+ LPWSTR remove = NULL;
+ LPWSTR *features = NULL;
+ BOOL full_uninstall = TRUE;
+ MSIFEATURE *feature;
+
+ static const WCHAR szRemove[] = {'R','E','M','O','V','E',0};
+ static const WCHAR szAll[] = {'A','L','L',0};
+
+ remove = msi_dup_property(package, szRemove);
+ if (!remove)
+ return ERROR_SUCCESS;
+
+ features = msi_split_string(remove, ',');
+ if (!features)
+ {
+ msi_free(remove);
+ ERR("REMOVE feature list is empty!\n");
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ if (!lstrcmpW(features[0], szAll))
+ full_uninstall = TRUE;
+ else
+ {
+ LIST_FOR_EACH_ENTRY(feature, &package->features, MSIFEATURE, entry)
+ {
+ if (feature->Action != INSTALLSTATE_ABSENT)
+ full_uninstall = FALSE;
+ }
+ }
+
+ if (!full_uninstall)
+ goto done;
+
+ MSIREG_DeleteProductKey(package->ProductCode);
+ MSIREG_DeleteUserProductKey(package->ProductCode);
+ MSIREG_DeleteUserDataProductKey(package->ProductCode);
+
+done:
+ msi_free(remove);
+ msi_free(features);
+ return ERROR_SUCCESS;
+}
+
static UINT ACTION_InstallFinalize(MSIPACKAGE *package)
{
UINT rc;
+ rc = msi_unpublish_product(package);
+ if (rc != ERROR_SUCCESS)
+ return rc;
+
/* turn off scheduling */
package->script->CurrentlyScripting= FALSE;
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index e5b5ea3..14a365e 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -713,6 +713,9 @@ extern UINT MSIREG_OpenUserFeaturesKey(L
extern UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create);
extern UINT MSIREG_OpenUpgradeCodesKey(LPCWSTR szProduct, HKEY* key, BOOL create);
extern UINT MSIREG_OpenUserUpgradeCodesKey(LPCWSTR szProduct, HKEY* key, BOOL create);
+extern UINT MSIREG_DeleteProductKey(LPCWSTR szProduct);
+extern UINT MSIREG_DeleteUserProductKey(LPCWSTR szProduct);
+extern UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct);
extern LPWSTR msi_reg_get_val_str( HKEY hkey, LPCWSTR name );
extern BOOL msi_reg_get_val_dword( HKEY hkey, LPCWSTR name, DWORD *val);
diff --git a/dlls/msi/registry.c b/dlls/msi/registry.c
index c557264..238cdd1 100644
--- a/dlls/msi/registry.c
+++ b/dlls/msi/registry.c
@@ -437,6 +437,20 @@ UINT MSIREG_OpenUserProductsKey(LPCWSTR
return rc;
}
+UINT MSIREG_DeleteUserProductKey(LPCWSTR szProduct)
+{
+ WCHAR squished_pc[GUID_SIZE];
+ WCHAR keypath[0x200];
+
+ TRACE("%s\n",debugstr_w(szProduct));
+ squash_guid(szProduct,squished_pc);
+ TRACE("squished (%s)\n", debugstr_w(squished_pc));
+
+ sprintfW(keypath,szUserProduct_fmt,squished_pc);
+
+ return RegDeleteTreeW(HKEY_CURRENT_USER, keypath);
+}
+
UINT MSIREG_OpenUserPatchesKey(LPCWSTR szPatch, HKEY* key, BOOL create)
{
UINT rc;
@@ -593,9 +607,34 @@ UINT MSIREG_OpenUserDataProductKey(LPCWS
else
rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
+ msi_free(usersid);
return rc;
}
+UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct)
+{
+ UINT rc;
+ WCHAR squished_pc[GUID_SIZE];
+ WCHAR keypath[0x200];
+ LPWSTR usersid;
+
+ TRACE("%s\n", debugstr_w(szProduct));
+ squash_guid(szProduct, squished_pc);
+ TRACE("squished (%s)\n", debugstr_w(squished_pc));
+
+ rc = get_user_sid(&usersid);
+ if (rc != ERROR_SUCCESS || !usersid)
+ {
+ ERR("Failed to retrieve user SID: %d\n", rc);
+ return rc;
+ }
+
+ sprintfW(keypath, szUserDataProd_fmt, usersid, squished_pc);
+
+ msi_free(usersid);
+ return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath);
+}
+
UINT MSIREG_OpenProducts(HKEY* key)
{
return RegCreateKeyW(HKEY_LOCAL_MACHINE,szInstaller_Products,key);
@@ -621,6 +660,20 @@ UINT MSIREG_OpenProductsKey(LPCWSTR szPr
return rc;
}
+UINT MSIREG_DeleteProductKey(LPCWSTR szProduct)
+{
+ WCHAR squished_pc[GUID_SIZE];
+ WCHAR keypath[0x200];
+
+ TRACE("%s\n", debugstr_w(szProduct));
+ squash_guid(szProduct, squished_pc);
+ TRACE("squished (%s)\n", debugstr_w(squished_pc));
+
+ sprintfW(keypath, szInstaller_Products_fmt, squished_pc);
+
+ return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath);
+}
+
UINT MSIREG_OpenPatchesKey(LPCWSTR szPatch, HKEY* key, BOOL create)
{
UINT rc;
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c
index f7df7eb..42d41a2 100644
--- a/dlls/msi/tests/install.c
+++ b/dlls/msi/tests/install.c
@@ -1706,10 +1706,7 @@ static void test_publish(void)
ok(pf_exists("msitest"), "File deleted\n");
state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- todo_wine
- {
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
- }
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
@@ -1952,10 +1949,7 @@ static void test_publish(void)
}
state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- todo_wine
- {
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
- }
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
todo_wine
@@ -1984,10 +1978,7 @@ static void test_publish(void)
ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
- todo_wine
- {
- ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
- }
+ ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
todo_wine
@@ -2013,16 +2004,10 @@ static void test_publish(void)
ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
- todo_wine
- {
- ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
- }
+ ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
- todo_wine
- {
- ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
- }
+ ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
@@ -2071,10 +2056,7 @@ static void test_publish(void)
}
state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}");
- todo_wine
- {
- ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
- }
+ ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
todo_wine
@@ -2103,16 +2085,10 @@ static void test_publish(void)
ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature");
- todo_wine
- {
- ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
- }
+ ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo");
- todo_wine
- {
- ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
- }
+ ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
--
1.4.1
More information about the wine-patches
mailing list