19780544fSAndrew Rist#**************************************************************
29780544fSAndrew Rist#
39780544fSAndrew Rist#  Licensed to the Apache Software Foundation (ASF) under one
49780544fSAndrew Rist#  or more contributor license agreements.  See the NOTICE file
59780544fSAndrew Rist#  distributed with this work for additional information
69780544fSAndrew Rist#  regarding copyright ownership.  The ASF licenses this file
79780544fSAndrew Rist#  to you under the Apache License, Version 2.0 (the
89780544fSAndrew Rist#  "License"); you may not use this file except in compliance
99780544fSAndrew Rist#  with the License.  You may obtain a copy of the License at
109780544fSAndrew Rist#
119780544fSAndrew Rist#    http://www.apache.org/licenses/LICENSE-2.0
129780544fSAndrew Rist#
139780544fSAndrew Rist#  Unless required by applicable law or agreed to in writing,
149780544fSAndrew Rist#  software distributed under the License is distributed on an
159780544fSAndrew Rist#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169780544fSAndrew Rist#  KIND, either express or implied.  See the License for the
179780544fSAndrew Rist#  specific language governing permissions and limitations
189780544fSAndrew Rist#  under the License.
199780544fSAndrew Rist#
209780544fSAndrew Rist#**************************************************************
219780544fSAndrew Rist
229780544fSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweirpackage installer::windows::file;
25cdf0e10cSrcweir
26cdf0e10cSrcweiruse Digest::MD5;
27cdf0e10cSrcweiruse installer::existence;
28cdf0e10cSrcweiruse installer::exiter;
29cdf0e10cSrcweiruse installer::files;
30cdf0e10cSrcweiruse installer::globals;
31cdf0e10cSrcweiruse installer::logger;
32cdf0e10cSrcweiruse installer::pathanalyzer;
33cdf0e10cSrcweiruse installer::worker;
34cdf0e10cSrcweiruse installer::windows::font;
35cdf0e10cSrcweiruse installer::windows::idtglobal;
3619d58b3aSEike Rathkeuse installer::windows::msiglobal;
37cdf0e10cSrcweiruse installer::windows::language;
389f91b7e3SAndre Fischeruse installer::patch::InstallationSet;
399f91b7e3SAndre Fischeruse installer::patch::FileSequenceList;
409f91b7e3SAndre Fischeruse File::Basename;
419f91b7e3SAndre Fischeruse File::Spec;
429f91b7e3SAndre Fischeruse strict;
43cdf0e10cSrcweir
44cdf0e10cSrcweir##########################################################################
45cdf0e10cSrcweir# Assigning one cabinet file to each file. This is requrired,
46cdf0e10cSrcweir# if cabinet files shall be equivalent to packages.
47cdf0e10cSrcweir##########################################################################
48cdf0e10cSrcweir
49cdf0e10cSrcweirsub assign_cab_to_files
50cdf0e10cSrcweir{
51cdf0e10cSrcweir	my ( $filesref ) = @_;
52cdf0e10cSrcweir
53cdf0e10cSrcweir	my $infoline = "";
54cdf0e10cSrcweir
551ba1fd99SAndre Fischer	foreach my $file (@$filesref)
56cdf0e10cSrcweir	{
571ba1fd99SAndre Fischer		if ( ! exists($file->{'modules'}) )
581ba1fd99SAndre Fischer        {
591ba1fd99SAndre Fischer            installer::exiter::exit_program(
601ba1fd99SAndre Fischer                sprintf("ERROR: No module assignment found for %s", $file->{'gid'}),
611ba1fd99SAndre Fischer                "assign_cab_to_files");
621ba1fd99SAndre Fischer        }
631ba1fd99SAndre Fischer		my $module = $file->{'modules'};
64cdf0e10cSrcweir		# If modules contains a list of modules, only taking the first one.
65cdf0e10cSrcweir		if ( $module =~ /^\s*(.*?)\,/ ) { $module = $1; }
66cdf0e10cSrcweir
671ba1fd99SAndre Fischer		if ( ! exists($installer::globals::allcabinetassigns{$module}) )
681ba1fd99SAndre Fischer        {
691ba1fd99SAndre Fischer            installer::exiter::exit_program(
701ba1fd99SAndre Fischer                sprintf("ERROR: No cabinet file assigned to module \"%s\" %s",
711ba1fd99SAndre Fischer                    $module,
721ba1fd99SAndre Fischer                    $file->{'gid'}),
731ba1fd99SAndre Fischer                "assign_cab_to_files");
741ba1fd99SAndre Fischer        }
751ba1fd99SAndre Fischer		$file->{'assignedcabinetfile'} = $installer::globals::allcabinetassigns{$module};
76cdf0e10cSrcweir
77cdf0e10cSrcweir		# Counting the files in each cabinet file
781ba1fd99SAndre Fischer		if ( ! exists($installer::globals::cabfilecounter{$file->{'assignedcabinetfile'}}) )
79cdf0e10cSrcweir		{
801ba1fd99SAndre Fischer			$installer::globals::cabfilecounter{$file->{'assignedcabinetfile'}} = 1;
81cdf0e10cSrcweir		}
82cdf0e10cSrcweir		else
83cdf0e10cSrcweir		{
841ba1fd99SAndre Fischer			$installer::globals::cabfilecounter{$file->{'assignedcabinetfile'}}++;
85cdf0e10cSrcweir		}
86cdf0e10cSrcweir	}
87cdf0e10cSrcweir
88cdf0e10cSrcweir	# assigning startsequencenumbers for each cab file
891ba1fd99SAndre Fischer
901ba1fd99SAndre Fischer    my %count = ();
91cdf0e10cSrcweir	my $offset = 1;
921ba1fd99SAndre Fischer	foreach my $cabfile ( sort keys %installer::globals::cabfilecounter )
93cdf0e10cSrcweir	{
94cdf0e10cSrcweir		my $filecount = $installer::globals::cabfilecounter{$cabfile};
951ba1fd99SAndre Fischer        $count{$cabfile} = $filecount;
96cdf0e10cSrcweir		$installer::globals::cabfilecounter{$cabfile} = $offset;
97cdf0e10cSrcweir		$offset = $offset + $filecount;
98cdf0e10cSrcweir
99cdf0e10cSrcweir		$installer::globals::lastsequence{$cabfile} = $offset - 1;
100cdf0e10cSrcweir	}
101cdf0e10cSrcweir
1021ba1fd99SAndre Fischer	# logging the number of files in each cabinet file
103cdf0e10cSrcweir
104b274bc22SAndre Fischer	$installer::logger::Lang->print("\n");
1051ba1fd99SAndre Fischer	$installer::logger::Lang->print("Cabinet files:\n");
1061ba1fd99SAndre Fischer	foreach my $cabfile (sort keys %installer::globals::cabfilecounter)
107cdf0e10cSrcweir	{
1081ba1fd99SAndre Fischer		$installer::logger::Lang->printf(
1091ba1fd99SAndre Fischer            "%-30s : %4s files, from %4d to %4d\n",
1101ba1fd99SAndre Fischer            $cabfile,
1111ba1fd99SAndre Fischer            $count{$cabfile},
1121ba1fd99SAndre Fischer            $installer::globals::cabfilecounter{$cabfile},
1131ba1fd99SAndre Fischer            $installer::globals::lastsequence{$cabfile});
114cdf0e10cSrcweir	}
115cdf0e10cSrcweir}
116cdf0e10cSrcweir
117cdf0e10cSrcweir##########################################################################
118cdf0e10cSrcweir# Assigning sequencenumbers to files. This is requrired,
119cdf0e10cSrcweir# if cabinet files shall be equivalent to packages.
120cdf0e10cSrcweir##########################################################################
121cdf0e10cSrcweir
122cdf0e10cSrcweirsub assign_sequencenumbers_to_files
123cdf0e10cSrcweir{
124cdf0e10cSrcweir	my ( $filesref ) = @_;
125cdf0e10cSrcweir
126cdf0e10cSrcweir	my %directaccess = ();
127cdf0e10cSrcweir	my %allassigns = ();
1281ba1fd99SAndre Fischer
129cdf0e10cSrcweir	for ( my $i = 0; $i <= $#{$filesref}; $i++ )
130cdf0e10cSrcweir	{
131cdf0e10cSrcweir		my $onefile = ${$filesref}[$i];
132cdf0e10cSrcweir
133cdf0e10cSrcweir		# Keeping order in cabinet files
134cdf0e10cSrcweir		# -> collecting all files in one cabinet file
135cdf0e10cSrcweir		# -> sorting files and assigning numbers
136cdf0e10cSrcweir
137cdf0e10cSrcweir		# Saving counter $i for direct access into files array
138cdf0e10cSrcweir		# "destination" of the file is a unique identifier ('Name' is not unique!)
139cdf0e10cSrcweir		if ( exists($directaccess{$onefile->{'destination'}}) ) { installer::exiter::exit_program("ERROR: 'destination' at file not unique: $onefile->{'destination'}", "assign_sequencenumbers_to_files"); }
140cdf0e10cSrcweir		$directaccess{$onefile->{'destination'}} = $i;
141cdf0e10cSrcweir
142cdf0e10cSrcweir		my $cabfilename = $onefile->{'assignedcabinetfile'};
143cdf0e10cSrcweir		# collecting files in cabinet files
144cdf0e10cSrcweir		if ( ! exists($allassigns{$cabfilename}) )
145cdf0e10cSrcweir		{
146cdf0e10cSrcweir			my %onecabfile = ();
147cdf0e10cSrcweir			$onecabfile{$onefile->{'destination'}} = 1;
148cdf0e10cSrcweir			$allassigns{$cabfilename} = \%onecabfile;
149cdf0e10cSrcweir		}
150cdf0e10cSrcweir		else
151cdf0e10cSrcweir		{
152cdf0e10cSrcweir			$allassigns{$cabfilename}->{$onefile->{'destination'}} = 1;
153cdf0e10cSrcweir		}
154cdf0e10cSrcweir	}
155cdf0e10cSrcweir
156cdf0e10cSrcweir	# Sorting each hash and assigning numbers
157cdf0e10cSrcweir	# The destination of the file determines the sort order, not the filename!
158cdf0e10cSrcweir	my $cabfile;
159cdf0e10cSrcweir	foreach $cabfile ( sort keys %allassigns )
160cdf0e10cSrcweir	{
161cdf0e10cSrcweir		my $counter = $installer::globals::cabfilecounter{$cabfile};
162cdf0e10cSrcweir		my $dest;
163cdf0e10cSrcweir		foreach $dest ( sort keys %{$allassigns{$cabfile}} ) # <- sorting the destination!
164cdf0e10cSrcweir		{
165cdf0e10cSrcweir			my $directaccessnumber = $directaccess{$dest};
1661ba1fd99SAndre Fischer            ${$filesref}[$directaccessnumber]->{'assignedsequencenumber'} = $counter;
167cdf0e10cSrcweir			$counter++;
168cdf0e10cSrcweir		}
169cdf0e10cSrcweir	}
170cdf0e10cSrcweir}
171cdf0e10cSrcweir
172cdf0e10cSrcweir#########################################################
173cdf0e10cSrcweir# Create a shorter version of a long component name,
174cdf0e10cSrcweir# because maximum length in msi database is 72.
175cdf0e10cSrcweir# Attention: In multi msi installation sets, the short
176cdf0e10cSrcweir# names have to be unique over all packages, because
177cdf0e10cSrcweir# this string is used to create the globally unique id
178cdf0e10cSrcweir# -> no resetting of
179cdf0e10cSrcweir# %installer::globals::allshortcomponents
180cdf0e10cSrcweir# after a package was created.
18119d58b3aSEike Rathke# Using no counter because of reproducibility.
182cdf0e10cSrcweir#########################################################
183cdf0e10cSrcweir
184cdf0e10cSrcweirsub generate_new_short_componentname
185cdf0e10cSrcweir{
186cdf0e10cSrcweir	my ($componentname) = @_;
187cdf0e10cSrcweir
188cdf0e10cSrcweir	my $startversion = substr($componentname, 0, 60); # taking only the first 60 characters
18919d58b3aSEike Rathke	my $subid = installer::windows::msiglobal::calculate_id($componentname, 9); # taking only the first 9 digits
19019d58b3aSEike Rathke	my $shortcomponentname = $startversion . "_" . $subid;
191cdf0e10cSrcweir
19219d58b3aSEike Rathke	if ( exists($installer::globals::allshortcomponents{$shortcomponentname}) ) { installer::exiter::exit_program("Failed to create unique component name: \"$shortcomponentname\"", "generate_new_short_componentname"); }
193cdf0e10cSrcweir
194cdf0e10cSrcweir	$installer::globals::allshortcomponents{$shortcomponentname} = 1;
195cdf0e10cSrcweir
196cdf0e10cSrcweir	return $shortcomponentname;
197cdf0e10cSrcweir}
198cdf0e10cSrcweir
199cdf0e10cSrcweir###############################################
200cdf0e10cSrcweir# Generating the component name from a file
201cdf0e10cSrcweir###############################################
202cdf0e10cSrcweir
203cdf0e10cSrcweirsub get_file_component_name
204cdf0e10cSrcweir{
205cdf0e10cSrcweir	my ($fileref, $filesref) = @_;
206cdf0e10cSrcweir
207cdf0e10cSrcweir	my $componentname = "";
208cdf0e10cSrcweir
209cdf0e10cSrcweir	# Special handling for files with ASSIGNCOMPOMENT
210cdf0e10cSrcweir
211cdf0e10cSrcweir	my $styles = "";
212cdf0e10cSrcweir	if ( $fileref->{'Styles'} ) { $styles = $fileref->{'Styles'}; }
213cdf0e10cSrcweir	if ( $styles =~ /\bASSIGNCOMPOMENT\b/ )
214cdf0e10cSrcweir	{
215cdf0e10cSrcweir		$componentname = get_component_from_assigned_file($fileref->{'AssignComponent'}, $filesref);
216cdf0e10cSrcweir	}
217cdf0e10cSrcweir	else
218cdf0e10cSrcweir	{
219cdf0e10cSrcweir		# In this function exists the rule to create components from files
220cdf0e10cSrcweir		# Rule:
221cdf0e10cSrcweir		# Two files get the same componentid, if:
222cdf0e10cSrcweir		# both have the same destination directory.
223cdf0e10cSrcweir		# both have the same "gid" -> both were packed in the same zip file
224cdf0e10cSrcweir		# All other files are included into different components!
225cdf0e10cSrcweir
226cdf0e10cSrcweir		# my $componentname = $fileref->{'gid'} . "_" . $fileref->{'Dir'};
227cdf0e10cSrcweir
228cdf0e10cSrcweir		# $fileref->{'Dir'} is not sufficient! All files in a zip file have the same $fileref->{'Dir'},
229cdf0e10cSrcweir		# but can be in different subdirectories.
230cdf0e10cSrcweir		# Solution: destination=share\Scripts\beanshell\Capitalise\capitalise.bsh
231cdf0e10cSrcweir		# in which the filename (capitalise.bsh) has to be removed and all backslashes (slashes) are
232cdf0e10cSrcweir		# converted into underline.
233cdf0e10cSrcweir
234cdf0e10cSrcweir		my $destination = $fileref->{'destination'};
235cdf0e10cSrcweir		installer::pathanalyzer::get_path_from_fullqualifiedname(\$destination);
236cdf0e10cSrcweir		$destination =~ s/\s//g;
237cdf0e10cSrcweir		$destination =~ s/\\/\_/g;
238cdf0e10cSrcweir		$destination =~ s/\//\_/g;
239cdf0e10cSrcweir		$destination =~ s/\_\s*$//g;	# removing ending underline
240cdf0e10cSrcweir
241cdf0e10cSrcweir		$componentname = $fileref->{'gid'} . "__" . $destination;
242cdf0e10cSrcweir
243cdf0e10cSrcweir		# Files with different languages, need to be packed into different components.
244cdf0e10cSrcweir		# Then the installation of the language specific component is determined by a language condition.
245cdf0e10cSrcweir
246cdf0e10cSrcweir		if ( $fileref->{'ismultilingual'} )
247cdf0e10cSrcweir		{
248cdf0e10cSrcweir			my $officelanguage = $fileref->{'specificlanguage'};
249cdf0e10cSrcweir			$componentname = $componentname . "_" . $officelanguage;
250cdf0e10cSrcweir		}
251cdf0e10cSrcweir
252cdf0e10cSrcweir		$componentname = lc($componentname);	# componentnames always lowercase
253cdf0e10cSrcweir
254cdf0e10cSrcweir		$componentname =~ s/\-/\_/g;			# converting "-" to "_"
255cdf0e10cSrcweir		$componentname =~ s/\./\_/g;			# converting "-" to "_"
256cdf0e10cSrcweir
257cdf0e10cSrcweir		# Attention: Maximum length for the componentname is 72
258cdf0e10cSrcweir		# %installer::globals::allcomponents_in_this_database : resetted for each database
259cdf0e10cSrcweir		# %installer::globals::allcomponents : not resetted for each database
260cdf0e10cSrcweir		# Component strings must be unique for the complete product, because they are used for
261cdf0e10cSrcweir		# the creation of the globally unique identifier.
262cdf0e10cSrcweir
263cdf0e10cSrcweir		my $fullname = $componentname;  # This can be longer than 72
264cdf0e10cSrcweir
265cdf0e10cSrcweir		if (( exists($installer::globals::allcomponents{$fullname}) ) && ( ! exists($installer::globals::allcomponents_in_this_database{$fullname}) ))
266cdf0e10cSrcweir		{
267cdf0e10cSrcweir			# This is not allowed: One component cannot be installed with different packages.
268cdf0e10cSrcweir			installer::exiter::exit_program("ERROR: Component \"$fullname\" is already included into another package. This is not allowed.", "get_file_component_name");
269cdf0e10cSrcweir		}
270cdf0e10cSrcweir
271cdf0e10cSrcweir		if ( exists($installer::globals::allcomponents{$fullname}) )
272cdf0e10cSrcweir		{
273cdf0e10cSrcweir			$componentname = $installer::globals::allcomponents{$fullname};
274cdf0e10cSrcweir		}
275cdf0e10cSrcweir		else
276cdf0e10cSrcweir		{
27719d58b3aSEike Rathke			if ( length($componentname) > 70 )
278cdf0e10cSrcweir			{
279cdf0e10cSrcweir				$componentname = generate_new_short_componentname($componentname); # This has to be unique for the complete product, not only one package
280cdf0e10cSrcweir			}
281cdf0e10cSrcweir
282cdf0e10cSrcweir			$installer::globals::allcomponents{$fullname} = $componentname;
283cdf0e10cSrcweir			$installer::globals::allcomponents_in_this_database{$fullname} = 1;
284cdf0e10cSrcweir		}
285cdf0e10cSrcweir
286cdf0e10cSrcweir		# $componentname =~ s/gid_file_/g_f_/g;
287cdf0e10cSrcweir		# $componentname =~ s/_extra_/_e_/g;
288cdf0e10cSrcweir		# $componentname =~ s/_config_/_c_/g;
289cdf0e10cSrcweir		# $componentname =~ s/_org_openoffice_/_o_o_/g;
290cdf0e10cSrcweir		# $componentname =~ s/_program_/_p_/g;
291cdf0e10cSrcweir		# $componentname =~ s/_typedetection_/_td_/g;
292cdf0e10cSrcweir		# $componentname =~ s/_linguistic_/_l_/g;
293cdf0e10cSrcweir		# $componentname =~ s/_module_/_m_/g;
294cdf0e10cSrcweir		# $componentname =~ s/_optional_/_opt_/g;
295cdf0e10cSrcweir		# $componentname =~ s/_packages/_pack/g;
296cdf0e10cSrcweir		# $componentname =~ s/_menubar/_mb/g;
297cdf0e10cSrcweir		# $componentname =~ s/_common_/_cm_/g;
298cdf0e10cSrcweir		# $componentname =~ s/_export_/_exp_/g;
299cdf0e10cSrcweir		# $componentname =~ s/_table_/_tb_/g;
300cdf0e10cSrcweir		# $componentname =~ s/_sofficecfg_/_sc_/g;
301cdf0e10cSrcweir		# $componentname =~ s/_soffice_cfg_/_sc_/g;
302cdf0e10cSrcweir		# $componentname =~ s/_startmodulecommands_/_smc_/g;
303cdf0e10cSrcweir		# $componentname =~ s/_drawimpresscommands_/_dic_/g;
304cdf0e10cSrcweir		# $componentname =~ s/_basiccommands_/_bac_/g;
305cdf0e10cSrcweir		# $componentname =~ s/_basicidecommands_/_baic_/g;
306cdf0e10cSrcweir		# $componentname =~ s/_genericcommands_/_genc_/g;
307cdf0e10cSrcweir		# $componentname =~ s/_bibliographycommands_/_bibc_/g;
308cdf0e10cSrcweir		# $componentname =~ s/_gentiumbookbasicbolditalic_/_gbbbi_/g;
309cdf0e10cSrcweir		# $componentname =~ s/_share_/_s_/g;
310cdf0e10cSrcweir		# $componentname =~ s/_extension_/_ext_/g;
311cdf0e10cSrcweir		# $componentname =~ s/_extensions_/_exs_/g;
312cdf0e10cSrcweir		# $componentname =~ s/_modules_/_ms_/g;
313cdf0e10cSrcweir		# $componentname =~ s/_uiconfig_zip_/_ucz_/g;
314cdf0e10cSrcweir		# $componentname =~ s/_productivity_/_pr_/g;
315cdf0e10cSrcweir		# $componentname =~ s/_wizard_/_wz_/g;
316cdf0e10cSrcweir		# $componentname =~ s/_import_/_im_/g;
317cdf0e10cSrcweir		# $componentname =~ s/_javascript_/_js_/g;
318cdf0e10cSrcweir		# $componentname =~ s/_template_/_tpl_/g;
319cdf0e10cSrcweir		# $componentname =~ s/_tplwizletter_/_twl_/g;
320cdf0e10cSrcweir		# $componentname =~ s/_beanshell_/_bs_/g;
321cdf0e10cSrcweir		# $componentname =~ s/_presentation_/_bs_/g;
322cdf0e10cSrcweir		# $componentname =~ s/_columns_/_cls_/g;
323cdf0e10cSrcweir		# $componentname =~ s/_python_/_py_/g;
324cdf0e10cSrcweir
325cdf0e10cSrcweir		# $componentname =~ s/_tools/_ts/g;
326cdf0e10cSrcweir		# $componentname =~ s/_transitions/_trs/g;
327cdf0e10cSrcweir		# $componentname =~ s/_scriptbinding/_scrb/g;
328cdf0e10cSrcweir		# $componentname =~ s/_spreadsheet/_ssh/g;
329cdf0e10cSrcweir		# $componentname =~ s/_publisher/_pub/g;
330cdf0e10cSrcweir		# $componentname =~ s/_presenter/_pre/g;
331cdf0e10cSrcweir		# $componentname =~ s/_registry/_reg/g;
332cdf0e10cSrcweir
333cdf0e10cSrcweir		# $componentname =~ s/screen/sc/g;
334cdf0e10cSrcweir		# $componentname =~ s/wordml/wm/g;
335cdf0e10cSrcweir		# $componentname =~ s/openoffice/oo/g;
336cdf0e10cSrcweir	}
337cdf0e10cSrcweir
338cdf0e10cSrcweir	return $componentname;
339cdf0e10cSrcweir}
340cdf0e10cSrcweir
341cdf0e10cSrcweir####################################################################
342cdf0e10cSrcweir# Returning the component name for a defined file gid.
343cdf0e10cSrcweir# This is necessary for files with flag ASSIGNCOMPOMENT
344cdf0e10cSrcweir####################################################################
345cdf0e10cSrcweir
346cdf0e10cSrcweirsub get_component_from_assigned_file
347cdf0e10cSrcweir{
348cdf0e10cSrcweir	my ($gid, $filesref) = @_;
349cdf0e10cSrcweir
350cdf0e10cSrcweir	my $onefile = installer::existence::get_specified_file($filesref, $gid);
351cdf0e10cSrcweir	my $componentname = "";
352cdf0e10cSrcweir	if ( $onefile->{'componentname'} ) { $componentname = $onefile->{'componentname'}; }
353cdf0e10cSrcweir	else { installer::exiter::exit_program("ERROR: No component defined for file: $gid", "get_component_from_assigned_file"); }
354cdf0e10cSrcweir
355cdf0e10cSrcweir	return $componentname;
356cdf0e10cSrcweir}
357cdf0e10cSrcweir
358cdf0e10cSrcweir####################################################################
359cdf0e10cSrcweir# Generating the special filename for the database file File.idt
360cdf0e10cSrcweir# Sample: CONTEXTS, CONTEXTS1
361cdf0e10cSrcweir# This name has to be unique.
362cdf0e10cSrcweir# In most cases this is simply the filename.
363cdf0e10cSrcweir####################################################################
364cdf0e10cSrcweir
3659f91b7e3SAndre Fischersub generate_unique_filename_for_filetable ($)
366cdf0e10cSrcweir{
3679f91b7e3SAndre Fischer	my ($oldname) = @_;
368cdf0e10cSrcweir
369cdf0e10cSrcweir	# This new filename has to be saved into $fileref, because this is needed to find the source.
370cdf0e10cSrcweir	# The filename sbasic.idx/OFFSETS is changed to OFFSETS, but OFFSETS is not unique.
371cdf0e10cSrcweir	# In this procedure names like OFFSETS5 are produced. And exactly this string has to be added to
372cdf0e10cSrcweir	# the array of all files.
373cdf0e10cSrcweir
3749f91b7e3SAndre Fischer	my $uniquefilename = $oldname;
3759f91b7e3SAndre Fischer    if ( ! defined $uniquefilename || $uniquefilename eq "")
3769f91b7e3SAndre Fischer    {
3779f91b7e3SAndre Fischer        installer::logger::PrintError("file name does not exist or is empty, can not create unique name for it.");
3789f91b7e3SAndre Fischer        die;
3799f91b7e3SAndre Fischer        return;
3809f91b7e3SAndre Fischer    }
381cdf0e10cSrcweir
3821ba1fd99SAndre Fischer   	# making /registry/schema/org/openoffice/VCL.xcs to VCL.xcs
3831ba1fd99SAndre Fischer	installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$uniquefilename);
384cdf0e10cSrcweir
385cdf0e10cSrcweir	$uniquefilename =~ s/\-/\_/g;		# no "-" allowed
386cdf0e10cSrcweir	$uniquefilename =~ s/\@/\_/g;		# no "@" allowed
387cdf0e10cSrcweir	$uniquefilename =~ s/\$/\_/g;		# no "$" allowed
388cdf0e10cSrcweir	$uniquefilename =~ s/^\s*\./\_/g;		# no "." at the beginning allowed allowed
389cdf0e10cSrcweir	$uniquefilename =~ s/^\s*\d/\_d/g;		# no number at the beginning allowed allowed (even file "0.gif", replacing to "_d.gif")
390cdf0e10cSrcweir	$uniquefilename =~ s/org_openoffice_/ooo_/g;	# shorten the unique file name
391cdf0e10cSrcweir
392cdf0e10cSrcweir	my $lcuniquefilename = lc($uniquefilename);	# only lowercase names
393cdf0e10cSrcweir
394cdf0e10cSrcweir	my $newname = 0;
395cdf0e10cSrcweir
3961ba1fd99SAndre Fischer	if ( ! exists($installer::globals::alllcuniquefilenames{$lcuniquefilename}))
397cdf0e10cSrcweir	{
398cdf0e10cSrcweir		$installer::globals::alluniquefilenames{$uniquefilename} = 1;
399cdf0e10cSrcweir		$installer::globals::alllcuniquefilenames{$lcuniquefilename} = 1;
400cdf0e10cSrcweir		$newname = 1;
401cdf0e10cSrcweir	}
402cdf0e10cSrcweir
403cdf0e10cSrcweir	if ( ! $newname )
404cdf0e10cSrcweir	{
405cdf0e10cSrcweir		# adding a number until the name is really unique: OFFSETS, OFFSETS1, OFFSETS2, ...
406cdf0e10cSrcweir		# But attention: Making "abc.xcu" to "abc1.xcu"
407cdf0e10cSrcweir
408cdf0e10cSrcweir		my $uniquefilenamebase = $uniquefilename;
409cdf0e10cSrcweir
4109f91b7e3SAndre Fischer        my $counter = 0;
411cdf0e10cSrcweir		do
412cdf0e10cSrcweir		{
413cdf0e10cSrcweir			$counter++;
414cdf0e10cSrcweir
415cdf0e10cSrcweir			if ( $uniquefilenamebase =~ /\./ )
416cdf0e10cSrcweir			{
417cdf0e10cSrcweir				$uniquefilename = $uniquefilenamebase;
418cdf0e10cSrcweir				$uniquefilename =~ s/\./$counter\./;
419cdf0e10cSrcweir			}
420cdf0e10cSrcweir			else
421cdf0e10cSrcweir			{
422cdf0e10cSrcweir				$uniquefilename = $uniquefilenamebase . $counter;
423cdf0e10cSrcweir			}
424cdf0e10cSrcweir
425cdf0e10cSrcweir			$newname = 0;
426cdf0e10cSrcweir			$lcuniquefilename = lc($uniquefilename);	# only lowercase names
427cdf0e10cSrcweir
4281ba1fd99SAndre Fischer			if ( ! exists($installer::globals::alllcuniquefilenames{$lcuniquefilename}))
429cdf0e10cSrcweir			{
430cdf0e10cSrcweir				$installer::globals::alluniquefilenames{$uniquefilename} = 1;
431cdf0e10cSrcweir				$installer::globals::alllcuniquefilenames{$lcuniquefilename} = 1;
432cdf0e10cSrcweir				$newname = 1;
433cdf0e10cSrcweir			}
434cdf0e10cSrcweir		}
435cdf0e10cSrcweir		until ( $newname )
436cdf0e10cSrcweir	}
437cdf0e10cSrcweir
438cdf0e10cSrcweir	return $uniquefilename;
439cdf0e10cSrcweir}
440cdf0e10cSrcweir
441cdf0e10cSrcweir####################################################################
442cdf0e10cSrcweir# Generating the special file column for the database file File.idt
443cdf0e10cSrcweir# Sample: NAMETR~1.TAB|.nametranslation.table
444cdf0e10cSrcweir# The first part has to be 8.3 conform.
445cdf0e10cSrcweir####################################################################
446cdf0e10cSrcweir
447dca4887fSAndre Fischersub generate_filename_for_filetable ($$)
448cdf0e10cSrcweir{
449dca4887fSAndre Fischer	my ($fileref, $shortnamesref) = @_;
450cdf0e10cSrcweir
451cdf0e10cSrcweir	my $returnstring = "";
452cdf0e10cSrcweir
453cdf0e10cSrcweir	my $filename = $fileref->{'Name'};
4541ba1fd99SAndre Fischer
4551ba1fd99SAndre Fischer    # making /registry/schema/org/openoffice/VCL.xcs to VCL.xcs
4561ba1fd99SAndre Fischer	installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$filename);
457cdf0e10cSrcweir
4581ba1fd99SAndre Fischer	my $shortstring = installer::windows::idtglobal::make_eight_three_conform_with_hash($filename, "file", $shortnamesref);
459cdf0e10cSrcweir
4601ba1fd99SAndre Fischer	if ( $shortstring eq $filename )
4611ba1fd99SAndre Fischer    {
4621ba1fd99SAndre Fischer        # nothing changed
4631ba1fd99SAndre Fischer        $returnstring = $filename;
4641ba1fd99SAndre Fischer    }
465cdf0e10cSrcweir	else
4661ba1fd99SAndre Fischer    {
4671ba1fd99SAndre Fischer        $returnstring = $shortstring . "\|" . $filename;
4681ba1fd99SAndre Fischer    }
469cdf0e10cSrcweir
470cdf0e10cSrcweir	return $returnstring;
471cdf0e10cSrcweir}
472cdf0e10cSrcweir
473cdf0e10cSrcweir#########################################
474cdf0e10cSrcweir# Returning the filesize of a file
475cdf0e10cSrcweir#########################################
476cdf0e10cSrcweir
477cdf0e10cSrcweirsub get_filesize
478cdf0e10cSrcweir{
479cdf0e10cSrcweir	my ($fileref) = @_;
480cdf0e10cSrcweir
481cdf0e10cSrcweir	my $file = $fileref->{'sourcepath'};
482cdf0e10cSrcweir
483cdf0e10cSrcweir	my $filesize;
484cdf0e10cSrcweir
485cdf0e10cSrcweir	if ( -f $file )	# test of existence. For instance services.rdb does not always exist
486cdf0e10cSrcweir	{
487cdf0e10cSrcweir		$filesize = ( -s $file );	# file size can be "0"
488cdf0e10cSrcweir	}
489cdf0e10cSrcweir	else
490cdf0e10cSrcweir	{
491cdf0e10cSrcweir		$filesize = -1;
492cdf0e10cSrcweir	}
493cdf0e10cSrcweir
494cdf0e10cSrcweir	return $filesize;
495cdf0e10cSrcweir}
496cdf0e10cSrcweir
497cdf0e10cSrcweir#############################################
498cdf0e10cSrcweir# Returning the file version, if required
499cdf0e10cSrcweir# Sample: "8.0.1.8976";
500cdf0e10cSrcweir#############################################
501cdf0e10cSrcweir
502cdf0e10cSrcweirsub get_fileversion
503cdf0e10cSrcweir{
5049f91b7e3SAndre Fischer	my ($onefile, $allvariables) = @_;
505cdf0e10cSrcweir
506cdf0e10cSrcweir	my $fileversion = "";
507cdf0e10cSrcweir
508cdf0e10cSrcweir	if ( $allvariables->{'USE_FILEVERSION'} )
509cdf0e10cSrcweir	{
5101ba1fd99SAndre Fischer		if ( ! $allvariables->{'LIBRARYVERSION'} )
5111ba1fd99SAndre Fischer        {
5121ba1fd99SAndre Fischer            installer::exiter::exit_program("ERROR: USE_FILEVERSION is set, but not LIBRARYVERSION", "get_fileversion");
5131ba1fd99SAndre Fischer        }
514cdf0e10cSrcweir		my $libraryversion = $allvariables->{'LIBRARYVERSION'};
515cdf0e10cSrcweir		if ( $libraryversion =~ /^\s*(\d+)\.(\d+)\.(\d+)\s*$/ )
516cdf0e10cSrcweir		{
517cdf0e10cSrcweir			my $major = $1;
518cdf0e10cSrcweir			my $minor = $2;
519cdf0e10cSrcweir			my $micro = $3;
520cdf0e10cSrcweir			my $concat = 100 * $minor + $micro;
521cdf0e10cSrcweir			$libraryversion = $major . "\." . $concat;
522cdf0e10cSrcweir		}
523cdf0e10cSrcweir		my $vendornumber = 0;
5241ba1fd99SAndre Fischer		if ( $allvariables->{'VENDORPATCHVERSION'} )
5251ba1fd99SAndre Fischer        {
5261ba1fd99SAndre Fischer            $vendornumber = $allvariables->{'VENDORPATCHVERSION'};
5271ba1fd99SAndre Fischer        }
528cdf0e10cSrcweir		$fileversion = $libraryversion . "\." . $installer::globals::buildid . "\." . $vendornumber;
5291ba1fd99SAndre Fischer		if ( $onefile->{'FileVersion'} )
5301ba1fd99SAndre Fischer        {
5311ba1fd99SAndre Fischer            # overriding FileVersion in scp
5321ba1fd99SAndre Fischer            $fileversion = $onefile->{'FileVersion'};
5331ba1fd99SAndre Fischer        }
534cdf0e10cSrcweir	}
535cdf0e10cSrcweir
5361ba1fd99SAndre Fischer	if ( $installer::globals::prepare_winpatch )
5371ba1fd99SAndre Fischer    {
5381ba1fd99SAndre Fischer        # Windows patches do not allow this version # -> who says so?
5391ba1fd99SAndre Fischer        $fileversion = "";
5401ba1fd99SAndre Fischer    }
541cdf0e10cSrcweir
542cdf0e10cSrcweir	return $fileversion;
543cdf0e10cSrcweir}
544cdf0e10cSrcweir
5459f91b7e3SAndre Fischer
5469f91b7e3SAndre Fischer
5479f91b7e3SAndre Fischer
5489f91b7e3SAndre Fischersub retrieve_sequence_and_uniquename ($$)
5499f91b7e3SAndre Fischer{
5509f91b7e3SAndre Fischer    my ($file_list, $source_data) = @_;
5519f91b7e3SAndre Fischer
5529f91b7e3SAndre Fischer    my @added_files = ();
5539f91b7e3SAndre Fischer
5549f91b7e3SAndre Fischer    # Read the sequence numbers of the previous version.
5559f91b7e3SAndre Fischer    if ($installer::globals::is_release)
5569f91b7e3SAndre Fischer    {
5579f91b7e3SAndre Fischer        foreach my $file (@$file_list)
5589f91b7e3SAndre Fischer        {
5599f91b7e3SAndre Fischer            # Use the source path of the file as key to retrieve sequence number and unique name.
5609f91b7e3SAndre Fischer            # The source path is the part of the 'destination' without the first part.
5619f91b7e3SAndre Fischer            # There is a special case when 'Dir' is PREDEFINED_OSSHELLNEWDIR.
5629f91b7e3SAndre Fischer            my $source_path;
5639f91b7e3SAndre Fischer            if (defined $file->{'Dir'} && $file->{'Dir'} eq "PREDEFINED_OSSHELLNEWDIR")
5649f91b7e3SAndre Fischer            {
5659f91b7e3SAndre Fischer                $source_path = $installer::globals::templatefoldername
5669f91b7e3SAndre Fischer                    . $installer::globals::separator
5679f91b7e3SAndre Fischer                    . $file->{'Name'};
5689f91b7e3SAndre Fischer            }
5699f91b7e3SAndre Fischer            else
5709f91b7e3SAndre Fischer            {
5719f91b7e3SAndre Fischer                $source_path = $file->{'destination'};
5729f91b7e3SAndre Fischer                $source_path =~ s/^[^\/]+\///;
5739f91b7e3SAndre Fischer            }
5749f91b7e3SAndre Fischer            my ($sequence, $uniquename) = $source_data->get_sequence_and_unique_name($source_path);
5759f91b7e3SAndre Fischer            if (defined $sequence && defined $uniquename)
5769f91b7e3SAndre Fischer            {
5779f91b7e3SAndre Fischer                $file->{'sequencenumber'} = $sequence;
5789f91b7e3SAndre Fischer                $file->{'uniquename'} = $uniquename;
5799f91b7e3SAndre Fischer            }
5809f91b7e3SAndre Fischer            else
5819f91b7e3SAndre Fischer            {
5829f91b7e3SAndre Fischer                # No data found in the source release.  File has been added.
5839f91b7e3SAndre Fischer                push @added_files, $file;
5849f91b7e3SAndre Fischer            }
5859f91b7e3SAndre Fischer        }
5869f91b7e3SAndre Fischer    }
5879f91b7e3SAndre Fischer
5889f91b7e3SAndre Fischer    return @added_files;
5899f91b7e3SAndre Fischer}
5909f91b7e3SAndre Fischer
5919f91b7e3SAndre Fischer
5929f91b7e3SAndre Fischer
5939f91b7e3SAndre Fischer
5949f91b7e3SAndre Fischer=head2 assign_mssing_sequence_numbers ($file_list)
5959f91b7e3SAndre Fischer
5969f91b7e3SAndre Fischer    Assign sequence numbers where still missing.
5979f91b7e3SAndre Fischer
5989f91b7e3SAndre Fischer    When we are preparing a patch then all files that have no sequence numbers
5999f91b7e3SAndre Fischer    at this point are new.  Otherwise no file has a sequence number yet.
6009f91b7e3SAndre Fischer
6019f91b7e3SAndre Fischer=cut
6029f91b7e3SAndre Fischersub assign_missing_sequence_numbers ($)
6039f91b7e3SAndre Fischer{
6049f91b7e3SAndre Fischer    my ($file_list) = @_;
6059f91b7e3SAndre Fischer
6069f91b7e3SAndre Fischer    # First, set up a hash on the sequence numbers that are already in use.
6079f91b7e3SAndre Fischer    my %used_sequence_numbers = ();
6089f91b7e3SAndre Fischer    foreach my $file (@$file_list)
6099f91b7e3SAndre Fischer    {
6109f91b7e3SAndre Fischer        next unless defined $file->{'sequencenumber'};
6119f91b7e3SAndre Fischer        $used_sequence_numbers{$file->{'sequencenumber'}} = 1;
6129f91b7e3SAndre Fischer    }
6139f91b7e3SAndre Fischer
6149f91b7e3SAndre Fischer    # Assign sequence numbers.  Try consecutive numbers, starting at 1.
6159f91b7e3SAndre Fischer    my $current_sequence_number = 1;
6169f91b7e3SAndre Fischer    foreach my $file (@$file_list)
6179f91b7e3SAndre Fischer    {
6189f91b7e3SAndre Fischer        # Skip over all files that already have sequence numbers.
6199f91b7e3SAndre Fischer        next if defined $file->{'sequencenumber'};
6209f91b7e3SAndre Fischer
6219f91b7e3SAndre Fischer        # Find the next available number.
6229f91b7e3SAndre Fischer        while (defined $used_sequence_numbers{$current_sequence_number})
6239f91b7e3SAndre Fischer        {
6249f91b7e3SAndre Fischer            ++$current_sequence_number;
6259f91b7e3SAndre Fischer        }
6269f91b7e3SAndre Fischer
6279f91b7e3SAndre Fischer        # Use the number and mark it as used.
6289f91b7e3SAndre Fischer        $file->{'sequencenumber'} = $current_sequence_number;
6299f91b7e3SAndre Fischer        $used_sequence_numbers{$current_sequence_number} = 1;
6309f91b7e3SAndre Fischer    }
6319f91b7e3SAndre Fischer}
6329f91b7e3SAndre Fischer
6339f91b7e3SAndre Fischer
6349f91b7e3SAndre Fischer
6359f91b7e3SAndre Fischer
6369f91b7e3SAndre Fischersub create_items_for_missing_files ($$$)
6379f91b7e3SAndre Fischer{
638*677600b0SAndre Fischer    my ($missing_items, $source_msi, $directory_list) = @_;
6399f91b7e3SAndre Fischer
6409f91b7e3SAndre Fischer    # For creation of the FeatureComponent table (in a later step) we
6419f91b7e3SAndre Fischer    # have to provide references from the file to component and
6429f91b7e3SAndre Fischer    # modules (ie features).  Note that Each file belongs to exactly
6439f91b7e3SAndre Fischer    # one component but one component can belong to multiple features.
644*677600b0SAndre Fischer    my $component_to_features_map = create_feature_component_map($source_msi);
6459f91b7e3SAndre Fischer
6469f91b7e3SAndre Fischer    my @new_files = ();
6479f91b7e3SAndre Fischer    foreach my $row (@$missing_items)
6489f91b7e3SAndre Fischer    {
6499f91b7e3SAndre Fischer        $installer::logger::Info->printf("creating new file item for '%s'\n", $row->GetValue('File'));
650*677600b0SAndre Fischer        my $file_item = create_script_item_for_deleted_file($row, $source_msi, $component_to_features_map);
6519f91b7e3SAndre Fischer        push @new_files, $file_item;
6529f91b7e3SAndre Fischer    }
6539f91b7e3SAndre Fischer
6549f91b7e3SAndre Fischer    return @new_files;
6559f91b7e3SAndre Fischer}
6569f91b7e3SAndre Fischer
6579f91b7e3SAndre Fischer
6589f91b7e3SAndre Fischer
6599f91b7e3SAndre Fischer
660*677600b0SAndre Fischer=head2 create_script_item_for_deleted_file (($file_row, $source_msi, $component_to_features_map)
661*677600b0SAndre Fischer
662*677600b0SAndre Fischer    Create a new script item for a file that was present in the
663*677600b0SAndre Fischer    previous release but isn't anymore.  Most of the necessary
664*677600b0SAndre Fischer    information is taken from the 'File' table of the source release.
665*677600b0SAndre Fischer
666*677600b0SAndre Fischer    The values of 'sourcepath' and 'cyg_sourcepath' will point to the
667*677600b0SAndre Fischer    respective file in the unpacked source release.  An alternative
668*677600b0SAndre Fischer    would be to let them point to an empty file.  That, however, might
669*677600b0SAndre Fischer    make the patch bigger (diff between identical file contents is
670*677600b0SAndre Fischer    (almost) empty, diff between file and empty file is the 'inverse'
671*677600b0SAndre Fischer    of the file).
672*677600b0SAndre Fischer
673*677600b0SAndre Fischer=cut
674*677600b0SAndre Fischer
675*677600b0SAndre Fischermy $use_source_files_for_missing_files = 1;
676*677600b0SAndre Fischer
6779f91b7e3SAndre Fischersub create_script_item_for_deleted_file ($$$)
6789f91b7e3SAndre Fischer{
679*677600b0SAndre Fischer    my ($file_row, $source_msi, $component_to_features_map) = @_;
6809f91b7e3SAndre Fischer
6819f91b7e3SAndre Fischer    my $uniquename = $file_row->GetValue('File');
6829f91b7e3SAndre Fischer
683*677600b0SAndre Fischer    my $file_map = $source_msi->GetFileMap();
6849f91b7e3SAndre Fischer
685*677600b0SAndre Fischer    my $file_item = $file_map->{$uniquename};
686*677600b0SAndre Fischer    my $directory_item = $file_item->{'directory'};
6879f91b7e3SAndre Fischer    my $source_path = $directory_item->{'full_source_long_name'};
6889f91b7e3SAndre Fischer    my $target_path = $directory_item->{'full_target_long_name'};
689*677600b0SAndre Fischer    my $full_source_name = undef;
690*677600b0SAndre Fischer    if ($use_source_files_for_missing_files)
691*677600b0SAndre Fischer    {
692*677600b0SAndre Fischer        $full_source_name = File::Spec->catfile(
693*677600b0SAndre Fischer            installer::patch::InstallationSet::GetUnpackedCabPath(
694*677600b0SAndre Fischer                $source_msi->{'version'},
695*677600b0SAndre Fischer                $source_msi->{'is_current_version'},
696*677600b0SAndre Fischer                $source_msi->{'language'},
697*677600b0SAndre Fischer                $source_msi->{'package_format'},
698*677600b0SAndre Fischer                $source_msi->{'product_name'}),
699*677600b0SAndre Fischer            $source_path,
700*677600b0SAndre Fischer            $file_item->{'long_name'});
701*677600b0SAndre Fischer    }
702*677600b0SAndre Fischer    else
703*677600b0SAndre Fischer    {
704*677600b0SAndre Fischer        $full_source_name = "/c/tmp/missing/".$uniquename;
705*677600b0SAndre Fischer        installer::patch::Tools::touch($full_source_name);
706*677600b0SAndre Fischer    }
7079f91b7e3SAndre Fischer    my ($long_name, undef) = installer::patch::Msi::SplitLongShortName($file_row->GetValue("FileName"));
7089f91b7e3SAndre Fischer    my $target_name = File::Spec->catfile($target_path, $long_name);
7099f91b7e3SAndre Fischer    if ( ! -f $full_source_name)
7109f91b7e3SAndre Fischer    {
7119f91b7e3SAndre Fischer        installer::logger::PrintError("can not find file '%s' in previous version (tried '%s')\n",
7129f91b7e3SAndre Fischer            $uniquename,
7139f91b7e3SAndre Fischer            $full_source_name);
7149f91b7e3SAndre Fischer        return undef;
7159f91b7e3SAndre Fischer    }
7169f91b7e3SAndre Fischer    my $cygwin_full_source_name = qx(cygpath -w '$full_source_name');
7179f91b7e3SAndre Fischer    my $component_name = $file_row->GetValue('Component_');
7189f91b7e3SAndre Fischer    my $module_names = join(",", @{$component_to_features_map->{$component_name}});
7199f91b7e3SAndre Fischer    my $sequence_number = $file_row->GetValue('Sequence');
7209f91b7e3SAndre Fischer
7219f91b7e3SAndre Fischer    return {
7229f91b7e3SAndre Fischer        'uniquename' => $uniquename,
7239f91b7e3SAndre Fischer        'destination' => $target_name,
7249f91b7e3SAndre Fischer        'componentname' => $component_name,
7259f91b7e3SAndre Fischer        'modules' => $module_names,
7269f91b7e3SAndre Fischer        'UnixRights' => 444,
7279f91b7e3SAndre Fischer        'Name' => $long_name,
7289f91b7e3SAndre Fischer        'sourcepath' => $full_source_name,
7299f91b7e3SAndre Fischer        'cyg_sourcepath' => $cygwin_full_source_name,
7309f91b7e3SAndre Fischer        'sequencenumber' => $sequence_number
7319f91b7e3SAndre Fischer        };
7329f91b7e3SAndre Fischer}
7339f91b7e3SAndre Fischer
7349f91b7e3SAndre Fischer
7359f91b7e3SAndre Fischer
7369f91b7e3SAndre Fischer
7379f91b7e3SAndre Fischer=head2 create_feature_component_maps($msi)
7389f91b7e3SAndre Fischer
7399f91b7e3SAndre Fischer    Return a hash map that maps from component names to arrays of
7409f91b7e3SAndre Fischer    feature names.  In most cases the array of features contains only
7419f91b7e3SAndre Fischer    one element.  But there can be cases where the number is greater.
7429f91b7e3SAndre Fischer
7439f91b7e3SAndre Fischer=cut
7449f91b7e3SAndre Fischersub create_feature_component_map ($)
7459f91b7e3SAndre Fischer{
7469f91b7e3SAndre Fischer    my ($msi) = @_;
7479f91b7e3SAndre Fischer
7489f91b7e3SAndre Fischer    my $component_to_features_map = {};
7499f91b7e3SAndre Fischer    my $feature_component_table = $msi->GetTable("FeatureComponents");
7509f91b7e3SAndre Fischer    my $feature_column_index = $feature_component_table->GetColumnIndex("Feature_");
7519f91b7e3SAndre Fischer    my $component_column_index = $feature_component_table->GetColumnIndex("Component_");
7529f91b7e3SAndre Fischer    foreach my $row (@{$feature_component_table->GetAllRows()})
7539f91b7e3SAndre Fischer    {
7549f91b7e3SAndre Fischer        my $feature = $row->GetValue($feature_column_index);
7559f91b7e3SAndre Fischer        my $component = $row->GetValue($component_column_index);
7569f91b7e3SAndre Fischer        if ( ! defined $component_to_features_map->{$component})
7579f91b7e3SAndre Fischer        {
7589f91b7e3SAndre Fischer            $component_to_features_map->{$component} = [$feature];
7599f91b7e3SAndre Fischer        }
7609f91b7e3SAndre Fischer        else
7619f91b7e3SAndre Fischer        {
7629f91b7e3SAndre Fischer            push @{$component_to_features_map->{$component}}, $feature;
7639f91b7e3SAndre Fischer        }
7649f91b7e3SAndre Fischer    }
7659f91b7e3SAndre Fischer
7669f91b7e3SAndre Fischer    return $component_to_features_map;
7679f91b7e3SAndre Fischer}
7689f91b7e3SAndre Fischer
7699f91b7e3SAndre Fischer
770cdf0e10cSrcweir#############################################
771cdf0e10cSrcweir# Returning the Windows language of a file
772cdf0e10cSrcweir#############################################
773cdf0e10cSrcweir
774cdf0e10cSrcweirsub get_language_for_file
775cdf0e10cSrcweir{
776cdf0e10cSrcweir	my ($fileref) = @_;
777cdf0e10cSrcweir
778cdf0e10cSrcweir	my $language = "";
779cdf0e10cSrcweir
780cdf0e10cSrcweir	if ( $fileref->{'specificlanguage'} ) { $language = $fileref->{'specificlanguage'}; }
781cdf0e10cSrcweir
782cdf0e10cSrcweir	if ( $language eq "" )
783cdf0e10cSrcweir	{
784cdf0e10cSrcweir		$language = 0;  # language independent
785cdf0e10cSrcweir		# If this is not a font, the return value should be "0" (Check ICE 60)
786cdf0e10cSrcweir		my $styles = "";
787cdf0e10cSrcweir		if ( $fileref->{'Styles'} ) { $styles = $fileref->{'Styles'}; }
788cdf0e10cSrcweir		if ( $styles =~ /\bFONT\b/ ) { $language = ""; }
789cdf0e10cSrcweir	}
790cdf0e10cSrcweir	else
791cdf0e10cSrcweir	{
792cdf0e10cSrcweir		$language = installer::windows::language::get_windows_language($language);
793cdf0e10cSrcweir	}
794cdf0e10cSrcweir
795cdf0e10cSrcweir	return $language;
796cdf0e10cSrcweir}
797cdf0e10cSrcweir
798cdf0e10cSrcweir####################################################################
799cdf0e10cSrcweir# Creating a new KeyPath for components in TemplatesFolder.
800cdf0e10cSrcweir####################################################################
801cdf0e10cSrcweir
802cdf0e10cSrcweirsub generate_registry_keypath
803cdf0e10cSrcweir{
804cdf0e10cSrcweir	my ($onefile) = @_;
805cdf0e10cSrcweir
806cdf0e10cSrcweir	my $keypath = $onefile->{'Name'};
807cdf0e10cSrcweir	$keypath =~ s/\.//g;
808cdf0e10cSrcweir	$keypath = lc($keypath);
809cdf0e10cSrcweir	$keypath = "userreg_" . $keypath;
810cdf0e10cSrcweir
811cdf0e10cSrcweir	return $keypath;
812cdf0e10cSrcweir}
813cdf0e10cSrcweir
8149f91b7e3SAndre Fischer
815cdf0e10cSrcweir###################################################################
816cdf0e10cSrcweir# Collecting further conditions for the component table.
817cdf0e10cSrcweir# This is used by multilayer products, to enable installation
818cdf0e10cSrcweir# of separate layers.
819cdf0e10cSrcweir###################################################################
820cdf0e10cSrcweir
821cdf0e10cSrcweirsub get_tree_condition_for_component
822cdf0e10cSrcweir{
823cdf0e10cSrcweir	my ($onefile, $componentname) = @_;
824cdf0e10cSrcweir
825cdf0e10cSrcweir	if ( $onefile->{'destination'} )
826cdf0e10cSrcweir	{
827cdf0e10cSrcweir		my $dest = $onefile->{'destination'};
828cdf0e10cSrcweir
829cdf0e10cSrcweir		# Comparing the destination path with
830cdf0e10cSrcweir		# $installer::globals::hostnametreestyles{$hostname} = $treestyle;
831cdf0e10cSrcweir		# (-> hostname is the key, the style the value!)
832cdf0e10cSrcweir
833cdf0e10cSrcweir		foreach my $hostname ( keys %installer::globals::hostnametreestyles )
834cdf0e10cSrcweir		{
835cdf0e10cSrcweir			if (( $dest eq $hostname ) || ( $dest =~ /^\s*\Q$hostname\E\\/ ))
836cdf0e10cSrcweir			{
837cdf0e10cSrcweir				# the value is the style
838cdf0e10cSrcweir				my $style = $installer::globals::hostnametreestyles{$hostname};
839cdf0e10cSrcweir				# the condition is saved in %installer::globals::treestyles
840cdf0e10cSrcweir				my $condition = $installer::globals::treestyles{$style};
841cdf0e10cSrcweir				# Saving condition to be added in table Property
842cdf0e10cSrcweir				$installer::globals::usedtreeconditions{$condition} = 1;
843cdf0e10cSrcweir				$condition = $condition . "=1";
844cdf0e10cSrcweir				# saving this condition
845cdf0e10cSrcweir				$installer::globals::treeconditions{$componentname} = $condition;
846cdf0e10cSrcweir
847cdf0e10cSrcweir				# saving also at the file, for usage in fileinfo
848cdf0e10cSrcweir				$onefile->{'layer'} = $installer::globals::treelayername{$style};
849cdf0e10cSrcweir			}
850cdf0e10cSrcweir		}
851cdf0e10cSrcweir	}
852cdf0e10cSrcweir}
853cdf0e10cSrcweir
854cdf0e10cSrcweir############################################
855cdf0e10cSrcweir# Collecting all short names, that are
856cdf0e10cSrcweir# already used by the old database
857cdf0e10cSrcweir############################################
858cdf0e10cSrcweir
859cdf0e10cSrcweirsub collect_shortnames_from_old_database
860cdf0e10cSrcweir{
861cdf0e10cSrcweir	my ($uniquefilenamehashref, $shortnameshashref) = @_;
862cdf0e10cSrcweir
863cdf0e10cSrcweir	foreach my $key ( keys %{$uniquefilenamehashref} )
864cdf0e10cSrcweir	{
865cdf0e10cSrcweir		my $value = $uniquefilenamehashref->{$key};  # syntax of $value: ($uniquename;$shortname)
866cdf0e10cSrcweir
867cdf0e10cSrcweir		if ( $value =~ /^\s*(.*?)\;\s*(.*?)\s*$/ )
868cdf0e10cSrcweir		{
869cdf0e10cSrcweir			my $shortstring = $2;
870cdf0e10cSrcweir			$shortnameshashref->{$shortstring} = 1;	# adding the shortname to the array of all shortnames
871cdf0e10cSrcweir		}
872cdf0e10cSrcweir	}
873cdf0e10cSrcweir}
874cdf0e10cSrcweir
875cdf0e10cSrcweir
8769f91b7e3SAndre Fischersub process_language_conditions ($)
877cdf0e10cSrcweir{
8789f91b7e3SAndre Fischer    my ($onefile) = @_;
8799f91b7e3SAndre Fischer
8809f91b7e3SAndre Fischer    # Collecting all languages specific conditions
8819f91b7e3SAndre Fischer    if ( $onefile->{'ismultilingual'} )
8829f91b7e3SAndre Fischer    {
8839f91b7e3SAndre Fischer        if ( $onefile->{'ComponentCondition'} )
8849f91b7e3SAndre Fischer        {
8859f91b7e3SAndre Fischer            installer::exiter::exit_program(
8869f91b7e3SAndre Fischer                "ERROR: Cannot set language condition. There is already another component condition for file $onefile->{'gid'}: \"$onefile->{'ComponentCondition'}\" !", "create_files_table");
8879f91b7e3SAndre Fischer        }
888cdf0e10cSrcweir
8899f91b7e3SAndre Fischer        if ( $onefile->{'specificlanguage'} eq "" )
8909f91b7e3SAndre Fischer        {
8919f91b7e3SAndre Fischer            installer::exiter::exit_program(
8929f91b7e3SAndre Fischer                "ERROR: There is no specific language for file at language module: $onefile->{'gid'} !", "create_files_table");
8939f91b7e3SAndre Fischer        }
8949f91b7e3SAndre Fischer        my $locallanguage = $onefile->{'specificlanguage'};
8959f91b7e3SAndre Fischer        my $property = "IS" . $onefile->{'windows_language'};
8969f91b7e3SAndre Fischer        my $value = 1;
8979f91b7e3SAndre Fischer        my $condition = $property . "=" . $value;
8989f91b7e3SAndre Fischer
8999f91b7e3SAndre Fischer        $onefile->{'ComponentCondition'} = $condition;
9009f91b7e3SAndre Fischer
9019f91b7e3SAndre Fischer        if ( exists($installer::globals::componentcondition{$onefile->{'componentname'}}))
9029f91b7e3SAndre Fischer        {
9039f91b7e3SAndre Fischer            if ( $installer::globals::componentcondition{$onefile->{'componentname'}} ne $condition )
9049f91b7e3SAndre Fischer            {
9059f91b7e3SAndre Fischer                installer::exiter::exit_program(
9069f91b7e3SAndre Fischer                    sprintf(
9079f91b7e3SAndre Fischer                        "ERROR: There is already another component condition for file %s: \"%s\" and \"%s\" !",
9089f91b7e3SAndre Fischer                        $onefile->{'gid'},
9099f91b7e3SAndre Fischer                        $installer::globals::componentcondition{$onefile->{'componentname'}},
9109f91b7e3SAndre Fischer                        $condition),
9119f91b7e3SAndre Fischer                    "create_files_table");
9129f91b7e3SAndre Fischer            }
9139f91b7e3SAndre Fischer        }
9149f91b7e3SAndre Fischer        else
9159f91b7e3SAndre Fischer        {
9169f91b7e3SAndre Fischer            $installer::globals::componentcondition{$onefile->{'componentname'}} = $condition;
9179f91b7e3SAndre Fischer        }
918cdf0e10cSrcweir
9199f91b7e3SAndre Fischer        # collecting all properties for table Property
9209f91b7e3SAndre Fischer        if ( ! exists($installer::globals::languageproperties{$property}) )
9219f91b7e3SAndre Fischer        {
9229f91b7e3SAndre Fischer            $installer::globals::languageproperties{$property} = $value;
9239f91b7e3SAndre Fischer        }
9249f91b7e3SAndre Fischer    }
9259f91b7e3SAndre Fischer}
926cdf0e10cSrcweir
927cdf0e10cSrcweir
928cdf0e10cSrcweir
929cdf0e10cSrcweir
9309f91b7e3SAndre Fischersub has_style ($$)
9319f91b7e3SAndre Fischer{
9329f91b7e3SAndre Fischer    my ($style_list_string, $style_name) = @_;
933cdf0e10cSrcweir
9349f91b7e3SAndre Fischer    return 0 unless defined $style_list_string;
9359f91b7e3SAndre Fischer    return $style_list_string =~ /\b$style_name\b/ ? 1 : 0;
9369f91b7e3SAndre Fischer}
937cdf0e10cSrcweir
938cdf0e10cSrcweir
939cdf0e10cSrcweir
940cdf0e10cSrcweir
9419f91b7e3SAndre Fischersub prepare_file_table_creation ($$$)
9429f91b7e3SAndre Fischer{
9439f91b7e3SAndre Fischer    my ($file_list, $directory_list, $allvariables) = @_;
9449f91b7e3SAndre Fischer
9459f91b7e3SAndre Fischer    if ( $^O =~ /cygwin/i )
9469f91b7e3SAndre Fischer    {
9479f91b7e3SAndre Fischer        installer::worker::generate_cygwin_pathes($file_list);
9489f91b7e3SAndre Fischer    }
949cdf0e10cSrcweir
9509f91b7e3SAndre Fischer    # Reset the fields 'sequencenumber' and 'uniquename'. They should not yet exist but better be sure.
9519f91b7e3SAndre Fischer    foreach my $file (@$file_list)
9529f91b7e3SAndre Fischer    {
9539f91b7e3SAndre Fischer        delete $file->{'sequencenumber'};
9549f91b7e3SAndre Fischer        delete $file->{'uniquename'};
9559f91b7e3SAndre Fischer    }
956cdf0e10cSrcweir
9579f91b7e3SAndre Fischer    # Create FileSequenceList object for the old sequence data.
9589f91b7e3SAndre Fischer    if (defined $installer::globals::source_msi)
9599f91b7e3SAndre Fischer    {
9609f91b7e3SAndre Fischer        my $previous_sequence_data = new installer::patch::FileSequenceList();
9619f91b7e3SAndre Fischer        $previous_sequence_data->SetFromMsi($installer::globals::source_msi);
9629f91b7e3SAndre Fischer        my @added_files = retrieve_sequence_and_uniquename($file_list, $previous_sequence_data);
9639f91b7e3SAndre Fischer
9649f91b7e3SAndre Fischer        # Extract just the unique names.
9659f91b7e3SAndre Fischer        my %target_unique_names = map {$_->{'uniquename'} => 1} @$file_list;
9669f91b7e3SAndre Fischer        my @removed_items = $previous_sequence_data->get_removed_files(\%target_unique_names);
9679f91b7e3SAndre Fischer
9689f91b7e3SAndre Fischer        $installer::logger::Lang->printf(
9699f91b7e3SAndre Fischer            "there are %d files that have been removed from source and %d files added\n",
9709f91b7e3SAndre Fischer            scalar @removed_items,
9719f91b7e3SAndre Fischer            scalar @added_files);
9729f91b7e3SAndre Fischer
9739f91b7e3SAndre Fischer        my $file_map = $installer::globals::source_msi->GetFileMap();
9749f91b7e3SAndre Fischer        my $index = 0;
9759f91b7e3SAndre Fischer        foreach my $removed_row (@removed_items)
9769f91b7e3SAndre Fischer        {
9779f91b7e3SAndre Fischer            $installer::logger::Lang->printf("    removed file %d: %s\n",
9789f91b7e3SAndre Fischer                ++$index,
9799f91b7e3SAndre Fischer                $removed_row->GetValue('File'));
9809f91b7e3SAndre Fischer            my $directory = $file_map->{$removed_row->GetValue('File')}->{'directory'};
9819f91b7e3SAndre Fischer            while (my ($key,$value) = each %$directory)
9829f91b7e3SAndre Fischer            {
9839f91b7e3SAndre Fischer                $installer::logger::Lang->printf("        %16s -> %s\n", $key, $value);
9849f91b7e3SAndre Fischer            }
9859f91b7e3SAndre Fischer        }
9869f91b7e3SAndre Fischer        $index = 0;
9879f91b7e3SAndre Fischer        foreach my $added_file (@added_files)
9889f91b7e3SAndre Fischer        {
9899f91b7e3SAndre Fischer            $installer::logger::Lang->printf("    added file %d: %s\n",
9909f91b7e3SAndre Fischer                ++$index,
9919f91b7e3SAndre Fischer                $added_file->{'uniquename'});
9929f91b7e3SAndre Fischer            installer::scriptitems::print_script_item($added_file);
9939f91b7e3SAndre Fischer        }
9949f91b7e3SAndre Fischer        my @new_files = create_items_for_missing_files(
9959f91b7e3SAndre Fischer            \@removed_items,
9969f91b7e3SAndre Fischer            $installer::globals::source_msi,
9979f91b7e3SAndre Fischer            $directory_list);
9989f91b7e3SAndre Fischer        push @$file_list, @new_files;
9999f91b7e3SAndre Fischer    }
10009f91b7e3SAndre Fischer    assign_missing_sequence_numbers($file_list);
1001cdf0e10cSrcweir
10029f91b7e3SAndre Fischer    foreach my $file (@$file_list)
10039f91b7e3SAndre Fischer	{
10049f91b7e3SAndre Fischer        if ( ! defined $file->{'componentname'})
10059f91b7e3SAndre Fischer        {
10069f91b7e3SAndre Fischer            $file->{'componentname'} = get_file_component_name($file, $file_list);
10079f91b7e3SAndre Fischer        }
10089f91b7e3SAndre Fischer        if ( ! defined $file->{'uniquename'})
10099f91b7e3SAndre Fischer        {
10109f91b7e3SAndre Fischer            $file->{'uniquename'} = generate_unique_filename_for_filetable($file->{'Name'});
10119f91b7e3SAndre Fischer        }
1012cdf0e10cSrcweir
1013cdf0e10cSrcweir		# Collecting all component conditions
10149f91b7e3SAndre Fischer		if ( $file->{'ComponentCondition'} )
1015cdf0e10cSrcweir		{
10169f91b7e3SAndre Fischer			if ( ! exists($installer::globals::componentcondition{$file->{'componentname'}}))
1017cdf0e10cSrcweir			{
10189f91b7e3SAndre Fischer				$installer::globals::componentcondition{$file->{'componentname'}}
10199f91b7e3SAndre Fischer                = $file->{'ComponentCondition'};
1020cdf0e10cSrcweir			}
1021cdf0e10cSrcweir		}
1022cdf0e10cSrcweir		# Collecting also all tree conditions for multilayer products
10239f91b7e3SAndre Fischer		get_tree_condition_for_component($file, $file->{'componentname'});
1024cdf0e10cSrcweir
1025cdf0e10cSrcweir		# Collecting all component names, that have flag VERSION_INDEPENDENT_COMP_ID
1026cdf0e10cSrcweir		# This should be all components with constant API, for example URE
10279f91b7e3SAndre Fischer		if (has_style($file->{'Styles'}, "VERSION_INDEPENDENT_COMP_ID"))
1028cdf0e10cSrcweir		{
10299f91b7e3SAndre Fischer			$installer::globals::base_independent_components{$file->{'componentname'}} = 1;
1030cdf0e10cSrcweir		}
1031cdf0e10cSrcweir
10329f91b7e3SAndre Fischer        # Special handling for files in PREDEFINED_OSSHELLNEWDIR. These components
10339f91b7e3SAndre Fischer		# need as KeyPath a RegistryItem in HKCU
10349f91b7e3SAndre Fischer        if ($file->{'needs_user_registry_key'}
10359f91b7e3SAndre Fischer            || (defined $file->{'Dir'} && $file->{'Dir'} =~ /\bPREDEFINED_OSSHELLNEWDIR\b/))
10369f91b7e3SAndre Fischer		{
10379f91b7e3SAndre Fischer			my $keypath = generate_registry_keypath($file);
10389f91b7e3SAndre Fischer			$file->{'userregkeypath'} = $keypath;
10399f91b7e3SAndre Fischer			push(@installer::globals::userregistrycollector, $file);
10409f91b7e3SAndre Fischer			$installer::globals::addeduserregitrykeys = 1;
10419f91b7e3SAndre Fischer		}
1042cdf0e10cSrcweir
10439f91b7e3SAndre Fischer		$file->{'windows_language'} = get_language_for_file($file);
1044cdf0e10cSrcweir
10459f91b7e3SAndre Fischer        process_language_conditions($file);
10469f91b7e3SAndre Fischer    }
1047cdf0e10cSrcweir
10489f91b7e3SAndre Fischer    # The filenames must be collected because of uniqueness
10499f91b7e3SAndre Fischer	# 01-44-~1.DAT, 01-44-~2.DAT, ...
10509f91b7e3SAndre Fischer	my %shortnames = ();
10519f91b7e3SAndre Fischer    foreach my $file (@$file_list)
10529f91b7e3SAndre Fischer    {
10539f91b7e3SAndre Fischer        $file->{'short_name'} = generate_filename_for_filetable($file, \%shortnames);
10549f91b7e3SAndre Fischer    }
10559f91b7e3SAndre Fischer}
1056cdf0e10cSrcweir
1057cdf0e10cSrcweir
1058cdf0e10cSrcweir
1059cdf0e10cSrcweir
10609f91b7e3SAndre Fischersub create_file_table_data ($$)
10619f91b7e3SAndre Fischer{
10629f91b7e3SAndre Fischer    my ($file_list, $allvariables) = @_;
10639f91b7e3SAndre Fischer
10649f91b7e3SAndre Fischer    my @file_table_data = ();
10659f91b7e3SAndre Fischer	foreach my $file (@$file_list)
10669f91b7e3SAndre Fischer	{
10679f91b7e3SAndre Fischer        my $attributes;
10689f91b7e3SAndre Fischer		if (has_style($file->{'Styles'}, "DONT_PACK"))
10699f91b7e3SAndre Fischer        {
10709f91b7e3SAndre Fischer            # Sourcefile is unpacked (msidbFileAttributesNoncompressed).
10719f91b7e3SAndre Fischer            $attributes = "8192";
10729f91b7e3SAndre Fischer        }
10739f91b7e3SAndre Fischer		else
10749f91b7e3SAndre Fischer        {
10759f91b7e3SAndre Fischer            # Sourcefile is packed (msidbFileAttributesCompressed).
10769f91b7e3SAndre Fischer            $attributes = "16384";
10779f91b7e3SAndre Fischer        }
1078cdf0e10cSrcweir
10799f91b7e3SAndre Fischer        my $row_data = {
10809f91b7e3SAndre Fischer            'File' => $file->{'uniquename'},
10819f91b7e3SAndre Fischer            'Component_' => $file->{'componentname'},
10829f91b7e3SAndre Fischer            'FileName' => $file->{'short_name'},
10839f91b7e3SAndre Fischer            'FileSize' => get_filesize($file),
10849f91b7e3SAndre Fischer            'Version' => get_fileversion($file, $allvariables),
10859f91b7e3SAndre Fischer            'Language' => $file->{'windows_language'},
10869f91b7e3SAndre Fischer            'Attributes' => $attributes,
10879f91b7e3SAndre Fischer            'Sequence' => $file->{'sequencenumber'}
10889f91b7e3SAndre Fischer            };
10899f91b7e3SAndre Fischer        push @file_table_data, $row_data;
1090cdf0e10cSrcweir	}
1091cdf0e10cSrcweir
10929f91b7e3SAndre Fischer    return \@file_table_data;
10939f91b7e3SAndre Fischer}
10949f91b7e3SAndre Fischer
10959f91b7e3SAndre Fischer
10969f91b7e3SAndre Fischer
10979f91b7e3SAndre Fischer
10989f91b7e3SAndre Fischersub collect_components ($)
10999f91b7e3SAndre Fischer{
11009f91b7e3SAndre Fischer    my ($file_list) = @_;
11019f91b7e3SAndre Fischer
11029f91b7e3SAndre Fischer	my %components = ();
11039f91b7e3SAndre Fischer    foreach my $file (@$file_list)
11049f91b7e3SAndre Fischer    {
11059f91b7e3SAndre Fischer        $components{$file->{'componentname'}} = 1;
11069f91b7e3SAndre Fischer    }
11079f91b7e3SAndre Fischer    return keys %components;
11089f91b7e3SAndre Fischer}
11099f91b7e3SAndre Fischer
11109f91b7e3SAndre Fischer
11119f91b7e3SAndre Fischer
11129f91b7e3SAndre Fischer
11139f91b7e3SAndre Fischer=head filter_files($file_list, $allvariables)
11149f91b7e3SAndre Fischer
11159f91b7e3SAndre Fischer    Filter out Java files when not building a Java product.
11169f91b7e3SAndre Fischer
11179f91b7e3SAndre Fischer    Is this still triggered?
11189f91b7e3SAndre Fischer
11199f91b7e3SAndre Fischer=cut
11209f91b7e3SAndre Fischersub filter_files ($$)
11219f91b7e3SAndre Fischer{
11229f91b7e3SAndre Fischer    my ($file_list, $allvariables) = @_;
11239f91b7e3SAndre Fischer
11249f91b7e3SAndre Fischer    if ($allvariables->{'JAVAPRODUCT'})
11259f91b7e3SAndre Fischer    {
11269f91b7e3SAndre Fischer        return $file_list;
11279f91b7e3SAndre Fischer    }
11289f91b7e3SAndre Fischer    else
11299f91b7e3SAndre Fischer    {
11309f91b7e3SAndre Fischer        my @filtered_files = ();
11319f91b7e3SAndre Fischer        foreach my $file (@$file_list)
11329f91b7e3SAndre Fischer        {
11339f91b7e3SAndre Fischer            if ( ! has_style($file->{'Styles'}, "JAVAFILE"))
11349f91b7e3SAndre Fischer            {
11359f91b7e3SAndre Fischer                push @filtered_files, $file;
11369f91b7e3SAndre Fischer            }
11379f91b7e3SAndre Fischer        }
11389f91b7e3SAndre Fischer        return \@filtered_files;
11399f91b7e3SAndre Fischer    }
11409f91b7e3SAndre Fischer}
1141cdf0e10cSrcweir
11429f91b7e3SAndre Fischer
11439f91b7e3SAndre Fischer
11449f91b7e3SAndre Fischer
11459f91b7e3SAndre Fischer# Structure of the files table:
11469f91b7e3SAndre Fischer# File Component_ FileName FileSize Version Language Attributes Sequence
11479f91b7e3SAndre Fischersub create_file_table ($$)
11489f91b7e3SAndre Fischer{
11499f91b7e3SAndre Fischer    my ($file_table_data, $basedir) = @_;
11509f91b7e3SAndre Fischer
11519f91b7e3SAndre Fischer    # Set up the 'File' table.
11529f91b7e3SAndre Fischer	my @filetable = ();
11539f91b7e3SAndre Fischer	installer::windows::idtglobal::write_idt_header(\@filetable, "file");
11549f91b7e3SAndre Fischer    my @keys = ('File', 'Component_', 'FileName', 'FileSize', 'Version', 'Language', 'Attributes', 'Sequence');
11559f91b7e3SAndre Fischer    my $index = 0;
11569f91b7e3SAndre Fischer    foreach my $row_data (@$file_table_data)
11579f91b7e3SAndre Fischer    {
11589f91b7e3SAndre Fischer        ++$index;
11599f91b7e3SAndre Fischer        my @values = map {$row_data->{$_}} @keys;
11609f91b7e3SAndre Fischer        my $line = join("\t", @values) . "\n";
11619f91b7e3SAndre Fischer		push(@filetable, $line);
11629f91b7e3SAndre Fischer    }
11639f91b7e3SAndre Fischer
11649f91b7e3SAndre Fischer    my $filetablename = $basedir . $installer::globals::separator . "File.idt";
1165cdf0e10cSrcweir	installer::files::save_file($filetablename ,\@filetable);
1166b274bc22SAndre Fischer	$installer::logger::Lang->print("\n");
1167b274bc22SAndre Fischer	$installer::logger::Lang->printf("Created idt file: %s\n", $filetablename);
11689f91b7e3SAndre Fischer}
1169cdf0e10cSrcweir
1170cdf0e10cSrcweir
1171cdf0e10cSrcweir
11729f91b7e3SAndre Fischer
11739f91b7e3SAndre Fischersub create_filehash_table ($$)
11749f91b7e3SAndre Fischer{
11759f91b7e3SAndre Fischer    my ($file_list, $basedir) = @_;
11769f91b7e3SAndre Fischer
11779f91b7e3SAndre Fischer    my @filehashtable = ();
11789f91b7e3SAndre Fischer
11799f91b7e3SAndre Fischer    if ( $installer::globals::prepare_winpatch )
11809f91b7e3SAndre Fischer    {
11819f91b7e3SAndre Fischer
11829f91b7e3SAndre Fischer        installer::windows::idtglobal::write_idt_header(\@filehashtable, "filehash");
11839f91b7e3SAndre Fischer
11849f91b7e3SAndre Fischer        foreach my $file (@$file_list)
11859f91b7e3SAndre Fischer        {
11869f91b7e3SAndre Fischer            my $path = $file->{'sourcepath'};
11879f91b7e3SAndre Fischer            if ($^O =~ /cygwin/i)
11889f91b7e3SAndre Fischer            {
11899f91b7e3SAndre Fischer                $path = $file->{'cyg_sourcepath'};
11909f91b7e3SAndre Fischer            }
11919f91b7e3SAndre Fischer
11929f91b7e3SAndre Fischer            open(FILE, $path) or die "ERROR: Can't open $path for creating file hash";
11939f91b7e3SAndre Fischer            binmode(FILE);
11949f91b7e3SAndre Fischer            my $hashinfo = pack("l", 20);
11959f91b7e3SAndre Fischer            $hashinfo .= Digest::MD5->new->addfile(*FILE)->digest;
11969f91b7e3SAndre Fischer
11979f91b7e3SAndre Fischer            my @i = unpack ('x[l]l4', $hashinfo);
11989f91b7e3SAndre Fischer            my $oneline = join("\t",
11999f91b7e3SAndre Fischer                (
12009f91b7e3SAndre Fischer                    $file->{'uniquename'},
12019f91b7e3SAndre Fischer                    "0",
12029f91b7e3SAndre Fischer                    @i
12039f91b7e3SAndre Fischer                ));
12049f91b7e3SAndre Fischer            push (@filehashtable, $oneline . "\n");
12059f91b7e3SAndre Fischer        }
12069f91b7e3SAndre Fischer
12079f91b7e3SAndre Fischer        my $filehashtablename = $basedir . $installer::globals::separator . "MsiFileHash.idt";
12089f91b7e3SAndre Fischer        installer::files::save_file($filehashtablename ,\@filehashtable);
12099f91b7e3SAndre Fischer        $installer::logger::Lang->print("\n");
12109f91b7e3SAndre Fischer        $installer::logger::Lang->printf("Created idt file: %s\n", $filehashtablename);
12119f91b7e3SAndre Fischer    }
1212cdf0e10cSrcweir}
1213cdf0e10cSrcweir
12149f91b7e3SAndre Fischer
1215cdf0e10cSrcweir1;
1216