Filename | /cygdrive/c/lo/libo-master/instsetoo_native/util/C:/lo/libo-master/solenv/bin/modules/installer/windows/admin.pm |
Statements | Executed 17 statements in 5.31ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 400µs | 455µs | BEGIN@30 | installer::windows::admin::
1 | 1 | 1 | 17µs | 23µs | BEGIN@36 | installer::windows::admin::
1 | 1 | 1 | 15µs | 18µs | BEGIN@37 | installer::windows::admin::
1 | 1 | 1 | 14µs | 16µs | BEGIN@31 | installer::windows::admin::
1 | 1 | 1 | 13µs | 15µs | BEGIN@33 | installer::windows::admin::
1 | 1 | 1 | 13µs | 16µs | BEGIN@35 | installer::windows::admin::
1 | 1 | 1 | 13µs | 15µs | BEGIN@32 | installer::windows::admin::
1 | 1 | 1 | 13µs | 16µs | BEGIN@34 | installer::windows::admin::
0 | 0 | 0 | 0s | 0s | analyze_component_file | installer::windows::admin::
0 | 0 | 0 | 0s | 0s | analyze_directory_file | installer::windows::admin::
0 | 0 | 0 | 0s | 0s | analyze_file_file | installer::windows::admin::
0 | 0 | 0 | 0s | 0s | copy_files_into_directory_structure | installer::windows::admin::
0 | 0 | 0 | 0s | 0s | create_directory_structure | installer::windows::admin::
0 | 0 | 0 | 0s | 0s | create_directory_tree | installer::windows::admin::
0 | 0 | 0 | 0s | 0s | extract_tables_from_pcpfile | installer::windows::admin::
0 | 0 | 0 | 0s | 0s | get_sis_time_string | installer::windows::admin::
0 | 0 | 0 | 0s | 0s | make_admin_install | installer::windows::admin::
0 | 0 | 0 | 0s | 0s | unpack_cabinet_file | installer::windows::admin::
0 | 0 | 0 | 0s | 0s | write_sis_info | installer::windows::admin::
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 | |||||
28 | package installer::windows::admin; | ||||
29 | |||||
30 | 2 | 59µs | 2 | 510µs | # spent 455µs (400+55) within installer::windows::admin::BEGIN@30 which was called:
# once (400µs+55µs) by installer::windows::msp::BEGIN@39 at line 30 # spent 455µs making 1 call to installer::windows::admin::BEGIN@30
# spent 55µs making 1 call to Exporter::import |
31 | 2 | 52µs | 2 | 19µs | # spent 16µs (14+3) within installer::windows::admin::BEGIN@31 which was called:
# once (14µs+3µs) by installer::windows::msp::BEGIN@39 at line 31 # spent 16µs making 1 call to installer::windows::admin::BEGIN@31
# spent 2µs making 1 call to UNIVERSAL::import |
32 | 2 | 52µs | 2 | 17µs | # spent 15µs (13+2) within installer::windows::admin::BEGIN@32 which was called:
# once (13µs+2µs) by installer::windows::msp::BEGIN@39 at line 32 # spent 15µs making 1 call to installer::windows::admin::BEGIN@32
# spent 2µs making 1 call to UNIVERSAL::import |
33 | 2 | 51µs | 2 | 16µs | # spent 15µs (13+1) within installer::windows::admin::BEGIN@33 which was called:
# once (13µs+1µs) by installer::windows::msp::BEGIN@39 at line 33 # spent 15µs making 1 call to installer::windows::admin::BEGIN@33
# spent 2µs making 1 call to UNIVERSAL::import |
34 | 2 | 51µs | 2 | 18µs | # spent 16µs (13+3) within installer::windows::admin::BEGIN@34 which was called:
# once (13µs+3µs) by installer::windows::msp::BEGIN@39 at line 34 # spent 16µs making 1 call to installer::windows::admin::BEGIN@34
# spent 3µs making 1 call to UNIVERSAL::import |
35 | 2 | 52µs | 2 | 18µs | # spent 16µs (13+3) within installer::windows::admin::BEGIN@35 which was called:
# once (13µs+3µs) by installer::windows::msp::BEGIN@39 at line 35 # spent 16µs making 1 call to installer::windows::admin::BEGIN@35
# spent 3µs making 1 call to UNIVERSAL::import |
36 | 2 | 58µs | 2 | 29µs | # spent 23µs (17+6) within installer::windows::admin::BEGIN@36 which was called:
# once (17µs+6µs) by installer::windows::msp::BEGIN@39 at line 36 # spent 23µs making 1 call to installer::windows::admin::BEGIN@36
# spent 6µs making 1 call to UNIVERSAL::import |
37 | 2 | 4.92ms | 2 | 20µs | # spent 18µs (15+3) within installer::windows::admin::BEGIN@37 which was called:
# once (15µs+3µs) by installer::windows::msp::BEGIN@39 at line 37 # spent 18µs making 1 call to installer::windows::admin::BEGIN@37
# spent 2µs making 1 call to UNIVERSAL::import |
38 | |||||
39 | ################################################################################# | ||||
40 | # Unpacking cabinet files with expand | ||||
41 | ################################################################################# | ||||
42 | |||||
43 | sub unpack_cabinet_file | ||||
44 | { | ||||
45 | my ($cabfilename, $unpackdir) = @_; | ||||
46 | |||||
47 | my $infoline = "Unpacking cabinet file: $cabfilename\n"; | ||||
48 | push( @installer::globals::logfileinfo, $infoline); | ||||
49 | |||||
50 | my $expandfile = "expand.exe"; # Has to be in the path | ||||
51 | if ( $installer::globals::isunix ) | ||||
52 | { | ||||
53 | $infoline = "ERROR: We need to change this to use cabextract instead of expand.exe\n"; | ||||
54 | push( @installer::globals::logfileinfo, $infoline); | ||||
55 | } | ||||
56 | |||||
57 | # expand.exe has to be located in the system directory. | ||||
58 | # Cygwin has another tool expand.exe, that converts tabs to spaces. This cannot be used of course. | ||||
59 | # But this wrong expand.exe is typically in the PATH before this expand.exe, to unpack | ||||
60 | # cabinet files. | ||||
61 | |||||
62 | if ( $^O =~ /cygwin/i ) | ||||
63 | { | ||||
64 | $expandfile = qx(cygpath -u "$ENV{WINDIR}"/System32/expand.exe); | ||||
65 | chomp $expandfile; | ||||
66 | } | ||||
67 | |||||
68 | my $expandlogfile = $unpackdir . $installer::globals::separator . "expand.log"; | ||||
69 | |||||
70 | # exclude cabinet file | ||||
71 | |||||
72 | my $systemcall = ""; | ||||
73 | if ( $^O =~ /cygwin/i ) { | ||||
74 | my $localunpackdir = qx{cygpath -w "$unpackdir"}; | ||||
75 | chomp ($localunpackdir); | ||||
76 | $localunpackdir =~ s/\\/\\\\/g; | ||||
77 | $cabfilename =~ s/\\/\\\\/g; | ||||
78 | $cabfilename =~ s/\s*$//g; | ||||
79 | $systemcall = $expandfile . " " . $cabfilename . " -F:\* " . $localunpackdir . " \> " . $expandlogfile; | ||||
80 | } | ||||
81 | else | ||||
82 | { | ||||
83 | $systemcall = $expandfile . " " . $cabfilename . " -F:\* " . $unpackdir . " \> " . $expandlogfile; | ||||
84 | } | ||||
85 | |||||
86 | my $returnvalue = system($systemcall); | ||||
87 | $infoline = "Systemcall: $systemcall\n"; | ||||
88 | push( @installer::globals::logfileinfo, $infoline); | ||||
89 | |||||
90 | if ($returnvalue) | ||||
91 | { | ||||
92 | $infoline = "ERROR: Could not execute $systemcall !\n"; | ||||
93 | push( @installer::globals::logfileinfo, $infoline); | ||||
94 | installer::exiter::exit_program("ERROR: Could not extract cabinet file: $mergemodulehash->{'cabinetfile'} !", "change_file_table"); | ||||
95 | } | ||||
96 | else | ||||
97 | { | ||||
98 | $infoline = "Success: Executed $systemcall successfully!\n"; | ||||
99 | push( @installer::globals::logfileinfo, $infoline); | ||||
100 | } | ||||
101 | } | ||||
102 | |||||
103 | ################################################################################# | ||||
104 | # Extracting tables from msi database | ||||
105 | ################################################################################# | ||||
106 | |||||
107 | sub extract_tables_from_pcpfile | ||||
108 | { | ||||
109 | my ($fullmsidatabasepath, $workdir, $tablelist) = @_; | ||||
110 | |||||
111 | my $msidb = "msidb.exe"; # Has to be in the path | ||||
112 | if ( $installer::globals::isunix ) | ||||
113 | { | ||||
114 | $msidb = "$ENV{'OUTDIR_FOR_BUILD'}/bin/msidb.exe"; | ||||
115 | } | ||||
116 | my $infoline = ""; | ||||
117 | my $systemcall = ""; | ||||
118 | my $returnvalue = ""; | ||||
119 | |||||
120 | my $localfullmsidatabasepath = $fullmsidatabasepath; | ||||
121 | |||||
122 | # Export of all tables by using "*" | ||||
123 | |||||
124 | if ( $^O =~ /cygwin/i ) { | ||||
125 | # Copying the msi database locally guarantees the format of the directory. | ||||
126 | # Otherwise it is defined in the file of UPDATE_DATABASE_LISTNAME | ||||
127 | |||||
128 | my $msifilename = $localfullmsidatabasepath; | ||||
129 | installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$msifilename); | ||||
130 | my $destdatabasename = $workdir . $installer::globals::separator . $msifilename; | ||||
131 | installer::systemactions::copy_one_file($localfullmsidatabasepath, $destdatabasename); | ||||
132 | $localfullmsidatabasepath = $destdatabasename; | ||||
133 | |||||
134 | chomp( $localfullmsidatabasepath = qx{cygpath -w "$localfullmsidatabasepath"} ); | ||||
135 | chomp( $workdir = qx{cygpath -w "$workdir"} ); | ||||
136 | |||||
137 | # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) | ||||
138 | $localfullmsidatabasepath =~ s/\\/\\\\/g; | ||||
139 | $workdir =~ s/\\/\\\\/g; | ||||
140 | |||||
141 | # and if there are still slashes, they also need to be double backslash | ||||
142 | $localfullmsidatabasepath =~ s/\//\\\\/g; | ||||
143 | $workdir =~ s/\//\\\\/g; | ||||
144 | } | ||||
145 | |||||
146 | $systemcall = $msidb . " -d " . $localfullmsidatabasepath . " -f " . $workdir . " -e $tablelist"; | ||||
147 | $returnvalue = system($systemcall); | ||||
148 | |||||
149 | $infoline = "Systemcall: $systemcall\n"; | ||||
150 | push( @installer::globals::logfileinfo, $infoline); | ||||
151 | |||||
152 | if ($returnvalue) | ||||
153 | { | ||||
154 | $infoline = "ERROR: Could not execute $systemcall !\n"; | ||||
155 | push( @installer::globals::logfileinfo, $infoline); | ||||
156 | installer::exiter::exit_program("ERROR: Could not exclude tables from pcp file: $localfullmsidatabasepath !", "extract_tables_from_pcpfile"); | ||||
157 | } | ||||
158 | else | ||||
159 | { | ||||
160 | $infoline = "Success: Executed $systemcall successfully!\n"; | ||||
161 | push( @installer::globals::logfileinfo, $infoline); | ||||
162 | } | ||||
163 | } | ||||
164 | |||||
165 | ################################################################################ | ||||
166 | # Analyzing the content of Directory.idt | ||||
167 | ################################################################################# | ||||
168 | |||||
169 | sub analyze_directory_file | ||||
170 | { | ||||
171 | my ($filecontent) = @_; | ||||
172 | |||||
173 | my %table = (); | ||||
174 | |||||
175 | for ( my $i = 0; $i <= $#{$filecontent}; $i++ ) | ||||
176 | { | ||||
177 | if (( $i == 0 ) || ( $i == 1 ) || ( $i == 2 )) { next; } | ||||
178 | |||||
179 | if ( ${$filecontent}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\s*$/ ) | ||||
180 | { | ||||
181 | my $dir = $1; | ||||
182 | my $parent = $2; | ||||
183 | my $name = $3; | ||||
184 | |||||
185 | if ( $name =~ /^\s*(.*?)\s*\:\s*(.*?)\s*$/ ) { $name = $2; } | ||||
186 | if ( $name =~ /^\s*(.*?)\s*\|\s*(.*?)\s*$/ ) { $name = $2; } | ||||
187 | |||||
188 | my %helphash = (); | ||||
189 | $helphash{'Directory_Parent'} = $parent; | ||||
190 | $helphash{'DefaultDir'} = $name; | ||||
191 | $table{$dir} = \%helphash; | ||||
192 | } | ||||
193 | } | ||||
194 | |||||
195 | return \%table; | ||||
196 | } | ||||
197 | |||||
198 | ################################################################################# | ||||
199 | # Analyzing the content of Component.idt | ||||
200 | ################################################################################# | ||||
201 | |||||
202 | sub analyze_component_file | ||||
203 | { | ||||
204 | my ($filecontent) = @_; | ||||
205 | |||||
206 | my %table = (); | ||||
207 | |||||
208 | for ( my $i = 0; $i <= $#{$filecontent}; $i++ ) | ||||
209 | { | ||||
210 | if (( $i == 0 ) || ( $i == 1 ) || ( $i == 2 )) { next; } | ||||
211 | |||||
212 | if ( ${$filecontent}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ ) | ||||
213 | { | ||||
214 | my $component = $1; | ||||
215 | my $dir = $3; | ||||
216 | |||||
217 | $table{$component} = $dir; | ||||
218 | } | ||||
219 | } | ||||
220 | |||||
221 | return \%table; | ||||
222 | } | ||||
223 | |||||
224 | ################################################################################# | ||||
225 | # Analyzing the content of File.idt | ||||
226 | ################################################################################# | ||||
227 | |||||
228 | sub analyze_file_file | ||||
229 | { | ||||
230 | my ($filecontent) = @_; | ||||
231 | |||||
232 | my %table = (); | ||||
233 | my %fileorder = (); | ||||
234 | my $maxsequence = 0; | ||||
235 | |||||
236 | for ( my $i = 0; $i <= $#{$filecontent}; $i++ ) | ||||
237 | { | ||||
238 | if (( $i == 0 ) || ( $i == 1 ) || ( $i == 2 )) { next; } | ||||
239 | |||||
240 | if ( ${$filecontent}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ ) | ||||
241 | { | ||||
242 | my $file = $1; | ||||
243 | my $comp = $2; | ||||
244 | my $filename = $3; | ||||
245 | my $sequence = $8; | ||||
246 | |||||
247 | if ( $filename =~ /^\s*(.*?)\s*\|\s*(.*?)\s*$/ ) { $filename = $2; } | ||||
248 | |||||
249 | my %helphash = (); | ||||
250 | $helphash{'Component'} = $comp; | ||||
251 | $helphash{'FileName'} = $filename; | ||||
252 | $helphash{'Sequence'} = $sequence; | ||||
253 | |||||
254 | $table{$file} = \%helphash; | ||||
255 | |||||
256 | $fileorder{$sequence} = $file; | ||||
257 | |||||
258 | if ( $sequence > $maxsequence ) { $maxsequence = $sequence; } | ||||
259 | } | ||||
260 | } | ||||
261 | |||||
262 | return (\%table, \%fileorder, $maxsequence); | ||||
263 | } | ||||
264 | |||||
265 | #################################################################################### | ||||
266 | # Recursively creating the directory tree | ||||
267 | #################################################################################### | ||||
268 | |||||
269 | sub create_directory_tree | ||||
270 | { | ||||
271 | my ($parent, $pathcollector, $fulldir, $dirhash) = @_; | ||||
272 | |||||
273 | foreach my $dir ( keys %{$dirhash} ) | ||||
274 | { | ||||
275 | if (( $dirhash->{$dir}->{'Directory_Parent'} eq $parent ) && ( $dirhash->{$dir}->{'DefaultDir'} ne "." )) | ||||
276 | { | ||||
277 | my $dirname = $dirhash->{$dir}->{'DefaultDir'}; | ||||
278 | # Create the directory | ||||
279 | my $newdir = $fulldir . $installer::globals::separator . $dirname; | ||||
280 | if ( ! -f $newdir ) { mkdir $newdir; } | ||||
281 | # Saving in collector | ||||
282 | $pathcollector->{$dir} = $newdir; | ||||
283 | # Iteration | ||||
284 | create_directory_tree($dir, $pathcollector, $newdir, $dirhash); | ||||
285 | } | ||||
286 | } | ||||
287 | } | ||||
288 | |||||
289 | #################################################################################### | ||||
290 | # Creating the directory tree | ||||
291 | #################################################################################### | ||||
292 | |||||
293 | sub create_directory_structure | ||||
294 | { | ||||
295 | my ($dirhash, $targetdir) = @_; | ||||
296 | |||||
297 | my %fullpathhash = (); | ||||
298 | |||||
299 | my @startparents = ("TARGETDIR", "INSTALLLOCATION"); | ||||
300 | |||||
301 | foreach $dir (@startparents) { create_directory_tree($dir, \%fullpathhash, $targetdir, $dirhash); } | ||||
302 | |||||
303 | # Also adding the paths of the startparents | ||||
304 | foreach $dir (@startparents) | ||||
305 | { | ||||
306 | if ( ! exists($fullpathhash{$dir}) ) { $fullpathhash{$dir} = $targetdir; } | ||||
307 | } | ||||
308 | |||||
309 | return \%fullpathhash; | ||||
310 | } | ||||
311 | |||||
312 | #################################################################################### | ||||
313 | # Copying files into installation set | ||||
314 | #################################################################################### | ||||
315 | |||||
316 | sub copy_files_into_directory_structure | ||||
317 | { | ||||
318 | my ($fileorder, $filehash, $componenthash, $fullpathhash, $maxsequence, $unpackdir, $installdir, $dirhash) = @_; | ||||
319 | |||||
320 | for ( my $i = 1; $i <= $maxsequence; $i++ ) | ||||
321 | { | ||||
322 | if ( exists($fileorder->{$i}) ) | ||||
323 | { | ||||
324 | my $file = $fileorder->{$i}; | ||||
325 | if ( ! exists($filehash->{$file}->{'Component'}) ) { installer::exiter::exit_program("ERROR: Did not find component for file: \"$file\".", "copy_files_into_directory_structure"); } | ||||
326 | my $component = $filehash->{$file}->{'Component'}; | ||||
327 | if ( ! exists($componenthash->{$component}) ) { installer::exiter::exit_program("ERROR: Did not find directory for component: \"$component\".", "copy_files_into_directory_structure"); } | ||||
328 | my $dirname = $componenthash->{$component}; | ||||
329 | if ( ! exists($fullpathhash->{$dirname}) ) { installer::exiter::exit_program("ERROR: Did not find full directory path for dir: \"$dirname\".", "copy_files_into_directory_structure"); } | ||||
330 | my $destdir = $fullpathhash->{$dirname}; | ||||
331 | if ( ! exists($filehash->{$file}->{'FileName'}) ) { installer::exiter::exit_program("ERROR: Did not find \"FileName\" for file: \"$file\".", "copy_files_into_directory_structure"); } | ||||
332 | my $destfile = $filehash->{$file}->{'FileName'}; | ||||
333 | |||||
334 | $destfile = $destdir . $installer::globals::separator . $destfile; | ||||
335 | my $sourcefile = $unpackdir . $installer::globals::separator . $file; | ||||
336 | |||||
337 | if ( ! -f $sourcefile ) | ||||
338 | { | ||||
339 | # It is possible, that this was an unpacked file | ||||
340 | # Looking in the dirhash, to find the subdirectory in the installation set (the id is $dirname) | ||||
341 | # subdir is not recursively analyzed, only one directory. | ||||
342 | |||||
343 | my $oldsourcefile = $sourcefile; | ||||
344 | my $subdir = ""; | ||||
345 | if ( exists($dirhash->{$dirname}->{'DefaultDir'}) ) { $subdir = $dirhash->{$dirname}->{'DefaultDir'} . $installer::globals::separator; } | ||||
346 | my $realfilename = $filehash->{$file}->{'FileName'}; | ||||
347 | my $localinstalldir = $installdir; | ||||
348 | |||||
349 | $localinstalldir =~ s/\\\s*$//; | ||||
350 | $localinstalldir =~ s/\/\s*$//; | ||||
351 | |||||
352 | $sourcefile = $localinstalldir . $installer::globals::separator . $subdir . $realfilename; | ||||
353 | |||||
354 | if ( ! -f $sourcefile ) | ||||
355 | { | ||||
356 | installer::exiter::exit_program("ERROR: File not found: \"$oldsourcefile\" (or \"$sourcefile\").", "copy_files_into_directory_structure"); | ||||
357 | } | ||||
358 | } | ||||
359 | |||||
360 | my $copyreturn = copy($sourcefile, $destfile); | ||||
361 | |||||
362 | if ( ! $copyreturn) # only logging problems | ||||
363 | { | ||||
364 | my $infoline = "ERROR: Could not copy $sourcefile to $destfile (insufficient disc space for $destfile ?)\n"; | ||||
365 | $returnvalue = 0; | ||||
366 | push(@installer::globals::logfileinfo, $infoline); | ||||
367 | installer::exiter::exit_program($infoline, "copy_files_into_directory_structure"); | ||||
368 | } | ||||
369 | } | ||||
370 | } | ||||
371 | } | ||||
372 | |||||
373 | |||||
374 | ############################################################### | ||||
375 | # Setting the time string for the | ||||
376 | # Summary Information stream in the | ||||
377 | # msi database of the admin installations. | ||||
378 | ############################################################### | ||||
379 | |||||
380 | sub get_sis_time_string | ||||
381 | { | ||||
382 | # Syntax: <yyyy/mm/dd hh:mm:ss> | ||||
383 | my $second = (localtime())[0]; | ||||
384 | my $minute = (localtime())[1]; | ||||
385 | my $hour = (localtime())[2]; | ||||
386 | my $day = (localtime())[3]; | ||||
387 | my $month = (localtime())[4]; | ||||
388 | my $year = 1900 + (localtime())[5]; | ||||
389 | |||||
390 | $month++; # zero based month | ||||
391 | |||||
392 | if ( $second < 10 ) { $second = "0" . $second; } | ||||
393 | if ( $minute < 10 ) { $minute = "0" . $minute; } | ||||
394 | if ( $hour < 10 ) { $hour = "0" . $hour; } | ||||
395 | if ( $day < 10 ) { $day = "0" . $day; } | ||||
396 | if ( $month < 10 ) { $month = "0" . $month; } | ||||
397 | |||||
398 | my $timestring = $year . "/" . $month . "/" . $day . " " . $hour . ":" . $minute . ":" . $second; | ||||
399 | |||||
400 | return $timestring; | ||||
401 | } | ||||
402 | |||||
403 | ############################################################### | ||||
404 | # Writing content of administrative installations into | ||||
405 | # Summary Information Stream of msi database. | ||||
406 | # This is required for example for following | ||||
407 | # patch processes using Windows Installer service. | ||||
408 | ############################################################### | ||||
409 | |||||
410 | sub write_sis_info | ||||
411 | { | ||||
412 | my ($msidatabase) = @_ ; | ||||
413 | |||||
414 | if ( ! -f $msidatabase ) { installer::exiter::exit_program("ERROR: Cannot find file $msidatabase", "write_sis_info"); } | ||||
415 | |||||
416 | my $msiinfo = "msiinfo.exe"; # Has to be in the path | ||||
417 | if ( $installer::globals::isunix ) | ||||
418 | { | ||||
419 | $msiinfo = "$ENV{'OUTDIR_FOR_BUILD'}/bin/msiinfo.exe"; | ||||
420 | } | ||||
421 | my $infoline = ""; | ||||
422 | my $systemcall = ""; | ||||
423 | my $returnvalue = ""; | ||||
424 | |||||
425 | # Required setting for administrative installations: | ||||
426 | # -w 4 (source files are unpacked), wordcount | ||||
427 | # -s <date of admin installation>, LastPrinted, Syntax: <yyyy/mm/dd hh:mm:ss> | ||||
428 | # -l <person_making_admin_installation>, LastSavedBy | ||||
429 | |||||
430 | my $wordcount = 4; # Unpacked files | ||||
431 | my $lastprinted = get_sis_time_string(); | ||||
432 | my $lastsavedby = "Installer"; | ||||
433 | |||||
434 | my $localmsidatabase = $msidatabase; | ||||
435 | |||||
436 | if( $^O =~ /cygwin/i ) | ||||
437 | { | ||||
438 | $localmsidatabase = qx{cygpath -w "$localmsidatabase"}; | ||||
439 | $localmsidatabase =~ s/\\/\\\\/g; | ||||
440 | $localmsidatabase =~ s/\s*$//g; | ||||
441 | } | ||||
442 | |||||
443 | $systemcall = $msiinfo . " " . "\"" . $localmsidatabase . "\"" . " -w " . $wordcount . " -s " . "\"" . $lastprinted . "\"" . " -l $lastsavedby"; | ||||
444 | push(@installer::globals::logfileinfo, $systemcall); | ||||
445 | $returnvalue = system($systemcall); | ||||
446 | |||||
447 | if ($returnvalue) | ||||
448 | { | ||||
449 | $infoline = "ERROR: Could not execute $systemcall !\n"; | ||||
450 | push(@installer::globals::logfileinfo, $infoline); | ||||
451 | installer::exiter::exit_program($infoline, "write_sis_info"); | ||||
452 | } | ||||
453 | } | ||||
454 | |||||
455 | #################################################################################### | ||||
456 | # Simulating an administrative installation | ||||
457 | #################################################################################### | ||||
458 | |||||
459 | sub make_admin_install | ||||
460 | { | ||||
461 | my ($databasepath, $targetdir) = @_; | ||||
462 | |||||
463 | # Create helper directory | ||||
464 | |||||
465 | installer::logger::print_message( "... installing $databasepath in directory $targetdir ...\n" ); | ||||
466 | |||||
467 | my $helperdir = $targetdir . $installer::globals::separator . "installhelper"; | ||||
468 | installer::systemactions::create_directory($helperdir); | ||||
469 | |||||
470 | # Get File.idt, Component.idt and Directory.idt from database | ||||
471 | |||||
472 | my $tablelist = "File Directory Component Registry"; | ||||
473 | extract_tables_from_pcpfile($databasepath, $helperdir, $tablelist); | ||||
474 | |||||
475 | # Unpack all cab files into $helperdir, cab files must be located next to msi database | ||||
476 | my $installdir = $databasepath; | ||||
477 | |||||
478 | if ( $^O =~ /cygwin/i ) { $installdir =~ s/\\/\//g; } # backslash to slash | ||||
479 | |||||
480 | installer::pathanalyzer::get_path_from_fullqualifiedname(\$installdir); | ||||
481 | |||||
482 | if ( $^O =~ /cygwin/i ) { $installdir =~ s/\//\\/g; } # slash to backslash | ||||
483 | |||||
484 | my $databasefilename = $databasepath; | ||||
485 | installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$databasefilename); | ||||
486 | |||||
487 | my $cabfiles = installer::systemactions::find_file_with_file_extension("cab", $installdir); | ||||
488 | |||||
489 | if ( $#{$cabfiles} < 0 ) { installer::exiter::exit_program("ERROR: Did not find any cab file in directory $installdir", "make_admin_install"); } | ||||
490 | |||||
491 | # Set unpackdir | ||||
492 | my $unpackdir = $helperdir . $installer::globals::separator . "unpack"; | ||||
493 | installer::systemactions::create_directory($unpackdir); | ||||
494 | |||||
495 | for ( my $i = 0; $i <= $#{$cabfiles}; $i++ ) | ||||
496 | { | ||||
497 | my $cabfile = ""; | ||||
498 | if ( $^O =~ /cygwin/i ) | ||||
499 | { | ||||
500 | $cabfile = $installdir . ${$cabfiles}[$i]; | ||||
501 | } | ||||
502 | else | ||||
503 | { | ||||
504 | $cabfile = $installdir . $installer::globals::separator . ${$cabfiles}[$i]; | ||||
505 | } | ||||
506 | unpack_cabinet_file($cabfile, $unpackdir); | ||||
507 | } | ||||
508 | |||||
509 | # Reading tables | ||||
510 | my $filename = $helperdir . $installer::globals::separator . "Directory.idt"; | ||||
511 | my $filecontent = installer::files::read_file($filename); | ||||
512 | my $dirhash = analyze_directory_file($filecontent); | ||||
513 | |||||
514 | $filename = $helperdir . $installer::globals::separator . "Component.idt"; | ||||
515 | my $componentfilecontent = installer::files::read_file($filename); | ||||
516 | my $componenthash = analyze_component_file($componentfilecontent); | ||||
517 | |||||
518 | $filename = $helperdir . $installer::globals::separator . "File.idt"; | ||||
519 | $filecontent = installer::files::read_file($filename); | ||||
520 | my ( $filehash, $fileorder, $maxsequence ) = analyze_file_file($filecontent); | ||||
521 | |||||
522 | # Creating the directory structure | ||||
523 | my $fullpathhash = create_directory_structure($dirhash, $targetdir); | ||||
524 | |||||
525 | # Copying files | ||||
526 | copy_files_into_directory_structure($fileorder, $filehash, $componenthash, $fullpathhash, $maxsequence, $unpackdir, $installdir, $dirhash); | ||||
527 | |||||
528 | my $msidatabase = $targetdir . $installer::globals::separator . $databasefilename; | ||||
529 | installer::systemactions::copy_one_file($databasepath, $msidatabase); | ||||
530 | |||||
531 | # Saving info in Summary Information Stream of msi database (required for following patches) | ||||
532 | write_sis_info($msidatabase); | ||||
533 | |||||
534 | return $msidatabase; | ||||
535 | } | ||||
536 | |||||
537 | 1 | 10µs | 1; |