1cdf0e10cSrcweir#*************************************************************************
2cdf0e10cSrcweir#
3cdf0e10cSrcweir# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4cdf0e10cSrcweir#
5cdf0e10cSrcweir# Copyright 2000, 2010 Oracle and/or its affiliates.
6cdf0e10cSrcweir#
7cdf0e10cSrcweir# OpenOffice.org - a multi-platform office productivity suite
8cdf0e10cSrcweir#
9cdf0e10cSrcweir# This file is part of OpenOffice.org.
10cdf0e10cSrcweir#
11cdf0e10cSrcweir# OpenOffice.org is free software: you can redistribute it and/or modify
12cdf0e10cSrcweir# it under the terms of the GNU Lesser General Public License version 3
13cdf0e10cSrcweir# only, as published by the Free Software Foundation.
14cdf0e10cSrcweir#
15cdf0e10cSrcweir# OpenOffice.org is distributed in the hope that it will be useful,
16cdf0e10cSrcweir# but WITHOUT ANY WARRANTY; without even the implied warranty of
17cdf0e10cSrcweir# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18cdf0e10cSrcweir# GNU Lesser General Public License version 3 for more details
19cdf0e10cSrcweir# (a copy is included in the LICENSE file that accompanied this code).
20cdf0e10cSrcweir#
21cdf0e10cSrcweir# You should have received a copy of the GNU Lesser General Public License
22cdf0e10cSrcweir# version 3 along with OpenOffice.org.  If not, see
23cdf0e10cSrcweir# <http://www.openoffice.org/license.html>
24cdf0e10cSrcweir# for a copy of the LGPLv3 License.
25cdf0e10cSrcweir#
26cdf0e10cSrcweir#*************************************************************************
27cdf0e10cSrcweir
28cdf0e10cSrcweirpackage installer::windows::msiglobal;
29cdf0e10cSrcweir
30cdf0e10cSrcweiruse Cwd;
31cdf0e10cSrcweiruse Digest::MD5;
32cdf0e10cSrcweiruse installer::converter;
33cdf0e10cSrcweiruse installer::exiter;
34cdf0e10cSrcweiruse installer::files;
35cdf0e10cSrcweiruse installer::globals;
36cdf0e10cSrcweiruse installer::logger;
37cdf0e10cSrcweiruse installer::pathanalyzer;
38cdf0e10cSrcweiruse installer::remover;
39cdf0e10cSrcweiruse installer::scriptitems;
40cdf0e10cSrcweiruse installer::systemactions;
41cdf0e10cSrcweiruse installer::worker;
42cdf0e10cSrcweiruse installer::windows::idtglobal;
43cdf0e10cSrcweiruse installer::windows::language;
44cdf0e10cSrcweir
45cdf0e10cSrcweir###########################################################################
46cdf0e10cSrcweir# Generating the header of the ddf file.
47cdf0e10cSrcweir# The usage of ddf files is needed, because makecab.exe can only include
48cdf0e10cSrcweir# one sourcefile into a cab file
49cdf0e10cSrcweir###########################################################################
50cdf0e10cSrcweir
51cdf0e10cSrcweirsub write_ddf_file_header
52cdf0e10cSrcweir{
53cdf0e10cSrcweir	my ($ddffileref, $cabinetfile, $installdir) = @_;
54cdf0e10cSrcweir
55cdf0e10cSrcweir	my $oneline;
56cdf0e10cSrcweir
57cdf0e10cSrcweir	$oneline = ".Set CabinetName1=" . $cabinetfile . "\n";
58cdf0e10cSrcweir	push(@{$ddffileref} ,$oneline);
59cdf0e10cSrcweir	$oneline = ".Set ReservePerCabinetSize=128\n";	# This reserves space for a digital signature.
60cdf0e10cSrcweir	push(@{$ddffileref} ,$oneline);
61cdf0e10cSrcweir	$oneline = ".Set MaxDiskSize=2147483648\n";		# This allows the .cab file to get a size of 2 GB.
62cdf0e10cSrcweir	push(@{$ddffileref} ,$oneline);
63cdf0e10cSrcweir	$oneline = ".Set CompressionType=LZX\n";
64cdf0e10cSrcweir	push(@{$ddffileref} ,$oneline);
65cdf0e10cSrcweir	$oneline = ".Set Compress=ON\n";
66cdf0e10cSrcweir	push(@{$ddffileref} ,$oneline);
67cdf0e10cSrcweir	$oneline = ".Set CompressionLevel=$installer::globals::cabfilecompressionlevel\n";
68cdf0e10cSrcweir	push(@{$ddffileref} ,$oneline);
69cdf0e10cSrcweir	$oneline = ".Set Cabinet=ON\n";
70cdf0e10cSrcweir	push(@{$ddffileref} ,$oneline);
71cdf0e10cSrcweir	$oneline = ".Set DiskDirectoryTemplate=" . $installdir . "\n";
72cdf0e10cSrcweir	push(@{$ddffileref} ,$oneline);
73cdf0e10cSrcweir}
74cdf0e10cSrcweir
75cdf0e10cSrcweir##########################################################################
76cdf0e10cSrcweir# Lines in ddf files must not contain more than 256 characters
77cdf0e10cSrcweir##########################################################################
78cdf0e10cSrcweir
79cdf0e10cSrcweirsub check_ddf_file
80cdf0e10cSrcweir{
81cdf0e10cSrcweir	my ( $ddffile, $ddffilename ) = @_;
82cdf0e10cSrcweir
83cdf0e10cSrcweir	my $maxlength = 0;
84cdf0e10cSrcweir	my $maxline = 0;
85cdf0e10cSrcweir	my $linelength = 0;
86cdf0e10cSrcweir	my $linenumber = 0;
87cdf0e10cSrcweir
88cdf0e10cSrcweir	for ( my $i = 0; $i <= $#{$ddffile}; $i++ )
89cdf0e10cSrcweir	{
90cdf0e10cSrcweir		my $oneline = ${$ddffile}[$i];
91cdf0e10cSrcweir
92cdf0e10cSrcweir		$linelength = length($oneline);
93cdf0e10cSrcweir		$linenumber = $i + 1;
94cdf0e10cSrcweir
95cdf0e10cSrcweir		if ( $linelength > 256 )
96cdf0e10cSrcweir		{
97cdf0e10cSrcweir			installer::exiter::exit_program("ERROR \"$ddffilename\" line $linenumber: Lines in ddf files must not contain more than 256 characters!", "check_ddf_file");
98cdf0e10cSrcweir		}
99cdf0e10cSrcweir
100cdf0e10cSrcweir		if ( $linelength > $maxlength )
101cdf0e10cSrcweir		{
102cdf0e10cSrcweir			$maxlength = $linelength;
103cdf0e10cSrcweir			$maxline = $linenumber;
104cdf0e10cSrcweir		}
105cdf0e10cSrcweir	}
106cdf0e10cSrcweir
107cdf0e10cSrcweir	my $infoline = "Check of ddf file \"$ddffilename\": Maximum length \"$maxlength\" in line \"$maxline\" (allowed line length: 256 characters)\n";
108cdf0e10cSrcweir	push(@installer::globals::logfileinfo, $infoline);
109cdf0e10cSrcweir}
110cdf0e10cSrcweir
111cdf0e10cSrcweir##########################################################################
112cdf0e10cSrcweir# Lines in ddf files must not be longer than 256 characters.
113cdf0e10cSrcweir# Therefore it can be useful to use relative pathes. Then it is
114cdf0e10cSrcweir# necessary to change into temp directory before calling
115cdf0e10cSrcweir# makecab.exe.
116cdf0e10cSrcweir##########################################################################
117cdf0e10cSrcweir
118cdf0e10cSrcweirsub make_relative_ddf_path
119cdf0e10cSrcweir{
120cdf0e10cSrcweir	my ( $sourcepath ) = @_;
121cdf0e10cSrcweir
122cdf0e10cSrcweir	my $windowstemppath = $installer::globals::temppath;
123cdf0e10cSrcweir
124cdf0e10cSrcweir	if ( $^O =~ /cygwin/i )
125cdf0e10cSrcweir	{
126cdf0e10cSrcweir		$windowstemppath = $installer::globals::cyg_temppath;
127cdf0e10cSrcweir	}
128cdf0e10cSrcweir
129cdf0e10cSrcweir	$sourcepath =~ s/\Q$windowstemppath\E//;
130cdf0e10cSrcweir	$sourcepath =~ s/^\\//;
131cdf0e10cSrcweir
132cdf0e10cSrcweir	return $sourcepath;
133cdf0e10cSrcweir}
134cdf0e10cSrcweir
135cdf0e10cSrcweir##########################################################################
136cdf0e10cSrcweir# Returning the order of the sequences in the files array.
137cdf0e10cSrcweir##########################################################################
138cdf0e10cSrcweir
139cdf0e10cSrcweirsub get_sequenceorder
140cdf0e10cSrcweir{
141cdf0e10cSrcweir	my ($filesref) = @_;
142cdf0e10cSrcweir
143cdf0e10cSrcweir	my %order = ();
144cdf0e10cSrcweir
145cdf0e10cSrcweir	for ( my $i = 0; $i <= $#{$filesref}; $i++ )
146cdf0e10cSrcweir	{
147cdf0e10cSrcweir		my $onefile = ${$filesref}[$i];
148cdf0e10cSrcweir		if ( ! $onefile->{'assignedsequencenumber'} ) { installer::exiter::exit_program("ERROR: No sequence number assigned to $onefile->{'gid'} ($onefile->{'uniquename'})!", "get_sequenceorder"); }
149cdf0e10cSrcweir		$order{$onefile->{'assignedsequencenumber'}} = $i;
150cdf0e10cSrcweir	}
151cdf0e10cSrcweir
152cdf0e10cSrcweir	return \%order;
153cdf0e10cSrcweir}
154cdf0e10cSrcweir
155cdf0e10cSrcweir##########################################################################
156cdf0e10cSrcweir# Generation the list, in which the source of the files is connected
157cdf0e10cSrcweir# with the cabinet destination file. Because more than one file needs
158cdf0e10cSrcweir# to be included into a cab file, this has to be done via ddf files.
159cdf0e10cSrcweir##########################################################################
160cdf0e10cSrcweir
161cdf0e10cSrcweirsub generate_cab_file_list
162cdf0e10cSrcweir{
163cdf0e10cSrcweir	my ($filesref, $installdir, $ddfdir, $allvariables) = @_;
164cdf0e10cSrcweir
165cdf0e10cSrcweir	my @cabfilelist = ();
166cdf0e10cSrcweir
167cdf0e10cSrcweir	installer::logger::include_header_into_logfile("Generating ddf files");
168cdf0e10cSrcweir
169cdf0e10cSrcweir	installer::logger::include_timestamp_into_logfile("Performance Info: ddf file generation start");
170cdf0e10cSrcweir
171cdf0e10cSrcweir	if ( $^O =~ /cygwin/i ) { installer::worker::generate_cygwin_pathes($filesref); }
172cdf0e10cSrcweir
173cdf0e10cSrcweir	if ( $installer::globals::use_packages_for_cabs )
174cdf0e10cSrcweir	{
175cdf0e10cSrcweir		my $sequenceorder = get_sequenceorder($filesref);
176cdf0e10cSrcweir
177cdf0e10cSrcweir		my $counter = 1;
178cdf0e10cSrcweir		my $currentcabfile = "";
179cdf0e10cSrcweir
180cdf0e10cSrcweir		while ( ( exists($sequenceorder->{$counter}) ) || ( exists($installer::globals::allmergemodulefilesequences{$counter}) ) ) # Taking care of files from merge modules
181cdf0e10cSrcweir		{
182cdf0e10cSrcweir			if ( exists($installer::globals::allmergemodulefilesequences{$counter}) )
183cdf0e10cSrcweir			{
184cdf0e10cSrcweir				# Skipping this sequence, it is not included in $filesref, because it is assigned to a file from a merge module.\n";
185cdf0e10cSrcweir				$counter++;
186cdf0e10cSrcweir				next;
187cdf0e10cSrcweir			}
188cdf0e10cSrcweir
189cdf0e10cSrcweir			# Files with increasing sequencerorder are included in one cab file
190cdf0e10cSrcweir			my $onefile = ${$filesref}[$sequenceorder->{$counter}];
191cdf0e10cSrcweir			my $cabinetfile = $onefile->{'assignedcabinetfile'};
192cdf0e10cSrcweir			my $sourcepath =  $onefile->{'sourcepath'};
193cdf0e10cSrcweir			if ( $^O =~ /cygwin/i ) { $sourcepath = $onefile->{'cyg_sourcepath'}; }
194cdf0e10cSrcweir			my $uniquename =  $onefile->{'uniquename'};
195cdf0e10cSrcweir
196cdf0e10cSrcweir			my $styles = "";
197cdf0e10cSrcweir			my $doinclude = 1;
198cdf0e10cSrcweir			if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; };
199cdf0e10cSrcweir			if ( $styles =~ /\bDONT_PACK\b/ ) { $doinclude = 0; }
200cdf0e10cSrcweir
201cdf0e10cSrcweir			# to avoid lines with more than 256 characters, it can be useful to use relative pathes
202cdf0e10cSrcweir			if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) { $sourcepath = make_relative_ddf_path($sourcepath); }
203cdf0e10cSrcweir
204cdf0e10cSrcweir			# all files with the same cabinetfile have increasing sequencenumbers
205cdf0e10cSrcweir
206cdf0e10cSrcweir			my @ddffile = ();
207cdf0e10cSrcweir
208cdf0e10cSrcweir			write_ddf_file_header(\@ddffile, $cabinetfile, $installdir);
209cdf0e10cSrcweir
210cdf0e10cSrcweir			my $ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
211cdf0e10cSrcweir			if ( $doinclude ) { push(@ddffile, $ddfline); }
212cdf0e10cSrcweir
213cdf0e10cSrcweir			$counter++;	# increasing the counter
214cdf0e10cSrcweir			my $nextfile = "";
215cdf0e10cSrcweir			my $nextcabinetfile = "";
216cdf0e10cSrcweir			if ( exists($sequenceorder->{$counter}) ) { $nextfile = ${$filesref}[$sequenceorder->{$counter}]; }
217cdf0e10cSrcweir			if ( $nextfile->{'assignedcabinetfile'} ) { $nextcabinetfile = $nextfile->{'assignedcabinetfile'}; }
218cdf0e10cSrcweir
219cdf0e10cSrcweir			while ( $nextcabinetfile eq $cabinetfile )
220cdf0e10cSrcweir			{
221cdf0e10cSrcweir				$sourcepath =  $nextfile->{'sourcepath'};
222cdf0e10cSrcweir				if ( $^O =~ /cygwin/i ) { $sourcepath = $nextfile->{'cyg_sourcepath'}; }
223cdf0e10cSrcweir				# to avoid lines with more than 256 characters, it can be useful to use relative pathes
224cdf0e10cSrcweir				if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) { $sourcepath = make_relative_ddf_path($sourcepath); }
225cdf0e10cSrcweir				$uniquename =  $nextfile->{'uniquename'};
226cdf0e10cSrcweir				my $localdoinclude = 1;
227cdf0e10cSrcweir				my $nextfilestyles = "";
228cdf0e10cSrcweir				if ( $nextfile->{'Styles'} ) { $nextfilestyles = $nextfile->{'Styles'}; }
229cdf0e10cSrcweir				if ( $nextfilestyles =~ /\bDONT_PACK\b/ ) { $localdoinclude = 0; }
230cdf0e10cSrcweir				$ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
231cdf0e10cSrcweir				if ( $localdoinclude ) { push(@ddffile, $ddfline); }
232cdf0e10cSrcweir
233cdf0e10cSrcweir				$counter++;	# increasing the counter!
234cdf0e10cSrcweir				$nextcabinetfile = "_lastfile_";
235cdf0e10cSrcweir				if ( exists($sequenceorder->{$counter}) )
236cdf0e10cSrcweir				{
237cdf0e10cSrcweir					$nextfile = ${$filesref}[$sequenceorder->{$counter}];
238cdf0e10cSrcweir					$nextcabinetfile = $nextfile->{'assignedcabinetfile'};
239cdf0e10cSrcweir				}
240cdf0e10cSrcweir			}
241cdf0e10cSrcweir
242cdf0e10cSrcweir			# creating the DDF file
243cdf0e10cSrcweir
244cdf0e10cSrcweir			my $ddffilename = $cabinetfile;
245cdf0e10cSrcweir			$ddffilename =~ s/.cab/.ddf/;
246cdf0e10cSrcweir			$ddfdir =~ s/\Q$installer::globals::separator\E\s*$//;
247cdf0e10cSrcweir			$ddffilename = $ddfdir . $installer::globals::separator . $ddffilename;
248cdf0e10cSrcweir
249cdf0e10cSrcweir			installer::files::save_file($ddffilename ,\@ddffile);
250cdf0e10cSrcweir			my $infoline = "Created ddf file: $ddffilename\n";
251cdf0e10cSrcweir			push(@installer::globals::logfileinfo, $infoline);
252cdf0e10cSrcweir
253cdf0e10cSrcweir			# lines in ddf files must not be longer than 256 characters
254cdf0e10cSrcweir			check_ddf_file(\@ddffile, $ddffilename);
255cdf0e10cSrcweir
256cdf0e10cSrcweir			# Writing the makecab system call
257cdf0e10cSrcweir
258cdf0e10cSrcweir			my $oneline = "makecab.exe /V3 /F " . $ddffilename . " 2\>\&1 |" . "\n";
259cdf0e10cSrcweir
260cdf0e10cSrcweir			push(@cabfilelist, $oneline);
261cdf0e10cSrcweir
262cdf0e10cSrcweir			# collecting all ddf files
263cdf0e10cSrcweir			push(@installer::globals::allddffiles, $ddffilename);
264cdf0e10cSrcweir		}
265cdf0e10cSrcweir	}
266cdf0e10cSrcweir	elsif ((( $installer::globals::cab_file_per_component ) || ( $installer::globals::fix_number_of_cab_files )) && ( $installer::globals::updatedatabase ))
267cdf0e10cSrcweir	{
268cdf0e10cSrcweir		my $sequenceorder = get_sequenceorder($filesref);
269cdf0e10cSrcweir
270cdf0e10cSrcweir		my $counter = 1;
271cdf0e10cSrcweir		my $currentcabfile = "";
272cdf0e10cSrcweir
273cdf0e10cSrcweir		while ( ( exists($sequenceorder->{$counter}) ) || ( exists($installer::globals::allmergemodulefilesequences{$counter}) ) ) # Taking care of files from merge modules
274cdf0e10cSrcweir		{
275cdf0e10cSrcweir#			if ( exists($installer::globals::allmergemodulefilesequences{$counter}) )
276cdf0e10cSrcweir#			{
277cdf0e10cSrcweir#				# Skipping this sequence, it is not included in $filesref, because it is assigned to a file from a merge module.\n";
278cdf0e10cSrcweir#				$counter++;
279cdf0e10cSrcweir#				next;
280cdf0e10cSrcweir#			}
281cdf0e10cSrcweir
282cdf0e10cSrcweir			my $onefile = ${$filesref}[$sequenceorder->{$counter}];
283cdf0e10cSrcweir			$counter++;
284cdf0e10cSrcweir
285cdf0e10cSrcweir			my $cabinetfile = $onefile->{'cabinet'};
286cdf0e10cSrcweir			my $sourcepath =  $onefile->{'sourcepath'};
287cdf0e10cSrcweir			if ( $^O =~ /cygwin/i ) { $sourcepath = $onefile->{'cyg_sourcepath'}; }
288cdf0e10cSrcweir			my $uniquename =  $onefile->{'uniquename'};
289cdf0e10cSrcweir
290cdf0e10cSrcweir			my $styles = "";
291cdf0e10cSrcweir			my $doinclude = 1;
292cdf0e10cSrcweir			if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; };
293cdf0e10cSrcweir			if ( $styles =~ /\bDONT_PACK\b/ ) { $doinclude = 0; }
294cdf0e10cSrcweir
295cdf0e10cSrcweir			# to avoid lines with more than 256 characters, it can be useful to use relative pathes
296cdf0e10cSrcweir			if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) { $sourcepath = make_relative_ddf_path($sourcepath); }
297cdf0e10cSrcweir
298cdf0e10cSrcweir			my @ddffile = ();
299cdf0e10cSrcweir
300cdf0e10cSrcweir			write_ddf_file_header(\@ddffile, $cabinetfile, $installdir);
301cdf0e10cSrcweir
302cdf0e10cSrcweir			my $ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
303cdf0e10cSrcweir			if ( $doinclude ) { push(@ddffile, $ddfline); }
304cdf0e10cSrcweir
305cdf0e10cSrcweir			my $nextfile = "";
306cdf0e10cSrcweir			if ( ${$filesref}[$sequenceorder->{$counter}] ) { $nextfile = ${$filesref}[$sequenceorder->{$counter}]; }
307cdf0e10cSrcweir
308cdf0e10cSrcweir			my $nextcabinetfile = "";
309cdf0e10cSrcweir
310cdf0e10cSrcweir			if ( $nextfile->{'cabinet'} ) { $nextcabinetfile = $nextfile->{'cabinet'}; }
311cdf0e10cSrcweir
312cdf0e10cSrcweir			while ( $nextcabinetfile eq $cabinetfile )
313cdf0e10cSrcweir			{
314cdf0e10cSrcweir				$sourcepath =  $nextfile->{'sourcepath'};
315cdf0e10cSrcweir				if ( $^O =~ /cygwin/i ) { $sourcepath = $nextfile->{'cyg_sourcepath'}; }
316cdf0e10cSrcweir				# to avoid lines with more than 256 characters, it can be useful to use relative pathes
317cdf0e10cSrcweir				if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) { $sourcepath = make_relative_ddf_path($sourcepath); }
318cdf0e10cSrcweir				$uniquename =  $nextfile->{'uniquename'};
319cdf0e10cSrcweir				my $localdoinclude = 1;
320cdf0e10cSrcweir				my $nextfilestyles = "";
321cdf0e10cSrcweir				if ( $nextfile->{'Styles'} ) { $nextfilestyles = $nextfile->{'Styles'}; }
322cdf0e10cSrcweir				if ( $nextfilestyles =~ /\bDONT_PACK\b/ ) { $localdoinclude = 0; }
323cdf0e10cSrcweir				$ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
324cdf0e10cSrcweir				if ( $localdoinclude ) { push(@ddffile, $ddfline); }
325cdf0e10cSrcweir				$counter++;											# increasing the counter!
326cdf0e10cSrcweir				$nextfile = "";
327cdf0e10cSrcweir				$nextcabinetfile = "_lastfile_";
328cdf0e10cSrcweir				if (( exists($sequenceorder->{$counter}) ) && ( ${$filesref}[$sequenceorder->{$counter}] ))
329cdf0e10cSrcweir				{
330cdf0e10cSrcweir					$nextfile = ${$filesref}[$sequenceorder->{$counter}];
331cdf0e10cSrcweir					$nextcabinetfile = $nextfile->{'cabinet'};
332cdf0e10cSrcweir				}
333cdf0e10cSrcweir			}
334cdf0e10cSrcweir
335cdf0e10cSrcweir			# creating the DDF file
336cdf0e10cSrcweir
337cdf0e10cSrcweir			my $ddffilename = $cabinetfile;
338cdf0e10cSrcweir			$ddffilename =~ s/.cab/.ddf/;
339cdf0e10cSrcweir			$ddfdir =~ s/\Q$installer::globals::separator\E\s*$//;
340cdf0e10cSrcweir			$ddffilename = $ddfdir . $installer::globals::separator . $ddffilename;
341cdf0e10cSrcweir
342cdf0e10cSrcweir			installer::files::save_file($ddffilename ,\@ddffile);
343cdf0e10cSrcweir			my $infoline = "Created ddf file: $ddffilename\n";
344cdf0e10cSrcweir			push(@installer::globals::logfileinfo, $infoline);
345cdf0e10cSrcweir
346cdf0e10cSrcweir			# lines in ddf files must not be longer than 256 characters
347cdf0e10cSrcweir			check_ddf_file(\@ddffile, $ddffilename);
348cdf0e10cSrcweir
349cdf0e10cSrcweir			# Writing the makecab system call
350cdf0e10cSrcweir
351cdf0e10cSrcweir			my $oneline = "makecab.exe /V3 /F " . $ddffilename . " 2\>\&1 |" . "\n";
352cdf0e10cSrcweir
353cdf0e10cSrcweir			push(@cabfilelist, $oneline);
354cdf0e10cSrcweir
355cdf0e10cSrcweir			# collecting all ddf files
356cdf0e10cSrcweir			push(@installer::globals::allddffiles, $ddffilename);
357cdf0e10cSrcweir		}
358cdf0e10cSrcweir	}
359cdf0e10cSrcweir	elsif (( $installer::globals::cab_file_per_component ) || ( $installer::globals::fix_number_of_cab_files ))
360cdf0e10cSrcweir	{
361cdf0e10cSrcweir		for ( my $i = 0; $i <= $#{$filesref}; $i++ )
362cdf0e10cSrcweir		{
363cdf0e10cSrcweir			my $onefile = ${$filesref}[$i];
364cdf0e10cSrcweir			my $cabinetfile = $onefile->{'cabinet'};
365cdf0e10cSrcweir			my $sourcepath =  $onefile->{'sourcepath'};
366cdf0e10cSrcweir			if ( $^O =~ /cygwin/i ) { $sourcepath = $onefile->{'cyg_sourcepath'}; }
367cdf0e10cSrcweir			my $uniquename =  $onefile->{'uniquename'};
368cdf0e10cSrcweir
369cdf0e10cSrcweir			my $styles = "";
370cdf0e10cSrcweir			my $doinclude = 1;
371cdf0e10cSrcweir			if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; };
372cdf0e10cSrcweir			if ( $styles =~ /\bDONT_PACK\b/ ) { $doinclude = 0; }
373cdf0e10cSrcweir
374cdf0e10cSrcweir
375cdf0e10cSrcweir			# to avoid lines with more than 256 characters, it can be useful to use relative pathes
376cdf0e10cSrcweir			if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) { $sourcepath = make_relative_ddf_path($sourcepath); }
377cdf0e10cSrcweir
378cdf0e10cSrcweir			# all files with the same cabinetfile are directly behind each other in the files collector
379cdf0e10cSrcweir
380cdf0e10cSrcweir			my @ddffile = ();
381cdf0e10cSrcweir
382cdf0e10cSrcweir			write_ddf_file_header(\@ddffile, $cabinetfile, $installdir);
383cdf0e10cSrcweir
384cdf0e10cSrcweir			my $ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
385cdf0e10cSrcweir			if ( $doinclude ) { push(@ddffile, $ddfline); }
386cdf0e10cSrcweir
387cdf0e10cSrcweir			my $nextfile = ${$filesref}[$i+1];
388cdf0e10cSrcweir			my $nextcabinetfile = "";
389cdf0e10cSrcweir
390cdf0e10cSrcweir			if ( $nextfile->{'cabinet'} ) { $nextcabinetfile = $nextfile->{'cabinet'}; }
391cdf0e10cSrcweir
392cdf0e10cSrcweir			while ( $nextcabinetfile eq $cabinetfile )
393cdf0e10cSrcweir			{
394cdf0e10cSrcweir				$sourcepath =  $nextfile->{'sourcepath'};
395cdf0e10cSrcweir				if ( $^O =~ /cygwin/i ) { $sourcepath = $nextfile->{'cyg_sourcepath'}; }
396cdf0e10cSrcweir				# to avoid lines with more than 256 characters, it can be useful to use relative pathes
397cdf0e10cSrcweir				if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) { $sourcepath = make_relative_ddf_path($sourcepath); }
398cdf0e10cSrcweir				$uniquename =  $nextfile->{'uniquename'};
399cdf0e10cSrcweir				my $localdoinclude = 1;
400cdf0e10cSrcweir				my $nextfilestyles = "";
401cdf0e10cSrcweir				if ( $nextfile->{'Styles'} ) { $nextfilestyles = $nextfile->{'Styles'}; }
402cdf0e10cSrcweir				if ( $nextfilestyles =~ /\bDONT_PACK\b/ ) { $localdoinclude = 0; }
403cdf0e10cSrcweir				$ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
404cdf0e10cSrcweir				if ( $localdoinclude ) { push(@ddffile, $ddfline); }
405cdf0e10cSrcweir				$i++;											# increasing the counter!
406cdf0e10cSrcweir				$nextfile = ${$filesref}[$i+1];
407cdf0e10cSrcweir				if ( $nextfile ) { $nextcabinetfile = $nextfile->{'cabinet'}; }
408cdf0e10cSrcweir				else { $nextcabinetfile = "_lastfile_"; }
409cdf0e10cSrcweir			}
410cdf0e10cSrcweir
411cdf0e10cSrcweir			# creating the DDF file
412cdf0e10cSrcweir
413cdf0e10cSrcweir			my $ddffilename = $cabinetfile;
414cdf0e10cSrcweir			$ddffilename =~ s/.cab/.ddf/;
415cdf0e10cSrcweir			$ddfdir =~ s/\Q$installer::globals::separator\E\s*$//;
416cdf0e10cSrcweir			$ddffilename = $ddfdir . $installer::globals::separator . $ddffilename;
417cdf0e10cSrcweir
418cdf0e10cSrcweir			installer::files::save_file($ddffilename ,\@ddffile);
419cdf0e10cSrcweir			my $infoline = "Created ddf file: $ddffilename\n";
420cdf0e10cSrcweir			push(@installer::globals::logfileinfo, $infoline);
421cdf0e10cSrcweir
422cdf0e10cSrcweir			# lines in ddf files must not be longer than 256 characters
423cdf0e10cSrcweir			check_ddf_file(\@ddffile, $ddffilename);
424cdf0e10cSrcweir
425cdf0e10cSrcweir			# Writing the makecab system call
426cdf0e10cSrcweir
427cdf0e10cSrcweir			my $oneline = "makecab.exe /V3 /F " . $ddffilename . " 2\>\&1 |" . "\n";
428cdf0e10cSrcweir
429cdf0e10cSrcweir			push(@cabfilelist, $oneline);
430cdf0e10cSrcweir
431cdf0e10cSrcweir			# collecting all ddf files
432cdf0e10cSrcweir			push(@installer::globals::allddffiles, $ddffilename);
433cdf0e10cSrcweir		}
434cdf0e10cSrcweir	}
435cdf0e10cSrcweir	elsif (( $installer::globals::one_cab_file ) && ( $installer::globals::updatedatabase ))
436cdf0e10cSrcweir	{
437cdf0e10cSrcweir		my $sequenceorder = get_sequenceorder($filesref);
438cdf0e10cSrcweir
439cdf0e10cSrcweir		my $counter = 1;
440cdf0e10cSrcweir		my $currentcabfile = "";
441cdf0e10cSrcweir
442cdf0e10cSrcweir		while ( ( exists($sequenceorder->{$counter}) ) || ( exists($installer::globals::allmergemodulefilesequences{$counter}) ) ) # Taking care of files from merge modules
443cdf0e10cSrcweir		{
444cdf0e10cSrcweir			if ( exists($installer::globals::allmergemodulefilesequences{$counter}) )
445cdf0e10cSrcweir			{
446cdf0e10cSrcweir				# Skipping this sequence, it is not included in $filesref, because it is assigned to a file from a merge module.\n";
447cdf0e10cSrcweir				$counter++;
448cdf0e10cSrcweir				next;
449cdf0e10cSrcweir			}
450cdf0e10cSrcweir
451cdf0e10cSrcweir			my $onefile = ${$filesref}[$sequenceorder->{$counter}];
452cdf0e10cSrcweir
453cdf0e10cSrcweir			$cabinetfile = $onefile->{'cabinet'};
454cdf0e10cSrcweir			my $sourcepath =  $onefile->{'sourcepath'};
455cdf0e10cSrcweir			if ( $^O =~ /cygwin/i ) { $sourcepath = $onefile->{'cyg_sourcepath'}; }
456cdf0e10cSrcweir			my $uniquename =  $onefile->{'uniquename'};
457cdf0e10cSrcweir
458cdf0e10cSrcweir			# to avoid lines with more than 256 characters, it can be useful to use relative pathes
459cdf0e10cSrcweir			if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) { $sourcepath = make_relative_ddf_path($sourcepath); }
460cdf0e10cSrcweir
461cdf0e10cSrcweir			if ( $counter == 1 ) { write_ddf_file_header(\@ddffile, $cabinetfile, $installdir); }
462cdf0e10cSrcweir
463cdf0e10cSrcweir			my $styles = "";
464cdf0e10cSrcweir			my $doinclude = 1;
465cdf0e10cSrcweir			if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; };
466cdf0e10cSrcweir			if ( $styles =~ /\bDONT_PACK\b/ ) { $doinclude = 0; }
467cdf0e10cSrcweir
468cdf0e10cSrcweir			my $ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
469cdf0e10cSrcweir			if ( $doinclude ) { push(@ddffile, $ddfline); }
470cdf0e10cSrcweir
471cdf0e10cSrcweir			$counter++;	# increasing the counter
472cdf0e10cSrcweir		}
473cdf0e10cSrcweir
474cdf0e10cSrcweir		# creating the DDF file
475cdf0e10cSrcweir
476cdf0e10cSrcweir		my $ddffilename = $cabinetfile;
477cdf0e10cSrcweir		$ddffilename =~ s/.cab/.ddf/;
478cdf0e10cSrcweir		$ddfdir =~ s/[\/\\]\s*$//;
479cdf0e10cSrcweir		$ddffilename = $ddfdir . $installer::globals::separator . $ddffilename;
480cdf0e10cSrcweir
481cdf0e10cSrcweir		installer::files::save_file($ddffilename ,\@ddffile);
482cdf0e10cSrcweir		my $infoline = "Created ddf file: $ddffilename\n";
483cdf0e10cSrcweir		push(@installer::globals::logfileinfo, $infoline);
484cdf0e10cSrcweir
485cdf0e10cSrcweir		# lines in ddf files must not be longer than 256 characters
486cdf0e10cSrcweir		check_ddf_file(\@ddffile, $ddffilename);
487cdf0e10cSrcweir
488cdf0e10cSrcweir		# Writing the makecab system call
489cdf0e10cSrcweir
490cdf0e10cSrcweir		# my $oneline = "makecab.exe /F " . $ddffilename . "\n";
491cdf0e10cSrcweir		my $oneline = "makecab.exe /V3 /F " . $ddffilename . " 2\>\&1 |" . "\n";
492cdf0e10cSrcweir
493cdf0e10cSrcweir		push(@cabfilelist, $oneline);
494cdf0e10cSrcweir
495cdf0e10cSrcweir		# collecting all ddf files
496cdf0e10cSrcweir		push(@installer::globals::allddffiles, $ddffilename);
497cdf0e10cSrcweir	}
498cdf0e10cSrcweir	elsif ( $installer::globals::one_cab_file )
499cdf0e10cSrcweir	{
500cdf0e10cSrcweir		my @ddffile = ();
501cdf0e10cSrcweir
502cdf0e10cSrcweir		my $cabinetfile = "";
503cdf0e10cSrcweir
504cdf0e10cSrcweir		for ( my $i = 0; $i <= $#{$filesref}; $i++ )
505cdf0e10cSrcweir		{
506cdf0e10cSrcweir			my $onefile = ${$filesref}[$i];
507cdf0e10cSrcweir			$cabinetfile = $onefile->{'cabinet'};
508cdf0e10cSrcweir			my $sourcepath =  $onefile->{'sourcepath'};
509cdf0e10cSrcweir			if ( $^O =~ /cygwin/i ) { $sourcepath = $onefile->{'cyg_sourcepath'}; }
510cdf0e10cSrcweir			my $uniquename =  $onefile->{'uniquename'};
511cdf0e10cSrcweir
512cdf0e10cSrcweir			# to avoid lines with more than 256 characters, it can be useful to use relative pathes
513cdf0e10cSrcweir			if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) { $sourcepath = make_relative_ddf_path($sourcepath); }
514cdf0e10cSrcweir
515cdf0e10cSrcweir			if ( $i == 0 ) { write_ddf_file_header(\@ddffile, $cabinetfile, $installdir); }
516cdf0e10cSrcweir
517cdf0e10cSrcweir			my $styles = "";
518cdf0e10cSrcweir			my $doinclude = 1;
519cdf0e10cSrcweir			if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; };
520cdf0e10cSrcweir			if ( $styles =~ /\bDONT_PACK\b/ ) { $doinclude = 0; }
521cdf0e10cSrcweir
522cdf0e10cSrcweir			my $ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
523cdf0e10cSrcweir			if ( $doinclude ) { push(@ddffile, $ddfline); }
524cdf0e10cSrcweir		}
525cdf0e10cSrcweir
526cdf0e10cSrcweir		# creating the DDF file
527cdf0e10cSrcweir
528cdf0e10cSrcweir		my $ddffilename = $cabinetfile;
529cdf0e10cSrcweir		$ddffilename =~ s/.cab/.ddf/;
530cdf0e10cSrcweir		$ddfdir =~ s/[\/\\]\s*$//;
531cdf0e10cSrcweir		$ddffilename = $ddfdir . $installer::globals::separator . $ddffilename;
532cdf0e10cSrcweir
533cdf0e10cSrcweir		installer::files::save_file($ddffilename ,\@ddffile);
534cdf0e10cSrcweir		my $infoline = "Created ddf file: $ddffilename\n";
535cdf0e10cSrcweir		push(@installer::globals::logfileinfo, $infoline);
536cdf0e10cSrcweir
537cdf0e10cSrcweir		# lines in ddf files must not be longer than 256 characters
538cdf0e10cSrcweir		check_ddf_file(\@ddffile, $ddffilename);
539cdf0e10cSrcweir
540cdf0e10cSrcweir		# Writing the makecab system call
541cdf0e10cSrcweir
542cdf0e10cSrcweir		my $oneline = "makecab.exe /F " . $ddffilename . "\n";
543cdf0e10cSrcweir
544cdf0e10cSrcweir		push(@cabfilelist, $oneline);
545cdf0e10cSrcweir
546cdf0e10cSrcweir		# collecting all ddf files
547cdf0e10cSrcweir		push(@installer::globals::allddffiles, $ddffilename);
548cdf0e10cSrcweir	}
549cdf0e10cSrcweir	else
550cdf0e10cSrcweir	{
551cdf0e10cSrcweir		installer::exiter::exit_program("ERROR: No cab file specification in globals.pm !", "create_media_table");
552cdf0e10cSrcweir	}
553cdf0e10cSrcweir
554cdf0e10cSrcweir	installer::logger::include_timestamp_into_logfile("Performance Info: ddf file generation end");
555cdf0e10cSrcweir
556cdf0e10cSrcweir	return \@cabfilelist;	# contains all system calls for packaging process
557cdf0e10cSrcweir}
558cdf0e10cSrcweir
559cdf0e10cSrcweir########################################################################
560cdf0e10cSrcweir# Returning the file sequence of a specified file.
561cdf0e10cSrcweir########################################################################
562cdf0e10cSrcweir
563cdf0e10cSrcweirsub get_file_sequence
564cdf0e10cSrcweir{
565cdf0e10cSrcweir	my ($filesref, $uniquefilename) = @_;
566cdf0e10cSrcweir
567cdf0e10cSrcweir	my $sequence = "";
568cdf0e10cSrcweir	my $found_sequence = 0;
569cdf0e10cSrcweir
570cdf0e10cSrcweir	for ( my $i = 0; $i <= $#{$filesref}; $i++ )
571cdf0e10cSrcweir	{
572cdf0e10cSrcweir		my $onefile = ${$filesref}[$i];
573cdf0e10cSrcweir		my $uniquename = $onefile->{'uniquename'};
574cdf0e10cSrcweir
575cdf0e10cSrcweir		if ( $uniquename eq $uniquefilename )
576cdf0e10cSrcweir		{
577cdf0e10cSrcweir			$sequence = $onefile->{'sequencenumber'};
578cdf0e10cSrcweir			$found_sequence = 1;
579cdf0e10cSrcweir			last;
580cdf0e10cSrcweir		}
581cdf0e10cSrcweir	}
582cdf0e10cSrcweir
583cdf0e10cSrcweir	if ( ! $found_sequence ) { installer::exiter::exit_program("ERROR: No sequence found for $uniquefilename !", "get_file_sequence"); }
584cdf0e10cSrcweir
585cdf0e10cSrcweir	return $sequence;
586cdf0e10cSrcweir}
587cdf0e10cSrcweir
588cdf0e10cSrcweir########################################################################
589cdf0e10cSrcweir# For update and patch reasons the pack order needs to be saved.
590cdf0e10cSrcweir# The pack order is saved in the ddf files; the names and locations
591cdf0e10cSrcweir# of the ddf files are saved in @installer::globals::allddffiles.
592cdf0e10cSrcweir# The outputfile "packorder.txt" can be saved in
593cdf0e10cSrcweir# $installer::globals::infodirectory .
594cdf0e10cSrcweir########################################################################
595cdf0e10cSrcweir
596cdf0e10cSrcweirsub save_packorder
597cdf0e10cSrcweir{
598cdf0e10cSrcweir	installer::logger::include_header_into_logfile("Saving pack order");
599cdf0e10cSrcweir
600cdf0e10cSrcweir	installer::logger::include_timestamp_into_logfile("Performance Info: saving pack order start");
601cdf0e10cSrcweir
602cdf0e10cSrcweir	my $packorderfilename = "packorder.txt";
603cdf0e10cSrcweir	$packorderfilename = $installer::globals::infodirectory . $installer::globals::separator . $packorderfilename;
604cdf0e10cSrcweir
605cdf0e10cSrcweir	my @packorder = ();
606cdf0e10cSrcweir
607cdf0e10cSrcweir	my $headerline = "\# Syntax\: Filetable_Sequence Cabinetfilename Physical_FileName Unique_FileName\n\n";
608cdf0e10cSrcweir	push(@packorder, $headerline);
609cdf0e10cSrcweir
610cdf0e10cSrcweir	for ( my $i = 0; $i <= $#installer::globals::allddffiles; $i++ )
611cdf0e10cSrcweir	{
612cdf0e10cSrcweir		my $ddffilename = $installer::globals::allddffiles[$i];
613cdf0e10cSrcweir		my $ddffile = installer::files::read_file($ddffilename);
614cdf0e10cSrcweir		my $cabinetfile = "";
615cdf0e10cSrcweir
616cdf0e10cSrcweir		for ( my $j = 0; $j <= $#{$ddffile}; $j++ )
617cdf0e10cSrcweir		{
618cdf0e10cSrcweir			my $oneline = ${$ddffile}[$j];
619cdf0e10cSrcweir
620cdf0e10cSrcweir			# Getting the Cabinet file name
621cdf0e10cSrcweir
622cdf0e10cSrcweir			if ( $oneline =~ /^\s*\.Set\s+CabinetName.*\=(.*?)\s*$/ ) { $cabinetfile = $1; }
623cdf0e10cSrcweir			if ( $oneline =~ /^\s*\.Set\s+/ ) { next; }
624cdf0e10cSrcweir
625cdf0e10cSrcweir			if ( $oneline =~ /^\s*\"(.*?)\"\s+(.*?)\s*$/ )
626cdf0e10cSrcweir			{
627cdf0e10cSrcweir				my $sourcefile = $1;
628cdf0e10cSrcweir				my $uniquefilename = $2;
629cdf0e10cSrcweir
630cdf0e10cSrcweir				installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$sourcefile);
631cdf0e10cSrcweir
632cdf0e10cSrcweir				# Using the hash created in create_files_table for performance reasons to get the sequence number
633cdf0e10cSrcweir				my $filesequence = "";
634cdf0e10cSrcweir				if ( exists($installer::globals::uniquefilenamesequence{$uniquefilename}) ) { $filesequence = $installer::globals::uniquefilenamesequence{$uniquefilename}; }
635cdf0e10cSrcweir				else { installer::exiter::exit_program("ERROR: No sequence number value for $uniquefilename !", "save_packorder"); }
636cdf0e10cSrcweir
637cdf0e10cSrcweir				my $line = $filesequence . "\t" . $cabinetfile . "\t" . $sourcefile . "\t" . $uniquefilename . "\n";
638cdf0e10cSrcweir				push(@packorder, $line);
639cdf0e10cSrcweir			}
640cdf0e10cSrcweir		}
641cdf0e10cSrcweir	}
642cdf0e10cSrcweir
643cdf0e10cSrcweir	installer::files::save_file($packorderfilename ,\@packorder);
644cdf0e10cSrcweir
645cdf0e10cSrcweir	installer::logger::include_timestamp_into_logfile("Performance Info: saving pack order end");
646cdf0e10cSrcweir}
647cdf0e10cSrcweir
648cdf0e10cSrcweir#################################################################
649cdf0e10cSrcweir# Returning the name of the msi database
650cdf0e10cSrcweir#################################################################
651cdf0e10cSrcweir
652cdf0e10cSrcweirsub get_msidatabasename
653cdf0e10cSrcweir{
654cdf0e10cSrcweir	my ($allvariableshashref, $language) = @_;
655cdf0e10cSrcweir
656cdf0e10cSrcweir	my $databasename = $allvariableshashref->{'PRODUCTNAME'} . $allvariableshashref->{'PRODUCTVERSION'};
657cdf0e10cSrcweir	$databasename = lc($databasename);
658cdf0e10cSrcweir	$databasename =~ s/\.//g;
659cdf0e10cSrcweir	$databasename =~ s/\-//g;
660cdf0e10cSrcweir	$databasename =~ s/\s//g;
661cdf0e10cSrcweir
662cdf0e10cSrcweir	# possibility to overwrite the name with variable DATABASENAME
663cdf0e10cSrcweir	if ( $allvariableshashref->{'DATABASENAME'} )
664cdf0e10cSrcweir	{
665cdf0e10cSrcweir		$databasename = $allvariableshashref->{'DATABASENAME'};
666cdf0e10cSrcweir	}
667cdf0e10cSrcweir
668cdf0e10cSrcweir	if ( $language )
669cdf0e10cSrcweir	{
670cdf0e10cSrcweir		if (!($language eq ""))
671cdf0e10cSrcweir		{
672cdf0e10cSrcweir			$databasename .= "_$language";
673cdf0e10cSrcweir		}
674cdf0e10cSrcweir	}
675cdf0e10cSrcweir
676cdf0e10cSrcweir	$databasename .= ".msi";
677cdf0e10cSrcweir
678cdf0e10cSrcweir	return $databasename;
679cdf0e10cSrcweir}
680cdf0e10cSrcweir
681cdf0e10cSrcweir#################################################################
682cdf0e10cSrcweir# Creating the msi database
683cdf0e10cSrcweir# This works only on Windows
684cdf0e10cSrcweir#################################################################
685cdf0e10cSrcweir
686cdf0e10cSrcweirsub create_msi_database
687cdf0e10cSrcweir{
688cdf0e10cSrcweir	my ($idtdirbase ,$msifilename) = @_;
689cdf0e10cSrcweir
690cdf0e10cSrcweir	# -f : path containing the idt files
691cdf0e10cSrcweir	# -d : msi database, including path
692cdf0e10cSrcweir	# -c : create database
693cdf0e10cSrcweir	# -i : include the following tables ("*" includes all available tables)
694cdf0e10cSrcweir
695cdf0e10cSrcweir	my $msidb = "msidb.exe";	# Has to be in the path
696cdf0e10cSrcweir	my $extraslash = "";		# Has to be set for non-ActiveState perl
697cdf0e10cSrcweir
698cdf0e10cSrcweir	installer::logger::include_header_into_logfile("Creating msi database");
699cdf0e10cSrcweir
700cdf0e10cSrcweir	$idtdirbase = installer::converter::make_path_conform($idtdirbase);
701cdf0e10cSrcweir
702cdf0e10cSrcweir	$msifilename = installer::converter::make_path_conform($msifilename);
703cdf0e10cSrcweir
704cdf0e10cSrcweir	if ( $^O =~ /cygwin/i ) {
705cdf0e10cSrcweir		# msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
706cdf0e10cSrcweir		$idtdirbase =~ s/\//\\\\/g;
707cdf0e10cSrcweir		$msifilename =~ s/\//\\\\/g;
708cdf0e10cSrcweir		$extraslash = "\\";
709cdf0e10cSrcweir	}
710cdf0e10cSrcweir	my $systemcall = $msidb . " -f " . $idtdirbase . " -d " . $msifilename . " -c " . "-i " . $extraslash . "*";
711cdf0e10cSrcweir
712cdf0e10cSrcweir	my $returnvalue = system($systemcall);
713cdf0e10cSrcweir
714cdf0e10cSrcweir	my $infoline = "Systemcall: $systemcall\n";
715cdf0e10cSrcweir	push( @installer::globals::logfileinfo, $infoline);
716cdf0e10cSrcweir
717cdf0e10cSrcweir	if ($returnvalue)
718cdf0e10cSrcweir	{
719cdf0e10cSrcweir		$infoline = "ERROR: Could not execute $msidb!\n";
720cdf0e10cSrcweir		push( @installer::globals::logfileinfo, $infoline);
721cdf0e10cSrcweir	}
722cdf0e10cSrcweir	else
723cdf0e10cSrcweir	{
724cdf0e10cSrcweir		$infoline = "Success: Executed $msidb successfully!\n";
725cdf0e10cSrcweir		push( @installer::globals::logfileinfo, $infoline);
726cdf0e10cSrcweir	}
727cdf0e10cSrcweir}
728cdf0e10cSrcweir
729cdf0e10cSrcweir#####################################################################
730cdf0e10cSrcweir# Returning the value from sis.mlf for Summary Information Stream
731cdf0e10cSrcweir#####################################################################
732cdf0e10cSrcweir
733cdf0e10cSrcweirsub get_value_from_sis_lng
734cdf0e10cSrcweir{
735cdf0e10cSrcweir	my ($language, $languagefile, $searchstring) = @_;
736cdf0e10cSrcweir
737cdf0e10cSrcweir	my $language_block = installer::windows::idtglobal::get_language_block_from_language_file($searchstring, $languagefile);
738cdf0e10cSrcweir	my $newstring = installer::windows::idtglobal::get_language_string_from_language_block($language_block, $language, $searchstring);
739cdf0e10cSrcweir	$newstring = "\"" . $newstring . "\"";
740cdf0e10cSrcweir
741cdf0e10cSrcweir	return $newstring;
742cdf0e10cSrcweir}
743cdf0e10cSrcweir
744cdf0e10cSrcweir#################################################################
745cdf0e10cSrcweir# Returning the msi version for the Summary Information Stream
746cdf0e10cSrcweir#################################################################
747cdf0e10cSrcweir
748cdf0e10cSrcweirsub get_msiversion_for_sis
749cdf0e10cSrcweir{
750cdf0e10cSrcweir	my $msiversion = "200";
751cdf0e10cSrcweir	return $msiversion;
752cdf0e10cSrcweir}
753cdf0e10cSrcweir
754cdf0e10cSrcweir#################################################################
755cdf0e10cSrcweir# Returning the word count for the Summary Information Stream
756cdf0e10cSrcweir#################################################################
757cdf0e10cSrcweir
758cdf0e10cSrcweirsub get_wordcount_for_sis
759cdf0e10cSrcweir{
760cdf0e10cSrcweir	my $wordcount = "0";
761cdf0e10cSrcweir	return $wordcount;
762cdf0e10cSrcweir}
763cdf0e10cSrcweir
764cdf0e10cSrcweir#################################################################
765cdf0e10cSrcweir# Returning the codepage for the Summary Information Stream
766cdf0e10cSrcweir#################################################################
767cdf0e10cSrcweir
768cdf0e10cSrcweirsub get_codepage_for_sis
769cdf0e10cSrcweir{
770cdf0e10cSrcweir	my ( $language ) = @_;
771cdf0e10cSrcweir
772cdf0e10cSrcweir	my $codepage = installer::windows::language::get_windows_encoding($language);
773cdf0e10cSrcweir
774cdf0e10cSrcweir	# Codepage 65001 does not work in Summary Information Stream
775cdf0e10cSrcweir	if ( $codepage == 65001 ) { $codepage = 0; }
776cdf0e10cSrcweir
777cdf0e10cSrcweir	# my $codepage = "1252";	# determine dynamically in a function
778cdf0e10cSrcweir	# my $codepage = "65001";		# UTF-8
779cdf0e10cSrcweir	return $codepage;
780cdf0e10cSrcweir}
781cdf0e10cSrcweir
782cdf0e10cSrcweir#################################################################
783cdf0e10cSrcweir# Returning the template for the Summary Information Stream
784cdf0e10cSrcweir#################################################################
785cdf0e10cSrcweir
786cdf0e10cSrcweirsub get_template_for_sis
787cdf0e10cSrcweir{
788cdf0e10cSrcweir	my ( $language, $allvariables ) = @_;
789cdf0e10cSrcweir
790cdf0e10cSrcweir	my $windowslanguage = installer::windows::language::get_windows_language($language);
791cdf0e10cSrcweir
792cdf0e10cSrcweir	my $architecture = "Intel";
793cdf0e10cSrcweir
794cdf0e10cSrcweir	# Adding 256, if this is a 64 bit installation set.
795cdf0e10cSrcweir	if (( $allvariables->{'64BITPRODUCT'} ) && ( $allvariables->{'64BITPRODUCT'} == 1 )) { $architecture = "x64"; }
796cdf0e10cSrcweir
797cdf0e10cSrcweir	my $value = "\"" . $architecture . ";" . $windowslanguage;	# adding the Windows language
798cdf0e10cSrcweir
799cdf0e10cSrcweir	$value = $value . "\"";						# adding ending '"'
800cdf0e10cSrcweir
801cdf0e10cSrcweir	return $value ;
802cdf0e10cSrcweir}
803cdf0e10cSrcweir
804cdf0e10cSrcweir#################################################################
805cdf0e10cSrcweir# Returning the PackageCode for the Summary Information Stream
806cdf0e10cSrcweir#################################################################
807cdf0e10cSrcweir
808cdf0e10cSrcweirsub get_packagecode_for_sis
809cdf0e10cSrcweir{
810cdf0e10cSrcweir	# always generating a new package code for each package
811cdf0e10cSrcweir
812cdf0e10cSrcweir	my $guidref = get_guid_list(1, 1);	# only one GUID shall be generated
813cdf0e10cSrcweir
814cdf0e10cSrcweir	${$guidref}[0] =~ s/\s*$//;		# removing ending spaces
815cdf0e10cSrcweir
816cdf0e10cSrcweir	my $guid = "\{" . ${$guidref}[0] . "\}";
817cdf0e10cSrcweir
818cdf0e10cSrcweir	my $infoline = "PackageCode: $guid\n";
819cdf0e10cSrcweir	push( @installer::globals::logfileinfo, $infoline);
820cdf0e10cSrcweir
821cdf0e10cSrcweir	return $guid;
822cdf0e10cSrcweir}
823cdf0e10cSrcweir
824cdf0e10cSrcweir#################################################################
825cdf0e10cSrcweir# Returning the title for the Summary Information Stream
826cdf0e10cSrcweir#################################################################
827cdf0e10cSrcweir
828cdf0e10cSrcweirsub get_title_for_sis
829cdf0e10cSrcweir{
830cdf0e10cSrcweir	my ( $language, $languagefile, $searchstring ) = @_;
831cdf0e10cSrcweir
832cdf0e10cSrcweir	my $title = get_value_from_sis_lng($language, $languagefile, $searchstring );
833cdf0e10cSrcweir
834cdf0e10cSrcweir	return $title;
835cdf0e10cSrcweir}
836cdf0e10cSrcweir
837cdf0e10cSrcweir#################################################################
838cdf0e10cSrcweir# Returning the author for the Summary Information Stream
839cdf0e10cSrcweir#################################################################
840cdf0e10cSrcweir
841cdf0e10cSrcweirsub get_author_for_sis
842cdf0e10cSrcweir{
843cdf0e10cSrcweir	my $author = $installer::globals::longmanufacturer;
844cdf0e10cSrcweir
845cdf0e10cSrcweir	$author = "\"" . $author . "\"";
846cdf0e10cSrcweir
847cdf0e10cSrcweir	return $author;
848cdf0e10cSrcweir}
849cdf0e10cSrcweir
850cdf0e10cSrcweir#################################################################
851cdf0e10cSrcweir# Returning the subject for the Summary Information Stream
852cdf0e10cSrcweir#################################################################
853cdf0e10cSrcweir
854cdf0e10cSrcweirsub get_subject_for_sis
855cdf0e10cSrcweir{
856cdf0e10cSrcweir	my ( $allvariableshashref ) = @_;
857cdf0e10cSrcweir
858cdf0e10cSrcweir	my $subject = $allvariableshashref->{'PRODUCTNAME'} . " " . $allvariableshashref->{'PRODUCTVERSION'};
859cdf0e10cSrcweir
860cdf0e10cSrcweir	$subject = "\"" . $subject . "\"";
861cdf0e10cSrcweir
862cdf0e10cSrcweir	return $subject;
863cdf0e10cSrcweir}
864cdf0e10cSrcweir
865cdf0e10cSrcweir#################################################################
866cdf0e10cSrcweir# Returning the comment for the Summary Information Stream
867cdf0e10cSrcweir#################################################################
868cdf0e10cSrcweir
869cdf0e10cSrcweirsub get_comment_for_sis
870cdf0e10cSrcweir{
871cdf0e10cSrcweir	my ( $language, $languagefile, $searchstring ) = @_;
872cdf0e10cSrcweir
873cdf0e10cSrcweir	my $comment = get_value_from_sis_lng($language, $languagefile, $searchstring );
874cdf0e10cSrcweir
875cdf0e10cSrcweir	return $comment;
876cdf0e10cSrcweir}
877cdf0e10cSrcweir
878cdf0e10cSrcweir#################################################################
879cdf0e10cSrcweir# Returning the keywords for the Summary Information Stream
880cdf0e10cSrcweir#################################################################
881cdf0e10cSrcweir
882cdf0e10cSrcweirsub get_keywords_for_sis
883cdf0e10cSrcweir{
884cdf0e10cSrcweir	my ( $language, $languagefile, $searchstring ) = @_;
885cdf0e10cSrcweir
886cdf0e10cSrcweir	my $keywords = get_value_from_sis_lng($language, $languagefile, $searchstring );
887cdf0e10cSrcweir
888cdf0e10cSrcweir	return $keywords;
889cdf0e10cSrcweir}
890cdf0e10cSrcweir
891cdf0e10cSrcweir######################################################################
892cdf0e10cSrcweir# Returning the application name for the Summary Information Stream
893cdf0e10cSrcweir######################################################################
894cdf0e10cSrcweir
895cdf0e10cSrcweirsub get_appname_for_sis
896cdf0e10cSrcweir{
897cdf0e10cSrcweir	my ( $language, $languagefile, $searchstring ) = @_;
898cdf0e10cSrcweir
899cdf0e10cSrcweir	my $appname = get_value_from_sis_lng($language, $languagefile, $searchstring );
900cdf0e10cSrcweir
901cdf0e10cSrcweir	return $appname;
902cdf0e10cSrcweir}
903cdf0e10cSrcweir
904cdf0e10cSrcweir######################################################################
905cdf0e10cSrcweir# Returning the security for the Summary Information Stream
906cdf0e10cSrcweir######################################################################
907cdf0e10cSrcweir
908cdf0e10cSrcweirsub get_security_for_sis
909cdf0e10cSrcweir{
910cdf0e10cSrcweir	my $security = "0";
911cdf0e10cSrcweir	return $security;
912cdf0e10cSrcweir}
913cdf0e10cSrcweir
914cdf0e10cSrcweir#################################################################
915cdf0e10cSrcweir# Writing the Summary information stream into the msi database
916cdf0e10cSrcweir# This works only on Windows
917cdf0e10cSrcweir#################################################################
918cdf0e10cSrcweir
919cdf0e10cSrcweirsub write_summary_into_msi_database
920cdf0e10cSrcweir{
921cdf0e10cSrcweir	my ($msifilename, $language, $languagefile, $allvariableshashref) = @_;
922cdf0e10cSrcweir
923cdf0e10cSrcweir	# -g : requrired msi version
924cdf0e10cSrcweir	# -c : codepage
925cdf0e10cSrcweir	# -p : template
926cdf0e10cSrcweir
927cdf0e10cSrcweir	installer::logger::include_header_into_logfile("Writing summary information stream");
928cdf0e10cSrcweir
929cdf0e10cSrcweir	my $msiinfo = "msiinfo.exe";	# Has to be in the path
930cdf0e10cSrcweir
931cdf0e10cSrcweir	my $sislanguage = "en-US";	# title, comment, keyword and appname alway in english
932cdf0e10cSrcweir
933cdf0e10cSrcweir	my $msiversion = get_msiversion_for_sis();
934cdf0e10cSrcweir	my $codepage = get_codepage_for_sis($language);
935cdf0e10cSrcweir	my $template = get_template_for_sis($language, $allvariableshashref);
936cdf0e10cSrcweir	my $guid = get_packagecode_for_sis();
937cdf0e10cSrcweir	my $title = get_title_for_sis($sislanguage,$languagefile, "OOO_SIS_TITLE");
938cdf0e10cSrcweir	my $author = get_author_for_sis();
939cdf0e10cSrcweir	my $subject = get_subject_for_sis($allvariableshashref);
940cdf0e10cSrcweir	my $comment = get_comment_for_sis($sislanguage,$languagefile, "OOO_SIS_COMMENT");
941cdf0e10cSrcweir	my $keywords = get_keywords_for_sis($sislanguage,$languagefile, "OOO_SIS_KEYWORDS");
942cdf0e10cSrcweir	my $appname = get_appname_for_sis($sislanguage,$languagefile, "OOO_SIS_APPNAME");
943cdf0e10cSrcweir	my $security = get_security_for_sis();
944cdf0e10cSrcweir	my $wordcount = get_wordcount_for_sis();
945cdf0e10cSrcweir
946cdf0e10cSrcweir	$msifilename = installer::converter::make_path_conform($msifilename);
947cdf0e10cSrcweir
948cdf0e10cSrcweir	my $systemcall = $msiinfo . " " . $msifilename . " -g " . $msiversion . " -c " . $codepage
949cdf0e10cSrcweir					. " -p " . $template . " -v " . $guid . " -t " . $title . " -a " . $author
950cdf0e10cSrcweir					. " -j " . $subject . " -o " . $comment . " -k " . $keywords . " -n " . $appname
951cdf0e10cSrcweir					. " -u " . $security . " -w " . $wordcount;
952cdf0e10cSrcweir
953cdf0e10cSrcweir	my $returnvalue = system($systemcall);
954cdf0e10cSrcweir
955cdf0e10cSrcweir	my $infoline = "Systemcall: $systemcall\n";
956cdf0e10cSrcweir	push( @installer::globals::logfileinfo, $infoline);
957cdf0e10cSrcweir
958cdf0e10cSrcweir	if ($returnvalue)
959cdf0e10cSrcweir	{
960cdf0e10cSrcweir		$infoline = "ERROR: Could not execute $msiinfo!\n";
961cdf0e10cSrcweir		push( @installer::globals::logfileinfo, $infoline);
962cdf0e10cSrcweir	}
963cdf0e10cSrcweir	else
964cdf0e10cSrcweir	{
965cdf0e10cSrcweir		$infoline = "Success: Executed $msiinfo successfully!\n";
966cdf0e10cSrcweir		push( @installer::globals::logfileinfo, $infoline);
967cdf0e10cSrcweir	}
968cdf0e10cSrcweir}
969cdf0e10cSrcweir
970cdf0e10cSrcweir#########################################################################
971cdf0e10cSrcweir# For more than one language in the installation set:
972cdf0e10cSrcweir# Use one database and create Transformations for all other languages
973cdf0e10cSrcweir#########################################################################
974cdf0e10cSrcweir
975cdf0e10cSrcweirsub create_transforms
976cdf0e10cSrcweir{
977cdf0e10cSrcweir	my ($languagesarray, $defaultlanguage, $installdir, $allvariableshashref) = @_;
978cdf0e10cSrcweir
979cdf0e10cSrcweir	installer::logger::include_header_into_logfile("Creating Transforms");
980cdf0e10cSrcweir
981cdf0e10cSrcweir	my $msitran = "msitran.exe";	# Has to be in the path
982cdf0e10cSrcweir
983cdf0e10cSrcweir	$installdir = installer::converter::make_path_conform($installdir);
984cdf0e10cSrcweir
985cdf0e10cSrcweir	# Syntax for creating a transformation
986cdf0e10cSrcweir	# msitran.exe -g <baseDB> <referenceDB> <transformfile> [<errorhandling>}
987cdf0e10cSrcweir
988cdf0e10cSrcweir	my $basedbname = get_msidatabasename($allvariableshashref, $defaultlanguage);
989cdf0e10cSrcweir	$basedbname = $installdir . $installer::globals::separator . $basedbname;
990cdf0e10cSrcweir
991cdf0e10cSrcweir	my $errorhandling = "f";	# Suppress "change codepage" error
992cdf0e10cSrcweir
993cdf0e10cSrcweir	# Iterating over all files
994cdf0e10cSrcweir
995cdf0e10cSrcweir	foreach ( @{$languagesarray} )
996cdf0e10cSrcweir	{
997cdf0e10cSrcweir		my $onelanguage = $_;
998cdf0e10cSrcweir
999cdf0e10cSrcweir		if ( $onelanguage eq $defaultlanguage ) { next; }
1000cdf0e10cSrcweir
1001cdf0e10cSrcweir		my $referencedbname = get_msidatabasename($allvariableshashref, $onelanguage);
1002cdf0e10cSrcweir		$referencedbname = $installdir . $installer::globals::separator . $referencedbname;
1003cdf0e10cSrcweir
1004cdf0e10cSrcweir		my $transformfile = $installdir . $installer::globals::separator . "trans_" . $onelanguage . ".mst";
1005cdf0e10cSrcweir
1006cdf0e10cSrcweir		my $systemcall = $msitran . " " . " -g " . $basedbname . " " . $referencedbname . " " . $transformfile . " " . $errorhandling;
1007cdf0e10cSrcweir
1008cdf0e10cSrcweir		my $returnvalue = system($systemcall);
1009cdf0e10cSrcweir
1010cdf0e10cSrcweir		my $infoline = "Systemcall: $systemcall\n";
1011cdf0e10cSrcweir		push( @installer::globals::logfileinfo, $infoline);
1012cdf0e10cSrcweir
1013cdf0e10cSrcweir		# Problem: msitran.exe in version 4.0 always returns "1", even if no failure occured.
1014cdf0e10cSrcweir		# Therefore it has to be checked, if this is version 4.0. If yes, if the mst file
1015cdf0e10cSrcweir		# exists and if it is larger than 0 bytes. If this is true, then no error occured.
1016cdf0e10cSrcweir		# File Version of msitran.exe: 4.0.6000.16384 has checksum: "b66190a70145a57773ec769e16777b29".
1017cdf0e10cSrcweir		# Same for msitran.exe from wntmsci12: "aa25d3445b94ffde8ef0c1efb77a56b8"
1018cdf0e10cSrcweir
1019cdf0e10cSrcweir		if ($returnvalue)
1020cdf0e10cSrcweir		{
1021cdf0e10cSrcweir			$infoline = "WARNING: Returnvalue of $msitran is not 0. Checking version of $msitran!\n";
1022cdf0e10cSrcweir			push( @installer::globals::logfileinfo, $infoline);
1023cdf0e10cSrcweir
1024cdf0e10cSrcweir			open(FILE, "<$installer::globals::msitranpath") or die "ERROR: Can't open $installer::globals::msitranpath for creating file hash";
1025cdf0e10cSrcweir			binmode(FILE);
1026cdf0e10cSrcweir			my $digest = Digest::MD5->new->addfile(*FILE)->hexdigest;
1027cdf0e10cSrcweir			close(FILE);
1028cdf0e10cSrcweir
1029cdf0e10cSrcweir			my @problemchecksums = ("b66190a70145a57773ec769e16777b29", "aa25d3445b94ffde8ef0c1efb77a56b8");
1030cdf0e10cSrcweir			my $isproblemchecksum = 0;
1031cdf0e10cSrcweir
1032cdf0e10cSrcweir			foreach my $problemchecksum ( @problemchecksums )
1033cdf0e10cSrcweir			{
1034cdf0e10cSrcweir				$infoline = "Checksum of problematic MsiTran.exe: $problemchecksum\n";
1035cdf0e10cSrcweir				push( @installer::globals::logfileinfo, $infoline);
1036cdf0e10cSrcweir				$infoline = "Checksum of used MsiTran.exe: $digest\n";
1037cdf0e10cSrcweir				push( @installer::globals::logfileinfo, $infoline);
1038cdf0e10cSrcweir				if ( $digest eq $problemchecksum ) { $isproblemchecksum = 1; }
1039cdf0e10cSrcweir			}
1040cdf0e10cSrcweir
1041cdf0e10cSrcweir			if ( $isproblemchecksum )
1042cdf0e10cSrcweir			{
1043cdf0e10cSrcweir				# Check existence of mst
1044cdf0e10cSrcweir				if ( -f $transformfile )
1045cdf0e10cSrcweir				{
1046cdf0e10cSrcweir					$infoline = "File $transformfile exists.\n";
1047cdf0e10cSrcweir					push( @installer::globals::logfileinfo, $infoline);
1048cdf0e10cSrcweir					my $filesize = ( -s $transformfile );
1049cdf0e10cSrcweir					$infoline = "Size of $transformfile: $filesize\n";
1050cdf0e10cSrcweir					push( @installer::globals::logfileinfo, $infoline);
1051cdf0e10cSrcweir
1052cdf0e10cSrcweir					if ( $filesize > 0 )
1053cdf0e10cSrcweir					{
1054cdf0e10cSrcweir						$infoline = "Info: Returnvalue $returnvalue of $msitran is no problem :-) .\n";
1055cdf0e10cSrcweir						push( @installer::globals::logfileinfo, $infoline);
1056cdf0e10cSrcweir						$returnvalue = 0; # reset the error
1057cdf0e10cSrcweir					}
1058cdf0e10cSrcweir					else
1059cdf0e10cSrcweir					{
1060cdf0e10cSrcweir						$infoline = "Filesize indicates that an error occured.\n";
1061cdf0e10cSrcweir						push( @installer::globals::logfileinfo, $infoline);
1062cdf0e10cSrcweir					}
1063cdf0e10cSrcweir				}
1064cdf0e10cSrcweir				else
1065cdf0e10cSrcweir				{
1066cdf0e10cSrcweir					$infoline = "File $transformfile does not exist -> An error occured.\n";
1067cdf0e10cSrcweir					push( @installer::globals::logfileinfo, $infoline);
1068cdf0e10cSrcweir				}
1069cdf0e10cSrcweir			}
1070cdf0e10cSrcweir			else
1071cdf0e10cSrcweir			{
1072cdf0e10cSrcweir				$infoline = "This is not a problematic version of msitran.exe. Therefore the error is not caused by problematic msitran.exe.\n";
1073cdf0e10cSrcweir				push( @installer::globals::logfileinfo, $infoline);
1074cdf0e10cSrcweir			}
1075cdf0e10cSrcweir		}
1076cdf0e10cSrcweir
1077cdf0e10cSrcweir		if ($returnvalue)
1078cdf0e10cSrcweir		{
1079cdf0e10cSrcweir			$infoline = "ERROR: Could not execute $msitran!\n";
1080cdf0e10cSrcweir			push( @installer::globals::logfileinfo, $infoline);
1081cdf0e10cSrcweir		}
1082cdf0e10cSrcweir		else
1083cdf0e10cSrcweir		{
1084cdf0e10cSrcweir			$infoline = "Success: Executed $msitran successfully!\n";
1085cdf0e10cSrcweir			push( @installer::globals::logfileinfo, $infoline);
1086cdf0e10cSrcweir		}
1087cdf0e10cSrcweir
1088cdf0e10cSrcweir		# The reference database can be deleted
1089cdf0e10cSrcweir
1090cdf0e10cSrcweir		my $result = unlink($referencedbname);
1091cdf0e10cSrcweir		# $result contains the number of deleted files
1092cdf0e10cSrcweir
1093cdf0e10cSrcweir		if ( $result == 0 )
1094cdf0e10cSrcweir		{
1095cdf0e10cSrcweir			$infoline = "ERROR: Could not remove file $$referencedbname !\n";
1096cdf0e10cSrcweir			push( @installer::globals::logfileinfo, $infoline);
1097cdf0e10cSrcweir			installer::exiter::exit_program($infoline, "create_transforms");
1098cdf0e10cSrcweir		}
1099cdf0e10cSrcweir	}
1100cdf0e10cSrcweir}
1101cdf0e10cSrcweir
1102cdf0e10cSrcweir#########################################################################
1103cdf0e10cSrcweir# The default language msi database does not need to contain
1104cdf0e10cSrcweir# the language in the database name. Therefore the file
1105cdf0e10cSrcweir# is renamed. Example: "openofficeorg20_01.msi" to "openofficeorg20.msi"
1106cdf0e10cSrcweir#########################################################################
1107cdf0e10cSrcweir
1108cdf0e10cSrcweirsub rename_msi_database_in_installset
1109cdf0e10cSrcweir{
1110cdf0e10cSrcweir	my ($defaultlanguage, $installdir, $allvariableshashref) = @_;
1111cdf0e10cSrcweir
1112cdf0e10cSrcweir	installer::logger::include_header_into_logfile("Renaming msi database");
1113cdf0e10cSrcweir
1114cdf0e10cSrcweir	my $olddatabasename = get_msidatabasename($allvariableshashref, $defaultlanguage);
1115cdf0e10cSrcweir	$olddatabasename = $installdir . $installer::globals::separator . $olddatabasename;
1116cdf0e10cSrcweir
1117cdf0e10cSrcweir	my $newdatabasename = get_msidatabasename($allvariableshashref);
1118cdf0e10cSrcweir
1119cdf0e10cSrcweir	$installer::globals::shortmsidatabasename = $newdatabasename;
1120cdf0e10cSrcweir
1121cdf0e10cSrcweir	$newdatabasename = $installdir . $installer::globals::separator . $newdatabasename;
1122cdf0e10cSrcweir
1123cdf0e10cSrcweir	installer::systemactions::rename_one_file($olddatabasename, $newdatabasename);
1124cdf0e10cSrcweir
1125cdf0e10cSrcweir	$installer::globals::msidatabasename = $newdatabasename;
1126cdf0e10cSrcweir}
1127cdf0e10cSrcweir
1128cdf0e10cSrcweir#########################################################################
1129cdf0e10cSrcweir# Adding the language to the name of the msi databasename,
1130cdf0e10cSrcweir# if this is required (ADDLANGUAGEINDATABASENAME)
1131cdf0e10cSrcweir#########################################################################
1132cdf0e10cSrcweir
1133cdf0e10cSrcweirsub add_language_to_msi_database
1134cdf0e10cSrcweir{
1135cdf0e10cSrcweir	my ($defaultlanguage, $installdir, $allvariables) = @_;
1136cdf0e10cSrcweir
1137cdf0e10cSrcweir	my $languagestring = $defaultlanguage;
1138cdf0e10cSrcweir	if ( $allvariables->{'USELANGUAGECODE'} ) { $languagestring = installer::windows::language::get_windows_language($defaultlanguage); }
1139cdf0e10cSrcweir	my $newdatabasename = $installer::globals::shortmsidatabasename;
1140cdf0e10cSrcweir	$newdatabasename =~ s/\.msi\s*$/_$languagestring\.msi/;
1141cdf0e10cSrcweir	$installer::globals::shortmsidatabasename = $newdatabasename;
1142cdf0e10cSrcweir	$newdatabasename = $installdir . $installer::globals::separator . $newdatabasename;
1143cdf0e10cSrcweir
1144cdf0e10cSrcweir	my $olddatabasename = $installer::globals::msidatabasename;
1145cdf0e10cSrcweir
1146cdf0e10cSrcweir	installer::systemactions::rename_one_file($olddatabasename, $newdatabasename);
1147cdf0e10cSrcweir
1148cdf0e10cSrcweir	$installer::globals::msidatabasename = $newdatabasename;
1149cdf0e10cSrcweir}
1150cdf0e10cSrcweir
1151cdf0e10cSrcweir##########################################################################
1152cdf0e10cSrcweir# Writing the databasename into the setup.ini.
1153cdf0e10cSrcweir##########################################################################
1154cdf0e10cSrcweir
1155cdf0e10cSrcweirsub put_databasename_into_setupini
1156cdf0e10cSrcweir{
1157cdf0e10cSrcweir	my ($setupinifile, $allvariableshashref) = @_;
1158cdf0e10cSrcweir
1159cdf0e10cSrcweir	my $databasename = get_msidatabasename($allvariableshashref);
1160cdf0e10cSrcweir	my $line = "database=" . $databasename . "\n";
1161cdf0e10cSrcweir
1162cdf0e10cSrcweir	push(@{$setupinifile}, $line);
1163cdf0e10cSrcweir}
1164cdf0e10cSrcweir
1165cdf0e10cSrcweir##########################################################################
1166cdf0e10cSrcweir# Writing the required msi version into setup.ini
1167cdf0e10cSrcweir##########################################################################
1168cdf0e10cSrcweir
1169cdf0e10cSrcweirsub put_msiversion_into_setupini
1170cdf0e10cSrcweir{
1171cdf0e10cSrcweir	my ($setupinifile) = @_;
1172cdf0e10cSrcweir
1173cdf0e10cSrcweir	my $msiversion = "2.0";
1174cdf0e10cSrcweir	my $line = "msiversion=" . $msiversion . "\n";
1175cdf0e10cSrcweir
1176cdf0e10cSrcweir	push(@{$setupinifile}, $line);
1177cdf0e10cSrcweir}
1178cdf0e10cSrcweir
1179cdf0e10cSrcweir##########################################################################
1180cdf0e10cSrcweir# Writing the productname into setup.ini
1181cdf0e10cSrcweir##########################################################################
1182cdf0e10cSrcweir
1183cdf0e10cSrcweirsub put_productname_into_setupini
1184cdf0e10cSrcweir{
1185cdf0e10cSrcweir	my ($setupinifile, $allvariableshashref) = @_;
1186cdf0e10cSrcweir
1187cdf0e10cSrcweir	my $productname = $allvariableshashref->{'PRODUCTNAME'};
1188cdf0e10cSrcweir	my $line = "productname=" . $productname . "\n";
1189cdf0e10cSrcweir
1190cdf0e10cSrcweir	push(@{$setupinifile}, $line);
1191cdf0e10cSrcweir}
1192cdf0e10cSrcweir
1193cdf0e10cSrcweir##########################################################################
1194cdf0e10cSrcweir# Writing the productcode into setup.ini
1195cdf0e10cSrcweir##########################################################################
1196cdf0e10cSrcweir
1197cdf0e10cSrcweirsub put_productcode_into_setupini
1198cdf0e10cSrcweir{
1199cdf0e10cSrcweir	my ($setupinifile) = @_;
1200cdf0e10cSrcweir
1201cdf0e10cSrcweir	my $productcode = $installer::globals::productcode;
1202cdf0e10cSrcweir	my $line = "productcode=" . $productcode . "\n";
1203cdf0e10cSrcweir
1204cdf0e10cSrcweir	push(@{$setupinifile}, $line);
1205cdf0e10cSrcweir}
1206cdf0e10cSrcweir
1207cdf0e10cSrcweir##########################################################################
1208cdf0e10cSrcweir# Writing the ProductVersion from Property table into setup.ini
1209cdf0e10cSrcweir##########################################################################
1210cdf0e10cSrcweir
1211cdf0e10cSrcweirsub put_productversion_into_setupini
1212cdf0e10cSrcweir{
1213cdf0e10cSrcweir	my ($setupinifile) = @_;
1214cdf0e10cSrcweir
1215cdf0e10cSrcweir	my $line = "productversion=" . $installer::globals::msiproductversion . "\n";
1216cdf0e10cSrcweir	push(@{$setupinifile}, $line);
1217cdf0e10cSrcweir}
1218cdf0e10cSrcweir
1219cdf0e10cSrcweir##########################################################################
1220cdf0e10cSrcweir# Writing the key for Minor Upgrades into setup.ini
1221cdf0e10cSrcweir##########################################################################
1222cdf0e10cSrcweir
1223cdf0e10cSrcweirsub put_upgradekey_into_setupini
1224cdf0e10cSrcweir{
1225cdf0e10cSrcweir	my ($setupinifile) = @_;
1226cdf0e10cSrcweir
1227cdf0e10cSrcweir	if ( $installer::globals::minorupgradekey ne "" )
1228cdf0e10cSrcweir	{
1229cdf0e10cSrcweir		my $line = "upgradekey=" . $installer::globals::minorupgradekey . "\n";
1230cdf0e10cSrcweir		push(@{$setupinifile}, $line);
1231cdf0e10cSrcweir	}
1232cdf0e10cSrcweir}
1233cdf0e10cSrcweir
1234cdf0e10cSrcweir##########################################################################
1235cdf0e10cSrcweir# Writing the number of languages into setup.ini
1236cdf0e10cSrcweir##########################################################################
1237cdf0e10cSrcweir
1238cdf0e10cSrcweirsub put_languagecount_into_setupini
1239cdf0e10cSrcweir{
1240cdf0e10cSrcweir	my ($setupinifile, $languagesarray) = @_;
1241cdf0e10cSrcweir
1242cdf0e10cSrcweir	my $languagecount = $#{$languagesarray} + 1;
1243cdf0e10cSrcweir	my $line = "count=" . $languagecount . "\n";
1244cdf0e10cSrcweir
1245cdf0e10cSrcweir	push(@{$setupinifile}, $line);
1246cdf0e10cSrcweir}
1247cdf0e10cSrcweir
1248cdf0e10cSrcweir##########################################################################
1249cdf0e10cSrcweir# Writing the defaultlanguage into setup.ini
1250cdf0e10cSrcweir##########################################################################
1251cdf0e10cSrcweir
1252cdf0e10cSrcweirsub put_defaultlanguage_into_setupini
1253cdf0e10cSrcweir{
1254cdf0e10cSrcweir	my ($setupinifile, $defaultlanguage) = @_;
1255cdf0e10cSrcweir
1256cdf0e10cSrcweir	my $windowslanguage = installer::windows::language::get_windows_language($defaultlanguage);
1257cdf0e10cSrcweir	my $line = "default=" . $windowslanguage . "\n";
1258cdf0e10cSrcweir	push(@{$setupinifile}, $line);
1259cdf0e10cSrcweir}
1260cdf0e10cSrcweir
1261cdf0e10cSrcweir##########################################################################
1262cdf0e10cSrcweir# Writing the information about transformations into setup.ini
1263cdf0e10cSrcweir##########################################################################
1264cdf0e10cSrcweir
1265cdf0e10cSrcweirsub put_transforms_into_setupini
1266cdf0e10cSrcweir{
1267cdf0e10cSrcweir	my ($setupinifile, $onelanguage, $counter) = @_;
1268cdf0e10cSrcweir
1269cdf0e10cSrcweir	my $windowslanguage = installer::windows::language::get_windows_language($onelanguage);
1270cdf0e10cSrcweir	my $transformfilename = "trans_" . $onelanguage . ".mst";
1271cdf0e10cSrcweir
1272cdf0e10cSrcweir	my $line = "lang" . $counter . "=" . $windowslanguage . "," . $transformfilename . "\n";
1273cdf0e10cSrcweir
1274cdf0e10cSrcweir	push(@{$setupinifile}, $line);
1275cdf0e10cSrcweir}
1276cdf0e10cSrcweir
1277cdf0e10cSrcweir###################################################
1278cdf0e10cSrcweir# Including Windows line ends in ini files
1279cdf0e10cSrcweir# Profiles on Windows shall have \r\n line ends
1280cdf0e10cSrcweir###################################################
1281cdf0e10cSrcweir
1282cdf0e10cSrcweirsub include_windows_lineends
1283cdf0e10cSrcweir{
1284cdf0e10cSrcweir	my ($onefile) = @_;
1285cdf0e10cSrcweir
1286cdf0e10cSrcweir	for ( my $i = 0; $i <= $#{$onefile}; $i++ )
1287cdf0e10cSrcweir	{
1288cdf0e10cSrcweir		${$onefile}[$i] =~ s/\r?\n$/\r\n/;
1289cdf0e10cSrcweir	}
1290cdf0e10cSrcweir}
1291cdf0e10cSrcweir
1292cdf0e10cSrcweir##########################################################################
1293cdf0e10cSrcweir# Generation the file setup.ini, that is used by the loader setup.exe.
1294cdf0e10cSrcweir##########################################################################
1295cdf0e10cSrcweir
1296cdf0e10cSrcweirsub create_setup_ini
1297cdf0e10cSrcweir{
1298cdf0e10cSrcweir	my ($languagesarray, $defaultlanguage, $installdir, $allvariableshashref) = @_;
1299cdf0e10cSrcweir
1300cdf0e10cSrcweir	installer::logger::include_header_into_logfile("Creating setup.ini");
1301cdf0e10cSrcweir
1302cdf0e10cSrcweir	my $setupinifilename = $installdir . $installer::globals::separator . "setup.ini";
1303cdf0e10cSrcweir
1304cdf0e10cSrcweir	my @setupinifile = ();
1305cdf0e10cSrcweir	my $setupinifile = \@setupinifile;
1306cdf0e10cSrcweir
1307cdf0e10cSrcweir	my $line = "\[setup\]\n";
1308cdf0e10cSrcweir	push(@setupinifile, $line);
1309cdf0e10cSrcweir
1310cdf0e10cSrcweir	put_databasename_into_setupini($setupinifile, $allvariableshashref);
1311cdf0e10cSrcweir	put_msiversion_into_setupini($setupinifile);
1312cdf0e10cSrcweir	put_productname_into_setupini($setupinifile, $allvariableshashref);
1313cdf0e10cSrcweir	put_productcode_into_setupini($setupinifile);
1314cdf0e10cSrcweir	put_productversion_into_setupini($setupinifile);
1315cdf0e10cSrcweir	put_upgradekey_into_setupini($setupinifile);
1316cdf0e10cSrcweir
1317cdf0e10cSrcweir	$line = "\[languages\]\n";
1318cdf0e10cSrcweir	push(@setupinifile, $line);
1319cdf0e10cSrcweir
1320cdf0e10cSrcweir	put_languagecount_into_setupini($setupinifile, $languagesarray);
1321cdf0e10cSrcweir	put_defaultlanguage_into_setupini($setupinifile, $defaultlanguage);
1322cdf0e10cSrcweir
1323cdf0e10cSrcweir	if ( $#{$languagesarray} > 0 )	# writing the transforms information
1324cdf0e10cSrcweir	{
1325cdf0e10cSrcweir		my $counter = 1;
1326cdf0e10cSrcweir
1327cdf0e10cSrcweir		for ( my $i = 0; $i <= $#{$languagesarray}; $i++ )
1328cdf0e10cSrcweir		{
1329cdf0e10cSrcweir			if ( ${$languagesarray}[$i] eq $defaultlanguage ) { next; }
1330cdf0e10cSrcweir
1331cdf0e10cSrcweir			put_transforms_into_setupini($setupinifile, ${$languagesarray}[$i], $counter);
1332cdf0e10cSrcweir			$counter++;
1333cdf0e10cSrcweir		}
1334cdf0e10cSrcweir	}
1335cdf0e10cSrcweir
1336cdf0e10cSrcweir	if ( $installer::globals::iswin && $installer::globals::plat =~ /cygwin/i)		# Windows line ends only for Cygwin
1337cdf0e10cSrcweir	{
1338cdf0e10cSrcweir		include_windows_lineends($setupinifile);
1339cdf0e10cSrcweir	}
1340cdf0e10cSrcweir
1341cdf0e10cSrcweir	installer::files::save_file($setupinifilename, $setupinifile);
1342cdf0e10cSrcweir
1343cdf0e10cSrcweir	$infoline = "Generated file $setupinifilename !\n";
1344cdf0e10cSrcweir	push( @installer::globals::logfileinfo, $infoline);
1345cdf0e10cSrcweir}
1346cdf0e10cSrcweir
1347cdf0e10cSrcweir#################################################################
1348cdf0e10cSrcweir# Copying the files defined as ScpActions into the
1349cdf0e10cSrcweir# installation set.
1350cdf0e10cSrcweir#################################################################
1351cdf0e10cSrcweir
1352cdf0e10cSrcweirsub copy_scpactions_into_installset
1353cdf0e10cSrcweir{
1354cdf0e10cSrcweir	my ($defaultlanguage, $installdir, $allscpactions) = @_;
1355cdf0e10cSrcweir
1356cdf0e10cSrcweir	installer::logger::include_header_into_logfile("Copying ScpAction files into installation set");
1357cdf0e10cSrcweir
1358cdf0e10cSrcweir	for ( my $i = 0; $i <= $#{$allscpactions}; $i++ )
1359cdf0e10cSrcweir	{
1360cdf0e10cSrcweir		my $onescpaction = ${$allscpactions}[$i];
1361cdf0e10cSrcweir
1362cdf0e10cSrcweir		if ( $onescpaction->{'Name'} eq "loader.exe" ) { next; }	# do not copy this ScpAction loader
1363cdf0e10cSrcweir
1364cdf0e10cSrcweir		# only copying language independent files or files with the correct language (the defaultlanguage)
1365cdf0e10cSrcweir
1366cdf0e10cSrcweir		my $filelanguage = $onescpaction->{'specificlanguage'};
1367cdf0e10cSrcweir
1368cdf0e10cSrcweir		if ( ($filelanguage eq $defaultlanguage) || ($filelanguage eq "") )
1369cdf0e10cSrcweir		{
1370cdf0e10cSrcweir			my $sourcefile = $onescpaction->{'sourcepath'};
1371cdf0e10cSrcweir			my $destfile = $installdir . $installer::globals::separator . $onescpaction->{'DestinationName'};
1372cdf0e10cSrcweir
1373cdf0e10cSrcweir			installer::systemactions::copy_one_file($sourcefile, $destfile);
1374cdf0e10cSrcweir		}
1375cdf0e10cSrcweir	}
1376cdf0e10cSrcweir}
1377cdf0e10cSrcweir
1378cdf0e10cSrcweir#################################################################
1379cdf0e10cSrcweir# Copying the files for the Windows installer into the
1380cdf0e10cSrcweir# installation set (setup.exe).
1381cdf0e10cSrcweir#################################################################
1382cdf0e10cSrcweir
1383cdf0e10cSrcweirsub copy_windows_installer_files_into_installset
1384cdf0e10cSrcweir{
1385cdf0e10cSrcweir	my ($installdir, $includepatharrayref, $allvariables) = @_;
1386cdf0e10cSrcweir
1387cdf0e10cSrcweir    installer::logger::include_header_into_logfile("Copying Windows installer files into installation set");
1388cdf0e10cSrcweir
1389cdf0e10cSrcweir	@copyfile = ();
1390cdf0e10cSrcweir	push(@copyfile, "loader2.exe");
1391cdf0e10cSrcweir
1392cdf0e10cSrcweir	if ( $allvariables->{'NOLOADERREQUIRED'} ) { @copyfile = (); }
1393cdf0e10cSrcweir
1394cdf0e10cSrcweir	for ( my $i = 0; $i <= $#copyfile; $i++ )
1395cdf0e10cSrcweir	{
1396cdf0e10cSrcweir		my $filename = $copyfile[$i];
1397cdf0e10cSrcweir		my $sourcefileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$filename, $includepatharrayref, 1);
1398cdf0e10cSrcweir
1399cdf0e10cSrcweir		if ( ! -f $$sourcefileref ) { installer::exiter::exit_program("ERROR: msi file not found: $$sourcefileref !", "copy_windows_installer_files_into_installset"); }
1400cdf0e10cSrcweir
1401cdf0e10cSrcweir		my $destfile;
1402cdf0e10cSrcweir		if ( $copyfile[$i] eq "loader2.exe" ) { $destfile = "setup.exe"; }	# renaming the loader
1403cdf0e10cSrcweir		else { $destfile = $copyfile[$i]; }
1404cdf0e10cSrcweir
1405cdf0e10cSrcweir		$destfile = $installdir . $installer::globals::separator . $destfile;
1406cdf0e10cSrcweir
1407cdf0e10cSrcweir		installer::systemactions::copy_one_file($$sourcefileref, $destfile);
1408cdf0e10cSrcweir	}
1409cdf0e10cSrcweir}
1410cdf0e10cSrcweir
1411cdf0e10cSrcweir#################################################################
1412cdf0e10cSrcweir# Copying MergeModules for the Windows installer into the
1413cdf0e10cSrcweir# installation set. The list of MergeModules is located
1414cdf0e10cSrcweir# in %installer::globals::copy_msm_files
1415cdf0e10cSrcweir#################################################################
1416cdf0e10cSrcweir
1417cdf0e10cSrcweirsub copy_merge_modules_into_installset
1418cdf0e10cSrcweir{
1419cdf0e10cSrcweir	my ($installdir) = @_;
1420cdf0e10cSrcweir
1421cdf0e10cSrcweir	installer::logger::include_header_into_logfile("Copying Merge files into installation set");
1422cdf0e10cSrcweir
1423cdf0e10cSrcweir	my $cabfile;
1424cdf0e10cSrcweir	foreach $cabfile ( keys  %installer::globals::copy_msm_files )
1425cdf0e10cSrcweir	{
1426cdf0e10cSrcweir		my $sourcefile  = $installer::globals::copy_msm_files{$cabfile};
1427cdf0e10cSrcweir		my $destfile = $installdir . $installer::globals::separator . $cabfile;
1428cdf0e10cSrcweir
1429cdf0e10cSrcweir		installer::systemactions::copy_one_file($sourcefile, $destfile);
1430cdf0e10cSrcweir	}
1431cdf0e10cSrcweir}
1432cdf0e10cSrcweir
1433cdf0e10cSrcweir#################################################################
1434cdf0e10cSrcweir# Copying the child projects into the
1435cdf0e10cSrcweir# installation set
1436cdf0e10cSrcweir#################################################################
1437cdf0e10cSrcweir
1438cdf0e10cSrcweirsub copy_child_projects_into_installset
1439cdf0e10cSrcweir{
1440cdf0e10cSrcweir	my ($installdir, $allvariables) = @_;
1441cdf0e10cSrcweir
1442cdf0e10cSrcweir	my $sourcefile = "";
1443cdf0e10cSrcweir	my $destdir = "";
1444cdf0e10cSrcweir
1445cdf0e10cSrcweir	# adding Java
1446cdf0e10cSrcweir
1447cdf0e10cSrcweir	if ( $allvariables->{'JAVAPRODUCT'} )
1448cdf0e10cSrcweir	{
1449cdf0e10cSrcweir		$sourcefile = $installer::globals::javafile->{'sourcepath'};
1450cdf0e10cSrcweir		$destdir = $installdir . $installer::globals::separator . $installer::globals::javafile->{'Subdir'};
1451cdf0e10cSrcweir		if ( ! -d $destdir) { installer::systemactions::create_directory($destdir); }
1452cdf0e10cSrcweir		installer::systemactions::copy_one_file($sourcefile, $destdir);
1453cdf0e10cSrcweir	}
1454cdf0e10cSrcweir
1455cdf0e10cSrcweir	if ( $allvariables->{'UREPRODUCT'} )
1456cdf0e10cSrcweir	{
1457cdf0e10cSrcweir		$sourcefile = $installer::globals::urefile->{'sourcepath'};
1458cdf0e10cSrcweir		$destdir = $installdir . $installer::globals::separator . $installer::globals::urefile->{'Subdir'};
1459cdf0e10cSrcweir		if ( ! -d $destdir) { installer::systemactions::create_directory($destdir); }
1460cdf0e10cSrcweir		installer::systemactions::copy_one_file($sourcefile, $destdir);
1461cdf0e10cSrcweir	}
1462cdf0e10cSrcweir}
1463cdf0e10cSrcweir
1464cdf0e10cSrcweir#################################################################
1465cdf0e10cSrcweir# Getting a list of GUID using uuidgen.exe.
1466cdf0e10cSrcweir# This works only on Windows
1467cdf0e10cSrcweir#################################################################
1468cdf0e10cSrcweir
1469cdf0e10cSrcweirsub get_guid_list
1470cdf0e10cSrcweir{
1471cdf0e10cSrcweir	my ($number, $log) = @_;
1472cdf0e10cSrcweir
1473cdf0e10cSrcweir	if ( $log ) { installer::logger::include_header_into_logfile("Generating $number GUID"); }
1474cdf0e10cSrcweir
1475cdf0e10cSrcweir	my $uuidgen = "uuidgen.exe";		# Has to be in the path
1476cdf0e10cSrcweir
1477cdf0e10cSrcweir	# "-c" for uppercase output
1478cdf0e10cSrcweir
1479cdf0e10cSrcweir	# my $systemcall = "$uuidgen -n$number -c |";
1480cdf0e10cSrcweir	my $systemcall = "$uuidgen -n$number |";
1481cdf0e10cSrcweir	open (UUIDGEN, "$systemcall" ) or die("uuidgen is missing.");
1482cdf0e10cSrcweir	my @uuidlist = <UUIDGEN>;
1483cdf0e10cSrcweir	close (UUIDGEN);
1484cdf0e10cSrcweir
1485cdf0e10cSrcweir	my $infoline = "Systemcall: $systemcall\n";
1486cdf0e10cSrcweir	if ( $log ) { push( @installer::globals::logfileinfo, $infoline); }
1487cdf0e10cSrcweir
1488cdf0e10cSrcweir	my $comparenumber = $#uuidlist + 1;
1489cdf0e10cSrcweir
1490cdf0e10cSrcweir	if ( $comparenumber == $number )
1491cdf0e10cSrcweir	{
1492cdf0e10cSrcweir		$infoline = "Success: Executed $uuidgen successfully!\n";
1493cdf0e10cSrcweir		if ( $log ) { push( @installer::globals::logfileinfo, $infoline); }
1494cdf0e10cSrcweir	}
1495cdf0e10cSrcweir	else
1496cdf0e10cSrcweir	{
1497cdf0e10cSrcweir		$infoline = "ERROR: Could not execute $uuidgen successfully!\n";
1498cdf0e10cSrcweir		if ( $log ) { push( @installer::globals::logfileinfo, $infoline); }
1499cdf0e10cSrcweir	}
1500cdf0e10cSrcweir
1501cdf0e10cSrcweir	# uppercase, no longer "-c", because this is only supported in uuidgen.exe v.1.01
1502cdf0e10cSrcweir	for ( my $i = 0; $i <= $#uuidlist; $i++ ) { $uuidlist[$i] = uc($uuidlist[$i]); }
1503cdf0e10cSrcweir
1504cdf0e10cSrcweir	return \@uuidlist;
1505cdf0e10cSrcweir}
1506cdf0e10cSrcweir
1507cdf0e10cSrcweir#################################################################
1508cdf0e10cSrcweir# Calculating a GUID with a string using md5.
1509cdf0e10cSrcweir#################################################################
1510cdf0e10cSrcweir
1511cdf0e10cSrcweirsub calculate_guid
1512cdf0e10cSrcweir{
1513cdf0e10cSrcweir	my ( $string ) = @_;
1514cdf0e10cSrcweir
1515cdf0e10cSrcweir	my $guid = "";
1516cdf0e10cSrcweir
1517cdf0e10cSrcweir    my $md5 = Digest::MD5->new;
1518cdf0e10cSrcweir    $md5->add($string);
1519cdf0e10cSrcweir    my $digest = $md5->hexdigest;
1520cdf0e10cSrcweir    $digest = uc($digest);
1521cdf0e10cSrcweir
1522cdf0e10cSrcweir	# my $id = pack("A32", $digest);
1523cdf0e10cSrcweir	my ($first, $second, $third, $fourth, $fifth) = unpack ('A8 A4 A4 A4 A12', $digest);
1524cdf0e10cSrcweir	$guid = "$first-$second-$third-$fourth-$fifth";
1525cdf0e10cSrcweir
1526cdf0e10cSrcweir	return $guid;
1527cdf0e10cSrcweir}
1528cdf0e10cSrcweir
1529*19d58b3aSEike Rathke#################################################################
1530*19d58b3aSEike Rathke# Calculating a ID with a string using md5 (very fast).
1531*19d58b3aSEike Rathke#################################################################
1532*19d58b3aSEike Rathke
1533*19d58b3aSEike Rathkesub calculate_id
1534*19d58b3aSEike Rathke{
1535*19d58b3aSEike Rathke	my ( $string, $length ) = @_;
1536*19d58b3aSEike Rathke
1537*19d58b3aSEike Rathke	my $id = "";
1538*19d58b3aSEike Rathke
1539*19d58b3aSEike Rathke    my $md5 = Digest::MD5->new;
1540*19d58b3aSEike Rathke    $md5->add($string);
1541*19d58b3aSEike Rathke    my $digest = lc($md5->hexdigest);
1542*19d58b3aSEike Rathke	$id = substr($digest, 0, $length);
1543*19d58b3aSEike Rathke
1544*19d58b3aSEike Rathke	return $id;
1545*19d58b3aSEike Rathke}
1546*19d58b3aSEike Rathke
1547cdf0e10cSrcweir#################################################################
1548cdf0e10cSrcweir# Filling the component hash with the values of the
1549cdf0e10cSrcweir# component file.
1550cdf0e10cSrcweir#################################################################
1551cdf0e10cSrcweir
1552cdf0e10cSrcweirsub fill_component_hash
1553cdf0e10cSrcweir{
1554cdf0e10cSrcweir	my ($componentfile) = @_;
1555cdf0e10cSrcweir
1556cdf0e10cSrcweir	my %components = ();
1557cdf0e10cSrcweir
1558cdf0e10cSrcweir	for ( my $i = 0; $i <= $#{$componentfile}; $i++ )
1559cdf0e10cSrcweir	{
1560cdf0e10cSrcweir		my $line = ${$componentfile}[$i];
1561cdf0e10cSrcweir
1562cdf0e10cSrcweir		if ( $line =~ /^\s*(.*?)\t(.*?)\s*$/ )
1563cdf0e10cSrcweir		{
1564cdf0e10cSrcweir			my $key = $1;
1565cdf0e10cSrcweir			my $value = $2;
1566cdf0e10cSrcweir
1567cdf0e10cSrcweir			$components{$key} = $value;
1568cdf0e10cSrcweir		}
1569cdf0e10cSrcweir	}
1570cdf0e10cSrcweir
1571cdf0e10cSrcweir	return \%components;
1572cdf0e10cSrcweir}
1573cdf0e10cSrcweir
1574cdf0e10cSrcweir#################################################################
1575cdf0e10cSrcweir# Creating a new component file, if new guids were generated.
1576cdf0e10cSrcweir#################################################################
1577cdf0e10cSrcweir
1578cdf0e10cSrcweirsub create_new_component_file
1579cdf0e10cSrcweir{
1580cdf0e10cSrcweir	my ($componenthash) = @_;
1581cdf0e10cSrcweir
1582cdf0e10cSrcweir	my @componentfile = ();
1583cdf0e10cSrcweir
1584cdf0e10cSrcweir	my $key;
1585cdf0e10cSrcweir
1586cdf0e10cSrcweir	foreach $key (keys %{$componenthash})
1587cdf0e10cSrcweir	{
1588cdf0e10cSrcweir		my $value = $componenthash->{$key};
1589cdf0e10cSrcweir		my $input = "$key\t$value\n";
1590cdf0e10cSrcweir		push(@componentfile ,$input);
1591cdf0e10cSrcweir	}
1592cdf0e10cSrcweir
1593cdf0e10cSrcweir	return \@componentfile;
1594cdf0e10cSrcweir}
1595cdf0e10cSrcweir
1596cdf0e10cSrcweir#################################################################
1597cdf0e10cSrcweir# Filling real component GUID into the component table.
1598cdf0e10cSrcweir# This works only on Windows
1599cdf0e10cSrcweir#################################################################
1600cdf0e10cSrcweir
1601cdf0e10cSrcweirsub set_uuid_into_component_table
1602cdf0e10cSrcweir{
1603cdf0e10cSrcweir	my ($idtdirbase, $allvariables) = @_;
1604cdf0e10cSrcweir
1605cdf0e10cSrcweir	my $componenttablename  = $idtdirbase . $installer::globals::separator . "Componen.idt";
1606cdf0e10cSrcweir
1607cdf0e10cSrcweir	my $componenttable = installer::files::read_file($componenttablename);
1608cdf0e10cSrcweir
1609cdf0e10cSrcweir	# For update and patch reasons (small update) the GUID of an existing component must not change!
1610cdf0e10cSrcweir	# The collection of component GUIDs is saved in the directory $installer::globals::idttemplatepath in the file "components.txt"
1611cdf0e10cSrcweir
1612cdf0e10cSrcweir	my $infoline = "";
1613cdf0e10cSrcweir	my $counter = 0;
1614cdf0e10cSrcweir	# my $componentfile = installer::files::read_file($installer::globals::componentfilename);
1615cdf0e10cSrcweir	# my $componenthash = fill_component_hash($componentfile);
1616cdf0e10cSrcweir
1617cdf0e10cSrcweir	for ( my $i = 3; $i <= $#{$componenttable}; $i++ )	# ignoring the first three lines
1618cdf0e10cSrcweir	{
1619cdf0e10cSrcweir		my $oneline = ${$componenttable}[$i];
1620cdf0e10cSrcweir		my $componentname = "";
1621cdf0e10cSrcweir		if ( $oneline =~ /^\s*(\S+?)\t/ ) { $componentname = $1; }
1622cdf0e10cSrcweir
1623cdf0e10cSrcweir		my $uuid = "";
1624cdf0e10cSrcweir
1625cdf0e10cSrcweir	#	if ( $componenthash->{$componentname} )
1626cdf0e10cSrcweir	#	{
1627cdf0e10cSrcweir	#		$uuid = $componenthash->{$componentname};
1628cdf0e10cSrcweir	#	}
1629cdf0e10cSrcweir	#	else
1630cdf0e10cSrcweir	#	{
1631cdf0e10cSrcweir
1632cdf0e10cSrcweir			if ( exists($installer::globals::calculated_component_guids{$componentname}))
1633cdf0e10cSrcweir			{
1634cdf0e10cSrcweir				$uuid = $installer::globals::calculated_component_guids{$componentname};
1635cdf0e10cSrcweir			}
1636cdf0e10cSrcweir			else
1637cdf0e10cSrcweir			{
1638cdf0e10cSrcweir				# Calculating new GUID with the help of the component name.
1639cdf0e10cSrcweir				my $useooobaseversion = 1;
1640cdf0e10cSrcweir				if ( exists($installer::globals::base_independent_components{$componentname})) { $useooobaseversion = 0; }
1641cdf0e10cSrcweir				my $sourcestring = $componentname;
1642cdf0e10cSrcweir
1643cdf0e10cSrcweir				if ( $useooobaseversion )
1644cdf0e10cSrcweir				{
1645cdf0e10cSrcweir					if ( ! exists($allvariables->{'OOOBASEVERSION'}) ) { installer::exiter::exit_program("ERROR: Could not find variable \"OOOBASEVERSION\" (required value for GUID creation)!", "set_uuid_into_component_table"); }
1646cdf0e10cSrcweir					$sourcestring = $sourcestring . "_" . $allvariables->{'OOOBASEVERSION'};
1647cdf0e10cSrcweir				}
1648cdf0e10cSrcweir				$uuid = calculate_guid($sourcestring);
1649cdf0e10cSrcweir				$counter++;
1650cdf0e10cSrcweir
1651cdf0e10cSrcweir				# checking, if there is a conflict with an already created guid
1652cdf0e10cSrcweir				if ( exists($installer::globals::allcalculated_guids{$uuid}) ) { installer::exiter::exit_program("ERROR: \"$uuid\" was already created before!", "set_uuid_into_component_table"); }
1653cdf0e10cSrcweir				$installer::globals::allcalculated_guids{$uuid} = 1;
1654cdf0e10cSrcweir				$installer::globals::calculated_component_guids{$componentname} = $uuid;
1655cdf0e10cSrcweir
1656cdf0e10cSrcweir				# Setting new uuid
1657cdf0e10cSrcweir				# $componenthash->{$componentname} = $uuid;
1658cdf0e10cSrcweir
1659cdf0e10cSrcweir				# Setting flag
1660cdf0e10cSrcweir				# $installer::globals::created_new_component_guid = 1;	# this is very important!
1661cdf0e10cSrcweir			}
1662cdf0e10cSrcweir	#	}
1663cdf0e10cSrcweir
1664cdf0e10cSrcweir		${$componenttable}[$i] =~ s/COMPONENTGUID/$uuid/;
1665cdf0e10cSrcweir	}
1666cdf0e10cSrcweir
1667cdf0e10cSrcweir	installer::files::save_file($componenttablename, $componenttable);
1668cdf0e10cSrcweir
1669cdf0e10cSrcweir#	if ( $installer::globals::created_new_component_guid )
1670cdf0e10cSrcweir#	{
1671cdf0e10cSrcweir#		# create new component file!
1672cdf0e10cSrcweir#		$componentfile = create_new_component_file($componenthash);
1673cdf0e10cSrcweir#		installer::worker::sort_array($componentfile);
1674cdf0e10cSrcweir#
1675cdf0e10cSrcweir#		# To avoid conflict the components file cannot be saved at the same place
1676cdf0e10cSrcweir#		# All important data have to be saved in the directory: $installer::globals::infodirectory
1677cdf0e10cSrcweir#		my $localcomponentfilename = $installer::globals::componentfilename;
1678cdf0e10cSrcweir#		installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$localcomponentfilename);
1679cdf0e10cSrcweir#		$localcomponentfilename = $installer::globals::infodirectory . $installer::globals::separator . $localcomponentfilename;
1680cdf0e10cSrcweir#		installer::files::save_file($localcomponentfilename, $componentfile);
1681cdf0e10cSrcweir#
1682cdf0e10cSrcweir#		# installer::files::save_file($installer::globals::componentfilename, $componentfile);	# version using new file in solver
1683cdf0e10cSrcweir#
1684cdf0e10cSrcweir#		$infoline = "COMPONENTCODES: Created $counter new GUIDs for components ! \n";
1685cdf0e10cSrcweir#		push( @installer::globals::logfileinfo, $infoline);
1686cdf0e10cSrcweir#	}
1687cdf0e10cSrcweir#	else
1688cdf0e10cSrcweir#	{
1689cdf0e10cSrcweir#		$infoline = "SUCCESS COMPONENTCODES: All component codes exist! \n";
1690cdf0e10cSrcweir#		push( @installer::globals::logfileinfo, $infoline);
1691cdf0e10cSrcweir#	}
1692cdf0e10cSrcweir
1693cdf0e10cSrcweir}
1694cdf0e10cSrcweir
1695cdf0e10cSrcweir#########################################################################
1696cdf0e10cSrcweir# Adding final 64 properties into msi database, if required.
1697cdf0e10cSrcweir# RegLocator : +16 in type column to search in 64 bit registry.
1698cdf0e10cSrcweir# All conditions: "VersionNT" -> "VersionNT64" (several tables).
1699cdf0e10cSrcweir# Already done: "+256" in Attributes column of table "Component".
1700cdf0e10cSrcweir# Still following: Setting "x64" instead of "Intel" in Summary
1701cdf0e10cSrcweir# Information Stream of msi database in "get_template_for_sis".
1702cdf0e10cSrcweir#########################################################################
1703cdf0e10cSrcweir
1704cdf0e10cSrcweirsub prepare_64bit_database
1705cdf0e10cSrcweir{
1706cdf0e10cSrcweir	my ($basedir, $allvariables) = @_;
1707cdf0e10cSrcweir
1708cdf0e10cSrcweir	my $infoline = "";
1709cdf0e10cSrcweir
1710cdf0e10cSrcweir	if (( $allvariables->{'64BITPRODUCT'} ) && ( $allvariables->{'64BITPRODUCT'} == 1 ))
1711cdf0e10cSrcweir	{
1712cdf0e10cSrcweir		# 1. Beginning with table "RegLocat.idt". Adding "16" to the type.
1713cdf0e10cSrcweir
1714cdf0e10cSrcweir		my $reglocatfile = "";
1715cdf0e10cSrcweir		my $reglocatfilename = $basedir . $installer::globals::separator . "RegLocat.idt";
1716cdf0e10cSrcweir
1717cdf0e10cSrcweir		if ( -f $reglocatfilename )
1718cdf0e10cSrcweir		{
1719cdf0e10cSrcweir			my $saving_required = 0;
1720cdf0e10cSrcweir			$reglocatfile = installer::files::read_file($reglocatfilename);
1721cdf0e10cSrcweir
1722cdf0e10cSrcweir			for ( my $i = 3; $i <= $#{$reglocatfile}; $i++ ) 	# ignoring the first three lines
1723cdf0e10cSrcweir			{
1724cdf0e10cSrcweir				my $oneline = ${$reglocatfile}[$i];
1725cdf0e10cSrcweir
1726cdf0e10cSrcweir				if ( $oneline =~ /^\s*\#/ ) { next; }	# this is a comment line
1727cdf0e10cSrcweir				if ( $oneline =~ /^\s*$/ ) { next; }
1728cdf0e10cSrcweir
1729cdf0e10cSrcweir				if ( $oneline =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(\d+)\s*$/ )
1730cdf0e10cSrcweir				{
1731cdf0e10cSrcweir					# Syntax: Signature_ Root Key Name Type
1732cdf0e10cSrcweir					my $sig = $1;
1733cdf0e10cSrcweir					my $root = $2;
1734cdf0e10cSrcweir					my $key = $3;
1735cdf0e10cSrcweir					my $name = $4;
1736cdf0e10cSrcweir					my $type = $5;
1737cdf0e10cSrcweir
1738cdf0e10cSrcweir					$type = $type + 16;
1739cdf0e10cSrcweir
1740cdf0e10cSrcweir					my $newline = $sig . "\t" . $root . "\t" . $key . "\t" . $name . "\t" . $type . "\n";
1741cdf0e10cSrcweir					${$reglocatfile}[$i] = $newline;
1742cdf0e10cSrcweir
1743cdf0e10cSrcweir					$saving_required = 1;
1744cdf0e10cSrcweir				}
1745cdf0e10cSrcweir			}
1746cdf0e10cSrcweir
1747cdf0e10cSrcweir			if ( $saving_required )
1748cdf0e10cSrcweir			{
1749cdf0e10cSrcweir				# Saving the files
1750cdf0e10cSrcweir				installer::files::save_file($reglocatfilename ,$reglocatfile);
1751cdf0e10cSrcweir				$infoline = "Making idt file 64 bit conform: $reglocatfilename\n";
1752cdf0e10cSrcweir				push(@installer::globals::logfileinfo, $infoline);
1753cdf0e10cSrcweir			}
1754cdf0e10cSrcweir		}
1755cdf0e10cSrcweir
1756cdf0e10cSrcweir		# 2. Replacing all occurences of "VersionNT" by "VersionNT64"
1757cdf0e10cSrcweir
1758cdf0e10cSrcweir		my @versionnt_files = ("Componen.idt", "InstallE.idt", "InstallU.idt", "LaunchCo.idt");
1759cdf0e10cSrcweir
1760cdf0e10cSrcweir		foreach my $onefile ( @versionnt_files )
1761cdf0e10cSrcweir		{
1762cdf0e10cSrcweir			my $fullfilename = $basedir . $installer::globals::separator . $onefile;
1763cdf0e10cSrcweir
1764cdf0e10cSrcweir			if ( -f $fullfilename )
1765cdf0e10cSrcweir			{
1766cdf0e10cSrcweir				my $saving_required = 0;
1767cdf0e10cSrcweir				$filecontent = installer::files::read_file($fullfilename);
1768cdf0e10cSrcweir
1769cdf0e10cSrcweir				for ( my $i = 3; $i <= $#{$filecontent}; $i++ ) 	# ignoring the first three lines
1770cdf0e10cSrcweir				{
1771cdf0e10cSrcweir					my $oneline = ${$filecontent}[$i];
1772cdf0e10cSrcweir
1773cdf0e10cSrcweir					if ( $oneline =~ /\bVersionNT\b/ )
1774cdf0e10cSrcweir					{
1775cdf0e10cSrcweir						${$filecontent}[$i] =~ s/\bVersionNT\b/VersionNT64/g;
1776cdf0e10cSrcweir						$saving_required = 1;
1777cdf0e10cSrcweir					}
1778cdf0e10cSrcweir				}
1779cdf0e10cSrcweir
1780cdf0e10cSrcweir				if ( $saving_required )
1781cdf0e10cSrcweir				{
1782cdf0e10cSrcweir					# Saving the files
1783cdf0e10cSrcweir					installer::files::save_file($fullfilename ,$filecontent);
1784cdf0e10cSrcweir					$infoline = "Making idt file 64 bit conform: $fullfilename\n";
1785cdf0e10cSrcweir					push(@installer::globals::logfileinfo, $infoline);
1786cdf0e10cSrcweir				}
1787cdf0e10cSrcweir			}
1788cdf0e10cSrcweir		}
1789cdf0e10cSrcweir	}
1790cdf0e10cSrcweir
1791cdf0e10cSrcweir}
1792cdf0e10cSrcweir
1793cdf0e10cSrcweir#################################################################
1794cdf0e10cSrcweir# Include all cab files into the msi database.
1795cdf0e10cSrcweir# This works only on Windows
1796cdf0e10cSrcweir#################################################################
1797cdf0e10cSrcweir
1798cdf0e10cSrcweirsub include_cabs_into_msi
1799cdf0e10cSrcweir{
1800cdf0e10cSrcweir	my ($installdir) = @_;
1801cdf0e10cSrcweir
1802cdf0e10cSrcweir	installer::logger::include_header_into_logfile("Including cabs into msi database");
1803cdf0e10cSrcweir
1804cdf0e10cSrcweir	my $from = cwd();
1805cdf0e10cSrcweir	my $to = $installdir;
1806cdf0e10cSrcweir
1807cdf0e10cSrcweir	chdir($to);
1808cdf0e10cSrcweir
1809cdf0e10cSrcweir	my $infoline = "Changing into directory: $to";
1810cdf0e10cSrcweir	push( @installer::globals::logfileinfo, $infoline);
1811cdf0e10cSrcweir
1812cdf0e10cSrcweir	my $msidb = "msidb.exe";	# Has to be in the path
1813cdf0e10cSrcweir	my $extraslash = "";		# Has to be set for non-ActiveState perl
1814cdf0e10cSrcweir
1815cdf0e10cSrcweir	my $msifilename = $installer::globals::msidatabasename;
1816cdf0e10cSrcweir
1817cdf0e10cSrcweir	$msifilename = installer::converter::make_path_conform($msifilename);
1818cdf0e10cSrcweir
1819cdf0e10cSrcweir	# msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
1820cdf0e10cSrcweir	$msifilename =~ s/\//\\\\/g;
1821cdf0e10cSrcweir	$extraslash = "\\";
1822cdf0e10cSrcweir
1823cdf0e10cSrcweir	my $allcabfiles = installer::systemactions::find_file_with_file_extension("cab", $installdir);
1824cdf0e10cSrcweir
1825cdf0e10cSrcweir	for ( my $i = 0; $i <= $#{$allcabfiles}; $i++ )
1826cdf0e10cSrcweir	{
1827cdf0e10cSrcweir		my $systemcall = $msidb . " -d " . $msifilename . " -a " . ${$allcabfiles}[$i];
1828cdf0e10cSrcweir
1829cdf0e10cSrcweir		my $returnvalue = system($systemcall);
1830cdf0e10cSrcweir
1831cdf0e10cSrcweir		$infoline = "Systemcall: $systemcall\n";
1832cdf0e10cSrcweir		push( @installer::globals::logfileinfo, $infoline);
1833cdf0e10cSrcweir
1834cdf0e10cSrcweir		if ($returnvalue)
1835cdf0e10cSrcweir		{
1836cdf0e10cSrcweir			$infoline = "ERROR: Could not execute $systemcall !\n";
1837cdf0e10cSrcweir			push( @installer::globals::logfileinfo, $infoline);
1838cdf0e10cSrcweir		}
1839cdf0e10cSrcweir		else
1840cdf0e10cSrcweir		{
1841cdf0e10cSrcweir			$infoline = "Success: Executed $systemcall successfully!\n";
1842cdf0e10cSrcweir			push( @installer::globals::logfileinfo, $infoline);
1843cdf0e10cSrcweir		}
1844cdf0e10cSrcweir
1845cdf0e10cSrcweir		# deleting the cab file
1846cdf0e10cSrcweir
1847cdf0e10cSrcweir		unlink(${$allcabfiles}[$i]);
1848cdf0e10cSrcweir
1849cdf0e10cSrcweir		$infoline = "Deleted cab file: ${$allcabfiles}[$i]\n";
1850cdf0e10cSrcweir		push( @installer::globals::logfileinfo, $infoline);
1851cdf0e10cSrcweir	}
1852cdf0e10cSrcweir
1853cdf0e10cSrcweir	$infoline = "Changing back into directory: $from";
1854cdf0e10cSrcweir	push( @installer::globals::logfileinfo, $infoline);
1855cdf0e10cSrcweir
1856cdf0e10cSrcweir	chdir($from);
1857cdf0e10cSrcweir}
1858cdf0e10cSrcweir
1859cdf0e10cSrcweir#################################################################
1860cdf0e10cSrcweir# Executing the created batch file to pack all files.
1861cdf0e10cSrcweir# This works only on Windows
1862cdf0e10cSrcweir#################################################################
1863cdf0e10cSrcweir
1864cdf0e10cSrcweirsub execute_packaging
1865cdf0e10cSrcweir{
1866cdf0e10cSrcweir	my ($localpackjobref, $loggingdir, $allvariables) = @_;
1867cdf0e10cSrcweir
1868cdf0e10cSrcweir	installer::logger::include_header_into_logfile("Packaging process");
1869cdf0e10cSrcweir
1870cdf0e10cSrcweir	installer::logger::include_timestamp_into_logfile("Performance Info: Execute packaging start");
1871cdf0e10cSrcweir
1872cdf0e10cSrcweir	my $infoline = "";
1873cdf0e10cSrcweir	my $from = cwd();
1874cdf0e10cSrcweir	my $to = $loggingdir;
1875cdf0e10cSrcweir
1876cdf0e10cSrcweir	chdir($to);
1877cdf0e10cSrcweir	$infoline = "chdir: $to \n";
1878cdf0e10cSrcweir	push( @installer::globals::logfileinfo, $infoline);
1879cdf0e10cSrcweir
1880cdf0e10cSrcweir	# if the ddf file contains relative pathes, it is necessary to change into the temp directory
1881cdf0e10cSrcweir	if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} )
1882cdf0e10cSrcweir	{
1883cdf0e10cSrcweir		$to = $installer::globals::temppath;
1884cdf0e10cSrcweir		chdir($to);
1885cdf0e10cSrcweir		$infoline = "chdir: $to \n";
1886cdf0e10cSrcweir		push( @installer::globals::logfileinfo, $infoline);
1887cdf0e10cSrcweir	}
1888cdf0e10cSrcweir
1889cdf0e10cSrcweir	# changing the tmp directory, because makecab.exe generates temporary cab files
1890cdf0e10cSrcweir	my $origtemppath = "";
1891cdf0e10cSrcweir	if ( $ENV{'TMP'} ) { $origtemppath = $ENV{'TMP'}; }
1892cdf0e10cSrcweir	$ENV{'TMP'} = $installer::globals::temppath;	# setting TMP to the new unique directory!
1893cdf0e10cSrcweir
1894cdf0e10cSrcweir	my $maxmakecabcalls = 3;
1895cdf0e10cSrcweir	my $allmakecabcalls = $#{$localpackjobref} + 1;
1896cdf0e10cSrcweir
1897cdf0e10cSrcweir	for ( my $i = 0; $i <= $#{$localpackjobref}; $i++ )
1898cdf0e10cSrcweir	{
1899cdf0e10cSrcweir		my $systemcall = ${$localpackjobref}[$i];
1900cdf0e10cSrcweir
1901cdf0e10cSrcweir		my $callscounter = $i + 1;
1902cdf0e10cSrcweir
1903cdf0e10cSrcweir		installer::logger::print_message( "... makecab.exe ($callscounter/$allmakecabcalls) ... \n" );
1904cdf0e10cSrcweir
1905cdf0e10cSrcweir		# my $returnvalue = system($systemcall);
1906cdf0e10cSrcweir
1907cdf0e10cSrcweir		for ( my $n = 1; $n <= $maxmakecabcalls; $n++ )
1908cdf0e10cSrcweir		{
1909cdf0e10cSrcweir			my @ddfoutput = ();
1910cdf0e10cSrcweir
1911cdf0e10cSrcweir			$infoline = "Systemcall: $systemcall";
1912cdf0e10cSrcweir			push( @installer::globals::logfileinfo, $infoline);
1913cdf0e10cSrcweir
1914cdf0e10cSrcweir			open (DDF, "$systemcall");
1915cdf0e10cSrcweir			while (<DDF>) {push(@ddfoutput, $_); }
1916cdf0e10cSrcweir			close (DDF);
1917cdf0e10cSrcweir
1918cdf0e10cSrcweir			my $returnvalue = $?;	# $? contains the return value of the systemcall
1919cdf0e10cSrcweir
1920cdf0e10cSrcweir			if ($returnvalue)
1921cdf0e10cSrcweir			{
1922cdf0e10cSrcweir				if ( $n < $maxmakecabcalls )
1923cdf0e10cSrcweir				{
1924cdf0e10cSrcweir					installer::logger::print_message( "makecab_error (Try $n): Trying again \n" );
1925cdf0e10cSrcweir					$infoline = "makecab_error (Try $n): $systemcall !";
1926cdf0e10cSrcweir				}
1927cdf0e10cSrcweir				else
1928cdf0e10cSrcweir				{
1929cdf0e10cSrcweir					installer::logger::print_message( "ERROR (Try $n): Abort packing \n" );
1930cdf0e10cSrcweir					$infoline = "ERROR (Try $n): $systemcall !";
1931cdf0e10cSrcweir				}
1932cdf0e10cSrcweir
1933cdf0e10cSrcweir				push( @installer::globals::logfileinfo, $infoline);
1934cdf0e10cSrcweir				# for ( my $j = 0; $j <= $#ddfoutput; $j++ ) { push( @installer::globals::logfileinfo, "$ddfoutput[$j]"); }
1935cdf0e10cSrcweir
1936cdf0e10cSrcweir				for ( my $m = 0; $m <= $#ddfoutput; $m++ )
1937cdf0e10cSrcweir				{
1938cdf0e10cSrcweir					if ( $ddfoutput[$m] =~ /(ERROR\:.*?)\s*$/ )
1939cdf0e10cSrcweir					{
1940cdf0e10cSrcweir						$infoline = $1 . "\n";
1941cdf0e10cSrcweir						if ( $n < $maxmakecabcalls ) { $infoline =~ s/ERROR\:/makecab_error\:/i; }
1942cdf0e10cSrcweir						installer::logger::print_message( $infoline );
1943cdf0e10cSrcweir						push( @installer::globals::logfileinfo, $infoline);
1944cdf0e10cSrcweir					}
1945cdf0e10cSrcweir				}
1946cdf0e10cSrcweir
1947cdf0e10cSrcweir				if ( $n == $maxmakecabcalls ) { installer::exiter::exit_program("ERROR: \"$systemcall\"!", "execute_packaging"); }
1948cdf0e10cSrcweir			}
1949cdf0e10cSrcweir			else
1950cdf0e10cSrcweir			{
1951cdf0e10cSrcweir				# installer::logger::print_message( "Success (Try $n): \"$systemcall\"\n" );
1952cdf0e10cSrcweir				$infoline = "Success (Try $n): $systemcall";
1953cdf0e10cSrcweir				push( @installer::globals::logfileinfo, $infoline);
1954cdf0e10cSrcweir				last;
1955cdf0e10cSrcweir			}
1956cdf0e10cSrcweir		}
1957cdf0e10cSrcweir	}
1958cdf0e10cSrcweir
1959cdf0e10cSrcweir	installer::logger::include_timestamp_into_logfile("Performance Info: Execute packaging end");
1960cdf0e10cSrcweir
1961cdf0e10cSrcweir	# setting back to the original tmp directory
1962cdf0e10cSrcweir	$ENV{'TMP'} = $origtemppath;
1963cdf0e10cSrcweir
1964cdf0e10cSrcweir	chdir($from);
1965cdf0e10cSrcweir	$infoline = "chdir: $from \n";
1966cdf0e10cSrcweir	push( @installer::globals::logfileinfo, $infoline);
1967cdf0e10cSrcweir}
1968cdf0e10cSrcweir
1969cdf0e10cSrcweir###############################################################
1970cdf0e10cSrcweir# Setting the global variables ProductCode and the UpgradeCode
1971cdf0e10cSrcweir###############################################################
1972cdf0e10cSrcweir
1973cdf0e10cSrcweirsub set_global_code_variables
1974cdf0e10cSrcweir{
1975cdf0e10cSrcweir	my ( $languagesref, $languagestringref, $allvariableshashref, $alloldproperties ) = @_;
1976cdf0e10cSrcweir
1977cdf0e10cSrcweir	# In the msi template directory a files "codes.txt" has to exist, in which the ProductCode
1978cdf0e10cSrcweir	# and the UpgradeCode for the product are defined.
1979cdf0e10cSrcweir	# The name "codes.txt" can be overwritten in Product definition with CODEFILENAME .
1980cdf0e10cSrcweir	# Default $installer::globals::codefilename is defined in parameter.pm.
1981cdf0e10cSrcweir
1982cdf0e10cSrcweir	if ( $allvariableshashref->{'CODEFILENAME'} )
1983cdf0e10cSrcweir	{
1984cdf0e10cSrcweir		$installer::globals::codefilename = $installer::globals::idttemplatepath  . $installer::globals::separator . $allvariableshashref->{'CODEFILENAME'};
1985cdf0e10cSrcweir		installer::files::check_file($installer::globals::codefilename);
1986cdf0e10cSrcweir	}
1987cdf0e10cSrcweir
1988cdf0e10cSrcweir	my $infoline = "Using Codes file: $installer::globals::codefilename \n";
1989cdf0e10cSrcweir	push( @installer::globals::logfileinfo, $infoline);
1990cdf0e10cSrcweir
1991cdf0e10cSrcweir	my $codefile = installer::files::read_file($installer::globals::codefilename);
1992cdf0e10cSrcweir
1993cdf0e10cSrcweir	my $isopensource = 0;
1994cdf0e10cSrcweir	if ( $allvariableshashref->{'OPENSOURCE'} ) { $isopensource = $allvariableshashref->{'OPENSOURCE'}; }
1995cdf0e10cSrcweir
1996cdf0e10cSrcweir	my $onelanguage = "";
1997cdf0e10cSrcweir
1998cdf0e10cSrcweir	if ( $#{$languagesref} > 0 )	# more than one language
1999cdf0e10cSrcweir	{
2000cdf0e10cSrcweir		if (( $installer::globals::added_english ) && ( $#{$languagesref} == 1 )) # only multilingual because of added English
2001cdf0e10cSrcweir		{
2002cdf0e10cSrcweir			$onelanguage = ${$languagesref}[1];  # setting the first language, that is not english
2003cdf0e10cSrcweir		}
2004cdf0e10cSrcweir		else
2005cdf0e10cSrcweir		{
2006cdf0e10cSrcweir			if (( ${$languagesref}[1] =~ /jp/ ) ||
2007cdf0e10cSrcweir				( ${$languagesref}[1] =~ /ko/ ) ||
2008cdf0e10cSrcweir				( ${$languagesref}[1] =~ /zh/ ))
2009cdf0e10cSrcweir			{
2010cdf0e10cSrcweir				$onelanguage = "multiasia";
2011cdf0e10cSrcweir			}
2012cdf0e10cSrcweir			else
2013cdf0e10cSrcweir			{
2014cdf0e10cSrcweir				$onelanguage = "multiwestern";
2015cdf0e10cSrcweir			}
2016cdf0e10cSrcweir		}
2017cdf0e10cSrcweir	}
2018cdf0e10cSrcweir	else	# only one language
2019cdf0e10cSrcweir	{
2020cdf0e10cSrcweir		$onelanguage = ${$languagesref}[0];
2021cdf0e10cSrcweir	}
2022cdf0e10cSrcweir
2023cdf0e10cSrcweir	# ProductCode must not change, if Windows patches shall be applied
2024cdf0e10cSrcweir	if ( $installer::globals::updatedatabase )
2025cdf0e10cSrcweir	{
2026cdf0e10cSrcweir		$installer::globals::productcode = $alloldproperties->{'ProductCode'};
2027cdf0e10cSrcweir	}
2028cdf0e10cSrcweir	elsif ( $installer::globals::prepare_winpatch )
2029cdf0e10cSrcweir	{
2030cdf0e10cSrcweir		# ProductCode has to be specified in each language
2031cdf0e10cSrcweir		my $searchstring = "PRODUCTCODE";
2032cdf0e10cSrcweir		my $codeblock = installer::windows::idtglobal::get_language_block_from_language_file($searchstring, $codefile);
2033cdf0e10cSrcweir		$installer::globals::productcode = installer::windows::idtglobal::get_code_from_code_block($codeblock, $onelanguage);
2034cdf0e10cSrcweir	} else {
2035cdf0e10cSrcweir		my $guidref = get_guid_list(1, 1);	# only one GUID shall be generated
2036cdf0e10cSrcweir		${$guidref}[0] =~ s/\s*$//;		# removing ending spaces
2037cdf0e10cSrcweir		$installer::globals::productcode = "\{" . ${$guidref}[0] . "\}";
2038cdf0e10cSrcweir	}
2039cdf0e10cSrcweir
2040cdf0e10cSrcweir	if ( $installer::globals::patch ) # patch upgrade codes are defined in soffice.lst
2041cdf0e10cSrcweir	{
2042cdf0e10cSrcweir		if ( $allvariableshashref->{'PATCHUPGRADECODE'} ) { $installer::globals::upgradecode = $allvariableshashref->{'PATCHUPGRADECODE'}; }
2043cdf0e10cSrcweir		else { installer::exiter::exit_program("ERROR: PATCHUPGRADECODE not defined in list file!", "set_global_code_variables"); }
2044cdf0e10cSrcweir	}
2045cdf0e10cSrcweir	else
2046cdf0e10cSrcweir	{
2047cdf0e10cSrcweir		# UpgradeCode can take english as default, if not defined in specified language
2048cdf0e10cSrcweir
2049cdf0e10cSrcweir		$searchstring = "UPGRADECODE";	# searching in the codes.txt file
2050cdf0e10cSrcweir		$codeblock = installer::windows::idtglobal::get_language_block_from_language_file($searchstring, $codefile);
2051cdf0e10cSrcweir		$installer::globals::upgradecode = installer::windows::idtglobal::get_language_string_from_language_block($codeblock, $onelanguage, "");
2052cdf0e10cSrcweir	}
2053cdf0e10cSrcweir
2054cdf0e10cSrcweir	# if (( $installer::globals::productcode eq "" ) && ( ! $isopensource )) { installer::exiter::exit_program("ERROR: ProductCode for language $onelanguage not defined in $installer::globals::codefilename !", "set_global_code_variables"); }
2055cdf0e10cSrcweir	if ( $installer::globals::upgradecode eq "" ) { installer::exiter::exit_program("ERROR: UpgradeCode not defined in $installer::globals::codefilename !", "set_global_code_variables"); }
2056cdf0e10cSrcweir
2057cdf0e10cSrcweir	$infoline = "Setting ProductCode to: $installer::globals::productcode \n";
2058cdf0e10cSrcweir	push( @installer::globals::logfileinfo, $infoline);
2059cdf0e10cSrcweir	$infoline = "Setting UpgradeCode to: $installer::globals::upgradecode \n";
2060cdf0e10cSrcweir	push( @installer::globals::logfileinfo, $infoline);
2061cdf0e10cSrcweir
2062cdf0e10cSrcweir	# Adding both variables into the variables array
2063cdf0e10cSrcweir
2064cdf0e10cSrcweir	$allvariableshashref->{'PRODUCTCODE'} = $installer::globals::productcode;
2065cdf0e10cSrcweir	$allvariableshashref->{'UPGRADECODE'} = $installer::globals::upgradecode;
2066cdf0e10cSrcweir
2067cdf0e10cSrcweir	$infoline = "Defined variable PRODUCTCODE: $installer::globals::productcode \n";
2068cdf0e10cSrcweir	push( @installer::globals::logfileinfo, $infoline);
2069cdf0e10cSrcweir
2070cdf0e10cSrcweir	$infoline = "Defined variable UPGRADECODE: $installer::globals::upgradecode \n";
2071cdf0e10cSrcweir	push( @installer::globals::logfileinfo, $infoline);
2072cdf0e10cSrcweir
2073cdf0e10cSrcweir}
2074cdf0e10cSrcweir
2075cdf0e10cSrcweir###############################################################
2076cdf0e10cSrcweir# Setting the product version used in property table and
2077cdf0e10cSrcweir# upgrade table. Saving in global variable $msiproductversion
2078cdf0e10cSrcweir###############################################################
2079cdf0e10cSrcweir
2080cdf0e10cSrcweirsub set_msiproductversion
2081cdf0e10cSrcweir{
2082cdf0e10cSrcweir	my ( $allvariables ) = @_;
2083cdf0e10cSrcweir
2084cdf0e10cSrcweir	my $productversion = $allvariables->{'PRODUCTVERSION'};
2085cdf0e10cSrcweir
2086cdf0e10cSrcweir	if (( $productversion =~ /^\s*\d+\s*$/ ) && ( $productversion > 255 )) { $productversion = $productversion%256; }
2087cdf0e10cSrcweir
2088cdf0e10cSrcweir	if ( $productversion =~ /^\s*(\d+)\.(\d+)\.(\d+)\s*$/ )
2089cdf0e10cSrcweir	{
2090cdf0e10cSrcweir		$productversion = $1 . "\." . $2 . $3 . "\." . $installer::globals::buildid;
2091cdf0e10cSrcweir	}
2092cdf0e10cSrcweir	elsif  ( $productversion =~ /^\s*(\d+)\.(\d+)\s*$/ )
2093cdf0e10cSrcweir	{
2094cdf0e10cSrcweir		$productversion = $1 . "\." . $2 . "\." . $installer::globals::buildid;
2095cdf0e10cSrcweir	}
2096cdf0e10cSrcweir	else
2097cdf0e10cSrcweir	{
2098cdf0e10cSrcweir		my $productminor = "00";
2099cdf0e10cSrcweir		if (( $allvariables->{'PACKAGEVERSION'} ) && ( $allvariables->{'PACKAGEVERSION'} ne "" ))
2100cdf0e10cSrcweir		{
2101cdf0e10cSrcweir			if ( $allvariables->{'PACKAGEVERSION'} =~ /^\s*(\d+)\.(\d+)\.(\d+)\s*$/ ) { $productminor = $2; }
2102cdf0e10cSrcweir		}
2103cdf0e10cSrcweir
2104cdf0e10cSrcweir		$productversion = $productversion . "\." . $productminor . "\." . $installer::globals::buildid;
2105cdf0e10cSrcweir	}
2106cdf0e10cSrcweir
2107cdf0e10cSrcweir	$installer::globals::msiproductversion = $productversion;
2108cdf0e10cSrcweir
2109cdf0e10cSrcweir	# Setting $installer::globals::msimajorproductversion, to differ between old version in upgrade table
2110cdf0e10cSrcweir
2111cdf0e10cSrcweir	if ( $installer::globals::msiproductversion =~ /^\s*(\d+)\./ )
2112cdf0e10cSrcweir	{
2113cdf0e10cSrcweir		my $major = $1;
2114cdf0e10cSrcweir		$installer::globals::msimajorproductversion = $major . "\.0\.0";
2115cdf0e10cSrcweir	}
2116cdf0e10cSrcweir}
2117cdf0e10cSrcweir
2118cdf0e10cSrcweir#################################################################################
2119cdf0e10cSrcweir# Including the msi product version into the bootstrap.ini, Windows only
2120cdf0e10cSrcweir#################################################################################
2121cdf0e10cSrcweir
2122cdf0e10cSrcweirsub put_msiproductversion_into_bootstrapfile
2123cdf0e10cSrcweir{
2124cdf0e10cSrcweir	my ($filesref) = @_;
2125cdf0e10cSrcweir
2126cdf0e10cSrcweir	for ( my $i = 0; $i <= $#{$filesref}; $i++ )
2127cdf0e10cSrcweir	{
2128cdf0e10cSrcweir		my $onefile = ${$filesref}[$i];
2129cdf0e10cSrcweir
2130cdf0e10cSrcweir		if ( $onefile->{'gid'} eq "gid_Profile_Version_Ini" )
2131cdf0e10cSrcweir		{
2132cdf0e10cSrcweir			my $file = installer::files::read_file($onefile->{'sourcepath'});
2133cdf0e10cSrcweir
2134cdf0e10cSrcweir			for ( my $j = 0; $j <= $#{$file}; $j++ )
2135cdf0e10cSrcweir			{
2136cdf0e10cSrcweir				${$file}[$j] =~ s/\<msiproductversion\>/$installer::globals::msiproductversion/;
2137cdf0e10cSrcweir			}
2138cdf0e10cSrcweir
2139cdf0e10cSrcweir			installer::files::save_file($onefile->{'sourcepath'}, $file);
2140cdf0e10cSrcweir
2141cdf0e10cSrcweir			last;
2142cdf0e10cSrcweir		}
2143cdf0e10cSrcweir	}
2144cdf0e10cSrcweir}
2145cdf0e10cSrcweir
2146cdf0e10cSrcweir####################################################################################
2147cdf0e10cSrcweir# Updating the file Property.idt dynamically
2148cdf0e10cSrcweir# Content:
2149cdf0e10cSrcweir# Property Value
2150cdf0e10cSrcweir####################################################################################
2151cdf0e10cSrcweir
2152cdf0e10cSrcweirsub update_reglocat_table
2153cdf0e10cSrcweir{
2154cdf0e10cSrcweir	my ($basedir, $allvariables) = @_;
2155cdf0e10cSrcweir
2156cdf0e10cSrcweir	my $reglocatfilename = $basedir . $installer::globals::separator . "RegLocat.idt";
2157cdf0e10cSrcweir
2158cdf0e10cSrcweir	# Only do something, if this file exists
2159cdf0e10cSrcweir
2160cdf0e10cSrcweir	if ( -f $reglocatfilename )
2161cdf0e10cSrcweir	{
2162cdf0e10cSrcweir		my $reglocatfile = installer::files::read_file($reglocatfilename);
2163cdf0e10cSrcweir
2164cdf0e10cSrcweir		my $layername = "";
2165cdf0e10cSrcweir		if ( $allvariables->{'REGISTRYLAYERNAME'} )
2166cdf0e10cSrcweir		{
2167cdf0e10cSrcweir			$layername = $allvariables->{'REGISTRYLAYERNAME'};
2168cdf0e10cSrcweir		}
2169cdf0e10cSrcweir		else
2170cdf0e10cSrcweir		{
2171cdf0e10cSrcweir			for ( my $i = 0; $i <= $#{$reglocatfile}; $i++ )
2172cdf0e10cSrcweir			{
2173cdf0e10cSrcweir				if ( ${$reglocatfile}[$i] =~ /\bLAYERNAMETEMPLATE\b/ )
2174cdf0e10cSrcweir				{
2175cdf0e10cSrcweir					installer::exiter::exit_program("ERROR: Variable \"REGISTRYLAYERNAME\" has to be defined", "update_reglocat_table");
2176cdf0e10cSrcweir				}
2177cdf0e10cSrcweir			}
2178cdf0e10cSrcweir		}
2179cdf0e10cSrcweir
2180cdf0e10cSrcweir		if ( $layername ne "" )
2181cdf0e10cSrcweir		{
2182cdf0e10cSrcweir			# Updating the layername in
2183cdf0e10cSrcweir
2184cdf0e10cSrcweir			for ( my $i = 0; $i <= $#{$reglocatfile}; $i++ )
2185cdf0e10cSrcweir			{
2186cdf0e10cSrcweir				${$reglocatfile}[$i] =~ s/\bLAYERNAMETEMPLATE\b/$layername/;
2187cdf0e10cSrcweir			}
2188cdf0e10cSrcweir
2189cdf0e10cSrcweir			# Saving the file
2190cdf0e10cSrcweir			installer::files::save_file($reglocatfilename ,$reglocatfile);
2191cdf0e10cSrcweir			my $infoline = "Updated idt file: $reglocatfilename\n";
2192cdf0e10cSrcweir			push(@installer::globals::logfileinfo, $infoline);
2193cdf0e10cSrcweir		}
2194cdf0e10cSrcweir	}
2195cdf0e10cSrcweir}
2196cdf0e10cSrcweir
2197cdf0e10cSrcweir
2198cdf0e10cSrcweir
2199cdf0e10cSrcweir####################################################################################
2200cdf0e10cSrcweir# Updating the file RemoveRe.idt dynamically (RemoveRegistry.idt)
2201cdf0e10cSrcweir# The name of the component has to be replaced.
2202cdf0e10cSrcweir####################################################################################
2203cdf0e10cSrcweir
2204cdf0e10cSrcweirsub update_removere_table
2205cdf0e10cSrcweir{
2206cdf0e10cSrcweir	my ($basedir) = @_;
2207cdf0e10cSrcweir
2208cdf0e10cSrcweir	my $removeregistryfilename = $basedir . $installer::globals::separator . "RemoveRe.idt";
2209cdf0e10cSrcweir
2210cdf0e10cSrcweir	# Only do something, if this file exists
2211cdf0e10cSrcweir
2212cdf0e10cSrcweir	if ( -f $removeregistryfilename )
2213cdf0e10cSrcweir	{
2214cdf0e10cSrcweir		my $removeregistryfile = installer::files::read_file($removeregistryfilename);
2215cdf0e10cSrcweir
2216cdf0e10cSrcweir		for ( my $i = 0; $i <= $#{$removeregistryfile}; $i++ )
2217cdf0e10cSrcweir		{
2218cdf0e10cSrcweir			for ( my $i = 0; $i <= $#{$removeregistryfile}; $i++ )
2219cdf0e10cSrcweir			{
2220cdf0e10cSrcweir				${$removeregistryfile}[$i] =~ s/\bREGISTRYROOTCOMPONENT\b/$installer::globals::registryrootcomponent/;
2221cdf0e10cSrcweir			}
2222cdf0e10cSrcweir		}
2223cdf0e10cSrcweir
2224cdf0e10cSrcweir		# Saving the file
2225cdf0e10cSrcweir		installer::files::save_file($removeregistryfilename ,$removeregistryfile);
2226cdf0e10cSrcweir		my $infoline = "Updated idt file: $removeregistryfilename \n";
2227cdf0e10cSrcweir		push(@installer::globals::logfileinfo, $infoline);
2228cdf0e10cSrcweir	}
2229cdf0e10cSrcweir}
2230cdf0e10cSrcweir
2231cdf0e10cSrcweir##########################################################################
2232cdf0e10cSrcweir# Reading saved mappings in Files.idt and Director.idt.
2233cdf0e10cSrcweir# This is required, if installation sets shall be created,
2234cdf0e10cSrcweir# that can be used for creation of msp files.
2235cdf0e10cSrcweir##########################################################################
2236cdf0e10cSrcweir
2237cdf0e10cSrcweirsub read_saved_mappings
2238cdf0e10cSrcweir{
2239cdf0e10cSrcweir	installer::logger::include_header_into_logfile("Reading saved mappings from older installation sets:");
2240cdf0e10cSrcweir
2241cdf0e10cSrcweir	installer::logger::include_timestamp_into_logfile("Performance Info: Reading saved mappings start");
2242cdf0e10cSrcweir
2243cdf0e10cSrcweir	if ( $installer::globals::previous_idt_dir )
2244cdf0e10cSrcweir	{
2245cdf0e10cSrcweir		my @errorlines = ();
2246cdf0e10cSrcweir		my $errorstring = "";
2247cdf0e10cSrcweir		my $error_occured = 0;
2248cdf0e10cSrcweir		my $file_error_occured = 0;
2249cdf0e10cSrcweir		my $dir_error = 0;
2250cdf0e10cSrcweir
2251cdf0e10cSrcweir		my $idtdir = $installer::globals::previous_idt_dir;
2252cdf0e10cSrcweir		$idtdir =~ s/\Q$installer::globals::separator\E\s*$//;
2253cdf0e10cSrcweir
2254cdf0e10cSrcweir		# Reading File.idt
2255cdf0e10cSrcweir
2256cdf0e10cSrcweir		my $idtfile = $idtdir . $installer::globals::separator . "File.idt";
2257cdf0e10cSrcweir		push( @installer::globals::globallogfileinfo, "\nAnalyzing file: $idtfile\n" );
2258cdf0e10cSrcweir		if ( ! -f $idtfile ) { push( @installer::globals::globallogfileinfo, "Warning: File $idtfile does not exist!\n" ); }
2259cdf0e10cSrcweir
2260cdf0e10cSrcweir		my $n = 0;
2261cdf0e10cSrcweir		open (F, "<$idtfile") || installer::exiter::exit_program("ERROR: Cannot open file $idtfile for reading", "read_saved_mappings");
2262cdf0e10cSrcweir		<F>; <F>; <F>;
2263cdf0e10cSrcweir		while (<F>)
2264cdf0e10cSrcweir		{
2265cdf0e10cSrcweir			m/^([^\t]+)\t([^\t]+)\t((.*)\|)?([^\t]*)/;
2266cdf0e10cSrcweir			print "OUT1: \$1: $1, \$2: $2, \$3: $3, \$4: $4, \$5: $5\n";
2267cdf0e10cSrcweir			next if ("$1" eq "$5") && (!defined($3));
2268cdf0e10cSrcweir			my $lc1 = lc($1);
2269cdf0e10cSrcweir
2270cdf0e10cSrcweir			if ( exists($installer::globals::savedmapping{"$2/$5"}))
2271cdf0e10cSrcweir			{
2272cdf0e10cSrcweir				if ( ! $file_error_occured )
2273cdf0e10cSrcweir				{
2274cdf0e10cSrcweir					$errorstring = "\nErrors in $idtfile: \n";
2275cdf0e10cSrcweir					push(@errorlines, $errorstring);
2276cdf0e10cSrcweir				}
2277cdf0e10cSrcweir				$errorstring = "Duplicate savedmapping{" . "$2/$5}\n";
2278cdf0e10cSrcweir				push(@errorlines, $errorstring);
2279cdf0e10cSrcweir				$error_occured = 1;
2280cdf0e10cSrcweir				$file_error_occured = 1;
2281cdf0e10cSrcweir			}
2282cdf0e10cSrcweir
2283cdf0e10cSrcweir			if ( exists($installer::globals::savedrevmapping{$lc1}))
2284cdf0e10cSrcweir			{
2285cdf0e10cSrcweir				if ( ! $file_error_occured )
2286cdf0e10cSrcweir				{
2287cdf0e10cSrcweir					$errorstring = "\nErrors in $idtfile: \n";
2288cdf0e10cSrcweir					push(@errorlines, $errorstring);
2289cdf0e10cSrcweir				}
2290cdf0e10cSrcweir				$errorstring = "Duplicate savedrevmapping{" . "$lc1}\n";
2291cdf0e10cSrcweir				push(@errorlines, $errorstring);
2292cdf0e10cSrcweir				$error_occured = 1;
2293cdf0e10cSrcweir				$file_error_occured = 1;
2294cdf0e10cSrcweir			}
2295cdf0e10cSrcweir
2296cdf0e10cSrcweir			my $shortname = $4 || '';
2297cdf0e10cSrcweir
2298cdf0e10cSrcweir			# Don't reuse illegal 8.3 mappings that we used to generate in 2.0.4
2299cdf0e10cSrcweir			if (index($shortname, '.') > 8 ||
2300cdf0e10cSrcweir			    (index($shortname, '.') == -1 && length($shortname) > 8))
2301cdf0e10cSrcweir			{
2302cdf0e10cSrcweir			    $shortname = '';
2303cdf0e10cSrcweir			}
2304cdf0e10cSrcweir
2305cdf0e10cSrcweir			if (( $shortname ne '' ) && ( index($shortname, '~') > 0 ) && ( exists($installer::globals::savedrev83mapping{$shortname}) ))
2306cdf0e10cSrcweir			{
2307cdf0e10cSrcweir				if ( ! $file_error_occured )
2308cdf0e10cSrcweir				{
2309cdf0e10cSrcweir					$errorstring = "\nErrors in $idtfile: \n";
2310cdf0e10cSrcweir					push(@errorlines, $errorstring);
2311cdf0e10cSrcweir				}
2312cdf0e10cSrcweir				$errorstring = "Duplicate savedrev83mapping{" . "$shortname}\n";
2313cdf0e10cSrcweir				push(@errorlines, $errorstring);
2314cdf0e10cSrcweir				$error_occured = 1;
2315cdf0e10cSrcweir				$file_error_occured = 1;
2316cdf0e10cSrcweir			}
2317cdf0e10cSrcweir
2318cdf0e10cSrcweir			$installer::globals::savedmapping{"$2/$5"} = "$1;$shortname";
2319cdf0e10cSrcweir			$installer::globals::savedrevmapping{lc($1)} = "$2/$5";
2320cdf0e10cSrcweir			$installer::globals::savedrev83mapping{$shortname} = "$2/$5" if $shortname ne '';
2321cdf0e10cSrcweir			$n++;
2322cdf0e10cSrcweir		}
2323cdf0e10cSrcweir
2324cdf0e10cSrcweir		close (F);
2325cdf0e10cSrcweir
2326cdf0e10cSrcweir		push( @installer::globals::globallogfileinfo, "Read $n old file table key or 8.3 name mappings from $idtfile\n" );
2327cdf0e10cSrcweir
2328cdf0e10cSrcweir		# Reading Director.idt
2329cdf0e10cSrcweir
2330cdf0e10cSrcweir		$idtfile = $idtdir . $installer::globals::separator . "Director.idt";
2331cdf0e10cSrcweir		push( @installer::globals::globallogfileinfo, "\nAnalyzing file $idtfile\n" );
2332cdf0e10cSrcweir		if ( ! -f $idtfile ) { push( @installer::globals::globallogfileinfo, "Warning: File $idtfile does not exist!\n" ); }
2333cdf0e10cSrcweir
2334cdf0e10cSrcweir		$n = 0;
2335cdf0e10cSrcweir		open (F, "<$idtfile") || installer::exiter::exit_program("ERROR: Cannot open file $idtfile for reading", "read_saved_mappings");
2336cdf0e10cSrcweir		<F>; <F>; <F>;
2337cdf0e10cSrcweir		while (<F>)
2338cdf0e10cSrcweir		{
2339cdf0e10cSrcweir			m/^([^\t]+)\t([^\t]+)\t(([^~]+~\d.*)\|)?([^\t]*)/;
2340cdf0e10cSrcweir			next if (!defined($3));
2341cdf0e10cSrcweir			my $lc1 = lc($1);
2342cdf0e10cSrcweir
2343cdf0e10cSrcweir			print "OUT2: \$1: $1, \$2: $2, \$3: $3\n";
2344cdf0e10cSrcweir
2345cdf0e10cSrcweir			if ( exists($installer::globals::saved83dirmapping{$1}) )
2346cdf0e10cSrcweir			{
2347cdf0e10cSrcweir				if ( ! $dir_error_occured )
2348cdf0e10cSrcweir				{
2349cdf0e10cSrcweir					$errorstring = "\nErrors in $idtfile: \n";
2350cdf0e10cSrcweir					push(@errorlines, $errorstring);
2351cdf0e10cSrcweir				}
2352cdf0e10cSrcweir				$errorstring = "Duplicate saved83dirmapping{" . "$1}\n";
2353cdf0e10cSrcweir				push(@errorlines, $errorstring);
2354cdf0e10cSrcweir				$error_occured = 1;
2355cdf0e10cSrcweir				$dir_error_occured = 1;
2356cdf0e10cSrcweir			}
2357cdf0e10cSrcweir
2358cdf0e10cSrcweir			$installer::globals::saved83dirmapping{$1} = $4;
2359cdf0e10cSrcweir			$n++;
2360cdf0e10cSrcweir		}
2361cdf0e10cSrcweir		close (F);
2362cdf0e10cSrcweir
2363cdf0e10cSrcweir		push( @installer::globals::globallogfileinfo, "Read $n old directory 8.3 name mappings from $idtfile\n" );
2364cdf0e10cSrcweir
2365cdf0e10cSrcweir		# Analyzing errors
2366cdf0e10cSrcweir
2367cdf0e10cSrcweir		if ( $error_occured )
2368cdf0e10cSrcweir		{
2369cdf0e10cSrcweir			for ( my $i = 0; $i <= $#errorlines; $i++ )
2370cdf0e10cSrcweir			{
2371cdf0e10cSrcweir				print "$errorlines[$i]";
2372cdf0e10cSrcweir				push( @installer::globals::globallogfileinfo, "$errorlines[$i]");
2373cdf0e10cSrcweir			}
2374cdf0e10cSrcweir			installer::exiter::exit_program("ERROR: Duplicate entries in saved mappings!", "read_saved_mappings");
2375cdf0e10cSrcweir		}
2376cdf0e10cSrcweir	} else {
2377cdf0e10cSrcweir		# push( @installer::globals::globallogfileinfo, "WARNING: Windows patch shall be prepared, but PREVIOUS_IDT_DIR is not set!\n" );
2378cdf0e10cSrcweir		installer::exiter::exit_program("ERROR: Windows patch shall be prepared, but environment variable PREVIOUS_IDT_DIR is not set!", "read_saved_mappings");
2379cdf0e10cSrcweir	}
2380cdf0e10cSrcweir
2381cdf0e10cSrcweir	installer::logger::include_timestamp_into_logfile("Performance Info: Reading saved mappings end");
2382cdf0e10cSrcweir}
2383cdf0e10cSrcweir
2384cdf0e10cSrcweir1;
2385cdf0e10cSrcweir
2386