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