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