19780544fSAndrew Rist#************************************************************** 29780544fSAndrew Rist# 39780544fSAndrew Rist# Licensed to the Apache Software Foundation (ASF) under one 49780544fSAndrew Rist# or more contributor license agreements. See the NOTICE file 59780544fSAndrew Rist# distributed with this work for additional information 69780544fSAndrew Rist# regarding copyright ownership. The ASF licenses this file 79780544fSAndrew Rist# to you under the Apache License, Version 2.0 (the 89780544fSAndrew Rist# "License"); you may not use this file except in compliance 99780544fSAndrew Rist# with the License. You may obtain a copy of the License at 109780544fSAndrew Rist# 119780544fSAndrew Rist# http://www.apache.org/licenses/LICENSE-2.0 129780544fSAndrew Rist# 139780544fSAndrew Rist# Unless required by applicable law or agreed to in writing, 149780544fSAndrew Rist# software distributed under the License is distributed on an 159780544fSAndrew Rist# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 169780544fSAndrew Rist# KIND, either express or implied. See the License for the 179780544fSAndrew Rist# specific language governing permissions and limitations 189780544fSAndrew Rist# under the License. 199780544fSAndrew Rist# 209780544fSAndrew Rist#************************************************************** 219780544fSAndrew Rist 229780544fSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweirpackage installer::windows::sign; 25cdf0e10cSrcweir 26cdf0e10cSrcweiruse Cwd; 27cdf0e10cSrcweiruse installer::converter; 28cdf0e10cSrcweiruse installer::existence; 29cdf0e10cSrcweiruse installer::files; 30cdf0e10cSrcweiruse installer::globals; 31cdf0e10cSrcweiruse installer::scriptitems; 32cdf0e10cSrcweiruse installer::worker; 33cdf0e10cSrcweiruse installer::windows::admin; 34cdf0e10cSrcweir 35cdf0e10cSrcweir######################################################## 36cdf0e10cSrcweir# Copying an existing Windows installation set. 37cdf0e10cSrcweir######################################################## 38cdf0e10cSrcweir 39cdf0e10cSrcweirsub copy_install_set 40cdf0e10cSrcweir{ 41cdf0e10cSrcweir my ( $installsetpath ) = @_; 42cdf0e10cSrcweir 43cdf0e10cSrcweir installer::logger::include_header_into_logfile("Start: Copying installation set $installsetpath"); 44cdf0e10cSrcweir 45cdf0e10cSrcweir my $infoline = ""; 46cdf0e10cSrcweir 47cdf0e10cSrcweir my $dirname = $installsetpath; 48cdf0e10cSrcweir installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$dirname); 49cdf0e10cSrcweir 50cdf0e10cSrcweir my $path = $installsetpath; 51cdf0e10cSrcweir installer::pathanalyzer::get_path_from_fullqualifiedname(\$path); 52cdf0e10cSrcweir 53cdf0e10cSrcweir $path =~ s/\Q$installer::globals::separator\E\s*$//; 54cdf0e10cSrcweir 55cdf0e10cSrcweir if ( $dirname =~ /\./ ) { $dirname =~ s/\./_signed_inprogress./; } 56cdf0e10cSrcweir else { $dirname = $dirname . "_signed_inprogress"; } 57cdf0e10cSrcweir 58cdf0e10cSrcweir my $newpath = $path . $installer::globals::separator . $dirname; 59cdf0e10cSrcweir my $removepath = $newpath; 60cdf0e10cSrcweir $removepath =~ s/_inprogress/_witherror/; 61cdf0e10cSrcweir 62cdf0e10cSrcweir if ( -d $newpath ) { installer::systemactions::remove_complete_directory($newpath, 1); } 63cdf0e10cSrcweir if ( -d $removepath ) { installer::systemactions::remove_complete_directory($removepath, 1); } 64cdf0e10cSrcweir 65cdf0e10cSrcweir $infoline = "Copy installation set from $installsetpath to $newpath\n"; 66*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 67cdf0e10cSrcweir 68cdf0e10cSrcweir $installsetpath = installer::systemactions::copy_complete_directory($installsetpath, $newpath); 69cdf0e10cSrcweir 70cdf0e10cSrcweir installer::logger::include_header_into_logfile("End: Copying installation set $installsetpath"); 71cdf0e10cSrcweir 72cdf0e10cSrcweir return $newpath; 73cdf0e10cSrcweir} 74cdf0e10cSrcweir 75cdf0e10cSrcweir######################################################## 76cdf0e10cSrcweir# Renaming an existing Windows installation set. 77cdf0e10cSrcweir######################################################## 78cdf0e10cSrcweir 79cdf0e10cSrcweirsub rename_install_set 80cdf0e10cSrcweir{ 81cdf0e10cSrcweir my ( $installsetpath ) = @_; 82cdf0e10cSrcweir 83cdf0e10cSrcweir my $infoline = ""; 84cdf0e10cSrcweir 85cdf0e10cSrcweir my $dirname = $installsetpath; 86cdf0e10cSrcweir installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$dirname); 87cdf0e10cSrcweir 88cdf0e10cSrcweir my $path = $installsetpath; 89cdf0e10cSrcweir installer::pathanalyzer::get_path_from_fullqualifiedname(\$path); 90cdf0e10cSrcweir 91cdf0e10cSrcweir $path =~ s/\Q$installer::globals::separator\E\s*$//; 92cdf0e10cSrcweir 93cdf0e10cSrcweir if ( $dirname =~ /\./ ) { $dirname =~ s/\./_inprogress./; } 94cdf0e10cSrcweir else { $dirname = $dirname . "_inprogress"; } 95cdf0e10cSrcweir 96cdf0e10cSrcweir my $newpath = $path . $installer::globals::separator . $dirname; 97cdf0e10cSrcweir my $removepath = $newpath; 98cdf0e10cSrcweir $removepath =~ s/_inprogress/_witherror/; 99cdf0e10cSrcweir 100cdf0e10cSrcweir if ( -d $newpath ) { installer::systemactions::remove_complete_directory($newpath, 1); } 101cdf0e10cSrcweir if ( -d $removepath ) { installer::systemactions::remove_complete_directory($removepath, 1); } 102cdf0e10cSrcweir 103cdf0e10cSrcweir $installsetpath = installer::systemactions::rename_directory($installsetpath, $newpath); 104cdf0e10cSrcweir 105cdf0e10cSrcweir return $newpath; 106cdf0e10cSrcweir} 107cdf0e10cSrcweir 108cdf0e10cSrcweir######################################################### 109cdf0e10cSrcweir# Checking the local system 110cdf0e10cSrcweir# Checking existence of needed files in include path 111cdf0e10cSrcweir######################################################### 112cdf0e10cSrcweir 113cdf0e10cSrcweirsub check_system_path 114cdf0e10cSrcweir{ 115cdf0e10cSrcweir # The following files have to be found in the environment variable PATH 116cdf0e10cSrcweir # Only, if \"-sign\" is used. 117cdf0e10cSrcweir # Windows : "msicert.exe", "diff.exe", "msidb.exe", "signtool.exe" 118cdf0e10cSrcweir 119cdf0e10cSrcweir my @needed_files_in_path = ("msicert.exe", "msidb.exe", "signtool.exe", "diff.exe"); 120cdf0e10cSrcweir if ( $installer::globals::internal_cabinet_signing ) 121cdf0e10cSrcweir { 122cdf0e10cSrcweir push(@needed_files_in_path, "cabarc.exe"); 123cdf0e10cSrcweir push(@needed_files_in_path, "makecab.exe"); 124cdf0e10cSrcweir } 125cdf0e10cSrcweir 126cdf0e10cSrcweir my $onefile; 127cdf0e10cSrcweir my $error = 0; 128cdf0e10cSrcweir my $pathvariable = $ENV{'PATH'}; 129cdf0e10cSrcweir my $local_pathseparator = $installer::globals::pathseparator; 130cdf0e10cSrcweir 131cdf0e10cSrcweir if( $^O =~ /cygwin/i ) 132cdf0e10cSrcweir { # When using cygwin's perl the PATH variable is POSIX style and ... 133cdf0e10cSrcweir $pathvariable = qx{cygpath -mp "$pathvariable"} ; 134cdf0e10cSrcweir # has to be converted to DOS style for further use. 135cdf0e10cSrcweir $local_pathseparator = ';'; 136cdf0e10cSrcweir } 137cdf0e10cSrcweir 138cdf0e10cSrcweir my $patharrayref = installer::converter::convert_stringlist_into_array(\$pathvariable, $local_pathseparator); 139cdf0e10cSrcweir 140cdf0e10cSrcweir $installer::globals::patharray = $patharrayref; 141cdf0e10cSrcweir 142cdf0e10cSrcweir foreach my $onefile ( @needed_files_in_path ) 143cdf0e10cSrcweir { 144*b274bc22SAndre Fischer 145*b274bc22SAndre Fischer $installer::logger::Info->printf("...... searching %s ...\n", $onefile); 146cdf0e10cSrcweir 147cdf0e10cSrcweir my $fileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath_classic(\$onefile, $patharrayref , 0); 148cdf0e10cSrcweir 149cdf0e10cSrcweir if ( $$fileref eq "" ) 150cdf0e10cSrcweir { 151cdf0e10cSrcweir $error = 1; 152cdf0e10cSrcweir installer::logger::print_error( "$onefile not found\n" ); 153cdf0e10cSrcweir } 154cdf0e10cSrcweir else 155cdf0e10cSrcweir { 156*b274bc22SAndre Fischer $installer::logger::Info->printf("\tFound: %s\n", $$fileref); 157cdf0e10cSrcweir } 158cdf0e10cSrcweir } 159cdf0e10cSrcweir 160cdf0e10cSrcweir $installer::globals::signfiles_checked = 1; 161cdf0e10cSrcweir 162cdf0e10cSrcweir if ( $error ) { installer::exiter::exit_program("ERROR: Could not find all needed files in path!", "check_system_path"); } 163cdf0e10cSrcweir} 164cdf0e10cSrcweir 165cdf0e10cSrcweir###################################################### 166cdf0e10cSrcweir# Making systemcall 167cdf0e10cSrcweir###################################################### 168cdf0e10cSrcweir 169cdf0e10cSrcweirsub make_systemcall 170cdf0e10cSrcweir{ 171cdf0e10cSrcweir my ($systemcall, $displaysystemcall) = @_; 172cdf0e10cSrcweir 173*b274bc22SAndre Fischer $installer::logger::Info->printf("... %s ...\n", $displaysystemcall); 174cdf0e10cSrcweir 175cdf0e10cSrcweir my $success = 1; 176cdf0e10cSrcweir my $returnvalue = system($systemcall); 177cdf0e10cSrcweir 178cdf0e10cSrcweir my $infoline = "Systemcall: $displaysystemcall\n"; 179*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 180cdf0e10cSrcweir 181cdf0e10cSrcweir if ($returnvalue) 182cdf0e10cSrcweir { 183cdf0e10cSrcweir $infoline = "ERROR: Could not execute \"$displaysystemcall\"!\n"; 184*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 185cdf0e10cSrcweir $success = 0; 186cdf0e10cSrcweir } 187cdf0e10cSrcweir else 188cdf0e10cSrcweir { 189cdf0e10cSrcweir $infoline = "Success: Executed \"$displaysystemcall\" successfully!\n"; 190*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 191cdf0e10cSrcweir } 192cdf0e10cSrcweir 193cdf0e10cSrcweir return $success; 194cdf0e10cSrcweir} 195cdf0e10cSrcweir 196cdf0e10cSrcweir###################################################### 197cdf0e10cSrcweir# Making systemcall with warning 198cdf0e10cSrcweir###################################################### 199cdf0e10cSrcweir 200cdf0e10cSrcweirsub make_systemcall_with_warning 201cdf0e10cSrcweir{ 202cdf0e10cSrcweir my ($systemcall, $displaysystemcall) = @_; 203cdf0e10cSrcweir 204*b274bc22SAndre Fischer $installer::logger::Info->printf("... %s ...\n", $displaysystemcall); 205cdf0e10cSrcweir 206cdf0e10cSrcweir my $success = 1; 207cdf0e10cSrcweir my $returnvalue = system($systemcall); 208cdf0e10cSrcweir 209cdf0e10cSrcweir my $infoline = "Systemcall: $displaysystemcall\n"; 210*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 211cdf0e10cSrcweir 212cdf0e10cSrcweir if ($returnvalue) 213cdf0e10cSrcweir { 214cdf0e10cSrcweir $infoline = "WARNING: Could not execute \"$displaysystemcall\"!\n"; 215*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 216cdf0e10cSrcweir $success = 0; 217cdf0e10cSrcweir } 218cdf0e10cSrcweir else 219cdf0e10cSrcweir { 220cdf0e10cSrcweir $infoline = "Success: Executed \"$displaysystemcall\" successfully!\n"; 221*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 222cdf0e10cSrcweir } 223cdf0e10cSrcweir 224cdf0e10cSrcweir return $success; 225cdf0e10cSrcweir} 226cdf0e10cSrcweir 227cdf0e10cSrcweir###################################################### 228cdf0e10cSrcweir# Making systemcall with more return data 229cdf0e10cSrcweir###################################################### 230cdf0e10cSrcweir 231cdf0e10cSrcweirsub execute_open_system_call 232cdf0e10cSrcweir{ 233cdf0e10cSrcweir my ( $systemcall ) = @_; 234cdf0e10cSrcweir 235cdf0e10cSrcweir my @openoutput = (); 236cdf0e10cSrcweir my $success = 1; 237cdf0e10cSrcweir 238cdf0e10cSrcweir my $comspec = $ENV{COMSPEC}; 239cdf0e10cSrcweir $comspec = $comspec . " -c "; 240cdf0e10cSrcweir 241cdf0e10cSrcweir if( $^O =~ /cygwin/i ) 242cdf0e10cSrcweir { 243cdf0e10cSrcweir # $comspec =~ s/\\/\\\\/g; 244cdf0e10cSrcweir # $comspec = qx{cygpath -u "$comspec"}; 245cdf0e10cSrcweir # $comspec =~ s/\s*$//g; 246cdf0e10cSrcweir $comspec = ""; 247cdf0e10cSrcweir } 248cdf0e10cSrcweir 249cdf0e10cSrcweir my $localsystemcall = "$comspec $systemcall 2>&1 |"; 250cdf0e10cSrcweir 251cdf0e10cSrcweir open( OPN, "$localsystemcall") or warn "Can't execute $localsystemcall\n"; 252cdf0e10cSrcweir while (<OPN>) { push(@openoutput, $_); } 253cdf0e10cSrcweir close (OPN); 254cdf0e10cSrcweir 255cdf0e10cSrcweir my $returnvalue = $?; # $? contains the return value of the systemcall 256cdf0e10cSrcweir 257cdf0e10cSrcweir if ($returnvalue) 258cdf0e10cSrcweir { 259cdf0e10cSrcweir $infoline = "ERROR: Could not execute \"$systemcall\"!\n"; 260*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 261cdf0e10cSrcweir $success = 0; 262cdf0e10cSrcweir } 263cdf0e10cSrcweir else 264cdf0e10cSrcweir { 265cdf0e10cSrcweir $infoline = "Success: Executed \"$systemcall\" successfully!\n"; 266*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 267cdf0e10cSrcweir } 268cdf0e10cSrcweir 269cdf0e10cSrcweir return ($success, \@openoutput); 270cdf0e10cSrcweir} 271cdf0e10cSrcweir 272cdf0e10cSrcweir######################################################## 273cdf0e10cSrcweir# Reading first line of pw file. 274cdf0e10cSrcweir######################################################## 275cdf0e10cSrcweir 276cdf0e10cSrcweirsub get_pw 277cdf0e10cSrcweir{ 278cdf0e10cSrcweir my ( $file ) = @_; 279cdf0e10cSrcweir 280cdf0e10cSrcweir my $filecontent = installer::files::read_file($file); 281cdf0e10cSrcweir 282cdf0e10cSrcweir my $pw = ${$filecontent}[0]; 283cdf0e10cSrcweir $pw =~ s/^\s*//; 284cdf0e10cSrcweir $pw =~ s/\s*$//; 285cdf0e10cSrcweir 286cdf0e10cSrcweir return $pw; 287cdf0e10cSrcweir} 288cdf0e10cSrcweir 289cdf0e10cSrcweir######################################################## 290cdf0e10cSrcweir# Counting the keys of a hash. 291cdf0e10cSrcweir######################################################## 292cdf0e10cSrcweir 293cdf0e10cSrcweirsub get_hash_count 294cdf0e10cSrcweir{ 295cdf0e10cSrcweir my ($hashref) = @_; 296cdf0e10cSrcweir 297cdf0e10cSrcweir my $counter = 0; 298cdf0e10cSrcweir 299cdf0e10cSrcweir foreach my $key ( keys %{$hashref} ) { $counter++; } 300cdf0e10cSrcweir 301cdf0e10cSrcweir return $counter; 302cdf0e10cSrcweir} 303cdf0e10cSrcweir 304cdf0e10cSrcweir############################################################ 305cdf0e10cSrcweir# Collect all last files in a cabinet file. This is 306cdf0e10cSrcweir# necessary to control, if the cabinet file was damaged 307cdf0e10cSrcweir# by calling signtool.exe. 308cdf0e10cSrcweir############################################################ 309cdf0e10cSrcweir 310cdf0e10cSrcweirsub analyze_file_file 311cdf0e10cSrcweir{ 312cdf0e10cSrcweir my ($filecontent) = @_; 313cdf0e10cSrcweir 314cdf0e10cSrcweir my %filenamehash = (); 315cdf0e10cSrcweir 316cdf0e10cSrcweir for ( my $i = 0; $i <= $#{$filecontent}; $i++ ) 317cdf0e10cSrcweir { 318cdf0e10cSrcweir if ( $i < 3 ) { next; } 319cdf0e10cSrcweir 320cdf0e10cSrcweir if ( ${$filecontent}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ ) 321cdf0e10cSrcweir { 322cdf0e10cSrcweir my $name = $1; 323cdf0e10cSrcweir my $sequence = $8; 324cdf0e10cSrcweir 325cdf0e10cSrcweir $filenamehash{$sequence} = $name; 326cdf0e10cSrcweir } 327cdf0e10cSrcweir } 328cdf0e10cSrcweir 329cdf0e10cSrcweir return ( \%filenamehash ); 330cdf0e10cSrcweir} 331cdf0e10cSrcweir 332cdf0e10cSrcweir############################################################ 333cdf0e10cSrcweir# Collect all DiskIds to the corresponding cabinet files. 334cdf0e10cSrcweir############################################################ 335cdf0e10cSrcweir 336cdf0e10cSrcweirsub analyze_media_file 337cdf0e10cSrcweir{ 338cdf0e10cSrcweir my ($filecontent) = @_; 339cdf0e10cSrcweir 340cdf0e10cSrcweir my %diskidhash = (); 341cdf0e10cSrcweir my %lastsequencehash = (); 342cdf0e10cSrcweir 343cdf0e10cSrcweir for ( my $i = 0; $i <= $#{$filecontent}; $i++ ) 344cdf0e10cSrcweir { 345cdf0e10cSrcweir if ( $i < 3 ) { next; } 346cdf0e10cSrcweir 347cdf0e10cSrcweir if ( ${$filecontent}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ ) 348cdf0e10cSrcweir { 349cdf0e10cSrcweir my $diskid = $1; 350cdf0e10cSrcweir my $lastsequence = $2; 351cdf0e10cSrcweir my $cabfile = $4; 352cdf0e10cSrcweir 353cdf0e10cSrcweir $diskidhash{$cabfile} = $diskid; 354cdf0e10cSrcweir $lastsequencehash{$cabfile} = $lastsequence; 355cdf0e10cSrcweir } 356cdf0e10cSrcweir } 357cdf0e10cSrcweir 358cdf0e10cSrcweir return ( \%diskidhash, \%lastsequencehash ); 359cdf0e10cSrcweir} 360cdf0e10cSrcweir 361cdf0e10cSrcweir######################################################## 362cdf0e10cSrcweir# Collect all DiskIds from database table "Media". 363cdf0e10cSrcweir######################################################## 364cdf0e10cSrcweir 365cdf0e10cSrcweirsub collect_diskid_from_media_table 366cdf0e10cSrcweir{ 367cdf0e10cSrcweir my ($msidatabase, $languagestring) = @_; 368cdf0e10cSrcweir 369cdf0e10cSrcweir # creating working directory 370cdf0e10cSrcweir my $workdir = installer::systemactions::create_directories("media", \$languagestring); 371cdf0e10cSrcweir installer::windows::admin::extract_tables_from_pcpfile($msidatabase, $workdir, "Media File"); 372cdf0e10cSrcweir 373cdf0e10cSrcweir # Reading tables 374cdf0e10cSrcweir my $filename = $workdir . $installer::globals::separator . "Media.idt"; 375cdf0e10cSrcweir if ( ! -f $filename ) { installer::exiter::exit_program("ERROR: Could not find required file: $filename !", "collect_diskid_from_media_table"); } 376cdf0e10cSrcweir my $filecontent = installer::files::read_file($filename); 377cdf0e10cSrcweir my ( $diskidhash, $lastsequencehash ) = analyze_media_file($filecontent); 378cdf0e10cSrcweir 379cdf0e10cSrcweir $filename = $workdir . $installer::globals::separator . "File.idt"; 380cdf0e10cSrcweir if ( ! -f $filename ) { installer::exiter::exit_program("ERROR: Could not find required file: $filename !", "collect_diskid_from_media_table"); } 381cdf0e10cSrcweir $filecontent = installer::files::read_file($filename); 382cdf0e10cSrcweir my $filenamehash = analyze_file_file($filecontent); 383cdf0e10cSrcweir 384cdf0e10cSrcweir return ( $diskidhash, $filenamehash, $lastsequencehash ); 385cdf0e10cSrcweir} 386cdf0e10cSrcweir 387cdf0e10cSrcweir######################################################## 388cdf0e10cSrcweir# Check, if this installation set contains 389cdf0e10cSrcweir# internal cabinet files included into the msi 390cdf0e10cSrcweir# database. 391cdf0e10cSrcweir######################################################## 392cdf0e10cSrcweir 393cdf0e10cSrcweirsub check_for_internal_cabfiles 394cdf0e10cSrcweir{ 395cdf0e10cSrcweir my ($cabfilehash) = @_; 396cdf0e10cSrcweir 397cdf0e10cSrcweir my $contains_internal_cabfiles = 0; 398cdf0e10cSrcweir my %allcabfileshash = (); 399cdf0e10cSrcweir 400cdf0e10cSrcweir foreach my $filename ( keys %{$cabfilehash} ) 401cdf0e10cSrcweir { 402cdf0e10cSrcweir if ( $filename =~ /^\s*\#/ ) # starting with a hash 403cdf0e10cSrcweir { 404cdf0e10cSrcweir $contains_internal_cabfiles = 1; 405cdf0e10cSrcweir # setting real filename without hash as key and name with hash as value 406cdf0e10cSrcweir my $realfilename = $filename; 407cdf0e10cSrcweir $realfilename =~ s/^\s*\#//; 408cdf0e10cSrcweir $allcabfileshash{$realfilename} = $filename; 409cdf0e10cSrcweir } 410cdf0e10cSrcweir } 411cdf0e10cSrcweir 412cdf0e10cSrcweir return ( $contains_internal_cabfiles, \%allcabfileshash ); 413cdf0e10cSrcweir} 414cdf0e10cSrcweir 415cdf0e10cSrcweir######################################################## 416cdf0e10cSrcweir# Collecting all files in an installation set. 417cdf0e10cSrcweir######################################################## 418cdf0e10cSrcweir 419cdf0e10cSrcweirsub analyze_installset_content 420cdf0e10cSrcweir{ 421cdf0e10cSrcweir my ( $installsetpath ) = @_; 422cdf0e10cSrcweir 423cdf0e10cSrcweir my @sourcefiles = (); 424cdf0e10cSrcweir my $pathstring = ""; 425cdf0e10cSrcweir installer::systemactions::read_complete_directory($installsetpath, $pathstring, \@sourcefiles); 426cdf0e10cSrcweir 427cdf0e10cSrcweir if ( ! ( $#sourcefiles > -1 )) { installer::exiter::exit_program("ERROR: No file in installation set. Path: $installsetpath !", "analyze_installset_content"); } 428cdf0e10cSrcweir 429cdf0e10cSrcweir my %allcabfileshash = (); 430cdf0e10cSrcweir my %allmsidatabaseshash = (); 431cdf0e10cSrcweir my %allfileshash = (); 432cdf0e10cSrcweir my $contains_external_cabfiles = 0; 433cdf0e10cSrcweir my $msidatabase = ""; 434cdf0e10cSrcweir my $contains_msidatabase = 0; 435cdf0e10cSrcweir 436cdf0e10cSrcweir for ( my $j = 0; $j <= $#sourcefiles; $j++ ) 437cdf0e10cSrcweir { 438cdf0e10cSrcweir if ( $sourcefiles[$j] =~ /\.cab\s*$/ ) { $allcabfileshash{$sourcefiles[$j]} = 1; } 439cdf0e10cSrcweir else 440cdf0e10cSrcweir { 441cdf0e10cSrcweir if ( $sourcefiles[$j] =~ /\.txt\s*$/ ) { next; } 442cdf0e10cSrcweir if ( $sourcefiles[$j] =~ /\.html\s*$/ ) { next; } 443cdf0e10cSrcweir if ( $sourcefiles[$j] =~ /\.ini\s*$/ ) { next; } 444cdf0e10cSrcweir if ( $sourcefiles[$j] =~ /\.bmp\s*$/ ) { next; } 445cdf0e10cSrcweir if ( $sourcefiles[$j] =~ /\.msi\s*$/ ) 446cdf0e10cSrcweir { 447cdf0e10cSrcweir if ( $msidatabase eq "" ) { $msidatabase = $sourcefiles[$j]; } 448cdf0e10cSrcweir else { installer::exiter::exit_program("ERROR: There is more than one msi database in installation set. Path: $installsetpath !", "analyze_installset_content"); } 449cdf0e10cSrcweir } 450cdf0e10cSrcweir $allfileshash{$sourcefiles[$j]} = 1; 451cdf0e10cSrcweir } 452cdf0e10cSrcweir } 453cdf0e10cSrcweir 454cdf0e10cSrcweir # Is there at least one cab file in the installation set? 455cdf0e10cSrcweir my $cabcounter = get_hash_count(\%allcabfileshash); 456cdf0e10cSrcweir if ( $cabcounter > 0 ) { $contains_external_cabfiles = 1; } 457cdf0e10cSrcweir 458cdf0e10cSrcweir # How about a cab file without a msi database? 459cdf0e10cSrcweir if (( $cabcounter > 0 ) && ( $msidatabase eq "" )) { installer::exiter::exit_program("ERROR: There is no msi database in the installation set, but an external cabinet file. Path: $installsetpath !", "collect_installset_content"); } 460cdf0e10cSrcweir 461cdf0e10cSrcweir if ( $msidatabase ne "" ) { $contains_msidatabase = 1; } 462cdf0e10cSrcweir 463cdf0e10cSrcweir return (\%allcabfileshash, \%allfileshash, $msidatabase, $contains_external_cabfiles, $contains_msidatabase, \@sourcefiles); 464cdf0e10cSrcweir} 465cdf0e10cSrcweir 466cdf0e10cSrcweir######################################################## 467cdf0e10cSrcweir# Adding content of external cabinet files into the 468cdf0e10cSrcweir# msi database 469cdf0e10cSrcweir######################################################## 470cdf0e10cSrcweir 471cdf0e10cSrcweirsub msicert_database 472cdf0e10cSrcweir{ 473cdf0e10cSrcweir my ($msidatabase, $allcabfiles, $cabfilehash, $internalcabfile) = @_; 474cdf0e10cSrcweir 475cdf0e10cSrcweir my $fullsuccess = 1; 476cdf0e10cSrcweir 477cdf0e10cSrcweir foreach my $cabfile ( keys %{$allcabfiles} ) 478cdf0e10cSrcweir { 479cdf0e10cSrcweir my $origfilesize = -s $cabfile; 480cdf0e10cSrcweir 481cdf0e10cSrcweir my $mediacabfilename = $cabfile; 482cdf0e10cSrcweir if ( $internalcabfile ) { $mediacabfilename = "\#" . $mediacabfilename; } 483cdf0e10cSrcweir if ( ! exists($cabfilehash->{$mediacabfilename}) ) { installer::exiter::exit_program("ERROR: Could not determine DiskId from media table for cabinet file \"$cabfile\" !", "msicert_database"); } 484cdf0e10cSrcweir my $diskid = $cabfilehash->{$mediacabfilename}; 485cdf0e10cSrcweir 486cdf0e10cSrcweir my $systemcall = "msicert.exe -d $msidatabase -m $diskid -c $cabfile -h"; 487cdf0e10cSrcweir $success = make_systemcall($systemcall, $systemcall); 488cdf0e10cSrcweir if ( ! $success ) { $fullsuccess = 0; } 489cdf0e10cSrcweir 490cdf0e10cSrcweir # size of cabinet file must not change 491cdf0e10cSrcweir my $finalfilesize = -s $cabfile; 492cdf0e10cSrcweir 493cdf0e10cSrcweir if ( $origfilesize != $finalfilesize ) { installer::exiter::exit_program("ERROR: msicert.exe changed size of cabinet file !", "msicert_database"); } 494cdf0e10cSrcweir } 495cdf0e10cSrcweir 496cdf0e10cSrcweir return $fullsuccess; 497cdf0e10cSrcweir} 498cdf0e10cSrcweir 499cdf0e10cSrcweir######################################################## 500cdf0e10cSrcweir# Checking if cabinet file was broken by signtool. 501cdf0e10cSrcweir######################################################## 502cdf0e10cSrcweir 503cdf0e10cSrcweirsub cabinet_cosistency_check 504cdf0e10cSrcweir{ 505cdf0e10cSrcweir my ( $onefile, $followmeinfohash, $filenamehash, $lastsequencehash, $temppath ) = @_; 506cdf0e10cSrcweir 507cdf0e10cSrcweir my $infoline = "Making consistency check of $onefile\n"; 508*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 509cdf0e10cSrcweir my $expandfile = "expand.exe"; # Has to be in the path 510cdf0e10cSrcweir 511cdf0e10cSrcweir if ( $^O =~ /cygwin/i ) 512cdf0e10cSrcweir { 513cdf0e10cSrcweir $expandfile = qx(cygpath -u "$ENV{WINDIR}"/System32/expand.exe); 514cdf0e10cSrcweir chomp $expandfile; 515cdf0e10cSrcweir } 516cdf0e10cSrcweir 517cdf0e10cSrcweir if ( $filenamehash == 0 ) 518cdf0e10cSrcweir { 519cdf0e10cSrcweir $infoline = "Warning: Stopping consistency check: Important hash of filenames is empty!\n"; 520*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 521cdf0e10cSrcweir } 522cdf0e10cSrcweir elsif ( $lastsequencehash == 0 ) 523cdf0e10cSrcweir { 524cdf0e10cSrcweir $infoline = "Warning: Stopping consistency check; Important hash of last sequences is empty!\n"; 525*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 526cdf0e10cSrcweir } 527cdf0e10cSrcweir else # both hashes are available 528cdf0e10cSrcweir { 529cdf0e10cSrcweir # $onefile contains only the name of the cabinet file without path 530cdf0e10cSrcweir my $sequence = $lastsequencehash->{$onefile}; 531cdf0e10cSrcweir my $lastfile = $filenamehash->{$sequence}; 532cdf0e10cSrcweir $infoline = "Check of $onefile: Sequence: $sequence is file: $lastfile\n"; 533*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 534cdf0e10cSrcweir 535cdf0e10cSrcweir # Therefore the file $lastfile need to be binary compared. 536cdf0e10cSrcweir # It has to be expanded from the cabinet file 537cdf0e10cSrcweir # of the original installation set and from the 538cdf0e10cSrcweir # newly signed cabinet file. 539cdf0e10cSrcweir 540cdf0e10cSrcweir # How about cabinet files extracted from msi database? 541cdf0e10cSrcweir my $finalinstalldir = $followmeinfohash->{'finalinstalldir'}; 542cdf0e10cSrcweir 543cdf0e10cSrcweir $finalinstalldir =~ s/\\\s*$//; 544cdf0e10cSrcweir $finalinstalldir =~ s/\/\s*$//; 545cdf0e10cSrcweir my $sourcecabfile = $finalinstalldir . $installer::globals::separator . $onefile; 546cdf0e10cSrcweir my $currentpath = cwd(); 547cdf0e10cSrcweir my $destcabfile = $currentpath . $installer::globals::separator . $onefile; 548cdf0e10cSrcweir # my $destcabfile = $onefile; 549cdf0e10cSrcweir 550cdf0e10cSrcweir if ( $^O =~ /cygwin/i ) 551cdf0e10cSrcweir { 552cdf0e10cSrcweir chomp( $destcabfile = qx{cygpath -w "$destcabfile"} ); 553cdf0e10cSrcweir $destcabfile =~ s/\\/\//g; 554cdf0e10cSrcweir } 555cdf0e10cSrcweir 556cdf0e10cSrcweir if ( ! -f $sourcecabfile ) 557cdf0e10cSrcweir { 558cdf0e10cSrcweir $infoline = "WARNING: Check of cab file cannot happen, because source cabinet file was not found: $sourcecabfile\n"; 559*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 560cdf0e10cSrcweir } 561cdf0e10cSrcweir elsif ( ! -f $destcabfile ) 562cdf0e10cSrcweir { 563cdf0e10cSrcweir $infoline = "WARNING: Check of cab file cannot happen, because destination cabinet file was not found: $sourcecabfile\n"; 564*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 565cdf0e10cSrcweir } 566cdf0e10cSrcweir else # everything is okay for the check 567cdf0e10cSrcweir { 568cdf0e10cSrcweir my $diffpath = get_diff_path($temppath); 569cdf0e10cSrcweir 570cdf0e10cSrcweir my $origdiffpath = $diffpath . $installer::globals::separator . "orig"; 571cdf0e10cSrcweir my $newdiffpath = $diffpath . $installer::globals::separator . "new"; 572cdf0e10cSrcweir 573cdf0e10cSrcweir if ( ! -d $origdiffpath ) { mkdir($origdiffpath); } 574cdf0e10cSrcweir if ( ! -d $newdiffpath ) { mkdir($newdiffpath); } 575cdf0e10cSrcweir 576cdf0e10cSrcweir my $systemcall = "$expandfile $sourcecabfile $origdiffpath -f:$lastfile "; 577cdf0e10cSrcweir $infoline = $systemcall . "\n"; 578*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 579cdf0e10cSrcweir 580cdf0e10cSrcweir my $success = make_systemcall($systemcall, $systemcall); 581cdf0e10cSrcweir if ( ! $success ) { installer::exiter::exit_program("ERROR: Could not successfully execute: $systemcall !", "cabinet_cosistency_check"); } 582cdf0e10cSrcweir 583cdf0e10cSrcweir $systemcall = "$expandfile $destcabfile $newdiffpath -f:$lastfile "; 584cdf0e10cSrcweir $infoline = $systemcall . "\n"; 585*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 586cdf0e10cSrcweir 587cdf0e10cSrcweir $success = make_systemcall($systemcall, $systemcall); 588cdf0e10cSrcweir if ( ! $success ) { installer::exiter::exit_program("ERROR: Could not successfully execute: $systemcall !", "cabinet_cosistency_check"); } 589cdf0e10cSrcweir 590cdf0e10cSrcweir # and finally the two files can be diffed. 591cdf0e10cSrcweir my $origfile = $origdiffpath . $installer::globals::separator . $lastfile; 592cdf0e10cSrcweir my $newfile = $newdiffpath . $installer::globals::separator . $lastfile; 593cdf0e10cSrcweir 594cdf0e10cSrcweir if ( ! -f $origfile ) { installer::exiter::exit_program("ERROR: Unpacked original file not found: $origfile !", "cabinet_cosistency_check"); } 595cdf0e10cSrcweir if ( ! -f $newfile ) { installer::exiter::exit_program("ERROR: Unpacked new file not found: $newfile !", "cabinet_cosistency_check"); } 596cdf0e10cSrcweir 597cdf0e10cSrcweir my $origsize = -s $origfile; 598cdf0e10cSrcweir my $newsize = -s $newfile; 599cdf0e10cSrcweir 600cdf0e10cSrcweir if ( $origsize != $newsize ) # This shows an error! 601cdf0e10cSrcweir { 602cdf0e10cSrcweir $infoline = "ERROR: Different filesize after signtool.exe was used. Original: $origsize Bytes, new: $newsize. File: $lastfile\n"; 603*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 604cdf0e10cSrcweir installer::exiter::exit_program("ERROR: The cabinet file $destcabfile is broken after signtool.exe signed this file !", "cabinet_cosistency_check"); 605cdf0e10cSrcweir } 606cdf0e10cSrcweir else 607cdf0e10cSrcweir { 608cdf0e10cSrcweir $infoline = "Same size of last file in cabinet file after usage of signtool.exe: $newsize (File: $lastfile)\n"; 609*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 610cdf0e10cSrcweir 611cdf0e10cSrcweir # Also making a binary diff? 612cdf0e10cSrcweir 613cdf0e10cSrcweir my $difffile = "diff.exe"; # has to be in the path 614cdf0e10cSrcweir # $systemcall = "$difffile $sourcecabfile $destcabfile"; # Test for differences 615cdf0e10cSrcweir $systemcall = "$difffile $origfile $newfile"; 616cdf0e10cSrcweir $infoline = $systemcall . "\n"; 617cdf0e10cSrcweir $returnvalue = make_systemcall($systemcall, $systemcall); 618cdf0e10cSrcweir 619cdf0e10cSrcweir my $success = $?; 620cdf0e10cSrcweir 621cdf0e10cSrcweir if ( $success == 0 ) 622cdf0e10cSrcweir { 623cdf0e10cSrcweir $infoline = "Last files are identical after signing cabinet file (File: $lastfile)\n"; 624*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 625cdf0e10cSrcweir } 626cdf0e10cSrcweir elsif ( $success == 1 ) 627cdf0e10cSrcweir { 628cdf0e10cSrcweir $infoline = "ERROR: Last files are different after signing cabinet file (File: $lastfile)\n"; 629*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 630cdf0e10cSrcweir installer::exiter::exit_program("ERROR: Last files are different after signing cabinet file (File: $lastfile)!", "cabinet_cosistency_check"); 631cdf0e10cSrcweir } 632cdf0e10cSrcweir else 633cdf0e10cSrcweir { 634cdf0e10cSrcweir $infoline = "ERROR: Problem occured calling diff.exe (File: $lastfile)\n"; 635*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 636cdf0e10cSrcweir installer::exiter::exit_program("ERROR: Problem occured calling diff.exe (File: $lastfile) !", "cabinet_cosistency_check"); 637cdf0e10cSrcweir } 638cdf0e10cSrcweir } 639cdf0e10cSrcweir } 640cdf0e10cSrcweir } 641cdf0e10cSrcweir 642cdf0e10cSrcweir} 643cdf0e10cSrcweir 644cdf0e10cSrcweir######################################################## 645cdf0e10cSrcweir# Signing a list of files 646cdf0e10cSrcweir######################################################## 647cdf0e10cSrcweir 648cdf0e10cSrcweirsub sign_files 649cdf0e10cSrcweir{ 650cdf0e10cSrcweir my ( $followmeinfohash, $allfiles, $pw, $cabinternal, $filenamehash, $lastsequencehash, $temppath ) = @_; 651cdf0e10cSrcweir 652cdf0e10cSrcweir my $infoline = ""; 653cdf0e10cSrcweir my $fullsuccess = 1; 654cdf0e10cSrcweir my $maxcounter = 3; 655cdf0e10cSrcweir 656cdf0e10cSrcweir my $productname = ""; 657cdf0e10cSrcweir if ( $followmeinfohash->{'allvariableshash'}->{'PRODUCTNAME'} ) { $productname = "/d " . "\"$followmeinfohash->{'allvariableshash'}->{'PRODUCTNAME'}\""; } 658d2b96cdeSHerbert Dürr my $url = "/du " . "\"http://www.openoffice.org\""; 659cdf0e10cSrcweir my $timestampurl = "http://timestamp.verisign.com/scripts/timestamp.dll"; 660cdf0e10cSrcweir 661cdf0e10cSrcweir my $pfxfilepath = $installer::globals::pfxfile; 662cdf0e10cSrcweir 663cdf0e10cSrcweir if( $^O =~ /cygwin/i ) 664cdf0e10cSrcweir { 665cdf0e10cSrcweir $pfxfilepath = qx{cygpath -w "$pfxfilepath"}; 666cdf0e10cSrcweir $pfxfilepath =~ s/\\/\\\\/g; 667cdf0e10cSrcweir $pfxfilepath =~ s/\s*$//g; 668cdf0e10cSrcweir } 669cdf0e10cSrcweir 670cdf0e10cSrcweir foreach my $onefile ( reverse sort keys %{$allfiles} ) 671cdf0e10cSrcweir { 672cdf0e10cSrcweir if ( already_certified($onefile) ) 673cdf0e10cSrcweir { 674cdf0e10cSrcweir $infoline = "Already certified: Skipping file $onefile\n"; 675*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 676cdf0e10cSrcweir next; 677cdf0e10cSrcweir } 678cdf0e10cSrcweir 679cdf0e10cSrcweir my $counter = 1; 680cdf0e10cSrcweir my $success = 0; 681cdf0e10cSrcweir 682cdf0e10cSrcweir while (( $counter <= $maxcounter ) && ( ! $success )) 683cdf0e10cSrcweir { 684*b274bc22SAndre Fischer if ( $counter > 1 ) 685*b274bc22SAndre Fischer { 686*b274bc22SAndre Fischer $installer::logger::Info->printf("\n"); 687*b274bc22SAndre Fischer $installer::logger::Info->printf("\n"); 688*b274bc22SAndre Fischer $installer::logger::Info->printf("... repeating file %s ...\n", $onefile); 689*b274bc22SAndre Fischer } 690*b274bc22SAndre Fischer if ( $cabinternal ) 691*b274bc22SAndre Fischer { 692*b274bc22SAndre Fischer $installer::logger::Info->printf(" Signing: %s\n", $onefile); 693*b274bc22SAndre Fischer } 694cdf0e10cSrcweir my $systemcall = "signtool.exe sign /f \"$pfxfilepath\" /p $pw $productname $url /t \"$timestampurl\" \"$onefile\""; 695cdf0e10cSrcweir my $displaysystemcall = "signtool.exe sign /f \"$pfxfilepath\" /p ***** $productname $url /t \"$timestampurl\" \"$onefile\""; 696cdf0e10cSrcweir $success = make_systemcall_with_warning($systemcall, $displaysystemcall); 697cdf0e10cSrcweir $counter++; 698cdf0e10cSrcweir } 699cdf0e10cSrcweir 700cdf0e10cSrcweir # Special check for cabinet files, that sometimes get damaged by signtool.exe 701cdf0e10cSrcweir if (( $success ) && ( $onefile =~ /\.cab\s*$/ ) && ( ! $cabinternal )) 702cdf0e10cSrcweir { 703cdf0e10cSrcweir cabinet_cosistency_check($onefile, $followmeinfohash, $filenamehash, $lastsequencehash, $temppath); 704cdf0e10cSrcweir } 705cdf0e10cSrcweir 706cdf0e10cSrcweir if ( ! $success ) 707cdf0e10cSrcweir { 708cdf0e10cSrcweir $fullsuccess = 0; 709cdf0e10cSrcweir installer::exiter::exit_program("ERROR: Could not sign file: $onefile!", "sign_files"); 710cdf0e10cSrcweir } 711cdf0e10cSrcweir } 712cdf0e10cSrcweir 713cdf0e10cSrcweir return $fullsuccess; 714cdf0e10cSrcweir} 715cdf0e10cSrcweir 716cdf0e10cSrcweir########################################################################## 717cdf0e10cSrcweir# Lines in ddf files must not contain more than 256 characters 718cdf0e10cSrcweir########################################################################## 719cdf0e10cSrcweir 720cdf0e10cSrcweirsub check_ddf_file 721cdf0e10cSrcweir{ 722cdf0e10cSrcweir my ( $ddffile, $ddffilename ) = @_; 723cdf0e10cSrcweir 724cdf0e10cSrcweir my $maxlength = 0; 725cdf0e10cSrcweir my $maxline = 0; 726cdf0e10cSrcweir my $linelength = 0; 727cdf0e10cSrcweir my $linenumber = 0; 728cdf0e10cSrcweir 729cdf0e10cSrcweir for ( my $i = 0; $i <= $#{$ddffile}; $i++ ) 730cdf0e10cSrcweir { 731cdf0e10cSrcweir my $oneline = ${$ddffile}[$i]; 732cdf0e10cSrcweir 733cdf0e10cSrcweir $linelength = length($oneline); 734cdf0e10cSrcweir $linenumber = $i + 1; 735cdf0e10cSrcweir 736cdf0e10cSrcweir if ( $linelength > 256 ) 737cdf0e10cSrcweir { 738cdf0e10cSrcweir installer::exiter::exit_program("ERROR \"$ddffilename\" line $linenumber: Lines in ddf files must not contain more than 256 characters!", "check_ddf_file"); 739cdf0e10cSrcweir } 740cdf0e10cSrcweir 741cdf0e10cSrcweir if ( $linelength > $maxlength ) 742cdf0e10cSrcweir { 743cdf0e10cSrcweir $maxlength = $linelength; 744cdf0e10cSrcweir $maxline = $linenumber; 745cdf0e10cSrcweir } 746cdf0e10cSrcweir } 747cdf0e10cSrcweir 748cdf0e10cSrcweir my $infoline = "Check of ddf file \"$ddffilename\": Maximum length \"$maxlength\" in line \"$maxline\" (allowed line length: 256 characters)\n"; 749*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 750cdf0e10cSrcweir} 751cdf0e10cSrcweir 752cdf0e10cSrcweir################################################################# 753cdf0e10cSrcweir# Setting the path, where the cab files are unpacked. 754cdf0e10cSrcweir################################################################# 755cdf0e10cSrcweir 756cdf0e10cSrcweirsub get_cab_path 757cdf0e10cSrcweir{ 758cdf0e10cSrcweir my ($temppath) = @_; 759cdf0e10cSrcweir 760cdf0e10cSrcweir my $cabpath = "cabs_" . $$; 761cdf0e10cSrcweir $cabpath = $temppath . $installer::globals::separator . $cabpath; 762cdf0e10cSrcweir if ( ! -d $cabpath ) { installer::systemactions::create_directory($cabpath); } 763cdf0e10cSrcweir 764cdf0e10cSrcweir return $cabpath; 765cdf0e10cSrcweir} 766cdf0e10cSrcweir 767cdf0e10cSrcweir################################################################# 768cdf0e10cSrcweir# Setting the path, where the diff can happen. 769cdf0e10cSrcweir################################################################# 770cdf0e10cSrcweir 771cdf0e10cSrcweirsub get_diff_path 772cdf0e10cSrcweir{ 773cdf0e10cSrcweir my ($temppath) = @_; 774cdf0e10cSrcweir 775cdf0e10cSrcweir my $diffpath = "diff_" . $$; 776cdf0e10cSrcweir $diffpath = $temppath . $installer::globals::separator . $diffpath; 777cdf0e10cSrcweir if ( ! -d $diffpath ) { installer::systemactions::create_directory($diffpath); } 778cdf0e10cSrcweir 779cdf0e10cSrcweir return $diffpath; 780cdf0e10cSrcweir} 781cdf0e10cSrcweir 782cdf0e10cSrcweir################################################################# 783cdf0e10cSrcweir# Exclude all cab files from the msi database. 784cdf0e10cSrcweir################################################################# 785cdf0e10cSrcweir 786cdf0e10cSrcweirsub extract_cabs_from_database 787cdf0e10cSrcweir{ 788cdf0e10cSrcweir my ($msidatabase, $allcabfiles) = @_; 789cdf0e10cSrcweir 790cdf0e10cSrcweir installer::logger::include_header_into_logfile("Extracting cabs from msi database"); 791cdf0e10cSrcweir 792cdf0e10cSrcweir my $infoline = ""; 793cdf0e10cSrcweir my $fullsuccess = 1; 794cdf0e10cSrcweir my $msidb = "msidb.exe"; # Has to be in the path 795cdf0e10cSrcweir 796cdf0e10cSrcweir # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) 797cdf0e10cSrcweir $msidatabase =~ s/\//\\\\/g; 798cdf0e10cSrcweir 799cdf0e10cSrcweir foreach my $onefile ( keys %{$allcabfiles} ) 800cdf0e10cSrcweir { 801cdf0e10cSrcweir my $systemcall = $msidb . " -d " . $msidatabase . " -x " . $onefile; 802cdf0e10cSrcweir my $success = make_systemcall($systemcall, $systemcall); 803cdf0e10cSrcweir if ( ! $success ) { $fullsuccess = 0; } 804cdf0e10cSrcweir 805cdf0e10cSrcweir # and removing the stream from the database 806cdf0e10cSrcweir $systemcall = $msidb . " -d " . $msidatabase . " -k " . $onefile; 807cdf0e10cSrcweir $success = make_systemcall($systemcall, $systemcall); 808cdf0e10cSrcweir if ( ! $success ) { $fullsuccess = 0; } 809cdf0e10cSrcweir } 810cdf0e10cSrcweir 811cdf0e10cSrcweir return $fullsuccess; 812cdf0e10cSrcweir} 813cdf0e10cSrcweir 814cdf0e10cSrcweir################################################################# 815cdf0e10cSrcweir# Include cab files into the msi database. 816cdf0e10cSrcweir################################################################# 817cdf0e10cSrcweir 818cdf0e10cSrcweirsub include_cabs_into_database 819cdf0e10cSrcweir{ 820cdf0e10cSrcweir my ($msidatabase, $allcabfiles) = @_; 821cdf0e10cSrcweir 822cdf0e10cSrcweir installer::logger::include_header_into_logfile("Including cabs into msi database"); 823cdf0e10cSrcweir 824cdf0e10cSrcweir my $infoline = ""; 825cdf0e10cSrcweir my $fullsuccess = 1; 826cdf0e10cSrcweir my $msidb = "msidb.exe"; # Has to be in the path 827cdf0e10cSrcweir 828cdf0e10cSrcweir # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) 829cdf0e10cSrcweir $msidatabase =~ s/\//\\\\/g; 830cdf0e10cSrcweir 831cdf0e10cSrcweir foreach my $onefile ( keys %{$allcabfiles} ) 832cdf0e10cSrcweir { 833cdf0e10cSrcweir my $systemcall = $msidb . " -d " . $msidatabase . " -a " . $onefile; 834cdf0e10cSrcweir my $success = make_systemcall($systemcall, $systemcall); 835cdf0e10cSrcweir if ( ! $success ) { $fullsuccess = 0; } 836cdf0e10cSrcweir } 837cdf0e10cSrcweir 838cdf0e10cSrcweir return $fullsuccess; 839cdf0e10cSrcweir} 840cdf0e10cSrcweir 841cdf0e10cSrcweir######################################################## 842cdf0e10cSrcweir# Reading the order of the files inside the 843cdf0e10cSrcweir# cabinet files. 844cdf0e10cSrcweir######################################################## 845cdf0e10cSrcweir 846cdf0e10cSrcweirsub read_cab_file 847cdf0e10cSrcweir{ 848cdf0e10cSrcweir my ($cabfilename) = @_; 849cdf0e10cSrcweir 850*b274bc22SAndre Fischer $installer::logger::Info->printf("\n"); 851*b274bc22SAndre Fischer $installer::logger::Info->printf("... reading cabinet file %s ...\n", $cabfilename); 852cdf0e10cSrcweir my $infoline = "Reading cabinet file $cabfilename\n"; 853*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 854cdf0e10cSrcweir 855cdf0e10cSrcweir my $systemcall = "cabarc.exe" . " L " . $cabfilename; 856cdf0e10cSrcweir push(@logfile, "$systemcall\n"); 857cdf0e10cSrcweir 858cdf0e10cSrcweir my ($success, $fileorder) = execute_open_system_call($systemcall); 859cdf0e10cSrcweir 860cdf0e10cSrcweir my @allfiles = (); 861cdf0e10cSrcweir 862cdf0e10cSrcweir for ( my $i = 0; $i <= $#{$fileorder}; $i++ ) 863cdf0e10cSrcweir { 864cdf0e10cSrcweir my $line = ${$fileorder}[$i]; 865cdf0e10cSrcweir if ( $line =~ /^\s*(.*?)\s+\d+\s+\d+\/\d+\/\d+\s+\d+\:\d+\:\d+\s+[\w-]+\s*$/ ) 866cdf0e10cSrcweir { 867cdf0e10cSrcweir my $filename = $1; 868cdf0e10cSrcweir push(@allfiles, $filename); 869cdf0e10cSrcweir } 870cdf0e10cSrcweir } 871cdf0e10cSrcweir 872cdf0e10cSrcweir return \@allfiles; 873cdf0e10cSrcweir} 874cdf0e10cSrcweir 875cdf0e10cSrcweir######################################################## 876cdf0e10cSrcweir# Unpacking a cabinet file. 877cdf0e10cSrcweir######################################################## 878cdf0e10cSrcweir 879cdf0e10cSrcweirsub unpack_cab_file 880cdf0e10cSrcweir{ 881cdf0e10cSrcweir my ($cabfilename, $temppath) = @_; 882cdf0e10cSrcweir 883*b274bc22SAndre Fischer $installer::logger::Info->printf("\n"); 884*b274bc22SAndre Fischer $installer::logger::Info->printf("... unpacking cabinet file %s ...\n", $cabfilename); 885cdf0e10cSrcweir my $infoline = "Unpacking cabinet file $cabfilename\n"; 886*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 887cdf0e10cSrcweir 888cdf0e10cSrcweir my $dirname = $cabfilename; 889cdf0e10cSrcweir $dirname =~ s/\.cab\s*$//; 890cdf0e10cSrcweir my $workingpath = $temppath . $installer::globals::separator . "unpack_". $dirname . "_" . $$; 891cdf0e10cSrcweir if ( ! -d $workingpath ) { installer::systemactions::create_directory($workingpath); } 892cdf0e10cSrcweir 893cdf0e10cSrcweir # changing into unpack directory 894cdf0e10cSrcweir my $from = cwd(); 895cdf0e10cSrcweir chdir($workingpath); 896cdf0e10cSrcweir 897cdf0e10cSrcweir my $fullcabfilename = $from . $installer::globals::separator . $cabfilename; 898cdf0e10cSrcweir 899cdf0e10cSrcweir if( $^O =~ /cygwin/i ) 900cdf0e10cSrcweir { 901cdf0e10cSrcweir $fullcabfilename = qx{cygpath -w "$fullcabfilename"}; 902cdf0e10cSrcweir $fullcabfilename =~ s/\\/\\\\/g; 903cdf0e10cSrcweir $fullcabfilename =~ s/\s*$//g; 904cdf0e10cSrcweir } 905cdf0e10cSrcweir 906cdf0e10cSrcweir my $systemcall = "cabarc.exe" . " -p X " . $fullcabfilename; 907cdf0e10cSrcweir $success = make_systemcall($systemcall, $systemcall); 908cdf0e10cSrcweir if ( ! $success ) { installer::exiter::exit_program("ERROR: Could not unpack cabinet file: $fullcabfilename!", "unpack_cab_file"); } 909cdf0e10cSrcweir 910cdf0e10cSrcweir # returning to directory 911cdf0e10cSrcweir chdir($from); 912cdf0e10cSrcweir 913cdf0e10cSrcweir return $workingpath; 914cdf0e10cSrcweir} 915cdf0e10cSrcweir 916cdf0e10cSrcweir######################################################## 917cdf0e10cSrcweir# Returning the header of a ddf file. 918cdf0e10cSrcweir######################################################## 919cdf0e10cSrcweir 920cdf0e10cSrcweirsub get_ddf_file_header 921cdf0e10cSrcweir{ 922cdf0e10cSrcweir my ($ddffileref, $cabinetfile, $installdir) = @_; 923cdf0e10cSrcweir 924cdf0e10cSrcweir my $oneline; 925cdf0e10cSrcweir my $compressionlevel = 2; 926cdf0e10cSrcweir 927cdf0e10cSrcweir if( $^O =~ /cygwin/i ) 928cdf0e10cSrcweir { 929cdf0e10cSrcweir $installdir = qx{cygpath -w "$installdir"}; 930cdf0e10cSrcweir $installdir =~ s/\s*$//g; 931cdf0e10cSrcweir } 932cdf0e10cSrcweir 933cdf0e10cSrcweir $oneline = ".Set CabinetName1=" . $cabinetfile . "\n"; 934cdf0e10cSrcweir push(@{$ddffileref} ,$oneline); 935cdf0e10cSrcweir $oneline = ".Set ReservePerCabinetSize=128\n"; # This reserves space for a digital signature. 936cdf0e10cSrcweir push(@{$ddffileref} ,$oneline); 937cdf0e10cSrcweir $oneline = ".Set MaxDiskSize=2147483648\n"; # This allows the .cab file to get a size of 2 GB. 938cdf0e10cSrcweir push(@{$ddffileref} ,$oneline); 939cdf0e10cSrcweir $oneline = ".Set CompressionType=LZX\n"; 940cdf0e10cSrcweir push(@{$ddffileref} ,$oneline); 941cdf0e10cSrcweir $oneline = ".Set Compress=ON\n"; 942cdf0e10cSrcweir push(@{$ddffileref} ,$oneline); 943cdf0e10cSrcweir $oneline = ".Set CompressionLevel=$compressionlevel\n"; 944cdf0e10cSrcweir push(@{$ddffileref} ,$oneline); 945cdf0e10cSrcweir $oneline = ".Set Cabinet=ON\n"; 946cdf0e10cSrcweir push(@{$ddffileref} ,$oneline); 947cdf0e10cSrcweir $oneline = ".Set DiskDirectoryTemplate=" . $installdir . "\n"; 948cdf0e10cSrcweir push(@{$ddffileref} ,$oneline); 949cdf0e10cSrcweir} 950cdf0e10cSrcweir 951cdf0e10cSrcweir######################################################## 952cdf0e10cSrcweir# Writing content into ddf file. 953cdf0e10cSrcweir######################################################## 954cdf0e10cSrcweir 955cdf0e10cSrcweirsub put_all_files_into_ddffile 956cdf0e10cSrcweir{ 957cdf0e10cSrcweir my ($ddffile, $allfiles, $workingpath) = @_; 958cdf0e10cSrcweir 959cdf0e10cSrcweir $workingpath =~ s/\//\\/g; 960cdf0e10cSrcweir 961cdf0e10cSrcweir for ( my $i = 0; $i <= $#{$allfiles}; $i++ ) 962cdf0e10cSrcweir { 963cdf0e10cSrcweir my $filename = ${$allfiles}[$i]; 964cdf0e10cSrcweir if( $^O =~ /cygwin/i ) { $filename =~ s/\//\\/g; } # Backslash for Cygwin! 965cdf0e10cSrcweir if ( ! -f $filename ) { installer::exiter::exit_program("ERROR: Could not find file: $filename!", "put_all_files_into_ddffile"); } 966cdf0e10cSrcweir my $infoline = "\"" . $filename . "\"" . " " . ${$allfiles}[$i] . "\n"; 967cdf0e10cSrcweir push( @{$ddffile}, $infoline); 968cdf0e10cSrcweir } 969cdf0e10cSrcweir} 970cdf0e10cSrcweir 971cdf0e10cSrcweir######################################################## 972cdf0e10cSrcweir# Packing a cabinet file. 973cdf0e10cSrcweir######################################################## 974cdf0e10cSrcweir 975cdf0e10cSrcweirsub do_pack_cab_file 976cdf0e10cSrcweir{ 977cdf0e10cSrcweir my ($cabfilename, $allfiles, $workingpath, $temppath) = @_; 978cdf0e10cSrcweir 979*b274bc22SAndre Fischer $installer::logger::Info->print("\n"); 980*b274bc22SAndre Fischer $installer::logger::Info->printf("... packing cabinet file %s ...\n", $cabfilename); 981cdf0e10cSrcweir my $infoline = "Packing cabinet file $cabfilename\n"; 982*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 983cdf0e10cSrcweir 984cdf0e10cSrcweir if ( -f $cabfilename ) { unlink($cabfilename); } # removing cab file 985cdf0e10cSrcweir if ( -f $cabfilename ) { installer::exiter::exit_program("ERROR: Failed to remove file: $cabfilename!", "do_pack_cab_file"); } 986cdf0e10cSrcweir 987cdf0e10cSrcweir # generate ddf file for makecab.exe 988cdf0e10cSrcweir my @ddffile = (); 989cdf0e10cSrcweir 990cdf0e10cSrcweir my $dirname = $cabfilename; 991cdf0e10cSrcweir $dirname =~ s/\.cab\s*$//; 992cdf0e10cSrcweir my $ddfpath = $temppath . $installer::globals::separator . "ddf_". $dirname . "_" . $$; 993cdf0e10cSrcweir 994cdf0e10cSrcweir my $ddffilename = $cabfilename; 995cdf0e10cSrcweir $ddffilename =~ s/.cab/.ddf/; 996cdf0e10cSrcweir $ddffilename = $ddfpath . $installer::globals::separator . $ddffilename; 997cdf0e10cSrcweir 998cdf0e10cSrcweir if ( ! -d $ddfpath ) { installer::systemactions::create_directory($ddfpath); } 999cdf0e10cSrcweir 1000cdf0e10cSrcweir my $from = cwd(); 1001cdf0e10cSrcweir 1002cdf0e10cSrcweir chdir($workingpath); # changing into the directory with the unpacked files 1003cdf0e10cSrcweir 1004cdf0e10cSrcweir get_ddf_file_header(\@ddffile, $cabfilename, $from); 1005cdf0e10cSrcweir put_all_files_into_ddffile(\@ddffile, $allfiles, $workingpath); 1006cdf0e10cSrcweir # lines in ddf files must not be longer than 256 characters 1007cdf0e10cSrcweir check_ddf_file(\@ddffile, $ddffilename); 1008cdf0e10cSrcweir 1009cdf0e10cSrcweir installer::files::save_file($ddffilename, \@ddffile); 1010cdf0e10cSrcweir 1011cdf0e10cSrcweir if( $^O =~ /cygwin/i ) 1012cdf0e10cSrcweir { 1013cdf0e10cSrcweir $ddffilename = qx{cygpath -w "$ddffilename"}; 1014cdf0e10cSrcweir $ddffilename =~ s/\\/\\\\/g; 1015cdf0e10cSrcweir $ddffilename =~ s/\s*$//g; 1016cdf0e10cSrcweir } 1017cdf0e10cSrcweir 1018cdf0e10cSrcweir my $systemcall = "makecab.exe /V1 /F " . $ddffilename; 1019cdf0e10cSrcweir my $success = make_systemcall($systemcall, $systemcall); 1020cdf0e10cSrcweir if ( ! $success ) { installer::exiter::exit_program("ERROR: Could not pack cabinet file!", "do_pack_cab_file"); } 1021cdf0e10cSrcweir 1022cdf0e10cSrcweir chdir($from); 1023cdf0e10cSrcweir 1024cdf0e10cSrcweir return ($success); 1025cdf0e10cSrcweir} 1026cdf0e10cSrcweir 1027cdf0e10cSrcweir######################################################## 1028cdf0e10cSrcweir# Extraction the file extension from a file 1029cdf0e10cSrcweir######################################################## 1030cdf0e10cSrcweir 1031cdf0e10cSrcweirsub get_extension 1032cdf0e10cSrcweir{ 1033cdf0e10cSrcweir my ( $file ) = @_; 1034cdf0e10cSrcweir 1035cdf0e10cSrcweir my $extension = ""; 1036cdf0e10cSrcweir 1037cdf0e10cSrcweir if ( $file =~ /^\s*(.*)\.(\w+?)\s*$/ ) { $extension = $2; } 1038cdf0e10cSrcweir 1039cdf0e10cSrcweir return $extension; 1040cdf0e10cSrcweir} 1041cdf0e10cSrcweir 1042cdf0e10cSrcweir######################################################## 1043cdf0e10cSrcweir# Checking, if a file already contains a certificate. 1044cdf0e10cSrcweir# This must not be overwritten. 1045cdf0e10cSrcweir######################################################## 1046cdf0e10cSrcweir 1047cdf0e10cSrcweirsub already_certified 1048cdf0e10cSrcweir{ 1049cdf0e10cSrcweir my ( $filename ) = @_; 1050cdf0e10cSrcweir 1051cdf0e10cSrcweir my $success = 1; 1052cdf0e10cSrcweir my $is_certified = 0; 1053cdf0e10cSrcweir 1054cdf0e10cSrcweir my $systemcall = "signtool.exe verify /q /pa \"$filename\""; 1055cdf0e10cSrcweir my $returnvalue = system($systemcall); 1056cdf0e10cSrcweir 1057cdf0e10cSrcweir if ( $returnvalue ) { $success = 0; } 1058cdf0e10cSrcweir 1059cdf0e10cSrcweir # my $success = make_systemcall($systemcall, $systemcall); 1060cdf0e10cSrcweir 1061cdf0e10cSrcweir if ( $success ) 1062cdf0e10cSrcweir { 1063cdf0e10cSrcweir $is_certified = 1; 1064*b274bc22SAndre Fischer $installer::logger::Info->printf("... already certified -> skipping %s ...\n", $filename); 1065cdf0e10cSrcweir } 1066cdf0e10cSrcweir 1067cdf0e10cSrcweir return $is_certified; 1068cdf0e10cSrcweir} 1069cdf0e10cSrcweir 1070cdf0e10cSrcweir######################################################## 1071cdf0e10cSrcweir# Signing the files, that are included into 1072cdf0e10cSrcweir# cabinet files. 1073cdf0e10cSrcweir######################################################## 1074cdf0e10cSrcweir 1075cdf0e10cSrcweirsub sign_files_in_cabinet_files 1076cdf0e10cSrcweir{ 1077cdf0e10cSrcweir my ( $followmeinfohash, $allcabfiles, $pw, $temppath ) = @_; 1078cdf0e10cSrcweir 1079cdf0e10cSrcweir my $complete_success = 1; 1080cdf0e10cSrcweir my $from = cwd(); 1081cdf0e10cSrcweir 1082cdf0e10cSrcweir foreach my $cabfilename ( keys %{$allcabfiles} ) 1083cdf0e10cSrcweir { 1084cdf0e10cSrcweir my $success = 1; 1085cdf0e10cSrcweir 1086cdf0e10cSrcweir # saving order of files in cab file 1087cdf0e10cSrcweir my $fileorder = read_cab_file($cabfilename); 1088cdf0e10cSrcweir 1089cdf0e10cSrcweir # unpack into $working path 1090cdf0e10cSrcweir my $workingpath = unpack_cab_file($cabfilename, $temppath); 1091cdf0e10cSrcweir 1092cdf0e10cSrcweir chdir($workingpath); 1093cdf0e10cSrcweir 1094cdf0e10cSrcweir # sign files 1095cdf0e10cSrcweir my %allfileshash = (); 1096cdf0e10cSrcweir foreach my $onefile ( @{$fileorder} ) 1097cdf0e10cSrcweir { 1098cdf0e10cSrcweir my $extension = get_extension($onefile); 1099cdf0e10cSrcweir if ( exists( $installer::globals::sign_extensions{$extension} ) ) 1100cdf0e10cSrcweir { 1101cdf0e10cSrcweir $allfileshash{$onefile} = 1; 1102cdf0e10cSrcweir } 1103cdf0e10cSrcweir } 1104cdf0e10cSrcweir $success = sign_files($followmeinfohash, \%allfileshash, $pw, 1, 0, 0, $temppath); 1105cdf0e10cSrcweir if ( ! $success ) { $complete_success = 0; } 1106cdf0e10cSrcweir 1107cdf0e10cSrcweir chdir($from); 1108cdf0e10cSrcweir 1109cdf0e10cSrcweir # pack into new directory 1110cdf0e10cSrcweir do_pack_cab_file($cabfilename, $fileorder, $workingpath, $temppath); 1111cdf0e10cSrcweir } 1112cdf0e10cSrcweir 1113cdf0e10cSrcweir return $complete_success; 1114cdf0e10cSrcweir} 1115cdf0e10cSrcweir 1116cdf0e10cSrcweir######################################################## 1117cdf0e10cSrcweir# Comparing the content of two directories. 1118cdf0e10cSrcweir# Only filesize is compared. 1119cdf0e10cSrcweir######################################################## 1120cdf0e10cSrcweir 1121cdf0e10cSrcweirsub compare_directories 1122cdf0e10cSrcweir{ 1123cdf0e10cSrcweir my ( $dir1, $dir2, $files ) = @_; 1124cdf0e10cSrcweir 1125cdf0e10cSrcweir $dir1 =~ s/\\\s*//; 1126cdf0e10cSrcweir $dir2 =~ s/\\\s*//; 1127cdf0e10cSrcweir $dir1 =~ s/\/\s*//; 1128cdf0e10cSrcweir $dir2 =~ s/\/\s*//; 1129cdf0e10cSrcweir 1130cdf0e10cSrcweir my $infoline = "Comparing directories: $dir1 and $dir2\n"; 1131*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 1132cdf0e10cSrcweir 1133cdf0e10cSrcweir foreach my $onefile ( @{$files} ) 1134cdf0e10cSrcweir { 1135cdf0e10cSrcweir my $file1 = $dir1 . $installer::globals::separator . $onefile; 1136cdf0e10cSrcweir my $file2 = $dir2 . $installer::globals::separator . $onefile; 1137cdf0e10cSrcweir 1138cdf0e10cSrcweir if ( ! -f $file1 ) { installer::exiter::exit_program("ERROR: Missing file : $file1!", "compare_directories"); } 1139cdf0e10cSrcweir if ( ! -f $file2 ) { installer::exiter::exit_program("ERROR: Missing file : $file2!", "compare_directories"); } 1140cdf0e10cSrcweir 1141cdf0e10cSrcweir my $size1 = -s $file1; 1142cdf0e10cSrcweir my $size2 = -s $file2; 1143cdf0e10cSrcweir 1144cdf0e10cSrcweir $infoline = "Comparing files: $file1 ($size1) and $file2 ($size2)\n"; 1145*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 1146cdf0e10cSrcweir 1147cdf0e10cSrcweir if ( $size1 != $size2 ) 1148cdf0e10cSrcweir { 1149cdf0e10cSrcweir installer::exiter::exit_program("ERROR: File defect after copy (different size) $file1 ($size1 bytes) and $file2 ($size2 bytes)!", "compare_directories"); 1150cdf0e10cSrcweir } 1151cdf0e10cSrcweir } 1152cdf0e10cSrcweir} 1153cdf0e10cSrcweir 1154cdf0e10cSrcweir######################################################## 1155cdf0e10cSrcweir# Signing an existing Windows installation set. 1156cdf0e10cSrcweir######################################################## 1157cdf0e10cSrcweir 1158cdf0e10cSrcweirsub sign_install_set 1159cdf0e10cSrcweir{ 1160cdf0e10cSrcweir my ($followmeinfohash, $make_copy, $temppath) = @_; 1161cdf0e10cSrcweir 1162cdf0e10cSrcweir my $installsetpath = $followmeinfohash->{'finalinstalldir'}; 1163cdf0e10cSrcweir 1164cdf0e10cSrcweir installer::logger::include_header_into_logfile("Start: Signing installation set $installsetpath"); 1165cdf0e10cSrcweir 1166cdf0e10cSrcweir my $complete_success = 1; 1167cdf0e10cSrcweir my $success = 1; 1168cdf0e10cSrcweir 1169cdf0e10cSrcweir my $infoline = "Signing installation set in $installsetpath\n"; 1170*b274bc22SAndre Fischer $installer::logger::Lang->print($infoline); 1171cdf0e10cSrcweir 1172cdf0e10cSrcweir # check required files. 1173cdf0e10cSrcweir if ( ! $installer::globals::signfiles_checked ) { check_system_path(); } 1174cdf0e10cSrcweir 1175cdf0e10cSrcweir # get cerficate information 1176cdf0e10cSrcweir my $pw = get_pw($installer::globals::pwfile); 1177cdf0e10cSrcweir 1178cdf0e10cSrcweir # making a copy of the installation set, if required 1179cdf0e10cSrcweir if ( $make_copy ) { $installsetpath = copy_install_set($installsetpath); } 1180cdf0e10cSrcweir else { $installsetpath = rename_install_set($installsetpath); } 1181cdf0e10cSrcweir 1182cdf0e10cSrcweir # collecting all files in the installation set 1183cdf0e10cSrcweir my ($allcabfiles, $allfiles, $msidatabase, $contains_external_cabfiles, $contains_msidatabase, $sourcefiles) = analyze_installset_content($installsetpath); 1184cdf0e10cSrcweir 1185cdf0e10cSrcweir if ( $make_copy ) { compare_directories($installsetpath, $followmeinfohash->{'finalinstalldir'}, $sourcefiles); } 1186cdf0e10cSrcweir 1187cdf0e10cSrcweir # changing into installation set 1188cdf0e10cSrcweir my $from = cwd(); 1189cdf0e10cSrcweir my $fullmsidatabase = $installsetpath . $installer::globals::separator . $msidatabase; 1190cdf0e10cSrcweir 1191cdf0e10cSrcweir if( $^O =~ /cygwin/i ) 1192cdf0e10cSrcweir { 1193cdf0e10cSrcweir $fullmsidatabase = qx{cygpath -w "$fullmsidatabase"}; 1194cdf0e10cSrcweir $fullmsidatabase =~ s/\\/\\\\/g; 1195cdf0e10cSrcweir $fullmsidatabase =~ s/\s*$//g; 1196cdf0e10cSrcweir } 1197cdf0e10cSrcweir 1198cdf0e10cSrcweir chdir($installsetpath); 1199cdf0e10cSrcweir 1200cdf0e10cSrcweir if ( $contains_msidatabase ) 1201cdf0e10cSrcweir { 1202cdf0e10cSrcweir # exclude media table from msi database and get all diskids. 1203cdf0e10cSrcweir my ( $cabfilehash, $filenamehash, $lastsequencehash ) = collect_diskid_from_media_table($msidatabase, $followmeinfohash->{'languagestring'}); 1204cdf0e10cSrcweir 1205cdf0e10cSrcweir # Check, if there are internal cab files 1206cdf0e10cSrcweir my ( $contains_internal_cabfiles, $all_internal_cab_files) = check_for_internal_cabfiles($cabfilehash); 1207cdf0e10cSrcweir 1208cdf0e10cSrcweir if ( $contains_internal_cabfiles ) 1209cdf0e10cSrcweir { 1210cdf0e10cSrcweir my $cabpath = get_cab_path($temppath); 1211cdf0e10cSrcweir chdir($cabpath); 1212cdf0e10cSrcweir 1213cdf0e10cSrcweir # Exclude all cabinet files from database 1214cdf0e10cSrcweir $success = extract_cabs_from_database($fullmsidatabase, $all_internal_cab_files); 1215cdf0e10cSrcweir if ( ! $success ) { $complete_success = 0; } 1216cdf0e10cSrcweir 1217cdf0e10cSrcweir if ( $installer::globals::internal_cabinet_signing ) { sign_files_in_cabinet_files($followmeinfohash, $all_internal_cab_files, $pw, $temppath); } 1218cdf0e10cSrcweir 1219cdf0e10cSrcweir $success = sign_files($followmeinfohash, $all_internal_cab_files, $pw, 0, $filenamehash, $lastsequencehash, $temppath); 1220cdf0e10cSrcweir if ( ! $success ) { $complete_success = 0; } 1221cdf0e10cSrcweir $success = msicert_database($fullmsidatabase, $all_internal_cab_files, $cabfilehash, 1); 1222cdf0e10cSrcweir if ( ! $success ) { $complete_success = 0; } 1223cdf0e10cSrcweir 1224cdf0e10cSrcweir # Include all cabinet files into database 1225cdf0e10cSrcweir $success = include_cabs_into_database($fullmsidatabase, $all_internal_cab_files); 1226cdf0e10cSrcweir if ( ! $success ) { $complete_success = 0; } 1227cdf0e10cSrcweir chdir($installsetpath); 1228cdf0e10cSrcweir } 1229cdf0e10cSrcweir 1230cdf0e10cSrcweir # Warning: There might be a problem with very big cabinet files 1231cdf0e10cSrcweir # signing all external cab files first 1232cdf0e10cSrcweir if ( $contains_external_cabfiles ) 1233cdf0e10cSrcweir { 1234cdf0e10cSrcweir if ( $installer::globals::internal_cabinet_signing ) { sign_files_in_cabinet_files($followmeinfohash, $allcabfiles, $pw, $temppath); } 1235cdf0e10cSrcweir 1236cdf0e10cSrcweir $success = sign_files($followmeinfohash, $allcabfiles, $pw, 0, $filenamehash, $lastsequencehash, $temppath); 1237cdf0e10cSrcweir if ( ! $success ) { $complete_success = 0; } 1238cdf0e10cSrcweir $success = msicert_database($msidatabase, $allcabfiles, $cabfilehash, 0); 1239cdf0e10cSrcweir if ( ! $success ) { $complete_success = 0; } 1240cdf0e10cSrcweir } 1241cdf0e10cSrcweir } 1242cdf0e10cSrcweir 1243cdf0e10cSrcweir # finally all other files can be signed 1244cdf0e10cSrcweir $success = sign_files($followmeinfohash, $allfiles, $pw, 0, 0, 0, $temppath); 1245cdf0e10cSrcweir if ( ! $success ) { $complete_success = 0; } 1246cdf0e10cSrcweir 1247cdf0e10cSrcweir # and changing back 1248cdf0e10cSrcweir chdir($from); 1249cdf0e10cSrcweir 1250cdf0e10cSrcweir installer::logger::include_header_into_logfile("End: Signing installation set $installsetpath"); 1251cdf0e10cSrcweir 1252cdf0e10cSrcweir return ($installsetpath); 1253cdf0e10cSrcweir} 1254cdf0e10cSrcweir 1255cdf0e10cSrcweir1; 1256