diff options
-rw-r--r-- | solenv/bin/modules/installer.pm | 26 | ||||
-rw-r--r-- | solenv/bin/modules/installer/globals.pm | 1 | ||||
-rw-r--r-- | solenv/bin/modules/installer/windows/directory.pm | 62 | ||||
-rw-r--r-- | solenv/bin/modules/installer/windows/idtglobal.pm | 25 | ||||
-rw-r--r-- | solenv/bin/modules/installer/windows/update.pm | 28 |
5 files changed, 141 insertions, 1 deletions
diff --git a/solenv/bin/modules/installer.pm b/solenv/bin/modules/installer.pm index 605aec25e663..eb6ec70aafb9 100644 --- a/solenv/bin/modules/installer.pm +++ b/solenv/bin/modules/installer.pm @@ -519,9 +519,15 @@ sub run { if ( $installer::globals::updatedatabase ) { ($uniquefilename, $revuniquefilename, $revshortfilename, $allupdatesequences, $allupdatecomponents, $allupdatefileorder, $allupdatecomponentorder, $shortdirname, $componentid, $componentidkeypath, $alloldproperties, $allupdatelastsequences, $allupdatediskids) = installer::windows::update::create_database_hashes($refdatabase); - if ( $mergemodulesarrayref > -1 ) { installer::windows::update::readmergedatabase($mergemodulesarrayref, $languagestringref, $includepatharrayref); } } } + + # Always analyze the merge module. + # We need to investigate the directory table in merge module to emit + # custom action for directory names that start with standard prefix + if ( $mergemodulesarrayref > -1 ) { + installer::windows::update::readmergedatabase($mergemodulesarrayref, $languagestringref, $includepatharrayref); + } } ############################################## @@ -1510,6 +1516,24 @@ sub run { installer::windows::idtglobal::addcustomactions($languageidtdir, $windowscustomactionsarrayref, $filesinproductlanguageresolvedarrayref); + installer::logger::print_message( "... Analyze if custom action table must be patched with merge module directory names ...\n" ); + + my @customactions = (); + for my $e (keys %installer::globals::merge_directory_hash) { + my $var; + installer::logger::print_message( "... analyzing directory from merge module: $e\n"); + if (installer::windows::directory::has_standard_directory_prefix($e, \$var)) { + installer::logger::print_message( "... emitting custom action to set the var $e to directory: $var\n"); + push(@customactions, installer::windows::idtglobal::emit_custom_action_for_standard_directory($e, $var)); + } + } + + if (@customactions) { + installer::logger::print_message( "... Patching custom action table with merge module directory names ...\n" ); + #print Dumper(@customactions); + installer::windows::idtglobal::addcustomactions($languageidtdir, \@customactions, $filesinproductlanguageresolvedarrayref); + } + # Then the language specific msi database can be created if ( $installer::globals::iswin || $installer::globals::packageformat eq 'msi' ) diff --git a/solenv/bin/modules/installer/globals.pm b/solenv/bin/modules/installer/globals.pm index 5a7423aa48f8..c09b696c766c 100644 --- a/solenv/bin/modules/installer/globals.pm +++ b/solenv/bin/modules/installer/globals.pm @@ -159,6 +159,7 @@ BEGIN %merge_media_line = (); %merge_allfeature_hash = (); %merge_alldirectory_hash = (); + %merge_directory_hash = (); %copy_msm_files = (); $mergefeaturecollected = 0; $mergedirectoriescollected = 0; diff --git a/solenv/bin/modules/installer/windows/directory.pm b/solenv/bin/modules/installer/windows/directory.pm index a1d677393334..b29fa13c045a 100644 --- a/solenv/bin/modules/installer/windows/directory.pm +++ b/solenv/bin/modules/installer/windows/directory.pm @@ -29,6 +29,36 @@ use installer::windows::msiglobal; # Collecting all directory trees in global hash ############################################################## +my @msistandarddirectorynames = qw( + AdminToolsFolder + AppDataFolder + CommonAppDataFolder + CommonFiles64Folder + CommonFilesFolder + DesktopFolder + FavoritesFolder + FontsFolder + LocalAppDataFolder + MyPicturesFolder + NetHoodFolder + PersonalFolder + PrintHoodFolder + ProgramFiles64Folder + ProgramFilesFolder + ProgramMenuFolder + RecentFolder + SendToFolder + StartMenuFolder + StartupFolder + System16Folder + System64Folder + SystemFolder + TempFolder + TemplateFolder + WindowsFolder + WindowsVolume +); + sub collectdirectorytrees { my ( $directoryref ) = @_; @@ -569,4 +599,36 @@ sub create_directory_table } } +################################################ +# Check if the string starts with another string +################################################ + +sub starts_with +{ + my ($first, $second) = @_; + + return substr($first, 0, length($second)) eq $second; +} + +############################################### +# Check if the directory prefix is a standard +# directory name. If it is the case, then the +# standard directory name is returned in $var. +############################################### + +sub has_standard_directory_prefix +{ + my ($dir, $var) = @_; + + for my $d (@msistandarddirectorynames) { + if (starts_with($dir, $d) && $dir ne $d) { + installer::logger::print_message("... match found: [$d]\n"); + ${$var} = $d; + return 1; + } + } + + return 0; +} + 1; diff --git a/solenv/bin/modules/installer/windows/idtglobal.pm b/solenv/bin/modules/installer/windows/idtglobal.pm index d9d2f9e2c238..2fa46fbbdb6a 100644 --- a/solenv/bin/modules/installer/windows/idtglobal.pm +++ b/solenv/bin/modules/installer/windows/idtglobal.pm @@ -1834,4 +1834,29 @@ sub setbidiattributes push(@installer::globals::logfileinfo, $infoline); } +############################################### +# Emit custom action 51 for setting standard +# directory variable. Reference to a hash is +# returned, represented the custom action. +# This can be passed in to addcustomaction +# method. +############################################### + +sub emit_custom_action_for_standard_directory +{ + my ($dir, $var) = @_; + my %action = (); + + $action{'Name'} = $dir; + $action{'Typ'} = "51"; + $action{'Source'} = $dir; + $action{'Target'} = "[$var]"; + $action{'Styles'} = "NO_FILE"; + $action{'Assignment1'} = '("AdminExecuteSequence", "", "CostInitialize")'; + $action{'Assignment2'} = '("InstallExecuteSequence", "", "CostInitialize")'; + $action{'Assignment3'} = '("InstallUISequence", "", "CostInitialize")'; + + return \%action; +} + 1; diff --git a/solenv/bin/modules/installer/windows/update.pm b/solenv/bin/modules/installer/windows/update.pm index 0edaaf2d8d91..45c47ed7ab0d 100644 --- a/solenv/bin/modules/installer/windows/update.pm +++ b/solenv/bin/modules/installer/windows/update.pm @@ -183,6 +183,9 @@ sub read_all_tables_from_msidatabase if ( ! -f $longonefilename ) { installer::exiter::exit_program("ERROR: Could not find idt file: $longonefilename!", "read_all_tables_from_msidatabase"); } my $filecontent = installer::files::read_file($longonefilename); my $idtcontent = analyze_idt_file($filecontent); + if ($onefilename eq "Directory.idt") { + collect_directories($filecontent); + } my $key = $onefilename; $key =~ s/\.idt\s*$//; $database{$key} = $idtcontent; @@ -406,6 +409,31 @@ sub readdatabase return $database; } +######################################################################### +# Reading the file "Directory.idt". +######################################################################### + +sub collect_directories +{ + my ($filecontent) = @_; + + for ( my $i = 0; $i <= $#{$filecontent}; $i++ ) + { + if ( $i <= 2 ) { next; } # ignoring first three lines + if ( ${$filecontent}[$i] =~ /^\s*$/ ) { next; } # ignoring empty lines + # Format: Directory Directory_Parent DefaultDir + if ( ${$filecontent}[$i] =~ /^\s*(.+?)\t(.*?)\t(.*?)\s*$/ ) + { + $installer::globals::merge_directory_hash{$1} = 1; + } + else + { + my $linecount = $i + 1; + installer::exiter::exit_program("ERROR: Unknown line format in table \"$idtfilename\" (line $linecount) !", "collect_directories"); + } + } +} + ################################################################################# # Files can be included in merge modules. This is also important for update. ################################################################################# |