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