diff --git a/dlls/msi/action.c b/dlls/msi/action.c index e579e36..ef57728 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -2826,18 +2826,14 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) { WCHAR squished_pc[GUID_SIZE]; WCHAR squished_cc[GUID_SIZE]; - UINT rc; MSICOMPONENT *comp; - HKEY hkey=0,hkey2=0; + HKEY hkey; + UINT rc; TRACE("\n"); /* writes the Component and Features values to the registry */ - rc = MSIREG_OpenComponents(&hkey); - if (rc != ERROR_SUCCESS) - return rc; - squash_guid(package->ProductCode,squished_pc); ui_progress(package,1,COMPONENT_PROGRESS_VALUE,1,0); @@ -2868,51 +2864,26 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) */ if (ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL)) { - rc = RegCreateKeyW(hkey,squished_cc,&hkey2); - if (rc != ERROR_SUCCESS) - continue; - if (!comp->FullKeypath) continue; - msi_reg_set_val_str( hkey2, squished_pc, comp->FullKeypath ); - - if (comp->Attributes & msidbComponentAttributesPermanent) - { - static const WCHAR szPermKey[] = - { '0','0','0','0','0','0','0','0','0','0','0','0', - '0','0','0','0','0','0','0','0','0','0','0','0', - '0','0','0','0','0','0','0','0',0 }; - - msi_reg_set_val_str( hkey2, szPermKey, comp->FullKeypath ); - } - - RegCloseKey(hkey2); + if (package->Context == MSIINSTALLCONTEXT_MACHINE) + rc = MSIREG_OpenLocalUserDataComponentKey(comp->ComponentId, &hkey, TRUE); + else + rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, &hkey, TRUE); - rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, &hkey2, TRUE); if (rc != ERROR_SUCCESS) continue; - msi_reg_set_val_str(hkey2, squished_pc, comp->FullKeypath); - RegCloseKey(hkey2); + msi_reg_set_val_str(hkey, squished_pc, comp->FullKeypath); + RegCloseKey(hkey); } else if (ACTION_VerifyComponentForAction( comp, INSTALLSTATE_ABSENT)) { - DWORD res; - - rc = RegOpenKeyW(hkey,squished_cc,&hkey2); - if (rc != ERROR_SUCCESS) - continue; - - RegDeleteValueW(hkey2,squished_pc); - - /* if the key is empty delete it */ - res = RegEnumKeyExW(hkey2,0,NULL,0,0,NULL,0,NULL); - RegCloseKey(hkey2); - if (res == ERROR_NO_MORE_ITEMS) - RegDeleteKeyW(hkey,squished_cc); - - MSIREG_DeleteUserDataComponentKey(comp->ComponentId); + if (package->Context == MSIINSTALLCONTEXT_MACHINE) + MSIREG_DeleteLocalUserDataComponentKey(comp->ComponentId); + else + MSIREG_DeleteUserDataComponentKey(comp->ComponentId); } /* UI stuff */ @@ -2924,7 +2895,7 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) msiobj_release( &uirow->hdr ); } RegCloseKey(hkey); - return rc; + return ERROR_SUCCESS; } typedef struct { diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 90eaa19..662a838 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -769,6 +769,7 @@ extern UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_OpenUserDataFeaturesKey(LPCWSTR szProduct, HKEY *key, BOOL create); extern UINT MSIREG_OpenComponents(HKEY* key); extern UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create); +extern UINT MSIREG_OpenLocalUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create); extern UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create); extern UINT MSIREG_OpenProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_OpenPatchesKey(LPCWSTR szPatch, HKEY* key, BOOL create); @@ -787,6 +788,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_DeleteLocalUserDataComponentKey(LPCWSTR szComponent); extern UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent); extern LPWSTR msi_reg_get_val_str( HKEY hkey, LPCWSTR name ); diff --git a/dlls/msi/registry.c b/dlls/msi/registry.c index b95d5bb..9f2800c 100644 --- a/dlls/msi/registry.c +++ b/dlls/msi/registry.c @@ -214,6 +214,8 @@ static const WCHAR szInstaller_LocalManagedProd_fmt[] = { 'I','n','s','t','a','l','l','e','r','\\', 'P','r','o','d','u','c','t','s','\\','%','s',0}; +static const WCHAR localsid[] = {'S','-','1','-','5','-','1','8',0}; + BOOL unsquash_guid(LPCWSTR in, LPWSTR out) { DWORD i,n=0; @@ -671,6 +673,24 @@ UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create) return rc; } +UINT MSIREG_OpenLocalUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create) +{ + WCHAR comp[GUID_SIZE]; + WCHAR keypath[0x200]; + + TRACE("%s\n", debugstr_w(szComponent)); + if (!squash_guid(szComponent, comp)) + return ERROR_FUNCTION_FAILED; + TRACE("squished (%s)\n", debugstr_w(comp)); + + sprintfW(keypath, szUserDataComp_fmt, localsid, comp); + + if (create) + return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key); + + return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); +} + UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create) { UINT rc; @@ -701,6 +721,20 @@ UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create return rc; } +UINT MSIREG_DeleteLocalUserDataComponentKey(LPCWSTR szComponent) +{ + WCHAR comp[GUID_SIZE]; + WCHAR keypath[0x200]; + + TRACE("%s\n", debugstr_w(szComponent)); + if (!squash_guid(szComponent, comp)) + return ERROR_FUNCTION_FAILED; + TRACE("squished (%s)\n", debugstr_w(comp)); + + sprintfW(keypath, szUserDataComp_fmt, localsid, comp); + return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath); +} + UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent) { UINT rc; @@ -800,8 +834,6 @@ UINT MSIREG_OpenCurrentUserInstallProps(LPCWSTR szProduct, HKEY *key, UINT MSIREG_OpenLocalSystemInstallProps(LPCWSTR szProduct, HKEY *key, BOOL create) { - static const WCHAR localsid[] = {'S','-','1','-','5','-','1','8',0}; - return MSIREG_OpenInstallProps(szProduct, localsid, key, create); } diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c index 4dba0c6..3d8296f 100644 --- a/dlls/msi/tests/install.c +++ b/dlls/msi/tests/install.c @@ -2722,19 +2722,17 @@ static void test_publish_processcomponents(void) { UINT r; LONG res; - HKEY uninstall, prodkey, comp; - INSTALLSTATE state; + DWORD size; + HKEY comp, hkey; LPSTR usersid; + CHAR val[MAX_PATH]; CHAR keypath[MAX_PATH]; - CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"; - - static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; - if (!pMsiQueryComponentStateA) - { - skip("MsiQueryComponentStateA is not available\n"); - return; - } + static const CHAR keyfmt[] = + "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\" + "UserData\\%s\\Components\\CBABC2FDCCB35E749A8944D8C1C098B5"; + static const CHAR compkey[] = + "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components"; get_user_sid(&usersid); if (!usersid) @@ -2743,9 +2741,6 @@ static void test_publish_processcomponents(void) return; } - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, subkey, &uninstall); - ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - CreateDirectoryA("msitest", NULL); create_file("msitest\\maximus", 500); @@ -2753,154 +2748,59 @@ static void test_publish_processcomponents(void) MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); - state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - 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); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - res = RegOpenKeyA(uninstall, prodcode, &prodkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - /* ProcessComponent */ + /* ProcessComponents, per-user */ r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(pf_exists("msitest\\maximus"), "File not installed\n"); - ok(pf_exists("msitest"), "File not installed\n"); - - state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - 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); - - r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - res = RegOpenKeyA(uninstall, prodcode, &prodkey); - ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - - /* try to uninstall after ProcessComponents */ - r = MsiInstallProductA(msifile, "REMOVE=ALL"); - todo_wine - { - ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); - } - ok(pf_exists("msitest\\maximus"), "File deleted\n"); - ok(pf_exists("msitest"), "File deleted\n"); - - state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "File not installed\n"); - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + sprintf(keypath, keyfmt, usersid); - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + size = MAX_PATH; + res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB", + NULL, NULL, (LPBYTE)val, &size); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + ok(!lstrcmpA(val, "C:\\Program Files\\msitest\\maximus"), + "Expected \"%s\", got \"%s\"\n", "C:\\Program Files\\msitest\\maximus", val); - res = RegOpenKeyA(uninstall, prodcode, &prodkey); + res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey); ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - /* ProcessComponent with PublishProduct */ - r = MsiInstallProductA(msifile, "PUBLISH_PRODUCT=1 PROCESS_COMPONENTS=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(pf_exists("msitest\\maximus"), "File not installed\n"); - ok(pf_exists("msitest"), "File not installed\n"); - - state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB"); + RegDeleteKeyA(comp, ""); + RegCloseKey(comp); - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - /* uninstall */ - r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - - /* ProcessComponent with RegisterProduct */ - r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PROCESS_COMPONENTS=1"); + /* ProcessComponents, machine */ + r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1 ALLUSERS=1"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(pf_exists("msitest\\maximus"), "File not installed\n"); - ok(pf_exists("msitest"), "File not installed\n"); - - state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); - - r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); - - /* ProcessComponent with RegisterProduct and PublishProduct */ - r = MsiInstallProductA(msifile, "REGISTER_PRODUCT=1 PUBLISH_PRODUCT=1 PROCESS_COMPONENTS=1"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(pf_exists("msitest\\maximus"), "File not installed\n"); - ok(pf_exists("msitest"), "File not installed\n"); - - state = MsiQueryProductState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}"); - ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state); - - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "feature"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); + ok(delete_pf("msitest", FALSE), "File not installed\n"); - state = MsiQueryFeatureState("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}", "montecristo"); - ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state); + sprintf(keypath, keyfmt, "S-1-5-18"); - r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, - "{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}", &state); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); - ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state); + res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); - /* uninstall */ - r = MsiInstallProductA(msifile, "FULL=1 REMOVE=ALL"); - ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + size = MAX_PATH; + res = RegQueryValueExA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB", + NULL, NULL, (LPBYTE)val, &size); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + ok(!lstrcmpA(val, "C:\\Program Files\\msitest\\maximus"), + "Expected \"%s\", got \"%s\"\n", "C:\\Program Files\\msitest\\maximus", val); - lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\"); - lstrcatA(keypath, usersid); - lstrcatA(keypath, "\\Components\\CBABC2FDCCB35E749A8944D8C1C098B5"); + res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); - /* native has trouble removing the comp key unless it's a full install */ - res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp); - if (res == ERROR_SUCCESS) - { - RegDeleteKeyA(comp, ""); - RegCloseKey(comp); - } + RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB"); + RegDeleteKeyA(comp, ""); + RegCloseKey(comp); - RegCloseKey(uninstall); DeleteFile(msifile); DeleteFile("msitest\\maximus"); RemoveDirectory("msitest"); - delete_pfmsitest_files(); } static void test_publish(void) -- 1.5.4.3