summaryrefslogtreecommitdiff
path: root/solenv/bin/modules/installer/windows
diff options
context:
space:
mode:
Diffstat (limited to 'solenv/bin/modules/installer/windows')
-rw-r--r--solenv/bin/modules/installer/windows/file.pm12
-rw-r--r--solenv/bin/modules/installer/windows/idtglobal.pm3
-rw-r--r--solenv/bin/modules/installer/windows/msp.pm197
-rw-r--r--solenv/bin/modules/installer/windows/property.pm6
-rw-r--r--solenv/bin/modules/installer/windows/registry.pm76
5 files changed, 290 insertions, 4 deletions
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