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