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