1*b1cdbd2cSJim Jagielski#**************************************************************
2*b1cdbd2cSJim Jagielski#
3*b1cdbd2cSJim Jagielski#  Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski#  or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski#  distributed with this work for additional information
6*b1cdbd2cSJim Jagielski#  regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski#  to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski#  "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski#  with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski#
11*b1cdbd2cSJim Jagielski#    http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski#
13*b1cdbd2cSJim Jagielski#  Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski#  software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski#  KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski#  specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski#  under the License.
19*b1cdbd2cSJim Jagielski#
20*b1cdbd2cSJim Jagielski#**************************************************************
21*b1cdbd2cSJim Jagielski
22*b1cdbd2cSJim Jagielski
23*b1cdbd2cSJim Jagielski
24*b1cdbd2cSJim Jagielskipackage installer::windows::directory;
25*b1cdbd2cSJim Jagielski
26*b1cdbd2cSJim Jagielskiuse installer::exiter;
27*b1cdbd2cSJim Jagielskiuse installer::files;
28*b1cdbd2cSJim Jagielskiuse installer::globals;
29*b1cdbd2cSJim Jagielskiuse installer::pathanalyzer;
30*b1cdbd2cSJim Jagielskiuse installer::windows::idtglobal;
31*b1cdbd2cSJim Jagielskiuse installer::windows::msiglobal;
32*b1cdbd2cSJim Jagielskiuse installer::scriptitems;
33*b1cdbd2cSJim Jagielski
34*b1cdbd2cSJim Jagielskiuse strict;
35*b1cdbd2cSJim Jagielski
36*b1cdbd2cSJim Jagielski##############################################################
37*b1cdbd2cSJim Jagielski# Collecting all directory trees in global hash
38*b1cdbd2cSJim Jagielski##############################################################
39*b1cdbd2cSJim Jagielski
40*b1cdbd2cSJim Jagielskisub collectdirectorytrees
41*b1cdbd2cSJim Jagielski{
42*b1cdbd2cSJim Jagielski	my ( $directoryref ) = @_;
43*b1cdbd2cSJim Jagielski
44*b1cdbd2cSJim Jagielski	for ( my $i = 0; $i <= $#{$directoryref}; $i++ )
45*b1cdbd2cSJim Jagielski	{
46*b1cdbd2cSJim Jagielski		my $onedir = ${$directoryref}[$i];
47*b1cdbd2cSJim Jagielski		my $styles = "";
48*b1cdbd2cSJim Jagielski		if ( $onedir->{'Styles'} ) { $styles = $onedir->{'Styles'}; }
49*b1cdbd2cSJim Jagielski
50*b1cdbd2cSJim Jagielski		if ( $styles ne "" )
51*b1cdbd2cSJim Jagielski		{
52*b1cdbd2cSJim Jagielski			foreach my $treestyle ( keys %installer::globals::treestyles )
53*b1cdbd2cSJim Jagielski			{
54*b1cdbd2cSJim Jagielski				if ( $styles =~ /\b$treestyle\b/ )
55*b1cdbd2cSJim Jagielski				{
56*b1cdbd2cSJim Jagielski					my $hostname = $onedir->{'HostName'};
57*b1cdbd2cSJim Jagielski					# -> hostname is the key, the style the value!
58*b1cdbd2cSJim Jagielski					$installer::globals::hostnametreestyles{$hostname} = $treestyle;
59*b1cdbd2cSJim Jagielski				}
60*b1cdbd2cSJim Jagielski			}
61*b1cdbd2cSJim Jagielski		}
62*b1cdbd2cSJim Jagielski	}
63*b1cdbd2cSJim Jagielski}
64*b1cdbd2cSJim Jagielski
65*b1cdbd2cSJim Jagielski##############################################################
66*b1cdbd2cSJim Jagielski# Overwriting global programfilesfolder, if required
67*b1cdbd2cSJim Jagielski##############################################################
68*b1cdbd2cSJim Jagielski
69*b1cdbd2cSJim Jagielskisub overwrite_programfilesfolder
70*b1cdbd2cSJim Jagielski{
71*b1cdbd2cSJim Jagielski	my ( $allvariables ) = @_;
72*b1cdbd2cSJim Jagielski
73*b1cdbd2cSJim Jagielski	if ( $allvariables->{'PROGRAMFILESFOLDERNAME'} )
74*b1cdbd2cSJim Jagielski	{
75*b1cdbd2cSJim Jagielski		$installer::globals::programfilesfolder = $allvariables->{'PROGRAMFILESFOLDERNAME'};
76*b1cdbd2cSJim Jagielski	}
77*b1cdbd2cSJim Jagielski}
78*b1cdbd2cSJim Jagielski
79*b1cdbd2cSJim Jagielski
80*b1cdbd2cSJim Jagielski
81*b1cdbd2cSJim Jagielski
82*b1cdbd2cSJim Jagielski=head2 make_short_dir_version($longstring)
83*b1cdbd2cSJim Jagielski
84*b1cdbd2cSJim Jagielski    Transform the given string into one that is at most 70 characters long.
85*b1cdbd2cSJim Jagielski    That is done in two steps:
86*b1cdbd2cSJim Jagielski    - Cut all parts separated by '_' or '-' down to a length of 5.
87*b1cdbd2cSJim Jagielski    - Cut down the result to a length of 60 and fill it up to length 70
88*b1cdbd2cSJim Jagielski      with the MD5 checksum.
89*b1cdbd2cSJim Jagielski
90*b1cdbd2cSJim Jagielski    This transform always returns the same result for the same string.
91*b1cdbd2cSJim Jagielski    There is no counter and reference to a global set of names to make the string unique.
92*b1cdbd2cSJim Jagielski
93*b1cdbd2cSJim Jagielski=cut
94*b1cdbd2cSJim Jagielskisub make_short_dir_version ($)
95*b1cdbd2cSJim Jagielski{
96*b1cdbd2cSJim Jagielski	my ($longstring) = @_;
97*b1cdbd2cSJim Jagielski
98*b1cdbd2cSJim Jagielski	my $shortstring = "";
99*b1cdbd2cSJim Jagielski	my $cutlength = 60;
100*b1cdbd2cSJim Jagielski	my $length = 5; # So the directory can still be recognized
101*b1cdbd2cSJim Jagielski	my $longstring_save = $longstring;
102*b1cdbd2cSJim Jagielski
103*b1cdbd2cSJim Jagielski	# Splitting the string at each "underline" and allowing only $length characters per directory name.
104*b1cdbd2cSJim Jagielski	# Checking also uniqueness and length.
105*b1cdbd2cSJim Jagielski
106*b1cdbd2cSJim Jagielski	my @outer_parts = split(/_/, $longstring);
107*b1cdbd2cSJim Jagielski	foreach my $onestring (@outer_parts)
108*b1cdbd2cSJim Jagielski	{
109*b1cdbd2cSJim Jagielski		my $partstring = "";
110*b1cdbd2cSJim Jagielski
111*b1cdbd2cSJim Jagielski		if ( $onestring =~ /\-/ )
112*b1cdbd2cSJim Jagielski		{
113*b1cdbd2cSJim Jagielski			my @inner_parts = split(/-/, $onestring);
114*b1cdbd2cSJim Jagielski            @inner_parts = map {substr($_,0,$length)} @inner_parts;
115*b1cdbd2cSJim Jagielski            $partstring = join("-", @inner_parts);
116*b1cdbd2cSJim Jagielski			$partstring =~ s/^\s*\-//;
117*b1cdbd2cSJim Jagielski		}
118*b1cdbd2cSJim Jagielski		else
119*b1cdbd2cSJim Jagielski		{
120*b1cdbd2cSJim Jagielski			$partstring = substr($onestring, 0, $length);
121*b1cdbd2cSJim Jagielski		}
122*b1cdbd2cSJim Jagielski
123*b1cdbd2cSJim Jagielski		$shortstring .= "_" . $partstring;
124*b1cdbd2cSJim Jagielski	}
125*b1cdbd2cSJim Jagielski
126*b1cdbd2cSJim Jagielski	$shortstring =~ s/^\s*\_//;
127*b1cdbd2cSJim Jagielski
128*b1cdbd2cSJim Jagielski	# Setting unique ID to each directory
129*b1cdbd2cSJim Jagielski	# No counter allowed, process must be absolute reproducable due to patch creation process.
130*b1cdbd2cSJim Jagielski
131*b1cdbd2cSJim Jagielski	my $subid = installer::windows::msiglobal::calculate_id($longstring_save, 9); # taking only the first 9 digits
132*b1cdbd2cSJim Jagielski	$shortstring = substr($shortstring, 0, $cutlength) . "_" . $subid;
133*b1cdbd2cSJim Jagielski
134*b1cdbd2cSJim Jagielski	return $shortstring;
135*b1cdbd2cSJim Jagielski}
136*b1cdbd2cSJim Jagielski
137*b1cdbd2cSJim Jagielski
138*b1cdbd2cSJim Jagielski
139*b1cdbd2cSJim Jagielski
140*b1cdbd2cSJim Jagielski=head2 get_unique_name ($hostname, $unique_map, $shortdirhash, $shortdirhashreverse)
141*b1cdbd2cSJim Jagielski
142*b1cdbd2cSJim Jagielski    Return a long and a short unique name for the given $hostname.
143*b1cdbd2cSJim Jagielski    Despite the function name and unlike the generation of unique
144*b1cdbd2cSJim Jagielski    names for files, the returned names are not really unique.  Quite
145*b1cdbd2cSJim Jagielski    the opposite.  The returned names are quaranteed to return the
146*b1cdbd2cSJim Jagielski    same result for the same input.
147*b1cdbd2cSJim Jagielski
148*b1cdbd2cSJim Jagielski    The returned short name has at most length 70.
149*b1cdbd2cSJim Jagielski
150*b1cdbd2cSJim Jagielski=cut
151*b1cdbd2cSJim Jagielskisub get_unique_name ($$)
152*b1cdbd2cSJim Jagielski{
153*b1cdbd2cSJim Jagielski    my ($hostname, $hostnamehash) = @_;
154*b1cdbd2cSJim Jagielski
155*b1cdbd2cSJim Jagielski    # Make sure that we where not called for this hostname before.  Otherwise the other test would be triggered.
156*b1cdbd2cSJim Jagielski    if (defined $hostnamehash->{$hostname})
157*b1cdbd2cSJim Jagielski    {
158*b1cdbd2cSJim Jagielski        installer::exiter::exit_program(
159*b1cdbd2cSJim Jagielski            "ERROR: get_unique_name was already called for hostname ".$hostname,
160*b1cdbd2cSJim Jagielski            "get_unique_name");
161*b1cdbd2cSJim Jagielski    }
162*b1cdbd2cSJim Jagielski    $hostnamehash->{$hostname} = 1;
163*b1cdbd2cSJim Jagielski
164*b1cdbd2cSJim Jagielski    my $uniquename = $hostname;
165*b1cdbd2cSJim Jagielski
166*b1cdbd2cSJim Jagielski    $uniquename =~ s/^\s*//g;				# removing beginning white spaces
167*b1cdbd2cSJim Jagielski    $uniquename =~ s/\s*$//g;				# removing ending white spaces
168*b1cdbd2cSJim Jagielski    $uniquename =~ s/\s//g;					# removing white spaces
169*b1cdbd2cSJim Jagielski    $uniquename =~ s/\_//g;					# removing existing underlines
170*b1cdbd2cSJim Jagielski    $uniquename =~ s/\.//g;					# removing dots in directoryname
171*b1cdbd2cSJim Jagielski    $uniquename =~ s/OpenOffice/OO/g;
172*b1cdbd2cSJim Jagielski
173*b1cdbd2cSJim Jagielski    $uniquename =~ s/\Q$installer::globals::separator\E/\_/g;	# replacing slash and backslash with underline
174*b1cdbd2cSJim Jagielski
175*b1cdbd2cSJim Jagielski    $uniquename =~ s/_registry/_rgy/g;
176*b1cdbd2cSJim Jagielski    $uniquename =~ s/_registration/_rgn/g;
177*b1cdbd2cSJim Jagielski    $uniquename =~ s/_extension/_ext/g;
178*b1cdbd2cSJim Jagielski    $uniquename =~ s/_frame/_frm/g;
179*b1cdbd2cSJim Jagielski    $uniquename =~ s/_table/_tbl/g;
180*b1cdbd2cSJim Jagielski    $uniquename =~ s/_chart/_crt/g;
181*b1cdbd2cSJim Jagielski
182*b1cdbd2cSJim Jagielski    my $short_uniquename = make_short_dir_version($uniquename);
183*b1cdbd2cSJim Jagielski
184*b1cdbd2cSJim Jagielski    return ($uniquename, $short_uniquename);
185*b1cdbd2cSJim Jagielski}
186*b1cdbd2cSJim Jagielski
187*b1cdbd2cSJim Jagielski
188*b1cdbd2cSJim Jagielski
189*b1cdbd2cSJim Jagielski
190*b1cdbd2cSJim Jagielski=head2 check_unique_directorynames($directories)
191*b1cdbd2cSJim Jagielski
192*b1cdbd2cSJim Jagielski    The one really important check is made in get_unique_name().  It
193*b1cdbd2cSJim Jagielski    checks that get_unique_name() is not called twice for the same
194*b1cdbd2cSJim Jagielski    directory host name.  The tests in this function contain the
195*b1cdbd2cSJim Jagielski    legacy tests that basically only check if there where a collision
196*b1cdbd2cSJim Jagielski    of the partial MD5 sum that is used to make the short unique names
197*b1cdbd2cSJim Jagielski    unique.
198*b1cdbd2cSJim Jagielski
199*b1cdbd2cSJim Jagielski    The maps $unique_map, $shortdirhash, $shortdirhashreverse are used
200*b1cdbd2cSJim Jagielski    only to check that _different_ input names are mapped to different
201*b1cdbd2cSJim Jagielski    results.  They are not used to influence the result.  That assumes
202*b1cdbd2cSJim Jagielski    that this function is called only once for every directory
203*b1cdbd2cSJim Jagielski    hostname.
204*b1cdbd2cSJim Jagielski=cut
205*b1cdbd2cSJim Jagielskisub check_unique_directorynames ($)
206*b1cdbd2cSJim Jagielski{
207*b1cdbd2cSJim Jagielski    my ($directories) = @_;
208*b1cdbd2cSJim Jagielski
209*b1cdbd2cSJim Jagielski    my %completedirhashstep1 = ();
210*b1cdbd2cSJim Jagielski	my %shortdirhash = ();
211*b1cdbd2cSJim Jagielski	my %shortdirhashreverse = ();
212*b1cdbd2cSJim Jagielski
213*b1cdbd2cSJim Jagielski    # Check unique name of directories.
214*b1cdbd2cSJim Jagielski    foreach my $directory (@$directories)
215*b1cdbd2cSJim Jagielski    {
216*b1cdbd2cSJim Jagielski        my ($long_uniquename, $short_uniquename) = ($directory->{'long_uniquename'}, $directory->{'uniquename'});
217*b1cdbd2cSJim Jagielski
218*b1cdbd2cSJim Jagielski        # The names after this small changes must still be unique!
219*b1cdbd2cSJim Jagielski        if (exists($completedirhashstep1{$long_uniquename}))
220*b1cdbd2cSJim Jagielski        {
221*b1cdbd2cSJim Jagielski            installer::exiter::exit_program(
222*b1cdbd2cSJim Jagielski                sprintf("ERROR: Unallowed modification of directory name, not unique (step 1): \"%s\".",
223*b1cdbd2cSJim Jagielski                    $short_uniquename),
224*b1cdbd2cSJim Jagielski                "check_unique_directorynames");
225*b1cdbd2cSJim Jagielski        }
226*b1cdbd2cSJim Jagielski        $completedirhashstep1{$long_uniquename} = 1;
227*b1cdbd2cSJim Jagielski
228*b1cdbd2cSJim Jagielski
229*b1cdbd2cSJim Jagielski        # Checking if the same directory already exists, but has another short version.
230*b1cdbd2cSJim Jagielski        if (exists($shortdirhash{$long_uniquename})
231*b1cdbd2cSJim Jagielski            && ( $shortdirhash{$long_uniquename} ne $short_uniquename ))
232*b1cdbd2cSJim Jagielski        {
233*b1cdbd2cSJim Jagielski            installer::exiter::exit_program(
234*b1cdbd2cSJim Jagielski                sprintf(
235*b1cdbd2cSJim Jagielski                    "ERROR: Unallowed modification of directory name, not unique (step 2A): \"%s\".",
236*b1cdbd2cSJim Jagielski                    $short_uniquename),
237*b1cdbd2cSJim Jagielski                "check_unique_directorynames");
238*b1cdbd2cSJim Jagielski        }
239*b1cdbd2cSJim Jagielski        $shortdirhash{$long_uniquename} = $short_uniquename;
240*b1cdbd2cSJim Jagielski
241*b1cdbd2cSJim Jagielski        # Also checking vice versa
242*b1cdbd2cSJim Jagielski        # Checking if the same short directory already exists, but has another long version.
243*b1cdbd2cSJim Jagielski        if (exists($shortdirhashreverse{$short_uniquename})
244*b1cdbd2cSJim Jagielski            && ( $shortdirhashreverse{$short_uniquename} ne $long_uniquename ))
245*b1cdbd2cSJim Jagielski        {
246*b1cdbd2cSJim Jagielski            installer::exiter::exit_program(
247*b1cdbd2cSJim Jagielski                sprintf(
248*b1cdbd2cSJim Jagielski                    "ERROR: Unallowed modification of directory name, not unique (step 2B): \"%s\".",
249*b1cdbd2cSJim Jagielski                    $short_uniquename),
250*b1cdbd2cSJim Jagielski                "check_unique_directorynames");
251*b1cdbd2cSJim Jagielski        }
252*b1cdbd2cSJim Jagielski        $shortdirhashreverse{$short_uniquename} = $long_uniquename;
253*b1cdbd2cSJim Jagielski    }
254*b1cdbd2cSJim Jagielski
255*b1cdbd2cSJim Jagielski    # Check unique name of parents
256*b1cdbd2cSJim Jagielski    foreach my $directory (@$directories)
257*b1cdbd2cSJim Jagielski    {
258*b1cdbd2cSJim Jagielski        my ($long_uniquename, $short_uniquename)
259*b1cdbd2cSJim Jagielski            = ($directory->{'long_uniqueparentname'}, $directory->{'uniqueparentname'});
260*b1cdbd2cSJim Jagielski
261*b1cdbd2cSJim Jagielski        # Again checking if the same directory already exists, but has another short version.
262*b1cdbd2cSJim Jagielski        if (exists($shortdirhash{$long_uniquename})
263*b1cdbd2cSJim Jagielski            && ( $shortdirhash{$long_uniquename} ne $short_uniquename ))
264*b1cdbd2cSJim Jagielski        {
265*b1cdbd2cSJim Jagielski            installer::exiter::exit_program(
266*b1cdbd2cSJim Jagielski                sprintf(
267*b1cdbd2cSJim Jagielski                    "ERROR: Unallowed modification of directory name, not unique (step 3A): \"%s\".",
268*b1cdbd2cSJim Jagielski                    $short_uniquename),
269*b1cdbd2cSJim Jagielski                "check_unique_directorynames");
270*b1cdbd2cSJim Jagielski        }
271*b1cdbd2cSJim Jagielski        $shortdirhash{$long_uniquename} = $short_uniquename;
272*b1cdbd2cSJim Jagielski
273*b1cdbd2cSJim Jagielski        # Also checking vice versa
274*b1cdbd2cSJim Jagielski        # Checking if the same short directory already exists, but has another long version.
275*b1cdbd2cSJim Jagielski        if (exists($shortdirhashreverse{$short_uniquename})
276*b1cdbd2cSJim Jagielski            && ( $shortdirhashreverse{$short_uniquename} ne $long_uniquename ))
277*b1cdbd2cSJim Jagielski        {
278*b1cdbd2cSJim Jagielski            installer::exiter::exit_program(
279*b1cdbd2cSJim Jagielski                sprintf(
280*b1cdbd2cSJim Jagielski                    "ERROR: Unallowed modification of directory name, not unique (step 3B): \"%s\".",
281*b1cdbd2cSJim Jagielski                    $short_uniquename),
282*b1cdbd2cSJim Jagielski                "check_unique_directorynames");
283*b1cdbd2cSJim Jagielski        }
284*b1cdbd2cSJim Jagielski        $shortdirhashreverse{$short_uniquename} = $long_uniquename;
285*b1cdbd2cSJim Jagielski    }
286*b1cdbd2cSJim Jagielski}
287*b1cdbd2cSJim Jagielski
288*b1cdbd2cSJim Jagielski
289*b1cdbd2cSJim Jagielski
290*b1cdbd2cSJim Jagielski
291*b1cdbd2cSJim Jagielskisub get_unique_parent_name ($$)
292*b1cdbd2cSJim Jagielski{
293*b1cdbd2cSJim Jagielski    my ($uniqueparentname, $styles) = @_;
294*b1cdbd2cSJim Jagielski
295*b1cdbd2cSJim Jagielski    my $keepparent = 1;
296*b1cdbd2cSJim Jagielski
297*b1cdbd2cSJim Jagielski    if ( $uniqueparentname =~ /^\s*(.*)\_(.*?)\s*$/ )	# the underline is now the separator
298*b1cdbd2cSJim Jagielski    {
299*b1cdbd2cSJim Jagielski        $uniqueparentname = $1;
300*b1cdbd2cSJim Jagielski        $keepparent = 0;
301*b1cdbd2cSJim Jagielski    }
302*b1cdbd2cSJim Jagielski    else
303*b1cdbd2cSJim Jagielski    {
304*b1cdbd2cSJim Jagielski        $uniqueparentname = $installer::globals::programfilesfolder;
305*b1cdbd2cSJim Jagielski        $keepparent = 1;
306*b1cdbd2cSJim Jagielski    }
307*b1cdbd2cSJim Jagielski
308*b1cdbd2cSJim Jagielski    if ( $styles =~ /\bPROGRAMFILESFOLDER\b/ )
309*b1cdbd2cSJim Jagielski    {
310*b1cdbd2cSJim Jagielski        $uniqueparentname = $installer::globals::programfilesfolder;
311*b1cdbd2cSJim Jagielski        $keepparent = 1;
312*b1cdbd2cSJim Jagielski    }
313*b1cdbd2cSJim Jagielski    if ( $styles =~ /\bCOMMONFILESFOLDER\b/ )
314*b1cdbd2cSJim Jagielski    {
315*b1cdbd2cSJim Jagielski        $uniqueparentname = $installer::globals::commonfilesfolder;
316*b1cdbd2cSJim Jagielski        $keepparent = 1;
317*b1cdbd2cSJim Jagielski    }
318*b1cdbd2cSJim Jagielski    if ( $styles =~ /\bCOMMONAPPDATAFOLDER\b/ )
319*b1cdbd2cSJim Jagielski    {
320*b1cdbd2cSJim Jagielski        $uniqueparentname = $installer::globals::commonappdatafolder;
321*b1cdbd2cSJim Jagielski        $keepparent = 1;
322*b1cdbd2cSJim Jagielski    }
323*b1cdbd2cSJim Jagielski    if ( $styles =~ /\bLOCALAPPDATAFOLDER\b/ )
324*b1cdbd2cSJim Jagielski    {
325*b1cdbd2cSJim Jagielski        $uniqueparentname = $installer::globals::localappdatafolder;
326*b1cdbd2cSJim Jagielski        $keepparent = 1;
327*b1cdbd2cSJim Jagielski    }
328*b1cdbd2cSJim Jagielski
329*b1cdbd2cSJim Jagielski    if ( $styles =~ /\bSHAREPOINTPATH\b/ )
330*b1cdbd2cSJim Jagielski    {
331*b1cdbd2cSJim Jagielski        $uniqueparentname = "SHAREPOINTPATH";
332*b1cdbd2cSJim Jagielski        $installer::globals::usesharepointpath = 1;
333*b1cdbd2cSJim Jagielski        $keepparent = 1;
334*b1cdbd2cSJim Jagielski    }
335*b1cdbd2cSJim Jagielski
336*b1cdbd2cSJim Jagielski    # also setting short directory name for the parent
337*b1cdbd2cSJim Jagielski
338*b1cdbd2cSJim Jagielski    my $originaluniqueparentname = $uniqueparentname;
339*b1cdbd2cSJim Jagielski
340*b1cdbd2cSJim Jagielski    if ( ! $keepparent )
341*b1cdbd2cSJim Jagielski    {
342*b1cdbd2cSJim Jagielski        $uniqueparentname = make_short_dir_version($uniqueparentname);
343*b1cdbd2cSJim Jagielski    }
344*b1cdbd2cSJim Jagielski
345*b1cdbd2cSJim Jagielski    return ($originaluniqueparentname, $uniqueparentname);
346*b1cdbd2cSJim Jagielski}
347*b1cdbd2cSJim Jagielski
348*b1cdbd2cSJim Jagielski
349*b1cdbd2cSJim Jagielski
350*b1cdbd2cSJim Jagielski
351*b1cdbd2cSJim Jagielski##############################################################
352*b1cdbd2cSJim Jagielski# Adding unique directory names to the directory collection
353*b1cdbd2cSJim Jagielski##############################################################
354*b1cdbd2cSJim Jagielski
355*b1cdbd2cSJim Jagielskisub create_unique_directorynames ($)
356*b1cdbd2cSJim Jagielski{
357*b1cdbd2cSJim Jagielski	my ($directories) = @_;
358*b1cdbd2cSJim Jagielski
359*b1cdbd2cSJim Jagielski	$installer::globals::officeinstalldirectoryset = 0;
360*b1cdbd2cSJim Jagielski
361*b1cdbd2cSJim Jagielski    my %hostnamehash = ();
362*b1cdbd2cSJim Jagielski	my $infoline = "";
363*b1cdbd2cSJim Jagielski	my $errorcount = 0;
364*b1cdbd2cSJim Jagielski
365*b1cdbd2cSJim Jagielski	foreach my $directory (@$directories)
366*b1cdbd2cSJim Jagielski	{
367*b1cdbd2cSJim Jagielski        next if defined $directory->{'uniquename'};
368*b1cdbd2cSJim Jagielski
369*b1cdbd2cSJim Jagielski        my $styles = $directory->{'Styles'};
370*b1cdbd2cSJim Jagielski        $styles = "" unless defined $styles;
371*b1cdbd2cSJim Jagielski
372*b1cdbd2cSJim Jagielski		my ($originaluniquename, $uniquename) = get_unique_name(
373*b1cdbd2cSJim Jagielski            $directory->{'HostName'},
374*b1cdbd2cSJim Jagielski            \%hostnamehash);
375*b1cdbd2cSJim Jagielski
376*b1cdbd2cSJim Jagielski		my ($originaluniqueparentname, $uniqueparentname) = get_unique_parent_name(
377*b1cdbd2cSJim Jagielski            $originaluniquename,
378*b1cdbd2cSJim Jagielski            $styles);
379*b1cdbd2cSJim Jagielski
380*b1cdbd2cSJim Jagielski
381*b1cdbd2cSJim Jagielski		# Hyphen not allowed in database
382*b1cdbd2cSJim Jagielski		$uniquename =~ s/\-/\_/g;			# making "-" to "_"
383*b1cdbd2cSJim Jagielski		$uniqueparentname =~ s/\-/\_/g;		# making "-" to "_"
384*b1cdbd2cSJim Jagielski
385*b1cdbd2cSJim Jagielski		# And finally setting the values for the directories
386*b1cdbd2cSJim Jagielski		$directory->{'uniquename'} = $uniquename;
387*b1cdbd2cSJim Jagielski		$directory->{'uniqueparentname'} = $uniqueparentname;
388*b1cdbd2cSJim Jagielski		$directory->{'long_uniquename'} = $originaluniquename;
389*b1cdbd2cSJim Jagielski		$directory->{'long_uniqueparentname'} = $originaluniqueparentname;
390*b1cdbd2cSJim Jagielski    }
391*b1cdbd2cSJim Jagielski
392*b1cdbd2cSJim Jagielski    # Find the installation directory.
393*b1cdbd2cSJim Jagielski    foreach my $directory (@$directories)
394*b1cdbd2cSJim Jagielski    {
395*b1cdbd2cSJim Jagielski        next unless defined $directory->{'Styles'};
396*b1cdbd2cSJim Jagielski
397*b1cdbd2cSJim Jagielski		# setting the installlocation directory
398*b1cdbd2cSJim Jagielski		next unless $directory->{'Styles'} =~ /\bISINSTALLLOCATION\b/;
399*b1cdbd2cSJim Jagielski
400*b1cdbd2cSJim Jagielski        if ( $installer::globals::installlocationdirectoryset )
401*b1cdbd2cSJim Jagielski        {
402*b1cdbd2cSJim Jagielski            installer::exiter::exit_program(
403*b1cdbd2cSJim Jagielski                sprintf(
404*b1cdbd2cSJim Jagielski                    "ERROR: Directory with flag ISINSTALLLOCATION alread set: \"%s\".",
405*b1cdbd2cSJim Jagielski                    $installer::globals::installlocationdirectory),
406*b1cdbd2cSJim Jagielski                "create_unique_directorynames");
407*b1cdbd2cSJim Jagielski        }
408*b1cdbd2cSJim Jagielski
409*b1cdbd2cSJim Jagielski        $installer::globals::installlocationdirectory = $directory->{'uniquename'};
410*b1cdbd2cSJim Jagielski        $installer::globals::installlocationdirectoryset = 1;
411*b1cdbd2cSJim Jagielski    }
412*b1cdbd2cSJim Jagielski}
413*b1cdbd2cSJim Jagielski
414*b1cdbd2cSJim Jagielski
415*b1cdbd2cSJim Jagielski
416*b1cdbd2cSJim Jagielski
417*b1cdbd2cSJim Jagielski#####################################################
418*b1cdbd2cSJim Jagielski# Adding ":." to selected default directory names
419*b1cdbd2cSJim Jagielski#####################################################
420*b1cdbd2cSJim Jagielski
421*b1cdbd2cSJim Jagielskisub update_defaultdir ($$)
422*b1cdbd2cSJim Jagielski{
423*b1cdbd2cSJim Jagielski	my ( $onedir, $allvariableshashref ) = @_;
424*b1cdbd2cSJim Jagielski
425*b1cdbd2cSJim Jagielski	if ($installer::globals::addchildprojects
426*b1cdbd2cSJim Jagielski        || $installer::globals::patch
427*b1cdbd2cSJim Jagielski        || $installer::globals::languagepack
428*b1cdbd2cSJim Jagielski        || $allvariableshashref->{'CHANGETARGETDIR'})
429*b1cdbd2cSJim Jagielski	{
430*b1cdbd2cSJim Jagielski		my $sourcediraddon = "\:\.";
431*b1cdbd2cSJim Jagielski		return $onedir->{'defaultdir'} . $sourcediraddon;
432*b1cdbd2cSJim Jagielski	}
433*b1cdbd2cSJim Jagielski	else
434*b1cdbd2cSJim Jagielski    {
435*b1cdbd2cSJim Jagielski        return $onedir->{'defaultdir'};
436*b1cdbd2cSJim Jagielski    }
437*b1cdbd2cSJim Jagielski}
438*b1cdbd2cSJim Jagielski
439*b1cdbd2cSJim Jagielski#####################################################
440*b1cdbd2cSJim Jagielski# The directory with the style ISINSTALLLOCATION
441*b1cdbd2cSJim Jagielski# will be replaced by INSTALLLOCATION
442*b1cdbd2cSJim Jagielski#####################################################
443*b1cdbd2cSJim Jagielski
444*b1cdbd2cSJim Jagielskisub set_installlocation_directory
445*b1cdbd2cSJim Jagielski{
446*b1cdbd2cSJim Jagielski	my ( $directoryref, $allvariableshashref ) = @_;
447*b1cdbd2cSJim Jagielski
448*b1cdbd2cSJim Jagielski	if ( ! $installer::globals::installlocationdirectoryset )
449*b1cdbd2cSJim Jagielski    {
450*b1cdbd2cSJim Jagielski        installer::exiter::exit_program(
451*b1cdbd2cSJim Jagielski            "ERROR: Directory with flag ISINSTALLLOCATION not set!",
452*b1cdbd2cSJim Jagielski            "set_installlocation_directory");
453*b1cdbd2cSJim Jagielski    }
454*b1cdbd2cSJim Jagielski
455*b1cdbd2cSJim Jagielski	for ( my $i = 0; $i <= $#{$directoryref}; $i++ )
456*b1cdbd2cSJim Jagielski	{
457*b1cdbd2cSJim Jagielski		my $onedir = ${$directoryref}[$i];
458*b1cdbd2cSJim Jagielski
459*b1cdbd2cSJim Jagielski		if ( $onedir->{'uniquename'} eq $installer::globals::installlocationdirectory )
460*b1cdbd2cSJim Jagielski		{
461*b1cdbd2cSJim Jagielski			$onedir->{'uniquename'} = "INSTALLLOCATION";
462*b1cdbd2cSJim Jagielski			$onedir->{'defaultdir'} = update_defaultdir($onedir, $allvariableshashref);
463*b1cdbd2cSJim Jagielski		}
464*b1cdbd2cSJim Jagielski
465*b1cdbd2cSJim Jagielski		if ( $onedir->{'uniquename'} eq $installer::globals::vendordirectory )
466*b1cdbd2cSJim Jagielski		{
467*b1cdbd2cSJim Jagielski			$onedir->{'defaultdir'} = update_defaultdir($onedir, $allvariableshashref);
468*b1cdbd2cSJim Jagielski		}
469*b1cdbd2cSJim Jagielski
470*b1cdbd2cSJim Jagielski		if ( $onedir->{'uniqueparentname'} eq $installer::globals::installlocationdirectory )
471*b1cdbd2cSJim Jagielski		{
472*b1cdbd2cSJim Jagielski			$onedir->{'uniqueparentname'} = "INSTALLLOCATION";
473*b1cdbd2cSJim Jagielski		}
474*b1cdbd2cSJim Jagielski	}
475*b1cdbd2cSJim Jagielski}
476*b1cdbd2cSJim Jagielski
477*b1cdbd2cSJim Jagielski#####################################################
478*b1cdbd2cSJim Jagielski# Getting the name of the top level directory. This
479*b1cdbd2cSJim Jagielski# can have only one letter
480*b1cdbd2cSJim Jagielski#####################################################
481*b1cdbd2cSJim Jagielski
482*b1cdbd2cSJim Jagielskisub get_last_directory_name
483*b1cdbd2cSJim Jagielski{
484*b1cdbd2cSJim Jagielski	my ($completepathref) = @_;
485*b1cdbd2cSJim Jagielski
486*b1cdbd2cSJim Jagielski	if ( $$completepathref =~ /^.*[\/\\](.+?)\s*$/ )
487*b1cdbd2cSJim Jagielski	{
488*b1cdbd2cSJim Jagielski		$$completepathref = $1;
489*b1cdbd2cSJim Jagielski	}
490*b1cdbd2cSJim Jagielski}
491*b1cdbd2cSJim Jagielski
492*b1cdbd2cSJim Jagielskisub setup_global_font_directory_name ($)
493*b1cdbd2cSJim Jagielski{
494*b1cdbd2cSJim Jagielski	my ($directories) = @_;
495*b1cdbd2cSJim Jagielski
496*b1cdbd2cSJim Jagielski    $installer::logger::Info->printf("setup_global_font_directory_name, checking %d entries\n",
497*b1cdbd2cSJim Jagielski        scalar @$directories);
498*b1cdbd2cSJim Jagielski    $installer::logger::Info->printf(" fontsdirhostname is %s\n",
499*b1cdbd2cSJim Jagielski        $installer::globals::fontsdirhostname);
500*b1cdbd2cSJim Jagielski    $installer::logger::Info->printf(" fontsdirname is %s\n",
501*b1cdbd2cSJim Jagielski        $installer::globals::fontsdirname);
502*b1cdbd2cSJim Jagielski	foreach my $directory (@$directories)
503*b1cdbd2cSJim Jagielski	{
504*b1cdbd2cSJim Jagielski        next unless defined $directory->{'Dir'};
505*b1cdbd2cSJim Jagielski        next unless defined $directory->{'defaultdir'};
506*b1cdbd2cSJim Jagielski
507*b1cdbd2cSJim Jagielski        $installer::logger::Info->printf("    Dir is %s\n", $directory->{'Dir'});
508*b1cdbd2cSJim Jagielski        $installer::logger::Info->printf("    defaultdir is %s\n", $directory->{'defaultdir'});
509*b1cdbd2cSJim Jagielski        next if $directory->{'Dir'} ne "PREDEFINED_OSSYSTEMFONTDIR";
510*b1cdbd2cSJim Jagielski        next if $directory->{'defaultdir'} ne $installer::globals::fontsdirhostname;
511*b1cdbd2cSJim Jagielski
512*b1cdbd2cSJim Jagielski        $installer::globals::fontsdirname = $installer::globals::fontsdirhostname;
513*b1cdbd2cSJim Jagielski        $installer::globals::fontsdirparent = $directory->{'uniqueparentname'};
514*b1cdbd2cSJim Jagielski
515*b1cdbd2cSJim Jagielski        $installer::logger::Info->printf("%s, fdhn %s, dd %s, ipn %s, HN %s\n",
516*b1cdbd2cSJim Jagielski            "PREDEFINED_OSSYSTEMFONTDIR",
517*b1cdbd2cSJim Jagielski            $installer::globals::fontsdirhostname,
518*b1cdbd2cSJim Jagielski            $directory->{'defaultdir'},
519*b1cdbd2cSJim Jagielski            $directory->{'uniqueparentname'},
520*b1cdbd2cSJim Jagielski            $directory->{'HostName'});
521*b1cdbd2cSJim Jagielski        installer::scriptitems::print_script_item($directory);
522*b1cdbd2cSJim Jagielski	}
523*b1cdbd2cSJim Jagielski	foreach my $onedir (@$directories)
524*b1cdbd2cSJim Jagielski    {
525*b1cdbd2cSJim Jagielski    	my $fontdir = "";
526*b1cdbd2cSJim Jagielski		if ( $onedir->{'Dir'} ) { $fontdir = $onedir->{'Dir'}; }
527*b1cdbd2cSJim Jagielski
528*b1cdbd2cSJim Jagielski		my $fontdefaultdir = "";
529*b1cdbd2cSJim Jagielski		if ( $onedir->{'defaultdir'} ) { $fontdefaultdir = $onedir->{'defaultdir'}; }
530*b1cdbd2cSJim Jagielski
531*b1cdbd2cSJim Jagielski		if (( $fontdir eq "PREDEFINED_OSSYSTEMFONTDIR" ) && ( $fontdefaultdir eq $installer::globals::fontsdirhostname ))
532*b1cdbd2cSJim Jagielski		{
533*b1cdbd2cSJim Jagielski            $installer::logger::Info->printf("fontsdirname   = %s\n", $onedir->{'defaultdir'});
534*b1cdbd2cSJim Jagielski            $installer::logger::Info->printf("              is %s\n", $installer::globals::fontsdirname);
535*b1cdbd2cSJim Jagielski            $installer::logger::Info->printf("fontsdirparent = %s\n", $onedir->{'uniqueparentname'});
536*b1cdbd2cSJim Jagielski            $installer::logger::Info->printf("              is %s\n", $installer::globals::fontsdirparent);
537*b1cdbd2cSJim Jagielski		}
538*b1cdbd2cSJim Jagielski    }
539*b1cdbd2cSJim Jagielski}
540*b1cdbd2cSJim Jagielski
541*b1cdbd2cSJim Jagielski#####################################################
542*b1cdbd2cSJim Jagielski# Creating the defaultdir for the file Director.idt
543*b1cdbd2cSJim Jagielski#####################################################
544*b1cdbd2cSJim Jagielski
545*b1cdbd2cSJim Jagielskisub create_defaultdir_directorynames ($)
546*b1cdbd2cSJim Jagielski{
547*b1cdbd2cSJim Jagielski	my ($directoryref) = @_;
548*b1cdbd2cSJim Jagielski
549*b1cdbd2cSJim Jagielski	my @shortnames = ();
550*b1cdbd2cSJim Jagielski	if ( $installer::globals::prepare_winpatch ) { @shortnames = values(%installer::globals::saved83dirmapping); }
551*b1cdbd2cSJim Jagielski
552*b1cdbd2cSJim Jagielski	for ( my $i = 0; $i <= $#{$directoryref}; $i++ )
553*b1cdbd2cSJim Jagielski	{
554*b1cdbd2cSJim Jagielski		my $onedir = ${$directoryref}[$i];
555*b1cdbd2cSJim Jagielski		my $hostname = $onedir->{'HostName'};
556*b1cdbd2cSJim Jagielski
557*b1cdbd2cSJim Jagielski		$hostname =~ s/\Q$installer::globals::separator\E\s*$//;
558*b1cdbd2cSJim Jagielski		get_last_directory_name(\$hostname);
559*b1cdbd2cSJim Jagielski		# installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$hostname);	# making program/classes to classes
560*b1cdbd2cSJim Jagielski		my $uniquename = $onedir->{'uniquename'};
561*b1cdbd2cSJim Jagielski		my $shortstring;
562*b1cdbd2cSJim Jagielski		if (( $installer::globals::prepare_winpatch ) && ( exists($installer::globals::saved83dirmapping{$uniquename}) ))
563*b1cdbd2cSJim Jagielski		{
564*b1cdbd2cSJim Jagielski			$shortstring = $installer::globals::saved83dirmapping{$uniquename};
565*b1cdbd2cSJim Jagielski		}
566*b1cdbd2cSJim Jagielski		else
567*b1cdbd2cSJim Jagielski		{
568*b1cdbd2cSJim Jagielski			$shortstring = installer::windows::idtglobal::make_eight_three_conform($hostname, "dir", \@shortnames);
569*b1cdbd2cSJim Jagielski		}
570*b1cdbd2cSJim Jagielski
571*b1cdbd2cSJim Jagielski		my $defaultdir;
572*b1cdbd2cSJim Jagielski
573*b1cdbd2cSJim Jagielski		if ( $shortstring eq $hostname )
574*b1cdbd2cSJim Jagielski		{
575*b1cdbd2cSJim Jagielski			$defaultdir = $hostname;
576*b1cdbd2cSJim Jagielski		}
577*b1cdbd2cSJim Jagielski		else
578*b1cdbd2cSJim Jagielski		{
579*b1cdbd2cSJim Jagielski			$defaultdir = $shortstring . "|" . $hostname;
580*b1cdbd2cSJim Jagielski		}
581*b1cdbd2cSJim Jagielski
582*b1cdbd2cSJim Jagielski		$onedir->{'defaultdir'} = $defaultdir;
583*b1cdbd2cSJim Jagielski	}
584*b1cdbd2cSJim Jagielski}
585*b1cdbd2cSJim Jagielski
586*b1cdbd2cSJim Jagielski###############################################
587*b1cdbd2cSJim Jagielski# Fill content into the directory table
588*b1cdbd2cSJim Jagielski###############################################
589*b1cdbd2cSJim Jagielski
590*b1cdbd2cSJim Jagielskisub create_directorytable_from_collection ($$)
591*b1cdbd2cSJim Jagielski{
592*b1cdbd2cSJim Jagielski	my ($directorytableref, $directoryref) = @_;
593*b1cdbd2cSJim Jagielski
594*b1cdbd2cSJim Jagielski	foreach my $onedir (@$directoryref)
595*b1cdbd2cSJim Jagielski	{
596*b1cdbd2cSJim Jagielski        # Remove entries for special directories.
597*b1cdbd2cSJim Jagielski		if (defined $onedir->{'HostName'}
598*b1cdbd2cSJim Jagielski            && $onedir->{'HostName'} eq ""
599*b1cdbd2cSJim Jagielski            && defined $onedir->{'Dir'}
600*b1cdbd2cSJim Jagielski            && $onedir->{'Dir'} eq "PREDEFINED_PROGDIR")
601*b1cdbd2cSJim Jagielski        {
602*b1cdbd2cSJim Jagielski            next;
603*b1cdbd2cSJim Jagielski        }
604*b1cdbd2cSJim Jagielski
605*b1cdbd2cSJim Jagielski		my $oneline = sprintf(
606*b1cdbd2cSJim Jagielski            "%s\t%s\t%s\n",
607*b1cdbd2cSJim Jagielski            $onedir->{'uniquename'},
608*b1cdbd2cSJim Jagielski            $onedir->{'uniqueparentname'},
609*b1cdbd2cSJim Jagielski            $onedir->{'defaultdir'});
610*b1cdbd2cSJim Jagielski
611*b1cdbd2cSJim Jagielski		push @{$directorytableref}, $oneline;
612*b1cdbd2cSJim Jagielski	}
613*b1cdbd2cSJim Jagielski}
614*b1cdbd2cSJim Jagielski
615*b1cdbd2cSJim Jagielski###############################################
616*b1cdbd2cSJim Jagielski# Defining the root installation structure
617*b1cdbd2cSJim Jagielski###############################################
618*b1cdbd2cSJim Jagielski
619*b1cdbd2cSJim Jagielskisub process_root_directories ($$)
620*b1cdbd2cSJim Jagielski{
621*b1cdbd2cSJim Jagielski	my ($allvariableshashref, $functor) = @_;
622*b1cdbd2cSJim Jagielski
623*b1cdbd2cSJim Jagielski	my $oneline = "";
624*b1cdbd2cSJim Jagielski
625*b1cdbd2cSJim Jagielski	if (( ! $installer::globals::patch ) && ( ! $installer::globals::languagepack ) && ( ! $allvariableshashref->{'DONTUSESTARTMENUFOLDER'} ))
626*b1cdbd2cSJim Jagielski	{
627*b1cdbd2cSJim Jagielski		my $productname = $allvariableshashref->{'PRODUCTNAME'};
628*b1cdbd2cSJim Jagielski		my $productversion = $allvariableshashref->{'PRODUCTVERSION'};
629*b1cdbd2cSJim Jagielski		my $baseproductversion = $productversion;
630*b1cdbd2cSJim Jagielski
631*b1cdbd2cSJim Jagielski		if (( $installer::globals::prepare_winpatch ) && ( $allvariableshashref->{'BASEPRODUCTVERSION'} ))
632*b1cdbd2cSJim Jagielski		{
633*b1cdbd2cSJim Jagielski			$baseproductversion = $allvariableshashref->{'BASEPRODUCTVERSION'};  # for example "2.0" for OOo
634*b1cdbd2cSJim Jagielski		}
635*b1cdbd2cSJim Jagielski
636*b1cdbd2cSJim Jagielski		my $realproductkey = $productname . " " . $productversion;
637*b1cdbd2cSJim Jagielski		my $productkey = $productname . " " . $baseproductversion;
638*b1cdbd2cSJim Jagielski
639*b1cdbd2cSJim Jagielski		if (( $allvariableshashref->{'POSTVERSIONEXTENSION'} ) && ( ! $allvariableshashref->{'DONTUSEEXTENSIONINDEFAULTDIR'} ))
640*b1cdbd2cSJim Jagielski		{
641*b1cdbd2cSJim Jagielski			$productkey = $productkey . " " . $allvariableshashref->{'POSTVERSIONEXTENSION'};
642*b1cdbd2cSJim Jagielski			$realproductkey = $realproductkey . " " . $allvariableshashref->{'POSTVERSIONEXTENSION'};
643*b1cdbd2cSJim Jagielski		}
644*b1cdbd2cSJim Jagielski		if ( $allvariableshashref->{'NOSPACEINDIRECTORYNAME'} )
645*b1cdbd2cSJim Jagielski		{
646*b1cdbd2cSJim Jagielski			$productkey =~ s/\ /\_/g;
647*b1cdbd2cSJim Jagielski			$realproductkey =~ s/\ /\_/g;
648*b1cdbd2cSJim Jagielski		}
649*b1cdbd2cSJim Jagielski
650*b1cdbd2cSJim Jagielski		my $shortproductkey = installer::windows::idtglobal::make_eight_three_conform($productkey, "dir", undef);
651*b1cdbd2cSJim Jagielski		$shortproductkey =~ s/\s/\_/g;									# changing empty space to underline
652*b1cdbd2cSJim Jagielski
653*b1cdbd2cSJim Jagielski        &$functor(
654*b1cdbd2cSJim Jagielski            $installer::globals::officemenufolder,
655*b1cdbd2cSJim Jagielski            $installer::globals::programmenufolder,
656*b1cdbd2cSJim Jagielski            $shortproductkey . "|". $realproductkey);
657*b1cdbd2cSJim Jagielski	}
658*b1cdbd2cSJim Jagielski
659*b1cdbd2cSJim Jagielski	&$functor("TARGETDIR", "", "SourceDir");
660*b1cdbd2cSJim Jagielski	&$functor($installer::globals::programfilesfolder, "TARGETDIR", ".");
661*b1cdbd2cSJim Jagielski    &$functor($installer::globals::programmenufolder, "TARGETDIR", ".");
662*b1cdbd2cSJim Jagielski    &$functor($installer::globals::startupfolder, "TARGETDIR", ".");
663*b1cdbd2cSJim Jagielski	&$functor($installer::globals::desktopfolder, "TARGETDIR", ".");
664*b1cdbd2cSJim Jagielski	&$functor($installer::globals::startmenufolder, "TARGETDIR", ".");
665*b1cdbd2cSJim Jagielski	&$functor($installer::globals::commonfilesfolder, "TARGETDIR", ".");
666*b1cdbd2cSJim Jagielski	&$functor($installer::globals::commonappdatafolder, "TARGETDIR", ".");
667*b1cdbd2cSJim Jagielski	&$functor($installer::globals::localappdatafolder, "TARGETDIR", ".");
668*b1cdbd2cSJim Jagielski
669*b1cdbd2cSJim Jagielski	if ( $installer::globals::usesharepointpath )
670*b1cdbd2cSJim Jagielski	{
671*b1cdbd2cSJim Jagielski		&$functor("SHAREPOINTPATH", "TARGETDIR", ".");
672*b1cdbd2cSJim Jagielski	}
673*b1cdbd2cSJim Jagielski
674*b1cdbd2cSJim Jagielski	&$functor($installer::globals::systemfolder, "TARGETDIR", ".");
675*b1cdbd2cSJim Jagielski
676*b1cdbd2cSJim Jagielski	my $localtemplatefoldername = $installer::globals::templatefoldername;
677*b1cdbd2cSJim Jagielski	my $directorytableentry = $localtemplatefoldername;
678*b1cdbd2cSJim Jagielski	my $shorttemplatefoldername = installer::windows::idtglobal::make_eight_three_conform($localtemplatefoldername, "dir");
679*b1cdbd2cSJim Jagielski	if ( $shorttemplatefoldername ne $localtemplatefoldername )
680*b1cdbd2cSJim Jagielski    {
681*b1cdbd2cSJim Jagielski        $directorytableentry = $shorttemplatefoldername . "|" . $localtemplatefoldername;
682*b1cdbd2cSJim Jagielski    }
683*b1cdbd2cSJim Jagielski	&$functor($installer::globals::templatefolder, "TARGETDIR", $directorytableentry);
684*b1cdbd2cSJim Jagielski
685*b1cdbd2cSJim Jagielski    $installer::logger::Info->printf("process_root_directories: fontsdirname=%s, fontsfoldername=%s\n",
686*b1cdbd2cSJim Jagielski        $installer::globals::fontsdirname,
687*b1cdbd2cSJim Jagielski        $installer::globals::fontsfoldername);
688*b1cdbd2cSJim Jagielski	if ( $installer::globals::fontsdirname )
689*b1cdbd2cSJim Jagielski	{
690*b1cdbd2cSJim Jagielski		&$functor(
691*b1cdbd2cSJim Jagielski             $installer::globals::fontsfolder,
692*b1cdbd2cSJim Jagielski             $installer::globals::fontsdirparent,
693*b1cdbd2cSJim Jagielski             $installer::globals::fontsfoldername . ":" . $installer::globals::fontsdirname);
694*b1cdbd2cSJim Jagielski	}
695*b1cdbd2cSJim Jagielski	else
696*b1cdbd2cSJim Jagielski	{
697*b1cdbd2cSJim Jagielski		&$functor(
698*b1cdbd2cSJim Jagielski             $installer::globals::fontsfolder,
699*b1cdbd2cSJim Jagielski             "TARGETDIR",
700*b1cdbd2cSJim Jagielski             $installer::globals::fontsfoldername);
701*b1cdbd2cSJim Jagielski	}
702*b1cdbd2cSJim Jagielski}
703*b1cdbd2cSJim Jagielski
704*b1cdbd2cSJim Jagielski
705*b1cdbd2cSJim Jagielski
706*b1cdbd2cSJim Jagielski
707*b1cdbd2cSJim Jagielskisub find_missing_directories ($$)
708*b1cdbd2cSJim Jagielski{
709*b1cdbd2cSJim Jagielski    my ($directories, $allvariableshashref) = @_;
710*b1cdbd2cSJim Jagielski
711*b1cdbd2cSJim Jagielski    # Set up the list of target directories.
712*b1cdbd2cSJim Jagielski    my %target_directories = map {$_->{'uniquename'} => 1} @$directories;
713*b1cdbd2cSJim Jagielski    # Add special directories.
714*b1cdbd2cSJim Jagielski    process_root_directories(
715*b1cdbd2cSJim Jagielski        $allvariableshashref,
716*b1cdbd2cSJim Jagielski        sub($$$){
717*b1cdbd2cSJim Jagielski            my ($uniquename, $parentname, $defaultdir) = @_;
718*b1cdbd2cSJim Jagielski            $target_directories{$uniquename} = 1;
719*b1cdbd2cSJim Jagielski        }
720*b1cdbd2cSJim Jagielski    );
721*b1cdbd2cSJim Jagielski
722*b1cdbd2cSJim Jagielski    # Set up the list of source directories.
723*b1cdbd2cSJim Jagielski    my $source_directory_map = $installer::globals::source_msi->GetDirectoryMap();
724*b1cdbd2cSJim Jagielski    my $source_file_map = $installer::globals::source_msi->GetFileMap();
725*b1cdbd2cSJim Jagielski    my %source_directories = map {$_->{'unique_name'} => $_} values %$source_directory_map;
726*b1cdbd2cSJim Jagielski
727*b1cdbd2cSJim Jagielski    # Find the missing source directories.
728*b1cdbd2cSJim Jagielski    my @missing_directories = ();
729*b1cdbd2cSJim Jagielski    foreach my $source_uniquename (keys %source_directories)
730*b1cdbd2cSJim Jagielski    {
731*b1cdbd2cSJim Jagielski        if ( ! $target_directories{$source_uniquename})
732*b1cdbd2cSJim Jagielski        {
733*b1cdbd2cSJim Jagielski            push @missing_directories, $source_directories{$source_uniquename};
734*b1cdbd2cSJim Jagielski        }
735*b1cdbd2cSJim Jagielski    }
736*b1cdbd2cSJim Jagielski
737*b1cdbd2cSJim Jagielski    # Report the missing directories.
738*b1cdbd2cSJim Jagielski    $installer::logger::Info->printf("found %d missing directories\n", scalar @missing_directories);
739*b1cdbd2cSJim Jagielski    my $index = 0;
740*b1cdbd2cSJim Jagielski    foreach my $directory_item (@missing_directories)
741*b1cdbd2cSJim Jagielski    {
742*b1cdbd2cSJim Jagielski        # Print information about the directory.
743*b1cdbd2cSJim Jagielski        $installer::logger::Info->printf("missing directory %d: %s\n",
744*b1cdbd2cSJim Jagielski            ++$index,
745*b1cdbd2cSJim Jagielski            $directory_item->{'full_target_long_name'});
746*b1cdbd2cSJim Jagielski        while (my($key,$value) = each %$directory_item)
747*b1cdbd2cSJim Jagielski        {
748*b1cdbd2cSJim Jagielski            $installer::logger::Info->printf("    %s -> %s\n", $key, $value);
749*b1cdbd2cSJim Jagielski        }
750*b1cdbd2cSJim Jagielski
751*b1cdbd2cSJim Jagielski        # Print the referencing files.
752*b1cdbd2cSJim Jagielski        my @filenames = ();
753*b1cdbd2cSJim Jagielski        while (my ($key,$value) = each %$source_file_map)
754*b1cdbd2cSJim Jagielski        {
755*b1cdbd2cSJim Jagielski            if ($value->{'directory'}->{'unique_name'} eq $directory_item->{'unique_name'})
756*b1cdbd2cSJim Jagielski            {
757*b1cdbd2cSJim Jagielski                push @filenames, $key;
758*b1cdbd2cSJim Jagielski            }
759*b1cdbd2cSJim Jagielski        }
760*b1cdbd2cSJim Jagielski        $installer::logger::Info->printf("  referencing files are %s\n", join(", ", @filenames));
761*b1cdbd2cSJim Jagielski    }
762*b1cdbd2cSJim Jagielski
763*b1cdbd2cSJim Jagielski    foreach my $directory (@$directories)
764*b1cdbd2cSJim Jagielski    {
765*b1cdbd2cSJim Jagielski        $installer::logger::Lang->printf("target directory %s -> HN %s\n",
766*b1cdbd2cSJim Jagielski            $directory->{'uniquename'},
767*b1cdbd2cSJim Jagielski            $directory->{'HostName'});
768*b1cdbd2cSJim Jagielski        installer::scriptitems::print_script_item($directory);
769*b1cdbd2cSJim Jagielski    }
770*b1cdbd2cSJim Jagielski
771*b1cdbd2cSJim Jagielski    # Setup a map of directory uniquenames to verify that the new
772*b1cdbd2cSJim Jagielski    # entries don't use unique names that are already in use.
773*b1cdbd2cSJim Jagielski    my %unique_names = map {$_->{'uniquename'} => $_} @$directories;
774*b1cdbd2cSJim Jagielski
775*b1cdbd2cSJim Jagielski    # Create script items for the missing directories.
776*b1cdbd2cSJim Jagielski    my @new_source_directories = ();
777*b1cdbd2cSJim Jagielski    foreach my $source_directory_item (@missing_directories)
778*b1cdbd2cSJim Jagielski    {
779*b1cdbd2cSJim Jagielski        my $new_directory_item = {
780*b1cdbd2cSJim Jagielski            'uniquename' => $source_directory_item->{'unique_name'},
781*b1cdbd2cSJim Jagielski            'uniqueparentname' => $source_directory_item->{'parent_name'},
782*b1cdbd2cSJim Jagielski            'defaultdir' => $source_directory_item->{'default_dir'},
783*b1cdbd2cSJim Jagielski            'HostName' => $source_directory_item->{'full_target_long_name'},
784*b1cdbd2cSJim Jagielski            'componentname' => $source_directory_item->{'component_name'},
785*b1cdbd2cSJim Jagielski        };
786*b1cdbd2cSJim Jagielski
787*b1cdbd2cSJim Jagielski        if (defined $unique_names{$new_directory_item->{'uniquename'}})
788*b1cdbd2cSJim Jagielski        {
789*b1cdbd2cSJim Jagielski            installer::logger::PrintError("newly created directory entry collides with existing directory");
790*b1cdbd2cSJim Jagielski            last;
791*b1cdbd2cSJim Jagielski        }
792*b1cdbd2cSJim Jagielski
793*b1cdbd2cSJim Jagielski        push @new_source_directories, $new_directory_item;
794*b1cdbd2cSJim Jagielski    }
795*b1cdbd2cSJim Jagielski
796*b1cdbd2cSJim Jagielski    return @new_source_directories;
797*b1cdbd2cSJim Jagielski}
798*b1cdbd2cSJim Jagielski
799*b1cdbd2cSJim Jagielski
800*b1cdbd2cSJim Jagielski
801*b1cdbd2cSJim Jagielski
802*b1cdbd2cSJim Jagielskisub prepare_directory_table_creation ($$)
803*b1cdbd2cSJim Jagielski{
804*b1cdbd2cSJim Jagielski	my ($directories, $allvariableshashref) = @_;
805*b1cdbd2cSJim Jagielski
806*b1cdbd2cSJim Jagielski    foreach my $directory (@$directories)
807*b1cdbd2cSJim Jagielski    {
808*b1cdbd2cSJim Jagielski        delete $directory->{'uniquename'};
809*b1cdbd2cSJim Jagielski    }
810*b1cdbd2cSJim Jagielski
811*b1cdbd2cSJim Jagielski	overwrite_programfilesfolder($allvariableshashref);
812*b1cdbd2cSJim Jagielski	create_unique_directorynames($directories);
813*b1cdbd2cSJim Jagielski    check_unique_directorynames($directories);
814*b1cdbd2cSJim Jagielski	create_defaultdir_directorynames($directories);	# only destdir!
815*b1cdbd2cSJim Jagielski    setup_global_font_directory_name($directories);
816*b1cdbd2cSJim Jagielski	set_installlocation_directory($directories, $allvariableshashref);
817*b1cdbd2cSJim Jagielski
818*b1cdbd2cSJim Jagielski    if ($installer::globals::is_release)
819*b1cdbd2cSJim Jagielski    {
820*b1cdbd2cSJim Jagielski        my @new_directories = find_missing_directories($directories, $allvariableshashref);
821*b1cdbd2cSJim Jagielski        push @$directories, @new_directories;
822*b1cdbd2cSJim Jagielski    }
823*b1cdbd2cSJim Jagielski}
824*b1cdbd2cSJim Jagielski
825*b1cdbd2cSJim Jagielski
826*b1cdbd2cSJim Jagielski
827*b1cdbd2cSJim Jagielski
828*b1cdbd2cSJim Jagielski###############################################
829*b1cdbd2cSJim Jagielski# Creating the file Director.idt dynamically
830*b1cdbd2cSJim Jagielski###############################################
831*b1cdbd2cSJim Jagielski
832*b1cdbd2cSJim Jagielskisub create_directory_table ($$$)
833*b1cdbd2cSJim Jagielski{
834*b1cdbd2cSJim Jagielski	my ($directoryref, $basedir, $allvariableshashref) = @_;
835*b1cdbd2cSJim Jagielski
836*b1cdbd2cSJim Jagielski	# Structure of the directory table:
837*b1cdbd2cSJim Jagielski	# Directory Directory_Parent DefaultDir
838*b1cdbd2cSJim Jagielski	# Directory is a unique identifier
839*b1cdbd2cSJim Jagielski	# Directory_Parent is the unique identifier of the parent
840*b1cdbd2cSJim Jagielski	# DefaultDir is .:APPLIC~1|Application Data with
841*b1cdbd2cSJim Jagielski	# Before ":" : [sourcedir]:[destdir] (not programmed yet)
842*b1cdbd2cSJim Jagielski	# After ":" : 8+3 and not 8+3 the destination directory name
843*b1cdbd2cSJim Jagielski
844*b1cdbd2cSJim Jagielski	$installer::logger::Lang->add_timestamp("Performance Info: Directory Table start");
845*b1cdbd2cSJim Jagielski
846*b1cdbd2cSJim Jagielski	my @directorytable = ();
847*b1cdbd2cSJim Jagielski	installer::windows::idtglobal::write_idt_header(\@directorytable, "directory");
848*b1cdbd2cSJim Jagielski
849*b1cdbd2cSJim Jagielski    # Add entries for the root directories (and a few special directories like that for fonts).
850*b1cdbd2cSJim Jagielski    process_root_directories(
851*b1cdbd2cSJim Jagielski        $allvariableshashref,
852*b1cdbd2cSJim Jagielski        sub($$$){
853*b1cdbd2cSJim Jagielski            push(@directorytable, join("\t", @_)."\n");
854*b1cdbd2cSJim Jagielski        }
855*b1cdbd2cSJim Jagielski    );
856*b1cdbd2cSJim Jagielski
857*b1cdbd2cSJim Jagielski    # Add entries for the non-root directories.
858*b1cdbd2cSJim Jagielski	create_directorytable_from_collection(\@directorytable, $directoryref);
859*b1cdbd2cSJim Jagielski
860*b1cdbd2cSJim Jagielski	# Saving the file
861*b1cdbd2cSJim Jagielski
862*b1cdbd2cSJim Jagielski	my $directorytablename = $basedir . $installer::globals::separator . "Director.idt";
863*b1cdbd2cSJim Jagielski	installer::files::save_file($directorytablename ,\@directorytable);
864*b1cdbd2cSJim Jagielski    $installer::logger::Lang->printf("Created idt file: %s\n", $directorytablename);
865*b1cdbd2cSJim Jagielski
866*b1cdbd2cSJim Jagielski	$installer::logger::Lang->add_timestamp("Performance Info: Directory Table end");
867*b1cdbd2cSJim Jagielski}
868*b1cdbd2cSJim Jagielski
869*b1cdbd2cSJim Jagielski
870*b1cdbd2cSJim Jagielski1;
871