1*b1cdbd2cSJim Jagielski#************************************************************** 2*b1cdbd2cSJim Jagielski# 3*b1cdbd2cSJim Jagielski# Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski# or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski# distributed with this work for additional information 6*b1cdbd2cSJim Jagielski# regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski# to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski# "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski# with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski# 11*b1cdbd2cSJim Jagielski# http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski# 13*b1cdbd2cSJim Jagielski# Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski# software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski# KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski# specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski# under the License. 19*b1cdbd2cSJim Jagielski# 20*b1cdbd2cSJim Jagielski#************************************************************** 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielskipackage installer::windows::msiglobal; 25*b1cdbd2cSJim Jagielski 26*b1cdbd2cSJim Jagielskiuse Cwd; 27*b1cdbd2cSJim Jagielskiuse Digest::MD5; 28*b1cdbd2cSJim Jagielskiuse installer::converter; 29*b1cdbd2cSJim Jagielskiuse installer::exiter; 30*b1cdbd2cSJim Jagielskiuse installer::files; 31*b1cdbd2cSJim Jagielskiuse installer::globals; 32*b1cdbd2cSJim Jagielskiuse installer::logger; 33*b1cdbd2cSJim Jagielskiuse installer::pathanalyzer; 34*b1cdbd2cSJim Jagielskiuse installer::remover; 35*b1cdbd2cSJim Jagielskiuse installer::scriptitems; 36*b1cdbd2cSJim Jagielskiuse installer::systemactions; 37*b1cdbd2cSJim Jagielskiuse installer::worker; 38*b1cdbd2cSJim Jagielskiuse installer::windows::idtglobal; 39*b1cdbd2cSJim Jagielskiuse installer::windows::language; 40*b1cdbd2cSJim Jagielskiuse installer::patch::ReleasesList; 41*b1cdbd2cSJim Jagielski 42*b1cdbd2cSJim Jagielskiuse strict; 43*b1cdbd2cSJim Jagielski 44*b1cdbd2cSJim Jagielski########################################################################### 45*b1cdbd2cSJim Jagielski# Generating the header of the ddf file. 46*b1cdbd2cSJim Jagielski# The usage of ddf files is needed, because makecab.exe can only include 47*b1cdbd2cSJim Jagielski# one sourcefile into a cab file 48*b1cdbd2cSJim Jagielski########################################################################### 49*b1cdbd2cSJim Jagielski 50*b1cdbd2cSJim Jagielskisub write_ddf_file_header 51*b1cdbd2cSJim Jagielski{ 52*b1cdbd2cSJim Jagielski my ($ddffileref, $cabinetfile, $installdir) = @_; 53*b1cdbd2cSJim Jagielski 54*b1cdbd2cSJim Jagielski my $oneline; 55*b1cdbd2cSJim Jagielski 56*b1cdbd2cSJim Jagielski $oneline = ".Set CabinetName1=" . $cabinetfile . "\n"; 57*b1cdbd2cSJim Jagielski push(@{$ddffileref} ,$oneline); 58*b1cdbd2cSJim Jagielski $oneline = ".Set ReservePerCabinetSize=128\n"; # This reserves space for a digital signature. 59*b1cdbd2cSJim Jagielski push(@{$ddffileref} ,$oneline); 60*b1cdbd2cSJim Jagielski $oneline = ".Set MaxDiskSize=2147483648\n"; # This allows the .cab file to get a size of 2 GB. 61*b1cdbd2cSJim Jagielski push(@{$ddffileref} ,$oneline); 62*b1cdbd2cSJim Jagielski $oneline = ".Set CompressionType=LZX\n"; 63*b1cdbd2cSJim Jagielski push(@{$ddffileref} ,$oneline); 64*b1cdbd2cSJim Jagielski $oneline = ".Set Compress=ON\n"; 65*b1cdbd2cSJim Jagielski push(@{$ddffileref} ,$oneline); 66*b1cdbd2cSJim Jagielski $oneline = ".Set CompressionLevel=$installer::globals::cabfilecompressionlevel\n"; 67*b1cdbd2cSJim Jagielski push(@{$ddffileref} ,$oneline); 68*b1cdbd2cSJim Jagielski $oneline = ".Set Cabinet=ON\n"; 69*b1cdbd2cSJim Jagielski push(@{$ddffileref} ,$oneline); 70*b1cdbd2cSJim Jagielski $oneline = ".Set DiskDirectoryTemplate=" . $installdir . "\n"; 71*b1cdbd2cSJim Jagielski push(@{$ddffileref} ,$oneline); 72*b1cdbd2cSJim Jagielski} 73*b1cdbd2cSJim Jagielski 74*b1cdbd2cSJim Jagielski########################################################################## 75*b1cdbd2cSJim Jagielski# Lines in ddf files must not contain more than 256 characters 76*b1cdbd2cSJim Jagielski########################################################################## 77*b1cdbd2cSJim Jagielski 78*b1cdbd2cSJim Jagielskisub check_ddf_file 79*b1cdbd2cSJim Jagielski{ 80*b1cdbd2cSJim Jagielski my ( $ddffile, $ddffilename ) = @_; 81*b1cdbd2cSJim Jagielski 82*b1cdbd2cSJim Jagielski my $maxlength = 0; 83*b1cdbd2cSJim Jagielski my $maxline = 0; 84*b1cdbd2cSJim Jagielski my $linelength = 0; 85*b1cdbd2cSJim Jagielski my $linenumber = 0; 86*b1cdbd2cSJim Jagielski 87*b1cdbd2cSJim Jagielski for ( my $i = 0; $i <= $#{$ddffile}; $i++ ) 88*b1cdbd2cSJim Jagielski { 89*b1cdbd2cSJim Jagielski my $oneline = ${$ddffile}[$i]; 90*b1cdbd2cSJim Jagielski 91*b1cdbd2cSJim Jagielski $linelength = length($oneline); 92*b1cdbd2cSJim Jagielski $linenumber = $i + 1; 93*b1cdbd2cSJim Jagielski 94*b1cdbd2cSJim Jagielski if ( $linelength > 256 ) 95*b1cdbd2cSJim Jagielski { 96*b1cdbd2cSJim Jagielski installer::exiter::exit_program("ERROR \"$ddffilename\" line $linenumber: Lines in ddf files must not contain more than 256 characters!", "check_ddf_file"); 97*b1cdbd2cSJim Jagielski } 98*b1cdbd2cSJim Jagielski 99*b1cdbd2cSJim Jagielski if ( $linelength > $maxlength ) 100*b1cdbd2cSJim Jagielski { 101*b1cdbd2cSJim Jagielski $maxlength = $linelength; 102*b1cdbd2cSJim Jagielski $maxline = $linenumber; 103*b1cdbd2cSJim Jagielski } 104*b1cdbd2cSJim Jagielski } 105*b1cdbd2cSJim Jagielski 106*b1cdbd2cSJim Jagielski my $infoline = "Check of ddf file \"$ddffilename\": Maximum length \"$maxlength\" in line \"$maxline\" (allowed line length: 256 characters)\n"; 107*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 108*b1cdbd2cSJim Jagielski} 109*b1cdbd2cSJim Jagielski 110*b1cdbd2cSJim Jagielski########################################################################## 111*b1cdbd2cSJim Jagielski# Lines in ddf files must not be longer than 256 characters. 112*b1cdbd2cSJim Jagielski# Therefore it can be useful to use relative pathes. Then it is 113*b1cdbd2cSJim Jagielski# necessary to change into temp directory before calling 114*b1cdbd2cSJim Jagielski# makecab.exe. 115*b1cdbd2cSJim Jagielski########################################################################## 116*b1cdbd2cSJim Jagielski 117*b1cdbd2cSJim Jagielskisub make_relative_ddf_path 118*b1cdbd2cSJim Jagielski{ 119*b1cdbd2cSJim Jagielski my ( $sourcepath ) = @_; 120*b1cdbd2cSJim Jagielski 121*b1cdbd2cSJim Jagielski my $windowstemppath = $installer::globals::temppath; 122*b1cdbd2cSJim Jagielski 123*b1cdbd2cSJim Jagielski if ( $^O =~ /cygwin/i ) 124*b1cdbd2cSJim Jagielski { 125*b1cdbd2cSJim Jagielski $windowstemppath = $installer::globals::cyg_temppath; 126*b1cdbd2cSJim Jagielski } 127*b1cdbd2cSJim Jagielski 128*b1cdbd2cSJim Jagielski $sourcepath =~ s/\Q$windowstemppath\E//; 129*b1cdbd2cSJim Jagielski $sourcepath =~ s/^\\//; 130*b1cdbd2cSJim Jagielski 131*b1cdbd2cSJim Jagielski return $sourcepath; 132*b1cdbd2cSJim Jagielski} 133*b1cdbd2cSJim Jagielski 134*b1cdbd2cSJim Jagielski 135*b1cdbd2cSJim Jagielski########################################################################## 136*b1cdbd2cSJim Jagielski# Generation the list, in which the source of the files is connected 137*b1cdbd2cSJim Jagielski# with the cabinet destination file. Because more than one file needs 138*b1cdbd2cSJim Jagielski# to be included into a cab file, this has to be done via ddf files. 139*b1cdbd2cSJim Jagielski########################################################################## 140*b1cdbd2cSJim Jagielski 141*b1cdbd2cSJim Jagielskisub generate_cab_file_list ($$$$) 142*b1cdbd2cSJim Jagielski{ 143*b1cdbd2cSJim Jagielski my ($filesref, $installdir, $ddfdir, $allvariables) = @_; 144*b1cdbd2cSJim Jagielski 145*b1cdbd2cSJim Jagielski installer::logger::include_header_into_logfile("Generating ddf files"); 146*b1cdbd2cSJim Jagielski 147*b1cdbd2cSJim Jagielski if ( $^O =~ /cygwin/i ) 148*b1cdbd2cSJim Jagielski { 149*b1cdbd2cSJim Jagielski installer::worker::generate_cygwin_pathes($filesref); 150*b1cdbd2cSJim Jagielski } 151*b1cdbd2cSJim Jagielski 152*b1cdbd2cSJim Jagielski # Make sure that all files point to the same cabinet file. 153*b1cdbd2cSJim Jagielski # Multiple cabinet files are not supported anymore. 154*b1cdbd2cSJim Jagielski my $cabinetfile = $filesref->[0]->{'cabinet'}; 155*b1cdbd2cSJim Jagielski foreach my $onefile (@$filesref) 156*b1cdbd2cSJim Jagielski { 157*b1cdbd2cSJim Jagielski if ($onefile->{'cabinet'} ne $cabinetfile) 158*b1cdbd2cSJim Jagielski { 159*b1cdbd2cSJim Jagielski installer::exiter::exit_program( 160*b1cdbd2cSJim Jagielski "ERROR: multiple cabinet files are not supported", 161*b1cdbd2cSJim Jagielski "generate_cab_file_list"); 162*b1cdbd2cSJim Jagielski } 163*b1cdbd2cSJim Jagielski } 164*b1cdbd2cSJim Jagielski 165*b1cdbd2cSJim Jagielski # Sort files on the sequence number. 166*b1cdbd2cSJim Jagielski my @sorted_files = sort {$a->{'sequencenumber'} <=> $b->{'sequencenumber'}} @$filesref; 167*b1cdbd2cSJim Jagielski 168*b1cdbd2cSJim Jagielski my @ddffile = (); 169*b1cdbd2cSJim Jagielski write_ddf_file_header(\@ddffile, $cabinetfile, $installdir); 170*b1cdbd2cSJim Jagielski foreach my $onefile (@sorted_files) 171*b1cdbd2cSJim Jagielski { 172*b1cdbd2cSJim Jagielski my $styles = $onefile->{'Styles'}; 173*b1cdbd2cSJim Jagielski $styles = "" unless defined $styles; 174*b1cdbd2cSJim Jagielski if ($styles =~ /\bDONT_PACK\b/) 175*b1cdbd2cSJim Jagielski { 176*b1cdbd2cSJim Jagielski $installer::logger::Lang->printf(" excluding '%s' from ddf\n", $onefile->{'uniquename'}); 177*b1cdbd2cSJim Jagielski } 178*b1cdbd2cSJim Jagielski 179*b1cdbd2cSJim Jagielski my $uniquename = $onefile->{'uniquename'}; 180*b1cdbd2cSJim Jagielski my $sourcepath = $onefile->{'sourcepath'}; 181*b1cdbd2cSJim Jagielski if ( $^O =~ /cygwin/i ) 182*b1cdbd2cSJim Jagielski { 183*b1cdbd2cSJim Jagielski $sourcepath = $onefile->{'cyg_sourcepath'}; 184*b1cdbd2cSJim Jagielski } 185*b1cdbd2cSJim Jagielski 186*b1cdbd2cSJim Jagielski # to avoid lines with more than 256 characters, it can be useful to use relative pathes 187*b1cdbd2cSJim Jagielski if ($allvariables->{'RELATIVE_PATHES_IN_DDF'}) 188*b1cdbd2cSJim Jagielski { 189*b1cdbd2cSJim Jagielski $sourcepath = make_relative_ddf_path($sourcepath); 190*b1cdbd2cSJim Jagielski } 191*b1cdbd2cSJim Jagielski 192*b1cdbd2cSJim Jagielski my $ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n"; 193*b1cdbd2cSJim Jagielski push(@ddffile, $ddfline); 194*b1cdbd2cSJim Jagielski 195*b1cdbd2cSJim Jagielski $installer::logger::Lang->printf(" adding '%s' with sequence %d to ddf\n", 196*b1cdbd2cSJim Jagielski $onefile->{'uniquename'}, 197*b1cdbd2cSJim Jagielski $onefile->{'sequencenumber'}); 198*b1cdbd2cSJim Jagielski } 199*b1cdbd2cSJim Jagielski # creating the DDF file 200*b1cdbd2cSJim Jagielski 201*b1cdbd2cSJim Jagielski my $ddffilename = $cabinetfile; 202*b1cdbd2cSJim Jagielski $ddffilename =~ s/.cab/.ddf/; 203*b1cdbd2cSJim Jagielski $ddfdir =~ s/\Q$installer::globals::separator\E\s*$//; 204*b1cdbd2cSJim Jagielski $ddffilename = $ddfdir . $installer::globals::separator . $ddffilename; 205*b1cdbd2cSJim Jagielski 206*b1cdbd2cSJim Jagielski installer::files::save_file($ddffilename ,\@ddffile); 207*b1cdbd2cSJim Jagielski $installer::logger::Lang->print("Created ddf file: %s\n", $ddffilename); 208*b1cdbd2cSJim Jagielski 209*b1cdbd2cSJim Jagielski # lines in ddf files must not be longer than 256 characters 210*b1cdbd2cSJim Jagielski check_ddf_file(\@ddffile, $ddffilename); 211*b1cdbd2cSJim Jagielski 212*b1cdbd2cSJim Jagielski # collecting all ddf files 213*b1cdbd2cSJim Jagielski push(@installer::globals::allddffiles, $ddffilename); 214*b1cdbd2cSJim Jagielski 215*b1cdbd2cSJim Jagielski # Writing the makecab system call 216*b1cdbd2cSJim Jagielski # Return a list with all system calls for packaging process. 217*b1cdbd2cSJim Jagielski my @cabfilelist = ("makecab.exe /V3 /F " . $ddffilename . " 2\>\&1 |" . "\n"); 218*b1cdbd2cSJim Jagielski return \@cabfilelist; 219*b1cdbd2cSJim Jagielski} 220*b1cdbd2cSJim Jagielski 221*b1cdbd2cSJim Jagielski 222*b1cdbd2cSJim Jagielski 223*b1cdbd2cSJim Jagielski################################################################# 224*b1cdbd2cSJim Jagielski# Returning the name of the msi database 225*b1cdbd2cSJim Jagielski################################################################# 226*b1cdbd2cSJim Jagielski 227*b1cdbd2cSJim Jagielskisub get_msidatabasename 228*b1cdbd2cSJim Jagielski{ 229*b1cdbd2cSJim Jagielski my ($allvariableshashref, $language) = @_; 230*b1cdbd2cSJim Jagielski 231*b1cdbd2cSJim Jagielski my $databasename = $allvariableshashref->{'PRODUCTNAME'} . $allvariableshashref->{'PRODUCTVERSION'}; 232*b1cdbd2cSJim Jagielski $databasename = lc($databasename); 233*b1cdbd2cSJim Jagielski $databasename =~ s/\.//g; 234*b1cdbd2cSJim Jagielski $databasename =~ s/\-//g; 235*b1cdbd2cSJim Jagielski $databasename =~ s/\s//g; 236*b1cdbd2cSJim Jagielski 237*b1cdbd2cSJim Jagielski # possibility to overwrite the name with variable DATABASENAME 238*b1cdbd2cSJim Jagielski if ( $allvariableshashref->{'DATABASENAME'} ) 239*b1cdbd2cSJim Jagielski { 240*b1cdbd2cSJim Jagielski $databasename = $allvariableshashref->{'DATABASENAME'}; 241*b1cdbd2cSJim Jagielski } 242*b1cdbd2cSJim Jagielski 243*b1cdbd2cSJim Jagielski if ( $language ) 244*b1cdbd2cSJim Jagielski { 245*b1cdbd2cSJim Jagielski if (!($language eq "")) 246*b1cdbd2cSJim Jagielski { 247*b1cdbd2cSJim Jagielski $databasename .= "_$language"; 248*b1cdbd2cSJim Jagielski } 249*b1cdbd2cSJim Jagielski } 250*b1cdbd2cSJim Jagielski 251*b1cdbd2cSJim Jagielski $databasename .= ".msi"; 252*b1cdbd2cSJim Jagielski 253*b1cdbd2cSJim Jagielski return $databasename; 254*b1cdbd2cSJim Jagielski} 255*b1cdbd2cSJim Jagielski 256*b1cdbd2cSJim Jagielski################################################################# 257*b1cdbd2cSJim Jagielski# Creating the msi database 258*b1cdbd2cSJim Jagielski# This works only on Windows 259*b1cdbd2cSJim Jagielski################################################################# 260*b1cdbd2cSJim Jagielski 261*b1cdbd2cSJim Jagielskisub create_msi_database 262*b1cdbd2cSJim Jagielski{ 263*b1cdbd2cSJim Jagielski my ($idtdirbase ,$msifilename) = @_; 264*b1cdbd2cSJim Jagielski 265*b1cdbd2cSJim Jagielski # -f : path containing the idt files 266*b1cdbd2cSJim Jagielski # -d : msi database, including path 267*b1cdbd2cSJim Jagielski # -c : create database 268*b1cdbd2cSJim Jagielski # -i : include the following tables ("*" includes all available tables) 269*b1cdbd2cSJim Jagielski 270*b1cdbd2cSJim Jagielski my $msidb = "msidb.exe"; # Has to be in the path 271*b1cdbd2cSJim Jagielski my $extraslash = ""; # Has to be set for non-ActiveState perl 272*b1cdbd2cSJim Jagielski 273*b1cdbd2cSJim Jagielski installer::logger::include_header_into_logfile("Creating msi database"); 274*b1cdbd2cSJim Jagielski 275*b1cdbd2cSJim Jagielski $idtdirbase = installer::converter::make_path_conform($idtdirbase); 276*b1cdbd2cSJim Jagielski 277*b1cdbd2cSJim Jagielski $msifilename = installer::converter::make_path_conform($msifilename); 278*b1cdbd2cSJim Jagielski 279*b1cdbd2cSJim Jagielski if ( $^O =~ /cygwin/i ) { 280*b1cdbd2cSJim Jagielski # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) 281*b1cdbd2cSJim Jagielski $idtdirbase =~ s/\//\\\\/g; 282*b1cdbd2cSJim Jagielski $msifilename =~ s/\//\\\\/g; 283*b1cdbd2cSJim Jagielski $extraslash = "\\"; 284*b1cdbd2cSJim Jagielski } 285*b1cdbd2cSJim Jagielski my $systemcall = $msidb . " -f " . $idtdirbase . " -d " . $msifilename . " -c " . "-i " . $extraslash . "*"; 286*b1cdbd2cSJim Jagielski 287*b1cdbd2cSJim Jagielski my $returnvalue = system($systemcall); 288*b1cdbd2cSJim Jagielski 289*b1cdbd2cSJim Jagielski my $infoline = "Systemcall: $systemcall\n"; 290*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 291*b1cdbd2cSJim Jagielski 292*b1cdbd2cSJim Jagielski if ($returnvalue) 293*b1cdbd2cSJim Jagielski { 294*b1cdbd2cSJim Jagielski $infoline = "ERROR: Could not execute $msidb!\n"; 295*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 296*b1cdbd2cSJim Jagielski } 297*b1cdbd2cSJim Jagielski else 298*b1cdbd2cSJim Jagielski { 299*b1cdbd2cSJim Jagielski $infoline = "Success: Executed $msidb successfully!\n"; 300*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 301*b1cdbd2cSJim Jagielski } 302*b1cdbd2cSJim Jagielski} 303*b1cdbd2cSJim Jagielski 304*b1cdbd2cSJim Jagielski##################################################################### 305*b1cdbd2cSJim Jagielski# Returning the value from sis.mlf for Summary Information Stream 306*b1cdbd2cSJim Jagielski##################################################################### 307*b1cdbd2cSJim Jagielski 308*b1cdbd2cSJim Jagielskisub get_value_from_sis_lng 309*b1cdbd2cSJim Jagielski{ 310*b1cdbd2cSJim Jagielski my ($language, $languagefile, $searchstring) = @_; 311*b1cdbd2cSJim Jagielski 312*b1cdbd2cSJim Jagielski my $language_block = installer::windows::idtglobal::get_language_block_from_language_file($searchstring, $languagefile); 313*b1cdbd2cSJim Jagielski my $newstring = installer::windows::idtglobal::get_language_string_from_language_block($language_block, $language, $searchstring); 314*b1cdbd2cSJim Jagielski $newstring = "\"" . $newstring . "\""; 315*b1cdbd2cSJim Jagielski 316*b1cdbd2cSJim Jagielski return $newstring; 317*b1cdbd2cSJim Jagielski} 318*b1cdbd2cSJim Jagielski 319*b1cdbd2cSJim Jagielski################################################################# 320*b1cdbd2cSJim Jagielski# Returning the msi version for the Summary Information Stream 321*b1cdbd2cSJim Jagielski################################################################# 322*b1cdbd2cSJim Jagielski 323*b1cdbd2cSJim Jagielskisub get_msiversion_for_sis 324*b1cdbd2cSJim Jagielski{ 325*b1cdbd2cSJim Jagielski my $msiversion = "200"; 326*b1cdbd2cSJim Jagielski return $msiversion; 327*b1cdbd2cSJim Jagielski} 328*b1cdbd2cSJim Jagielski 329*b1cdbd2cSJim Jagielski################################################################# 330*b1cdbd2cSJim Jagielski# Returning the word count for the Summary Information Stream 331*b1cdbd2cSJim Jagielski################################################################# 332*b1cdbd2cSJim Jagielski 333*b1cdbd2cSJim Jagielskisub get_wordcount_for_sis 334*b1cdbd2cSJim Jagielski{ 335*b1cdbd2cSJim Jagielski my $wordcount = "0"; 336*b1cdbd2cSJim Jagielski return $wordcount; 337*b1cdbd2cSJim Jagielski} 338*b1cdbd2cSJim Jagielski 339*b1cdbd2cSJim Jagielski################################################################# 340*b1cdbd2cSJim Jagielski# Returning the codepage for the Summary Information Stream 341*b1cdbd2cSJim Jagielski################################################################# 342*b1cdbd2cSJim Jagielski 343*b1cdbd2cSJim Jagielskisub get_codepage_for_sis 344*b1cdbd2cSJim Jagielski{ 345*b1cdbd2cSJim Jagielski my ( $language ) = @_; 346*b1cdbd2cSJim Jagielski 347*b1cdbd2cSJim Jagielski my $codepage = installer::windows::language::get_windows_encoding($language); 348*b1cdbd2cSJim Jagielski 349*b1cdbd2cSJim Jagielski # Codepage 65001 does not work in Summary Information Stream 350*b1cdbd2cSJim Jagielski if ( $codepage == 65001 ) { $codepage = 0; } 351*b1cdbd2cSJim Jagielski 352*b1cdbd2cSJim Jagielski # my $codepage = "1252"; # determine dynamically in a function 353*b1cdbd2cSJim Jagielski # my $codepage = "65001"; # UTF-8 354*b1cdbd2cSJim Jagielski return $codepage; 355*b1cdbd2cSJim Jagielski} 356*b1cdbd2cSJim Jagielski 357*b1cdbd2cSJim Jagielski################################################################# 358*b1cdbd2cSJim Jagielski# Returning the template for the Summary Information Stream 359*b1cdbd2cSJim Jagielski################################################################# 360*b1cdbd2cSJim Jagielski 361*b1cdbd2cSJim Jagielskisub get_template_for_sis 362*b1cdbd2cSJim Jagielski{ 363*b1cdbd2cSJim Jagielski my ( $language, $allvariables ) = @_; 364*b1cdbd2cSJim Jagielski 365*b1cdbd2cSJim Jagielski my $windowslanguage = installer::windows::language::get_windows_language($language); 366*b1cdbd2cSJim Jagielski 367*b1cdbd2cSJim Jagielski my $architecture = "Intel"; 368*b1cdbd2cSJim Jagielski 369*b1cdbd2cSJim Jagielski # Adding 256, if this is a 64 bit installation set. 370*b1cdbd2cSJim Jagielski if (( $allvariables->{'64BITPRODUCT'} ) && ( $allvariables->{'64BITPRODUCT'} == 1 )) { $architecture = "x64"; } 371*b1cdbd2cSJim Jagielski 372*b1cdbd2cSJim Jagielski my $value = "\"" . $architecture . ";" . $windowslanguage; # adding the Windows language 373*b1cdbd2cSJim Jagielski 374*b1cdbd2cSJim Jagielski $value = $value . "\""; # adding ending '"' 375*b1cdbd2cSJim Jagielski 376*b1cdbd2cSJim Jagielski return $value ; 377*b1cdbd2cSJim Jagielski} 378*b1cdbd2cSJim Jagielski 379*b1cdbd2cSJim Jagielski################################################################# 380*b1cdbd2cSJim Jagielski# Returning the PackageCode for the Summary Information Stream 381*b1cdbd2cSJim Jagielski################################################################# 382*b1cdbd2cSJim Jagielski 383*b1cdbd2cSJim Jagielskisub get_packagecode_for_sis 384*b1cdbd2cSJim Jagielski{ 385*b1cdbd2cSJim Jagielski # always generating a new package code for each package 386*b1cdbd2cSJim Jagielski 387*b1cdbd2cSJim Jagielski my $guid = "\{" . create_guid() . "\}"; 388*b1cdbd2cSJim Jagielski 389*b1cdbd2cSJim Jagielski my $infoline = "PackageCode: $guid\n"; 390*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 391*b1cdbd2cSJim Jagielski 392*b1cdbd2cSJim Jagielski return $guid; 393*b1cdbd2cSJim Jagielski} 394*b1cdbd2cSJim Jagielski 395*b1cdbd2cSJim Jagielski################################################################# 396*b1cdbd2cSJim Jagielski# Returning the title for the Summary Information Stream 397*b1cdbd2cSJim Jagielski################################################################# 398*b1cdbd2cSJim Jagielski 399*b1cdbd2cSJim Jagielskisub get_title_for_sis 400*b1cdbd2cSJim Jagielski{ 401*b1cdbd2cSJim Jagielski my ( $language, $languagefile, $searchstring ) = @_; 402*b1cdbd2cSJim Jagielski 403*b1cdbd2cSJim Jagielski my $title = get_value_from_sis_lng($language, $languagefile, $searchstring ); 404*b1cdbd2cSJim Jagielski 405*b1cdbd2cSJim Jagielski return $title; 406*b1cdbd2cSJim Jagielski} 407*b1cdbd2cSJim Jagielski 408*b1cdbd2cSJim Jagielski################################################################# 409*b1cdbd2cSJim Jagielski# Returning the author for the Summary Information Stream 410*b1cdbd2cSJim Jagielski################################################################# 411*b1cdbd2cSJim Jagielski 412*b1cdbd2cSJim Jagielskisub get_author_for_sis 413*b1cdbd2cSJim Jagielski{ 414*b1cdbd2cSJim Jagielski my $author = $installer::globals::longmanufacturer; 415*b1cdbd2cSJim Jagielski 416*b1cdbd2cSJim Jagielski $author = "\"" . $author . "\""; 417*b1cdbd2cSJim Jagielski 418*b1cdbd2cSJim Jagielski return $author; 419*b1cdbd2cSJim Jagielski} 420*b1cdbd2cSJim Jagielski 421*b1cdbd2cSJim Jagielski################################################################# 422*b1cdbd2cSJim Jagielski# Returning the subject for the Summary Information Stream 423*b1cdbd2cSJim Jagielski################################################################# 424*b1cdbd2cSJim Jagielski 425*b1cdbd2cSJim Jagielskisub get_subject_for_sis 426*b1cdbd2cSJim Jagielski{ 427*b1cdbd2cSJim Jagielski my ( $allvariableshashref ) = @_; 428*b1cdbd2cSJim Jagielski 429*b1cdbd2cSJim Jagielski my $subject = $allvariableshashref->{'PRODUCTNAME'} . " " . $allvariableshashref->{'PRODUCTVERSION'}; 430*b1cdbd2cSJim Jagielski 431*b1cdbd2cSJim Jagielski $subject = "\"" . $subject . "\""; 432*b1cdbd2cSJim Jagielski 433*b1cdbd2cSJim Jagielski return $subject; 434*b1cdbd2cSJim Jagielski} 435*b1cdbd2cSJim Jagielski 436*b1cdbd2cSJim Jagielski################################################################# 437*b1cdbd2cSJim Jagielski# Returning the comment for the Summary Information Stream 438*b1cdbd2cSJim Jagielski################################################################# 439*b1cdbd2cSJim Jagielski 440*b1cdbd2cSJim Jagielskisub get_comment_for_sis 441*b1cdbd2cSJim Jagielski{ 442*b1cdbd2cSJim Jagielski my ( $language, $languagefile, $searchstring ) = @_; 443*b1cdbd2cSJim Jagielski 444*b1cdbd2cSJim Jagielski my $comment = get_value_from_sis_lng($language, $languagefile, $searchstring ); 445*b1cdbd2cSJim Jagielski 446*b1cdbd2cSJim Jagielski return $comment; 447*b1cdbd2cSJim Jagielski} 448*b1cdbd2cSJim Jagielski 449*b1cdbd2cSJim Jagielski################################################################# 450*b1cdbd2cSJim Jagielski# Returning the keywords for the Summary Information Stream 451*b1cdbd2cSJim Jagielski################################################################# 452*b1cdbd2cSJim Jagielski 453*b1cdbd2cSJim Jagielskisub get_keywords_for_sis 454*b1cdbd2cSJim Jagielski{ 455*b1cdbd2cSJim Jagielski my ( $language, $languagefile, $searchstring ) = @_; 456*b1cdbd2cSJim Jagielski 457*b1cdbd2cSJim Jagielski my $keywords = get_value_from_sis_lng($language, $languagefile, $searchstring ); 458*b1cdbd2cSJim Jagielski 459*b1cdbd2cSJim Jagielski return $keywords; 460*b1cdbd2cSJim Jagielski} 461*b1cdbd2cSJim Jagielski 462*b1cdbd2cSJim Jagielski###################################################################### 463*b1cdbd2cSJim Jagielski# Returning the application name for the Summary Information Stream 464*b1cdbd2cSJim Jagielski###################################################################### 465*b1cdbd2cSJim Jagielski 466*b1cdbd2cSJim Jagielskisub get_appname_for_sis 467*b1cdbd2cSJim Jagielski{ 468*b1cdbd2cSJim Jagielski my ( $language, $languagefile, $searchstring ) = @_; 469*b1cdbd2cSJim Jagielski 470*b1cdbd2cSJim Jagielski my $appname = get_value_from_sis_lng($language, $languagefile, $searchstring ); 471*b1cdbd2cSJim Jagielski 472*b1cdbd2cSJim Jagielski return $appname; 473*b1cdbd2cSJim Jagielski} 474*b1cdbd2cSJim Jagielski 475*b1cdbd2cSJim Jagielski###################################################################### 476*b1cdbd2cSJim Jagielski# Returning the security for the Summary Information Stream 477*b1cdbd2cSJim Jagielski###################################################################### 478*b1cdbd2cSJim Jagielski 479*b1cdbd2cSJim Jagielskisub get_security_for_sis 480*b1cdbd2cSJim Jagielski{ 481*b1cdbd2cSJim Jagielski my $security = "0"; 482*b1cdbd2cSJim Jagielski return $security; 483*b1cdbd2cSJim Jagielski} 484*b1cdbd2cSJim Jagielski 485*b1cdbd2cSJim Jagielski################################################################# 486*b1cdbd2cSJim Jagielski# Writing the Summary information stream into the msi database 487*b1cdbd2cSJim Jagielski# This works only on Windows 488*b1cdbd2cSJim Jagielski################################################################# 489*b1cdbd2cSJim Jagielski 490*b1cdbd2cSJim Jagielskisub write_summary_into_msi_database 491*b1cdbd2cSJim Jagielski{ 492*b1cdbd2cSJim Jagielski my ($msifilename, $language, $languagefile, $allvariableshashref) = @_; 493*b1cdbd2cSJim Jagielski 494*b1cdbd2cSJim Jagielski # -g : requrired msi version 495*b1cdbd2cSJim Jagielski # -c : codepage 496*b1cdbd2cSJim Jagielski # -p : template 497*b1cdbd2cSJim Jagielski 498*b1cdbd2cSJim Jagielski installer::logger::include_header_into_logfile("Writing summary information stream"); 499*b1cdbd2cSJim Jagielski 500*b1cdbd2cSJim Jagielski my $msiinfo = "msiinfo.exe"; # Has to be in the path 501*b1cdbd2cSJim Jagielski 502*b1cdbd2cSJim Jagielski my $sislanguage = "en-US"; # title, comment, keyword and appname alway in english 503*b1cdbd2cSJim Jagielski 504*b1cdbd2cSJim Jagielski my $msiversion = get_msiversion_for_sis(); 505*b1cdbd2cSJim Jagielski my $codepage = get_codepage_for_sis($language); 506*b1cdbd2cSJim Jagielski my $template = get_template_for_sis($language, $allvariableshashref); 507*b1cdbd2cSJim Jagielski my $guid = get_packagecode_for_sis(); 508*b1cdbd2cSJim Jagielski my $title = get_title_for_sis($sislanguage,$languagefile, "OOO_SIS_TITLE"); 509*b1cdbd2cSJim Jagielski my $author = get_author_for_sis(); 510*b1cdbd2cSJim Jagielski my $subject = get_subject_for_sis($allvariableshashref); 511*b1cdbd2cSJim Jagielski my $comment = get_comment_for_sis($sislanguage,$languagefile, "OOO_SIS_COMMENT"); 512*b1cdbd2cSJim Jagielski my $keywords = get_keywords_for_sis($sislanguage,$languagefile, "OOO_SIS_KEYWORDS"); 513*b1cdbd2cSJim Jagielski my $appname = get_appname_for_sis($sislanguage,$languagefile, "OOO_SIS_APPNAME"); 514*b1cdbd2cSJim Jagielski my $security = get_security_for_sis(); 515*b1cdbd2cSJim Jagielski my $wordcount = get_wordcount_for_sis(); 516*b1cdbd2cSJim Jagielski 517*b1cdbd2cSJim Jagielski $msifilename = installer::converter::make_path_conform($msifilename); 518*b1cdbd2cSJim Jagielski 519*b1cdbd2cSJim Jagielski my $systemcall = $msiinfo . " " . $msifilename . " -g " . $msiversion . " -c " . $codepage 520*b1cdbd2cSJim Jagielski . " -p " . $template . " -v " . $guid . " -t " . $title . " -a " . $author 521*b1cdbd2cSJim Jagielski . " -j " . $subject . " -o " . $comment . " -k " . $keywords . " -n " . $appname 522*b1cdbd2cSJim Jagielski . " -u " . $security . " -w " . $wordcount; 523*b1cdbd2cSJim Jagielski 524*b1cdbd2cSJim Jagielski my $returnvalue = system($systemcall); 525*b1cdbd2cSJim Jagielski 526*b1cdbd2cSJim Jagielski my $infoline = "Systemcall: $systemcall\n"; 527*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 528*b1cdbd2cSJim Jagielski 529*b1cdbd2cSJim Jagielski if ($returnvalue) 530*b1cdbd2cSJim Jagielski { 531*b1cdbd2cSJim Jagielski $infoline = "ERROR: Could not execute $msiinfo!\n"; 532*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 533*b1cdbd2cSJim Jagielski } 534*b1cdbd2cSJim Jagielski else 535*b1cdbd2cSJim Jagielski { 536*b1cdbd2cSJim Jagielski $infoline = "Success: Executed $msiinfo successfully!\n"; 537*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 538*b1cdbd2cSJim Jagielski } 539*b1cdbd2cSJim Jagielski} 540*b1cdbd2cSJim Jagielski 541*b1cdbd2cSJim Jagielski######################################################################### 542*b1cdbd2cSJim Jagielski# For more than one language in the installation set: 543*b1cdbd2cSJim Jagielski# Use one database and create Transformations for all other languages 544*b1cdbd2cSJim Jagielski######################################################################### 545*b1cdbd2cSJim Jagielski 546*b1cdbd2cSJim Jagielskisub create_transforms 547*b1cdbd2cSJim Jagielski{ 548*b1cdbd2cSJim Jagielski my ($languagesarray, $defaultlanguage, $installdir, $allvariableshashref) = @_; 549*b1cdbd2cSJim Jagielski 550*b1cdbd2cSJim Jagielski installer::logger::include_header_into_logfile("Creating Transforms"); 551*b1cdbd2cSJim Jagielski 552*b1cdbd2cSJim Jagielski my $msitran = "msitran.exe"; # Has to be in the path 553*b1cdbd2cSJim Jagielski 554*b1cdbd2cSJim Jagielski $installdir = installer::converter::make_path_conform($installdir); 555*b1cdbd2cSJim Jagielski 556*b1cdbd2cSJim Jagielski # Syntax for creating a transformation 557*b1cdbd2cSJim Jagielski # msitran.exe -g <baseDB> <referenceDB> <transformfile> [<errorhandling>} 558*b1cdbd2cSJim Jagielski 559*b1cdbd2cSJim Jagielski my $basedbname = get_msidatabasename($allvariableshashref, $defaultlanguage); 560*b1cdbd2cSJim Jagielski $basedbname = $installdir . $installer::globals::separator . $basedbname; 561*b1cdbd2cSJim Jagielski 562*b1cdbd2cSJim Jagielski my $errorhandling = "f"; # Suppress "change codepage" error 563*b1cdbd2cSJim Jagielski 564*b1cdbd2cSJim Jagielski # Iterating over all files 565*b1cdbd2cSJim Jagielski 566*b1cdbd2cSJim Jagielski foreach ( @{$languagesarray} ) 567*b1cdbd2cSJim Jagielski { 568*b1cdbd2cSJim Jagielski my $onelanguage = $_; 569*b1cdbd2cSJim Jagielski 570*b1cdbd2cSJim Jagielski if ( $onelanguage eq $defaultlanguage ) { next; } 571*b1cdbd2cSJim Jagielski 572*b1cdbd2cSJim Jagielski my $referencedbname = get_msidatabasename($allvariableshashref, $onelanguage); 573*b1cdbd2cSJim Jagielski $referencedbname = $installdir . $installer::globals::separator . $referencedbname; 574*b1cdbd2cSJim Jagielski 575*b1cdbd2cSJim Jagielski my $transformfile = $installdir . $installer::globals::separator . "trans_" . $onelanguage . ".mst"; 576*b1cdbd2cSJim Jagielski 577*b1cdbd2cSJim Jagielski my $systemcall = $msitran . " " . " -g " . $basedbname . " " . $referencedbname . " " . $transformfile . " " . $errorhandling; 578*b1cdbd2cSJim Jagielski 579*b1cdbd2cSJim Jagielski my $returnvalue = system($systemcall); 580*b1cdbd2cSJim Jagielski 581*b1cdbd2cSJim Jagielski my $infoline = "Systemcall: $systemcall\n"; 582*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 583*b1cdbd2cSJim Jagielski 584*b1cdbd2cSJim Jagielski # Problem: msitran.exe in version 4.0 always returns "1", even if no failure occured. 585*b1cdbd2cSJim Jagielski # Therefore it has to be checked, if this is version 4.0. If yes, if the mst file 586*b1cdbd2cSJim Jagielski # exists and if it is larger than 0 bytes. If this is true, then no error occured. 587*b1cdbd2cSJim Jagielski # File Version of msitran.exe: 4.0.6000.16384 has checksum: "b66190a70145a57773ec769e16777b29". 588*b1cdbd2cSJim Jagielski # Same for msitran.exe from wntmsci12: "aa25d3445b94ffde8ef0c1efb77a56b8" 589*b1cdbd2cSJim Jagielski 590*b1cdbd2cSJim Jagielski if ($returnvalue) 591*b1cdbd2cSJim Jagielski { 592*b1cdbd2cSJim Jagielski $infoline = "WARNING: Returnvalue of $msitran is not 0. Checking version of $msitran!\n"; 593*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 594*b1cdbd2cSJim Jagielski 595*b1cdbd2cSJim Jagielski open(FILE, "<$installer::globals::msitranpath") or die "ERROR: Can't open $installer::globals::msitranpath for creating file hash"; 596*b1cdbd2cSJim Jagielski binmode(FILE); 597*b1cdbd2cSJim Jagielski my $digest = Digest::MD5->new->addfile(*FILE)->hexdigest; 598*b1cdbd2cSJim Jagielski close(FILE); 599*b1cdbd2cSJim Jagielski 600*b1cdbd2cSJim Jagielski my @problemchecksums = ("b66190a70145a57773ec769e16777b29", "aa25d3445b94ffde8ef0c1efb77a56b8"); 601*b1cdbd2cSJim Jagielski my $isproblemchecksum = 0; 602*b1cdbd2cSJim Jagielski 603*b1cdbd2cSJim Jagielski foreach my $problemchecksum ( @problemchecksums ) 604*b1cdbd2cSJim Jagielski { 605*b1cdbd2cSJim Jagielski $infoline = "Checksum of problematic MsiTran.exe: $problemchecksum\n"; 606*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 607*b1cdbd2cSJim Jagielski $infoline = "Checksum of used MsiTran.exe: $digest\n"; 608*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 609*b1cdbd2cSJim Jagielski if ( $digest eq $problemchecksum ) { $isproblemchecksum = 1; } 610*b1cdbd2cSJim Jagielski } 611*b1cdbd2cSJim Jagielski 612*b1cdbd2cSJim Jagielski if ( $isproblemchecksum ) 613*b1cdbd2cSJim Jagielski { 614*b1cdbd2cSJim Jagielski # Check existence of mst 615*b1cdbd2cSJim Jagielski if ( -f $transformfile ) 616*b1cdbd2cSJim Jagielski { 617*b1cdbd2cSJim Jagielski $infoline = "File $transformfile exists.\n"; 618*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 619*b1cdbd2cSJim Jagielski my $filesize = ( -s $transformfile ); 620*b1cdbd2cSJim Jagielski $infoline = "Size of $transformfile: $filesize\n"; 621*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 622*b1cdbd2cSJim Jagielski 623*b1cdbd2cSJim Jagielski if ( $filesize > 0 ) 624*b1cdbd2cSJim Jagielski { 625*b1cdbd2cSJim Jagielski $infoline = "Info: Returnvalue $returnvalue of $msitran is no problem :-) .\n"; 626*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 627*b1cdbd2cSJim Jagielski $returnvalue = 0; # reset the error 628*b1cdbd2cSJim Jagielski } 629*b1cdbd2cSJim Jagielski else 630*b1cdbd2cSJim Jagielski { 631*b1cdbd2cSJim Jagielski $infoline = "Filesize indicates that an error occured.\n"; 632*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 633*b1cdbd2cSJim Jagielski } 634*b1cdbd2cSJim Jagielski } 635*b1cdbd2cSJim Jagielski else 636*b1cdbd2cSJim Jagielski { 637*b1cdbd2cSJim Jagielski $infoline = "File $transformfile does not exist -> An error occured.\n"; 638*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 639*b1cdbd2cSJim Jagielski } 640*b1cdbd2cSJim Jagielski } 641*b1cdbd2cSJim Jagielski else 642*b1cdbd2cSJim Jagielski { 643*b1cdbd2cSJim Jagielski $infoline = "This is not a problematic version of msitran.exe. Therefore the error is not caused by problematic msitran.exe.\n"; 644*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 645*b1cdbd2cSJim Jagielski } 646*b1cdbd2cSJim Jagielski } 647*b1cdbd2cSJim Jagielski 648*b1cdbd2cSJim Jagielski if ($returnvalue) 649*b1cdbd2cSJim Jagielski { 650*b1cdbd2cSJim Jagielski $infoline = "ERROR: Could not execute $msitran!\n"; 651*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 652*b1cdbd2cSJim Jagielski } 653*b1cdbd2cSJim Jagielski else 654*b1cdbd2cSJim Jagielski { 655*b1cdbd2cSJim Jagielski $infoline = "Success: Executed $msitran successfully!\n"; 656*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 657*b1cdbd2cSJim Jagielski } 658*b1cdbd2cSJim Jagielski 659*b1cdbd2cSJim Jagielski # The reference database can be deleted 660*b1cdbd2cSJim Jagielski 661*b1cdbd2cSJim Jagielski my $result = unlink($referencedbname); 662*b1cdbd2cSJim Jagielski # $result contains the number of deleted files 663*b1cdbd2cSJim Jagielski 664*b1cdbd2cSJim Jagielski if ( $result == 0 ) 665*b1cdbd2cSJim Jagielski { 666*b1cdbd2cSJim Jagielski $infoline = "ERROR: Could not remove file $$referencedbname !\n"; 667*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 668*b1cdbd2cSJim Jagielski installer::exiter::exit_program($infoline, "create_transforms"); 669*b1cdbd2cSJim Jagielski } 670*b1cdbd2cSJim Jagielski } 671*b1cdbd2cSJim Jagielski} 672*b1cdbd2cSJim Jagielski 673*b1cdbd2cSJim Jagielski######################################################################### 674*b1cdbd2cSJim Jagielski# The default language msi database does not need to contain 675*b1cdbd2cSJim Jagielski# the language in the database name. Therefore the file 676*b1cdbd2cSJim Jagielski# is renamed. Example: "openofficeorg20_01.msi" to "openofficeorg20.msi" 677*b1cdbd2cSJim Jagielski######################################################################### 678*b1cdbd2cSJim Jagielski 679*b1cdbd2cSJim Jagielskisub rename_msi_database_in_installset 680*b1cdbd2cSJim Jagielski{ 681*b1cdbd2cSJim Jagielski my ($defaultlanguage, $installdir, $allvariableshashref) = @_; 682*b1cdbd2cSJim Jagielski 683*b1cdbd2cSJim Jagielski installer::logger::include_header_into_logfile("Renaming msi database"); 684*b1cdbd2cSJim Jagielski 685*b1cdbd2cSJim Jagielski my $olddatabasename = get_msidatabasename($allvariableshashref, $defaultlanguage); 686*b1cdbd2cSJim Jagielski $olddatabasename = $installdir . $installer::globals::separator . $olddatabasename; 687*b1cdbd2cSJim Jagielski 688*b1cdbd2cSJim Jagielski my $newdatabasename = get_msidatabasename($allvariableshashref); 689*b1cdbd2cSJim Jagielski 690*b1cdbd2cSJim Jagielski $installer::globals::shortmsidatabasename = $newdatabasename; 691*b1cdbd2cSJim Jagielski 692*b1cdbd2cSJim Jagielski $newdatabasename = $installdir . $installer::globals::separator . $newdatabasename; 693*b1cdbd2cSJim Jagielski 694*b1cdbd2cSJim Jagielski installer::systemactions::rename_one_file($olddatabasename, $newdatabasename); 695*b1cdbd2cSJim Jagielski 696*b1cdbd2cSJim Jagielski $installer::globals::msidatabasename = $newdatabasename; 697*b1cdbd2cSJim Jagielski} 698*b1cdbd2cSJim Jagielski 699*b1cdbd2cSJim Jagielski######################################################################### 700*b1cdbd2cSJim Jagielski# Adding the language to the name of the msi databasename, 701*b1cdbd2cSJim Jagielski# if this is required (ADDLANGUAGEINDATABASENAME) 702*b1cdbd2cSJim Jagielski######################################################################### 703*b1cdbd2cSJim Jagielski 704*b1cdbd2cSJim Jagielskisub add_language_to_msi_database 705*b1cdbd2cSJim Jagielski{ 706*b1cdbd2cSJim Jagielski my ($defaultlanguage, $installdir, $allvariables) = @_; 707*b1cdbd2cSJim Jagielski 708*b1cdbd2cSJim Jagielski my $languagestring = $defaultlanguage; 709*b1cdbd2cSJim Jagielski if ( $allvariables->{'USELANGUAGECODE'} ) { $languagestring = installer::windows::language::get_windows_language($defaultlanguage); } 710*b1cdbd2cSJim Jagielski my $newdatabasename = $installer::globals::shortmsidatabasename; 711*b1cdbd2cSJim Jagielski $newdatabasename =~ s/\.msi\s*$/_$languagestring\.msi/; 712*b1cdbd2cSJim Jagielski $installer::globals::shortmsidatabasename = $newdatabasename; 713*b1cdbd2cSJim Jagielski $newdatabasename = $installdir . $installer::globals::separator . $newdatabasename; 714*b1cdbd2cSJim Jagielski 715*b1cdbd2cSJim Jagielski my $olddatabasename = $installer::globals::msidatabasename; 716*b1cdbd2cSJim Jagielski 717*b1cdbd2cSJim Jagielski installer::systemactions::rename_one_file($olddatabasename, $newdatabasename); 718*b1cdbd2cSJim Jagielski 719*b1cdbd2cSJim Jagielski $installer::globals::msidatabasename = $newdatabasename; 720*b1cdbd2cSJim Jagielski} 721*b1cdbd2cSJim Jagielski 722*b1cdbd2cSJim Jagielski########################################################################## 723*b1cdbd2cSJim Jagielski# Writing the databasename into the setup.ini. 724*b1cdbd2cSJim Jagielski########################################################################## 725*b1cdbd2cSJim Jagielski 726*b1cdbd2cSJim Jagielskisub put_databasename_into_setupini 727*b1cdbd2cSJim Jagielski{ 728*b1cdbd2cSJim Jagielski my ($setupinifile, $allvariableshashref) = @_; 729*b1cdbd2cSJim Jagielski 730*b1cdbd2cSJim Jagielski my $databasename = get_msidatabasename($allvariableshashref); 731*b1cdbd2cSJim Jagielski my $line = "database=" . $databasename . "\n"; 732*b1cdbd2cSJim Jagielski 733*b1cdbd2cSJim Jagielski push(@{$setupinifile}, $line); 734*b1cdbd2cSJim Jagielski} 735*b1cdbd2cSJim Jagielski 736*b1cdbd2cSJim Jagielski########################################################################## 737*b1cdbd2cSJim Jagielski# Writing the required msi version into setup.ini 738*b1cdbd2cSJim Jagielski########################################################################## 739*b1cdbd2cSJim Jagielski 740*b1cdbd2cSJim Jagielskisub put_msiversion_into_setupini 741*b1cdbd2cSJim Jagielski{ 742*b1cdbd2cSJim Jagielski my ($setupinifile) = @_; 743*b1cdbd2cSJim Jagielski 744*b1cdbd2cSJim Jagielski my $msiversion = "2.0"; 745*b1cdbd2cSJim Jagielski my $line = "msiversion=" . $msiversion . "\n"; 746*b1cdbd2cSJim Jagielski 747*b1cdbd2cSJim Jagielski push(@{$setupinifile}, $line); 748*b1cdbd2cSJim Jagielski} 749*b1cdbd2cSJim Jagielski 750*b1cdbd2cSJim Jagielski########################################################################## 751*b1cdbd2cSJim Jagielski# Writing the productname into setup.ini 752*b1cdbd2cSJim Jagielski########################################################################## 753*b1cdbd2cSJim Jagielski 754*b1cdbd2cSJim Jagielskisub put_productname_into_setupini 755*b1cdbd2cSJim Jagielski{ 756*b1cdbd2cSJim Jagielski my ($setupinifile, $allvariableshashref) = @_; 757*b1cdbd2cSJim Jagielski 758*b1cdbd2cSJim Jagielski my $productname = $allvariableshashref->{'PRODUCTNAME'}; 759*b1cdbd2cSJim Jagielski my $line = "productname=" . $productname . "\n"; 760*b1cdbd2cSJim Jagielski 761*b1cdbd2cSJim Jagielski push(@{$setupinifile}, $line); 762*b1cdbd2cSJim Jagielski} 763*b1cdbd2cSJim Jagielski 764*b1cdbd2cSJim Jagielski########################################################################## 765*b1cdbd2cSJim Jagielski# Writing the productcode into setup.ini 766*b1cdbd2cSJim Jagielski########################################################################## 767*b1cdbd2cSJim Jagielski 768*b1cdbd2cSJim Jagielskisub put_productcode_into_setupini 769*b1cdbd2cSJim Jagielski{ 770*b1cdbd2cSJim Jagielski my ($setupinifile) = @_; 771*b1cdbd2cSJim Jagielski 772*b1cdbd2cSJim Jagielski my $productcode = $installer::globals::productcode; 773*b1cdbd2cSJim Jagielski my $line = "productcode=" . $productcode . "\n"; 774*b1cdbd2cSJim Jagielski 775*b1cdbd2cSJim Jagielski push(@{$setupinifile}, $line); 776*b1cdbd2cSJim Jagielski} 777*b1cdbd2cSJim Jagielski 778*b1cdbd2cSJim Jagielski########################################################################## 779*b1cdbd2cSJim Jagielski# Writing the ProductVersion from Property table into setup.ini 780*b1cdbd2cSJim Jagielski########################################################################## 781*b1cdbd2cSJim Jagielski 782*b1cdbd2cSJim Jagielskisub put_productversion_into_setupini 783*b1cdbd2cSJim Jagielski{ 784*b1cdbd2cSJim Jagielski my ($setupinifile) = @_; 785*b1cdbd2cSJim Jagielski 786*b1cdbd2cSJim Jagielski my $line = "productversion=" . $installer::globals::msiproductversion . "\n"; 787*b1cdbd2cSJim Jagielski push(@{$setupinifile}, $line); 788*b1cdbd2cSJim Jagielski} 789*b1cdbd2cSJim Jagielski 790*b1cdbd2cSJim Jagielski########################################################################## 791*b1cdbd2cSJim Jagielski# Writing the key for Minor Upgrades into setup.ini 792*b1cdbd2cSJim Jagielski########################################################################## 793*b1cdbd2cSJim Jagielski 794*b1cdbd2cSJim Jagielskisub put_upgradekey_into_setupini 795*b1cdbd2cSJim Jagielski{ 796*b1cdbd2cSJim Jagielski my ($setupinifile) = @_; 797*b1cdbd2cSJim Jagielski 798*b1cdbd2cSJim Jagielski if ( $installer::globals::minorupgradekey ne "" ) 799*b1cdbd2cSJim Jagielski { 800*b1cdbd2cSJim Jagielski my $line = "upgradekey=" . $installer::globals::minorupgradekey . "\n"; 801*b1cdbd2cSJim Jagielski push(@{$setupinifile}, $line); 802*b1cdbd2cSJim Jagielski } 803*b1cdbd2cSJim Jagielski} 804*b1cdbd2cSJim Jagielski 805*b1cdbd2cSJim Jagielski########################################################################## 806*b1cdbd2cSJim Jagielski# Writing the number of languages into setup.ini 807*b1cdbd2cSJim Jagielski########################################################################## 808*b1cdbd2cSJim Jagielski 809*b1cdbd2cSJim Jagielskisub put_languagecount_into_setupini 810*b1cdbd2cSJim Jagielski{ 811*b1cdbd2cSJim Jagielski my ($setupinifile, $languagesarray) = @_; 812*b1cdbd2cSJim Jagielski 813*b1cdbd2cSJim Jagielski my $languagecount = $#{$languagesarray} + 1; 814*b1cdbd2cSJim Jagielski my $line = "count=" . $languagecount . "\n"; 815*b1cdbd2cSJim Jagielski 816*b1cdbd2cSJim Jagielski push(@{$setupinifile}, $line); 817*b1cdbd2cSJim Jagielski} 818*b1cdbd2cSJim Jagielski 819*b1cdbd2cSJim Jagielski########################################################################## 820*b1cdbd2cSJim Jagielski# Writing the defaultlanguage into setup.ini 821*b1cdbd2cSJim Jagielski########################################################################## 822*b1cdbd2cSJim Jagielski 823*b1cdbd2cSJim Jagielskisub put_defaultlanguage_into_setupini 824*b1cdbd2cSJim Jagielski{ 825*b1cdbd2cSJim Jagielski my ($setupinifile, $defaultlanguage) = @_; 826*b1cdbd2cSJim Jagielski 827*b1cdbd2cSJim Jagielski my $windowslanguage = installer::windows::language::get_windows_language($defaultlanguage); 828*b1cdbd2cSJim Jagielski my $line = "default=" . $windowslanguage . "\n"; 829*b1cdbd2cSJim Jagielski push(@{$setupinifile}, $line); 830*b1cdbd2cSJim Jagielski} 831*b1cdbd2cSJim Jagielski 832*b1cdbd2cSJim Jagielski########################################################################## 833*b1cdbd2cSJim Jagielski# Writing the information about transformations into setup.ini 834*b1cdbd2cSJim Jagielski########################################################################## 835*b1cdbd2cSJim Jagielski 836*b1cdbd2cSJim Jagielskisub put_transforms_into_setupini 837*b1cdbd2cSJim Jagielski{ 838*b1cdbd2cSJim Jagielski my ($setupinifile, $onelanguage, $counter) = @_; 839*b1cdbd2cSJim Jagielski 840*b1cdbd2cSJim Jagielski my $windowslanguage = installer::windows::language::get_windows_language($onelanguage); 841*b1cdbd2cSJim Jagielski my $transformfilename = "trans_" . $onelanguage . ".mst"; 842*b1cdbd2cSJim Jagielski 843*b1cdbd2cSJim Jagielski my $line = "lang" . $counter . "=" . $windowslanguage . "," . $transformfilename . "\n"; 844*b1cdbd2cSJim Jagielski 845*b1cdbd2cSJim Jagielski push(@{$setupinifile}, $line); 846*b1cdbd2cSJim Jagielski} 847*b1cdbd2cSJim Jagielski 848*b1cdbd2cSJim Jagielski################################################### 849*b1cdbd2cSJim Jagielski# Including Windows line ends in ini files 850*b1cdbd2cSJim Jagielski# Profiles on Windows shall have \r\n line ends 851*b1cdbd2cSJim Jagielski################################################### 852*b1cdbd2cSJim Jagielski 853*b1cdbd2cSJim Jagielskisub include_windows_lineends 854*b1cdbd2cSJim Jagielski{ 855*b1cdbd2cSJim Jagielski my ($onefile) = @_; 856*b1cdbd2cSJim Jagielski 857*b1cdbd2cSJim Jagielski for ( my $i = 0; $i <= $#{$onefile}; $i++ ) 858*b1cdbd2cSJim Jagielski { 859*b1cdbd2cSJim Jagielski ${$onefile}[$i] =~ s/\r?\n$/\r\n/; 860*b1cdbd2cSJim Jagielski } 861*b1cdbd2cSJim Jagielski} 862*b1cdbd2cSJim Jagielski 863*b1cdbd2cSJim Jagielski########################################################################## 864*b1cdbd2cSJim Jagielski# Generation the file setup.ini, that is used by the loader setup.exe. 865*b1cdbd2cSJim Jagielski########################################################################## 866*b1cdbd2cSJim Jagielski 867*b1cdbd2cSJim Jagielskisub create_setup_ini 868*b1cdbd2cSJim Jagielski{ 869*b1cdbd2cSJim Jagielski my ($languagesarray, $defaultlanguage, $installdir, $allvariableshashref) = @_; 870*b1cdbd2cSJim Jagielski 871*b1cdbd2cSJim Jagielski installer::logger::include_header_into_logfile("Creating setup.ini"); 872*b1cdbd2cSJim Jagielski 873*b1cdbd2cSJim Jagielski my $setupinifilename = $installdir . $installer::globals::separator . "setup.ini"; 874*b1cdbd2cSJim Jagielski 875*b1cdbd2cSJim Jagielski my @setupinifile = (); 876*b1cdbd2cSJim Jagielski my $setupinifile = \@setupinifile; 877*b1cdbd2cSJim Jagielski 878*b1cdbd2cSJim Jagielski my $line = "\[setup\]\n"; 879*b1cdbd2cSJim Jagielski push(@setupinifile, $line); 880*b1cdbd2cSJim Jagielski 881*b1cdbd2cSJim Jagielski put_databasename_into_setupini($setupinifile, $allvariableshashref); 882*b1cdbd2cSJim Jagielski put_msiversion_into_setupini($setupinifile); 883*b1cdbd2cSJim Jagielski put_productname_into_setupini($setupinifile, $allvariableshashref); 884*b1cdbd2cSJim Jagielski put_productcode_into_setupini($setupinifile); 885*b1cdbd2cSJim Jagielski put_productversion_into_setupini($setupinifile); 886*b1cdbd2cSJim Jagielski put_upgradekey_into_setupini($setupinifile); 887*b1cdbd2cSJim Jagielski 888*b1cdbd2cSJim Jagielski $line = "\[languages\]\n"; 889*b1cdbd2cSJim Jagielski push(@setupinifile, $line); 890*b1cdbd2cSJim Jagielski 891*b1cdbd2cSJim Jagielski put_languagecount_into_setupini($setupinifile, $languagesarray); 892*b1cdbd2cSJim Jagielski put_defaultlanguage_into_setupini($setupinifile, $defaultlanguage); 893*b1cdbd2cSJim Jagielski 894*b1cdbd2cSJim Jagielski if ( $#{$languagesarray} > 0 ) # writing the transforms information 895*b1cdbd2cSJim Jagielski { 896*b1cdbd2cSJim Jagielski my $counter = 1; 897*b1cdbd2cSJim Jagielski 898*b1cdbd2cSJim Jagielski for ( my $i = 0; $i <= $#{$languagesarray}; $i++ ) 899*b1cdbd2cSJim Jagielski { 900*b1cdbd2cSJim Jagielski if ( ${$languagesarray}[$i] eq $defaultlanguage ) { next; } 901*b1cdbd2cSJim Jagielski 902*b1cdbd2cSJim Jagielski put_transforms_into_setupini($setupinifile, ${$languagesarray}[$i], $counter); 903*b1cdbd2cSJim Jagielski $counter++; 904*b1cdbd2cSJim Jagielski } 905*b1cdbd2cSJim Jagielski } 906*b1cdbd2cSJim Jagielski 907*b1cdbd2cSJim Jagielski if ( $installer::globals::iswin && $installer::globals::plat =~ /cygwin/i) # Windows line ends only for Cygwin 908*b1cdbd2cSJim Jagielski { 909*b1cdbd2cSJim Jagielski include_windows_lineends($setupinifile); 910*b1cdbd2cSJim Jagielski } 911*b1cdbd2cSJim Jagielski 912*b1cdbd2cSJim Jagielski installer::files::save_file($setupinifilename, $setupinifile); 913*b1cdbd2cSJim Jagielski 914*b1cdbd2cSJim Jagielski $installer::logger::Lang->printf("Generated file %s\n", $setupinifilename); 915*b1cdbd2cSJim Jagielski} 916*b1cdbd2cSJim Jagielski 917*b1cdbd2cSJim Jagielski################################################################# 918*b1cdbd2cSJim Jagielski# Copying the files defined as ScpActions into the 919*b1cdbd2cSJim Jagielski# installation set. 920*b1cdbd2cSJim Jagielski################################################################# 921*b1cdbd2cSJim Jagielski 922*b1cdbd2cSJim Jagielskisub copy_scpactions_into_installset 923*b1cdbd2cSJim Jagielski{ 924*b1cdbd2cSJim Jagielski my ($defaultlanguage, $installdir, $allscpactions) = @_; 925*b1cdbd2cSJim Jagielski 926*b1cdbd2cSJim Jagielski installer::logger::include_header_into_logfile("Copying ScpAction files into installation set"); 927*b1cdbd2cSJim Jagielski 928*b1cdbd2cSJim Jagielski for ( my $i = 0; $i <= $#{$allscpactions}; $i++ ) 929*b1cdbd2cSJim Jagielski { 930*b1cdbd2cSJim Jagielski my $onescpaction = ${$allscpactions}[$i]; 931*b1cdbd2cSJim Jagielski 932*b1cdbd2cSJim Jagielski if ( $onescpaction->{'Name'} eq "loader.exe" ) { next; } # do not copy this ScpAction loader 933*b1cdbd2cSJim Jagielski 934*b1cdbd2cSJim Jagielski # only copying language independent files or files with the correct language (the defaultlanguage) 935*b1cdbd2cSJim Jagielski 936*b1cdbd2cSJim Jagielski my $filelanguage = $onescpaction->{'specificlanguage'}; 937*b1cdbd2cSJim Jagielski 938*b1cdbd2cSJim Jagielski if ( ($filelanguage eq $defaultlanguage) || ($filelanguage eq "") ) 939*b1cdbd2cSJim Jagielski { 940*b1cdbd2cSJim Jagielski my $sourcefile = $onescpaction->{'sourcepath'}; 941*b1cdbd2cSJim Jagielski my $destfile = $installdir . $installer::globals::separator . $onescpaction->{'DestinationName'}; 942*b1cdbd2cSJim Jagielski 943*b1cdbd2cSJim Jagielski installer::systemactions::copy_one_file($sourcefile, $destfile); 944*b1cdbd2cSJim Jagielski } 945*b1cdbd2cSJim Jagielski } 946*b1cdbd2cSJim Jagielski} 947*b1cdbd2cSJim Jagielski 948*b1cdbd2cSJim Jagielski################################################################# 949*b1cdbd2cSJim Jagielski# Copying the files for the Windows installer into the 950*b1cdbd2cSJim Jagielski# installation set (setup.exe). 951*b1cdbd2cSJim Jagielski################################################################# 952*b1cdbd2cSJim Jagielski 953*b1cdbd2cSJim Jagielskisub copy_windows_installer_files_into_installset 954*b1cdbd2cSJim Jagielski{ 955*b1cdbd2cSJim Jagielski my ($installdir, $includepatharrayref, $allvariables) = @_; 956*b1cdbd2cSJim Jagielski 957*b1cdbd2cSJim Jagielski installer::logger::include_header_into_logfile("Copying Windows installer files into installation set"); 958*b1cdbd2cSJim Jagielski 959*b1cdbd2cSJim Jagielski my @copyfile = (); 960*b1cdbd2cSJim Jagielski push(@copyfile, "loader2.exe"); 961*b1cdbd2cSJim Jagielski 962*b1cdbd2cSJim Jagielski if ( $allvariables->{'NOLOADERREQUIRED'} ) { @copyfile = (); } 963*b1cdbd2cSJim Jagielski 964*b1cdbd2cSJim Jagielski for ( my $i = 0; $i <= $#copyfile; $i++ ) 965*b1cdbd2cSJim Jagielski { 966*b1cdbd2cSJim Jagielski my $filename = $copyfile[$i]; 967*b1cdbd2cSJim Jagielski my $sourcefileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$filename, $includepatharrayref, 1); 968*b1cdbd2cSJim Jagielski 969*b1cdbd2cSJim Jagielski if ( ! -f $$sourcefileref ) { installer::exiter::exit_program("ERROR: msi file not found: $$sourcefileref !", "copy_windows_installer_files_into_installset"); } 970*b1cdbd2cSJim Jagielski 971*b1cdbd2cSJim Jagielski my $destfile; 972*b1cdbd2cSJim Jagielski if ( $copyfile[$i] eq "loader2.exe" ) { $destfile = "setup.exe"; } # renaming the loader 973*b1cdbd2cSJim Jagielski else { $destfile = $copyfile[$i]; } 974*b1cdbd2cSJim Jagielski 975*b1cdbd2cSJim Jagielski $destfile = $installdir . $installer::globals::separator . $destfile; 976*b1cdbd2cSJim Jagielski 977*b1cdbd2cSJim Jagielski installer::systemactions::copy_one_file($$sourcefileref, $destfile); 978*b1cdbd2cSJim Jagielski } 979*b1cdbd2cSJim Jagielski} 980*b1cdbd2cSJim Jagielski 981*b1cdbd2cSJim Jagielski################################################################# 982*b1cdbd2cSJim Jagielski# Copying the child projects into the 983*b1cdbd2cSJim Jagielski# installation set 984*b1cdbd2cSJim Jagielski################################################################# 985*b1cdbd2cSJim Jagielski 986*b1cdbd2cSJim Jagielskisub copy_child_projects_into_installset 987*b1cdbd2cSJim Jagielski{ 988*b1cdbd2cSJim Jagielski my ($installdir, $allvariables) = @_; 989*b1cdbd2cSJim Jagielski 990*b1cdbd2cSJim Jagielski my $sourcefile = ""; 991*b1cdbd2cSJim Jagielski my $destdir = ""; 992*b1cdbd2cSJim Jagielski 993*b1cdbd2cSJim Jagielski # adding Java 994*b1cdbd2cSJim Jagielski 995*b1cdbd2cSJim Jagielski if ( $allvariables->{'JAVAPRODUCT'} ) 996*b1cdbd2cSJim Jagielski { 997*b1cdbd2cSJim Jagielski $sourcefile = $installer::globals::javafile->{'sourcepath'}; 998*b1cdbd2cSJim Jagielski $destdir = $installdir . $installer::globals::separator . $installer::globals::javafile->{'Subdir'}; 999*b1cdbd2cSJim Jagielski if ( ! -d $destdir) { installer::systemactions::create_directory($destdir); } 1000*b1cdbd2cSJim Jagielski installer::systemactions::copy_one_file($sourcefile, $destdir); 1001*b1cdbd2cSJim Jagielski } 1002*b1cdbd2cSJim Jagielski 1003*b1cdbd2cSJim Jagielski if ( $allvariables->{'UREPRODUCT'} ) 1004*b1cdbd2cSJim Jagielski { 1005*b1cdbd2cSJim Jagielski $sourcefile = $installer::globals::urefile->{'sourcepath'}; 1006*b1cdbd2cSJim Jagielski $destdir = $installdir . $installer::globals::separator . $installer::globals::urefile->{'Subdir'}; 1007*b1cdbd2cSJim Jagielski if ( ! -d $destdir) { installer::systemactions::create_directory($destdir); } 1008*b1cdbd2cSJim Jagielski installer::systemactions::copy_one_file($sourcefile, $destdir); 1009*b1cdbd2cSJim Jagielski } 1010*b1cdbd2cSJim Jagielski} 1011*b1cdbd2cSJim Jagielski 1012*b1cdbd2cSJim Jagielski 1013*b1cdbd2cSJim Jagielski 1014*b1cdbd2cSJim Jagielski=head2 create_guid () 1015*b1cdbd2cSJim Jagielski 1016*b1cdbd2cSJim Jagielski Create a single UUID aka GUID via calling the external executable 'uuidgen'. 1017*b1cdbd2cSJim Jagielski There are Perl modules for that, but do they exist on the build bots? 1018*b1cdbd2cSJim Jagielski 1019*b1cdbd2cSJim Jagielski=cut 1020*b1cdbd2cSJim Jagielskisub create_guid () 1021*b1cdbd2cSJim Jagielski{ 1022*b1cdbd2cSJim Jagielski my $uuid = qx("uuidgen"); 1023*b1cdbd2cSJim Jagielski $uuid =~ s/\s*$//; 1024*b1cdbd2cSJim Jagielski return uc($uuid); 1025*b1cdbd2cSJim Jagielski} 1026*b1cdbd2cSJim Jagielski 1027*b1cdbd2cSJim Jagielski################################################################# 1028*b1cdbd2cSJim Jagielski# Calculating a GUID with a string using md5. 1029*b1cdbd2cSJim Jagielski################################################################# 1030*b1cdbd2cSJim Jagielski 1031*b1cdbd2cSJim Jagielskisub calculate_guid 1032*b1cdbd2cSJim Jagielski{ 1033*b1cdbd2cSJim Jagielski my ( $string ) = @_; 1034*b1cdbd2cSJim Jagielski 1035*b1cdbd2cSJim Jagielski my $guid = ""; 1036*b1cdbd2cSJim Jagielski 1037*b1cdbd2cSJim Jagielski my $md5 = Digest::MD5->new; 1038*b1cdbd2cSJim Jagielski $md5->add($string); 1039*b1cdbd2cSJim Jagielski my $digest = $md5->hexdigest; 1040*b1cdbd2cSJim Jagielski $digest = uc($digest); 1041*b1cdbd2cSJim Jagielski 1042*b1cdbd2cSJim Jagielski # my $id = pack("A32", $digest); 1043*b1cdbd2cSJim Jagielski my ($first, $second, $third, $fourth, $fifth) = unpack ('A8 A4 A4 A4 A12', $digest); 1044*b1cdbd2cSJim Jagielski $guid = "$first-$second-$third-$fourth-$fifth"; 1045*b1cdbd2cSJim Jagielski 1046*b1cdbd2cSJim Jagielski $installer::logger::Lang->printf("guid for '%s' is %s\n", 1047*b1cdbd2cSJim Jagielski $string, $guid); 1048*b1cdbd2cSJim Jagielski 1049*b1cdbd2cSJim Jagielski return $guid; 1050*b1cdbd2cSJim Jagielski} 1051*b1cdbd2cSJim Jagielski 1052*b1cdbd2cSJim Jagielski################################################################# 1053*b1cdbd2cSJim Jagielski# Calculating a ID with a string using md5 (very fast). 1054*b1cdbd2cSJim Jagielski################################################################# 1055*b1cdbd2cSJim Jagielski 1056*b1cdbd2cSJim Jagielskisub calculate_id 1057*b1cdbd2cSJim Jagielski{ 1058*b1cdbd2cSJim Jagielski my ( $string, $length ) = @_; 1059*b1cdbd2cSJim Jagielski 1060*b1cdbd2cSJim Jagielski my $id = ""; 1061*b1cdbd2cSJim Jagielski 1062*b1cdbd2cSJim Jagielski my $md5 = Digest::MD5->new; 1063*b1cdbd2cSJim Jagielski $md5->add($string); 1064*b1cdbd2cSJim Jagielski my $digest = lc($md5->hexdigest); 1065*b1cdbd2cSJim Jagielski $id = substr($digest, 0, $length); 1066*b1cdbd2cSJim Jagielski 1067*b1cdbd2cSJim Jagielski return $id; 1068*b1cdbd2cSJim Jagielski} 1069*b1cdbd2cSJim Jagielski 1070*b1cdbd2cSJim Jagielski################################################################# 1071*b1cdbd2cSJim Jagielski# Filling the component hash with the values of the 1072*b1cdbd2cSJim Jagielski# component file. 1073*b1cdbd2cSJim Jagielski################################################################# 1074*b1cdbd2cSJim Jagielski 1075*b1cdbd2cSJim Jagielskisub fill_component_hash 1076*b1cdbd2cSJim Jagielski{ 1077*b1cdbd2cSJim Jagielski my ($componentfile) = @_; 1078*b1cdbd2cSJim Jagielski 1079*b1cdbd2cSJim Jagielski my %components = (); 1080*b1cdbd2cSJim Jagielski 1081*b1cdbd2cSJim Jagielski for ( my $i = 0; $i <= $#{$componentfile}; $i++ ) 1082*b1cdbd2cSJim Jagielski { 1083*b1cdbd2cSJim Jagielski my $line = ${$componentfile}[$i]; 1084*b1cdbd2cSJim Jagielski 1085*b1cdbd2cSJim Jagielski if ( $line =~ /^\s*(.*?)\t(.*?)\s*$/ ) 1086*b1cdbd2cSJim Jagielski { 1087*b1cdbd2cSJim Jagielski my $key = $1; 1088*b1cdbd2cSJim Jagielski my $value = $2; 1089*b1cdbd2cSJim Jagielski 1090*b1cdbd2cSJim Jagielski $components{$key} = $value; 1091*b1cdbd2cSJim Jagielski } 1092*b1cdbd2cSJim Jagielski } 1093*b1cdbd2cSJim Jagielski 1094*b1cdbd2cSJim Jagielski return \%components; 1095*b1cdbd2cSJim Jagielski} 1096*b1cdbd2cSJim Jagielski 1097*b1cdbd2cSJim Jagielski################################################################# 1098*b1cdbd2cSJim Jagielski# Creating a new component file, if new guids were generated. 1099*b1cdbd2cSJim Jagielski################################################################# 1100*b1cdbd2cSJim Jagielski 1101*b1cdbd2cSJim Jagielskisub create_new_component_file 1102*b1cdbd2cSJim Jagielski{ 1103*b1cdbd2cSJim Jagielski my ($componenthash) = @_; 1104*b1cdbd2cSJim Jagielski 1105*b1cdbd2cSJim Jagielski my @componentfile = (); 1106*b1cdbd2cSJim Jagielski 1107*b1cdbd2cSJim Jagielski my $key; 1108*b1cdbd2cSJim Jagielski 1109*b1cdbd2cSJim Jagielski foreach $key (keys %{$componenthash}) 1110*b1cdbd2cSJim Jagielski { 1111*b1cdbd2cSJim Jagielski my $value = $componenthash->{$key}; 1112*b1cdbd2cSJim Jagielski my $input = "$key\t$value\n"; 1113*b1cdbd2cSJim Jagielski push(@componentfile ,$input); 1114*b1cdbd2cSJim Jagielski } 1115*b1cdbd2cSJim Jagielski 1116*b1cdbd2cSJim Jagielski return \@componentfile; 1117*b1cdbd2cSJim Jagielski} 1118*b1cdbd2cSJim Jagielski 1119*b1cdbd2cSJim Jagielski################################################################# 1120*b1cdbd2cSJim Jagielski# Filling real component GUID into the component table. 1121*b1cdbd2cSJim Jagielski# This works only on Windows 1122*b1cdbd2cSJim Jagielski################################################################# 1123*b1cdbd2cSJim Jagielski 1124*b1cdbd2cSJim Jagielskisub __set_uuid_into_component_table 1125*b1cdbd2cSJim Jagielski{ 1126*b1cdbd2cSJim Jagielski my ($idtdirbase, $allvariables) = @_; 1127*b1cdbd2cSJim Jagielski 1128*b1cdbd2cSJim Jagielski my $componenttablename = $idtdirbase . $installer::globals::separator . "Componen.idt"; 1129*b1cdbd2cSJim Jagielski 1130*b1cdbd2cSJim Jagielski my $componenttable = installer::files::read_file($componenttablename); 1131*b1cdbd2cSJim Jagielski 1132*b1cdbd2cSJim Jagielski # For update and patch reasons (small update) the GUID of an existing component must not change! 1133*b1cdbd2cSJim Jagielski # The collection of component GUIDs is saved in the directory $installer::globals::idttemplatepath in the file "components.txt" 1134*b1cdbd2cSJim Jagielski 1135*b1cdbd2cSJim Jagielski my $infoline = ""; 1136*b1cdbd2cSJim Jagielski my $counter = 0; 1137*b1cdbd2cSJim Jagielski # my $componentfile = installer::files::read_file($installer::globals::componentfilename); 1138*b1cdbd2cSJim Jagielski # my $componenthash = fill_component_hash($componentfile); 1139*b1cdbd2cSJim Jagielski 1140*b1cdbd2cSJim Jagielski for ( my $i = 3; $i <= $#{$componenttable}; $i++ ) # ignoring the first three lines 1141*b1cdbd2cSJim Jagielski { 1142*b1cdbd2cSJim Jagielski my $oneline = ${$componenttable}[$i]; 1143*b1cdbd2cSJim Jagielski my $componentname = ""; 1144*b1cdbd2cSJim Jagielski if ( $oneline =~ /^\s*(\S+?)\t/ ) { $componentname = $1; } 1145*b1cdbd2cSJim Jagielski 1146*b1cdbd2cSJim Jagielski my $uuid = ""; 1147*b1cdbd2cSJim Jagielski 1148*b1cdbd2cSJim Jagielski # if ( $componenthash->{$componentname} ) 1149*b1cdbd2cSJim Jagielski # { 1150*b1cdbd2cSJim Jagielski # $uuid = $componenthash->{$componentname}; 1151*b1cdbd2cSJim Jagielski # } 1152*b1cdbd2cSJim Jagielski # else 1153*b1cdbd2cSJim Jagielski # { 1154*b1cdbd2cSJim Jagielski 1155*b1cdbd2cSJim Jagielski if ( exists($installer::globals::calculated_component_guids{$componentname})) 1156*b1cdbd2cSJim Jagielski { 1157*b1cdbd2cSJim Jagielski $uuid = $installer::globals::calculated_component_guids{$componentname}; 1158*b1cdbd2cSJim Jagielski } 1159*b1cdbd2cSJim Jagielski else 1160*b1cdbd2cSJim Jagielski { 1161*b1cdbd2cSJim Jagielski # Calculating new GUID with the help of the component name. 1162*b1cdbd2cSJim Jagielski my $useooobaseversion = 1; 1163*b1cdbd2cSJim Jagielski if ( exists($installer::globals::base_independent_components{$componentname})) 1164*b1cdbd2cSJim Jagielski { 1165*b1cdbd2cSJim Jagielski $useooobaseversion = 0; 1166*b1cdbd2cSJim Jagielski } 1167*b1cdbd2cSJim Jagielski my $sourcestring = $componentname; 1168*b1cdbd2cSJim Jagielski 1169*b1cdbd2cSJim Jagielski if ( $useooobaseversion ) 1170*b1cdbd2cSJim Jagielski { 1171*b1cdbd2cSJim Jagielski if ( ! exists($allvariables->{'OOOBASEVERSION'}) ) 1172*b1cdbd2cSJim Jagielski { 1173*b1cdbd2cSJim Jagielski installer::exiter::exit_program( 1174*b1cdbd2cSJim Jagielski "ERROR: Could not find variable \"OOOBASEVERSION\" (required value for GUID creation)!", 1175*b1cdbd2cSJim Jagielski "set_uuid_into_component_table"); 1176*b1cdbd2cSJim Jagielski } 1177*b1cdbd2cSJim Jagielski $sourcestring = $sourcestring . "_" . $allvariables->{'OOOBASEVERSION'}; 1178*b1cdbd2cSJim Jagielski } 1179*b1cdbd2cSJim Jagielski $uuid = calculate_guid($sourcestring); 1180*b1cdbd2cSJim Jagielski $counter++; 1181*b1cdbd2cSJim Jagielski 1182*b1cdbd2cSJim Jagielski # checking, if there is a conflict with an already created guid 1183*b1cdbd2cSJim Jagielski if ( exists($installer::globals::allcalculated_guids{$uuid}) ) 1184*b1cdbd2cSJim Jagielski { 1185*b1cdbd2cSJim Jagielski installer::exiter::exit_program( 1186*b1cdbd2cSJim Jagielski "ERROR: \"$uuid\" was already created before!", 1187*b1cdbd2cSJim Jagielski "set_uuid_into_component_table"); 1188*b1cdbd2cSJim Jagielski } 1189*b1cdbd2cSJim Jagielski $installer::globals::allcalculated_guids{$uuid} = 1; 1190*b1cdbd2cSJim Jagielski $installer::globals::calculated_component_guids{$componentname} = $uuid; 1191*b1cdbd2cSJim Jagielski 1192*b1cdbd2cSJim Jagielski # Setting new uuid 1193*b1cdbd2cSJim Jagielski # $componenthash->{$componentname} = $uuid; 1194*b1cdbd2cSJim Jagielski 1195*b1cdbd2cSJim Jagielski # Setting flag 1196*b1cdbd2cSJim Jagielski # $installer::globals::created_new_component_guid = 1; # this is very important! 1197*b1cdbd2cSJim Jagielski } 1198*b1cdbd2cSJim Jagielski # } 1199*b1cdbd2cSJim Jagielski 1200*b1cdbd2cSJim Jagielski ${$componenttable}[$i] =~ s/COMPONENTGUID/$uuid/; 1201*b1cdbd2cSJim Jagielski } 1202*b1cdbd2cSJim Jagielski 1203*b1cdbd2cSJim Jagielski installer::files::save_file($componenttablename, $componenttable); 1204*b1cdbd2cSJim Jagielski 1205*b1cdbd2cSJim Jagielski# if ( $installer::globals::created_new_component_guid ) 1206*b1cdbd2cSJim Jagielski# { 1207*b1cdbd2cSJim Jagielski# # create new component file! 1208*b1cdbd2cSJim Jagielski# $componentfile = create_new_component_file($componenthash); 1209*b1cdbd2cSJim Jagielski# installer::worker::sort_array($componentfile); 1210*b1cdbd2cSJim Jagielski# 1211*b1cdbd2cSJim Jagielski# # To avoid conflict the components file cannot be saved at the same place 1212*b1cdbd2cSJim Jagielski# # All important data have to be saved in the directory: $installer::globals::infodirectory 1213*b1cdbd2cSJim Jagielski# my $localcomponentfilename = $installer::globals::componentfilename; 1214*b1cdbd2cSJim Jagielski# installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$localcomponentfilename); 1215*b1cdbd2cSJim Jagielski# $localcomponentfilename = $installer::globals::infodirectory . $installer::globals::separator . $localcomponentfilename; 1216*b1cdbd2cSJim Jagielski# installer::files::save_file($localcomponentfilename, $componentfile); 1217*b1cdbd2cSJim Jagielski# 1218*b1cdbd2cSJim Jagielski# # installer::files::save_file($installer::globals::componentfilename, $componentfile); # version using new file in solver 1219*b1cdbd2cSJim Jagielski# 1220*b1cdbd2cSJim Jagielski# $infoline = "COMPONENTCODES: Created $counter new GUIDs for components ! \n"; 1221*b1cdbd2cSJim Jagielski# $installer::logger::Lang->print($infoline); 1222*b1cdbd2cSJim Jagielski# } 1223*b1cdbd2cSJim Jagielski# else 1224*b1cdbd2cSJim Jagielski# { 1225*b1cdbd2cSJim Jagielski# $infoline = "SUCCESS COMPONENTCODES: All component codes exist! \n"; 1226*b1cdbd2cSJim Jagielski# $installer::logger::Lang->print($infoline); 1227*b1cdbd2cSJim Jagielski# } 1228*b1cdbd2cSJim Jagielski 1229*b1cdbd2cSJim Jagielski} 1230*b1cdbd2cSJim Jagielski 1231*b1cdbd2cSJim Jagielski######################################################################### 1232*b1cdbd2cSJim Jagielski# Adding final 64 properties into msi database, if required. 1233*b1cdbd2cSJim Jagielski# RegLocator : +16 in type column to search in 64 bit registry. 1234*b1cdbd2cSJim Jagielski# All conditions: "VersionNT" -> "VersionNT64" (several tables). 1235*b1cdbd2cSJim Jagielski# Already done: "+256" in Attributes column of table "Component". 1236*b1cdbd2cSJim Jagielski# Still following: Setting "x64" instead of "Intel" in Summary 1237*b1cdbd2cSJim Jagielski# Information Stream of msi database in "get_template_for_sis". 1238*b1cdbd2cSJim Jagielski######################################################################### 1239*b1cdbd2cSJim Jagielski 1240*b1cdbd2cSJim Jagielskisub prepare_64bit_database 1241*b1cdbd2cSJim Jagielski{ 1242*b1cdbd2cSJim Jagielski my ($basedir, $allvariables) = @_; 1243*b1cdbd2cSJim Jagielski 1244*b1cdbd2cSJim Jagielski my $infoline = ""; 1245*b1cdbd2cSJim Jagielski 1246*b1cdbd2cSJim Jagielski if (( $allvariables->{'64BITPRODUCT'} ) && ( $allvariables->{'64BITPRODUCT'} == 1 )) 1247*b1cdbd2cSJim Jagielski { 1248*b1cdbd2cSJim Jagielski # 1. Beginning with table "RegLocat.idt". Adding "16" to the type. 1249*b1cdbd2cSJim Jagielski 1250*b1cdbd2cSJim Jagielski my $reglocatfile = ""; 1251*b1cdbd2cSJim Jagielski my $reglocatfilename = $basedir . $installer::globals::separator . "RegLocat.idt"; 1252*b1cdbd2cSJim Jagielski 1253*b1cdbd2cSJim Jagielski if ( -f $reglocatfilename ) 1254*b1cdbd2cSJim Jagielski { 1255*b1cdbd2cSJim Jagielski my $saving_required = 0; 1256*b1cdbd2cSJim Jagielski $reglocatfile = installer::files::read_file($reglocatfilename); 1257*b1cdbd2cSJim Jagielski 1258*b1cdbd2cSJim Jagielski for ( my $i = 3; $i <= $#{$reglocatfile}; $i++ ) # ignoring the first three lines 1259*b1cdbd2cSJim Jagielski { 1260*b1cdbd2cSJim Jagielski my $oneline = ${$reglocatfile}[$i]; 1261*b1cdbd2cSJim Jagielski 1262*b1cdbd2cSJim Jagielski if ( $oneline =~ /^\s*\#/ ) { next; } # this is a comment line 1263*b1cdbd2cSJim Jagielski if ( $oneline =~ /^\s*$/ ) { next; } 1264*b1cdbd2cSJim Jagielski 1265*b1cdbd2cSJim Jagielski if ( $oneline =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(\d+)\s*$/ ) 1266*b1cdbd2cSJim Jagielski { 1267*b1cdbd2cSJim Jagielski # Syntax: Signature_ Root Key Name Type 1268*b1cdbd2cSJim Jagielski my $sig = $1; 1269*b1cdbd2cSJim Jagielski my $root = $2; 1270*b1cdbd2cSJim Jagielski my $key = $3; 1271*b1cdbd2cSJim Jagielski my $name = $4; 1272*b1cdbd2cSJim Jagielski my $type = $5; 1273*b1cdbd2cSJim Jagielski 1274*b1cdbd2cSJim Jagielski $type = $type + 16; 1275*b1cdbd2cSJim Jagielski 1276*b1cdbd2cSJim Jagielski my $newline = $sig . "\t" . $root . "\t" . $key . "\t" . $name . "\t" . $type . "\n"; 1277*b1cdbd2cSJim Jagielski ${$reglocatfile}[$i] = $newline; 1278*b1cdbd2cSJim Jagielski 1279*b1cdbd2cSJim Jagielski $saving_required = 1; 1280*b1cdbd2cSJim Jagielski } 1281*b1cdbd2cSJim Jagielski } 1282*b1cdbd2cSJim Jagielski 1283*b1cdbd2cSJim Jagielski if ( $saving_required ) 1284*b1cdbd2cSJim Jagielski { 1285*b1cdbd2cSJim Jagielski # Saving the files 1286*b1cdbd2cSJim Jagielski installer::files::save_file($reglocatfilename ,$reglocatfile); 1287*b1cdbd2cSJim Jagielski $infoline = "Making idt file 64 bit conform: $reglocatfilename\n"; 1288*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 1289*b1cdbd2cSJim Jagielski } 1290*b1cdbd2cSJim Jagielski } 1291*b1cdbd2cSJim Jagielski 1292*b1cdbd2cSJim Jagielski # 2. Replacing all occurences of "VersionNT" by "VersionNT64" 1293*b1cdbd2cSJim Jagielski 1294*b1cdbd2cSJim Jagielski my @versionnt_files = ("Componen.idt", "InstallE.idt", "InstallU.idt", "LaunchCo.idt"); 1295*b1cdbd2cSJim Jagielski 1296*b1cdbd2cSJim Jagielski foreach my $onefile ( @versionnt_files ) 1297*b1cdbd2cSJim Jagielski { 1298*b1cdbd2cSJim Jagielski my $fullfilename = $basedir . $installer::globals::separator . $onefile; 1299*b1cdbd2cSJim Jagielski 1300*b1cdbd2cSJim Jagielski if ( -f $fullfilename ) 1301*b1cdbd2cSJim Jagielski { 1302*b1cdbd2cSJim Jagielski my $saving_required = 0; 1303*b1cdbd2cSJim Jagielski my $filecontent = installer::files::read_file($fullfilename); 1304*b1cdbd2cSJim Jagielski 1305*b1cdbd2cSJim Jagielski for ( my $i = 3; $i <= $#{$filecontent}; $i++ ) # ignoring the first three lines 1306*b1cdbd2cSJim Jagielski { 1307*b1cdbd2cSJim Jagielski my $oneline = ${$filecontent}[$i]; 1308*b1cdbd2cSJim Jagielski 1309*b1cdbd2cSJim Jagielski if ( $oneline =~ /\bVersionNT\b/ ) 1310*b1cdbd2cSJim Jagielski { 1311*b1cdbd2cSJim Jagielski ${$filecontent}[$i] =~ s/\bVersionNT\b/VersionNT64/g; 1312*b1cdbd2cSJim Jagielski $saving_required = 1; 1313*b1cdbd2cSJim Jagielski } 1314*b1cdbd2cSJim Jagielski } 1315*b1cdbd2cSJim Jagielski 1316*b1cdbd2cSJim Jagielski if ( $saving_required ) 1317*b1cdbd2cSJim Jagielski { 1318*b1cdbd2cSJim Jagielski # Saving the files 1319*b1cdbd2cSJim Jagielski installer::files::save_file($fullfilename ,$filecontent); 1320*b1cdbd2cSJim Jagielski $infoline = "Making idt file 64 bit conform: $fullfilename\n"; 1321*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 1322*b1cdbd2cSJim Jagielski } 1323*b1cdbd2cSJim Jagielski } 1324*b1cdbd2cSJim Jagielski } 1325*b1cdbd2cSJim Jagielski } 1326*b1cdbd2cSJim Jagielski 1327*b1cdbd2cSJim Jagielski} 1328*b1cdbd2cSJim Jagielski 1329*b1cdbd2cSJim Jagielski################################################################# 1330*b1cdbd2cSJim Jagielski# Include all cab files into the msi database. 1331*b1cdbd2cSJim Jagielski# This works only on Windows 1332*b1cdbd2cSJim Jagielski################################################################# 1333*b1cdbd2cSJim Jagielski 1334*b1cdbd2cSJim Jagielskisub include_cabs_into_msi 1335*b1cdbd2cSJim Jagielski{ 1336*b1cdbd2cSJim Jagielski my ($installdir) = @_; 1337*b1cdbd2cSJim Jagielski 1338*b1cdbd2cSJim Jagielski installer::logger::include_header_into_logfile("Including cabs into msi database"); 1339*b1cdbd2cSJim Jagielski 1340*b1cdbd2cSJim Jagielski my $from = cwd(); 1341*b1cdbd2cSJim Jagielski my $to = $installdir; 1342*b1cdbd2cSJim Jagielski 1343*b1cdbd2cSJim Jagielski chdir($to); 1344*b1cdbd2cSJim Jagielski 1345*b1cdbd2cSJim Jagielski my $infoline = "Changing into directory: $to"; 1346*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 1347*b1cdbd2cSJim Jagielski 1348*b1cdbd2cSJim Jagielski my $msidb = "msidb.exe"; # Has to be in the path 1349*b1cdbd2cSJim Jagielski my $extraslash = ""; # Has to be set for non-ActiveState perl 1350*b1cdbd2cSJim Jagielski 1351*b1cdbd2cSJim Jagielski my $msifilename = $installer::globals::msidatabasename; 1352*b1cdbd2cSJim Jagielski 1353*b1cdbd2cSJim Jagielski $msifilename = installer::converter::make_path_conform($msifilename); 1354*b1cdbd2cSJim Jagielski 1355*b1cdbd2cSJim Jagielski # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) 1356*b1cdbd2cSJim Jagielski $msifilename =~ s/\//\\\\/g; 1357*b1cdbd2cSJim Jagielski $extraslash = "\\"; 1358*b1cdbd2cSJim Jagielski 1359*b1cdbd2cSJim Jagielski my $allcabfiles = installer::systemactions::find_file_with_file_extension("cab", $installdir); 1360*b1cdbd2cSJim Jagielski 1361*b1cdbd2cSJim Jagielski for ( my $i = 0; $i <= $#{$allcabfiles}; $i++ ) 1362*b1cdbd2cSJim Jagielski { 1363*b1cdbd2cSJim Jagielski my $systemcall = $msidb . " -d " . $msifilename . " -a " . ${$allcabfiles}[$i]; 1364*b1cdbd2cSJim Jagielski 1365*b1cdbd2cSJim Jagielski my $returnvalue = system($systemcall); 1366*b1cdbd2cSJim Jagielski 1367*b1cdbd2cSJim Jagielski $infoline = "Systemcall: $systemcall\n"; 1368*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 1369*b1cdbd2cSJim Jagielski 1370*b1cdbd2cSJim Jagielski if ($returnvalue) 1371*b1cdbd2cSJim Jagielski { 1372*b1cdbd2cSJim Jagielski $infoline = "ERROR: Could not execute $systemcall !\n"; 1373*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 1374*b1cdbd2cSJim Jagielski } 1375*b1cdbd2cSJim Jagielski else 1376*b1cdbd2cSJim Jagielski { 1377*b1cdbd2cSJim Jagielski $infoline = "Success: Executed $systemcall successfully!\n"; 1378*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 1379*b1cdbd2cSJim Jagielski } 1380*b1cdbd2cSJim Jagielski 1381*b1cdbd2cSJim Jagielski # deleting the cab file 1382*b1cdbd2cSJim Jagielski 1383*b1cdbd2cSJim Jagielski unlink(${$allcabfiles}[$i]); 1384*b1cdbd2cSJim Jagielski 1385*b1cdbd2cSJim Jagielski $infoline = "Deleted cab file: ${$allcabfiles}[$i]\n"; 1386*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 1387*b1cdbd2cSJim Jagielski } 1388*b1cdbd2cSJim Jagielski 1389*b1cdbd2cSJim Jagielski $infoline = "Changing back into directory: $from"; 1390*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 1391*b1cdbd2cSJim Jagielski 1392*b1cdbd2cSJim Jagielski chdir($from); 1393*b1cdbd2cSJim Jagielski} 1394*b1cdbd2cSJim Jagielski 1395*b1cdbd2cSJim Jagielski################################################################# 1396*b1cdbd2cSJim Jagielski# Executing the created batch file to pack all files. 1397*b1cdbd2cSJim Jagielski# This works only on Windows 1398*b1cdbd2cSJim Jagielski################################################################# 1399*b1cdbd2cSJim Jagielski 1400*b1cdbd2cSJim Jagielskisub execute_packaging 1401*b1cdbd2cSJim Jagielski{ 1402*b1cdbd2cSJim Jagielski my ($localpackjobref, $loggingdir, $allvariables) = @_; 1403*b1cdbd2cSJim Jagielski 1404*b1cdbd2cSJim Jagielski installer::logger::include_header_into_logfile("Packaging process"); 1405*b1cdbd2cSJim Jagielski 1406*b1cdbd2cSJim Jagielski $installer::logger::Lang->add_timestamp("Performance Info: Execute packaging start"); 1407*b1cdbd2cSJim Jagielski 1408*b1cdbd2cSJim Jagielski my $infoline = ""; 1409*b1cdbd2cSJim Jagielski my $from = cwd(); 1410*b1cdbd2cSJim Jagielski my $to = $loggingdir; 1411*b1cdbd2cSJim Jagielski 1412*b1cdbd2cSJim Jagielski chdir($to); 1413*b1cdbd2cSJim Jagielski $infoline = "chdir: $to \n"; 1414*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 1415*b1cdbd2cSJim Jagielski 1416*b1cdbd2cSJim Jagielski # if the ddf file contains relative pathes, it is necessary to change into the temp directory 1417*b1cdbd2cSJim Jagielski if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) 1418*b1cdbd2cSJim Jagielski { 1419*b1cdbd2cSJim Jagielski $to = $installer::globals::temppath; 1420*b1cdbd2cSJim Jagielski chdir($to); 1421*b1cdbd2cSJim Jagielski $infoline = "chdir: $to \n"; 1422*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 1423*b1cdbd2cSJim Jagielski } 1424*b1cdbd2cSJim Jagielski 1425*b1cdbd2cSJim Jagielski # changing the tmp directory, because makecab.exe generates temporary cab files 1426*b1cdbd2cSJim Jagielski my $origtemppath = ""; 1427*b1cdbd2cSJim Jagielski if ( $ENV{'TMP'} ) { $origtemppath = $ENV{'TMP'}; } 1428*b1cdbd2cSJim Jagielski $ENV{'TMP'} = $installer::globals::temppath; # setting TMP to the new unique directory! 1429*b1cdbd2cSJim Jagielski 1430*b1cdbd2cSJim Jagielski my $maxmakecabcalls = 3; 1431*b1cdbd2cSJim Jagielski my $allmakecabcalls = $#{$localpackjobref} + 1; 1432*b1cdbd2cSJim Jagielski 1433*b1cdbd2cSJim Jagielski for ( my $i = 0; $i <= $#{$localpackjobref}; $i++ ) 1434*b1cdbd2cSJim Jagielski { 1435*b1cdbd2cSJim Jagielski my $systemcall = ${$localpackjobref}[$i]; 1436*b1cdbd2cSJim Jagielski 1437*b1cdbd2cSJim Jagielski my $callscounter = $i + 1; 1438*b1cdbd2cSJim Jagielski 1439*b1cdbd2cSJim Jagielski $installer::logger::Info->printf("... makecab.exe (%s/%s) ... \n", $callscounter, $allmakecabcalls); 1440*b1cdbd2cSJim Jagielski 1441*b1cdbd2cSJim Jagielski # my $returnvalue = system($systemcall); 1442*b1cdbd2cSJim Jagielski 1443*b1cdbd2cSJim Jagielski for ( my $n = 1; $n <= $maxmakecabcalls; $n++ ) 1444*b1cdbd2cSJim Jagielski { 1445*b1cdbd2cSJim Jagielski my @ddfoutput = (); 1446*b1cdbd2cSJim Jagielski 1447*b1cdbd2cSJim Jagielski $infoline = "Systemcall: $systemcall"; 1448*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 1449*b1cdbd2cSJim Jagielski 1450*b1cdbd2cSJim Jagielski open (DDF, "$systemcall"); 1451*b1cdbd2cSJim Jagielski while (<DDF>) {push(@ddfoutput, $_); } 1452*b1cdbd2cSJim Jagielski close (DDF); 1453*b1cdbd2cSJim Jagielski 1454*b1cdbd2cSJim Jagielski my $returnvalue = $?; # $? contains the return value of the systemcall 1455*b1cdbd2cSJim Jagielski 1456*b1cdbd2cSJim Jagielski if ($returnvalue) 1457*b1cdbd2cSJim Jagielski { 1458*b1cdbd2cSJim Jagielski if ( $n < $maxmakecabcalls ) 1459*b1cdbd2cSJim Jagielski { 1460*b1cdbd2cSJim Jagielski $installer::logger::Info->printf("makecab_error (Try %s): Trying again\n", $n); 1461*b1cdbd2cSJim Jagielski $installer::logger::Lang->printf("makecab_error (Try %s): Trying again\n", $n); 1462*b1cdbd2cSJim Jagielski } 1463*b1cdbd2cSJim Jagielski else 1464*b1cdbd2cSJim Jagielski { 1465*b1cdbd2cSJim Jagielski $installer::logger::Info->printf("ERROR (Try %s): Abort packing \n", $n); 1466*b1cdbd2cSJim Jagielski $installer::logger::Lang->printf("ERROR (Try %s): Abort packing \n", $n); 1467*b1cdbd2cSJim Jagielski } 1468*b1cdbd2cSJim Jagielski 1469*b1cdbd2cSJim Jagielski for ( my $m = 0; $m <= $#ddfoutput; $m++ ) 1470*b1cdbd2cSJim Jagielski { 1471*b1cdbd2cSJim Jagielski if ( $ddfoutput[$m] =~ /(ERROR\:.*?)\s*$/ ) 1472*b1cdbd2cSJim Jagielski { 1473*b1cdbd2cSJim Jagielski $infoline = $1 . "\n"; 1474*b1cdbd2cSJim Jagielski if ( $n < $maxmakecabcalls ) 1475*b1cdbd2cSJim Jagielski { 1476*b1cdbd2cSJim Jagielski $infoline =~ s/ERROR\:/makecab_error\:/i; 1477*b1cdbd2cSJim Jagielski } 1478*b1cdbd2cSJim Jagielski $installer::logger::Info->print($infoline); 1479*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 1480*b1cdbd2cSJim Jagielski } 1481*b1cdbd2cSJim Jagielski } 1482*b1cdbd2cSJim Jagielski 1483*b1cdbd2cSJim Jagielski if ( $n == $maxmakecabcalls ) { installer::exiter::exit_program("ERROR: \"$systemcall\"!", "execute_packaging"); } 1484*b1cdbd2cSJim Jagielski } 1485*b1cdbd2cSJim Jagielski else 1486*b1cdbd2cSJim Jagielski { 1487*b1cdbd2cSJim Jagielski $infoline = "Success (Try $n): $systemcall"; 1488*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 1489*b1cdbd2cSJim Jagielski last; 1490*b1cdbd2cSJim Jagielski } 1491*b1cdbd2cSJim Jagielski } 1492*b1cdbd2cSJim Jagielski } 1493*b1cdbd2cSJim Jagielski 1494*b1cdbd2cSJim Jagielski $installer::logger::Lang->add_timestamp("Performance Info: Execute packaging end"); 1495*b1cdbd2cSJim Jagielski 1496*b1cdbd2cSJim Jagielski # setting back to the original tmp directory 1497*b1cdbd2cSJim Jagielski $ENV{'TMP'} = $origtemppath; 1498*b1cdbd2cSJim Jagielski 1499*b1cdbd2cSJim Jagielski chdir($from); 1500*b1cdbd2cSJim Jagielski $infoline = "chdir: $from \n"; 1501*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 1502*b1cdbd2cSJim Jagielski} 1503*b1cdbd2cSJim Jagielski 1504*b1cdbd2cSJim Jagielski 1505*b1cdbd2cSJim Jagielski=head2 get_source_codes($languagesref) 1506*b1cdbd2cSJim Jagielski 1507*b1cdbd2cSJim Jagielski Return product code and upgrade code from the source version. 1508*b1cdbd2cSJim Jagielski When no source version is defined then return undef for both. 1509*b1cdbd2cSJim Jagielski 1510*b1cdbd2cSJim Jagielski=cut 1511*b1cdbd2cSJim Jagielskisub get_source_codes ($) 1512*b1cdbd2cSJim Jagielski{ 1513*b1cdbd2cSJim Jagielski my ($languagesref) = @_; 1514*b1cdbd2cSJim Jagielski 1515*b1cdbd2cSJim Jagielski if ( ! $installer::globals::is_release) 1516*b1cdbd2cSJim Jagielski { 1517*b1cdbd2cSJim Jagielski return (undef, undef); 1518*b1cdbd2cSJim Jagielski } 1519*b1cdbd2cSJim Jagielski elsif ( ! defined $installer::globals::source_version) 1520*b1cdbd2cSJim Jagielski { 1521*b1cdbd2cSJim Jagielski $installer::logger::Lang->printf("no source version defined\n"); 1522*b1cdbd2cSJim Jagielski return (undef, undef); 1523*b1cdbd2cSJim Jagielski } 1524*b1cdbd2cSJim Jagielski 1525*b1cdbd2cSJim Jagielski my $onelanguage = installer::languages::get_key_language($languagesref); 1526*b1cdbd2cSJim Jagielski 1527*b1cdbd2cSJim Jagielski my $release_data = installer::patch::ReleasesList::Instance() 1528*b1cdbd2cSJim Jagielski ->{$installer::globals::source_version} 1529*b1cdbd2cSJim Jagielski ->{$installer::globals::packageformat}; 1530*b1cdbd2cSJim Jagielski if (defined $release_data) 1531*b1cdbd2cSJim Jagielski { 1532*b1cdbd2cSJim Jagielski my $normalized_language = installer::languages::get_normalized_language($languagesref); 1533*b1cdbd2cSJim Jagielski my $language_data = $release_data->{$normalized_language}; 1534*b1cdbd2cSJim Jagielski if (defined $language_data) 1535*b1cdbd2cSJim Jagielski { 1536*b1cdbd2cSJim Jagielski $installer::logger::Lang->printf("source product code is %s\n", $language_data->{'product-code'}); 1537*b1cdbd2cSJim Jagielski $installer::logger::Lang->printf("source upgrade code is %s\n", $release_data->{'upgrade-code'}); 1538*b1cdbd2cSJim Jagielski 1539*b1cdbd2cSJim Jagielski return ( 1540*b1cdbd2cSJim Jagielski $language_data->{'product-code'}, 1541*b1cdbd2cSJim Jagielski $release_data->{'upgrade-code'} 1542*b1cdbd2cSJim Jagielski ); 1543*b1cdbd2cSJim Jagielski } 1544*b1cdbd2cSJim Jagielski else 1545*b1cdbd2cSJim Jagielski { 1546*b1cdbd2cSJim Jagielski $installer::logger::Info->printf( 1547*b1cdbd2cSJim Jagielski "Warning: can not access information about previous version %s and language %s/%s/%s\n", 1548*b1cdbd2cSJim Jagielski $installer::globals::source_version, 1549*b1cdbd2cSJim Jagielski $onelanguage, 1550*b1cdbd2cSJim Jagielski join(", ",@$languagesref), 1551*b1cdbd2cSJim Jagielski $normalized_language); 1552*b1cdbd2cSJim Jagielski return (undef,undef); 1553*b1cdbd2cSJim Jagielski } 1554*b1cdbd2cSJim Jagielski } 1555*b1cdbd2cSJim Jagielski else 1556*b1cdbd2cSJim Jagielski { 1557*b1cdbd2cSJim Jagielski $installer::logger::Info->printf("Warning: can not access information about previous version %s\n", 1558*b1cdbd2cSJim Jagielski $installer::globals::source_version); 1559*b1cdbd2cSJim Jagielski return (undef,undef); 1560*b1cdbd2cSJim Jagielski } 1561*b1cdbd2cSJim Jagielski} 1562*b1cdbd2cSJim Jagielski 1563*b1cdbd2cSJim Jagielski 1564*b1cdbd2cSJim Jagielski 1565*b1cdbd2cSJim Jagielski 1566*b1cdbd2cSJim Jagielski=head2 set_global_code_variables ($languagesref, $allvariableshashref) 1567*b1cdbd2cSJim Jagielski 1568*b1cdbd2cSJim Jagielski Determine values for the product code and upgrade code of the target version. 1569*b1cdbd2cSJim Jagielski 1570*b1cdbd2cSJim Jagielski As perparation for building a Windows patch, certain conditions have to be fullfilled. 1571*b1cdbd2cSJim Jagielski - The upgrade code changes from old to new version 1572*b1cdbd2cSJim Jagielski - The product code remains the same 1573*b1cdbd2cSJim Jagielski In order to inforce that we have to access information about the source version. 1574*b1cdbd2cSJim Jagielski 1575*b1cdbd2cSJim Jagielski The resulting values are stored as global variables 1576*b1cdbd2cSJim Jagielski $installer::globals::productcode 1577*b1cdbd2cSJim Jagielski $installer::globals::upgradecode 1578*b1cdbd2cSJim Jagielski and as variables in the given hash 1579*b1cdbd2cSJim Jagielski $allvariableshashref->{'PRODUCTCODE'} 1580*b1cdbd2cSJim Jagielski $allvariableshashref->{'UPGRADECODE'} 1581*b1cdbd2cSJim Jagielski 1582*b1cdbd2cSJim Jagielski=cut 1583*b1cdbd2cSJim Jagielskisub set_global_code_variables ($$) 1584*b1cdbd2cSJim Jagielski{ 1585*b1cdbd2cSJim Jagielski my ($languagesref, $allvariableshashref) = @_; 1586*b1cdbd2cSJim Jagielski 1587*b1cdbd2cSJim Jagielski my ($source_product_code, $source_upgrade_code) = get_source_codes($languagesref); 1588*b1cdbd2cSJim Jagielski my ($target_product_code, $target_upgrade_code) = (undef, undef); 1589*b1cdbd2cSJim Jagielski 1590*b1cdbd2cSJim Jagielski if (defined $source_product_code && defined $source_upgrade_code) 1591*b1cdbd2cSJim Jagielski { 1592*b1cdbd2cSJim Jagielski if ($installer::globals::is_major_release) 1593*b1cdbd2cSJim Jagielski { 1594*b1cdbd2cSJim Jagielski # For a major release we have to change the product code. 1595*b1cdbd2cSJim Jagielski $target_product_code = "{" . create_guid() . "}"; 1596*b1cdbd2cSJim Jagielski $installer::logger::Lang->printf("building a major release, created new product code %s\n", 1597*b1cdbd2cSJim Jagielski $target_product_code); 1598*b1cdbd2cSJim Jagielski 1599*b1cdbd2cSJim Jagielski # Let's do a paranoia check that the new and the old guids are 1600*b1cdbd2cSJim Jagielski # different. In reality the new guid really has to be 1601*b1cdbd2cSJim Jagielski # different from all other guids used for * codes, components, 1602*b1cdbd2cSJim Jagielski # etc. 1603*b1cdbd2cSJim Jagielski if ($target_product_code eq $source_product_code) 1604*b1cdbd2cSJim Jagielski { 1605*b1cdbd2cSJim Jagielski installer::logger::PrintError( 1606*b1cdbd2cSJim Jagielski "new GUID for product code is the same as the old product code but should be different."); 1607*b1cdbd2cSJim Jagielski } 1608*b1cdbd2cSJim Jagielski } 1609*b1cdbd2cSJim Jagielski else 1610*b1cdbd2cSJim Jagielski { 1611*b1cdbd2cSJim Jagielski # For minor or micro releases we have to keeep the old product code. 1612*b1cdbd2cSJim Jagielski $target_product_code = "{" . $source_product_code . "}"; 1613*b1cdbd2cSJim Jagielski $installer::logger::Lang->printf("building a minor or micro release, reusing product code %s\n", 1614*b1cdbd2cSJim Jagielski $target_product_code); 1615*b1cdbd2cSJim Jagielski } 1616*b1cdbd2cSJim Jagielski 1617*b1cdbd2cSJim Jagielski $target_upgrade_code = "{" . create_guid() . "}"; 1618*b1cdbd2cSJim Jagielski # Again, just one test for paranoia. 1619*b1cdbd2cSJim Jagielski if ($target_upgrade_code eq $source_upgrade_code) 1620*b1cdbd2cSJim Jagielski { 1621*b1cdbd2cSJim Jagielski installer::logger::PrintError( 1622*b1cdbd2cSJim Jagielski "new GUID for upgrade code is the same as the old upgrade code but should be different."); 1623*b1cdbd2cSJim Jagielski } 1624*b1cdbd2cSJim Jagielski } 1625*b1cdbd2cSJim Jagielski else 1626*b1cdbd2cSJim Jagielski { 1627*b1cdbd2cSJim Jagielski # There is no previous version with which to compare the product code. 1628*b1cdbd2cSJim Jagielski # Just create two new uuids. 1629*b1cdbd2cSJim Jagielski $target_product_code = "{" . create_guid() . "}"; 1630*b1cdbd2cSJim Jagielski $target_upgrade_code = "{" . create_guid() . "}"; 1631*b1cdbd2cSJim Jagielski $installer::logger::Lang->printf("there is no source version => created new guids\n"); 1632*b1cdbd2cSJim Jagielski } 1633*b1cdbd2cSJim Jagielski 1634*b1cdbd2cSJim Jagielski # Keep the upgrade code constant between versions. Read it from the codes.txt file. 1635*b1cdbd2cSJim Jagielski # Note that this handles regular installation sets and language packs. 1636*b1cdbd2cSJim Jagielski my $onelanguage = ${$languagesref}[0]; 1637*b1cdbd2cSJim Jagielski $installer::logger::Lang->printf("reading upgrade code for language %s from %s\n", 1638*b1cdbd2cSJim Jagielski $onelanguage, 1639*b1cdbd2cSJim Jagielski $installer::globals::codefilename); 1640*b1cdbd2cSJim Jagielski if (defined $installer::globals::codefilename) 1641*b1cdbd2cSJim Jagielski { 1642*b1cdbd2cSJim Jagielski my $code_filename = $installer::globals::codefilename; 1643*b1cdbd2cSJim Jagielski installer::files::check_file($code_filename); 1644*b1cdbd2cSJim Jagielski my $codefile = installer::files::read_file($code_filename); 1645*b1cdbd2cSJim Jagielski my $searchstring = "UPGRADECODE"; 1646*b1cdbd2cSJim Jagielski my $codeblock = installer::windows::idtglobal::get_language_block_from_language_file( 1647*b1cdbd2cSJim Jagielski $searchstring, 1648*b1cdbd2cSJim Jagielski $codefile); 1649*b1cdbd2cSJim Jagielski $target_upgrade_code = installer::windows::idtglobal::get_language_string_from_language_block( 1650*b1cdbd2cSJim Jagielski $codeblock, 1651*b1cdbd2cSJim Jagielski $onelanguage, 1652*b1cdbd2cSJim Jagielski ""); 1653*b1cdbd2cSJim Jagielski } 1654*b1cdbd2cSJim Jagielski # else use the previously generated upgrade code. 1655*b1cdbd2cSJim Jagielski 1656*b1cdbd2cSJim Jagielski $installer::globals::productcode = $target_product_code; 1657*b1cdbd2cSJim Jagielski $installer::globals::upgradecode = $target_upgrade_code; 1658*b1cdbd2cSJim Jagielski $allvariableshashref->{'PRODUCTCODE'} = $target_product_code; 1659*b1cdbd2cSJim Jagielski $allvariableshashref->{'UPGRADECODE'} = $target_upgrade_code; 1660*b1cdbd2cSJim Jagielski 1661*b1cdbd2cSJim Jagielski $installer::logger::Lang->printf("target product code is %s\n", $target_product_code); 1662*b1cdbd2cSJim Jagielski $installer::logger::Lang->printf("target upgrade code is %s\n", $target_upgrade_code); 1663*b1cdbd2cSJim Jagielski} 1664*b1cdbd2cSJim Jagielski 1665*b1cdbd2cSJim Jagielski 1666*b1cdbd2cSJim Jagielski 1667*b1cdbd2cSJim Jagielski 1668*b1cdbd2cSJim Jagielski############################################################### 1669*b1cdbd2cSJim Jagielski# Setting the product version used in property table and 1670*b1cdbd2cSJim Jagielski# upgrade table. Saving in global variable $msiproductversion 1671*b1cdbd2cSJim Jagielski############################################################### 1672*b1cdbd2cSJim Jagielski 1673*b1cdbd2cSJim Jagielskisub set_msiproductversion 1674*b1cdbd2cSJim Jagielski{ 1675*b1cdbd2cSJim Jagielski my ( $allvariables ) = @_; 1676*b1cdbd2cSJim Jagielski 1677*b1cdbd2cSJim Jagielski my $productversion = $allvariables->{'PRODUCTVERSION'}; 1678*b1cdbd2cSJim Jagielski 1679*b1cdbd2cSJim Jagielski if (( $productversion =~ /^\s*\d+\s*$/ ) && ( $productversion > 255 )) { $productversion = $productversion%256; } 1680*b1cdbd2cSJim Jagielski 1681*b1cdbd2cSJim Jagielski if ( $productversion =~ /^\s*(\d+)\.(\d+)\.(\d+)\s*$/ ) 1682*b1cdbd2cSJim Jagielski { 1683*b1cdbd2cSJim Jagielski $productversion = $1 . "\." . $2 . $3 . "\." . $installer::globals::buildid; 1684*b1cdbd2cSJim Jagielski } 1685*b1cdbd2cSJim Jagielski elsif ( $productversion =~ /^\s*(\d+)\.(\d+)\s*$/ ) 1686*b1cdbd2cSJim Jagielski { 1687*b1cdbd2cSJim Jagielski $productversion = $1 . "\." . $2 . "\." . $installer::globals::buildid; 1688*b1cdbd2cSJim Jagielski } 1689*b1cdbd2cSJim Jagielski else 1690*b1cdbd2cSJim Jagielski { 1691*b1cdbd2cSJim Jagielski my $productminor = "00"; 1692*b1cdbd2cSJim Jagielski if (( $allvariables->{'PACKAGEVERSION'} ) && ( $allvariables->{'PACKAGEVERSION'} ne "" )) 1693*b1cdbd2cSJim Jagielski { 1694*b1cdbd2cSJim Jagielski if ( $allvariables->{'PACKAGEVERSION'} =~ /^\s*(\d+)\.(\d+)\.(\d+)\s*$/ ) { $productminor = $2; } 1695*b1cdbd2cSJim Jagielski } 1696*b1cdbd2cSJim Jagielski 1697*b1cdbd2cSJim Jagielski $productversion = $productversion . "\." . $productminor . "\." . $installer::globals::buildid; 1698*b1cdbd2cSJim Jagielski } 1699*b1cdbd2cSJim Jagielski 1700*b1cdbd2cSJim Jagielski $installer::globals::msiproductversion = $productversion; 1701*b1cdbd2cSJim Jagielski 1702*b1cdbd2cSJim Jagielski # Setting $installer::globals::msimajorproductversion, to differ between old version in upgrade table 1703*b1cdbd2cSJim Jagielski 1704*b1cdbd2cSJim Jagielski if ( $installer::globals::msiproductversion =~ /^\s*(\d+)\./ ) 1705*b1cdbd2cSJim Jagielski { 1706*b1cdbd2cSJim Jagielski my $major = $1; 1707*b1cdbd2cSJim Jagielski $installer::globals::msimajorproductversion = $major . "\.0\.0"; 1708*b1cdbd2cSJim Jagielski } 1709*b1cdbd2cSJim Jagielski} 1710*b1cdbd2cSJim Jagielski 1711*b1cdbd2cSJim Jagielski################################################################################# 1712*b1cdbd2cSJim Jagielski# Including the msi product version into the bootstrap.ini, Windows only 1713*b1cdbd2cSJim Jagielski################################################################################# 1714*b1cdbd2cSJim Jagielski 1715*b1cdbd2cSJim Jagielskisub put_msiproductversion_into_bootstrapfile 1716*b1cdbd2cSJim Jagielski{ 1717*b1cdbd2cSJim Jagielski my ($filesref) = @_; 1718*b1cdbd2cSJim Jagielski 1719*b1cdbd2cSJim Jagielski for ( my $i = 0; $i <= $#{$filesref}; $i++ ) 1720*b1cdbd2cSJim Jagielski { 1721*b1cdbd2cSJim Jagielski my $onefile = ${$filesref}[$i]; 1722*b1cdbd2cSJim Jagielski 1723*b1cdbd2cSJim Jagielski if ( $onefile->{'gid'} eq "gid_Profile_Version_Ini" ) 1724*b1cdbd2cSJim Jagielski { 1725*b1cdbd2cSJim Jagielski my $file = installer::files::read_file($onefile->{'sourcepath'}); 1726*b1cdbd2cSJim Jagielski 1727*b1cdbd2cSJim Jagielski for ( my $j = 0; $j <= $#{$file}; $j++ ) 1728*b1cdbd2cSJim Jagielski { 1729*b1cdbd2cSJim Jagielski ${$file}[$j] =~ s/\<msiproductversion\>/$installer::globals::msiproductversion/; 1730*b1cdbd2cSJim Jagielski } 1731*b1cdbd2cSJim Jagielski 1732*b1cdbd2cSJim Jagielski installer::files::save_file($onefile->{'sourcepath'}, $file); 1733*b1cdbd2cSJim Jagielski 1734*b1cdbd2cSJim Jagielski last; 1735*b1cdbd2cSJim Jagielski } 1736*b1cdbd2cSJim Jagielski } 1737*b1cdbd2cSJim Jagielski} 1738*b1cdbd2cSJim Jagielski 1739*b1cdbd2cSJim Jagielski#################################################################################### 1740*b1cdbd2cSJim Jagielski# Updating the file Property.idt dynamically 1741*b1cdbd2cSJim Jagielski# Content: 1742*b1cdbd2cSJim Jagielski# Property Value 1743*b1cdbd2cSJim Jagielski#################################################################################### 1744*b1cdbd2cSJim Jagielski 1745*b1cdbd2cSJim Jagielskisub update_reglocat_table 1746*b1cdbd2cSJim Jagielski{ 1747*b1cdbd2cSJim Jagielski my ($basedir, $allvariables) = @_; 1748*b1cdbd2cSJim Jagielski 1749*b1cdbd2cSJim Jagielski my $reglocatfilename = $basedir . $installer::globals::separator . "RegLocat.idt"; 1750*b1cdbd2cSJim Jagielski 1751*b1cdbd2cSJim Jagielski # Only do something, if this file exists 1752*b1cdbd2cSJim Jagielski 1753*b1cdbd2cSJim Jagielski if ( -f $reglocatfilename ) 1754*b1cdbd2cSJim Jagielski { 1755*b1cdbd2cSJim Jagielski my $reglocatfile = installer::files::read_file($reglocatfilename); 1756*b1cdbd2cSJim Jagielski 1757*b1cdbd2cSJim Jagielski my $layername = ""; 1758*b1cdbd2cSJim Jagielski if ( $allvariables->{'REGISTRYLAYERNAME'} ) 1759*b1cdbd2cSJim Jagielski { 1760*b1cdbd2cSJim Jagielski $layername = $allvariables->{'REGISTRYLAYERNAME'}; 1761*b1cdbd2cSJim Jagielski } 1762*b1cdbd2cSJim Jagielski else 1763*b1cdbd2cSJim Jagielski { 1764*b1cdbd2cSJim Jagielski for ( my $i = 0; $i <= $#{$reglocatfile}; $i++ ) 1765*b1cdbd2cSJim Jagielski { 1766*b1cdbd2cSJim Jagielski if ( ${$reglocatfile}[$i] =~ /\bLAYERNAMETEMPLATE\b/ ) 1767*b1cdbd2cSJim Jagielski { 1768*b1cdbd2cSJim Jagielski installer::exiter::exit_program("ERROR: Variable \"REGISTRYLAYERNAME\" has to be defined", "update_reglocat_table"); 1769*b1cdbd2cSJim Jagielski } 1770*b1cdbd2cSJim Jagielski } 1771*b1cdbd2cSJim Jagielski } 1772*b1cdbd2cSJim Jagielski 1773*b1cdbd2cSJim Jagielski if ( $layername ne "" ) 1774*b1cdbd2cSJim Jagielski { 1775*b1cdbd2cSJim Jagielski # Updating the layername in 1776*b1cdbd2cSJim Jagielski 1777*b1cdbd2cSJim Jagielski for ( my $i = 0; $i <= $#{$reglocatfile}; $i++ ) 1778*b1cdbd2cSJim Jagielski { 1779*b1cdbd2cSJim Jagielski ${$reglocatfile}[$i] =~ s/\bLAYERNAMETEMPLATE\b/$layername/; 1780*b1cdbd2cSJim Jagielski } 1781*b1cdbd2cSJim Jagielski 1782*b1cdbd2cSJim Jagielski # Saving the file 1783*b1cdbd2cSJim Jagielski installer::files::save_file($reglocatfilename ,$reglocatfile); 1784*b1cdbd2cSJim Jagielski my $infoline = "Updated idt file: $reglocatfilename\n"; 1785*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 1786*b1cdbd2cSJim Jagielski } 1787*b1cdbd2cSJim Jagielski } 1788*b1cdbd2cSJim Jagielski} 1789*b1cdbd2cSJim Jagielski 1790*b1cdbd2cSJim Jagielski 1791*b1cdbd2cSJim Jagielski 1792*b1cdbd2cSJim Jagielski#################################################################################### 1793*b1cdbd2cSJim Jagielski# Updating the file RemoveRe.idt dynamically (RemoveRegistry.idt) 1794*b1cdbd2cSJim Jagielski# The name of the component has to be replaced. 1795*b1cdbd2cSJim Jagielski#################################################################################### 1796*b1cdbd2cSJim Jagielski 1797*b1cdbd2cSJim Jagielskisub update_removere_table 1798*b1cdbd2cSJim Jagielski{ 1799*b1cdbd2cSJim Jagielski my ($basedir) = @_; 1800*b1cdbd2cSJim Jagielski 1801*b1cdbd2cSJim Jagielski my $removeregistryfilename = $basedir . $installer::globals::separator . "RemoveRe.idt"; 1802*b1cdbd2cSJim Jagielski 1803*b1cdbd2cSJim Jagielski # Only do something, if this file exists 1804*b1cdbd2cSJim Jagielski 1805*b1cdbd2cSJim Jagielski if ( -f $removeregistryfilename ) 1806*b1cdbd2cSJim Jagielski { 1807*b1cdbd2cSJim Jagielski my $removeregistryfile = installer::files::read_file($removeregistryfilename); 1808*b1cdbd2cSJim Jagielski 1809*b1cdbd2cSJim Jagielski for ( my $i = 0; $i <= $#{$removeregistryfile}; $i++ ) 1810*b1cdbd2cSJim Jagielski { 1811*b1cdbd2cSJim Jagielski for ( my $i = 0; $i <= $#{$removeregistryfile}; $i++ ) 1812*b1cdbd2cSJim Jagielski { 1813*b1cdbd2cSJim Jagielski ${$removeregistryfile}[$i] =~ s/\bREGISTRYROOTCOMPONENT\b/$installer::globals::registryrootcomponent/; 1814*b1cdbd2cSJim Jagielski } 1815*b1cdbd2cSJim Jagielski } 1816*b1cdbd2cSJim Jagielski 1817*b1cdbd2cSJim Jagielski # Saving the file 1818*b1cdbd2cSJim Jagielski installer::files::save_file($removeregistryfilename ,$removeregistryfile); 1819*b1cdbd2cSJim Jagielski my $infoline = "Updated idt file: $removeregistryfilename \n"; 1820*b1cdbd2cSJim Jagielski $installer::logger::Lang->print($infoline); 1821*b1cdbd2cSJim Jagielski } 1822*b1cdbd2cSJim Jagielski} 1823*b1cdbd2cSJim Jagielski 1824*b1cdbd2cSJim Jagielski 1825*b1cdbd2cSJim Jagielski1; 1826*b1cdbd2cSJim Jagielski 1827