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::featurecomponent; 25cdf0e10cSrcweir 26cdf0e10cSrcweiruse installer::converter; 27cdf0e10cSrcweiruse installer::existence; 28cdf0e10cSrcweiruse installer::exiter; 29cdf0e10cSrcweiruse installer::files; 30cdf0e10cSrcweiruse installer::globals; 31cdf0e10cSrcweiruse installer::windows::idtglobal; 32cdf0e10cSrcweir 33*1ba1fd99SAndre Fischeruse strict; 34*1ba1fd99SAndre Fischer 35*1ba1fd99SAndre Fischer 36cdf0e10cSrcweir################################################################################# 37cdf0e10cSrcweir# Collecting all pairs of features and components from the files collector 38cdf0e10cSrcweir################################################################################# 39cdf0e10cSrcweir 40*1ba1fd99SAndre Fischersub create_featurecomponent_table_from_files_collector ($$) 41cdf0e10cSrcweir{ 42cdf0e10cSrcweir my ($featurecomponenttableref, $filesref) = @_; 43cdf0e10cSrcweir 44*1ba1fd99SAndre Fischer foreach my $onefile (@$filesref) 45cdf0e10cSrcweir { 46cdf0e10cSrcweir my $filecomponent = $onefile->{'componentname'}; 47cdf0e10cSrcweir my $filemodules = $onefile->{'modules'}; 48cdf0e10cSrcweir 49cdf0e10cSrcweir if ( $filecomponent eq "" ) 50cdf0e10cSrcweir { 51*1ba1fd99SAndre Fischer installer::exiter::exit_program( 52*1ba1fd99SAndre Fischer sprintf("ERROR: No component defined for file %s", $onefile->{'Name'}), 53*1ba1fd99SAndre Fischer "create_featurecomponent_table_from_files_collector"); 54cdf0e10cSrcweir } 55*1ba1fd99SAndre Fischer if ( ! defined $filemodules) 56*1ba1fd99SAndre Fischer { 57*1ba1fd99SAndre Fischer # Temporary for files created from source installation set. 58*1ba1fd99SAndre Fischer die; 59*1ba1fd99SAndre Fischer } 60*1ba1fd99SAndre Fischer if ($filemodules eq "") 61cdf0e10cSrcweir { 62*1ba1fd99SAndre Fischer installer::exiter::exit_program( 63*1ba1fd99SAndre Fischer sprintf("ERROR: No modules found for file %s", $onefile->{'Name'}), 64*1ba1fd99SAndre Fischer "create_featurecomponent_table_from_files_collector"); 65cdf0e10cSrcweir } 66cdf0e10cSrcweir 67cdf0e10cSrcweir my $filemodulesarrayref = installer::converter::convert_stringlist_into_array(\$filemodules, ","); 68cdf0e10cSrcweir 69*1ba1fd99SAndre Fischer foreach my $onemodule (@$filemodulesarrayref) 70cdf0e10cSrcweir { 71cdf0e10cSrcweir my %featurecomponent = (); 72cdf0e10cSrcweir 73cdf0e10cSrcweir $onemodule =~ s/\s*$//; 74cdf0e10cSrcweir $featurecomponent{'Feature'} = $onemodule; 75cdf0e10cSrcweir $featurecomponent{'Component'} = $filecomponent; 76cdf0e10cSrcweir 77cdf0e10cSrcweir # Attention: Features are renamed, because the maximum length is 38. 78cdf0e10cSrcweir # But in the files collector ($filesref), the original names are saved. 79cdf0e10cSrcweir 80cdf0e10cSrcweir installer::windows::idtglobal::shorten_feature_gid(\$featurecomponent{'Feature'}); 81cdf0e10cSrcweir 82*1ba1fd99SAndre Fischer my $oneline = "$featurecomponent{'Feature'}\t$featurecomponent{'Component'}\n"; 83cdf0e10cSrcweir 84cdf0e10cSrcweir # control of uniqueness 85cdf0e10cSrcweir 86cdf0e10cSrcweir if (! installer::existence::exists_in_array($oneline, $featurecomponenttableref)) 87cdf0e10cSrcweir { 88cdf0e10cSrcweir push(@{$featurecomponenttableref}, $oneline); 89cdf0e10cSrcweir } 90cdf0e10cSrcweir } 91cdf0e10cSrcweir } 92cdf0e10cSrcweir} 93cdf0e10cSrcweir 94cdf0e10cSrcweir 95*1ba1fd99SAndre Fischer 96*1ba1fd99SAndre Fischer 97*1ba1fd99SAndre Fischer=head2 create_featurecomponent_table_from_registry_collector ($featurecomponenttableref, $registryref) 98*1ba1fd99SAndre Fischer 99*1ba1fd99SAndre Fischer Add entries for the FeatureComponent table for components that contain registry entries. 100*1ba1fd99SAndre Fischer 101*1ba1fd99SAndre Fischer=cut 102*1ba1fd99SAndre Fischersub create_featurecomponent_table_from_registry_collector ($$) 103cdf0e10cSrcweir{ 104cdf0e10cSrcweir my ($featurecomponenttableref, $registryref) = @_; 105cdf0e10cSrcweir 106*1ba1fd99SAndre Fischer my $replacement_count = 0; 107*1ba1fd99SAndre Fischer my $unique_count = 0; 108*1ba1fd99SAndre Fischer foreach my $oneregistry (@$registryref) 109cdf0e10cSrcweir { 110*1ba1fd99SAndre Fischer my $component_name = $oneregistry->{'componentname'}; 111*1ba1fd99SAndre Fischer if ($component_name eq "") 112cdf0e10cSrcweir { 113*1ba1fd99SAndre Fischer installer::exiter::exit_program( 114*1ba1fd99SAndre Fischer sprintf("ERROR: No component defined for registry %s", $oneregistry->{'gid'}), 115*1ba1fd99SAndre Fischer "create_featurecomponent_table_from_registry_collector"); 116cdf0e10cSrcweir } 117*1ba1fd99SAndre Fischer 118*1ba1fd99SAndre Fischer my $feature_name = $oneregistry->{'ModuleID'}; 119*1ba1fd99SAndre Fischer if ($feature_name eq "") 120cdf0e10cSrcweir { 121*1ba1fd99SAndre Fischer installer::exiter::exit_program( 122*1ba1fd99SAndre Fischer sprintf("ERROR: No modules found for registry %s", $oneregistry->{'gid'}), 123*1ba1fd99SAndre Fischer "create_featurecomponent_table_from_registry_collector"); 124cdf0e10cSrcweir } 125cdf0e10cSrcweir 126cdf0e10cSrcweir # Attention: Features are renamed, because the maximum length is 38. 127cdf0e10cSrcweir # But in the files collector ($filesref), the original names are saved. 128cdf0e10cSrcweir 129*1ba1fd99SAndre Fischer $feature_name = installer::windows::idtglobal::create_shortend_feature_gid($feature_name); 130*1ba1fd99SAndre Fischer 131*1ba1fd99SAndre Fischer my $oneline = sprintf("%s\t%s\n", $feature_name, $component_name); 132*1ba1fd99SAndre Fischer if ( ! installer::existence::exists_in_array($oneline, $featurecomponenttableref)) 133cdf0e10cSrcweir { 134*1ba1fd99SAndre Fischer push(@$featurecomponenttableref, $oneline); 135*1ba1fd99SAndre Fischer ++$unique_count; 136*1ba1fd99SAndre Fischer } 137*1ba1fd99SAndre Fischer else 138*1ba1fd99SAndre Fischer { 139*1ba1fd99SAndre Fischer $installer::logger::Lang->printf("feature component pair already exists\n"); 140*1ba1fd99SAndre Fischer } 141*1ba1fd99SAndre Fischer } 142*1ba1fd99SAndre Fischer $installer::logger::Lang->printf( 143*1ba1fd99SAndre Fischer "replaced %d (%d) of %d component names in FeatureComponent table\n", 144*1ba1fd99SAndre Fischer $unique_count, 145*1ba1fd99SAndre Fischer $replacement_count, 146*1ba1fd99SAndre Fischer scalar @$registryref); 147cdf0e10cSrcweir} 148cdf0e10cSrcweir 149cdf0e10cSrcweir################################################################################# 150cdf0e10cSrcweir# Collecting all feature that are listed in the featurecomponent table. 151cdf0e10cSrcweir################################################################################# 152cdf0e10cSrcweir 153*1ba1fd99SAndre Fischersub collect_all_features 154cdf0e10cSrcweir{ 155cdf0e10cSrcweir my ($featurecomponenttable) = @_; 156cdf0e10cSrcweir 157cdf0e10cSrcweir my @allfeature = (); 158cdf0e10cSrcweir 159cdf0e10cSrcweir for ( my $i = 3; $i <= $#{$featurecomponenttable}; $i++ ) # beginning in line 4 160cdf0e10cSrcweir { 161cdf0e10cSrcweir my $oneline = ${$featurecomponenttable}[$i]; 162cdf0e10cSrcweir 163cdf0e10cSrcweir if ( $oneline =~ /^\s*(\S+)\s+(\S+)\s*$/ ) 164cdf0e10cSrcweir { 165cdf0e10cSrcweir my $feature = $1; 166cdf0e10cSrcweir 167*1ba1fd99SAndre Fischer if (! installer::existence::exists_in_array($feature, \@allfeature)) 168*1ba1fd99SAndre Fischer { 169*1ba1fd99SAndre Fischer push(@allfeature, $feature); 170*1ba1fd99SAndre Fischer } 171cdf0e10cSrcweir } 172cdf0e10cSrcweir } 173cdf0e10cSrcweir 174cdf0e10cSrcweir return \@allfeature; 175cdf0e10cSrcweir} 176cdf0e10cSrcweir 177cdf0e10cSrcweir################################################################################# 178cdf0e10cSrcweir# On Win98 and Win Me there seems to be the problem, that maximum 817 179cdf0e10cSrcweir# components can be added to a feature. Even if Windows Installer 2.0 180cdf0e10cSrcweir# is used. 181cdf0e10cSrcweir################################################################################# 182cdf0e10cSrcweir 183cdf0e10cSrcweirsub check_number_of_components_at_feature 184cdf0e10cSrcweir{ 185cdf0e10cSrcweir my ($featurecomponenttable) = @_; 186cdf0e10cSrcweir 187b274bc22SAndre Fischer $installer::logger::Lang->print("\n"); 188b274bc22SAndre Fischer $installer::logger::Lang->print("Checking number of components at features. Maximum is 817 (for Win 98 and Win Me)\n"); 189cdf0e10cSrcweir 190*1ba1fd99SAndre Fischer my $allfeature = collect_all_features($featurecomponenttable); 191cdf0e10cSrcweir 192cdf0e10cSrcweir for ( my $i = 0; $i <= $#{$allfeature}; $i++ ) 193cdf0e10cSrcweir { 194cdf0e10cSrcweir my $onefeature = ${$allfeature}[$i]; 195cdf0e10cSrcweir my $featurecomponents = 0; 196cdf0e10cSrcweir 197cdf0e10cSrcweir for ( my $j = 0; $j <= $#{$featurecomponenttable}; $j++ ) 198cdf0e10cSrcweir { 199cdf0e10cSrcweir if ( ${$featurecomponenttable}[$j] =~ /^\s*\Q$onefeature\E\s+(\S+)\s*$/ ) { $featurecomponents++; } 200cdf0e10cSrcweir } 201cdf0e10cSrcweir 202cdf0e10cSrcweir if ( $featurecomponents > 816 ) 203cdf0e10cSrcweir { 204cdf0e10cSrcweir installer::exiter::exit_program("ERROR: More than 816 components ($featurecomponents) at feature $onefeature. This causes problems on Win 98 and Win Me!", "check_number_of_components_at_feature"); 205cdf0e10cSrcweir } 206cdf0e10cSrcweir 207cdf0e10cSrcweir # Logging the result 208cdf0e10cSrcweir 209b274bc22SAndre Fischer $installer::logger::Lang->printf("Number of components at feature $onefeature : %s\n", $featurecomponents); 210cdf0e10cSrcweir } 211cdf0e10cSrcweir 212b274bc22SAndre Fischer $installer::logger::Lang->print("\n"); 213cdf0e10cSrcweir} 214cdf0e10cSrcweir 215cdf0e10cSrcweir################################################################################# 216cdf0e10cSrcweir# Creating the file FeatureC.idt dynamically 217cdf0e10cSrcweir# Content: 218cdf0e10cSrcweir# Feature Component 219cdf0e10cSrcweir################################################################################# 220cdf0e10cSrcweir 221*1ba1fd99SAndre Fischersub create_featurecomponent_table ($$$) 222cdf0e10cSrcweir{ 223cdf0e10cSrcweir my ($filesref, $registryref, $basedir) = @_; 224cdf0e10cSrcweir 225cdf0e10cSrcweir my @featurecomponenttable = (); 226cdf0e10cSrcweir my $infoline; 227cdf0e10cSrcweir 228cdf0e10cSrcweir installer::windows::idtglobal::write_idt_header(\@featurecomponenttable, "featurecomponent"); 229cdf0e10cSrcweir 230cdf0e10cSrcweir # This is the first time, that features and componentes are related 231cdf0e10cSrcweir # Problem: How about created profiles, configurationfiles, services.rdb 232cdf0e10cSrcweir # -> simple solution: putting them all to the root module 233cdf0e10cSrcweir # Otherwise profiles and configurationfiles cannot be created the way, they are now created 234cdf0e10cSrcweir # -> especially a problem for the configurationfiles! # ToDo 235cdf0e10cSrcweir # Very good: All ProfileItems belong to the root 236cdf0e10cSrcweir # services.rdb belongs to the root anyway. 237cdf0e10cSrcweir 238cdf0e10cSrcweir # At the moment only the files are related to components (and the files know their modules). 239cdf0e10cSrcweir # The component for each file is written into the files collector $filesinproductlanguageresolvedarrayref 240cdf0e10cSrcweir 241*1ba1fd99SAndre Fischer create_featurecomponent_table_from_files_collector( 242*1ba1fd99SAndre Fischer \@featurecomponenttable, 243*1ba1fd99SAndre Fischer $filesref); 244cdf0e10cSrcweir 245*1ba1fd99SAndre Fischer create_featurecomponent_table_from_registry_collector( 246*1ba1fd99SAndre Fischer \@featurecomponenttable, 247*1ba1fd99SAndre Fischer $registryref); 248cdf0e10cSrcweir 249cdf0e10cSrcweir # Additional components have to be added here 250cdf0e10cSrcweir 251cdf0e10cSrcweir # Checking, whether there are more than 817 components at a feature 252cdf0e10cSrcweir 253cdf0e10cSrcweir check_number_of_components_at_feature(\@featurecomponenttable); 254cdf0e10cSrcweir 255cdf0e10cSrcweir # Saving the file 256cdf0e10cSrcweir 257cdf0e10cSrcweir my $featurecomponenttablename = $basedir . $installer::globals::separator . "FeatureC.idt"; 258cdf0e10cSrcweir installer::files::save_file($featurecomponenttablename ,\@featurecomponenttable); 259b274bc22SAndre Fischer $installer::logger::Lang->printf("Created idt file: %s\n", $featurecomponenttablename); 260cdf0e10cSrcweir} 261cdf0e10cSrcweir 262b274bc22SAndre Fischer1; 263