Commit fc6b9dd4 authored by James Hawkins's avatar James Hawkins Committed by Alexandre Julliard

msi: Properly register and unregister components.

parent eec9bbb1
...@@ -1845,6 +1845,9 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) ...@@ -1845,6 +1845,9 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
switch (feature->Action) switch (feature->Action)
{ {
case INSTALLSTATE_ABSENT:
component->anyAbsent = 1;
break;
case INSTALLSTATE_ADVERTISED: case INSTALLSTATE_ADVERTISED:
component->hasAdvertiseFeature = 1; component->hasAdvertiseFeature = 1;
break; break;
...@@ -1906,6 +1909,8 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) ...@@ -1906,6 +1909,8 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
} }
TRACE("nobody wants component %s\n", debugstr_w(component->Component)); TRACE("nobody wants component %s\n", debugstr_w(component->Component));
if (component->anyAbsent)
msi_component_set_state(component, INSTALLSTATE_ABSENT);
} }
LIST_FOR_EACH_ENTRY( component, &package->components, MSICOMPONENT, entry ) LIST_FOR_EACH_ENTRY( component, &package->components, MSICOMPONENT, entry )
...@@ -2767,6 +2772,8 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) ...@@ -2767,6 +2772,8 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
MSICOMPONENT *comp; MSICOMPONENT *comp;
HKEY hkey=0,hkey2=0; HKEY hkey=0,hkey2=0;
TRACE("\n");
/* writes the Component and Features values to the registry */ /* writes the Component and Features values to the registry */
rc = MSIREG_OpenComponents(&hkey); rc = MSIREG_OpenComponents(&hkey);
...@@ -2823,6 +2830,13 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) ...@@ -2823,6 +2830,13 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
} }
RegCloseKey(hkey2); RegCloseKey(hkey2);
rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, &hkey2, TRUE);
if (rc != ERROR_SUCCESS)
continue;
msi_reg_set_val_str(hkey2, squished_pc, comp->FullKeypath);
RegCloseKey(hkey2);
} }
else if (ACTION_VerifyComponentForAction( comp, INSTALLSTATE_ABSENT)) else if (ACTION_VerifyComponentForAction( comp, INSTALLSTATE_ABSENT))
{ {
...@@ -2840,6 +2854,7 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) ...@@ -2840,6 +2854,7 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
if (res == ERROR_NO_MORE_ITEMS) if (res == ERROR_NO_MORE_ITEMS)
RegDeleteKeyW(hkey,squished_cc); RegDeleteKeyW(hkey,squished_cc);
MSIREG_DeleteUserDataComponentKey(comp->ComponentId);
} }
/* UI stuff */ /* UI stuff */
...@@ -3785,6 +3800,7 @@ static UINT msi_make_package_local( MSIPACKAGE *package, HKEY hkey ) ...@@ -3785,6 +3800,7 @@ static UINT msi_make_package_local( MSIPACKAGE *package, HKEY hkey )
{'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0}; {'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0};
WCHAR packagefile[MAX_PATH]; WCHAR packagefile[MAX_PATH];
LPWSTR msiFilePath; LPWSTR msiFilePath;
HKEY props;
UINT r; UINT r;
r = msi_get_local_package_name( packagefile ); r = msi_get_local_package_name( packagefile );
...@@ -3805,8 +3821,14 @@ static UINT msi_make_package_local( MSIPACKAGE *package, HKEY hkey ) ...@@ -3805,8 +3821,14 @@ static UINT msi_make_package_local( MSIPACKAGE *package, HKEY hkey )
} }
msi_free( msiFilePath ); msi_free( msiFilePath );
/* FIXME: maybe set this key in ACTION_RegisterProduct instead */
msi_reg_set_val_str( hkey, INSTALLPROPERTY_LOCALPACKAGEW, packagefile ); msi_reg_set_val_str( hkey, INSTALLPROPERTY_LOCALPACKAGEW, packagefile );
r = MSIREG_OpenInstallPropertiesKey(package->ProductCode, &props, TRUE);
if (r != ERROR_SUCCESS)
return r;
msi_reg_set_val_str(props, INSTALLPROPERTY_LOCALPACKAGEW, packagefile);
RegCloseKey(props);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
......
...@@ -359,6 +359,7 @@ typedef struct tagMSICOMPONENT ...@@ -359,6 +359,7 @@ typedef struct tagMSICOMPONENT
LPWSTR FullKeypath; LPWSTR FullKeypath;
LPWSTR AdvertiseString; LPWSTR AdvertiseString;
unsigned int anyAbsent:1;
unsigned int hasAdvertiseFeature:1; unsigned int hasAdvertiseFeature:1;
unsigned int hasLocalFeature:1; unsigned int hasLocalFeature:1;
unsigned int hasSourceFeature:1; unsigned int hasSourceFeature:1;
...@@ -752,6 +753,7 @@ extern UINT MSIREG_OpenLocalSystemComponentKey(LPCWSTR szComponent, HKEY *key, B ...@@ -752,6 +753,7 @@ extern UINT MSIREG_OpenLocalSystemComponentKey(LPCWSTR szComponent, HKEY *key, B
extern UINT MSIREG_OpenLocalClassesProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create); extern UINT MSIREG_OpenLocalClassesProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create);
extern UINT MSIREG_OpenLocalManagedProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create); extern UINT MSIREG_OpenLocalManagedProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create);
extern UINT MSIREG_DeleteUserFeaturesKey(LPCWSTR szProduct); extern UINT MSIREG_DeleteUserFeaturesKey(LPCWSTR szProduct);
extern UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent);
extern LPWSTR msi_reg_get_val_str( HKEY hkey, LPCWSTR name ); extern LPWSTR msi_reg_get_val_str( HKEY hkey, LPCWSTR name );
extern BOOL msi_reg_get_val_dword( HKEY hkey, LPCWSTR name, DWORD *val); extern BOOL msi_reg_get_val_dword( HKEY hkey, LPCWSTR name, DWORD *val);
......
...@@ -729,6 +729,30 @@ UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create ...@@ -729,6 +729,30 @@ UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create
return rc; return rc;
} }
UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent)
{
UINT rc;
WCHAR comp[GUID_SIZE];
WCHAR keypath[0x200];
LPWSTR usersid;
TRACE("%s\n", debugstr_w(szComponent));
if (!squash_guid(szComponent, comp))
return ERROR_FUNCTION_FAILED;
TRACE("squished (%s)\n", debugstr_w(comp));
rc = get_user_sid(&usersid);
if (rc != ERROR_SUCCESS || !usersid)
{
ERR("Failed to retrieve user SID: %d\n", rc);
return rc;
}
sprintfW(keypath, szUserDataComp_fmt, usersid, comp);
return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath);
}
UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, HKEY *key, BOOL create) UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, HKEY *key, BOOL create)
{ {
UINT rc; UINT rc;
......
...@@ -2030,11 +2030,8 @@ static void test_publish(void) ...@@ -2030,11 +2030,8 @@ static void test_publish(void)
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
todo_wine
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
}
/* complete uninstall */ /* complete uninstall */
r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL"); r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
...@@ -2079,11 +2076,8 @@ static void test_publish(void) ...@@ -2079,11 +2076,8 @@ static void test_publish(void)
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
todo_wine
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
}
/* complete uninstall */ /* complete uninstall */
r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL"); r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
...@@ -2131,11 +2125,8 @@ static void test_publish(void) ...@@ -2131,11 +2125,8 @@ static void test_publish(void)
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
todo_wine
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
}
/* no UnpublishFeatures */ /* no UnpublishFeatures */
r = MsiInstallProductA(msifile, "REMOVE=ALL"); r = MsiInstallProductA(msifile, "REMOVE=ALL");
...@@ -2183,11 +2174,8 @@ static void test_publish(void) ...@@ -2183,11 +2174,8 @@ static void test_publish(void)
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
todo_wine
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
}
/* UnpublishFeatures, only feature removed. Only works when entire product is removed */ /* UnpublishFeatures, only feature removed. Only works when entire product is removed */
r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature"); r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature");
...@@ -2212,11 +2200,8 @@ static void test_publish(void) ...@@ -2212,11 +2200,8 @@ static void test_publish(void)
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
todo_wine
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
}
/* complete install */ /* complete install */
r = MsiInstallProductA(msifile, "FULL=1"); r = MsiInstallProductA(msifile, "FULL=1");
...@@ -2241,11 +2226,8 @@ static void test_publish(void) ...@@ -2241,11 +2226,8 @@ static void test_publish(void)
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
todo_wine
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
}
/* UnpublishFeatures, both features removed */ /* UnpublishFeatures, both features removed */
r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo"); r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo");
...@@ -2293,11 +2275,8 @@ static void test_publish(void) ...@@ -2293,11 +2275,8 @@ static void test_publish(void)
r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
"{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state);
todo_wine
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
}
/* complete uninstall */ /* complete uninstall */
r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL"); r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment