From fc6b9dd4e4ff2674ebeda31ef4c8ced4bafa7d6b Mon Sep 17 00:00:00 2001 From: James Hawkins Date: Thu, 1 Nov 2007 03:12:41 -0500 Subject: [PATCH] msi: Properly register and unregister components. --- dlls/msi/action.c | 24 +++++++++++++++++++- dlls/msi/msipriv.h | 2 ++ dlls/msi/registry.c | 24 ++++++++++++++++++++ dlls/msi/tests/install.c | 49 ++++++++++++---------------------------- 4 files changed, 63 insertions(+), 36 deletions(-) diff --git a/dlls/msi/action.c b/dlls/msi/action.c index 05bb4f1f528..83f3d841ef5 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -1845,6 +1845,9 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) switch (feature->Action) { + case INSTALLSTATE_ABSENT: + component->anyAbsent = 1; + break; case INSTALLSTATE_ADVERTISED: component->hasAdvertiseFeature = 1; break; @@ -1906,6 +1909,8 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) } 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 ) @@ -2767,6 +2772,8 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) MSICOMPONENT *comp; HKEY hkey=0,hkey2=0; + TRACE("\n"); + /* writes the Component and Features values to the registry */ rc = MSIREG_OpenComponents(&hkey); @@ -2823,6 +2830,13 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) } 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)) { @@ -2840,6 +2854,7 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) if (res == ERROR_NO_MORE_ITEMS) RegDeleteKeyW(hkey,squished_cc); + MSIREG_DeleteUserDataComponentKey(comp->ComponentId); } /* UI stuff */ @@ -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}; WCHAR packagefile[MAX_PATH]; LPWSTR msiFilePath; + HKEY props; UINT r; r = msi_get_local_package_name( packagefile ); @@ -3805,8 +3821,14 @@ static UINT msi_make_package_local( MSIPACKAGE *package, HKEY hkey ) } msi_free( msiFilePath ); - /* FIXME: maybe set this key in ACTION_RegisterProduct instead */ 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; } diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index d85ac5583cb..91249e18d31 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -359,6 +359,7 @@ typedef struct tagMSICOMPONENT LPWSTR FullKeypath; LPWSTR AdvertiseString; + unsigned int anyAbsent:1; unsigned int hasAdvertiseFeature:1; unsigned int hasLocalFeature:1; unsigned int hasSourceFeature:1; @@ -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_OpenLocalManagedProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create); extern UINT MSIREG_DeleteUserFeaturesKey(LPCWSTR szProduct); +extern UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent); 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 11631114cdb..9a88aeab935 100644 --- a/dlls/msi/registry.c +++ b/dlls/msi/registry.c @@ -729,6 +729,30 @@ UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create 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 rc; diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c index 3d5458a97d2..5f546092f3c 100644 --- a/dlls/msi/tests/install.c +++ b/dlls/msi/tests/install.c @@ -2030,11 +2030,8 @@ static void test_publish(void) r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - todo_wine - { - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); /* complete uninstall */ r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL"); @@ -2079,11 +2076,8 @@ static void test_publish(void) r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - todo_wine - { - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); /* complete uninstall */ r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL"); @@ -2131,11 +2125,8 @@ static void test_publish(void) r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - todo_wine - { - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); /* no UnpublishFeatures */ r = MsiInstallProductA(msifile, "REMOVE=ALL"); @@ -2183,11 +2174,8 @@ static void test_publish(void) r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - todo_wine - { - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); /* UnpublishFeatures, only feature removed. Only works when entire product is removed */ r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature"); @@ -2212,11 +2200,8 @@ static void test_publish(void) r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - todo_wine - { - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); /* complete install */ r = MsiInstallProductA(msifile, "FULL=1"); @@ -2241,11 +2226,8 @@ static void test_publish(void) r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - todo_wine - { - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); /* UnpublishFeatures, both features removed */ r = MsiInstallProductA(msifile, "UNPUBLISH_FEATURES=1 REMOVE=feature,montecristo"); @@ -2293,11 +2275,8 @@ static void test_publish(void) r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - todo_wine - { - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - } + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); /* complete uninstall */ r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL");