1#************************************************************** 2# 3# Licensed to the Apache Software Foundation (ASF) under one 4# or more contributor license agreements. See the NOTICE file 5# distributed with this work for additional information 6# regarding copyright ownership. The ASF licenses this file 7# to you under the Apache License, Version 2.0 (the 8# "License"); you may not use this file except in compliance 9# with the License. You may obtain a copy of the License at 10# 11# http://www.apache.org/licenses/LICENSE-2.0 12# 13# Unless required by applicable law or agreed to in writing, 14# software distributed under the License is distributed on an 15# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16# KIND, either express or implied. See the License for the 17# specific language governing permissions and limitations 18# under the License. 19# 20#************************************************************** 21 22 23 24package installer::windows::media; 25 26use installer::exiter; 27use installer::files; 28use installer::globals; 29use installer::windows::idtglobal; 30 31############################################################## 32# Returning the diskid for the media table. 33############################################################## 34 35sub get_media_diskid 36{ 37 my ($id) = @_; 38 39 return $id; 40} 41 42############################################################## 43# Returning the lastsequence for the media table. 44############################################################## 45 46sub get_media_lastsequence 47{ 48 my ($fileref) = @_; 49 50 return $fileref->{'sequencenumber'}; 51} 52 53############################################################## 54# Returning the diskprompt for the media table. 55############################################################## 56 57sub get_media_diskprompt 58{ 59 return 1; 60} 61 62############################################################## 63# Returning the cabinet file name for the media table. 64############################################################## 65 66sub get_media_cabinet 67{ 68 my ($id) = @_; 69 70 my $number = 1000 + $id; 71 my $filename = "f_" . $number . ".cab"; 72 73 if ( $installer::globals::include_cab_in_msi ) { $filename = "\#" . $filename; } 74 75 return $filename; 76} 77 78############################################################## 79# Returning the volumelabel for the media table. 80############################################################## 81 82sub get_media_volumelabel 83{ 84 return "DISK1"; 85} 86 87############################################################## 88# Returning the source for the media table. 89############################################################## 90 91sub get_media_source 92{ 93 return ""; 94} 95 96############################################################## 97# Saving the cabinet file name in the files collector. 98# This is useful for making a list to connect the 99# source of each file with the destination cabinet file. 100############################################################## 101 102sub set_cabinetfilename_for_component_in_file_collector 103{ 104 my ($cabinetfilename, $filesref, $componentname, $max) = @_; 105 106 for ( my $i = 0; $i <= $max; $i++ ) 107 { 108 my $onefile = ${$filesref}[$i]; 109 my $component = $onefile->{'componentname'}; 110 111 if ( $component eq $componentname ) 112 { 113 my $cabinet = ""; 114 115 if ( $onefile->{'cabinet'} ) { $cabinet = $onefile->{'cabinet'}; } 116 117 if ( $cabinet eq "" ) 118 { 119 $onefile->{'cabinet'} = $cabinetfilename; 120 } 121 } 122 } 123} 124 125################################################# 126# Creating the cab file name dynamically 127################################################# 128 129sub generate_cab_filename_for_some_cabs 130{ 131 my ( $allvariables, $id ) = @_; 132 133 my $name = $allvariables->{'PRODUCTNAME'}; 134 135 $name = lc($name); 136 $name =~ s/\.//g; 137 $name =~ s/\s//g; 138 139 # possibility to overwrite the name with variable CABFILENAME 140 if ( $allvariables->{'CABFILENAME'} ) { $name = $allvariables->{'CABFILENAME'}; } 141 142 $name = $name . $id . ".cab"; 143 144 if ( $installer::globals::include_cab_in_msi ) { $name = "\#" . $name; } 145 146 return $name; 147} 148 149################################################# 150# Creating the cab file name for cab files 151# defined in packages. 152################################################# 153 154sub get_cabfilename 155{ 156 my ($name) = @_; 157 158 if ( $installer::globals::include_cab_in_msi ) { $name = "\#" . $name; } 159 160 return $name; 161} 162 163################################################# 164# Creating the cab file name dynamically 165################################################# 166 167sub generate_cab_filename 168{ 169 my ( $allvariables ) = @_; 170 171 my $name = $allvariables->{'PRODUCTNAME'}; 172 173 $name = lc($name); 174 $name =~ s/\.//g; 175 $name =~ s/\s//g; 176 177 # possibility to overwrite the name with variable CABFILENAME 178 if ( $allvariables->{'CABFILENAME'} ) { $name = $allvariables->{'CABFILENAME'}; } 179 180 $name = $name . ".cab"; 181 182 if ( $installer::globals::include_cab_in_msi ) { $name = "\#" . $name; } 183 184 return $name; 185} 186 187sub get_maximum_filenumber 188{ 189 my ($allfiles, $maxcabfilenumber) = @_; 190 191 my $maxfile = 0; 192 193 while ( ! ( $allfiles%$maxcabfilenumber == 0 )) 194 { 195 $allfiles++; 196 } 197 198 $maxfile = $allfiles / $maxcabfilenumber; 199 200 $maxfile++; # for securitry 201 202 return $maxfile; 203} 204 205################################################################################# 206# Setting the last sequence for the cabinet files 207################################################################################# 208 209sub get_last_sequence 210{ 211 my ( $cabfilename, $alludpatelastsequences ) = @_; 212 213 my $sequence = 0; 214 215 if (( $installer::globals::updatedatabase ) && ( exists($alludpatelastsequences->{$cabfilename}) )) 216 { 217 $sequence = $alludpatelastsequences->{$cabfilename}; 218 } 219 else 220 { 221 $sequence = $installer::globals::lastsequence{$cabfilename}; 222 } 223 224 return $sequence; 225} 226 227################################################################################# 228# Creating the file Media.idt dynamically 229# Content: 230# DiskId LastSequence DiskPrompt Cabinet VolumeLabel Source 231# Idea: Every component is packed into each own cab file 232################################################################################# 233 234sub create_media_table 235{ 236 my ($filesref, $basedir, $allvariables, $alludpatelastsequences, $allupdatediskids) = @_; 237 238 my @mediatable = (); 239 240 my $diskid = 0; 241 242 installer::windows::idtglobal::write_idt_header(\@mediatable, "media"); 243 244 if ( $allvariables->{'INCLUDE_CAB_IN_MSI'} ) { $installer::globals::include_cab_in_msi = 1; } 245 246 if ( $installer::globals::use_packages_for_cabs ) 247 { 248 my $cabfile; 249 foreach $cabfile ( sort keys %installer::globals::lastsequence ) 250 { 251 my %media = (); 252 $diskid++; 253 254 $media{'DiskId'} = get_media_diskid($diskid); 255 $media{'LastSequence'} = get_last_sequence($cabfile, $alludpatelastsequences); 256 $media{'DiskPrompt'} = get_media_diskprompt(); 257 $media{'Cabinet'} = get_cabfilename($cabfile); 258 $media{'VolumeLabel'} = get_media_volumelabel(); 259 $media{'Source'} = get_media_source(); 260 261 my $oneline = $media{'DiskId'} . "\t" . $media{'LastSequence'} . "\t" . $media{'DiskPrompt'} . "\t" 262 . $media{'Cabinet'} . "\t" . $media{'VolumeLabel'} . "\t" . $media{'Source'} . "\n"; 263 264 push(@mediatable, $oneline); 265 266 # Comparing the disk id with the disk id from update database. Both have to be identical. New files have to be added 267 # to the new pff cabinet file. And existing cab files must not be removed. 268 if ( $installer::globals::updatedatabase ) 269 { 270 # Comparing lines in new media table with line from media table in udpate database. 271 if ( exists($allupdatediskids->{$media{'Cabinet'}}) ) 272 { 273 if ( $media{'DiskId'} != $allupdatediskids->{$media{'Cabinet'}} ) 274 { 275 installer::exiter::exit_program("ERROR: Different DiskIDs for cab file \"$media{'Cabinet'}\".\nCurrent installation set: \"$media{'DiskId'}\", but update database used \"$allupdatediskids->{$media{'Cabinet'}}\".\nWere cabinet files removed or added?", "create_media_table"); 276 } 277 } 278 else 279 { 280 my $localinfoline = "Warning: Could not find cabinet file \"$media{'Cabinet'}}\" in update database. This seems to be an new cabinet file!?\n"; 281 push(@installer::globals::logfileinfo, $localinfoline); 282 } 283 } 284 } 285 286 # one new cabinet file for all files added after the final release 287 if (( $installer::globals::updatedatabase ) && ( $installer::globals::pfffileexists )) 288 { 289 my %media = (); 290 $diskid++; 291 292 $media{'DiskId'} = get_media_diskid($diskid) + $installer::globals::mergemodulenumber; # Adding mergemodulenumber, because this files are included later 293 $media{'LastSequence'} = $installer::globals::updatesequencecounter; 294 $media{'DiskPrompt'} = get_media_diskprompt(); 295 $media{'Cabinet'} = get_cabfilename($installer::globals::pffcabfilename); 296 $media{'VolumeLabel'} = get_media_volumelabel(); 297 $media{'Source'} = get_media_source(); 298 299 my $oneline = $media{'DiskId'} . "\t" . $media{'LastSequence'} . "\t" . $media{'DiskPrompt'} . "\t" 300 . $media{'Cabinet'} . "\t" . $media{'VolumeLabel'} . "\t" . $media{'Source'} . "\n"; 301 302 push(@mediatable, $oneline); 303 } 304 305 } 306 elsif ( $installer::globals::cab_file_per_component ) 307 { 308 for ( my $i = 0; $i <= $#{$filesref}; $i++ ) 309 { 310 my $onefile = ${$filesref}[$i]; 311 my $nextfile = ${$filesref}[$i+1]; 312 313 my $filecomponent = ""; 314 my $nextcomponent = ""; 315 316 if ( $onefile->{'componentname'} ) { $filecomponent = $onefile->{'componentname'}; } 317 if ( $nextfile->{'componentname'} ) { $nextcomponent = $nextfile->{'componentname'}; } 318 319 if ( $filecomponent eq $nextcomponent ) 320 { 321 next; # nothing to do, this is not the last file of a component 322 } 323 324 my %media = (); 325 $diskid++; 326 327 $media{'DiskId'} = get_media_diskid($diskid); 328 $media{'LastSequence'} = get_media_lastsequence($onefile); 329 $media{'DiskPrompt'} = get_media_diskprompt(); 330 $media{'Cabinet'} = get_media_cabinet($diskid); 331 $media{'VolumeLabel'} = get_media_volumelabel(); 332 $media{'Source'} = get_media_source(); 333 334 my $oneline = $media{'DiskId'} . "\t" . $media{'LastSequence'} . "\t" . $media{'DiskPrompt'} . "\t" 335 . $media{'Cabinet'} . "\t" . $media{'VolumeLabel'} . "\t" . $media{'Source'} . "\n"; 336 337 push(@mediatable, $oneline); 338 339 $media{'Cabinet'} =~ s/^\s*\#//; # removing leading hash 340 set_cabinetfilename_for_component_in_file_collector($media{'Cabinet'}, $filesref, $filecomponent, $i); 341 } 342 } 343 elsif ( $installer::globals::fix_number_of_cab_files ) 344 { 345 # number of cabfiles 346 my $maxcabfilenumber = $installer::globals::number_of_cabfiles; 347 if ( $allvariables->{'CABFILENUMBER'} ) { $maxcabfilenumber = $allvariables->{'CABFILENUMBER'}; } 348 my $allfiles = $#{$filesref} + 1; 349 my $maxfilenumber = get_maximum_filenumber($allfiles, $maxcabfilenumber); 350 # my $maxfilenumber = 1000; # maximum 1000 files in each cabinet file 351 my $cabfilenumber = 0; 352 my $cabfull = 0; 353 my $counter = 0; 354 355 # Sorting of files collector files required ! 356 # Attention: The order in the cab file is not guaranteed (especially in udpate process) 357 358 for ( my $i = 0; $i <= $#{$filesref}; $i++ ) 359 { 360 if (( $counter >= $maxfilenumber ) || ( $i == $#{$filesref} )) { $cabfull = 1; } 361 362 $counter++; # counting the files in the cab file 363 364 my $onefile = ${$filesref}[$i]; 365 my $nextfile = ${$filesref}[$i+1]; 366 367 my $filecomponent = ""; 368 my $nextcomponent = ""; 369 370 if ( $onefile->{'componentname'} ) { $filecomponent = $onefile->{'componentname'}; } 371 if ( $nextfile->{'componentname'} ) { $nextcomponent = $nextfile->{'componentname'}; } 372 373 if ( $filecomponent eq $nextcomponent ) # all files of one component have to be in one cab file 374 { 375 next; # nothing to do, this is not the last file of a component 376 } 377 378 if ( $cabfull ) 379 { 380 my %media = (); 381 $cabfilenumber++; 382 383 $media{'DiskId'} = get_media_diskid($cabfilenumber); 384 # $media{'LastSequence'} = get_media_lastsequence($onefile); 385 $media{'LastSequence'} = $i + 1; # This should be correct, also for unsorted files collectors 386 $media{'DiskPrompt'} = get_media_diskprompt(); 387 $media{'Cabinet'} = generate_cab_filename_for_some_cabs($allvariables, $cabfilenumber); 388 $media{'VolumeLabel'} = get_media_volumelabel(); 389 $media{'Source'} = get_media_source(); 390 391 my $oneline = $media{'DiskId'} . "\t" . $media{'LastSequence'} . "\t" . $media{'DiskPrompt'} . "\t" 392 . $media{'Cabinet'} . "\t" . $media{'VolumeLabel'} . "\t" . $media{'Source'} . "\n"; 393 394 push(@mediatable, $oneline); 395 396 # Saving the cabinet file name in the file collector 397 398 $media{'Cabinet'} =~ s/^\s*\#//; # removing leading hash 399 400 for ( my $j = 0; $j <= $i; $j++ ) 401 { 402 my $onefile = ${$filesref}[$j]; 403 if ( ! $onefile->{'cabinet'} ) { $onefile->{'cabinet'} = $media{'Cabinet'}; } 404 } 405 406 $cabfull = 0; 407 $counter = 0; 408 } 409 } 410 } 411 elsif ( $installer::globals::one_cab_file ) 412 { 413 my %media = (); 414 $diskid++; 415 416 my $maximumfile = $#{$filesref}; 417 418 $media{'DiskId'} = get_media_diskid($diskid); 419 # $media{'LastSequence'} = ${$filesref}[$maximumfile]->{'sequencenumber'}; # sequence number of the last file 420 $media{'LastSequence'} = $maximumfile + 1; # This works also for unsorted file collector 421 $media{'DiskPrompt'} = get_media_diskprompt(); 422 $media{'Cabinet'} = generate_cab_filename($allvariables); 423 $media{'VolumeLabel'} = get_media_volumelabel(); 424 $media{'Source'} = get_media_source(); 425 426 my $oneline = $media{'DiskId'} . "\t" . $media{'LastSequence'} . "\t" . $media{'DiskPrompt'} . "\t" 427 . $media{'Cabinet'} . "\t" . $media{'VolumeLabel'} . "\t" . $media{'Source'} . "\n"; 428 429 push(@mediatable, $oneline); 430 431 # Saving the cabinet file name in the file collector 432 433 $media{'Cabinet'} =~ s/^\s*\#//; # removing leading hash 434 435 for ( my $i = 0; $i <= $#{$filesref}; $i++ ) 436 { 437 my $onefile = ${$filesref}[$i]; 438 $onefile->{'cabinet'} = $media{'Cabinet'}; 439 } 440 } 441 else 442 { 443 installer::exiter::exit_program("ERROR: No cab file specification in globals.pm !", "create_media_table"); 444 } 445 446 # Saving the file 447 448 my $mediatablename = $basedir . $installer::globals::separator . "Media.idt"; 449 installer::files::save_file($mediatablename ,\@mediatable); 450 my $infoline = "Created idt file: $mediatablename\n"; 451 push(@installer::globals::logfileinfo, $infoline); 452} 453 4541; 455