diff --git a/dlls/msi/action.c b/dlls/msi/action.c index 4eb266c..5272115 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -2824,13 +2824,6 @@ static void ACTION_RefCountComponent( MSIPACKAGE* package, MSICOMPONENT *comp ) ACTION_WriteSharedDLLsCount( comp->FullKeypath, comp->RefCount ); } -/* - * Ok further analysis makes me think that this work is - * actually done in the PublishComponents and PublishFeatures - * step, and not here. It appears like the keypath and all that is - * resolved in this step, however actually written in the Publish steps. - * But we will leave it here for now because it is unclear - */ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) { WCHAR squished_pc[GUID_SIZE]; @@ -2841,8 +2834,6 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) TRACE("\n"); - /* writes the Component values to the registry */ - squash_guid(package->ProductCode,squished_pc); ui_progress(package,1,COMPONENT_PROGRESS_VALUE,1,0); @@ -2859,7 +2850,6 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) msi_free(comp->FullKeypath); comp->FullKeypath = resolve_keypath( package, comp ); - /* do the refcounting */ ACTION_RefCountComponent( package, comp ); TRACE("Component %s (%s), Keypath=%s, RefCount=%i\n", @@ -2867,11 +2857,9 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) debugstr_w(squished_cc), debugstr_w(comp->FullKeypath), comp->RefCount); - /* - * Write the keypath out if the component is to be registered - * and delete the key if the component is to be unregistered - */ - if (ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL)) + + if (ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL) || + ACTION_VerifyComponentForAction( comp, INSTALLSTATE_SOURCE)) { if (!comp->FullKeypath) continue; @@ -2894,7 +2882,42 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) msi_reg_set_val_str(hkey, szPermKey, comp->FullKeypath); } - msi_reg_set_val_str(hkey, squished_pc, comp->FullKeypath); + if (comp->Action == INSTALLSTATE_LOCAL) + msi_reg_set_val_str(hkey, squished_pc, comp->FullKeypath); + else + { + MSIFILE *file; + MSIRECORD *row; + LPWSTR ptr, ptr2; + WCHAR source[MAX_PATH]; + WCHAR base[MAX_PATH]; + + static const WCHAR fmt[] = {'%','0','2','d','\\',0}; + static const WCHAR query[] = { + 'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ', + '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ', + '`','L','a','s','t','S','e','q','u','e','n','c','e','`',' ', + '>','=',' ','%','i',' ','O','R','D','E','R',' ','B','Y',' ', + '`','D','i','s','k','I','d','`',0}; + + file = get_loaded_file(package, comp->KeyPath); + if (!file) + continue; + + row = MSI_QueryGetRecord(package->db, query, file->Sequence); + sprintfW(source, fmt, MSI_RecordGetInteger(row, 1)); + ptr2 = strrchrW(source, '\\') + 1; + msiobj_release(&row->hdr); + + lstrcpyW(base, package->PackagePath); + ptr = strrchrW(base, '\\'); + *(ptr + 1) = '\0'; + + ptr = file->SourcePath + lstrlenW(base); + lstrcpyW(ptr2, ptr); + + msi_reg_set_val_str(hkey, squished_pc, source); + } RegCloseKey(hkey); } else if (ACTION_VerifyComponentForAction(comp, INSTALLSTATE_ABSENT)) diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c index 390d481..04a9675 100644 --- a/dlls/msi/tests/install.c +++ b/dlls/msi/tests/install.c @@ -439,6 +439,30 @@ static const CHAR pp_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" "PublishProduct\tPUBLISH_PRODUCT=1 Or FULL=1\t6400\n" "InstallFinalize\t\t6600"; +static const CHAR ppc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" + "s72\tS38\ts72\ti2\tS255\tS72\n" + "Component\tComponent\n" + "maximus\t{DF2CBABC-3BCC-47E5-A998-448D1C0C895B}\tMSITESTDIR\t0\tUILevel=5\tmaximus\n" + "augustus\t{5AD3C142-CEF8-490D-B569-784D80670685}\tMSITESTDIR\t1\t\taugustus\n"; + +static const CHAR ppc_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n" + "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n" + "File\tFile\n" + "maximus\tmaximus\tmaximus\t500\t\t\t8192\t1\n" + "augustus\taugustus\taugustus\t500\t\t\t8192\t2"; + +static const CHAR ppc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n" + "i2\ti4\tL64\tS255\tS32\tS72\n" + "Media\tDiskId\n" + "1\t2\t\t\tDISK1\t\n"; + +static const CHAR ppc_feature_comp_dat[] = "Feature_\tComponent_\n" + "s38\ts72\n" + "FeatureComponents\tFeature_\tComponent_\n" + "feature\tmaximus\n" + "feature\taugustus\n" + "montecristo\tmaximus"; + static const CHAR tp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n" "s72\tS38\ts72\ti2\tS255\tS72\n" "Component\tComponent\n" @@ -932,6 +956,18 @@ static const msi_table pp_tables[] = ADD_TABLE(property), }; +static const msi_table ppc_tables[] = +{ + ADD_TABLE(ppc_component), + ADD_TABLE(directory), + ADD_TABLE(rof_feature), + ADD_TABLE(ppc_feature_comp), + ADD_TABLE(ppc_file), + ADD_TABLE(pp_install_exec_seq), + ADD_TABLE(ppc_media), + ADD_TABLE(property), +}; + static const msi_table tp_tables[] = { ADD_TABLE(tp_component), @@ -3001,7 +3037,7 @@ static void test_publish_processcomponents(void) static const CHAR keyfmt[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\" - "UserData\\%s\\Components\\CBABC2FDCCB35E749A8944D8C1C098B5"; + "UserData\\%s\\Components\\%s"; static const CHAR compkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components"; @@ -3015,7 +3051,7 @@ static void test_publish_processcomponents(void) CreateDirectoryA("msitest", NULL); create_file("msitest\\maximus", 500); - create_database(msifile, pp_tables, sizeof(pp_tables) / sizeof(msi_table)); + create_database(msifile, ppc_tables, sizeof(ppc_tables) / sizeof(msi_table)); MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL); @@ -3025,7 +3061,7 @@ static void test_publish_processcomponents(void) ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); ok(delete_pf("msitest", FALSE), "File not installed\n"); - sprintf(keypath, keyfmt, usersid); + sprintf(keypath, keyfmt, usersid, "CBABC2FDCCB35E749A8944D8C1C098B5"); res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); @@ -3044,13 +3080,32 @@ static void test_publish_processcomponents(void) RegDeleteKeyA(comp, ""); RegCloseKey(comp); + sprintf(keypath, keyfmt, usersid, "241C3DA58FECD0945B9687D408766058"); + + res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + 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, "01\\msitest\\augustus"), + "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val); + + res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB"); + RegDeleteKeyA(comp, ""); + RegCloseKey(comp); + /* ProcessComponents, machine */ r = MsiInstallProductA(msifile, "PROCESS_COMPONENTS=1 ALLUSERS=1"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n"); ok(delete_pf("msitest", FALSE), "File not installed\n"); - sprintf(keypath, keyfmt, "S-1-5-18"); + sprintf(keypath, keyfmt, "S-1-5-18", "CBABC2FDCCB35E749A8944D8C1C098B5"); res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); @@ -3069,6 +3124,25 @@ static void test_publish_processcomponents(void) RegDeleteKeyA(comp, ""); RegCloseKey(comp); + sprintf(keypath, keyfmt, "S-1-5-18", "241C3DA58FECD0945B9687D408766058"); + + res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &comp); + ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + + 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, "01\\msitest\\augustus"), + "Expected \"01\\msitest\\augustus\", got \"%s\"\n", val); + + res = RegOpenKeyA(HKEY_LOCAL_MACHINE, compkey, &hkey); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + RegDeleteValueA(comp, "84A88FD7F6998CE40A22FB59F6B9C2BB"); + RegDeleteKeyA(comp, ""); + RegCloseKey(comp); + DeleteFile(msifile); DeleteFile("msitest\\maximus"); RemoveDirectory("msitest"); -- 1.5.4.3