msi: Unpublish the product when it is entirely removed.
This commit is contained in:
parent
5e46fc9019
commit
624bbbe78a
|
@ -3885,10 +3885,60 @@ static UINT ACTION_InstallExecute(MSIPACKAGE *package)
|
|||
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;
|
||||
|
||||
|
|
|
@ -713,6 +713,9 @@ extern UINT MSIREG_OpenUserFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create
|
|||
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);
|
||||
|
|
|
@ -437,6 +437,20 @@ UINT MSIREG_OpenUserProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create)
|
|||
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(LPCWSTR szProduct, HKEY *key, BOOL create)
|
|||
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 szProduct, HKEY* key, BOOL create)
|
|||
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue