diff options
Diffstat (limited to 'solenv/bin/modules')
-rw-r--r-- | solenv/bin/modules/installer/globals.pm | 4 | ||||
-rw-r--r-- | solenv/bin/modules/installer/windows/file.pm | 12 | ||||
-rw-r--r-- | solenv/bin/modules/installer/windows/idtglobal.pm | 3 | ||||
-rw-r--r-- | solenv/bin/modules/installer/windows/msp.pm | 197 | ||||
-rw-r--r-- | solenv/bin/modules/installer/windows/property.pm | 6 | ||||
-rw-r--r-- | solenv/bin/modules/installer/windows/registry.pm | 76 |
6 files changed, 294 insertions, 4 deletions
diff --git a/solenv/bin/modules/installer/globals.pm b/solenv/bin/modules/installer/globals.pm index 41df76644874..4bc8964901b9 100644 --- a/solenv/bin/modules/installer/globals.pm +++ b/solenv/bin/modules/installer/globals.pm @@ -385,6 +385,10 @@ BEGIN %allcomponents_in_this_database = (); %allshortcomponents = (); %alluniquedirectorynames = (); + %allregistrycomponents_ = (); + %allregistrycomponents_in_this_database_ = (); + %allshortregistrycomponents = (); + %allregistryidentifier = (); $installlocationdirectory = ""; $installlocationdirectoryset = 0; diff --git a/solenv/bin/modules/installer/windows/file.pm b/solenv/bin/modules/installer/windows/file.pm index b679d8b46e2b..3ac72ecf6ac3 100644 --- a/solenv/bin/modules/installer/windows/file.pm +++ b/solenv/bin/modules/installer/windows/file.pm @@ -282,7 +282,7 @@ sub get_file_component_name } else { - if ( length($componentname) > 72 ) + if ( length($componentname) > 60 ) { # Using md5sum needs much time # chomp(my $shorter = `echo $componentname | md5sum | sed -e "s/ .*//g"`); @@ -674,7 +674,15 @@ sub get_language_for_file if ( $fileref->{'specificlanguage'} ) { $language = $fileref->{'specificlanguage'}; } - if (!($language eq "")) + if ( $language eq "" ) + { + $language = 0; # language independent + # If this is not a font, the return value should be "0" (Check ICE 60) + my $styles = ""; + if ( $fileref->{'Styles'} ) { $styles = $fileref->{'Styles'}; } + if ( $styles =~ /\bFONT\b/ ) { $language = ""; } + } + else { $language = installer::windows::language::get_windows_language($language); } diff --git a/solenv/bin/modules/installer/windows/idtglobal.pm b/solenv/bin/modules/installer/windows/idtglobal.pm index 453464a3ae36..4a54ead9dfd4 100644 --- a/solenv/bin/modules/installer/windows/idtglobal.pm +++ b/solenv/bin/modules/installer/windows/idtglobal.pm @@ -49,11 +49,14 @@ sub shorten_feature_gid my ($stringref) = @_; $$stringref =~ s/gid_Module_/gm_/; + $$stringref =~ s/_Extension_/_ex_/; $$stringref =~ s/_Root_/_r_/; $$stringref =~ s/_Prg_/_p_/; $$stringref =~ s/_Optional_/_o_/; + $$stringref =~ s/_Tools_/_tl_/; $$stringref =~ s/_Wrt_Flt_/_w_f_/; $$stringref =~ s/_Javafilter_/_jf_/; + $$stringref =~ s/_Productivity_/_pr_/; } ############################################ diff --git a/solenv/bin/modules/installer/windows/msp.pm b/solenv/bin/modules/installer/windows/msp.pm index a4996945de4d..ac28f9258820 100644 --- a/solenv/bin/modules/installer/windows/msp.pm +++ b/solenv/bin/modules/installer/windows/msp.pm @@ -27,6 +27,7 @@ package installer::windows::msp; +use File::Copy; use installer::control; use installer::converter; use installer::exiter; @@ -85,6 +86,196 @@ sub install_installation_sets } ################################################################################# +# Collecting the destinations of all files with flag PATCH in a hash. +################################################################################# + +sub collect_patch_file_destinations +{ + my ( $filesarray ) = @_; + + my %patchfiledestinations = (); + my %nopatchfiledestinations = (); + my $patchcounter = 0; + my $nopatchcounter = 0; + + for ( my $i = 0; $i <= $#{$filesarray}; $i++ ) + { + my $onefile = ${$filesarray}[$i]; + my $styles = ""; + + if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'} }; + + if ( $styles =~ /\bPATCH\b/ ) + { + $patchfiledestinations{$onefile->{'destination'}} = 1; + $patchcounter++; + } + else + { + $nopatchfiledestinations{$onefile->{'destination'}} = 1; + $nopatchcounter++; + } + } + + return (\%patchfiledestinations, \%nopatchfiledestinations, $patchcounter, $nopatchcounter); +} + +################################################################################# +# Returning the first path segment of a path +################################################################################# + +sub get_first_path_segment +{ + my ( $path ) = @_; + + my $firstsegment = ""; + my $remainder = $path; + + if ( $path =~ /^\s*(.*?)[\/\\](.*)\s*$/ ) + { + $firstsegment = $1; + $remainder = $2; + } + + return ($firstsegment, $remainder); +} + +################################################################################# +# Finding the flexible path in the destinations, that are saved in +# the hash $nopatchfiledestinations. +################################################################################# + +sub prepare_path_in_nopatchfilehash +{ + my ($nopatchfiledestinations, $newpath) = @_; + + my $infoline = ""; + my $flexiblepath = ""; + my $found = 0; + my %checked_destinations = (); + + foreach my $onedestination ( keys %{$nopatchfiledestinations} ) + { + $flexiblepath = ""; + $found = 0; + + my $found_first_segement = 1; + my $firstsegement = ""; + my $fixedpath = $onedestination; + my $testfile = $newpath . $installer::globals::separator . $fixedpath; + + while (( ! -f $testfile ) && ( $found_first_segement )) + { + $firstsegement = ""; + ( $firstsegement, $fixedpath ) = get_first_path_segment($fixedpath); + + if ( $firstsegement ne "" ) + { + $found_first_segement = 1; + $flexiblepath = $flexiblepath . $firstsegement . $installer::globals::separator; + } + else + { + $found_first_segement = 0; + } + + $testfile = $newpath . $installer::globals::separator . $fixedpath; + } + + if ( -f $testfile ) { $found = 1; } + + if ( $found ) { last; } + } + + if ( ! $found ) { installer::exiter::exit_program("ERROR: Could not determine flexible destination path for msp patch creation!", "prepare_path_in_nopatchfilehash"); } + + $infoline = "Setting flexible path for msp creation: $flexiblepath\n"; + push( @installer::globals::logfileinfo, $infoline); + + foreach my $onedestination ( keys %{$nopatchfiledestinations} ) + { + $onedestination =~ s/^\s*\Q$flexiblepath\E//; + $checked_destinations{$onedestination} = 1; + } + + return \%checked_destinations; +} + +################################################################################# +# Synchronizing the two installed products in that way, that only +# files with flag PATCH are different. +################################################################################# + +sub synchronize_installation_sets +{ + my ($olddatabase, $newdatabase, $filesarray) = @_; + + my $infoline = "\nSynchronizing installed products because of PATCH flag\n"; + push( @installer::globals::logfileinfo, $infoline); + $infoline = "Old product: $olddatabase\n"; + push( @installer::globals::logfileinfo, $infoline); + $infoline = "New product: $newdatabase\n"; + push( @installer::globals::logfileinfo, $infoline); + + my ( $patchfiledestinations, $nopatchfiledestinations, $patchfilecounter, $nopatchfilecounter ) = collect_patch_file_destinations($filesarray); + + $infoline = "Number of files with PATCH flag: $patchfilecounter\n"; + push( @installer::globals::logfileinfo, $infoline); + + $infoline = "Number of files without PATCH flag: $nopatchfilecounter\n"; + push( @installer::globals::logfileinfo, $infoline); + + foreach my $localfile ( sort keys %{$patchfiledestinations} ) + { + $infoline = "\tPATCH file: $localfile\n"; + push( @installer::globals::logfileinfo, $infoline); + } + + my $oldpath = $olddatabase; + if ( $^O =~ /cygwin/i ) { $oldpath =~ s/\\/\//g; } + installer::pathanalyzer::get_path_from_fullqualifiedname(\$oldpath); + $oldpath =~ s/\\\s*$//; + $oldpath =~ s/\/\s*$//; + + my $newpath = $newdatabase; + if ( $^O =~ /cygwin/i ) { $newpath =~ s/\\/\//g; } + installer::pathanalyzer::get_path_from_fullqualifiedname(\$newpath); + $newpath =~ s/\\\s*$//; + $newpath =~ s/\/\s*$//; + + # The destination path is not correct. destinations in the hash contain + # the flexible installation path, that is not part in the administrative installation + $nopatchfiledestinations = prepare_path_in_nopatchfilehash($nopatchfiledestinations, $newpath); + + foreach my $onedestination ( keys %{$nopatchfiledestinations} ) + { + my $source = $oldpath . $installer::globals::separator . $onedestination; + my $dest = $newpath . $installer::globals::separator . $onedestination; + + if ( -f $source ) + { + if ( -f $dest ) + { + my $copyreturn = copy($source, $dest); + # installer::systemactions::copy_one_file($source, $dest); + # $infoline = "Synchronizing file: $source to $dest\n"; + # push( @installer::globals::logfileinfo, $infoline); + } + else + { + $infoline = "Not synchronizing. Destination file \"$dest\" does not exist.\n"; + push( @installer::globals::logfileinfo, $infoline); + } + } + else + { + $infoline = "Not synchronizing. Source file \"$source\" does not exist.\n"; + push( @installer::globals::logfileinfo, $infoline); + } + } +} + +################################################################################# # Extracting all tables from a pcp file ################################################################################# @@ -1200,6 +1391,12 @@ sub create_msp_patch installer::logger::print_message( "... installing products ...\n" ); my ($olddatabase, $newdatabase) = install_installation_sets($installationdir); + installer::logger::include_timestamp_into_logfile("\nPerformance Info: Starting synchronization of installation sets"); + + # Synchronizing installed products, allowing only different files with PATCH flag + installer::logger::print_message( "... synchronizing installation sets ...\n" ); + synchronize_installation_sets($olddatabase, $newdatabase, $filesarray); + installer::logger::include_timestamp_into_logfile("\nPerformance Info: Starting pcp file creation"); # Create pcp file diff --git a/solenv/bin/modules/installer/windows/property.pm b/solenv/bin/modules/installer/windows/property.pm index 9e5557e4dacc..a5d3745d94c3 100644 --- a/solenv/bin/modules/installer/windows/property.pm +++ b/solenv/bin/modules/installer/windows/property.pm @@ -294,6 +294,12 @@ sub set_important_properties push(@{$propertyfile}, $onepropertyline); } + if ( $allvariables->{'EXCLUDE_FROM_REBASE'} ) + { + my $onepropertyline = "EXCLUDE_FROM_REBASE" . "\t" . $allvariables->{'EXCLUDE_FROM_REBASE'} . "\n"; + push(@{$propertyfile}, $onepropertyline); + } + if ( $allvariables->{'PREREQUIREDPATCH'} ) { my $onepropertyline = "PREREQUIREDPATCH" . "\t" . $allvariables->{'PREREQUIREDPATCH'} . "\n"; diff --git a/solenv/bin/modules/installer/windows/registry.pm b/solenv/bin/modules/installer/windows/registry.pm index cf87ba174dd0..18981d661372 100644 --- a/solenv/bin/modules/installer/windows/registry.pm +++ b/solenv/bin/modules/installer/windows/registry.pm @@ -61,12 +61,13 @@ sub get_registry_component_name # Attention: Maximum length for the componentname is 72 + # identifying this component as registryitem component + $componentname = "registry_" . $componentname; + $componentname =~ s/gid_module_/g_m_/g; $componentname =~ s/_optional_/_o_/g; $componentname =~ s/_javafilter_/_jf_/g; - $componentname = $componentname . "_registry"; # identifying this component as registryitem component - # This componentname must be more specific my $addon = "_"; if ( $allvariables->{'PRODUCTNAME'} ) { $addon = $addon . $allvariables->{'PRODUCTNAME'}; } @@ -95,11 +96,74 @@ sub get_registry_component_name if (( $styles =~ /\bLANGUAGEPACK\b/ ) && ( $installer::globals::languagepack )) { $componentname = $componentname . "_lang"; } if ( $styles =~ /\bALWAYS_REQUIRED\b/ ) { $componentname = $componentname . "_forced"; } + # Attention: Maximum length for the componentname is 72 + # %installer::globals::allregistrycomponents_in_this_database_ : resetted for each database + # %installer::globals::allregistrycomponents_ : not resetted for each database + # Component strings must be unique for the complete product, because they are used for + # the creation of the globally unique identifier. + + my $fullname = $componentname; # This can be longer than 72 + + if (( exists($installer::globals::allregistrycomponents_{$fullname}) ) && ( ! exists($installer::globals::allregistrycomponents_in_this_database_{$fullname}) )) + { + # This is not allowed: One component cannot be installed with different packages. + installer::exiter::exit_program("ERROR: Windows registry component \"$fullname\" is already included into another package. This is not allowed.", "get_registry_component_name"); + } + + if ( exists($installer::globals::allregistrycomponents_{$fullname}) ) + { + $componentname = $installer::globals::allregistrycomponents_{$fullname}; + } + else + { + if ( length($componentname) > 60 ) + { + $componentname = generate_new_short_registrycomponentname($componentname); # This has to be unique for the complete product, not only one package + } + + $installer::globals::allregistrycomponents_{$fullname} = $componentname; + $installer::globals::allregistrycomponents_in_this_database_{$fullname} = 1; + } + if ( $isrootmodule ) { $installer::globals::registryrootcomponent = $componentname; } return $componentname; } +######################################################### +# Create a shorter version of a long component name, +# because maximum length in msi database is 72. +# Attention: In multi msi installation sets, the short +# names have to be unique over all packages, because +# this string is used to create the globally unique id +# -> no resetting of +# %installer::globals::allshortregistrycomponents +# after a package was created. +######################################################### + +sub generate_new_short_registrycomponentname +{ + my ($componentname) = @_; + + my $shortcomponentname = ""; + my $counter = 1; + + my $startversion = substr($componentname, 0, 60); # taking only the first 60 characters + $startversion = $startversion . "_"; + + $shortcomponentname = $startversion . $counter; + + while ( exists($installer::globals::allshortregistrycomponents{$shortcomponentname}) ) + { + $counter++; + $shortcomponentname = $startversion . $counter; + } + + $installer::globals::allshortregistrycomponents{$shortcomponentname} = 1; + + return $shortcomponentname; +} + ############################################################## # Returning identifier for registry table. ############################################################## @@ -121,8 +185,16 @@ sub get_registry_identifier $identifier =~ s/_clsid_/_c_/; $identifier =~ s/_currentversion_/_cv_/; $identifier =~ s/_microsoft_/_ms_/; + $identifier =~ s/_manufacturer_/_mf_/; + $identifier =~ s/_productname_/_pn_/; + $identifier =~ s/_productversion_/_pv_/; $identifier =~ s/_staroffice_/_so_/; + $identifier =~ s/_software_/_sw_/; + $identifier =~ s/_capabilities_/_cap_/; $identifier =~ s/_classpath_/_cp_/; + $identifier =~ s/_extension_/_ex_/; + $identifier =~ s/_fileassociations_/_fa_/; + $identifier =~ s/_propertysheethandlers_/_psh_/; $identifier =~ s/__/_/g; # Saving this in the registry collector |