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