summaryrefslogtreecommitdiff
path: root/solenv/bin/modules/installer/windows/msp.pm
diff options
context:
space:
mode:
Diffstat (limited to 'solenv/bin/modules/installer/windows/msp.pm')
-rw-r--r--solenv/bin/modules/installer/windows/msp.pm1493
1 files changed, 0 insertions, 1493 deletions
diff --git a/solenv/bin/modules/installer/windows/msp.pm b/solenv/bin/modules/installer/windows/msp.pm
deleted file mode 100644
index 735377439fc5..000000000000
--- a/solenv/bin/modules/installer/windows/msp.pm
+++ /dev/null
@@ -1,1493 +0,0 @@
-#**************************************************************
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-#**************************************************************
-
-
-
-package installer::windows::msp;
-
-use File::Copy;
-use installer::control;
-use installer::converter;
-use installer::exiter;
-use installer::files;
-use installer::globals;
-use installer::logger;
-use installer::pathanalyzer;
-use installer::systemactions;
-use installer::windows::admin;
-use installer::windows::idtglobal;
-use installer::windows::update;
-
-#################################################################################
-# Making all required administrative installations
-#################################################################################
-
-sub install_installation_sets
-{
- my ($installationdir) = @_;
-
- # Finding the msi database in the new installation set, that is located in $installationdir
-
- my $msifiles = installer::systemactions::find_file_with_file_extension("msi", $installationdir);
-
- if ( $#{$msifiles} < 0 ) { installer::exiter::exit_program("ERROR: Did not find msi database in directory $installationdir", "create_msp_patch"); }
- if ( $#{$msifiles} > 0 ) { installer::exiter::exit_program("ERROR: Did find more than one msi database in directory $installationdir", "create_msp_patch"); }
-
- my $newinstallsetdatabasepath = $installationdir . $installer::globals::separator . ${$msifiles}[0];
- my $oldinstallsetdatabasepath = $installer::globals::updatedatabasepath;
-
- # Creating temp directory again
- installer::systemactions::create_directory_structure($installer::globals::temppath);
-
- # Creating old installation directory
- my $dirname = "admin";
- my $installpath = $installer::globals::temppath . $installer::globals::separator . $dirname;
- if ( ! -d $installpath) { installer::systemactions::create_directory($installpath); }
-
- my $oldinstallpath = $installpath . $installer::globals::separator . "old";
- my $newinstallpath = $installpath . $installer::globals::separator . "new";
-
- if ( ! -d $oldinstallpath) { installer::systemactions::create_directory($oldinstallpath); }
- if ( ! -d $newinstallpath) { installer::systemactions::create_directory($newinstallpath); }
-
- my $olddatabase = installer::windows::admin::make_admin_install($oldinstallsetdatabasepath, $oldinstallpath);
- my $newdatabase = installer::windows::admin::make_admin_install($newinstallsetdatabasepath, $newinstallpath);
-
- if ( $^O =~ /cygwin/i ) {
- $olddatabase = qx{cygpath -w "$olddatabase"};
- $olddatabase =~ s/\s*$//g;
- $newdatabase = qx{cygpath -w "$newdatabase"};
- $newdatabase =~ s/\s*$//g;
- }
-
- return ($olddatabase, $newdatabase);
-}
-
-#################################################################################
-# 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";
- $installer::logger::Lang->print($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) = @_;
-
- $installer::logger::Lang->print("\n");
- $installer::logger::Lang->print("Synchronizing installed products because of PATCH flag\n");
- $infoline = "Old product: $olddatabase\n";
- $installer::logger::Lang->print($infoline);
- $infoline = "New product: $newdatabase\n";
- $installer::logger::Lang->print($infoline);
-
- my ( $patchfiledestinations, $nopatchfiledestinations, $patchfilecounter, $nopatchfilecounter ) = collect_patch_file_destinations($filesarray);
-
- $infoline = "Number of files with PATCH flag: $patchfilecounter\n";
- $installer::logger::Lang->print($infoline);
-
- $infoline = "Number of files without PATCH flag: $nopatchfilecounter\n";
- $installer::logger::Lang->print($infoline);
-
- foreach my $localfile ( sort keys %{$patchfiledestinations} )
- {
- $infoline = "\tPATCH file: $localfile\n";
- $installer::logger::Lang->print($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";
- # $installer::logger::Lang->print($infoline);
- }
- else
- {
- $infoline = "Not synchronizing. Destination file \"$dest\" does not exist.\n";
- $installer::logger::Lang->print($infoline);
- }
- }
- else
- {
- $infoline = "Not synchronizing. Source file \"$source\" does not exist.\n";
- $installer::logger::Lang->print($infoline);
- }
- }
-}
-
-#################################################################################
-# Extracting all tables from a pcp file
-#################################################################################
-
-sub extract_all_tables_from_pcpfile
-{
- my ($fullpcpfilepath, $workdir) = @_;
-
- my $msidb = "msidb.exe"; # Has to be in the path
- my $infoline = "";
- my $systemcall = "";
- my $returnvalue = "";
- my $extraslash = ""; # Has to be set for non-ActiveState perl
-
- my $localfullpcpfile = $fullpcpfilepath;
- my $localworkdir = $workdir;
-
- if ( $^O =~ /cygwin/i ) {
- # msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
- $localfullpcpfile =~ s/\//\\\\/g;
- $localworkdir =~ s/\//\\\\/g;
- $extraslash = "\\";
- }
-
- # Export of all tables by using "*"
-
- $systemcall = $msidb . " -d " . $localfullpcpfile . " -f " . $localworkdir . " -e " . $extraslash . "*";
- $returnvalue = system($systemcall);
-
- $infoline = "Systemcall: $systemcall\n";
- $installer::logger::Lang->print($infoline);
-
- if ($returnvalue)
- {
- $infoline = "ERROR: Could not execute $systemcall !\n";
- $installer::logger::Lang->print($infoline);
- installer::exiter::exit_program("ERROR: Could not exclude tables from pcp file: $fullpcpfilepath !", "extract_all_tables_from_msidatabase");
- }
- else
- {
- $infoline = "Success: Executed $systemcall successfully!\n";
- $installer::logger::Lang->print($infoline);
- }
-}
-
-#################################################################################
-# Include tables into a pcp file
-#################################################################################
-
-sub include_tables_into_pcpfile
-{
- my ($fullpcpfilepath, $workdir, $tables) = @_;
-
- my $msidb = "msidb.exe"; # Has to be in the path
- my $infoline = "";
- my $systemcall = "";
- my $returnvalue = "";
-
- # Make all table 8+3 conform
- my $alltables = installer::converter::convert_stringlist_into_array(\$tables, " ");
-
- for ( my $i = 0; $i <= $#{$alltables}; $i++ )
- {
- my $tablename = ${$alltables}[$i];
- $tablename =~ s/\s*$//;
- my $namelength = length($tablename);
- if ( $namelength > 8 )
- {
- my $newtablename = substr($tablename, 0, 8); # name, offset, length
- my $oldfile = $workdir . $installer::globals::separator . $tablename . ".idt";
- my $newfile = $workdir . $installer::globals::separator . $newtablename . ".idt";
- if ( -f $newfile ) { unlink $newfile; }
- installer::systemactions::copy_one_file($oldfile, $newfile);
- }
- }
-
- # Import of tables
-
- my $localworkdir = $workdir;
- my $localfullpcpfilepath = $fullpcpfilepath;
-
- if ( $^O =~ /cygwin/i ) {
- # msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
- $localfullpcpfilepath =~ s/\//\\\\/g;
- $localworkdir =~ s/\//\\\\/g;
- }
-
- $systemcall = $msidb . " -d " . $localfullpcpfilepath . " -f " . $localworkdir . " -i " . $tables;
-
- $returnvalue = system($systemcall);
-
- $infoline = "Systemcall: $systemcall\n";
- $installer::logger::Lang->print($infoline);
-
- if ($returnvalue)
- {
- $infoline = "ERROR: Could not execute $systemcall !\n";
- $installer::logger::Lang->print($infoline);
- installer::exiter::exit_program("ERROR: Could not include tables into pcp file: $fullpcpfilepath !", "include_tables_into_pcpfile");
- }
- else
- {
- $infoline = "Success: Executed $systemcall successfully!\n";
- $installer::logger::Lang->print($infoline);
- }
-}
-
-#################################################################################
-# Calling msimsp.exe
-#################################################################################
-
-sub execute_msimsp
-{
- my ($fullpcpfilename, $mspfilename, $localmspdir) = @_;
-
- my $msimsp = "msimsp.exe"; # Has to be in the path
- my $infoline = "";
- my $systemcall = "";
- my $returnvalue = "";
- my $logfilename = $localmspdir . $installer::globals::separator . "msimsp.log";
-
- # Using a specific temp for each msimsp.exe process
- # Creating temp directory again (should already have happened)
- installer::systemactions::create_directory_structure($installer::globals::temppath);
-
- # Creating old installation directory
- my $dirname = "msimsptemp";
- my $msimsptemppath = $installer::globals::temppath . $installer::globals::separator . $dirname;
- if ( ! -d $msimsptemppath) { installer::systemactions::create_directory($msimsptemppath); }
-
- # r:\msvc9p\PlatformSDK\v6.1\bin\msimsp.exe -s c:\patch\hotfix_qfe1.pcp -p c:\patch\patch_ooo3_m2_m3.msp -l c:\patch\patch_ooo3_m2_m3.log
-
- if ( -f $logfilename ) { unlink $logfilename; }
-
- my $localfullpcpfilename = $fullpcpfilename;
- my $localmspfilename = $mspfilename;
- my $locallogfilename = $logfilename;
- my $localmsimsptemppath = $msimsptemppath;
-
- if ( $^O =~ /cygwin/i ) {
- # msimsp.exe really wants backslashes. (And double escaping because system() expands the string.)
- $localfullpcpfilename =~ s/\//\\\\/g;
- $locallogfilename =~ s/\//\\\\/g;
-
- $localmspfilename =~ s/\\/\\\\/g; # path already contains backslash
- # $localmspfilename =~ s/\//\\\\/g;
-
- $localmsimsptemppath = qx{cygpath -w "$localmsimsptemppath"};
- $localmsimsptemppath =~ s/\\/\\\\/g;
- $localmsimsptemppath =~ s/\s*$//g;
- }
-
- $systemcall = $msimsp . " -s " . $localfullpcpfilename . " -p " . $localmspfilename . " -l " . $locallogfilename . " -f " . $localmsimsptemppath;
- $installer::logger::Info->printf("... %s ...\n", $systemcall);
-
- $returnvalue = system($systemcall);
-
- $infoline = "Systemcall: $systemcall\n";
- $installer::logger::Lang->print($infoline);
-
- if ($returnvalue)
- {
- $infoline = "ERROR: Could not execute $systemcall !\n";
- $installer::logger::Lang->print($infoline);
- installer::exiter::exit_program("ERROR: Could not execute $systemcall !", "execute_msimsp");
- }
- else
- {
- $infoline = "Success: Executed $systemcall successfully!\n";
- $installer::logger::Lang->print($infoline);
- }
-
- return $logfilename;
-}
-
-####################################################################
-# Checking existence and saving all tables, that need to be edited
-####################################################################
-
-sub check_and_save_tables
-{
- my ($tablelist, $workdir) = @_;
-
- my $tables = installer::converter::convert_stringlist_into_array(\$tablelist, " ");
-
- for ( my $i = 0; $i <= $#{$tables}; $i++ )
- {
- my $filename = ${$tables}[$i];
- $filename =~ s/\s*$//;
- my $fullfilename = $workdir . $installer::globals::separator . $filename . ".idt";
-
- if ( ! -f $fullfilename ) { installer::exiter::exit_program("ERROR: Required idt file could not be found: \"$fullfilename\"!", "check_and_save_tables"); }
-
- my $savfilename = $fullfilename . ".sav";
- installer::systemactions::copy_one_file($fullfilename, $savfilename);
- }
-}
-
-####################################################################
-# Setting the languages for the service packs
-####################################################################
-
-sub create_langstring
-{
- my ( $languagesarrayref ) = @_;
-
- my $langstring = "";
- for ( my $i = 0; $i <= $#{$languagesarrayref}; $i++ ) { $langstring = $langstring . "_" . ${$languagesarrayref}[$i]; }
-
- return $langstring;
-}
-
-####################################################################
-# Setting the name of the msp database
-####################################################################
-
-sub set_mspfilename
-{
- my ($allvariables, $mspdir, $languagesarrayref) = @_;
-
- my $databasename = $allvariables->{'PRODUCTNAME'};
- $databasename = lc($databasename);
- $databasename =~ s/\.//g;
- $databasename =~ s/\-//g;
- $databasename =~ s/\s//g;
-
- if ( $allvariables->{'MSPPRODUCTVERSION'} ) { $databasename = $databasename . $allvariables->{'MSPPRODUCTVERSION'}; }
-
- # possibility to overwrite the name with variable DATABASENAME
- # if ( $allvariables->{'DATABASENAME'} ) { $databasename = $allvariables->{'DATABASENAME'}; }
-
- # Adding patch info to database name
- # if ( $installer::globals::buildid ) { $databasename = $databasename . "_" . $installer::globals::buildid; }
-
- # if ( $allvariables->{'VENDORPATCHVERSION'} ) { $databasename = $databasename . "_" . $allvariables->{'VENDORPATCHVERSION'}; }
-
-
- if (( $allvariables->{'SERVICEPACK'} ) && ( $allvariables->{'SERVICEPACK'} == 1 ))
- {
- my $windowspatchlevel = 0;
- if ( $allvariables->{'MSPPATCHLEVEL'} ) { $windowspatchlevel = $allvariables->{'MSPPATCHLEVEL'}; }
- $databasename = $databasename . "_servicepack_" . $windowspatchlevel;
- my $languagestring = create_langstring($languagesarrayref);
- $databasename = $databasename . $languagestring;
- }
- else
- {
- my $hotfixaddon = "hotfix_";
- $hotfixaddon = $hotfixaddon . $installer::globals::buildid;
- my $cwsname = "";
- if ( $ENV{'CWS_WORK_STAMP'} ) { $hotfixaddon = $ENV{'CWS_WORK_STAMP'}; }
- if ( $allvariables->{'OVERWRITE_CWSNAME'} ) { $hotfixaddon = $allvariables->{'OVERWRITE_CWSNAME'}; }
- $databasename = $databasename . "_" . $hotfixaddon;
- }
-
- $databasename = $databasename . ".msp";
-
- my $fullmspname = $mspdir . $installer::globals::separator . $databasename;
-
- if ( $^O =~ /cygwin/i ) { $fullmspname =~ s/\//\\/g; }
-
- return $fullmspname;
-}
-
-####################################################################
-# Editing table Properties
-####################################################################
-
-sub change_properties_table
-{
- my ($localmspdir, $mspfilename) = @_;
-
- my $infoline = "Changing content of table \"Properties\"\n";
- $installer::logger::Lang->print($infoline);
-
- my $filename = $localmspdir . $installer::globals::separator . "Properties.idt";
- if ( ! -f $filename ) { installer::exiter::exit_program("ERROR: Could not find file \"$filename\" !", "change_properties_table"); }
-
- my $filecontent = installer::files::read_file($filename);
-
-
- my $guidref = installer::windows::msiglobal::get_guid_list(1, 1);
- ${$guidref}[0] =~ s/\s*$//; # removing ending spaces
- my $patchcode = "\{" . ${$guidref}[0] . "\}";
-
- # Setting "PatchOutputPath"
- my $found_patchoutputpath = 0;
- my $found_patchguid = 0;
-
- for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
- {
- if ( ${$filecontent}[$i] =~ /^\s*PatchOutputPath\t(.*?)\s*$/ )
- {
- my $oldvalue = $1;
- ${$filecontent}[$i] =~ s/\Q$oldvalue\E/$mspfilename/;
- $found_patchoutputpath = 1;
- }
-
- if ( ${$filecontent}[$i] =~ /^\s*PatchGUID\t(.*?)\s*$/ )
- {
- my $oldvalue = $1;
- ${$filecontent}[$i] =~ s/\Q$oldvalue\E/$patchcode/;
- $found_patchguid = 1;
- }
- }
-
- if ( ! $found_patchoutputpath )
- {
- my $newline = "PatchOutputPath\t$mspfilename\n";
- push(@{$filecontent}, $newline);
- }
-
- if ( ! $found_patchguid )
- {
- my $newline = "PatchGUID\t$patchcode\n";
- push(@{$filecontent}, $newline);
- }
-
- # saving file
- installer::files::save_file($filename, $filecontent);
-}
-
-####################################################################
-# Editing table TargetImages
-####################################################################
-
-sub change_targetimages_table
-{
- my ($localmspdir, $olddatabase) = @_;
-
- my $infoline = "Changing content of table \"TargetImages\"\n";
- $installer::logger::Lang->print($infoline);
-
- my $filename = $localmspdir . $installer::globals::separator . "TargetImages.idt";
- if ( ! -f $filename ) { installer::exiter::exit_program("ERROR: Could not find file \"$filename\" !", "change_targetimages_table"); }
-
- my $filecontent = installer::files::read_file($filename);
- my @newcontent = ();
-
- # Copying the header
- for ( my $i = 0; $i <= $#{$filecontent}; $i++ ) { if ( $i < 3 ) { push(@newcontent, ${$filecontent}[$i]); } }
-
- #Adding all targets
- my $newline = "T1\t$olddatabase\t\tU1\t1\t0x00000922\t1\n";
- push(@newcontent, $newline);
-
- # saving file
- installer::files::save_file($filename, \@newcontent);
-}
-
-####################################################################
-# Editing table UpgradedImages
-####################################################################
-
-sub change_upgradedimages_table
-{
- my ($localmspdir, $newdatabase) = @_;
-
- my $infoline = "Changing content of table \"UpgradedImages\"\n";
- $installer::logger::Lang->print($infoline);
-
- my $filename = $localmspdir . $installer::globals::separator . "UpgradedImages.idt";
- if ( ! -f $filename ) { installer::exiter::exit_program("ERROR: Could not find file \"$filename\" !", "change_upgradedimages_table"); }
-
- my $filecontent = installer::files::read_file($filename);
- my @newcontent = ();
-
- # Copying the header
- for ( my $i = 0; $i <= $#{$filecontent}; $i++ ) { if ( $i < 3 ) { push(@newcontent, ${$filecontent}[$i]); } }
-
- # Syntax: Upgraded MsiPath PatchMsiPath SymbolPaths Family
-
- # default values
- my $upgraded = "U1";
- my $msipath = $newdatabase;
- my $patchmsipath = "";
- my $symbolpaths = "";
- my $family = "22334455";
-
- if ( $#{$filecontent} >= 3 )
- {
- my $line = ${$filecontent}[3];
- if ( $line =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ )
- {
- $upgraded = $1;
- $patchmsipath = $3;
- $symbolpaths = $4;
- $family = $5;
- }
- }
-
- #Adding sequence line, saving PatchFamily
- my $newline = "$upgraded\t$msipath\t$patchmsipath\t$symbolpaths\t$family\n";
- push(@newcontent, $newline);
-
- # saving file
- installer::files::save_file($filename, \@newcontent);
-}
-
-####################################################################
-# Editing table ImageFamilies
-####################################################################
-
-sub change_imagefamilies_table
-{
- my ($localmspdir) = @_;
-
- my $infoline = "Changing content of table \"ImageFamilies\"\n";
- $installer::logger::Lang->print($infoline);
-
- my $filename = $localmspdir . $installer::globals::separator . "ImageFamilies.idt";
- if ( ! -f $filename ) { installer::exiter::exit_program("ERROR: Could not find file \"$filename\" !", "change_imagefamilies_table"); }
-
- my $filecontent = installer::files::read_file($filename);
- my @newcontent = ();
-
- # Copying the header
- for ( my $i = 0; $i <= $#{$filecontent}; $i++ ) { if ( $i < 3 ) { push(@newcontent, ${$filecontent}[$i]); } }
-
- # Syntax: Family MediaSrcPropName MediaDiskId FileSequenceStart DiskPrompt VolumeLabel
- # "FileSequenceStart has to be set
-
- # Default values:
-
- my $family = "22334455";
- my $mediasrcpropname = "MediaSrcPropName";
- my $mediadiskid = "2";
- my $filesequencestart = get_filesequencestart();
- my $diskprompt = "";
- my $volumelabel = "";
-
- if ( $#{$filecontent} >= 3 )
- {
- my $line = ${$filecontent}[3];
- if ( $line =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ )
- {
- $family = $1;
- $mediasrcpropname = $2;
- $mediadiskid = $3;
- $diskprompt = $5;
- $volumelabel = $6;
- }
- }
-
- #Adding sequence line
- my $newline = "$family\t$mediasrcpropname\t$mediadiskid\t$filesequencestart\t$diskprompt\t$volumelabel\n";
- push(@newcontent, $newline);
-
- # saving file
- installer::files::save_file($filename, \@newcontent);
-}
-
-####################################################################
-# Setting start sequence for patch
-####################################################################
-
-sub get_filesequencestart
-{
- my $sequence = 1000; # default
-
- if ( $installer::globals::updatelastsequence ) { $sequence = $installer::globals::updatelastsequence + 500; }
-
- return $sequence;
-}
-
-####################################################################
-# Setting time value into pcp file
-# Format mm/dd/yyyy hh:mm
-####################################################################
-
-sub get_patchtime_value
-{
- # Syntax: 8/8/2008 11:55
- my $minute = (localtime())[1];
- my $hour = (localtime())[2];
- my $day = (localtime())[3];
- my $month = (localtime())[4];
- my $year = 1900 + (localtime())[5];
-
- $month++; # zero based month
- if ( $minute < 10 ) { $minute = "0" . $minute; }
- if ( $hour < 10 ) { $hour = "0" . $hour; }
-
- my $timestring = $month . "/" . $day . "/" . $year . " " . $hour . ":" . $minute;
-
- return $timestring;
-}
-
-#################################################################################
-# Checking, if this is the correct database.
-#################################################################################
-
-sub correct_langs
-{
- my ($langs, $languagestringref) = @_;
-
- my $correct_langs = 0;
-
- # Comparing $langs with $languagestringref
-
- my $langlisthash = installer::converter::convert_stringlist_into_hash(\$langs, ",");
- my $langstringhash = installer::converter::convert_stringlist_into_hash($languagestringref, "_");
-
- my $not_included = 0;
- foreach my $onelang ( keys %{$langlisthash} )
- {
- if ( ! exists($langstringhash->{$onelang}) )
- {
- $not_included = 1;
- last;
- }
- }
-
- if ( ! $not_included )
- {
- foreach my $onelanguage ( keys %{$langstringhash} )
- {
- if ( ! exists($langlisthash->{$onelanguage}) )
- {
- $not_included = 1;
- last;
- }
- }
-
- if ( ! $not_included ) { $correct_langs = 1; }
- }
-
- return $correct_langs;
-}
-
-#################################################################################
-# Searching for the path to the reference database for this special product.
-#################################################################################
-
-sub get_patchid_from_list
-{
- my ($filecontent, $languagestringref, $filename) = @_;
-
- my $patchid = "";
-
- for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
- {
- my $line = ${$filecontent}[$i];
- if ( $line =~ /^\s*$/ ) { next; } # empty line
- if ( $line =~ /^\s*\#/ ) { next; } # comment line
-
- if ( $line =~ /^\s*(.+?)\s*=\s*(.+?)\s*$/ )
- {
- my $langs = $1;
- my $localpatchid = $2;
-
- if ( correct_langs($langs, $languagestringref) )
- {
- $patchid = $localpatchid;
- last;
- }
- }
- else
- {
- installer::exiter::exit_program("ERROR: Wrong syntax in file: $filename! Line: \"$line\"", "get_patchid_from_list");
- }
- }
-
- return $patchid;
-}
-
-####################################################################
-# Editing table PatchMetadata
-####################################################################
-
-sub change_patchmetadata_table
-{
- my ($localmspdir, $allvariables, $languagestringref) = @_;
-
- my $infoline = "Changing content of table \"PatchMetadata\"\n";
- $installer::logger::Lang->print($infoline);
-
- my $filename = $localmspdir . $installer::globals::separator . "PatchMetadata.idt";
- if ( ! -f $filename ) { installer::exiter::exit_program("ERROR: Could not find file \"$filename\" !", "change_patchmetadata_table"); }
-
- my $filecontent = installer::files::read_file($filename);
- my @newcontent = ();
-
- # Syntax: Company Property Value
- # Interesting properties: "Classification" and "CreationTimeUTC"
-
- my $classification_set = 0;
- my $creationtime_set = 0;
- my $targetproductname_set = 0;
- my $manufacturer_set = 0;
- my $displayname_set = 0;
- my $description_set = 0;
- my $allowremoval_set = 0;
-
- my $defaultcompany = "";
-
- my $classificationstring = "Classification";
- my $classificationvalue = "Hotfix";
- if (( $allvariables->{'SERVICEPACK'} ) && ( $allvariables->{'SERVICEPACK'} == 1 )) { $classificationvalue = "ServicePack"; }
-
- my $allowremovalstring = "AllowRemoval";
- my $allowremovalvalue = "1";
- if (( exists($allvariables->{'MSPALLOWREMOVAL'}) ) && ( $allvariables->{'MSPALLOWREMOVAL'} == 0 )) { $allowremovalvalue = 0; }
-
- my $timestring = "CreationTimeUTC";
- # Syntax: 8/8/2008 11:55
- my $timevalue = get_patchtime_value();
-
- my $targetproductnamestring = "TargetProductName";
- my $targetproductnamevalue = $allvariables->{'PRODUCTNAME'};
- if ( $allvariables->{'PROPERTYTABLEPRODUCTNAME'} ) { $targetproductnamevalue = $allvariables->{'PROPERTYTABLEPRODUCTNAME'}; }
-
- my $manufacturerstring = "ManufacturerName";
- my $manufacturervalue = "Apache OpenOffice";
- if ( $installer::globals::longmanufacturer ) { $manufacturervalue = $installer::globals::longmanufacturer; }
-
- my $displaynamestring = "DisplayName";
- my $descriptionstring = "Description";
- my $displaynamevalue = "";
- my $descriptionvalue = "";
-
- my $base = $allvariables->{'PRODUCTNAME'} . " " . $allvariables->{'PRODUCTVERSION'};
- if ( $installer::globals::languagepack ) { $base = $targetproductnamevalue; }
-
- my $windowspatchlevel = 0;
- if ( $allvariables->{'WINDOWSPATCHLEVEL'} ) { $windowspatchlevel = $allvariables->{'WINDOWSPATCHLEVEL'}; }
-
- my $displayaddon = "";
- if ( $allvariables->{'PATCHDISPLAYADDON'} ) { $displayaddon = $allvariables->{'PATCHDISPLAYADDON'}; }
-
- my $cwsname = "";
- if ( $ENV{'CWS_WORK_STAMP'} ) { $cwsname = $ENV{'CWS_WORK_STAMP'}; }
- if (( $cwsname ne "" ) && ( $allvariables->{'OVERWRITE_CWSNAME'} )) { $cwsname = $allvariables->{'OVERWRITE_CWSNAME'}; }
-
- my $patchsequence = get_patchsequence($allvariables);
-
- if (( $allvariables->{'SERVICEPACK'} ) && ( $allvariables->{'SERVICEPACK'} == 1 ))
- {
- $displaynamevalue = $base . " ServicePack " . $windowspatchlevel . " " . $patchsequence . " Build: " . $installer::globals::buildid;
- $descriptionvalue = $base . " ServicePack " . $windowspatchlevel . " " . $patchsequence . " Build: " . $installer::globals::buildid;
- }
- else
- {
- $displaynamevalue = $base . " Hotfix " . $cwsname . " " . $displayaddon . " " . $patchsequence . " Build: " . $installer::globals::buildid;
- $descriptionvalue = $base . " Hotfix " . $cwsname . " " . $displayaddon . " " . $patchsequence . " Build: " . $installer::globals::buildid;
- $displaynamevalue =~ s/ / /g;
- $descriptionvalue =~ s/ / /g;
- $displaynamevalue =~ s/ / /g;
- $descriptionvalue =~ s/ / /g;
- $displaynamevalue =~ s/ / /g;
- $descriptionvalue =~ s/ / /g;
- }
-
- if ( $allvariables->{'MSPPATCHNAMELIST'} )
- {
- my $patchnamelistfile = $allvariables->{'MSPPATCHNAMELIST'};
- $patchnamelistfile = $installer::globals::idttemplatepath . $installer::globals::separator . $patchnamelistfile;
- if ( ! -f $patchnamelistfile ) { installer::exiter::exit_program("ERROR: Could not find file \"$patchnamelistfile\".", "change_patchmetadata_table"); }
- my $filecontent = installer::files::read_file($patchnamelistfile);
-
- # Get name and path of reference database
- my $patchid = get_patchid_from_list($filecontent, $languagestringref, $patchnamelistfile);
-
- if ( $patchid eq "" ) { installer::exiter::exit_program("ERROR: Could not find file patchid in file \"$patchnamelistfile\" for language(s) \"$$languagestringref\".", "change_patchmetadata_table"); }
-
- # Setting language specific patch id
- }
-
- for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
- {
- if ( ${$filecontent}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\s*$/ )
- {
- my $company = $1;
- my $property = $2;
- my $value = $3;
-
- if ( $property eq $classificationstring )
- {
- ${$filecontent}[$i] = "$company\t$property\t$classificationvalue\n";
- $classification_set = 1;
- }
-
- if ( $property eq $allowremovalstring )
- {
- ${$filecontent}[$i] = "$company\t$property\t$allowremovalvalue\n";
- $allowremoval_set = 1;
- }
-
- if ( $property eq $timestring )
- {
- ${$filecontent}[$i] = "$company\t$property\t$timevalue\n";
- $creationtime_set = 1;
- }
-
- if ( $property eq $targetproductnamestring )
- {
- ${$filecontent}[$i] = "$company\t$property\t$targetproductnamevalue\n";
- $targetproductname_set = 1;
- }
-
- if ( $property eq $manufacturerstring )
- {
- ${$filecontent}[$i] = "$company\t$property\t$manufacturervalue\n";
- $manufacturer_set = 1;
- }
-
- if ( $property eq $displaynamestring )
- {
- ${$filecontent}[$i] = "$company\t$property\t$displaynamevalue\n";
- $displayname_set = 1;
- }
-
- if ( $property eq $descriptionstring )
- {
- ${$filecontent}[$i] = "$company\t$property\t$descriptionvalue\n";
- $description_set = 1;
- }
- }
-
- push(@newcontent, ${$filecontent}[$i]);
- }
-
- if ( ! $classification_set )
- {
- my $line = "$defaultcompany\t$classificationstring\t$classificationvalue\n";
- push(@newcontent, $line);
- }
-
- if ( ! $allowremoval_set )
- {
- my $line = "$defaultcompany\t$classificationstring\t$allowremovalvalue\n";
- push(@newcontent, $line);
- }
-
- if ( ! $allowremoval_set )
- {
- my $line = "$defaultcompany\t$classificationstring\t$allowremovalvalue\n";
- push(@newcontent, $line);
- }
-
- if ( ! $creationtime_set )
- {
- my $line = "$defaultcompany\t$timestring\t$timevalue\n";
- push(@newcontent, $line);
- }
-
- if ( ! $targetproductname_set )
- {
- my $line = "$defaultcompany\t$targetproductnamestring\t$targetproductnamevalue\n";
- push(@newcontent, $line);
- }
-
- if ( ! $manufacturer_set )
- {
- my $line = "$defaultcompany\t$manufacturerstring\t$manufacturervalue\n";
- push(@newcontent, $line);
- }
-
- if ( ! $displayname_set )
- {
- my $line = "$defaultcompany\t$displaynamestring\t$displaynamevalue\n";
- push(@newcontent, $line);
- }
-
- if ( ! $description_set )
- {
- my $line = "$defaultcompany\t$descriptionstring\t$descriptionvalue\n";
- push(@newcontent, $line);
- }
-
- # saving file
- installer::files::save_file($filename, \@newcontent);
-}
-
-####################################################################
-# Editing table PatchSequence
-####################################################################
-
-sub change_patchsequence_table
-{
- my ($localmspdir, $allvariables) = @_;
-
- my $infoline = "Changing content of table \"PatchSequence\"\n";
- $installer::logger::Lang->print($infoline);
-
- my $filename = $localmspdir . $installer::globals::separator . "PatchSequence.idt";
- if ( ! -f $filename ) { installer::exiter::exit_program("ERROR: Could not find file \"$filename\" !", "change_patchsequence_table"); }
-
- my $filecontent = installer::files::read_file($filename);
- my @newcontent = ();
-
- # Copying the header
- for ( my $i = 0; $i <= $#{$filecontent}; $i++ ) { if ( $i < 3 ) { push(@newcontent, ${$filecontent}[$i]); } }
-
- # Syntax: PatchFamily Target Sequence Supersede
-
- my $patchfamily = "SO";
- my $target = "";
- my $patchsequence = get_patchsequence($allvariables);
- my $supersede = get_supersede($allvariables);
-
- if ( $#{$filecontent} >= 3 )
- {
- my $line = ${$filecontent}[3];
- if ( $line =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\s$/ )
- {
- $patchfamily = $1;
- $target = $2;
- }
- }
-
- #Adding sequence line, saving PatchFamily
- my $newline = "$patchfamily\t$target\t$patchsequence\t$supersede\n";
- push(@newcontent, $newline);
-
- # saving file
- installer::files::save_file($filename, \@newcontent);
-}
-
-####################################################################
-# Setting supersede, "0" for Hotfixes, "1" for ServicePack
-####################################################################
-
-sub get_supersede
-{
- my ( $allvariables ) = @_;
-
- my $supersede = 0; # if not defined, this is a Hotfix
-
- if (( $allvariables->{'SERVICEPACK'} ) && ( $allvariables->{'SERVICEPACK'} == 1 )) { $supersede = 1; }
-
- return $supersede;
-}
-
-####################################################################
-# Setting the sequence of the patch
-####################################################################
-
-sub get_patchsequence
-{
- my ( $allvariables ) = @_;
-
- my $patchsequence = "1.0";
-
- if ( ! $allvariables->{'PACKAGEVERSION'} ) { installer::exiter::exit_program("ERROR: PACKAGEVERSION must be set for msp patch creation!", "get_patchsequence"); }
-
- my $packageversion = $allvariables->{'PACKAGEVERSION'};
-
- if ( $packageversion =~ /^\s*(\d+)\.(\d+)\.(\d+)\s*$/ )
- {
- my $major = $1;
- my $minor = $2;
- my $micro = $3;
- my $concat = 100 * $minor + $micro;
- $packageversion = $major . "\." . $concat;
- }
- my $vendornumber = 0;
- if ( $allvariables->{'VENDORPATCHVERSION'} ) { $vendornumber = $allvariables->{'VENDORPATCHVERSION'}; }
- $patchsequence = $packageversion . "\." . $installer::globals::buildid . "\." . $vendornumber;
-
- if ( $allvariables->{'PATCHSEQUENCE'} ) { $patchsequence = $allvariables->{'PATCHSEQUENCE'}; }
-
- return $patchsequence;
-}
-
-####################################################################
-# Editing all tables from pcp file, that need to be edited
-####################################################################
-
-sub edit_tables
-{
- my ($tablelist, $localmspdir, $olddatabase, $newdatabase, $mspfilename, $allvariables, $languagestringref) = @_;
-
- # table list contains: my $tablelist = "Properties TargetImages UpgradedImages ImageFamilies PatchMetadata PatchSequence";
-
- change_properties_table($localmspdir, $mspfilename);
- change_targetimages_table($localmspdir, $olddatabase);
- change_upgradedimages_table($localmspdir, $newdatabase);
- change_imagefamilies_table($localmspdir);
- change_patchmetadata_table($localmspdir, $allvariables, $languagestringref);
- change_patchsequence_table($localmspdir, $allvariables);
-}
-
-#################################################################################
-# Checking, if this is the correct database.
-#################################################################################
-
-sub correct_patch
-{
- my ($product, $pro, $langs, $languagestringref) = @_;
-
- my $correct_patch = 0;
-
- # Comparing $product with $installer::globals::product and
- # $pro with $installer::globals::pro and
- # $langs with $languagestringref
-
- my $product_is_good = 0;
-
- my $localproduct = $installer::globals::product;
- if ( $installer::globals::languagepack ) { $localproduct = $localproduct . "LanguagePack"; }
-
- if ( $product eq $localproduct ) { $product_is_good = 1; }
-
- if ( $product_is_good )
- {
- my $pro_is_good = 0;
-
- if ((( $pro eq "pro" ) && ( $installer::globals::pro )) || (( $pro eq "nonpro" ) && ( ! $installer::globals::pro ))) { $pro_is_good = 1; }
-
- if ( $pro_is_good )
- {
- my $langlisthash = installer::converter::convert_stringlist_into_hash(\$langs, ",");
- my $langstringhash = installer::converter::convert_stringlist_into_hash($languagestringref, "_");
-
- my $not_included = 0;
- foreach my $onelang ( keys %{$langlisthash} )
- {
- if ( ! exists($langstringhash->{$onelang}) )
- {
- $not_included = 1;
- last;
- }
- }
-
- if ( ! $not_included )
- {
- foreach my $onelanguage ( keys %{$langstringhash} )
- {
- if ( ! exists($langlisthash->{$onelanguage}) )
- {
- $not_included = 1;
- last;
- }
- }
-
- if ( ! $not_included ) { $correct_patch = 1; }
- }
- }
- }
-
- return $correct_patch;
-}
-
-#################################################################################
-# Searching for the path to the required patch for this special product.
-#################################################################################
-
-sub get_requiredpatchfile_from_list
-{
- my ($filecontent, $languagestringref, $filename) = @_;
-
- my $patchpath = "";
-
- for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
- {
- my $line = ${$filecontent}[$i];
- if ( $line =~ /^\s*$/ ) { next; } # empty line
- if ( $line =~ /^\s*\#/ ) { next; } # comment line
-
- if ( $line =~ /^\s*(.+?)\s*\t+\s*(.+?)\s*\t+\s*(.+?)\s*\t+\s*(.+?)\s*$/ )
- {
- my $product = $1;
- my $pro = $2;
- my $langs = $3;
- my $path = $4;
-
- if (( $pro ne "pro" ) && ( $pro ne "nonpro" )) { installer::exiter::exit_program("ERROR: Wrong syntax in file: $filename. Only \"pro\" or \"nonpro\" allowed in column 1! Line: \"$line\"", "get_databasename_from_list"); }
-
- if ( correct_patch($product, $pro, $langs, $languagestringref) )
- {
- $patchpath = $path;
- last;
- }
- }
- else
- {
- installer::exiter::exit_program("ERROR: Wrong syntax in file: $filename! Line: \"$line\"", "get_requiredpatchfile_from_list");
- }
- }
-
- return $patchpath;
-}
-
-##################################################################
-# Converting unicode file to ascii
-# to be more precise: uft-16 little endian to ascii
-##################################################################
-
-sub convert_unicode_to_ascii
-{
- my ( $filename ) = @_;
-
- my @localfile = ();
-
- my $savfilename = $filename . "_before.unicode";
- installer::systemactions::copy_one_file($filename, $savfilename);
-
-# open( IN, "<:utf16", $filename ) || installer::exiter::exit_program("ERROR: Cannot open file $filename for reading", "convert_unicode_to_ascii");
-# open( IN, "<:para:crlf:uni", $filename ) || installer::exiter::exit_program("ERROR: Cannot open file $filename for reading", "convert_unicode_to_ascii");
- open( IN, "<:encoding(UTF16-LE)", $filename ) || installer::exiter::exit_program("ERROR: Cannot open file $filename for reading", "convert_unicode_to_ascii");
-# open( IN, "<:encoding(UTF-8)", $filename ) || installer::exiter::exit_program("ERROR: Cannot open file $filename for reading", "convert_unicode_to_ascii");
- while ( $line = <IN> ) {
- push @localfile, $line;
- }
- close( IN );
-
- if ( open( OUT, ">", $filename ) )
- {
- print OUT @localfile;
- close(OUT);
- }
-}
-
-####################################################################
-# Analyzing the log file created by msimsp.exe to find all
-# files included into the patch.
-####################################################################
-
-sub analyze_msimsp_logfile
-{
- my ($logfile, $filesarray) = @_;
-
- # Reading log file after converting from utf-16 (LE) to ascii
- convert_unicode_to_ascii($logfile);
- my $logfilecontent = installer::files::read_file($logfile);
-
- # Creating hash from $filesarray: unique file name -> destination of file
- my %filehash = ();
- my %destinationcollector = ();
-
- for ( my $i = 0; $i <= $#{$filesarray}; $i++ )
- {
- my $onefile = ${$filesarray}[$i];
-
- # Only collecting files with "uniquename" and "destination"
- if (( exists($onefile->{'uniquename'}) ) && ( exists($onefile->{'uniquename'}) ))
- {
- my $uniquefilename = $onefile->{'uniquename'};
- my $destpath = $onefile->{'destination'};
- $filehash{$uniquefilename} = $destpath;
- }
- }
-
- # Analyzing log file of msimsp.exe, finding all changed files
- # and searching all destinations of unique file names.
- # Content in log file: "INFO File Key: <file key> is modified"
- # Collecting content in @installer::globals::patchfilecollector
-
- for ( my $i = 0; $i <= $#{$logfilecontent}; $i++ )
- {
- if ( ${$logfilecontent}[$i] =~ /Key\:\s*(.*?) is modified\s*$/ )
- {
- my $filekey = $1;
- if ( exists($filehash{$filekey}) ) { $destinationcollector{$filehash{$filekey}} = 1; }
- else { installer::exiter::exit_program("ERROR: Could not find file key \"$filekey\" in file collector.", "analyze_msimsp_logfile"); }
- }
- }
-
- foreach my $onedest ( sort keys %destinationcollector ) { push(@installer::globals::patchfilecollector, "$onedest\n"); }
-
-}
-
-####################################################################
-# Creating msp patch files for Windows
-####################################################################
-
-sub create_msp_patch
-{
- my ($installationdir, $includepatharrayref, $allvariables, $languagestringref, $languagesarrayref, $filesarray) = @_;
-
- # print this message even in 'quiet' mode
- $installer::logger::Info->print("\n");
- $installer::logger::Info->print("******************************************\n");
- $installer::logger::Info->print("... creating msp installation set ...\n", 1);
- $installer::logger::Info->print("******************************************\n");
-
- $installer::globals::creating_windows_installer_patch = 1;
-
- my @needed_files = ("msimsp.exe"); # only required for patch creation process
- installer::control::check_needed_files_in_path(\@needed_files);
-
- installer::logger::include_header_into_logfile("Creating msp installation sets:");
-
- my $firstdir = $installationdir;
- installer::pathanalyzer::get_path_from_fullqualifiedname(\$firstdir);
-
- my $lastdir = $installationdir;
- installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$lastdir);
-
- if ( $lastdir =~ /\./ ) { $lastdir =~ s/\./_msp_inprogress\./ }
- else { $lastdir = $lastdir . "_msp_inprogress"; }
-
- # Removing existing directory "_native_packed_inprogress" and "_native_packed_witherror" and "_native_packed"
-
- my $mspdir = $firstdir . $lastdir;
- if ( -d $mspdir ) { installer::systemactions::remove_complete_directory($mspdir); }
-
- my $olddir = $mspdir;
- $olddir =~ s/_inprogress/_witherror/;
- if ( -d $olddir ) { installer::systemactions::remove_complete_directory($olddir); }
-
- $olddir = $mspdir;
- $olddir =~ s/_inprogress//;
- if ( -d $olddir ) { installer::systemactions::remove_complete_directory($olddir); }
-
- # Creating the new directory for new installation set
- installer::systemactions::create_directory($mspdir);
-
- $installer::globals::saveinstalldir = $mspdir;
-
- $installer::logger::Lang->print("\n");
- $installer::logger::Lang->add_timestamp("Performance Info: Starting product installation");
-
- # Installing both installation sets
- $installer::logger::Info->printf("... installing products ...\n");
- my ($olddatabase, $newdatabase) = install_installation_sets($installationdir);
-
- $installer::logger::Lang->print("\n");
- $installer::logger::Lang->add_timestamp("Performance Info: Starting synchronization of installation sets");
-
- # Synchronizing installed products, allowing only different files with PATCH flag
- $installer::logger::Info->printf("... synchronizing installation sets ...\n");
- synchronize_installation_sets($olddatabase, $newdatabase, $filesarray);
-
- $installer::logger::Lang->print("\n");
- $installer::logger::Lang->add_timestamp("Performance Info: Starting pcp file creation");
-
- # Create pcp file
- $installer::logger::Info->printf("... creating pcp file ...\n");
-
- my $localmspdir = installer::systemactions::create_directories("msp", $languagestringref);
-
- if ( ! $allvariables->{'PCPFILENAME'} ) { installer::exiter::exit_program("ERROR: Property \"PCPFILENAME\" has to be defined.", "create_msp_patch"); }
- my $pcpfilename = $allvariables->{'PCPFILENAME'};
-
- if ( $installer::globals::languagepack ) { $pcpfilename =~ s/.pcp\s*$/languagepack.pcp/; }
-
- # Searching the pcp file in the include pathes
- my $fullpcpfilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$pcpfilename, $includepatharrayref, 1);
- if ( $$fullpcpfilenameref eq "" ) { installer::exiter::exit_program("ERROR: pcp file not found: $pcpfilename !", "create_msp_patch"); }
- my $fullpcpfilenamesource = $$fullpcpfilenameref;
-
- # Copying pcp file
- my $fullpcpfilename = $localmspdir . $installer::globals::separator . $pcpfilename;
- installer::systemactions::copy_one_file($fullpcpfilenamesource, $fullpcpfilename);
-
- # a. Extracting tables from msi database: msidb.exe -d <msifile> -f <directory> -e File Media, ...
- # b. Changing content of msi database in tables: File, Media, Directory, FeatureComponent
- # c. Including tables into msi database: msidb.exe -d <msifile> -f <directory> -i File Media, ...
-
- # Unpacking tables from pcp file
- extract_all_tables_from_pcpfile($fullpcpfilename, $localmspdir);
-
- # Tables, that need to be edited
- my $tablelist = "Properties TargetImages UpgradedImages ImageFamilies PatchMetadata PatchSequence"; # required tables
-
- # Saving all tables
- check_and_save_tables($tablelist, $localmspdir);
-
- # Setting the name of the new msp file
- my $mspfilename = set_mspfilename($allvariables, $mspdir, $languagesarrayref);
-
- # Editing tables
- edit_tables($tablelist, $localmspdir, $olddatabase, $newdatabase, $mspfilename, $allvariables, $languagestringref);
-
- # Adding edited tables into pcp file
- include_tables_into_pcpfile($fullpcpfilename, $localmspdir, $tablelist);
-
- # Start msimsp.exe
- $installer::logger::Lang->print("\n");
- $installer::logger::Lang->add_timestamp("Performance Info: Starting msimsp.exe");
- my $msimsplogfile = execute_msimsp($fullpcpfilename, $mspfilename, $localmspdir);
-
- # Copy final installation set next to msp file
- $installer::logger::Lang->print("\n");
- $installer::logger::Lang->add_timestamp("Performance Info: Copying installation set");
- $installer::logger::Info->printf("... copying installation set ...\n");
-
- my $oldinstallationsetpath = $installer::globals::updatedatabasepath;
-
- if ( $^O =~ /cygwin/i ) { $oldinstallationsetpath =~ s/\\/\//g; }
-
- installer::pathanalyzer::get_path_from_fullqualifiedname(\$oldinstallationsetpath);
- installer::systemactions::copy_complete_directory($oldinstallationsetpath, $mspdir);
-
- # Copying additional patches into the installation set, if required
- if (( $allvariables->{'ADDITIONALREQUIREDPATCHES'} ) && ( $allvariables->{'ADDITIONALREQUIREDPATCHES'} ne "" ) && ( ! $installer::globals::languagepack ))
- {
- my $filename = $allvariables->{'ADDITIONALREQUIREDPATCHES'};
-
- my $fullfilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$filename, $includepatharrayref, 1);
- if ( $$fullfilenameref eq "" ) { installer::exiter::exit_program("ERROR: Could not find file with required patches, although it is defined: $filename !", "create_msp_patch"); }
- my $fullfilename = $$fullfilenameref;
-
- # Reading list file
- my $listfile = installer::files::read_file($fullfilename);
-
- # Get name and path of reference database
- my $requiredpatchfile = get_requiredpatchfile_from_list($listfile, $languagestringref, $fullfilename);
- if ( $requiredpatchfile eq "" ) { installer::exiter::exit_program("ERROR: Could not find path to required patch in file $fullfilename for language(s) $$languagestringref!", "create_msp_patch"); }
-
- # Copying patch file
- installer::systemactions::copy_one_file($requiredpatchfile, $mspdir);
- # my $infoline = "Copy $requiredpatchfile to $mspdir\n";
- # $installer::logger::Lang->print($infoline);
- }
-
- # Find all files included into the patch
- # Analyzing the msimsp log file $msimsplogfile
- analyze_msimsp_logfile($msimsplogfile, $filesarray);
-
- # Done
- $installer::logger::Lang->print("\n");
- $installer::logger::Lang->add_timestamp("Performance Info: msp creation done");
-
- return $mspdir;
-}
-
-1;