Branch libreoffice-5-0-4
[LibreOffice.git] / solenv / bin / modules / installer / windows / component.pm
blob65d79b84b816965659b558717f3e7f9526c7759a
2 # This file is part of the LibreOffice project.
4 # This Source Code Form is subject to the terms of the Mozilla Public
5 # License, v. 2.0. If a copy of the MPL was not distributed with this
6 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 # This file incorporates work covered by the following license notice:
10 # Licensed to the Apache Software Foundation (ASF) under one or more
11 # contributor license agreements. See the NOTICE file distributed
12 # with this work for additional information regarding copyright
13 # ownership. The ASF licenses this file to you under the Apache
14 # License, Version 2.0 (the "License"); you may not use this file
15 # except in compliance with the License. You may obtain a copy of
16 # the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 package installer::windows::component;
21 use installer::exiter;
22 use installer::files;
23 use installer::globals;
24 use installer::windows::idtglobal;
25 use installer::windows::language;
27 ##############################################################
28 # Returning a globally unique ID (GUID) for a component
29 # If the component is new, a unique guid has to be created.
30 # If the component already exists, the guid has to be
31 # taken from a list component <-> guid
32 # Sample for a guid: {B68FD953-3CEF-4489-8269-8726848056E8}
33 ##############################################################
35 sub get_component_guid
37 my ( $componentname, $componentidhashref ) = @_;
39 # At this time only a template
40 my $returnvalue = "\{COMPONENTGUID\}";
42 if (( $installer::globals::updatedatabase ) && ( exists($componentidhashref->{$componentname}) ))
44 $returnvalue = $componentidhashref->{$componentname};
47 # Returning a ComponentID, that is assigned in scp project
48 if ( exists($installer::globals::componentid{$componentname}) )
50 $returnvalue = "\{" . $installer::globals::componentid{$componentname} . "\}";
53 return $returnvalue;
56 ##############################################################
57 # Returning the directory for a file component.
58 ##############################################################
60 sub get_file_component_directory
62 my ($componentname, $filesref, $dirref) = @_;
64 my ($onefile, $component, $onedir, $hostname, $uniquedir);
65 my $found = 0;
67 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
69 $onefile = ${$filesref}[$i];
70 $component = $onefile->{'componentname'};
72 if ( $component eq $componentname )
74 $found = 1;
75 last;
79 if (!($found))
81 # This component can be ignored, if it exists in a version with extension "_pff" (this was renamed in file::get_sequence_for_file() )
82 my $ignore_this_component = 0;
83 my $origcomponentname = $componentname;
84 my $componentname = $componentname . "_pff";
86 for ( my $j = 0; $j <= $#{$filesref}; $j++ )
88 $onefile = ${$filesref}[$j];
89 $component = $onefile->{'componentname'};
91 if ( $component eq $componentname )
93 $ignore_this_component = 1;
94 last;
98 if ( $ignore_this_component ) { return "IGNORE_COMP"; }
99 else { installer::exiter::exit_program("ERROR: Did not find component \"$origcomponentname\" in file collection", "get_file_component_directory"); }
102 my $localstyles = "";
104 if ( $onefile->{'Styles'} ) { $localstyles = $onefile->{'Styles'}; }
106 if ( $localstyles =~ /\bFONT\b/ ) # special handling for font files
108 return $installer::globals::fontsfolder;
111 my $destdir = "";
113 if ( $onefile->{'Dir'} ) { $destdir = $onefile->{'Dir'}; }
115 my $destination = $onefile->{'destination'};
117 installer::pathanalyzer::get_path_from_fullqualifiedname(\$destination);
119 $destination =~ s/\Q$installer::globals::separator\E\s*$//;
121 # This path has to be defined in the directory collection at "HostName"
123 if ($destination eq "") # files in the installation root
125 $uniquedir = "INSTALLLOCATION";
127 else
129 $found = 0;
131 for ( my $i = 0; $i <= $#{$dirref}; $i++ )
133 $onedir = ${$dirref}[$i];
134 $hostname = $onedir->{'HostName'};
136 if ( $hostname eq $destination )
138 $found = 1;
139 last;
143 if (!($found))
145 installer::exiter::exit_program("ERROR: Did not find destination $destination in directory collection", "get_file_component_directory");
148 $uniquedir = $onedir->{'uniquename'};
150 if ( $uniquedir eq $installer::globals::officeinstalldirectory )
152 $uniquedir = "INSTALLLOCATION";
156 $onefile->{'uniquedirname'} = $uniquedir; # saving it in the file collection
158 return $uniquedir
161 ##############################################################
162 # Returning the directory for a registry component.
163 # This cannot be a useful value
164 ##############################################################
166 sub get_registry_component_directory
168 my $componentdir = "INSTALLLOCATION";
170 return $componentdir;
173 ##############################################################
174 # Returning the attributes for a file component.
175 ##############################################################
177 sub get_file_component_attributes
179 my ($componentname, $filesref, $allvariables) = @_;
181 my $attributes;
183 $attributes = 2;
185 # special handling for font files
187 my $onefile;
188 my $found = 0;
190 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
192 $onefile = ${$filesref}[$i];
193 my $component = $onefile->{'componentname'};
195 if ( $component eq $componentname )
197 $found = 1;
198 last;
202 if (!($found))
204 installer::exiter::exit_program("ERROR: Did not find component in file collection", "get_file_component_attributes");
207 my $localstyles = "";
209 if ( $onefile->{'Styles'} ) { $localstyles = $onefile->{'Styles'}; }
211 if ( $localstyles =~ /\bFONT\b/ )
213 $attributes = 8; # font files will be deinstalled if the ref count is 0
216 if ( $localstyles =~ /\bASSEMBLY\b/ )
218 $attributes = 0; # Assembly files cannot run from source
221 if ( $onefile->{'needs_user_registry_key'} )
223 $attributes = 4; # Files in non advertised startmenu entries must have user registry key as KeyPath
226 # Setting msidbComponentAttributes64bit, if this is a 64 bit installation set.
227 if (( $allvariables->{'64BITPRODUCT'} ) && ( $allvariables->{'64BITPRODUCT'} == 1 )) { $attributes |= 256; }
229 return $attributes;
232 ##############################################################
233 # Returning the attributes for a registry component.
234 # Always 4, indicating, the keypath is a defined in
235 # table registry
236 ##############################################################
238 sub get_registry_component_attributes
240 my ($componentname, $allvariables) = @_;
242 my $attributes;
244 $attributes = 4;
246 # Setting msidbComponentAttributes64bit, if this is a 64 bit installation set.
247 if (( $allvariables->{'64BITPRODUCT'} ) && ( $allvariables->{'64BITPRODUCT'} == 1 )) { $attributes |= 256; }
249 # Setting msidbComponentAttributes64bit for 64 bit shell extension in 32 bit installer, too
250 if ( $componentname =~ m/winexplorerext_x64/ ) { $attributes |= 256; }
252 # Setting msidbComponentAttributesPermanent
253 if ( exists($installer::globals::dontdeletecomponents{$componentname}) ) { $attributes |= 16; }
255 return $attributes;
258 ##############################################################
259 # Returning the conditions for a component.
260 # This is important for language dependent components
261 # in multilingual installation sets.
262 ##############################################################
264 sub get_file_component_condition
266 my ($componentname, $filesref) = @_;
268 my $condition = "";
270 if (exists($installer::globals::componentcondition{$componentname}))
272 $condition = $installer::globals::componentcondition{$componentname};
275 # there can be also tree conditions for multilayer products
276 if (exists($installer::globals::treeconditions{$componentname}))
278 if ( $condition eq "" )
280 $condition = $installer::globals::treeconditions{$componentname};
282 else
284 $condition = "($condition) And ($installer::globals::treeconditions{$componentname})";
288 return $condition
291 ##############################################################
292 # Returning the conditions for a registry component.
293 ##############################################################
295 sub get_component_condition
297 my ($componentname) = @_;
299 my $condition;
301 $condition = ""; # Always ?
303 if (exists($installer::globals::componentcondition{$componentname}))
305 $condition = $installer::globals::componentcondition{$componentname};
308 return $condition
311 ####################################################################
312 # Returning the keypath for a component.
313 # This will be the name of the first file/registry, found in the
314 # collection $itemsref
315 # Attention: This has to be the unique (file)name, not the
316 # real filename!
317 ####################################################################
319 sub get_component_keypath
321 my ($componentname, $itemsref, $componentidkeypathhashref) = @_;
323 my $oneitem;
324 my $found = 0;
325 my $infoline = "";
327 for ( my $i = 0; $i <= $#{$itemsref}; $i++ )
329 $oneitem = ${$itemsref}[$i];
330 my $component = $oneitem->{'componentname'};
332 if ( $component eq $componentname )
334 $found = 1;
335 last;
339 if (!($found))
341 installer::exiter::exit_program("ERROR: Did not find component in file/registry collection, function get_component_keypath", "get_component_keypath");
344 my $keypath = $oneitem->{'uniquename'}; # "uniquename", not "Name"
346 # Special handling for updates from existing databases, because KeyPath must not change
347 if (( $installer::globals::updatedatabase ) && ( exists($componentidkeypathhashref->{$componentname}) ))
349 $keypath = $componentidkeypathhashref->{$componentname};
350 # -> check, if this is a valid key path?!
351 if ( $keypath ne $oneitem->{'uniquename'} )
353 # Warning: This keypath was changed because of info from old database
354 $infoline = "WARNING: The KeyPath for component \"$componentname\" was changed from \"$oneitem->{'uniquename'}\" to \"$keypath\" because of information from update database";
355 push(@installer::globals::logfileinfo, $infoline);
359 if ( $oneitem->{'userregkeypath'} ) { $keypath = $oneitem->{'userregkeypath'}; }
361 # saving it in the file and registry collection
362 $oneitem->{'keypath'} = $keypath;
364 return $keypath
367 ###################################################################
368 # Creating the file Componen.idt dynamically
369 # Content:
370 # Component ComponentId Directory_ Attributes Condition KeyPath
371 ###################################################################
373 sub create_component_table
375 my ($filesref, $registryref, $dirref, $allfilecomponentsref, $allregistrycomponents, $basedir, $componentidhashref, $componentidkeypathhashref, $allvariables) = @_;
377 my @componenttable = ();
379 my ($oneline, $infoline);
381 installer::windows::idtglobal::write_idt_header(\@componenttable, "component");
383 # File components
385 for ( my $i = 0; $i <= $#{$allfilecomponentsref}; $i++ )
387 my %onecomponent = ();
389 $onecomponent{'name'} = ${$allfilecomponentsref}[$i];
390 $onecomponent{'guid'} = get_component_guid($onecomponent{'name'}, $componentidhashref);
391 $onecomponent{'directory'} = get_file_component_directory($onecomponent{'name'}, $filesref, $dirref);
392 if ( $onecomponent{'directory'} eq "IGNORE_COMP" ) { next; }
393 $onecomponent{'attributes'} = get_file_component_attributes($onecomponent{'name'}, $filesref, $allvariables);
394 $onecomponent{'condition'} = get_file_component_condition($onecomponent{'name'}, $filesref);
395 $onecomponent{'keypath'} = get_component_keypath($onecomponent{'name'}, $filesref, $componentidkeypathhashref);
397 $oneline = $onecomponent{'name'} . "\t" . $onecomponent{'guid'} . "\t" . $onecomponent{'directory'} . "\t"
398 . $onecomponent{'attributes'} . "\t" . $onecomponent{'condition'} . "\t" . $onecomponent{'keypath'} . "\n";
400 push(@componenttable, $oneline);
403 # Registry components
405 for ( my $i = 0; $i <= $#{$allregistrycomponents}; $i++ )
407 my %onecomponent = ();
409 $onecomponent{'name'} = ${$allregistrycomponents}[$i];
410 $onecomponent{'guid'} = get_component_guid($onecomponent{'name'}, $componentidhashref);
411 $onecomponent{'directory'} = get_registry_component_directory();
412 $onecomponent{'attributes'} = get_registry_component_attributes($onecomponent{'name'}, $allvariables);
413 $onecomponent{'condition'} = get_component_condition($onecomponent{'name'});
414 $onecomponent{'keypath'} = get_component_keypath($onecomponent{'name'}, $registryref, $componentidkeypathhashref);
416 $oneline = $onecomponent{'name'} . "\t" . $onecomponent{'guid'} . "\t" . $onecomponent{'directory'} . "\t"
417 . $onecomponent{'attributes'} . "\t" . $onecomponent{'condition'} . "\t" . $onecomponent{'keypath'} . "\n";
419 push(@componenttable, $oneline);
422 # Saving the file
424 my $componenttablename = $basedir . $installer::globals::separator . "Componen.idt";
425 installer::files::save_file($componenttablename ,\@componenttable);
426 $infoline = "Created idt file: $componenttablename\n";
427 push(@installer::globals::logfileinfo, $infoline);
430 ####################################################################################
431 # Returning a component for a scp module gid.
432 # Pairs are saved in the files collector.
433 ####################################################################################
435 sub get_component_name_from_modulegid
437 my ($modulegid, $filesref) = @_;
439 my $componentname = "";
441 for my $file ( @{$filesref} )
443 next if ( ! $file->{'modules'} );
445 my @filemodules = split /,\s*/, $file->{'modules'};
447 if (grep {$_ eq $modulegid} @filemodules)
449 $componentname = $file->{'componentname'};
450 last;
454 return $componentname;
457 ####################################################################################
458 # Updating the file Environm.idt dynamically
459 # Content:
460 # Environment Name Value Component_
461 ####################################################################################
463 sub set_component_in_environment_table
465 my ($basedir, $filesref) = @_;
467 my $infoline = "";
469 my $environmentfilename = $basedir . $installer::globals::separator . "Environm.idt";
471 if ( -f $environmentfilename ) # only do something, if file exists
473 my $environmentfile = installer::files::read_file($environmentfilename);
475 for ( my $i = 3; $i <= $#{$environmentfile}; $i++ ) # starting in line 4 of Environm.idt
477 if ( ${$environmentfile}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ )
479 my $modulegid = $4; # in Environment table a scp module gid can be used as component replacement
481 my $componentname = get_component_name_from_modulegid($modulegid, $filesref);
483 if ( $componentname ) # only do something if a component could be found
485 $infoline = "Updated Environment table:\n";
486 push(@installer::globals::logfileinfo, $infoline);
487 $infoline = "Old line: ${$environmentfile}[$i]\n";
488 push(@installer::globals::logfileinfo, $infoline);
490 ${$environmentfile}[$i] =~ s/$modulegid/$componentname/;
492 $infoline = "New line: ${$environmentfile}[$i]\n";
493 push(@installer::globals::logfileinfo, $infoline);
499 # Saving the file
501 installer::files::save_file($environmentfilename ,$environmentfile);
502 $infoline = "Updated idt file: $environmentfilename\n";
503 push(@installer::globals::logfileinfo, $infoline);