← Index
NYTProf Performance Profile   « block view • line view • sub view »
For C:/lo/libo-master/solenv/bin/make_installer.pl
  Run on Mon Sep 24 00:52:54 2012
Reported on Mon Sep 24 07:34:54 2012

Filename/cygdrive/c/lo/libo-master/instsetoo_native/util/C:/lo/libo-master/solenv/bin/modules/installer/windows/mergemodule.pm
StatementsExecuted 1420700 statements in 99.5s
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
848186.7s86.7sinstaller::windows::mergemodule::::CORE:systeminstaller::windows::mergemodule::CORE:system (opcode)
15316.20s6.20sinstaller::windows::mergemodule::::CORE:backtickinstaller::windows::mergemodule::CORE:backtick (opcode)
117927212.40s2.40sinstaller::windows::mergemodule::::CORE:regcompinstaller::windows::mergemodule::CORE:regcomp (opcode)
5111.96s2.38sinstaller::windows::mergemodule::::analyze_filetable_fileinstaller::windows::mergemodule::analyze_filetable_file
5111.14s3.87sinstaller::windows::mergemodule::::change_component_tableinstaller::windows::mergemodule::change_component_table
282524361542ms542msinstaller::windows::mergemodule::::CORE:matchinstaller::windows::mergemodule::CORE:match (opcode)
511418ms12.1sinstaller::windows::mergemodule::::change_file_tableinstaller::windows::mergemodule::change_file_table
26843135.0ms35.0msinstaller::windows::mergemodule::::CORE:ftfileinstaller::windows::mergemodule::CORE:ftfile (opcode)
51119.6ms264msinstaller::windows::mergemodule::::change_featurecomponent_tableinstaller::windows::mergemodule::change_featurecomponent_table
11116.9ms31.4msinstaller::windows::mergemodule::::collect_featureinstaller::windows::mergemodule::collect_feature
201114.6ms18.2msinstaller::windows::mergemodule::::make_executeidtcontent_hashinstaller::windows::mergemodule::make_executeidtcontent_hash
11113.0ms101sinstaller::windows::mergemodule::::merge_mergemodules_into_msi_databaseinstaller::windows::mergemodule::merge_mergemodules_into_msi_database
30615.48ms5.48msinstaller::windows::mergemodule::::CORE:chdirinstaller::windows::mergemodule::CORE:chdir (opcode)
20414.48ms51.8msinstaller::windows::mergemodule::::change_executesequence_tableinstaller::windows::mergemodule::change_executesequence_table
20113.60ms4.52msinstaller::windows::mergemodule::::make_moduleexecuteidtcontent_hashinstaller::windows::mergemodule::make_moduleexecuteidtcontent_hash
10211.96ms1.96msinstaller::windows::mergemodule::::CORE:ftdirinstaller::windows::mergemodule::CORE:ftdir (opcode)
881211.26ms1.26msinstaller::windows::mergemodule::::CORE:substinstaller::windows::mergemodule::CORE:subst (opcode)
4111.19ms1.46msinstaller::windows::mergemodule::::analyze_msiassemblytable_fileinstaller::windows::mergemodule::analyze_msiassemblytable_file
511602µs5.22msinstaller::windows::mergemodule::::change_media_tableinstaller::windows::mergemodule::change_media_table
3311477µs477µsinstaller::windows::mergemodule::::get_new_line_for_file_tableinstaller::windows::mergemodule::get_new_line_for_file_table
411449µs5.80msinstaller::windows::mergemodule::::change_msiassembly_tableinstaller::windows::mergemodule::change_msiassembly_table
111362µs463µsinstaller::windows::mergemodule::::BEGIN@30installer::windows::mergemodule::BEGIN@30
511320µs373µsinstaller::windows::mergemodule::::analyze_media_fileinstaller::windows::mergemodule::analyze_media_file
511107µs107µsinstaller::windows::mergemodule::::CORE:sortinstaller::windows::mergemodule::CORE:sort (opcode)
51198µs98µsinstaller::windows::mergemodule::::set_current_last_sequenceinstaller::windows::mergemodule::set_current_last_sequence
51163µs63µsinstaller::windows::mergemodule::::get_last_diskidinstaller::windows::mergemodule::get_last_diskid
51154µs54µsinstaller::windows::mergemodule::::change_directory_tableinstaller::windows::mergemodule::change_directory_table
41144µs44µsinstaller::windows::mergemodule::::get_new_line_for_msiassembly_tableinstaller::windows::mergemodule::get_new_line_for_msiassembly_table
11121µs24µsinstaller::windows::mergemodule::::BEGIN@32installer::windows::mergemodule::BEGIN@32
11120µs22µsinstaller::windows::mergemodule::::BEGIN@41installer::windows::mergemodule::BEGIN@41
11119µs19µsinstaller::windows::mergemodule::::set_last_cabfile_nameinstaller::windows::mergemodule::set_last_cabfile_name
11118µs20µsinstaller::windows::mergemodule::::BEGIN@39installer::windows::mergemodule::BEGIN@39
11117µs19µsinstaller::windows::mergemodule::::BEGIN@40installer::windows::mergemodule::BEGIN@40
11117µs19µsinstaller::windows::mergemodule::::BEGIN@38installer::windows::mergemodule::BEGIN@38
11117µs18µsinstaller::windows::mergemodule::::BEGIN@43installer::windows::mergemodule::BEGIN@43
11116µs41µsinstaller::windows::mergemodule::::BEGIN@31installer::windows::mergemodule::BEGIN@31
11115µs42µsinstaller::windows::mergemodule::::BEGIN@36installer::windows::mergemodule::BEGIN@36
11114µs16µsinstaller::windows::mergemodule::::BEGIN@33installer::windows::mergemodule::BEGIN@33
11114µs16µsinstaller::windows::mergemodule::::BEGIN@34installer::windows::mergemodule::BEGIN@34
11114µs16µsinstaller::windows::mergemodule::::BEGIN@37installer::windows::mergemodule::BEGIN@37
11114µs16µsinstaller::windows::mergemodule::::BEGIN@35installer::windows::mergemodule::BEGIN@35
11114µs16µsinstaller::windows::mergemodule::::BEGIN@42installer::windows::mergemodule::BEGIN@42
0000s0sinstaller::windows::mergemodule::::analyze_directorytable_fileinstaller::windows::mergemodule::analyze_directorytable_file
0000s0sinstaller::windows::mergemodule::::collect_directoriesinstaller::windows::mergemodule::collect_directories
0000s0sinstaller::windows::mergemodule::::create_new_media_lineinstaller::windows::mergemodule::create_new_media_line
0000s0sinstaller::windows::mergemodule::::get_diskidinstaller::windows::mergemodule::get_diskid
0000s0sinstaller::windows::mergemodule::::get_diskpromptinstaller::windows::mergemodule::get_diskprompt
0000s0sinstaller::windows::mergemodule::::get_lastsequenceinstaller::windows::mergemodule::get_lastsequence
0000s0sinstaller::windows::mergemodule::::get_new_line_for_directory_tableinstaller::windows::mergemodule::get_new_line_for_directory_table
0000s0sinstaller::windows::mergemodule::::get_sourceinstaller::windows::mergemodule::get_source
0000s0sinstaller::windows::mergemodule::::get_volumelabelinstaller::windows::mergemodule::get_volumelabel
0000s0sinstaller::windows::mergemodule::::sort_files_collector_for_sequenceinstaller::windows::mergemodule::sort_files_collector_for_sequence
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1#*************************************************************************
2#
3# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4#
5# Copyright 2000, 2010 Oracle and/or its affiliates.
6#
7# OpenOffice.org - a multi-platform office productivity suite
8#
9# This file is part of OpenOffice.org.
10#
11# OpenOffice.org is free software: you can redistribute it and/or modify
12# it under the terms of the GNU Lesser General Public License version 3
13# only, as published by the Free Software Foundation.
14#
15# OpenOffice.org is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU Lesser General Public License version 3 for more details
19# (a copy is included in the LICENSE file that accompanied this code).
20#
21# You should have received a copy of the GNU Lesser General Public License
22# version 3 along with OpenOffice.org. If not, see
23# <http://www.openoffice.org/license.html>
24# for a copy of the LGPLv3 License.
25#
26#*************************************************************************
27
28package installer::windows::mergemodule;
29
30265µs2564µs
# spent 463µs (362+101) within installer::windows::mergemodule::BEGIN@30 which was called: # once (362µs+101µs) by installer::BEGIN@74 at line 30
use Cwd;
# spent 463µs making 1 call to installer::windows::mergemodule::BEGIN@30 # spent 101µs making 1 call to Exporter::import
31258µs266µs
# spent 41µs (16+25) within installer::windows::mergemodule::BEGIN@31 which was called: # once (16µs+25µs) by installer::BEGIN@74 at line 31
use Digest::MD5;
# spent 41µs making 1 call to installer::windows::mergemodule::BEGIN@31 # spent 25µs making 1 call to Exporter::import
32255µs226µs
# spent 24µs (21+3) within installer::windows::mergemodule::BEGIN@32 which was called: # once (21µs+3µs) by installer::BEGIN@74 at line 32
use installer::converter;
# spent 24µs making 1 call to installer::windows::mergemodule::BEGIN@32 # spent 3µs making 1 call to UNIVERSAL::import
33253µs219µs
# spent 16µs (14+3) within installer::windows::mergemodule::BEGIN@33 which was called: # once (14µs+3µs) by installer::BEGIN@74 at line 33
use installer::exiter;
# spent 16µs making 1 call to installer::windows::mergemodule::BEGIN@33 # spent 3µs making 1 call to UNIVERSAL::import
34253µs219µs
# spent 16µs (14+3) within installer::windows::mergemodule::BEGIN@34 which was called: # once (14µs+3µs) by installer::BEGIN@74 at line 34
use installer::files;
# spent 16µs making 1 call to installer::windows::mergemodule::BEGIN@34 # spent 3µs making 1 call to UNIVERSAL::import
35251µs218µs
# spent 16µs (14+2) within installer::windows::mergemodule::BEGIN@35 which was called: # once (14µs+2µs) by installer::BEGIN@74 at line 35
use installer::globals;
# spent 16µs making 1 call to installer::windows::mergemodule::BEGIN@35 # spent 2µs making 1 call to UNIVERSAL::import
36254µs270µs
# spent 42µs (15+27) within installer::windows::mergemodule::BEGIN@36 which was called: # once (15µs+27µs) by installer::BEGIN@74 at line 36
use installer::logger;
# spent 42µs making 1 call to installer::windows::mergemodule::BEGIN@36 # spent 27µs making 1 call to Exporter::import
37260µs218µs
# spent 16µs (14+2) within installer::windows::mergemodule::BEGIN@37 which was called: # once (14µs+2µs) by installer::BEGIN@74 at line 37
use installer::pathanalyzer;
# spent 16µs making 1 call to installer::windows::mergemodule::BEGIN@37 # spent 2µs making 1 call to UNIVERSAL::import
38256µs222µs
# spent 19µs (17+3) within installer::windows::mergemodule::BEGIN@38 which was called: # once (17µs+3µs) by installer::BEGIN@74 at line 38
use installer::remover;
# spent 19µs making 1 call to installer::windows::mergemodule::BEGIN@38 # spent 2µs making 1 call to UNIVERSAL::import
39254µs223µs
# spent 20µs (18+3) within installer::windows::mergemodule::BEGIN@39 which was called: # once (18µs+3µs) by installer::BEGIN@74 at line 39
use installer::scriptitems;
# spent 20µs making 1 call to installer::windows::mergemodule::BEGIN@39 # spent 3µs making 1 call to UNIVERSAL::import
40254µs220µs
# spent 19µs (17+1) within installer::windows::mergemodule::BEGIN@40 which was called: # once (17µs+1µs) by installer::BEGIN@74 at line 40
use installer::systemactions;
# spent 19µs making 1 call to installer::windows::mergemodule::BEGIN@40 # spent 2µs making 1 call to UNIVERSAL::import
41255µs224µs
# spent 22µs (20+2) within installer::windows::mergemodule::BEGIN@41 which was called: # once (20µs+2µs) by installer::BEGIN@74 at line 41
use installer::worker;
# spent 22µs making 1 call to installer::windows::mergemodule::BEGIN@41 # spent 2µs making 1 call to UNIVERSAL::import
42252µs218µs
# spent 16µs (14+2) within installer::windows::mergemodule::BEGIN@42 which was called: # once (14µs+2µs) by installer::BEGIN@74 at line 42
use installer::windows::idtglobal;
# spent 16µs making 1 call to installer::windows::mergemodule::BEGIN@42 # spent 2µs making 1 call to UNIVERSAL::import
43217.4ms220µs
# spent 18µs (17+2) within installer::windows::mergemodule::BEGIN@43 which was called: # once (17µs+2µs) by installer::BEGIN@74 at line 43
use installer::windows::language;
# spent 18µs making 1 call to installer::windows::mergemodule::BEGIN@43 # spent 2µs making 1 call to UNIVERSAL::import
44
45#################################################################
46# Merging the Windows MergeModules into the msi database.
47#################################################################
48
49sub merge_mergemodules_into_msi_database
50
# spent 101s (13.0ms+101) within installer::windows::mergemodule::merge_mergemodules_into_msi_database which was called: # once (13.0ms+101s) by installer::run at line 1710 of /cygdrive/c/lo/libo-master/instsetoo_native/util/C:/lo/libo-master/solenv/bin/modules/installer.pm
{
5118µs my ($mergemodules, $filesref, $msifilename, $languagestringref, $allvariables, $includepatharrayref, $allupdatesequences, $allupdatelastsequences, $allupdatediskids) = @_;
52
5311µs my $domerge = 0;
5414µs if (( $#{$mergemodules} > -1 ) && ( ! $installer::globals::patch ) && ( ! $installer::globals::languagepack ) && ( ! $installer::globals::helppack )) { $domerge = 1; }
55
5611µs if ( $domerge )
57 {
5815µs1210µs installer::logger::include_header_into_logfile("Merging merge modules into msi database");
# spent 210µs making 1 call to installer::logger::include_header_into_logfile
5914µs118µs installer::logger::print_message( "... merging msm files into msi database ... \n" );
# spent 18µs making 1 call to installer::logger::print_message
6014µs1124µs installer::logger::include_timestamp_into_logfile("\nPerformance Info: MergeModule into msi database, start");
# spent 124µs making 1 call to installer::logger::include_timestamp_into_logfile
61
6211µs my $msidb = "msidb.exe"; # Has to be in the path
6311µs my $cabinetfile = "MergeModule.CABinet"; # the name of each cabinet file in a merge file
6411µs my $infoline = "";
6511µs my $systemcall = "";
6611µs my $returnvalue = "";
67
68 # 1. Analyzing the MergeModule (has only to be done once)
69 # a. -> Extracting cabinet file: msidb.exe -d <msmfile> -x MergeModule.CABinet
70 # b. -> Number of files in cabinet file: msidb.exe -d <msmfile> -f <directory> -e File
71 # c. -> List of components: msidb.exe -d <msmfile> -f <directory> -e Component
72
7312µs if ( ! $installer::globals::mergemodules_analyzed )
74 {
7513µs1114µs installer::logger::include_timestamp_into_logfile("\nPerformance Info: Analyzing MergeModules, start");
# spent 114µs making 1 call to installer::logger::include_timestamp_into_logfile
7611µs $infoline = "Analyzing all Merge Modules\n\n";
7711µs push( @installer::globals::logfileinfo, $infoline);
78
7912µs %installer::globals::mergemodules = ();
80
8116µs1466ms my $mergemoduledir = installer::systemactions::create_directories("mergefiles", $languagestringref);
# spent 466ms making 1 call to installer::systemactions::create_directories
82
831500ns my $mergemodule;
8417µs foreach $mergemodule ( @{$mergemodules} )
85 {
86516µs my $filename = $mergemodule->{'Name'};
87537µs5213µs my $mergefile = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$filename, $includepatharrayref, 1);
# spent 213µs making 5 calls to installer::scriptitems::get_sourcepath_from_filename_and_includepath, avg 43µs/call
88
8951.18ms51.13ms if ( ! -f $$mergefile ) { installer::exiter::exit_program("ERROR: msm file not found: $filename !", "merge_mergemodules_into_msi_database"); }
# spent 1.13ms making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 225µs/call
9057µs my $completesource = $$mergefile;
91
92514µs my $mergegid = $mergemodule->{'gid'};
93515µs my $workdir = $mergemoduledir . $installer::globals::separator . $mergegid;
9451.08ms106.05ms if ( ! -d $workdir ) { installer::systemactions::create_directory($workdir); }
# spent 5.05ms making 5 calls to installer::systemactions::create_directory, avg 1.01ms/call # spent 1.00ms making 5 calls to installer::windows::mergemodule::CORE:ftdir, avg 200µs/call
95
96517µs $infoline = "Analyzing Merge Module: $filename\n";
97510µs push( @installer::globals::logfileinfo, $infoline);
98
99 # copy msm file into working directory
100518µs my $completedest = $workdir . $installer::globals::separator . $filename;
101538µs571.2ms installer::systemactions::copy_one_file($completesource, $completedest);
# spent 71.2ms making 5 calls to installer::systemactions::copy_one_file, avg 14.2ms/call
1025961µs5914µs if ( ! -f $completedest ) { installer::exiter::exit_program("ERROR: msm file not found: $completedest !", "merge_mergemodules_into_msi_database"); }
# spent 914µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 183µs/call
103
104 # changing directory
105544µs592µs my $from = cwd();
# spent 92µs making 5 calls to Cwd::__ANON__[Cwd.pm:406], avg 18µs/call
10658µs my $to = $workdir;
1075675µs5626µs chdir($to);
# spent 626µs making 5 calls to installer::windows::mergemodule::CORE:chdir, avg 125µs/call
108
109 # remove an existing cabinet file
1105994µs5953µs if ( -f $cabinetfile ) { unlink($cabinetfile); }
# spent 953µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 191µs/call
111
112 # exclude cabinet file
113522µs $systemcall = $msidb . " -d " . $filename . " -x " . $cabinetfile;
11452.46s52.46s $returnvalue = system($systemcall);
# spent 2.46s making 5 calls to installer::windows::mergemodule::CORE:system, avg 493ms/call
115
116526µs $infoline = "Systemcall: $systemcall\n";
117538µs push( @installer::globals::logfileinfo, $infoline);
118
119512µs if ($returnvalue)
120 {
121 $infoline = "ERROR: Could not execute $systemcall !\n";
122 push( @installer::globals::logfileinfo, $infoline);
123 installer::exiter::exit_program("ERROR: Could not extract cabinet file from merge file: $completedest !", "merge_mergemodules_into_msi_database");
124 }
125 else
126 {
127510µs $infoline = "Success: Executed $systemcall successfully!\n";
128515µs push( @installer::globals::logfileinfo, $infoline);
129 }
130
131 # exclude tables from mergefile
132 # Attention: All listed tables have to exist in the database. If they not exist, an error window pops up
133 # and the return value of msidb.exe is not zero. The error window makes it impossible to check the existence
134 # of a table with the help of the return value.
135 # Solution: Export of all tables by using "*" . Some tables must exist (File Component Directory), other
136 # tables do not need to exist (MsiAssembly).
137
1385144µs585µs if ( $^O =~ /cygwin/i ) {
# spent 85µs making 5 calls to installer::windows::mergemodule::CORE:match, avg 17µs/call
139 # msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
140511µs my $localworkdir = $workdir;
1415182µs5135µs $localworkdir =~ s/\//\\\\/g;
# spent 135µs making 5 calls to installer::windows::mergemodule::CORE:subst, avg 27µs/call
142529µs $systemcall = $msidb . " -d " . $filename . " -f " . $localworkdir . " -e \\\*";
143 }
144 else
145 {
146 $systemcall = $msidb . " -d " . $filename . " -f " . $workdir . " -e \*";
147 }
148
14952.44s52.44s $returnvalue = system($systemcall);
# spent 2.44s making 5 calls to installer::windows::mergemodule::CORE:system, avg 489ms/call
150
151558µs $infoline = "Systemcall: $systemcall\n";
152546µs push( @installer::globals::logfileinfo, $infoline);
153
154515µs if ($returnvalue)
155 {
156 $infoline = "ERROR: Could not execute $systemcall !\n";
157 push( @installer::globals::logfileinfo, $infoline);
158 installer::exiter::exit_program("ERROR: Could not exclude tables from merge file: $completedest !", "merge_mergemodules_into_msi_database");
159 }
160 else
161 {
162510µs $infoline = "Success: Executed $systemcall successfully!\n";
163523µs push( @installer::globals::logfileinfo, $infoline);
164 }
165
166 # Determining files
167513µs my $idtfilename = "File.idt"; # must exist
16851.23ms51.16ms if ( ! -f $idtfilename ) { installer::exiter::exit_program("ERROR: File \"$idtfilename\" not found in directory \"$workdir\" !", "merge_mergemodules_into_msi_database"); }
# spent 1.16ms making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 232µs/call
169558µs51.97ms my $filecontent = installer::files::read_file($idtfilename);
# spent 1.97ms making 5 calls to installer::files::read_file, avg 395µs/call
17055µs my @file_idt_content = ();
17156µs my $filecounter = 0;
172514µs my %mergefilesequence = ();
173592µs for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
174 {
1756337µs if ( $i <= 2 ) { next; } # ignoring first three lines
17633263µs33121µs if ( ${$filecontent}[$i] =~ /^\s*$/ ) { next; } # ignoring empty lines
# spent 121µs making 33 calls to installer::windows::mergemodule::CORE:match, avg 4µs/call
1773313µs $filecounter++;
1783366µs push(@file_idt_content, ${$filecontent}[$i]);
17933320µs33174µs if ( ${$filecontent}[$i] =~ /^\s*(.+?)\t(.+?)\t(.+?)\t(.+?)\t(.*?)\t(.*?)\t(.*?)\t(\d+?)\s*$/ )
# spent 174µs making 33 calls to installer::windows::mergemodule::CORE:match, avg 5µs/call
180 {
1813358µs my $filename = $1;
1823329µs my $filesequence = $8;
18333131µs $mergefilesequence{$filename} = $filesequence;
184 }
185 else
186 {
187 my $linecount = $i + 1;
188 installer::exiter::exit_program("ERROR: Unknown line format in table \"$idtfilename\" (line $linecount) !", "merge_mergemodules_into_msi_database");
189 }
190 }
191
192 # Determining components
19355µs $idtfilename = "Component.idt"; # must exist
1945738µs5696µs if ( ! -f $idtfilename ) { installer::exiter::exit_program("ERROR: File \"$idtfilename\" not found in directory \"$workdir\" !", "merge_mergemodules_into_msi_database"); }
# spent 696µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 139µs/call
195551µs51.39ms $filecontent = installer::files::read_file($idtfilename);
# spent 1.39ms making 5 calls to installer::files::read_file, avg 278µs/call
19659µs my %componentnames = ();
197545µs for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
198 {
1994323µs if ( $i <= 2 ) { next; } # ignoring first three lines
2001394µs1331µs if ( ${$filecontent}[$i] =~ /^\s*$/ ) { next; } # ignoring empty lines
# spent 31µs making 13 calls to installer::windows::mergemodule::CORE:match, avg 2µs/call
20113141µs1338µs if ( ${$filecontent}[$i] =~ /^\s*(\S+)\s+/ ) { $componentnames{$1} = 1; }
# spent 38µs making 13 calls to installer::windows::mergemodule::CORE:match, avg 3µs/call
202 }
203
204 # Determining directories
20556µs $idtfilename = "Directory.idt"; # must exist
2065529µs5492µs if ( ! -f $idtfilename ) { installer::exiter::exit_program("ERROR: File \"$idtfilename\" not found in directory \"$workdir\" !", "merge_mergemodules_into_msi_database"); }
# spent 492µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 98µs/call
207536µs51.37ms $filecontent = installer::files::read_file($idtfilename);
# spent 1.37ms making 5 calls to installer::files::read_file, avg 273µs/call
20857µs my %mergedirectories = ();
209568µs for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
210 {
2116434µs if ( $i <= 2 ) { next; } # ignoring first three lines
21234186µs3455µs if ( ${$filecontent}[$i] =~ /^\s*$/ ) { next; } # ignoring empty lines
# spent 55µs making 34 calls to installer::windows::mergemodule::CORE:match, avg 2µs/call
21334289µs3473µs if ( ${$filecontent}[$i] =~ /^\s*(\S+)\s+/ ) { $mergedirectories{$1} = 1; }
# spent 73µs making 34 calls to installer::windows::mergemodule::CORE:match, avg 2µs/call
214 }
215
216 # Determining assemblies
21753µs $idtfilename = "MsiAssembly.idt"; # does not need to exist
21853µs my $hasmsiassemblies = 0;
21956µs my %mergeassemblies = ();
2205636µs5591µs if ( -f $idtfilename )
# spent 591µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 118µs/call
221 {
222434µs4985µs $filecontent = installer::files::read_file($idtfilename);
# spent 985µs making 4 calls to installer::files::read_file, avg 246µs/call
22343µs $hasmsiassemblies = 1;
224424µs for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
225 {
2262816µs if ( $i <= 2 ) { next; } # ignoring first three lines
227437µs411µs if ( ${$filecontent}[$i] =~ /^\s*$/ ) { next; } # ignoring empty lines
# spent 11µs making 4 calls to installer::windows::mergemodule::CORE:match, avg 3µs/call
228448µs412µs if ( ${$filecontent}[$i] =~ /^\s*(\S+)\s+/ ) { $mergeassemblies{$1} = 1; }
# spent 12µs making 4 calls to installer::windows::mergemodule::CORE:match, avg 3µs/call
229 }
230 }
231
232 # It is possible, that other tables have to be checked here. This happens, if tables in the
233 # merge module have to know the "Feature" or the "Directory", under which the content of the
234 # msm file is integrated into the msi database.
235
236 # Determining name of cabinet file in installation set
237514µs my $cabfilename = $mergemodule->{'Cabfilename'};
23855µs if ( $cabfilename ) { installer::packagelist::resolve_packagevariables(\$cabfilename, $allvariables, 0); }
239
240 # Analyzing styles
241 # Flag REMOVE_FILE_TABLE is required for msvc9 Merge-Module, because otherwise msidb.exe
242 # fails during integration of msm file into msi database.
243
24456µs my $styles = "";
24553µs my $removefiletable = 0;
24656µs if ( $mergemodule->{'Styles'} ) { $styles = $mergemodule->{'Styles'}; }
247531µs54µs if ( $styles =~ /\bREMOVE_FILE_TABLE\b/ ) { $removefiletable = 1; }
# spent 4µs making 5 calls to installer::windows::mergemodule::CORE:match, avg 760ns/call
248
24952µs if ( $removefiletable )
250 {
251 my $removeworkdir = $workdir . $installer::globals::separator . "remove_file_idt";
252 if ( ! -d $removeworkdir ) { installer::systemactions::create_directory($removeworkdir); }
253 my $completeremovedest = $removeworkdir . $installer::globals::separator . $filename;
254 installer::systemactions::copy_one_file($completedest, $completeremovedest);
255 if ( ! -f $completeremovedest ) { installer::exiter::exit_program("ERROR: msm file not found: $completeremovedest !", "merge_mergemodules_into_msi_database"); }
256
257 # Unpacking msm file
258 if ( $^O =~ /cygwin/i ) {
259 # msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
260 my $localcompleteremovedest = $completeremovedest;
261 my $localremoveworkdir = $removeworkdir;
262 $localcompleteremovedest =~ s/\//\\\\/g;
263 $localremoveworkdir =~ s/\//\\\\/g;
264 $systemcall = $msidb . " -d " . $localcompleteremovedest . " -f " . $localremoveworkdir . " -e \\\*";
265 }
266 else
267 {
268 $systemcall = $msidb . " -d " . $completeremovedest . " -f " . $removeworkdir . " -e \*";
269 }
270
271 $returnvalue = system($systemcall);
272
273 my $idtfilename = $removeworkdir . $installer::globals::separator . "File.idt";
274 if ( -f $idtfilename ) { unlink $idtfilename; }
275 unlink $completeremovedest;
276
277 # Packing msm file without "File.idt"
278 if ( $^O =~ /cygwin/i ) {
279 # msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
280 my $localcompleteremovedest = $completeremovedest;
281 my $localremoveworkdir = $removeworkdir;
282 $localcompleteremovedest =~ s/\//\\\\/g;
283 $localremoveworkdir =~ s/\//\\\\/g;
284 $systemcall = $msidb . " -c -d " . $localcompleteremovedest . " -f " . $localremoveworkdir . " -i \\\*";
285 }
286 else
287 {
288 $systemcall = $msidb . " -c -d " . $completeremovedest . " -f " . $removeworkdir . " -i \*";
289 }
290 $returnvalue = system($systemcall);
291
292 # Using this msm file for merging
293 if ( -f $completeremovedest ) { $completedest = $completeremovedest; }
294 else { installer::exiter::exit_program("ERROR: Could not find msm file without File.idt: $completeremovedest !", "merge_mergemodules_into_msi_database"); }
295 }
296
297 # Saving MergeModule info
298
29956µs my %onemergemodulehash = ();
300514µs $onemergemodulehash{'mergefilepath'} = $completedest;
301513µs $onemergemodulehash{'workdir'} = $workdir;
302518µs $onemergemodulehash{'cabinetfile'} = $workdir . $installer::globals::separator . $cabinetfile;
30356µs $onemergemodulehash{'filenumber'} = $filecounter;
304511µs $onemergemodulehash{'componentnames'} = \%componentnames;
305522µs $onemergemodulehash{'componentcondition'} = $mergemodule->{'ComponentCondition'};
30656µs $onemergemodulehash{'cabfilename'} = $cabfilename;
307518µs $onemergemodulehash{'feature'} = $mergemodule->{'Feature'};
308514µs $onemergemodulehash{'rootdir'} = $mergemodule->{'RootDir'};
309513µs $onemergemodulehash{'name'} = $mergemodule->{'Name'};
310510µs $onemergemodulehash{'mergefilesequence'} = \%mergefilesequence;
31157µs $onemergemodulehash{'mergeassemblies'} = \%mergeassemblies;
31256µs $onemergemodulehash{'mergedirectories'} = \%mergedirectories;
31354µs $onemergemodulehash{'hasmsiassemblies'} = $hasmsiassemblies;
31456µs $onemergemodulehash{'removefiletable'} = $removefiletable;
315514µs $onemergemodulehash{'fileidtcontent'} = \@file_idt_content;
316
317518µs $installer::globals::mergemodules{$mergegid} = \%onemergemodulehash;
318
319 # Collecting all cab files, to copy them into installation set
32053µs if ( $cabfilename ) { $installer::globals::copy_msm_files{$cabfilename} = $onemergemodulehash{'cabinetfile'}; }
321
3225696µs5596µs chdir($from);
# spent 596µs making 5 calls to installer::windows::mergemodule::CORE:chdir, avg 119µs/call
323 }
324
32511µs $infoline = "All Merge Modules successfully analyzed\n";
32612µs push( @installer::globals::logfileinfo, $infoline);
327
32811µs $installer::globals::mergemodules_analyzed = 1;
32916µs1214µs installer::logger::include_timestamp_into_logfile("\nPerformance Info: Analyzing MergeModules, stop");
# spent 214µs making 1 call to installer::logger::include_timestamp_into_logfile
330
3311500ns $infoline = "\n";
33212µs push( @installer::globals::logfileinfo, $infoline);
333 }
334
335 # 2. Change msi database (has to be done for every msi database -> for every language)
336 # a. Merge msm file into msi database: msidb.exe -d <msifile> -m <mergefile>
337 # b. Extracting tables from msi database: msidb.exe -d <msifile> -f <directory> -e File Media, ...
338 # c. Changing content of msi database in tables: File, Media, Directory, FeatureComponent
339 # d. Including tables into msi database: msidb.exe -d <msifile> -f <directory> -i File Media, ...
340 # e. Copying cabinet file into installation set (later)
341
3421500ns my $counter = 0;
3431500ns my $mergemodulegid;
344113µs foreach $mergemodulegid (keys %installer::globals::mergemodules)
345 {
346515µs my $mergemodulehash = $installer::globals::mergemodules{$mergemodulegid};
34754µs $counter++;
348
349541µs5684µs installer::logger::include_header_into_logfile("Merging Module: $mergemodulehash->{'name'}");
# spent 684µs making 5 calls to installer::logger::include_header_into_logfile, avg 137µs/call
350529µs5104µs installer::logger::print_message( "\t... $mergemodulehash->{'name'} ... \n" );
# spent 104µs making 5 calls to installer::logger::print_message, avg 21µs/call
351
352533µs5144µs $msifilename = installer::converter::make_path_conform($msifilename);
# spent 144µs making 5 calls to installer::converter::make_path_conform, avg 29µs/call
35356µs my $workdir = $msifilename;
354530µs5234µs installer::pathanalyzer::get_path_from_fullqualifiedname(\$workdir);
# spent 234µs making 5 calls to installer::pathanalyzer::get_path_from_fullqualifiedname, avg 47µs/call
355
356 # changing directory
357536µs578µs my $from = cwd();
# spent 78µs making 5 calls to Cwd::__ANON__[Cwd.pm:406], avg 16µs/call
35856µs my $to = $workdir;
3595677µs5637µs chdir($to);
# spent 637µs making 5 calls to installer::windows::mergemodule::CORE:chdir, avg 127µs/call
360
361 # Saving original msi database
362541µs5112ms installer::systemactions::copy_one_file($msifilename, "$msifilename\.$counter");
# spent 112ms making 5 calls to installer::systemactions::copy_one_file, avg 22.3ms/call
363
364 # Merging msm file, this is the "real" merge command
365
366542µs51.03ms installer::logger::include_timestamp_into_logfile("\nPerformance Info: Before merging database");
# spent 1.03ms making 5 calls to installer::logger::include_timestamp_into_logfile, avg 206µs/call
367
368572µs529µs if ( $^O =~ /cygwin/i ) {
# spent 29µs making 5 calls to installer::windows::mergemodule::CORE:match, avg 6µs/call
369 # msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
370521µs my $localmergemodulepath = $mergemodulehash->{'mergefilepath'};
37158µs my $localmsifilename = $msifilename;
3725155µs5119µs $localmergemodulepath =~ s/\//\\\\/g;
# spent 119µs making 5 calls to installer::windows::mergemodule::CORE:subst, avg 24µs/call
3735112µs582µs $localmsifilename =~ s/\//\\\\/g;
# spent 82µs making 5 calls to installer::windows::mergemodule::CORE:subst, avg 16µs/call
374520µs $systemcall = $msidb . " -d " . $localmsifilename . " -m " . $localmergemodulepath;
375 }
376 else
377 {
378 $systemcall = $msidb . " -d " . $msifilename . " -m " . $mergemodulehash->{'mergefilepath'};
379 }
38053.68s53.68s $returnvalue = system($systemcall);
# spent 3.68s making 5 calls to installer::windows::mergemodule::CORE:system, avg 737ms/call
381
382530µs $infoline = "Systemcall: $systemcall\n";
383559µs push( @installer::globals::logfileinfo, $infoline);
384
385512µs if ($returnvalue)
386 {
387 $infoline = "ERROR: Could not execute $systemcall . Returnvalue: $returnvalue!\n";
388 push( @installer::globals::logfileinfo, $infoline);
389 installer::exiter::exit_program("ERROR: Could not merge msm file into database: $mergemodulehash->{'mergefilepath'} !", "merge_mergemodules_into_msi_database");
390 }
391 else
392 {
393512µs $infoline = "Success: Executed $systemcall successfully!\n";
394519µs push( @installer::globals::logfileinfo, $infoline);
395 }
396
397553µs51.10ms installer::logger::include_timestamp_into_logfile("\nPerformance Info: After merging database");
# spent 1.10ms making 5 calls to installer::logger::include_timestamp_into_logfile, avg 221µs/call
398
399 # Saving original idt files
40051.30ms915.1ms if ( -f "File.idt" ) { installer::systemactions::rename_one_file("File.idt", "old.File.idt.$counter"); }
# spent 13.8ms making 4 calls to installer::systemactions::rename_one_file, avg 3.46ms/call # spent 1.22ms making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 244µs/call
4015763µs93.37ms if ( -f "Media.idt" ) { installer::systemactions::rename_one_file("Media.idt", "old.Media.idt.$counter"); }
# spent 2.68ms making 4 calls to installer::systemactions::rename_one_file, avg 671µs/call # spent 692µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 138µs/call
4025983µs5942µs if ( -f "Directory.idt" ) { installer::systemactions::rename_one_file("Directory.idt", "old.Directory.idt.$counter"); }
# spent 942µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 188µs/call
4035571µs93.08ms if ( -f "Director.idt" ) { installer::systemactions::rename_one_file("Director.idt", "old.Director.idt.$counter"); }
# spent 2.56ms making 4 calls to installer::systemactions::rename_one_file, avg 640µs/call # spent 519µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 104µs/call
4045960µs5923µs if ( -f "FeatureComponents.idt" ) { installer::systemactions::rename_one_file("FeatureComponents.idt", "old.FeatureComponents.idt.$counter"); }
# spent 923µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 185µs/call
4055570µs910.2ms if ( -f "FeatureC.idt" ) { installer::systemactions::rename_one_file("FeatureC.idt", "old.FeatureC.idt.$counter"); }
# spent 9.69ms making 4 calls to installer::systemactions::rename_one_file, avg 2.42ms/call # spent 516µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 103µs/call
4065919µs5882µs if ( -f "MsiAssembly.idt" ) { installer::systemactions::rename_one_file("MsiAssembly.idt", "old.MsiAssembly.idt.$counter"); }
# spent 882µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 176µs/call
4075569µs93.72ms if ( -f "MsiAssem.idt" ) { installer::systemactions::rename_one_file("MsiAssem.idt", "old.MsiAssem.idt.$counter"); }
# spent 3.20ms making 4 calls to installer::systemactions::rename_one_file, avg 801µs/call # spent 516µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 103µs/call
4085585µs917.0ms if ( -f "Componen.idt" ) { installer::systemactions::rename_one_file("Componen.idt", "old.Componen.idt.$counter"); }
# spent 16.5ms making 4 calls to installer::systemactions::rename_one_file, avg 4.12ms/call # spent 531µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 106µs/call
409
410 # Extracting tables
411
412531µs5940µs installer::logger::include_timestamp_into_logfile("\nPerformance Info: Before extracting tables");
# spent 940µs making 5 calls to installer::logger::include_timestamp_into_logfile, avg 188µs/call
413
41455µs my $workingtables = "File Media Directory FeatureComponents"; # required tables
415 # Optional tables can be added now
416516µs if ( $mergemodulehash->{'hasmsiassemblies'} ) { $workingtables = $workingtables . " MsiAssembly"; }
41758µs if ( $mergemodulehash->{'componentcondition'} ) { $workingtables = $workingtables . " Component"; }
418
419 # Table "Feature" has to be exported, but it is not necessary to import it.
420566µs527µs if ( $^O =~ /cygwin/i ) {
# spent 27µs making 5 calls to installer::windows::mergemodule::CORE:match, avg 5µs/call
421 # msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
42259µs my $localmsifilename = $msifilename;
42358µs my $localworkdir = $workdir;
4245146µs5111µs $localmsifilename =~ s/\//\\\\/g;
# spent 111µs making 5 calls to installer::windows::mergemodule::CORE:subst, avg 22µs/call
4255105µs579µs $localworkdir =~ s/\//\\\\/g;
# spent 79µs making 5 calls to installer::windows::mergemodule::CORE:subst, avg 16µs/call
426521µs $systemcall = $msidb . " -d " . $localmsifilename . " -f " . $localworkdir . " -e " . "Feature " . $workingtables;
427 }
428 else
429 {
430 $systemcall = $msidb . " -d " . $msifilename . " -f " . $workdir . " -e " . "Feature " . $workingtables;
431 }
432534.0s534.0s $returnvalue = system($systemcall);
# spent 34.0s making 5 calls to installer::windows::mergemodule::CORE:system, avg 6.80s/call
433
434542µs $infoline = "Systemcall: $systemcall\n";
435550µs push( @installer::globals::logfileinfo, $infoline);
436
437513µs if ($returnvalue)
438 {
439 $infoline = "ERROR: Could not execute $systemcall !\n";
440 push( @installer::globals::logfileinfo, $infoline);
441 installer::exiter::exit_program("ERROR: Could not exclude tables from msi database: $msifilename !", "merge_mergemodules_into_msi_database");
442 }
443 else
444 {
445513µs $infoline = "Success: Executed $systemcall successfully!\n";
446520µs push( @installer::globals::logfileinfo, $infoline);
447 }
448
449559µs51.11ms installer::logger::include_timestamp_into_logfile("\nPerformance Info: After extracting tables");
# spent 1.11ms making 5 calls to installer::logger::include_timestamp_into_logfile, avg 222µs/call
450
451 # Using 8+3 table names, that are used, when tables are integrated into database. The export of tables
452 # creates idt-files, that have long names.
453
45451.17ms1010.4ms if ( -f "Directory.idt" ) { installer::systemactions::rename_one_file("Directory.idt", "Director.idt"); }
# spent 9.32ms making 5 calls to installer::systemactions::rename_one_file, avg 1.86ms/call # spent 1.09ms making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 219µs/call
4555734µs1021.7ms if ( -f "FeatureComponents.idt" ) { installer::systemactions::rename_one_file("FeatureComponents.idt", "FeatureC.idt"); }
# spent 21.0ms making 5 calls to installer::systemactions::rename_one_file, avg 4.20ms/call # spent 657µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 131µs/call
4565609µs93.72ms if ( -f "MsiAssembly.idt" ) { installer::systemactions::rename_one_file("MsiAssembly.idt", "MsiAssem.idt"); }
# spent 3.16ms making 4 calls to installer::systemactions::rename_one_file, avg 791µs/call # spent 556µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 111µs/call
4575526µs1032.2ms if ( -f "Component.idt" ) { installer::systemactions::rename_one_file("Component.idt", "Componen.idt"); }
# spent 31.7ms making 5 calls to installer::systemactions::rename_one_file, avg 6.35ms/call # spent 470µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 94µs/call
458
459 # Changing content of tables: File, Media, Directory, FeatureComponent, MsiAssembly, Component
460527µs5893µs installer::logger::include_timestamp_into_logfile("\nPerformance Info: Changing Media table");
# spent 893µs making 5 calls to installer::logger::include_timestamp_into_logfile, avg 179µs/call
461530µs55.22ms change_media_table($mergemodulehash, $workdir, $mergemodulegid, $allupdatelastsequences, $allupdatediskids);
# spent 5.22ms making 5 calls to installer::windows::mergemodule::change_media_table, avg 1.04ms/call
462519µs5590µs installer::logger::include_timestamp_into_logfile("\nPerformance Info: Changing File table");
# spent 590µs making 5 calls to installer::logger::include_timestamp_into_logfile, avg 118µs/call
463532µs512.1s $filesref = change_file_table($mergemodulehash, $workdir, $allupdatesequences, $includepatharrayref, $filesref, $mergemodulegid);
# spent 12.1s making 5 calls to installer::windows::mergemodule::change_file_table, avg 2.42s/call
464555µs51.09ms installer::logger::include_timestamp_into_logfile("\nPerformance Info: Changing FeatureComponent table");
# spent 1.09ms making 5 calls to installer::logger::include_timestamp_into_logfile, avg 218µs/call
465534µs5264ms change_featurecomponent_table($mergemodulehash, $workdir);
# spent 264ms making 5 calls to installer::windows::mergemodule::change_featurecomponent_table, avg 52.7ms/call
466553µs51.06ms installer::logger::include_timestamp_into_logfile("\nPerformance Info: Changing Directory table");
# spent 1.06ms making 5 calls to installer::logger::include_timestamp_into_logfile, avg 213µs/call
467526µs554µs change_directory_table($mergemodulehash, $workdir);
# spent 54µs making 5 calls to installer::windows::mergemodule::change_directory_table, avg 11µs/call
468512µs if ( $mergemodulehash->{'hasmsiassemblies'} )
469 {
470412µs4450µs installer::logger::include_timestamp_into_logfile("\nPerformance Info: Changing MsiAssembly table");
# spent 450µs making 4 calls to installer::logger::include_timestamp_into_logfile, avg 112µs/call
471418µs45.80ms change_msiassembly_table($mergemodulehash, $workdir);
# spent 5.80ms making 4 calls to installer::windows::mergemodule::change_msiassembly_table, avg 1.45ms/call
472 }
473
474519µs if ( $mergemodulehash->{'componentcondition'} )
475 {
476516µs5607µs installer::logger::include_timestamp_into_logfile("\nPerformance Info: Changing Component table");
# spent 607µs making 5 calls to installer::logger::include_timestamp_into_logfile, avg 121µs/call
477524µs53.87s change_component_table($mergemodulehash, $workdir);
# spent 3.87s making 5 calls to installer::windows::mergemodule::change_component_table, avg 774ms/call
478 }
479
480 # msidb.exe does not merge InstallExecuteSequence, AdminExecuteSequence and AdvtExecuteSequence. Instead it creates
481 # new tables ModuleInstallExecuteSequence, ModuleAdminExecuteSequence and ModuleAdvtExecuteSequence that need to be
482 # merged into the three ExecuteSequences with the following process (also into InstallUISequence.idt).
483
484 # Saving original idt files
48551.27ms95.00ms if ( -f "InstallE.idt" ) { installer::systemactions::rename_one_file("InstallE.idt", "old.InstallE.idt.$counter"); }
# spent 3.82ms making 4 calls to installer::systemactions::rename_one_file, avg 955µs/call # spent 1.18ms making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 236µs/call
4865680µs93.29ms if ( -f "InstallU.idt" ) { installer::systemactions::rename_one_file("InstallU.idt", "old.InstallU.idt.$counter"); }
# spent 2.66ms making 4 calls to installer::systemactions::rename_one_file, avg 666µs/call # spent 624µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 125µs/call
4875592µs93.30ms if ( -f "AdminExe.idt" ) { installer::systemactions::rename_one_file("AdminExe.idt", "old.AdminExe.idt.$counter"); }
# spent 2.75ms making 4 calls to installer::systemactions::rename_one_file, avg 688µs/call # spent 545µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 109µs/call
4885597µs93.08ms if ( -f "AdvtExec.idt" ) { installer::systemactions::rename_one_file("AdvtExec.idt", "old.AdvtExec.idt.$counter"); }
# spent 2.54ms making 4 calls to installer::systemactions::rename_one_file, avg 635µs/call # spent 541µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 108µs/call
4895602µs93.15ms if ( -f "ModuleInstallExecuteSequence.idt" ) { installer::systemactions::rename_one_file("ModuleInstallExecuteSequence.idt", "old.ModuleInstallExecuteSequence.idt.$counter"); }
# spent 2.60ms making 4 calls to installer::systemactions::rename_one_file, avg 650µs/call # spent 554µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 111µs/call
4905602µs93.19ms if ( -f "ModuleAdminExecuteSequence.idt" ) { installer::systemactions::rename_one_file("ModuleAdminExecuteSequence.idt", "old.ModuleAdminExecuteSequence.idt.$counter"); }
# spent 2.64ms making 4 calls to installer::systemactions::rename_one_file, avg 660µs/call # spent 549µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 110µs/call
4915593µs93.39ms if ( -f "ModuleAdvtExecuteSequence.idt" ) { installer::systemactions::rename_one_file("ModuleAdvtExecuteSequence.idt", "old.ModuleAdvtExecuteSequence.idt.$counter"); }
# spent 2.84ms making 4 calls to installer::systemactions::rename_one_file, avg 711µs/call # spent 547µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 109µs/call
492
493 # Extracting tables
49458µs my $moduleexecutetables = "ModuleInstallExecuteSequence ModuleAdminExecuteSequence ModuleAdvtExecuteSequence"; # new tables
49554µs my $executetables = "InstallExecuteSequence InstallUISequence AdminExecuteSequence AdvtExecuteSequence"; # tables to be merged
496
497
498596µs560µs if ( $^O =~ /cygwin/i ) {
# spent 60µs making 5 calls to installer::windows::mergemodule::CORE:match, avg 12µs/call
499 # msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
50058µs my $localmsifilename = $msifilename;
50157µs my $localworkdir = $workdir;
5025162µs5127µs $localmsifilename =~ s/\//\\\\/g;
# spent 127µs making 5 calls to installer::windows::mergemodule::CORE:subst, avg 25µs/call
5035100µs576µs $localworkdir =~ s/\//\\\\/g;
# spent 76µs making 5 calls to installer::windows::mergemodule::CORE:subst, avg 15µs/call
504523µs $systemcall = $msidb . " -d " . $localmsifilename . " -f " . $localworkdir . " -e " . "Feature " . $moduleexecutetables;
505 }
506 else
507 {
508 $systemcall = $msidb . " -d " . $msifilename . " -f " . $workdir . " -e " . "Feature " . $moduleexecutetables;
509 }
51053.30s53.30s $returnvalue = system($systemcall);
# spent 3.30s making 5 calls to installer::windows::mergemodule::CORE:system, avg 659ms/call
511
5125642µs5586µs if ( $^O =~ /cygwin/i ) {
# spent 586µs making 5 calls to installer::windows::mergemodule::CORE:match, avg 117µs/call
513 # msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
514518µs my $localmsifilename = $msifilename;
51557µs my $localworkdir = $workdir;
5165208µs5166µs $localmsifilename =~ s/\//\\\\/g;
# spent 166µs making 5 calls to installer::windows::mergemodule::CORE:subst, avg 33µs/call
5175106µs579µs $localworkdir =~ s/\//\\\\/g;
# spent 79µs making 5 calls to installer::windows::mergemodule::CORE:subst, avg 16µs/call
518538µs $systemcall = $msidb . " -d " . $localmsifilename . " -f " . $localworkdir . " -e " . "Feature " . $executetables;
519 }
520 else
521 {
522 $systemcall = $msidb . " -d " . $msifilename . " -f " . $workdir . " -e " . "Feature " . $executetables;
523 }
52453.34s53.34s $returnvalue = system($systemcall);
# spent 3.34s making 5 calls to installer::windows::mergemodule::CORE:system, avg 667ms/call
525
526 # Using 8+3 table names, that are used, when tables are integrated into database. The export of tables
527 # creates idt-files, that have long names.
528
52951.20ms107.73ms if ( -f "InstallExecuteSequence.idt" ) { installer::systemactions::rename_one_file("InstallExecuteSequence.idt", "InstallE.idt"); }
# spent 6.64ms making 5 calls to installer::systemactions::rename_one_file, avg 1.33ms/call # spent 1.09ms making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 219µs/call
5305700µs105.98ms if ( -f "InstallUISequence.idt" ) { installer::systemactions::rename_one_file("InstallUISequence.idt", "InstallU.idt"); }
# spent 5.36ms making 5 calls to installer::systemactions::rename_one_file, avg 1.07ms/call # spent 625µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 125µs/call
5315594µs104.36ms if ( -f "AdminExecuteSequence.idt" ) { installer::systemactions::rename_one_file("AdminExecuteSequence.idt", "AdminExe.idt"); }
# spent 3.83ms making 5 calls to installer::systemactions::rename_one_file, avg 766µs/call # spent 535µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 107µs/call
5325512µs103.74ms if ( -f "AdvtExecuteSequence.idt" ) { installer::systemactions::rename_one_file("AdvtExecuteSequence.idt", "AdvtExec.idt"); }
# spent 3.27ms making 5 calls to installer::systemactions::rename_one_file, avg 655µs/call # spent 462µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 92µs/call
533
534 # Merging content of tables ModuleInstallExecuteSequence, ModuleAdminExecuteSequence and ModuleAdvtExecuteSequence
535 # into tables InstallExecuteSequence, AdminExecuteSequence and AdvtExecuteSequence
5365506µs5468µs if ( -f "ModuleInstallExecuteSequence.idt" )
# spent 468µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 94µs/call
537 {
538531µs5996µs installer::logger::include_timestamp_into_logfile("\nPerformance Info: Changing InstallExecuteSequence table");
# spent 996µs making 5 calls to installer::logger::include_timestamp_into_logfile, avg 199µs/call
539531µs522.8ms change_executesequence_table($mergemodulehash, $workdir, "InstallE.idt", "ModuleInstallExecuteSequence.idt");
# spent 22.8ms making 5 calls to installer::windows::mergemodule::change_executesequence_table, avg 4.57ms/call
540520µs5641µs installer::logger::include_timestamp_into_logfile("\nPerformance Info: Changing InstallUISequence table");
# spent 641µs making 5 calls to installer::logger::include_timestamp_into_logfile, avg 128µs/call
541520µs513.0ms change_executesequence_table($mergemodulehash, $workdir, "InstallU.idt", "ModuleInstallExecuteSequence.idt");
# spent 13.0ms making 5 calls to installer::windows::mergemodule::change_executesequence_table, avg 2.60ms/call
542 }
543
5445512µs5475µs if ( -f "ModuleAdminExecuteSequence.idt" )
# spent 475µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 95µs/call
545 {
546518µs5603µs installer::logger::include_timestamp_into_logfile("\nPerformance Info: Changing AdminExecuteSequence table");
# spent 603µs making 5 calls to installer::logger::include_timestamp_into_logfile, avg 121µs/call
547518µs58.19ms change_executesequence_table($mergemodulehash, $workdir, "AdminExe.idt", "ModuleAdminExecuteSequence.idt");
# spent 8.19ms making 5 calls to installer::windows::mergemodule::change_executesequence_table, avg 1.64ms/call
548 }
549
5505505µs5469µs if ( -f "ModuleAdvtExecuteSequence.idt" )
# spent 469µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 94µs/call
551 {
552518µs5588µs installer::logger::include_timestamp_into_logfile("\nPerformance Info: Changing AdvtExecuteSequence table");
# spent 588µs making 5 calls to installer::logger::include_timestamp_into_logfile, avg 118µs/call
553516µs57.71ms change_executesequence_table($mergemodulehash, $workdir, "AdvtExec.idt", "ModuleAdvtExecuteSequence.idt");
# spent 7.71ms making 5 calls to installer::windows::mergemodule::change_executesequence_table, avg 1.54ms/call
554 }
555
556518µs5583µs installer::logger::include_timestamp_into_logfile("\nPerformance Info: All tables edited");
# spent 583µs making 5 calls to installer::logger::include_timestamp_into_logfile, avg 117µs/call
557
558 # Including tables into msi database
559
560514µs5532µs installer::logger::include_timestamp_into_logfile("\nPerformance Info: Before including tables");
# spent 532µs making 5 calls to installer::logger::include_timestamp_into_logfile, avg 106µs/call
561
5625112µs527µs if ( $^O =~ /cygwin/i ) {
# spent 27µs making 5 calls to installer::windows::mergemodule::CORE:match, avg 5µs/call
563 # msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
56457µs my $localmsifilename = $msifilename;
56554µs my $localworkdir = $workdir;
5665132µs5101µs $localmsifilename =~ s/\//\\\\/g;
# spent 101µs making 5 calls to installer::windows::mergemodule::CORE:subst, avg 20µs/call
567598µs576µs $localworkdir =~ s/\//\\\\/g;
# spent 76µs making 5 calls to installer::windows::mergemodule::CORE:subst, avg 15µs/call
568564µs foreach $table (split / /, $workingtables . ' ' . $executetables) {
56949207µs $systemcall = $msidb . " -d " . $localmsifilename . " -f " . $localworkdir . " -i " . $table;
5704934.9s4934.9s my $retval = system($systemcall);
# spent 34.9s making 49 calls to installer::windows::mergemodule::CORE:system, avg 712ms/call
57149864µs $infoline = "Systemcall returned $retval: $systemcall\n";
57249495µs push( @installer::globals::logfileinfo, $infoline);
57349330µs $returnvalue |= $retval;
574 }
575 }
576 else
577 {
578 $systemcall = $msidb . " -d " . $msifilename . " -f " . $workdir . " -i " . $workingtables. " " . $executetables;
579 $returnvalue = system($systemcall);
580 $infoline = "Systemcall: $systemcall\n";
581 push( @installer::globals::logfileinfo, $infoline);
582
583 }
584
585511µs if ($returnvalue)
586 {
587 $infoline = "ERROR: Could not execute $systemcall !\n";
588 push( @installer::globals::logfileinfo, $infoline);
589 installer::exiter::exit_program("ERROR: Could not include tables into msi database: $msifilename !", "merge_mergemodules_into_msi_database");
590 }
591 else
592 {
593512µs $infoline = "Success: Executed $systemcall successfully!\n";
594511µs push( @installer::globals::logfileinfo, $infoline);
595 }
596
597547µs51.04ms installer::logger::include_timestamp_into_logfile("\nPerformance Info: After including tables");
# spent 1.04ms making 5 calls to installer::logger::include_timestamp_into_logfile, avg 208µs/call
598
59951.18ms51.09ms chdir($from);
# spent 1.09ms making 5 calls to installer::windows::mergemodule::CORE:chdir, avg 217µs/call
600 }
601
60223µs if ( ! $installer::globals::mergefiles_added_into_collector ) { $installer::globals::mergefiles_added_into_collector = 1; } # Now all mergemodules are merged for one language.
603
60414µs1112µs installer::logger::include_timestamp_into_logfile("\nPerformance Info: MergeModule into msi database, stop");
# spent 112µs making 1 call to installer::logger::include_timestamp_into_logfile
605 }
606
607111µs return $filesref;
608}
609
610#########################################################################
611# Analyzing the content of the media table.
612#########################################################################
613
614sub analyze_media_file
615
# spent 373µs (320+54) within installer::windows::mergemodule::analyze_media_file which was called 5 times, avg 75µs/call: # 5 times (320µs+54µs) by installer::windows::mergemodule::change_media_table at line 859, avg 75µs/call
{
616513µs my ($filecontent, $workdir) = @_;
617
618512µs my %filehash = ();
61955µs my $linecount = 0;
62054µs my $counter = 0;
62155µs my $filename = "Media.idt";
622
623534µs for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
624 {
6253525µs if ( $i <= 2 ) { next; } # ignoring first three lines
626560µs524µs if ( ${$filecontent}[$i] =~ /^\s*$/ ) { next; } # ignoring empty lines
# spent 24µs making 5 calls to installer::windows::mergemodule::CORE:match, avg 5µs/call
627565µs530µs if ( ${$filecontent}[$i] =~ /^\s*(.+?)\t(.+?)\t(.+?)\t(.+?)\t(.+?)\t(.*?)\s*$/ )
# spent 30µs making 5 calls to installer::windows::mergemodule::CORE:match, avg 6µs/call
628 {
62956µs my %line = ();
630 # Format: DiskId LastSequence DiskPrompt Cabinet VolumeLabel Source
631523µs $line{'DiskId'} = $1;
632516µs $line{'LastSequence'} = $2;
633513µs $line{'DiskPrompt'} = $3;
634514µs $line{'Cabinet'} = $4;
635514µs $line{'VolumeLabel'} = $5;
636514µs $line{'Source'} = $6;
637
63853µs $counter++;
639520µs $filehash{$counter} = \%line;
640 }
641 else
642 {
643 $linecount = $i + 1;
644 installer::exiter::exit_program("ERROR: Unknown line format in table \"$filename\" in \"$workdir\" (line $linecount) !", "analyze_media_file");
645 }
646 }
647
648539µs return \%filehash;
649}
650
651#########################################################################
652# Setting the DiskID for the new cabinet file
653#########################################################################
654
655sub get_diskid
656{
657 my ($mediafile, $allupdatediskids, $cabfilename) = @_;
658
659 my $diskid = 0;
660 my $line;
661
662 if (( $installer::globals::updatedatabase ) && ( exists($allupdatediskids->{$cabfilename}) ))
663 {
664 $diskid = $allupdatediskids->{$cabfilename};
665 }
666 else
667 {
668 foreach $line ( keys %{$mediafile} )
669 {
670 if ( $mediafile->{$line}->{'DiskId'} > $diskid ) { $diskid = $mediafile->{$line}->{'DiskId'}; }
671 }
672
673 $diskid++;
674 }
675
676 return $diskid;
677}
678
679#########################################################################
680# Setting the global LastSequence variable
681#########################################################################
682
683sub set_current_last_sequence
684
# spent 98µs within installer::windows::mergemodule::set_current_last_sequence which was called 5 times, avg 20µs/call: # 5 times (98µs+0s) by installer::windows::mergemodule::change_media_table at line 860, avg 20µs/call
{
68556µs my ($mediafile) = @_;
686
68755µs my $lastsequence = 0;
68852µs my $line;
689535µs foreach $line ( keys %{$mediafile} )
690 {
691528µs if ( $mediafile->{$line}->{'LastSequence'} > $lastsequence ) { $lastsequence = $mediafile->{$line}->{'LastSequence'}; }
692 }
693
694540µs $installer::globals::lastsequence_before_merge = $lastsequence;
695}
696
697#########################################################################
698# Setting the LastSequence for the new cabinet file
699#########################################################################
700
701sub get_lastsequence
702{
703 my ($mergemodulehash, $allupdatelastsequences) = @_;
704
705 my $lastsequence = 0;
706
707 if (( $installer::globals::updatedatabase ) && ( exists($allupdatelastsequences->{$mergemodulehash->{'cabfilename'}}) ))
708 {
709 $lastsequence = $allupdatelastsequences->{$mergemodulehash->{'cabfilename'}};
710 }
711 else
712 {
713 $lastsequence = $installer::globals::lastsequence_before_merge + $mergemodulehash->{'filenumber'};
714 }
715
716 return $lastsequence;
717}
718
719#########################################################################
720# Setting the DiskPrompt for the new cabinet file
721#########################################################################
722
723sub get_diskprompt
724{
725 my ($mediafile) = @_;
726
727 my $diskprompt = "";
728 my $line;
729 foreach $line ( keys %{$mediafile} )
730 {
731 if ( exists($mediafile->{$line}->{'DiskPrompt'}) )
732 {
733 $diskprompt = $mediafile->{$line}->{'DiskPrompt'};
734 last;
735 }
736 }
737
738 return $diskprompt;
739}
740
741#########################################################################
742# Setting the VolumeLabel for the new cabinet file
743#########################################################################
744
745sub get_volumelabel
746{
747 my ($mediafile) = @_;
748
749 my $volumelabel = "";
750 my $line;
751 foreach $line ( keys %{$mediafile} )
752 {
753 if ( exists($mediafile->{$line}->{'VolumeLabel'}) )
754 {
755 $volumelabel = $mediafile->{$line}->{'VolumeLabel'};
756 last;
757 }
758 }
759
760 return $volumelabel;
761}
762
763#########################################################################
764# Setting the Source for the new cabinet file
765#########################################################################
766
767sub get_source
768{
769 my ($mediafile) = @_;
770
771 my $source = "";
772 my $line;
773 foreach $line ( keys %{$mediafile} )
774 {
775 if ( exists($mediafile->{$line}->{'Source'}) )
776 {
777 $diskprompt = $mediafile->{$line}->{'Source'};
778 last;
779 }
780 }
781
782 return $source;
783}
784
785#########################################################################
786# For each Merge Module one new line has to be included into the
787# media table.
788#########################################################################
789
790sub create_new_media_line
791{
792 my ($mergemodulehash, $mediafile, $allupdatelastsequences, $allupdatediskids) = @_;
793
794 my $diskid = get_diskid($mediafile, $allupdatediskids, $mergemodulehash->{'cabfilename'});
795 my $lastsequence = get_lastsequence($mergemodulehash, $allupdatelastsequences);
796 my $diskprompt = get_diskprompt($mediafile);
797 my $cabinet = $mergemodulehash->{'cabfilename'};
798 my $volumelabel = get_volumelabel($mediafile);
799 my $source = get_source($mediafile);
800
801 if ( $installer::globals::include_cab_in_msi ) { $cabinet = "\#" . $cabinet; }
802
803 my $newline = "$diskid\t$lastsequence\t$diskprompt\t$cabinet\t$volumelabel\t$source\n";
804
805 return $newline;
806}
807
808#########################################################################
809# Setting the last diskid in media table.
810#########################################################################
811
812sub get_last_diskid
813
# spent 63µs within installer::windows::mergemodule::get_last_diskid which was called 5 times, avg 13µs/call: # 5 times (63µs+0s) by installer::windows::mergemodule::change_media_table at line 865, avg 13µs/call
{
81454µs my ($mediafile) = @_;
815
81655µs my $lastdiskid = 0;
81752µs my $line;
818514µs foreach $line ( keys %{$mediafile} )
819 {
820518µs if ( $mediafile->{$line}->{'DiskId'} > $lastdiskid ) { $lastdiskid = $mediafile->{$line}->{'DiskId'}; }
821 }
822
823538µs return $lastdiskid;
824}
825
826#########################################################################
827# Setting global variable for last cab file name.
828#########################################################################
829
830sub set_last_cabfile_name
831
# spent 19µs within installer::windows::mergemodule::set_last_cabfile_name which was called: # once (19µs+0s) by installer::windows::mergemodule::change_media_table at line 866
{
83212µs my ($mediafile, $lastdiskid) = @_;
833
8341600ns my $line;
83512µs foreach $line ( keys %{$mediafile} )
836 {
83726µs if ( $mediafile->{$line}->{'DiskId'} == $lastdiskid ) { $installer::globals::lastcabfilename = $mediafile->{$line}->{'Cabinet'}; }
838 }
83914µs my $infoline = "Setting last cabinet file: $installer::globals::lastcabfilename\n";
840110µs push( @installer::globals::logfileinfo, $infoline);
841}
842
843#########################################################################
844# In the media table the new cabinet file has to be added or the
845# number of the last cabinet file has to be increased.
846#########################################################################
847
848sub change_media_table
849
# spent 5.22ms (602µs+4.62) within installer::windows::mergemodule::change_media_table which was called 5 times, avg 1.04ms/call: # 5 times (602µs+4.62ms) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 461, avg 1.04ms/call
{
850524µs my ( $mergemodulehash, $workdir, $mergemodulegid, $allupdatelastsequences, $allupdatediskids ) = @_;
851
85255µs my $infoline = "Changing content of table \"Media\"\n";
85355µs push( @installer::globals::logfileinfo, $infoline);
854
85555µs my $filename = "Media.idt";
8565531µs5493µs if ( ! -f $filename ) { installer::exiter::exit_program("ERROR: Could not find file \"$filename\" in \"$workdir\" !", "change_media_table"); }
# spent 493µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 99µs/call
857
858531µs51.46ms my $filecontent = installer::files::read_file($filename);
# spent 1.46ms making 5 calls to installer::files::read_file, avg 292µs/call
859528µs5373µs my $mediafile = analyze_media_file($filecontent, $workdir);
# spent 373µs making 5 calls to installer::windows::mergemodule::analyze_media_file, avg 75µs/call
860520µs598µs set_current_last_sequence($mediafile);
# spent 98µs making 5 calls to installer::windows::mergemodule::set_current_last_sequence, avg 20µs/call
861
86257µs if ( $installer::globals::fix_number_of_cab_files )
863 {
864 # Determining the line with the highest sequencenumber. That file needs to be updated.
865526µs563µs my $lastdiskid = get_last_diskid($mediafile);
# spent 63µs making 5 calls to installer::windows::mergemodule::get_last_diskid, avg 13µs/call
866512µs119µs if ( $installer::globals::lastcabfilename eq "" ) { set_last_cabfile_name($mediafile, $lastdiskid); }
867513µs my $newmaxsequencenumber = $installer::globals::lastsequence_before_merge + $mergemodulehash->{'filenumber'};
868
869529µs for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
870 {
8713516µs if ( $i <= 2 ) { next; } # ignoring first three lines
872542µs511µs if ( ${$filecontent}[$i] =~ /^\s*$/ ) { next; } # ignoring empty lines
# spent 11µs making 5 calls to installer::windows::mergemodule::CORE:match, avg 2µs/call
8735347µs10266µs if ( ${$filecontent}[$i] =~ /^\s*(\Q$lastdiskid\E\t)\Q$installer::globals::lastsequence_before_merge\E(\t.*)$/ )
# spent 244µs making 5 calls to installer::windows::mergemodule::CORE:regcomp, avg 49µs/call # spent 22µs making 5 calls to installer::windows::mergemodule::CORE:match, avg 4µs/call
874 {
87559µs my $start = $1;
87656µs my $final = $2;
877510µs $infoline = "Merge: Old line in media table: ${$filecontent}[$i]\n";
87858µs push( @installer::globals::logfileinfo, $infoline);
879514µs my $newline = $start . $newmaxsequencenumber . $final . "\n";
88054µs ${$filecontent}[$i] = $newline;
88157µs $infoline = "Merge: Changed line in media table: ${$filecontent}[$i]\n";
88257µs push( @installer::globals::logfileinfo, $infoline);
883 }
884 }
885 }
886 else
887 {
888 # the new line is identical for all localized databases, but has to be created for each MergeModule ($mergemodulegid)
889 if ( ! exists($installer::globals::merge_media_line{$mergemodulegid}) )
890 {
891 $installer::globals::merge_media_line{$mergemodulegid} = create_new_media_line($mergemodulehash, $mediafile, $allupdatelastsequences, $allupdatediskids);
892 }
893
894 $infoline = "Adding line: $installer::globals::merge_media_line{$mergemodulegid}\n";
895 push( @installer::globals::logfileinfo, $infoline);
896
897 # adding new line
898 push(@{$filecontent}, $installer::globals::merge_media_line{$mergemodulegid});
899 }
900
901 # saving file
902596µs51.83ms installer::files::save_file($filename, $filecontent);
# spent 1.83ms making 5 calls to installer::files::save_file, avg 366µs/call
903}
904
905#########################################################################
906# Putting the directory table content into a hash.
907#########################################################################
908
909sub analyze_directorytable_file
910{
911 my ($filecontent, $idtfilename) = @_;
912
913 my %dirhash = ();
914 # Iterating over the file content
915 for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
916 {
917 if ( $i <= 2 ) { next; } # ignoring first three lines
918 if ( ${$filecontent}[$i] =~ /^\s*$/ ) { next; } # ignoring empty lines
919 if ( ${$filecontent}[$i] =~ /^\s*(.+?)\t(.*?)\t(.*?)\s*$/ )
920 {
921 my %line = ();
922 # Format: Directory Directory_Parent DefaultDir
923 $line{'Directory'} = $1;
924 $line{'Directory_Parent'} = $2;
925 $line{'DefaultDir'} = $3;
926 $line{'linenumber'} = $i; # saving also the line number for direct access
927
928 my $uniquekey = $line{'Directory'};
929 $dirhash{$uniquekey} = \%line;
930 }
931 else
932 {
933 my $linecount = $i + 1;
934 installer::exiter::exit_program("ERROR: Unknown line format in table \"$idtfilename\" (line $linecount) !", "analyze_directorytable_file");
935 }
936 }
937
938 return \%dirhash;
939}
940
941#########################################################################
942# Putting the msi assembly table content into a hash.
943#########################################################################
944
945sub analyze_msiassemblytable_file
946
# spent 1.46ms (1.19+270µs) within installer::windows::mergemodule::analyze_msiassemblytable_file which was called 4 times, avg 365µs/call: # 4 times (1.19ms+270µs) by installer::windows::mergemodule::change_msiassembly_table at line 1524, avg 365µs/call
{
94747µs my ($filecontent, $idtfilename) = @_;
948
94948µs my %assemblyhash = ();
950 # Iterating over the file content
951492µs for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
952 {
9537438µs if ( $i <= 2 ) { next; } # ignoring first three lines
95450281µs5088µs if ( ${$filecontent}[$i] =~ /^\s*$/ ) { next; } # ignoring empty lines
# spent 88µs making 50 calls to installer::windows::mergemodule::CORE:match, avg 2µs/call
95550388µs50182µs if ( ${$filecontent}[$i] =~ /^\s*(.+?)\t(.+?)\t(.+?)\t(.*?)\t(.*?)\s*$/ )
# spent 182µs making 50 calls to installer::windows::mergemodule::CORE:match, avg 4µs/call
956 {
9575036µs my %line = ();
958 # Format: Component_ Feature_ File_Manifest File_Application Attributes
95950120µs $line{'Component'} = $1;
9605078µs $line{'Feature'} = $2;
9615069µs $line{'File_Manifest'} = $3;
9625071µs $line{'File_Application'} = $4;
9635073µs $line{'Attributes'} = $5;
9645036µs $line{'linenumber'} = $i; # saving also the line number for direct access
965
9665032µs my $uniquekey = $line{'Component'};
96750111µs $assemblyhash{$uniquekey} = \%line;
968 }
969 else
970 {
971 my $linecount = $i + 1;
972 installer::exiter::exit_program("ERROR: Unknown line format in table \"$idtfilename\" (line $linecount) !", "analyze_msiassemblytable_file");
973 }
974 }
975
976426µs return \%assemblyhash;
977}
978
979#########################################################################
980# Putting the file table content into a hash.
981#########################################################################
982
983sub analyze_filetable_file
984
# spent 2.38s (1.96+427ms) within installer::windows::mergemodule::analyze_filetable_file which was called 5 times, avg 477ms/call: # 5 times (1.96s+427ms) by installer::windows::mergemodule::change_file_table at line 1181, avg 477ms/call
{
985532µs my ( $filecontent, $idtfilename ) = @_;
986
987520µs my %filehash = ();
988 # Iterating over the file content
9895118ms for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
990 {
9917956431.2ms if ( $i <= 2 ) { next; } # ignoring first three lines
99279534401ms79534111ms if ( ${$filecontent}[$i] =~ /^\s*$/ ) { next; } # ignoring empty lines
# spent 111ms making 79534 calls to installer::windows::mergemodule::CORE:match, avg 1µs/call
99379534630ms79534315ms if ( ${$filecontent}[$i] =~ /^\s*(.+?)\t(.+?)\t(.+?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.+?)\s*$/ )
# spent 315ms making 79534 calls to installer::windows::mergemodule::CORE:match, avg 4µs/call
994 {
9957953449.5ms my %line = ();
996 # Format: File Component_ FileName FileSize Version Language Attributes Sequence
99779534172ms $line{'File'} = $1;
99879534110ms $line{'Component'} = $2;
99979534103ms $line{'FileName'} = $3;
100079534111ms $line{'FileSize'} = $4;
10017953496.6ms $line{'Version'} = $5;
100279534102ms $line{'Language'} = $6;
100379534107ms $line{'Attributes'} = $7;
100479534101ms $line{'Sequence'} = $8;
10057953451.8ms $line{'linenumber'} = $i; # saving also the line number for direct access
1006
10077953445.8ms my $uniquekey = $line{'File'};
100879534153ms $filehash{$uniquekey} = \%line;
1009 }
1010 else
1011 {
1012 my $linecount = $i + 1;
1013 installer::exiter::exit_program("ERROR: Unknown line format in table \"$idtfilename\" (line $linecount) !", "analyze_filetable_file");
1014 }
1015 }
1016
1017550µs return \%filehash;
1018}
1019
1020#########################################################################
1021# Creating a new line for the directory table.
1022#########################################################################
1023
1024sub get_new_line_for_directory_table
1025{
1026 my ($dir) = @_;
1027
1028 my $newline = "$dir->{'Directory'}\t$dir->{'Directory_Parent'}\t$dir->{'DefaultDir'}\n";
1029
1030 return $newline;
1031}
1032
1033#########################################################################
1034# Creating a new line for the file table.
1035#########################################################################
1036
1037sub get_new_line_for_file_table
1038
# spent 477µs within installer::windows::mergemodule::get_new_line_for_file_table which was called 33 times, avg 14µs/call: # 33 times (477µs+0s) by installer::windows::mergemodule::change_file_table at line 1213, avg 14µs/call
{
10393343µs my ($file) = @_;
1040
104133220µs my $newline = "$file->{'File'}\t$file->{'Component'}\t$file->{'FileName'}\t$file->{'FileSize'}\t$file->{'Version'}\t$file->{'Language'}\t$file->{'Attributes'}\t$file->{'Sequence'}\n";
1042
104333275µs return $newline;
1044}
1045
1046#########################################################################
1047# Creating a new line for the msiassembly table.
1048#########################################################################
1049
1050sub get_new_line_for_msiassembly_table
1051
# spent 44µs within installer::windows::mergemodule::get_new_line_for_msiassembly_table which was called 4 times, avg 11µs/call: # 4 times (44µs+0s) by installer::windows::mergemodule::change_msiassembly_table at line 1537, avg 11µs/call
{
105246µs my ($assembly) = @_;
1053
1054420µs my $newline = "$assembly->{'Component'}\t$assembly->{'Feature'}\t$assembly->{'File_Manifest'}\t$assembly->{'File_Application'}\t$assembly->{'Attributes'}\n";
1055
1056428µs return $newline;
1057}
1058
1059#########################################################################
1060# Sorting the files collector, if there are files, following
1061# the merge module files.
1062#########################################################################
1063
1064sub sort_files_collector_for_sequence
1065{
1066 my ($filesref) = @_;
1067
1068 my @sortarray = ();
1069 my %helphash = ();
1070
1071 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
1072 {
1073 my $onefile = ${$filesref}[$i];
1074 if ( ! exists($onefile->{'sequencenumber'}) ) { installer::exiter::exit_program("ERROR: Could not find sequencenumber for file: $onefile->{'uniquename'} !", "sort_files_collector_for_sequence"); }
1075 my $sequence = $onefile->{'sequencenumber'};
1076 $helphash{$sequence} = $onefile;
1077 }
1078
1079 foreach my $seq ( sort { $a <=> $b } keys %helphash ) { push(@sortarray, $helphash{$seq}); }
1080
1081 return \@sortarray;
1082}
1083
1084#########################################################################
1085# In the file table "Sequence" and "Attributes" have to be changed.
1086#########################################################################
1087
1088sub change_file_table
1089
# spent 12.1s (418ms+11.7) within installer::windows::mergemodule::change_file_table which was called 5 times, avg 2.42s/call: # 5 times (418ms+11.7s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 463, avg 2.42s/call
{
1090516µs my ($mergemodulehash, $workdir, $allupdatesequenceshashref, $includepatharrayref, $filesref, $mergemodulegid) = @_;
1091
109254µs my $infoline = "Changing content of table \"File\"\n";
109357µs push( @installer::globals::logfileinfo, $infoline);
1094
109555µs my $idtfilename = "File.idt";
10965518µs5485µs if ( ! -f $idtfilename ) { installer::exiter::exit_program("ERROR: Could not find file \"$idtfilename\" in \"$workdir\" !", "change_file_table"); }
# spent 485µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 97µs/call
1097
1098524µs5355ms my $filecontent = installer::files::read_file($idtfilename);
# spent 355ms making 5 calls to installer::files::read_file, avg 71.1ms/call
1099
1100 # If File.idt needed to be removed before the msm database was merged into the msi database,
1101 # now it is time to add the content into File.idt
1102520µs if ( $mergemodulehash->{'removefiletable'} )
1103 {
1104 for ( my $i = 0; $i <= $#{$mergemodulehash->{'fileidtcontent'}}; $i++ )
1105 {
1106 push(@{$filecontent}, ${$mergemodulehash->{'fileidtcontent'}}[$i]);
1107 }
1108 }
1109
1110 # Unpacking the MergeModule.CABinet (only once)
1111 # Unpacking into temp directory. Warning: expand.exe has problems with very long unpack directories.
1112
1113549µs57.33ms my $unpackdir = installer::systemactions::create_directories("cab", "");
# spent 7.33ms making 5 calls to installer::systemactions::create_directories, avg 1.47ms/call
1114510µs push(@installer::globals::removedirs, $unpackdir);
1115514µs $unpackdir = $unpackdir . $installer::globals::separator . $mergemodulegid;
1116
1117512µs my %newfileshash = ();
1118513µs if (( $installer::globals::fix_number_of_cab_files ) && ( ! $installer::globals::mergefiles_added_into_collector ))
1119 {
112051.02ms105.62ms if ( ! -d $unpackdir ) { installer::systemactions::create_directory($unpackdir); }
# spent 4.66ms making 5 calls to installer::systemactions::create_directory, avg 933µs/call # spent 961µs making 5 calls to installer::windows::mergemodule::CORE:ftdir, avg 192µs/call
1121
1122 # changing directory
1123538µs584µs my $from = cwd();
# spent 84µs making 5 calls to Cwd::__ANON__[Cwd.pm:406], avg 17µs/call
1124514µs my $to = $mergemodulehash->{'workdir'};
1125576µs539µs if ( $^O =~ /cygwin/i ) {
# spent 39µs making 5 calls to installer::windows::mergemodule::CORE:match, avg 8µs/call
112652.05s52.05s $to = qx(cygpath -u "$to");
# spent 2.05s making 5 calls to installer::windows::mergemodule::CORE:backtick, avg 411ms/call
1127527µs chomp $to;
1128 }
1129
113051.15ms51.09ms chdir($to) || die "Could not chdir to \"$to\"\n";
# spent 1.09ms making 5 calls to installer::windows::mergemodule::CORE:chdir, avg 219µs/call
1131
1132 # Unpack the cab file, so that in can be included into the last office cabinet file.
1133 # Not using cabarc.exe from cabsdk for unpacking cabinet files, but "expand.exe" that
1134 # should be available on every Windows system.
1135
1136546µs $infoline = "Unpacking cabinet file: $mergemodulehash->{'cabinetfile'}\n";
1137536µs push( @installer::globals::logfileinfo, $infoline);
1138
1139 # Avoid the Cygwin expand command
114058µs my $expandfile = "expand.exe"; # Has to be in the path
11415130µs580µs if ( $^O =~ /cygwin/i ) {
# spent 80µs making 5 calls to installer::windows::mergemodule::CORE:match, avg 16µs/call
114252.05s52.05s $expandfile = qx(cygpath -u "$ENV{WINDIR}"/System32/expand.exe);
# spent 2.05s making 5 calls to installer::windows::mergemodule::CORE:backtick, avg 410ms/call
1143530µs chomp $expandfile;
1144 }
1145
114659µs my $cabfilename = "MergeModule.CABinet";
1147
114855µs my $systemcall = "";
11495146µs588µs if ( $^O =~ /cygwin/i ) {
# spent 88µs making 5 calls to installer::windows::mergemodule::CORE:match, avg 18µs/call
115052.10s52.10s my $localunpackdir = qx(cygpath -m "$unpackdir");
# spent 2.10s making 5 calls to installer::windows::mergemodule::CORE:backtick, avg 420ms/call
1151524µs chomp $localunpackdir;
1152554µs $systemcall = $expandfile . " " . $cabfilename . " -F:\\\* " . $localunpackdir;
1153 }
1154 else
1155 {
1156 $systemcall = $expandfile . " " . $cabfilename . " -F:\* " . $unpackdir . " 2\>\&1";
1157 }
1158
115952.59s52.59s my $returnvalue = system($systemcall);
# spent 2.59s making 5 calls to installer::windows::mergemodule::CORE:system, avg 519ms/call
1160
1161535µs $infoline = "Systemcall: $systemcall\n";
1162549µs push( @installer::globals::logfileinfo, $infoline);
1163
1164526µs if ($returnvalue)
1165 {
1166 $infoline = "ERROR: Could not execute $systemcall !\n";
1167 push( @installer::globals::logfileinfo, $infoline);
1168 installer::exiter::exit_program("ERROR: Could not extract cabinet file: $mergemodulehash->{'cabinetfile'} !", "change_file_table");
1169 }
1170 else
1171 {
1172510µs $infoline = "Success: Executed $systemcall successfully!\n";
1173523µs push( @installer::globals::logfileinfo, $infoline);
1174 }
1175
117651.54ms51.44ms chdir($from);
# spent 1.44ms making 5 calls to installer::windows::mergemodule::CORE:chdir, avg 289µs/call
1177 }
1178
1179 # For performance reasons creating a hash with file names and rows
1180 # The content of File.idt is changed after every merge -> content cannot be saved in global hash
11815376ms52.38s $merge_filetablehashref = analyze_filetable_file($filecontent, $idtfilename);
# spent 2.38s making 5 calls to installer::windows::mergemodule::analyze_filetable_file, avg 477ms/call
1182
1183521µs my $attributes = "16384"; # Always
1184
118554µs my $filename;
1186595µs foreach $filename (keys %{$mergemodulehash->{'mergefilesequence'}} )
1187 {
11883392µs my $mergefilesequence = $mergemodulehash->{'mergefilesequence'}->{$filename};
1189
11903366µs if ( ! exists($merge_filetablehashref->{$filename}) ) { installer::exiter::exit_program("ERROR: Could not find file \"$filename\" in \"$idtfilename\" !", "change_file_table"); }
11913332µs my $filehash = $merge_filetablehashref->{$filename};
11923345µs my $linenumber = $filehash->{'linenumber'};
1193
1194 # <- this line has to be changed concerning "Sequence" and "Attributes"
11953346µs $filehash->{'Attributes'} = $attributes;
1196
1197 # If this is an update process, the sequence numbers have to be reused.
11983342µs if ( $installer::globals::updatedatabase )
1199 {
1200 if ( ! exists($allupdatesequenceshashref->{$filehash->{'File'}}) ) { installer::exiter::exit_program("ERROR: Sequence not defined for file \"$filehash->{'File'}\" !", "change_file_table"); }
1201 $filehash->{'Sequence'} = $allupdatesequenceshashref->{$filehash->{'File'}};
1202 # Saving all mergemodule sequence numbers. This is important for creating ddf files
1203 $installer::globals::allmergemodulefilesequences{$filehash->{'Sequence'}} = 1;
1204 }
1205 else
1206 {
1207 # Important saved data: $installer::globals::lastsequence_before_merge.
1208 # This mechanism keeps the correct order inside the new cabinet file.
120933107µs $filehash->{'Sequence'} = $filehash->{'Sequence'} + $installer::globals::lastsequence_before_merge;
1210 }
1211
12123370µs my $oldline = ${$filecontent}[$linenumber];
121333214µs33477µs my $newline = get_new_line_for_file_table($filehash);
# spent 477µs making 33 calls to installer::windows::mergemodule::get_new_line_for_file_table, avg 14µs/call
12143377µs ${$filecontent}[$linenumber] = $newline;
1215
12163319µs $infoline = "Merge, replacing line:\n";
12173343µs push( @installer::globals::logfileinfo, $infoline);
12183341µs $infoline = "Old: $oldline\n";
12193336µs push( @installer::globals::logfileinfo, $infoline);
12203331µs $infoline = "New: $newline\n";
12213342µs push( @installer::globals::logfileinfo, $infoline);
1222
1223 # Adding files to the files collector (but only once)
122433115µs if (( $installer::globals::fix_number_of_cab_files ) && ( ! $installer::globals::mergefiles_added_into_collector ))
1225 {
1226 # If the number of cabinet files is kept constant,
1227 # all files from the mergemodule cabinet files will
1228 # be integrated into the last office cabinet file
1229 # (installer::globals::lastcabfilename).
1230 # Therefore the files must now be added to the filescollector,
1231 # so that they will be integrated into the ddf files.
1232
1233 # Problem with very long filenames -> copying to shorter filenames
12343339µs my $newfilename = "f" . $filehash->{'Sequence'};
12353359µs my $completesource = $unpackdir . $installer::globals::separator . $filehash->{'File'};
12363329µs my $completedest = $unpackdir . $installer::globals::separator . $newfilename;
123733111µs3388.9ms installer::systemactions::copy_one_file($completesource, $completedest);
# spent 88.9ms making 33 calls to installer::systemactions::copy_one_file, avg 2.69ms/call
1238
12393335µs my $locallastcabfilename = $installer::globals::lastcabfilename;
124066730µs66413µs if ( $locallastcabfilename =~ /^\s*\#/ ) { $locallastcabfilename =~ s/^\s*\#//; } # removing beginning hashes
# spent 303µs making 33 calls to installer::windows::mergemodule::CORE:match, avg 9µs/call # spent 110µs making 33 calls to installer::windows::mergemodule::CORE:subst, avg 3µs/call
1241
1242 # Create new file hash for file collector
12433361µs my %newfile = ();
124433137µs $newfile{'sequencenumber'} = $filehash->{'Sequence'};
12453351µs $newfile{'assignedsequencenumber'} = $filehash->{'Sequence'};
12463349µs $newfile{'cabinet'} = $locallastcabfilename;
12473355µs $newfile{'sourcepath'} = $completedest;
12483370µs $newfile{'componentname'} = $filehash->{'Component'};
12493360µs $newfile{'uniquename'} = $filehash->{'File'};
12503356µs $newfile{'Name'} = $filehash->{'File'};
1251
1252 # Saving in globals sequence hash
125333108µs $installer::globals::uniquefilenamesequence{$filehash->{'File'}} = $filehash->{'Sequence'};
1254
1255333.07ms332.88ms if ( ! -f $newfile{'sourcepath'} ) { installer::exiter::exit_program("ERROR: File \"$newfile{'sourcepath'}\" must exist!", "change_file_table"); }
# spent 2.88ms making 33 calls to installer::windows::mergemodule::CORE:ftfile, avg 87µs/call
1256
1257 # Collecting all new files. Attention: This files must be included into files collector in correct order!
125833167µs $newfileshash{$filehash->{'Sequence'}} = \%newfile;
1259 # push(@{$filesref}, \%newfile); -> this is not the correct order
1260 }
1261 }
1262
1263 # Now the files can be added to the files collector
1264 # In the case of an update process, there can be new files, that have to be added after the merge module files.
1265 # Warning: In multilingual installation sets, the files only have to be added once to the files collector!
1266
126757µs if ( ! $installer::globals::mergefiles_added_into_collector )
1268 {
126938235µs5107µs foreach my $localsequence ( sort { $a <=> $b } keys %newfileshash ) { push(@{$filesref}, $newfileshash{$localsequence}); }
# spent 107µs making 5 calls to installer::windows::mergemodule::CORE:sort, avg 21µs/call
127054µs if ( $installer::globals::newfilesexist ) { $filesref = sort_files_collector_for_sequence($filesref); }
1271 # $installer::globals::mergefiles_added_into_collector = 1; -> Not yet. Only if all mergemodules are merged for one language.
1272 }
1273
1274 # Saving the idt file (for every language)
1275534µs540.8ms installer::files::save_file($idtfilename, $filecontent);
# spent 40.8ms making 5 calls to installer::files::save_file, avg 8.16ms/call
1276
1277536.8ms return $filesref;
1278}
1279
1280#########################################################################
1281# Reading the file "Director.idt". The Directory, that is defined in scp
1282# has to be defined in this table.
1283#########################################################################
1284
1285sub collect_directories
1286{
1287 my $idtfilename = "Director.idt";
1288 my $filecontent = installer::files::read_file($idtfilename);
1289
1290 for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
1291 {
1292 if ( $i <= 2 ) { next; } # ignoring first three lines
1293 if ( ${$filecontent}[$i] =~ /^\s*$/ ) { next; } # ignoring empty lines
1294 # Format: Directory Directory_Parent DefaultDir
1295 if ( ${$filecontent}[$i] =~ /^\s*(.+?)\t(.*?)\t(.*?)\s*$/ )
1296 {
1297 $installer::globals::merge_alldirectory_hash{$1} = 1;
1298 }
1299 else
1300 {
1301 my $linecount = $i + 1;
1302 installer::exiter::exit_program("ERROR: Unknown line format in table \"$idtfilename\" (line $linecount) !", "collect_directories");
1303 }
1304 }
1305}
1306
1307#########################################################################
1308# Reading the file "Feature.idt". The Feature, that is defined in scp
1309# has to be defined in this table.
1310#########################################################################
1311
1312sub collect_feature
1313
# spent 31.4ms (16.9+14.5) within installer::windows::mergemodule::collect_feature which was called: # once (16.9ms+14.5ms) by installer::windows::mergemodule::change_featurecomponent_table at line 1356
{
131411µs my $idtfilename = "Feature.idt";
13151179µs1170µs if ( ! -f $idtfilename ) { installer::exiter::exit_program("ERROR: Could not find file \"$idtfilename\" in \"$workdir\" !", "collect_feature"); }
# spent 170µs making 1 call to installer::windows::mergemodule::CORE:ftfile
131615µs16.93ms my $filecontent = installer::files::read_file($idtfilename);
# spent 6.93ms making 1 call to installer::files::read_file
1317
131812.58ms for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
1319 {
13201559555µs if ( $i <= 2 ) { next; } # ignoring first three lines
132115537.13ms15531.77ms if ( ${$filecontent}[$i] =~ /^\s*$/ ) { next; } # ignoring empty lines
# spent 1.77ms making 1553 calls to installer::windows::mergemodule::CORE:match, avg 1µs/call
1322 # Format: Feature Feature_Parent Title Description Display Level Directory_ Attributes
1323155314.0ms15535.63ms if ( ${$filecontent}[$i] =~ /^\s*(.+?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ )
# spent 5.63ms making 1553 calls to installer::windows::mergemodule::CORE:match, avg 4µs/call
1324 {
1325 $installer::globals::merge_allfeature_hash{$1} = 1;
1326 }
1327 else
1328 {
1329 my $linecount = $i + 1;
1330 installer::exiter::exit_program("ERROR: Unknown line format in table \"$idtfilename\" (line $linecount) !", "collect_feature");
1331 }
1332 }
1333}
1334
1335#########################################################################
1336# In the featurecomponent table, the new connections have to be added.
1337#########################################################################
1338
1339sub change_featurecomponent_table
1340
# spent 264ms (19.6+244) within installer::windows::mergemodule::change_featurecomponent_table which was called 5 times, avg 52.7ms/call: # 5 times (19.6ms+244ms) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 465, avg 52.7ms/call
{
1341510µs my ($mergemodulehash, $workdir) = @_;
1342
134355µs my $infoline = "Changing content of table \"FeatureComponents\"\n";
134456µs push( @installer::globals::logfileinfo, $infoline);
1345
134654µs my $idtfilename = "FeatureC.idt";
134751.41ms51.37ms if ( ! -f $idtfilename ) { installer::exiter::exit_program("ERROR: Could not find file \"$idtfilename\" in \"$workdir\" !", "change_featurecomponent_table"); }
# spent 1.37ms making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 274µs/call
1348
1349532µs5191ms my $filecontent = installer::files::read_file($idtfilename);
# spent 191ms making 5 calls to installer::files::read_file, avg 38.3ms/call
1350
1351 # Simply adding for each new component one line. The Feature has to be defined in scp project.
1352523µs my $feature = $mergemodulehash->{'feature'};
1353
135456µs if ( ! $installer::globals::mergefeaturecollected )
1355 {
135617µs131.4ms collect_feature(); # putting content into hash %installer::globals::merge_allfeature_hash
# spent 31.4ms making 1 call to installer::windows::mergemodule::collect_feature
135711µs $installer::globals::mergefeaturecollected = 1;
1358 }
1359
1360511µs if ( ! exists($installer::globals::merge_allfeature_hash{$feature}) )
1361 {
1362 installer::exiter::exit_program("ERROR: Unknown feature defined in scp: \"$feature\" . Not defined in table \"Feature\" !", "change_featurecomponent_table");
1363 }
1364
136552µs my $component;
1366553µs foreach $component ( keys %{$mergemodulehash->{'componentnames'}} )
1367 {
13681322µs my $line = "$feature\t$component\n";
13691317µs push(@{$filecontent}, $line);
13701315µs $infoline = "Adding line: $line\n";
13711329µs push( @installer::globals::logfileinfo, $infoline);
1372 }
1373
1374 # saving file
1375519.3ms520.0ms installer::files::save_file($idtfilename, $filecontent);
# spent 20.0ms making 5 calls to installer::files::save_file, avg 4.00ms/call
1376}
1377
1378###############################################################################
1379# In the components table, the conditions of merge modules should be updated
1380###############################################################################
1381
1382sub change_component_table
1383
# spent 3.87s (1.14+2.73) within installer::windows::mergemodule::change_component_table which was called 5 times, avg 774ms/call: # 5 times (1.14s+2.73s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 477, avg 774ms/call
{
138459µs my ($mergemodulehash, $workdir) = @_;
1385
138655µs my $infoline = "Changing content of table \"Component\"\n";
138755µs push( @installer::globals::logfileinfo, $infoline);
1388
138955µs my $idtfilename = "Componen.idt";
13905789µs5753µs if ( ! -f $idtfilename ) { installer::exiter::exit_program("ERROR: Could not find file \"$idtfilename\" in \"$workdir\" !", "change_component_table"); }
# spent 753µs making 5 calls to installer::windows::mergemodule::CORE:ftfile, avg 151µs/call
1391
1392526µs5201ms my $filecontent = installer::files::read_file($idtfilename);
# spent 201ms making 5 calls to installer::files::read_file, avg 40.3ms/call
1393
1394586.7ms for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
1395 {
13964535215.8ms my $component;
13974535291.6ms foreach $component ( keys %{$mergemodulehash->{'componentnames'}} )
1398 {
13991179223.42s2358442.50s if ( ${$filecontent}[$i] =~ /^\s*$component/)
# spent 2.40s making 117922 calls to installer::windows::mergemodule::CORE:regcomp, avg 20µs/call # spent 101ms making 117922 calls to installer::windows::mergemodule::CORE:match, avg 860ns/call
1400 {
140113294µs13214µs if ( ${$filecontent}[$i] =~ /^\s*(.+?)\t(.*?)\t(.+?)\t(.+?)\t(.*?)\t(.*?)\s*$/ )
# spent 214µs making 13 calls to installer::windows::mergemodule::CORE:match, avg 16µs/call
1402 {
14031389µs $infoline = "Adding condition ($mergemodulehash->{'componentcondition'}) from scp2 to component $1\n";
14041331µs push( @installer::globals::logfileinfo, $infoline);
14051327µs if ($5)
1406 {
14071136µs $infoline = "Old condition: $5\nNew condition: ($5) AND ($mergemodulehash->{'componentcondition'})\n";
14081115µs push( @installer::globals::logfileinfo, $infoline);
140911101µs ${$filecontent}[$i] = "$1\t$2\t$3\t$4\t($5) AND ($mergemodulehash->{'componentcondition'})\t$6\n";
1410 }
1411 else
1412 {
141324µs $infoline = "Old condition: <none>\nNew condition: $mergemodulehash->{'componentcondition'}\n";
141422µs push( @installer::globals::logfileinfo, $infoline);
1415216µs ${$filecontent}[$i] = "$1\t$2\t$3\t$4\t$mergemodulehash->{'componentcondition'}\t$6\n";
1416 }
1417 }
1418 }
1419 }
1420 }
1421
1422 # saving file
1423522.4ms528.7ms installer::files::save_file($idtfilename, $filecontent);
# spent 28.7ms making 5 calls to installer::files::save_file, avg 5.73ms/call
1424}
1425
1426#########################################################################
1427# In the directory table, the directory parent has to be changed,
1428# if it is not TARGETDIR.
1429#########################################################################
1430
1431sub change_directory_table
1432
# spent 54µs within installer::windows::mergemodule::change_directory_table which was called 5 times, avg 11µs/call: # 5 times (54µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 467, avg 11µs/call
{
1433510µs my ($mergemodulehash, $workdir) = @_;
1434
1435 # directory for MergeModule has to be defined in scp project
1436516µs my $scpdirectory = $mergemodulehash->{'rootdir'};
1437
1438534µs if ( $scpdirectory ne "TARGETDIR" ) # TARGETDIR works fine, when using msidb.exe
1439 {
1440 my $infoline = "Changing content of table \"Directory\"\n";
1441 push( @installer::globals::logfileinfo, $infoline);
1442
1443 my $idtfilename = "Director.idt";
1444 if ( ! -f $idtfilename ) { installer::exiter::exit_program("ERROR: Could not find file \"$idtfilename\" in \"$workdir\" !", "change_directory_table"); }
1445
1446 my $filecontent = installer::files::read_file($idtfilename);
1447
1448 if ( ! $installer::globals::mergedirectoriescollected )
1449 {
1450 collect_directories(); # putting content into %installer::globals::merge_alldirectory_hash, only first column!
1451 $installer::globals::mergedirectoriescollected = 1;
1452 }
1453
1454 if ( ! exists($installer::globals::merge_alldirectory_hash{$scpdirectory}) )
1455 {
1456 installer::exiter::exit_program("ERROR: Unknown directory defined in scp: \"$scpdirectory\" . Not defined in table \"Directory\" !", "change_directory_table");
1457 }
1458
1459 # If the definition in scp is okay, now the complete content of "Director.idt" can be analyzed
1460 my $merge_directorytablehashref = analyze_directorytable_file($filecontent, $idtfilename);
1461
1462 my $directory;
1463 foreach $directory (keys %{$mergemodulehash->{'mergedirectories'}} )
1464 {
1465 if ( ! exists($merge_directorytablehashref->{$directory}) ) { installer::exiter::exit_program("ERROR: Could not find directory \"$directory\" in \"$idtfilename\" !", "change_directory_table"); }
1466 my $dirhash = $merge_directorytablehashref->{$directory};
1467 my $linenumber = $dirhash->{'linenumber'};
1468
1469 # <- this line has to be changed concerning "Directory_Parent",
1470 # if the current value is "TARGETDIR", which is the default value from msidb.exe
1471
1472 if ( $dirhash->{'Directory_Parent'} eq "TARGETDIR" )
1473 {
1474 $dirhash->{'Directory_Parent'} = $scpdirectory;
1475
1476 my $oldline = ${$filecontent}[$linenumber];
1477 my $newline = get_new_line_for_directory_table($dirhash);
1478 ${$filecontent}[$linenumber] = $newline;
1479
1480 $infoline = "Merge, replacing line:\n";
1481 push( @installer::globals::logfileinfo, $infoline);
1482 $infoline = "Old: $oldline\n";
1483 push( @installer::globals::logfileinfo, $infoline);
1484 $infoline = "New: $newline\n";
1485 push( @installer::globals::logfileinfo, $infoline);
1486 }
1487 }
1488
1489 # saving file
1490 installer::files::save_file($idtfilename, $filecontent);
1491 }
1492}
1493
1494#########################################################################
1495# In the msiassembly table, the feature has to be changed.
1496#########################################################################
1497
1498sub change_msiassembly_table
1499
# spent 5.80ms (449µs+5.35) within installer::windows::mergemodule::change_msiassembly_table which was called 4 times, avg 1.45ms/call: # 4 times (449µs+5.35ms) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 471, avg 1.45ms/call
{
150047µs my ($mergemodulehash, $workdir) = @_;
1501
150243µs my $infoline = "Changing content of table \"MsiAssembly\"\n";
150344µs push( @installer::globals::logfileinfo, $infoline);
1504
150543µs my $idtfilename = "MsiAssem.idt";
15064953µs4921µs if ( ! -f $idtfilename ) { installer::exiter::exit_program("ERROR: Could not find file \"$idtfilename\" in \"$workdir\" !", "change_msiassembly_table"); }
# spent 921µs making 4 calls to installer::windows::mergemodule::CORE:ftfile, avg 230µs/call
1507
1508422µs41.45ms my $filecontent = installer::files::read_file($idtfilename);
# spent 1.45ms making 4 calls to installer::files::read_file, avg 361µs/call
1509
1510 # feature has to be defined in scp project
151149µs my $feature = $mergemodulehash->{'feature'};
1512
151342µs if ( ! $installer::globals::mergefeaturecollected )
1514 {
1515 collect_feature(); # putting content into hash %installer::globals::merge_allfeature_hash
1516 $installer::globals::mergefeaturecollected = 1;
1517 }
1518
151947µs if ( ! exists($installer::globals::merge_allfeature_hash{$feature}) )
1520 {
1521 installer::exiter::exit_program("ERROR: Unknown feature defined in scp: \"$feature\" . Not defined in table \"Feature\" !", "change_msiassembly_table");
1522 }
1523
1524419µs41.46ms my $merge_msiassemblytablehashref = analyze_msiassemblytable_file($filecontent, $idtfilename);
# spent 1.46ms making 4 calls to installer::windows::mergemodule::analyze_msiassemblytable_file, avg 365µs/call
1525
152642µs my $component;
1527430µs foreach $component (keys %{$mergemodulehash->{'mergeassemblies'}} )
1528 {
152944µs if ( ! exists($merge_msiassemblytablehashref->{$component}) ) { installer::exiter::exit_program("ERROR: Could not find component \"$component\" in \"$idtfilename\" !", "change_msiassembly_table"); }
153043µs my $assemblyhash = $merge_msiassemblytablehashref->{$component};
153143µs my $linenumber = $assemblyhash->{'linenumber'};
1532
1533 # <- this line has to be changed concerning "Feature"
153444µs $assemblyhash->{'Feature'} = $feature;
1535
153645µs my $oldline = ${$filecontent}[$linenumber];
1537420µs444µs my $newline = get_new_line_for_msiassembly_table($assemblyhash);
# spent 44µs making 4 calls to installer::windows::mergemodule::get_new_line_for_msiassembly_table, avg 11µs/call
153845µs ${$filecontent}[$linenumber] = $newline;
1539
154042µs $infoline = "Merge, replacing line:\n";
154146µs push( @installer::globals::logfileinfo, $infoline);
154246µs $infoline = "Old: $oldline\n";
154344µs push( @installer::globals::logfileinfo, $infoline);
154446µs $infoline = "New: $newline\n";
1545412µs push( @installer::globals::logfileinfo, $infoline);
1546 }
1547
1548 # saving file
15494204µs41.48ms installer::files::save_file($idtfilename, $filecontent);
# spent 1.48ms making 4 calls to installer::files::save_file, avg 370µs/call
1550}
1551
1552#########################################################################
1553# Creating file content hash
1554#########################################################################
1555
1556sub make_executeidtcontent_hash
1557
# spent 18.2ms (14.6+3.65) within installer::windows::mergemodule::make_executeidtcontent_hash which was called 20 times, avg 912µs/call: # 20 times (14.6ms+3.65ms) by installer::windows::mergemodule::change_executesequence_table at line 1640, avg 912µs/call
{
15582029µs my ($filecontent, $idtfilename) = @_;
1559
15602023µs my %newhash = ();
1561
1562201.24ms for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
1563 {
1564943382µs if ( $i <= 2 ) { next; } # ignoring first three lines
15658234.15ms8231.06ms if ( ${$filecontent}[$i] =~ /^\s*$/ ) { next; } # ignoring empty lines
# spent 1.06ms making 823 calls to installer::windows::mergemodule::CORE:match, avg 1µs/call
1566 # Format for all sequence tables: Action Condition Sequence
15678236.02ms8232.59ms if ( ${$filecontent}[$i] =~ /^\s*(.+?)\t(.*?)\t(.*?)\s*$/ )
# spent 2.59ms making 823 calls to installer::windows::mergemodule::CORE:match, avg 3µs/call
1568 {
1569823517µs my %onehash = ();
15708231.81ms $onehash{'Action'} = $1;
15718231.11ms $onehash{'Condition'} = $2;
15728231.11ms $onehash{'Sequence'} = $3;
15738231.77ms $newhash{$onehash{'Action'}} = \%onehash;
1574 }
1575 else
1576 {
1577 my $linecount = $i + 1;
1578 installer::exiter::exit_program("ERROR: Unknown line format in table \"$idtfilename\" (line $linecount) !", "make_executeidtcontent_hash");
1579 }
1580 }
1581
158220115µs return \%newhash;
1583}
1584
1585#########################################################################
1586# Creating file content hash
1587#########################################################################
1588
1589sub make_moduleexecuteidtcontent_hash
1590
# spent 4.52ms (3.60+919µs) within installer::windows::mergemodule::make_moduleexecuteidtcontent_hash which was called 20 times, avg 226µs/call: # 20 times (3.60ms+919µs) by installer::windows::mergemodule::change_executesequence_table at line 1641, avg 226µs/call
{
15912023µs my ($filecontent, $idtfilename) = @_;
1592
15932014µs my %newhash = ();
1594
159520311µs for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
1596 {
1597291125µs if ( $i <= 2 ) { next; } # ignoring first three lines
1598171902µs171239µs if ( ${$filecontent}[$i] =~ /^\s*$/ ) { next; } # ignoring empty lines
# spent 239µs making 171 calls to installer::windows::mergemodule::CORE:match, avg 1µs/call
1599 # Format for all module sequence tables: Action Sequence BaseAction After Condition
16001711.40ms171680µs if ( ${$filecontent}[$i] =~ /^\s*(.+?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ )
# spent 680µs making 171 calls to installer::windows::mergemodule::CORE:match, avg 4µs/call
1601 {
1602171114µs my %onehash = ();
1603171370µs $onehash{'Action'} = $1;
1604171231µs $onehash{'Sequence'} = $2;
1605171218µs $onehash{'BaseAction'} = $3;
1606171222µs $onehash{'After'} = $4;
1607171221µs $onehash{'Condition'} = $5;
1608171307µs $newhash{$onehash{'Action'}} = \%onehash;
1609 }
1610 else
1611 {
1612 my $linecount = $i + 1;
1613 installer::exiter::exit_program("ERROR: Unknown line format in table \"$idtfilename\" (line $linecount) !", "make_executeidtcontent_hash");
1614 }
1615 }
1616
161720109µs return \%newhash;
1618}
1619
1620#########################################################################
1621# ExecuteSequence tables need to be merged with
1622# ModuleExecuteSequence tables created by msidb.exe.
1623#########################################################################
1624
1625sub change_executesequence_table
1626
# spent 51.8ms (4.48+47.3) within installer::windows::mergemodule::change_executesequence_table which was called 20 times, avg 2.59ms/call: # 5 times (2.08ms+20.8ms) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 539, avg 4.57ms/call # 5 times (1.27ms+11.7ms) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 541, avg 2.60ms/call # 5 times (635µs+7.56ms) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 547, avg 1.64ms/call # 5 times (497µs+7.22ms) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 553, avg 1.54ms/call
{
16272038µs my ($mergemodulehash, $workdir, $idtfilename, $moduleidtfilename) = @_;
1628
16292021µs my $infoline = "Changing content of table \"$idtfilename\"\n";
16302020µs push( @installer::globals::logfileinfo, $infoline);
1631
1632202.25ms202.14ms if ( ! -f $idtfilename ) { installer::exiter::exit_program("ERROR: Could not find file \"$idtfilename\" in \"$workdir\" !", "change_executesequence_table"); }
# spent 2.14ms making 20 calls to installer::windows::mergemodule::CORE:ftfile, avg 107µs/call
1633201.82ms201.72ms if ( ! -f $moduleidtfilename ) { installer::exiter::exit_program("ERROR: Could not find file \"$moduleidtfilename\" in \"$workdir\" !", "change_executesequence_table"); }
# spent 1.72ms making 20 calls to installer::windows::mergemodule::CORE:ftfile, avg 86µs/call
1634
1635 # Reading file content
16362092µs208.45ms my $idtfilecontent = installer::files::read_file($idtfilename);
# spent 8.45ms making 20 calls to installer::files::read_file, avg 422µs/call
16372071µs205.44ms my $moduleidtfilecontent = installer::files::read_file($moduleidtfilename);
# spent 5.44ms making 20 calls to installer::files::read_file, avg 272µs/call
1638
1639 # Converting to hash
16402078µs2018.2ms my $idtcontenthash = make_executeidtcontent_hash($idtfilecontent, $idtfilename);
# spent 18.2ms making 20 calls to installer::windows::mergemodule::make_executeidtcontent_hash, avg 912µs/call
16412068µs204.52ms my $moduleidtcontenthash = make_moduleexecuteidtcontent_hash($moduleidtfilecontent, $moduleidtfilename);
# spent 4.52ms making 20 calls to installer::windows::mergemodule::make_moduleexecuteidtcontent_hash, avg 226µs/call
1642
1643 # Merging
164420215µs foreach my $action ( keys %{$moduleidtcontenthash} )
1645 {
1646270138µs if ( exists($idtcontenthash->{$action}) ) { next; } # Action already exists, can be ignored
1647
1648124275µs5645µs if (( $idtfilename eq "InstallU.idt" ) && ( ! ( $action =~ /^\s*WindowsFolder\./ ))) { next; } # Only "WindowsFolder.*" CustomActions for UI Sequence table
# spent 45µs making 56 calls to installer::windows::mergemodule::CORE:match, avg 804ns/call
1649
16502016µs my $actionhashref = $moduleidtcontenthash->{$action};
16512037µs if ( $actionhashref->{'Sequence'} ne "" )
1652 {
1653 # Format for all sequence tables: Action Condition Sequence
1654 my $newline = $actionhashref->{'Action'} . "\t" . $actionhashref->{'Condition'} . "\t" . $actionhashref->{'Sequence'} . "\n";
1655 # Adding to table
1656 push(@{$idtfilecontent}, $newline);
1657 # Also adding to hash
1658 my %idttablehash = ();
1659 $idttablehash{'Action'} = $actionhashref->{'Action'};
1660 $idttablehash{'Condition'} = $actionhashref->{'Condition'};
1661 $idttablehash{'Sequence'} = $actionhashref->{'Sequence'};
1662 $idtcontenthash->{$action} = \%idttablehash;
1663
1664 }
1665 else # no sequence defined, using syntax "BaseAction" and "After"
1666 {
16672021µs my $baseactionname = $actionhashref->{'BaseAction'};
1668 # If this baseactionname is not defined in execute idt file, it is not possible to merge
16692015µs if ( ! exists($idtcontenthash->{$baseactionname}) ) { installer::exiter::exit_program("ERROR: Merge problem: Could not find action \"$baseactionname\" in file \"$idtfilename\" !", "change_executesequence_table"); }
1670
16712015µs my $baseaction = $idtcontenthash->{$baseactionname};
16722017µs my $sequencenumber = $baseaction->{'Sequence'};
16732034µs if ( $actionhashref->{'After'} == 1 ) { $sequencenumber = $sequencenumber + 1; }
16741919µs else { $sequencenumber = $sequencenumber - 1; }
1675
1676 # Format for all sequence tables: Action Condition Sequence
16772046µs my $newline = $actionhashref->{'Action'} . "\t" . $actionhashref->{'Condition'} . "\t" . $sequencenumber . "\n";
1678 # Adding to table
16792026µs push(@{$idtfilecontent}, $newline);
1680 # Also adding to hash
16812016µs my %idttablehash = ();
16822038µs $idttablehash{'Action'} = $actionhashref->{'Action'};
16832026µs $idttablehash{'Condition'} = $actionhashref->{'Condition'};
16842022µs $idttablehash{'Sequence'} = $sequencenumber;
16852030µs $idtcontenthash->{$action} = \%idttablehash;
1686 }
1687 }
1688
1689 # saving file
1690202.75ms206.73ms installer::files::save_file($idtfilename, $idtfilecontent);
# spent 6.73ms making 20 calls to installer::files::save_file, avg 336µs/call
1691}
1692
1693
169418µs1;
 
# spent 6.20s within installer::windows::mergemodule::CORE:backtick which was called 15 times, avg 413ms/call: # 5 times (2.10s+0s) by installer::windows::mergemodule::change_file_table at line 1150, avg 420ms/call # 5 times (2.05s+0s) by installer::windows::mergemodule::change_file_table at line 1126, avg 411ms/call # 5 times (2.05s+0s) by installer::windows::mergemodule::change_file_table at line 1142, avg 410ms/call
sub installer::windows::mergemodule::CORE:backtick; # opcode
# spent 5.48ms within installer::windows::mergemodule::CORE:chdir which was called 30 times, avg 183µs/call: # 5 times (1.44ms+0s) by installer::windows::mergemodule::change_file_table at line 1176, avg 289µs/call # 5 times (1.09ms+0s) by installer::windows::mergemodule::change_file_table at line 1130, avg 219µs/call # 5 times (1.09ms+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 599, avg 217µs/call # 5 times (637µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 359, avg 127µs/call # 5 times (626µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 107, avg 125µs/call # 5 times (596µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 322, avg 119µs/call
sub installer::windows::mergemodule::CORE:chdir; # opcode
# spent 1.96ms within installer::windows::mergemodule::CORE:ftdir which was called 10 times, avg 196µs/call: # 5 times (1.00ms+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 94, avg 200µs/call # 5 times (961µs+0s) by installer::windows::mergemodule::change_file_table at line 1120, avg 192µs/call
sub installer::windows::mergemodule::CORE:ftdir; # opcode
# spent 35.0ms within installer::windows::mergemodule::CORE:ftfile which was called 268 times, avg 131µs/call: # 33 times (2.88ms+0s) by installer::windows::mergemodule::change_file_table at line 1255, avg 87µs/call # 20 times (2.14ms+0s) by installer::windows::mergemodule::change_executesequence_table at line 1632, avg 107µs/call # 20 times (1.72ms+0s) by installer::windows::mergemodule::change_executesequence_table at line 1633, avg 86µs/call # 5 times (1.37ms+0s) by installer::windows::mergemodule::change_featurecomponent_table at line 1347, avg 274µs/call # 5 times (1.22ms+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 400, avg 244µs/call # 5 times (1.18ms+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 485, avg 236µs/call # 5 times (1.16ms+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 168, avg 232µs/call # 5 times (1.13ms+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 89, avg 225µs/call # 5 times (1.09ms+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 454, avg 219µs/call # 5 times (1.09ms+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 529, avg 219µs/call # 5 times (953µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 110, avg 191µs/call # 5 times (942µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 402, avg 188µs/call # 5 times (923µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 404, avg 185µs/call # 5 times (914µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 102, avg 183µs/call # 5 times (882µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 406, avg 176µs/call # 5 times (753µs+0s) by installer::windows::mergemodule::change_component_table at line 1390, avg 151µs/call # 5 times (696µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 194, avg 139µs/call # 5 times (692µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 401, avg 138µs/call # 5 times (657µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 455, avg 131µs/call # 5 times (625µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 530, avg 125µs/call # 5 times (624µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 486, avg 125µs/call # 5 times (591µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 220, avg 118µs/call # 5 times (556µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 456, avg 111µs/call # 5 times (554µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 489, avg 111µs/call # 5 times (549µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 490, avg 110µs/call # 5 times (547µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 491, avg 109µs/call # 5 times (545µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 487, avg 109µs/call # 5 times (541µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 488, avg 108µs/call # 5 times (535µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 531, avg 107µs/call # 5 times (531µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 408, avg 106µs/call # 5 times (519µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 403, avg 104µs/call # 5 times (516µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 407, avg 103µs/call # 5 times (516µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 405, avg 103µs/call # 5 times (493µs+0s) by installer::windows::mergemodule::change_media_table at line 856, avg 99µs/call # 5 times (492µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 206, avg 98µs/call # 5 times (485µs+0s) by installer::windows::mergemodule::change_file_table at line 1096, avg 97µs/call # 5 times (475µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 544, avg 95µs/call # 5 times (470µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 457, avg 94µs/call # 5 times (469µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 550, avg 94µs/call # 5 times (468µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 536, avg 94µs/call # 5 times (462µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 532, avg 92µs/call # 4 times (921µs+0s) by installer::windows::mergemodule::change_msiassembly_table at line 1506, avg 230µs/call # once (170µs+0s) by installer::windows::mergemodule::collect_feature at line 1315
sub installer::windows::mergemodule::CORE:ftfile; # opcode
# spent 542ms within installer::windows::mergemodule::CORE:match which was called 282524 times, avg 2µs/call: # 117922 times (101ms+0s) by installer::windows::mergemodule::change_component_table at line 1399, avg 860ns/call # 79534 times (315ms+0s) by installer::windows::mergemodule::analyze_filetable_file at line 993, avg 4µs/call # 79534 times (111ms+0s) by installer::windows::mergemodule::analyze_filetable_file at line 992, avg 1µs/call # 1553 times (5.63ms+0s) by installer::windows::mergemodule::collect_feature at line 1323, avg 4µs/call # 1553 times (1.77ms+0s) by installer::windows::mergemodule::collect_feature at line 1321, avg 1µs/call # 823 times (2.59ms+0s) by installer::windows::mergemodule::make_executeidtcontent_hash at line 1567, avg 3µs/call # 823 times (1.06ms+0s) by installer::windows::mergemodule::make_executeidtcontent_hash at line 1565, avg 1µs/call # 171 times (680µs+0s) by installer::windows::mergemodule::make_moduleexecuteidtcontent_hash at line 1600, avg 4µs/call # 171 times (239µs+0s) by installer::windows::mergemodule::make_moduleexecuteidtcontent_hash at line 1598, avg 1µs/call # 56 times (45µs+0s) by installer::windows::mergemodule::change_executesequence_table at line 1648, avg 804ns/call # 50 times (182µs+0s) by installer::windows::mergemodule::analyze_msiassemblytable_file at line 955, avg 4µs/call # 50 times (88µs+0s) by installer::windows::mergemodule::analyze_msiassemblytable_file at line 954, avg 2µs/call # 34 times (73µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 213, avg 2µs/call # 34 times (55µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 212, avg 2µs/call # 33 times (303µs+0s) by installer::windows::mergemodule::change_file_table at line 1240, avg 9µs/call # 33 times (174µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 179, avg 5µs/call # 33 times (121µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 176, avg 4µs/call # 13 times (214µs+0s) by installer::windows::mergemodule::change_component_table at line 1401, avg 16µs/call # 13 times (38µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 201, avg 3µs/call # 13 times (31µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 200, avg 2µs/call # 5 times (586µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 512, avg 117µs/call # 5 times (88µs+0s) by installer::windows::mergemodule::change_file_table at line 1149, avg 18µs/call # 5 times (85µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 138, avg 17µs/call # 5 times (80µs+0s) by installer::windows::mergemodule::change_file_table at line 1141, avg 16µs/call # 5 times (60µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 498, avg 12µs/call # 5 times (39µs+0s) by installer::windows::mergemodule::change_file_table at line 1125, avg 8µs/call # 5 times (30µs+0s) by installer::windows::mergemodule::analyze_media_file at line 627, avg 6µs/call # 5 times (29µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 368, avg 6µs/call # 5 times (27µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 420, avg 5µs/call # 5 times (27µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 562, avg 5µs/call # 5 times (24µs+0s) by installer::windows::mergemodule::analyze_media_file at line 626, avg 5µs/call # 5 times (22µs+0s) by installer::windows::mergemodule::change_media_table at line 873, avg 4µs/call # 5 times (11µs+0s) by installer::windows::mergemodule::change_media_table at line 872, avg 2µs/call # 5 times (4µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 247, avg 760ns/call # 4 times (12µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 228, avg 3µs/call # 4 times (11µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 227, avg 3µs/call
sub installer::windows::mergemodule::CORE:match; # opcode
# spent 2.40s within installer::windows::mergemodule::CORE:regcomp which was called 117927 times, avg 20µs/call: # 117922 times (2.40s+0s) by installer::windows::mergemodule::change_component_table at line 1399, avg 20µs/call # 5 times (244µs+0s) by installer::windows::mergemodule::change_media_table at line 873, avg 49µs/call
sub installer::windows::mergemodule::CORE:regcomp; # opcode
# spent 107µs within installer::windows::mergemodule::CORE:sort which was called 5 times, avg 21µs/call: # 5 times (107µs+0s) by installer::windows::mergemodule::change_file_table at line 1269, avg 21µs/call
sub installer::windows::mergemodule::CORE:sort; # opcode
# spent 1.26ms within installer::windows::mergemodule::CORE:subst which was called 88 times, avg 14µs/call: # 33 times (110µs+0s) by installer::windows::mergemodule::change_file_table at line 1240, avg 3µs/call # 5 times (166µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 516, avg 33µs/call # 5 times (135µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 141, avg 27µs/call # 5 times (127µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 502, avg 25µs/call # 5 times (119µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 372, avg 24µs/call # 5 times (111µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 424, avg 22µs/call # 5 times (101µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 566, avg 20µs/call # 5 times (82µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 373, avg 16µs/call # 5 times (79µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 425, avg 16µs/call # 5 times (79µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 517, avg 16µs/call # 5 times (76µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 503, avg 15µs/call # 5 times (76µs+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 567, avg 15µs/call
sub installer::windows::mergemodule::CORE:subst; # opcode
# spent 86.7s within installer::windows::mergemodule::CORE:system which was called 84 times, avg 1.03s/call: # 49 times (34.9s+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 570, avg 712ms/call # 5 times (34.0s+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 432, avg 6.80s/call # 5 times (3.68s+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 380, avg 737ms/call # 5 times (3.34s+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 524, avg 667ms/call # 5 times (3.30s+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 510, avg 659ms/call # 5 times (2.59s+0s) by installer::windows::mergemodule::change_file_table at line 1159, avg 519ms/call # 5 times (2.46s+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 114, avg 493ms/call # 5 times (2.44s+0s) by installer::windows::mergemodule::merge_mergemodules_into_msi_database at line 149, avg 489ms/call
sub installer::windows::mergemodule::CORE:system; # opcode