19780544fSAndrew Rist#**************************************************************
29780544fSAndrew Rist#
39780544fSAndrew Rist#  Licensed to the Apache Software Foundation (ASF) under one
49780544fSAndrew Rist#  or more contributor license agreements.  See the NOTICE file
59780544fSAndrew Rist#  distributed with this work for additional information
69780544fSAndrew Rist#  regarding copyright ownership.  The ASF licenses this file
79780544fSAndrew Rist#  to you under the Apache License, Version 2.0 (the
89780544fSAndrew Rist#  "License"); you may not use this file except in compliance
99780544fSAndrew Rist#  with the License.  You may obtain a copy of the License at
109780544fSAndrew Rist#
119780544fSAndrew Rist#    http://www.apache.org/licenses/LICENSE-2.0
129780544fSAndrew Rist#
139780544fSAndrew Rist#  Unless required by applicable law or agreed to in writing,
149780544fSAndrew Rist#  software distributed under the License is distributed on an
159780544fSAndrew Rist#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169780544fSAndrew Rist#  KIND, either express or implied.  See the License for the
179780544fSAndrew Rist#  specific language governing permissions and limitations
189780544fSAndrew Rist#  under the License.
199780544fSAndrew Rist#
209780544fSAndrew Rist#**************************************************************
219780544fSAndrew Rist
229780544fSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweirpackage installer::windows::directory;
25cdf0e10cSrcweir
26cdf0e10cSrcweiruse installer::exiter;
27cdf0e10cSrcweiruse installer::files;
28cdf0e10cSrcweiruse installer::globals;
29cdf0e10cSrcweiruse installer::pathanalyzer;
30cdf0e10cSrcweiruse installer::windows::idtglobal;
3119d58b3aSEike Rathkeuse installer::windows::msiglobal;
329f91b7e3SAndre Fischeruse installer::scriptitems;
33cdf0e10cSrcweir
341ba1fd99SAndre Fischeruse strict;
351ba1fd99SAndre Fischer
36cdf0e10cSrcweir##############################################################
37cdf0e10cSrcweir# Collecting all directory trees in global hash
38cdf0e10cSrcweir##############################################################
39cdf0e10cSrcweir
40cdf0e10cSrcweirsub collectdirectorytrees
41cdf0e10cSrcweir{
42cdf0e10cSrcweir	my ( $directoryref ) = @_;
43cdf0e10cSrcweir
44cdf0e10cSrcweir	for ( my $i = 0; $i <= $#{$directoryref}; $i++ )
45cdf0e10cSrcweir	{
46cdf0e10cSrcweir		my $onedir = ${$directoryref}[$i];
47cdf0e10cSrcweir		my $styles = "";
48cdf0e10cSrcweir		if ( $onedir->{'Styles'} ) { $styles = $onedir->{'Styles'}; }
49cdf0e10cSrcweir
50cdf0e10cSrcweir		if ( $styles ne "" )
51cdf0e10cSrcweir		{
52cdf0e10cSrcweir			foreach my $treestyle ( keys %installer::globals::treestyles )
53cdf0e10cSrcweir			{
54cdf0e10cSrcweir				if ( $styles =~ /\b$treestyle\b/ )
55cdf0e10cSrcweir				{
56cdf0e10cSrcweir					my $hostname = $onedir->{'HostName'};
57cdf0e10cSrcweir					# -> hostname is the key, the style the value!
58cdf0e10cSrcweir					$installer::globals::hostnametreestyles{$hostname} = $treestyle;
59cdf0e10cSrcweir				}
60cdf0e10cSrcweir			}
61cdf0e10cSrcweir		}
62cdf0e10cSrcweir	}
63cdf0e10cSrcweir}
64cdf0e10cSrcweir
65cdf0e10cSrcweir##############################################################
66cdf0e10cSrcweir# Overwriting global programfilesfolder, if required
67cdf0e10cSrcweir##############################################################
68cdf0e10cSrcweir
69cdf0e10cSrcweirsub overwrite_programfilesfolder
70cdf0e10cSrcweir{
71cdf0e10cSrcweir	my ( $allvariables ) = @_;
72cdf0e10cSrcweir
73cdf0e10cSrcweir	if ( $allvariables->{'PROGRAMFILESFOLDERNAME'} )
74cdf0e10cSrcweir	{
75cdf0e10cSrcweir		$installer::globals::programfilesfolder = $allvariables->{'PROGRAMFILESFOLDERNAME'};
76cdf0e10cSrcweir	}
77cdf0e10cSrcweir}
78cdf0e10cSrcweir
79cdf0e10cSrcweir
801ba1fd99SAndre Fischer
811ba1fd99SAndre Fischer
821ba1fd99SAndre Fischer=head2 make_short_dir_version($longstring)
831ba1fd99SAndre Fischer
841ba1fd99SAndre Fischer    Transform the given string into one that is at most 70 characters long.
851ba1fd99SAndre Fischer    That is done in two steps:
861ba1fd99SAndre Fischer    - Cut all parts separated by '_' or '-' down to a length of 5.
871ba1fd99SAndre Fischer    - Cut down the result to a length of 60 and fill it up to length 70
881ba1fd99SAndre Fischer      with the MD5 checksum.
891ba1fd99SAndre Fischer
901ba1fd99SAndre Fischer    This transform always returns the same result for the same string.
911ba1fd99SAndre Fischer    There is no counter and reference to a global set of names to make the string unique.
921ba1fd99SAndre Fischer
931ba1fd99SAndre Fischer=cut
941ba1fd99SAndre Fischersub make_short_dir_version ($)
95cdf0e10cSrcweir{
9619d58b3aSEike Rathke	my ($longstring) = @_;
97cdf0e10cSrcweir
98cdf0e10cSrcweir	my $shortstring = "";
9919d58b3aSEike Rathke	my $cutlength = 60;
10019d58b3aSEike Rathke	my $length = 5; # So the directory can still be recognized
10119d58b3aSEike Rathke	my $longstring_save = $longstring;
102cdf0e10cSrcweir
103cdf0e10cSrcweir	# Splitting the string at each "underline" and allowing only $length characters per directory name.
104cdf0e10cSrcweir	# Checking also uniqueness and length.
105cdf0e10cSrcweir
1061ba1fd99SAndre Fischer	my @outer_parts = split(/_/, $longstring);
1071ba1fd99SAndre Fischer	foreach my $onestring (@outer_parts)
108cdf0e10cSrcweir	{
109cdf0e10cSrcweir		my $partstring = "";
110cdf0e10cSrcweir
111cdf0e10cSrcweir		if ( $onestring =~ /\-/ )
112cdf0e10cSrcweir		{
1131ba1fd99SAndre Fischer			my @inner_parts = split(/-/, $onestring);
1141ba1fd99SAndre Fischer            @inner_parts = map {substr($_,0,$length)} @inner_parts;
1151ba1fd99SAndre Fischer            $partstring = join("-", @inner_parts);
116cdf0e10cSrcweir			$partstring =~ s/^\s*\-//;
117cdf0e10cSrcweir		}
118cdf0e10cSrcweir		else
119cdf0e10cSrcweir		{
1201ba1fd99SAndre Fischer			$partstring = substr($onestring, 0, $length);
121cdf0e10cSrcweir		}
122cdf0e10cSrcweir
1231ba1fd99SAndre Fischer		$shortstring .= "_" . $partstring;
124cdf0e10cSrcweir	}
125cdf0e10cSrcweir
126cdf0e10cSrcweir	$shortstring =~ s/^\s*\_//;
127cdf0e10cSrcweir
12819d58b3aSEike Rathke	# Setting unique ID to each directory
12919d58b3aSEike Rathke	# No counter allowed, process must be absolute reproducable due to patch creation process.
13019d58b3aSEike Rathke
13119d58b3aSEike Rathke	my $subid = installer::windows::msiglobal::calculate_id($longstring_save, 9); # taking only the first 9 digits
1321ba1fd99SAndre Fischer	$shortstring = substr($shortstring, 0, $cutlength) . "_" . $subid;
133cdf0e10cSrcweir
134cdf0e10cSrcweir	return $shortstring;
135cdf0e10cSrcweir}
136cdf0e10cSrcweir
137cdf0e10cSrcweir
1389f91b7e3SAndre Fischer
1399f91b7e3SAndre Fischer
1409f91b7e3SAndre Fischer=head2 get_unique_name ($hostname, $unique_map, $shortdirhash, $shortdirhashreverse)
1419f91b7e3SAndre Fischer
1429f91b7e3SAndre Fischer    Return a long and a short unique name for the given $hostname.
1439f91b7e3SAndre Fischer    Despite the function name and unlike the generation of unique
1449f91b7e3SAndre Fischer    names for files, the returned names are not really unique.  Quite
1459f91b7e3SAndre Fischer    the opposite.  The returned names are quaranteed to return the
1469f91b7e3SAndre Fischer    same result for the same input.
1479f91b7e3SAndre Fischer
1489f91b7e3SAndre Fischer    The returned short name has at most length 70.
1499f91b7e3SAndre Fischer
1509f91b7e3SAndre Fischer=cut
1519f91b7e3SAndre Fischersub get_unique_name ($$)
152cdf0e10cSrcweir{
1539f91b7e3SAndre Fischer    my ($hostname, $hostnamehash) = @_;
1549f91b7e3SAndre Fischer
1559f91b7e3SAndre Fischer    # Make sure that we where not called for this hostname before.  Otherwise the other test would be triggered.
1569f91b7e3SAndre Fischer    if (defined $hostnamehash->{$hostname})
1579f91b7e3SAndre Fischer    {
1589f91b7e3SAndre Fischer        installer::exiter::exit_program(
1599f91b7e3SAndre Fischer            "ERROR: get_unique_name was already called for hostname ".$hostname,
1609f91b7e3SAndre Fischer            "get_unique_name");
1619f91b7e3SAndre Fischer    }
1629f91b7e3SAndre Fischer    $hostnamehash->{$hostname} = 1;
1639f91b7e3SAndre Fischer
1649f91b7e3SAndre Fischer    my $uniquename = $hostname;
1659f91b7e3SAndre Fischer
1669f91b7e3SAndre Fischer    $uniquename =~ s/^\s*//g;				# removing beginning white spaces
1679f91b7e3SAndre Fischer    $uniquename =~ s/\s*$//g;				# removing ending white spaces
1689f91b7e3SAndre Fischer    $uniquename =~ s/\s//g;					# removing white spaces
1699f91b7e3SAndre Fischer    $uniquename =~ s/\_//g;					# removing existing underlines
1709f91b7e3SAndre Fischer    $uniquename =~ s/\.//g;					# removing dots in directoryname
1719f91b7e3SAndre Fischer    $uniquename =~ s/OpenOffice/OO/g;
1729f91b7e3SAndre Fischer
1739f91b7e3SAndre Fischer    $uniquename =~ s/\Q$installer::globals::separator\E/\_/g;	# replacing slash and backslash with underline
1749f91b7e3SAndre Fischer
1759f91b7e3SAndre Fischer    $uniquename =~ s/_registry/_rgy/g;
1769f91b7e3SAndre Fischer    $uniquename =~ s/_registration/_rgn/g;
1779f91b7e3SAndre Fischer    $uniquename =~ s/_extension/_ext/g;
1789f91b7e3SAndre Fischer    $uniquename =~ s/_frame/_frm/g;
1799f91b7e3SAndre Fischer    $uniquename =~ s/_table/_tbl/g;
1809f91b7e3SAndre Fischer    $uniquename =~ s/_chart/_crt/g;
181cdf0e10cSrcweir
1829f91b7e3SAndre Fischer    my $short_uniquename = make_short_dir_version($uniquename);
1839f91b7e3SAndre Fischer
1849f91b7e3SAndre Fischer    return ($uniquename, $short_uniquename);
1859f91b7e3SAndre Fischer}
18619d58b3aSEike Rathke
187cdf0e10cSrcweir
188cdf0e10cSrcweir
189cdf0e10cSrcweir
1909f91b7e3SAndre Fischer=head2 check_unique_directorynames($directories)
1919f91b7e3SAndre Fischer
1929f91b7e3SAndre Fischer    The one really important check is made in get_unique_name().  It
1939f91b7e3SAndre Fischer    checks that get_unique_name() is not called twice for the same
1949f91b7e3SAndre Fischer    directory host name.  The tests in this function contain the
1959f91b7e3SAndre Fischer    legacy tests that basically only check if there where a collision
1969f91b7e3SAndre Fischer    of the partial MD5 sum that is used to make the short unique names
1979f91b7e3SAndre Fischer    unique.
1989f91b7e3SAndre Fischer
1999f91b7e3SAndre Fischer    The maps $unique_map, $shortdirhash, $shortdirhashreverse are used
2009f91b7e3SAndre Fischer    only to check that _different_ input names are mapped to different
2019f91b7e3SAndre Fischer    results.  They are not used to influence the result.  That assumes
2029f91b7e3SAndre Fischer    that this function is called only once for every directory
2039f91b7e3SAndre Fischer    hostname.
2049f91b7e3SAndre Fischer=cut
2059f91b7e3SAndre Fischersub check_unique_directorynames ($)
2069f91b7e3SAndre Fischer{
2079f91b7e3SAndre Fischer    my ($directories) = @_;
2089f91b7e3SAndre Fischer
2099f91b7e3SAndre Fischer    my %completedirhashstep1 = ();
2109f91b7e3SAndre Fischer	my %shortdirhash = ();
2119f91b7e3SAndre Fischer	my %shortdirhashreverse = ();
21219d58b3aSEike Rathke
2139f91b7e3SAndre Fischer    # Check unique name of directories.
2149f91b7e3SAndre Fischer    foreach my $directory (@$directories)
2159f91b7e3SAndre Fischer    {
2169f91b7e3SAndre Fischer        my ($long_uniquename, $short_uniquename) = ($directory->{'long_uniquename'}, $directory->{'uniquename'});
2179f91b7e3SAndre Fischer
2189f91b7e3SAndre Fischer        # The names after this small changes must still be unique!
2199f91b7e3SAndre Fischer        if (exists($completedirhashstep1{$long_uniquename}))
2209f91b7e3SAndre Fischer        {
2219f91b7e3SAndre Fischer            installer::exiter::exit_program(
2229f91b7e3SAndre Fischer                sprintf("ERROR: Unallowed modification of directory name, not unique (step 1): \"%s\".",
2239f91b7e3SAndre Fischer                    $short_uniquename),
2249f91b7e3SAndre Fischer                "check_unique_directorynames");
2259f91b7e3SAndre Fischer        }
2269f91b7e3SAndre Fischer        $completedirhashstep1{$long_uniquename} = 1;
2279f91b7e3SAndre Fischer
2289f91b7e3SAndre Fischer
2299f91b7e3SAndre Fischer        # Checking if the same directory already exists, but has another short version.
2309f91b7e3SAndre Fischer        if (exists($shortdirhash{$long_uniquename})
2319f91b7e3SAndre Fischer            && ( $shortdirhash{$long_uniquename} ne $short_uniquename ))
2329f91b7e3SAndre Fischer        {
2339f91b7e3SAndre Fischer            installer::exiter::exit_program(
2349f91b7e3SAndre Fischer                sprintf(
2359f91b7e3SAndre Fischer                    "ERROR: Unallowed modification of directory name, not unique (step 2A): \"%s\".",
2369f91b7e3SAndre Fischer                    $short_uniquename),
2379f91b7e3SAndre Fischer                "check_unique_directorynames");
2389f91b7e3SAndre Fischer        }
2399f91b7e3SAndre Fischer        $shortdirhash{$long_uniquename} = $short_uniquename;
2409f91b7e3SAndre Fischer
2419f91b7e3SAndre Fischer        # Also checking vice versa
2429f91b7e3SAndre Fischer        # Checking if the same short directory already exists, but has another long version.
2439f91b7e3SAndre Fischer        if (exists($shortdirhashreverse{$short_uniquename})
2449f91b7e3SAndre Fischer            && ( $shortdirhashreverse{$short_uniquename} ne $long_uniquename ))
2459f91b7e3SAndre Fischer        {
2469f91b7e3SAndre Fischer            installer::exiter::exit_program(
2479f91b7e3SAndre Fischer                sprintf(
2489f91b7e3SAndre Fischer                    "ERROR: Unallowed modification of directory name, not unique (step 2B): \"%s\".",
2499f91b7e3SAndre Fischer                    $short_uniquename),
2509f91b7e3SAndre Fischer                "check_unique_directorynames");
2519f91b7e3SAndre Fischer        }
2529f91b7e3SAndre Fischer        $shortdirhashreverse{$short_uniquename} = $long_uniquename;
2539f91b7e3SAndre Fischer    }
2549f91b7e3SAndre Fischer
2559f91b7e3SAndre Fischer    # Check unique name of parents
2569f91b7e3SAndre Fischer    foreach my $directory (@$directories)
2579f91b7e3SAndre Fischer    {
2589f91b7e3SAndre Fischer        my ($long_uniquename, $short_uniquename)
2599f91b7e3SAndre Fischer            = ($directory->{'long_uniqueparentname'}, $directory->{'uniqueparentname'});
2609f91b7e3SAndre Fischer
2619f91b7e3SAndre Fischer        # Again checking if the same directory already exists, but has another short version.
2629f91b7e3SAndre Fischer        if (exists($shortdirhash{$long_uniquename})
2639f91b7e3SAndre Fischer            && ( $shortdirhash{$long_uniquename} ne $short_uniquename ))
2649f91b7e3SAndre Fischer        {
2659f91b7e3SAndre Fischer            installer::exiter::exit_program(
2669f91b7e3SAndre Fischer                sprintf(
2679f91b7e3SAndre Fischer                    "ERROR: Unallowed modification of directory name, not unique (step 3A): \"%s\".",
2689f91b7e3SAndre Fischer                    $short_uniquename),
2699f91b7e3SAndre Fischer                "check_unique_directorynames");
2709f91b7e3SAndre Fischer        }
2719f91b7e3SAndre Fischer        $shortdirhash{$long_uniquename} = $short_uniquename;
2729f91b7e3SAndre Fischer
2739f91b7e3SAndre Fischer        # Also checking vice versa
2749f91b7e3SAndre Fischer        # Checking if the same short directory already exists, but has another long version.
2759f91b7e3SAndre Fischer        if (exists($shortdirhashreverse{$short_uniquename})
2769f91b7e3SAndre Fischer            && ( $shortdirhashreverse{$short_uniquename} ne $long_uniquename ))
2779f91b7e3SAndre Fischer        {
2789f91b7e3SAndre Fischer            installer::exiter::exit_program(
2799f91b7e3SAndre Fischer                sprintf(
2809f91b7e3SAndre Fischer                    "ERROR: Unallowed modification of directory name, not unique (step 3B): \"%s\".",
2819f91b7e3SAndre Fischer                    $short_uniquename),
2829f91b7e3SAndre Fischer                "check_unique_directorynames");
2839f91b7e3SAndre Fischer        }
2849f91b7e3SAndre Fischer        $shortdirhashreverse{$short_uniquename} = $long_uniquename;
2859f91b7e3SAndre Fischer    }
2869f91b7e3SAndre Fischer}
28719d58b3aSEike Rathke
288cdf0e10cSrcweir
289cdf0e10cSrcweir
29019d58b3aSEike Rathke
2919f91b7e3SAndre Fischersub get_unique_parent_name ($$)
2929f91b7e3SAndre Fischer{
2939f91b7e3SAndre Fischer    my ($uniqueparentname, $styles) = @_;
2949f91b7e3SAndre Fischer
2959f91b7e3SAndre Fischer    my $keepparent = 1;
2969f91b7e3SAndre Fischer
2979f91b7e3SAndre Fischer    if ( $uniqueparentname =~ /^\s*(.*)\_(.*?)\s*$/ )	# the underline is now the separator
2989f91b7e3SAndre Fischer    {
2999f91b7e3SAndre Fischer        $uniqueparentname = $1;
3009f91b7e3SAndre Fischer        $keepparent = 0;
3019f91b7e3SAndre Fischer    }
3029f91b7e3SAndre Fischer    else
3039f91b7e3SAndre Fischer    {
3049f91b7e3SAndre Fischer        $uniqueparentname = $installer::globals::programfilesfolder;
3059f91b7e3SAndre Fischer        $keepparent = 1;
3069f91b7e3SAndre Fischer    }
3079f91b7e3SAndre Fischer
3089f91b7e3SAndre Fischer    if ( $styles =~ /\bPROGRAMFILESFOLDER\b/ )
3099f91b7e3SAndre Fischer    {
3109f91b7e3SAndre Fischer        $uniqueparentname = $installer::globals::programfilesfolder;
3119f91b7e3SAndre Fischer        $keepparent = 1;
3129f91b7e3SAndre Fischer    }
3139f91b7e3SAndre Fischer    if ( $styles =~ /\bCOMMONFILESFOLDER\b/ )
3149f91b7e3SAndre Fischer    {
3159f91b7e3SAndre Fischer        $uniqueparentname = $installer::globals::commonfilesfolder;
3169f91b7e3SAndre Fischer        $keepparent = 1;
3179f91b7e3SAndre Fischer    }
3189f91b7e3SAndre Fischer    if ( $styles =~ /\bCOMMONAPPDATAFOLDER\b/ )
3199f91b7e3SAndre Fischer    {
3209f91b7e3SAndre Fischer        $uniqueparentname = $installer::globals::commonappdatafolder;
3219f91b7e3SAndre Fischer        $keepparent = 1;
3229f91b7e3SAndre Fischer    }
3239f91b7e3SAndre Fischer    if ( $styles =~ /\bLOCALAPPDATAFOLDER\b/ )
3249f91b7e3SAndre Fischer    {
3259f91b7e3SAndre Fischer        $uniqueparentname = $installer::globals::localappdatafolder;
3269f91b7e3SAndre Fischer        $keepparent = 1;
3279f91b7e3SAndre Fischer    }
3289f91b7e3SAndre Fischer
3299f91b7e3SAndre Fischer    if ( $styles =~ /\bSHAREPOINTPATH\b/ )
3309f91b7e3SAndre Fischer    {
3319f91b7e3SAndre Fischer        $uniqueparentname = "SHAREPOINTPATH";
3329f91b7e3SAndre Fischer        $installer::globals::usesharepointpath = 1;
3339f91b7e3SAndre Fischer        $keepparent = 1;
3349f91b7e3SAndre Fischer    }
3359f91b7e3SAndre Fischer
3369f91b7e3SAndre Fischer    # also setting short directory name for the parent
3379f91b7e3SAndre Fischer
3389f91b7e3SAndre Fischer    my $originaluniqueparentname = $uniqueparentname;
33919d58b3aSEike Rathke
3409f91b7e3SAndre Fischer    if ( ! $keepparent )
3419f91b7e3SAndre Fischer    {
3429f91b7e3SAndre Fischer        $uniqueparentname = make_short_dir_version($uniqueparentname);
3439f91b7e3SAndre Fischer    }
34419d58b3aSEike Rathke
3459f91b7e3SAndre Fischer    return ($originaluniqueparentname, $uniqueparentname);
3469f91b7e3SAndre Fischer}
347cdf0e10cSrcweir
348cdf0e10cSrcweir
349cdf0e10cSrcweir
350cdf0e10cSrcweir
3519f91b7e3SAndre Fischer##############################################################
3529f91b7e3SAndre Fischer# Adding unique directory names to the directory collection
3539f91b7e3SAndre Fischer##############################################################
354cdf0e10cSrcweir
3559f91b7e3SAndre Fischersub create_unique_directorynames ($)
3569f91b7e3SAndre Fischer{
3579f91b7e3SAndre Fischer	my ($directories) = @_;
358cdf0e10cSrcweir
3599f91b7e3SAndre Fischer	$installer::globals::officeinstalldirectoryset = 0;
360cdf0e10cSrcweir
3619f91b7e3SAndre Fischer    my %hostnamehash = ();
3629f91b7e3SAndre Fischer	my $infoline = "";
3639f91b7e3SAndre Fischer	my $errorcount = 0;
36419d58b3aSEike Rathke
3659f91b7e3SAndre Fischer	foreach my $directory (@$directories)
3669f91b7e3SAndre Fischer	{
3679f91b7e3SAndre Fischer        next if defined $directory->{'uniquename'};
36819d58b3aSEike Rathke
369d62abd1aSAndre Fischer        my $styles = $directory->{'Styles'};
370d62abd1aSAndre Fischer        $styles = "" unless defined $styles;
37119d58b3aSEike Rathke
3729f91b7e3SAndre Fischer		my ($originaluniquename, $uniquename) = get_unique_name(
3739f91b7e3SAndre Fischer            $directory->{'HostName'},
3749f91b7e3SAndre Fischer            \%hostnamehash);
3759f91b7e3SAndre Fischer
3769f91b7e3SAndre Fischer		my ($originaluniqueparentname, $uniqueparentname) = get_unique_parent_name(
3779f91b7e3SAndre Fischer            $originaluniquename,
3789f91b7e3SAndre Fischer            $styles);
37919d58b3aSEike Rathke
38019d58b3aSEike Rathke
38119d58b3aSEike Rathke		# Hyphen not allowed in database
382cdf0e10cSrcweir		$uniquename =~ s/\-/\_/g;			# making "-" to "_"
383cdf0e10cSrcweir		$uniqueparentname =~ s/\-/\_/g;		# making "-" to "_"
384cdf0e10cSrcweir
38519d58b3aSEike Rathke		# And finally setting the values for the directories
3869f91b7e3SAndre Fischer		$directory->{'uniquename'} = $uniquename;
3879f91b7e3SAndre Fischer		$directory->{'uniqueparentname'} = $uniqueparentname;
3889f91b7e3SAndre Fischer		$directory->{'long_uniquename'} = $originaluniquename;
3899f91b7e3SAndre Fischer		$directory->{'long_uniqueparentname'} = $originaluniqueparentname;
3909f91b7e3SAndre Fischer    }
3919f91b7e3SAndre Fischer
3929f91b7e3SAndre Fischer    # Find the installation directory.
3939f91b7e3SAndre Fischer    foreach my $directory (@$directories)
3949f91b7e3SAndre Fischer    {
3959f91b7e3SAndre Fischer        next unless defined $directory->{'Styles'};
3969f91b7e3SAndre Fischer
397cdf0e10cSrcweir		# setting the installlocation directory
3989f91b7e3SAndre Fischer		next unless $directory->{'Styles'} =~ /\bISINSTALLLOCATION\b/;
3999f91b7e3SAndre Fischer
4009f91b7e3SAndre Fischer        if ( $installer::globals::installlocationdirectoryset )
4019f91b7e3SAndre Fischer        {
4029f91b7e3SAndre Fischer            installer::exiter::exit_program(
4039f91b7e3SAndre Fischer                sprintf(
4049f91b7e3SAndre Fischer                    "ERROR: Directory with flag ISINSTALLLOCATION alread set: \"%s\".",
4059f91b7e3SAndre Fischer                    $installer::globals::installlocationdirectory),
4069f91b7e3SAndre Fischer                "create_unique_directorynames");
4079f91b7e3SAndre Fischer        }
4089f91b7e3SAndre Fischer
4099f91b7e3SAndre Fischer        $installer::globals::installlocationdirectory = $directory->{'uniquename'};
4109f91b7e3SAndre Fischer        $installer::globals::installlocationdirectoryset = 1;
4119f91b7e3SAndre Fischer    }
412cdf0e10cSrcweir}
413cdf0e10cSrcweir
4149f91b7e3SAndre Fischer
4159f91b7e3SAndre Fischer
4169f91b7e3SAndre Fischer
417cdf0e10cSrcweir#####################################################
418cdf0e10cSrcweir# Adding ":." to selected default directory names
419cdf0e10cSrcweir#####################################################
420cdf0e10cSrcweir
4219f91b7e3SAndre Fischersub update_defaultdir ($$)
422cdf0e10cSrcweir{
423cdf0e10cSrcweir	my ( $onedir, $allvariableshashref ) = @_;
424cdf0e10cSrcweir
4259f91b7e3SAndre Fischer	if ($installer::globals::addchildprojects
4269f91b7e3SAndre Fischer        || $installer::globals::patch
4279f91b7e3SAndre Fischer        || $installer::globals::languagepack
4289f91b7e3SAndre Fischer        || $allvariableshashref->{'CHANGETARGETDIR'})
429cdf0e10cSrcweir	{
430cdf0e10cSrcweir		my $sourcediraddon = "\:\.";
4319f91b7e3SAndre Fischer		return $onedir->{'defaultdir'} . $sourcediraddon;
432cdf0e10cSrcweir	}
4339f91b7e3SAndre Fischer	else
4349f91b7e3SAndre Fischer    {
4359f91b7e3SAndre Fischer        return $onedir->{'defaultdir'};
4369f91b7e3SAndre Fischer    }
437cdf0e10cSrcweir}
438cdf0e10cSrcweir
439cdf0e10cSrcweir#####################################################
440cdf0e10cSrcweir# The directory with the style ISINSTALLLOCATION
441cdf0e10cSrcweir# will be replaced by INSTALLLOCATION
442cdf0e10cSrcweir#####################################################
443cdf0e10cSrcweir
444cdf0e10cSrcweirsub set_installlocation_directory
445cdf0e10cSrcweir{
446cdf0e10cSrcweir	my ( $directoryref, $allvariableshashref ) = @_;
447cdf0e10cSrcweir
4489f91b7e3SAndre Fischer	if ( ! $installer::globals::installlocationdirectoryset )
4499f91b7e3SAndre Fischer    {
4509f91b7e3SAndre Fischer        installer::exiter::exit_program(
4519f91b7e3SAndre Fischer            "ERROR: Directory with flag ISINSTALLLOCATION not set!",
4529f91b7e3SAndre Fischer            "set_installlocation_directory");
4539f91b7e3SAndre Fischer    }
454cdf0e10cSrcweir
455cdf0e10cSrcweir	for ( my $i = 0; $i <= $#{$directoryref}; $i++ )
456cdf0e10cSrcweir	{
457cdf0e10cSrcweir		my $onedir = ${$directoryref}[$i];
458cdf0e10cSrcweir
459cdf0e10cSrcweir		if ( $onedir->{'uniquename'} eq $installer::globals::installlocationdirectory )
460cdf0e10cSrcweir		{
461cdf0e10cSrcweir			$onedir->{'uniquename'} = "INSTALLLOCATION";
4629f91b7e3SAndre Fischer			$onedir->{'defaultdir'} = update_defaultdir($onedir, $allvariableshashref);
463cdf0e10cSrcweir		}
464cdf0e10cSrcweir
465cdf0e10cSrcweir		if ( $onedir->{'uniquename'} eq $installer::globals::vendordirectory )
466cdf0e10cSrcweir		{
4679f91b7e3SAndre Fischer			$onedir->{'defaultdir'} = update_defaultdir($onedir, $allvariableshashref);
468cdf0e10cSrcweir		}
469cdf0e10cSrcweir
470cdf0e10cSrcweir		if ( $onedir->{'uniqueparentname'} eq $installer::globals::installlocationdirectory )
471cdf0e10cSrcweir		{
472cdf0e10cSrcweir			$onedir->{'uniqueparentname'} = "INSTALLLOCATION";
473cdf0e10cSrcweir		}
474cdf0e10cSrcweir	}
475cdf0e10cSrcweir}
476cdf0e10cSrcweir
477cdf0e10cSrcweir#####################################################
478cdf0e10cSrcweir# Getting the name of the top level directory. This
479cdf0e10cSrcweir# can have only one letter
480cdf0e10cSrcweir#####################################################
481cdf0e10cSrcweir
482cdf0e10cSrcweirsub get_last_directory_name
483cdf0e10cSrcweir{
484cdf0e10cSrcweir	my ($completepathref) = @_;
485cdf0e10cSrcweir
486cdf0e10cSrcweir	if ( $$completepathref =~ /^.*[\/\\](.+?)\s*$/ )
487cdf0e10cSrcweir	{
488cdf0e10cSrcweir		$$completepathref = $1;
489cdf0e10cSrcweir	}
490cdf0e10cSrcweir}
491cdf0e10cSrcweir
4929f91b7e3SAndre Fischersub setup_global_font_directory_name ($)
4939f91b7e3SAndre Fischer{
4949f91b7e3SAndre Fischer	my ($directories) = @_;
4959f91b7e3SAndre Fischer
496*4374bebbSAndre Fischer    $installer::logger::Info->printf("setup_global_font_directory_name, checking %d entries\n",
497*4374bebbSAndre Fischer        scalar @$directories);
498*4374bebbSAndre Fischer    $installer::logger::Info->printf(" fontsdirhostname is %s\n",
499*4374bebbSAndre Fischer        $installer::globals::fontsdirhostname);
500*4374bebbSAndre Fischer    $installer::logger::Info->printf(" fontsdirname is %s\n",
501*4374bebbSAndre Fischer        $installer::globals::fontsdirname);
5029f91b7e3SAndre Fischer	foreach my $directory (@$directories)
5039f91b7e3SAndre Fischer	{
5049f91b7e3SAndre Fischer        next unless defined $directory->{'Dir'};
5059f91b7e3SAndre Fischer        next unless defined $directory->{'defaultdir'};
5069f91b7e3SAndre Fischer
507*4374bebbSAndre Fischer        $installer::logger::Info->printf("    Dir is %s\n", $directory->{'Dir'});
508*4374bebbSAndre Fischer        $installer::logger::Info->printf("    defaultdir is %s\n", $directory->{'defaultdir'});
5099f91b7e3SAndre Fischer        next if $directory->{'Dir'} ne "PREDEFINED_OSSYSTEMFONTDIR";
5109f91b7e3SAndre Fischer        next if $directory->{'defaultdir'} ne $installer::globals::fontsdirhostname;
5119f91b7e3SAndre Fischer
5129f91b7e3SAndre Fischer        $installer::globals::fontsdirname = $installer::globals::fontsdirhostname;
5139f91b7e3SAndre Fischer        $installer::globals::fontsdirparent = $directory->{'uniqueparentname'};
5149f91b7e3SAndre Fischer
5159f91b7e3SAndre Fischer        $installer::logger::Info->printf("%s, fdhn %s, dd %s, ipn %s, HN %s\n",
5169f91b7e3SAndre Fischer            "PREDEFINED_OSSYSTEMFONTDIR",
5179f91b7e3SAndre Fischer            $installer::globals::fontsdirhostname,
5189f91b7e3SAndre Fischer            $directory->{'defaultdir'},
5199f91b7e3SAndre Fischer            $directory->{'uniqueparentname'},
5209f91b7e3SAndre Fischer            $directory->{'HostName'});
5219f91b7e3SAndre Fischer        installer::scriptitems::print_script_item($directory);
5229f91b7e3SAndre Fischer	}
523*4374bebbSAndre Fischer	foreach my $onedir (@$directories)
524*4374bebbSAndre Fischer    {
525*4374bebbSAndre Fischer    	my $fontdir = "";
526*4374bebbSAndre Fischer		if ( $onedir->{'Dir'} ) { $fontdir = $onedir->{'Dir'}; }
527*4374bebbSAndre Fischer
528*4374bebbSAndre Fischer		my $fontdefaultdir = "";
529*4374bebbSAndre Fischer		if ( $onedir->{'defaultdir'} ) { $fontdefaultdir = $onedir->{'defaultdir'}; }
530*4374bebbSAndre Fischer
531*4374bebbSAndre Fischer		if (( $fontdir eq "PREDEFINED_OSSYSTEMFONTDIR" ) && ( $fontdefaultdir eq $installer::globals::fontsdirhostname ))
532*4374bebbSAndre Fischer		{
533*4374bebbSAndre Fischer            $installer::logger::Info->printf("fontsdirname   = %s\n", $onedir->{'defaultdir'});
534*4374bebbSAndre Fischer            $installer::logger::Info->printf("              is %s\n", $installer::globals::fontsdirname);
535*4374bebbSAndre Fischer            $installer::logger::Info->printf("fontsdirparent = %s\n", $onedir->{'uniqueparentname'});
536*4374bebbSAndre Fischer            $installer::logger::Info->printf("              is %s\n", $installer::globals::fontsdirparent);
537*4374bebbSAndre Fischer		}
538*4374bebbSAndre Fischer    }
5399f91b7e3SAndre Fischer}
5409f91b7e3SAndre Fischer
541cdf0e10cSrcweir#####################################################
542cdf0e10cSrcweir# Creating the defaultdir for the file Director.idt
543cdf0e10cSrcweir#####################################################
544cdf0e10cSrcweir
545dca4887fSAndre Fischersub create_defaultdir_directorynames ($)
546cdf0e10cSrcweir{
547dca4887fSAndre Fischer	my ($directoryref) = @_;
548cdf0e10cSrcweir
549cdf0e10cSrcweir	my @shortnames = ();
550f30bf281SAndre Fischer	if ( $installer::globals::prepare_winpatch ) { @shortnames = values(%installer::globals::saved83dirmapping); }
551cdf0e10cSrcweir
552cdf0e10cSrcweir	for ( my $i = 0; $i <= $#{$directoryref}; $i++ )
553cdf0e10cSrcweir	{
554cdf0e10cSrcweir		my $onedir = ${$directoryref}[$i];
555cdf0e10cSrcweir		my $hostname = $onedir->{'HostName'};
556cdf0e10cSrcweir
557cdf0e10cSrcweir		$hostname =~ s/\Q$installer::globals::separator\E\s*$//;
558cdf0e10cSrcweir		get_last_directory_name(\$hostname);
559cdf0e10cSrcweir		# installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$hostname);	# making program/classes to classes
560cdf0e10cSrcweir		my $uniquename = $onedir->{'uniquename'};
561cdf0e10cSrcweir		my $shortstring;
562f30bf281SAndre Fischer		if (( $installer::globals::prepare_winpatch ) && ( exists($installer::globals::saved83dirmapping{$uniquename}) ))
563cdf0e10cSrcweir		{
564cdf0e10cSrcweir			$shortstring = $installer::globals::saved83dirmapping{$uniquename};
565cdf0e10cSrcweir		}
566cdf0e10cSrcweir		else
567cdf0e10cSrcweir		{
568cdf0e10cSrcweir			$shortstring = installer::windows::idtglobal::make_eight_three_conform($hostname, "dir", \@shortnames);
569cdf0e10cSrcweir		}
570cdf0e10cSrcweir
571cdf0e10cSrcweir		my $defaultdir;
572cdf0e10cSrcweir
573cdf0e10cSrcweir		if ( $shortstring eq $hostname )
574cdf0e10cSrcweir		{
575cdf0e10cSrcweir			$defaultdir = $hostname;
576cdf0e10cSrcweir		}
577cdf0e10cSrcweir		else
578cdf0e10cSrcweir		{
579cdf0e10cSrcweir			$defaultdir = $shortstring . "|" . $hostname;
580cdf0e10cSrcweir		}
581cdf0e10cSrcweir
582cdf0e10cSrcweir		$onedir->{'defaultdir'} = $defaultdir;
583cdf0e10cSrcweir	}
584cdf0e10cSrcweir}
585cdf0e10cSrcweir
586cdf0e10cSrcweir###############################################
587cdf0e10cSrcweir# Fill content into the directory table
588cdf0e10cSrcweir###############################################
589cdf0e10cSrcweir
5909f91b7e3SAndre Fischersub create_directorytable_from_collection ($$)
591cdf0e10cSrcweir{
592cdf0e10cSrcweir	my ($directorytableref, $directoryref) = @_;
593cdf0e10cSrcweir
5949f91b7e3SAndre Fischer	foreach my $onedir (@$directoryref)
595cdf0e10cSrcweir	{
5969f91b7e3SAndre Fischer        # Remove entries for special directories.
5979f91b7e3SAndre Fischer		if (defined $onedir->{'HostName'}
5989f91b7e3SAndre Fischer            && $onedir->{'HostName'} eq ""
5999f91b7e3SAndre Fischer            && defined $onedir->{'Dir'}
6009f91b7e3SAndre Fischer            && $onedir->{'Dir'} eq "PREDEFINED_PROGDIR")
6019f91b7e3SAndre Fischer        {
6029f91b7e3SAndre Fischer            next;
6039f91b7e3SAndre Fischer        }
6049f91b7e3SAndre Fischer
6059f91b7e3SAndre Fischer		my $oneline = sprintf(
6069f91b7e3SAndre Fischer            "%s\t%s\t%s\n",
6079f91b7e3SAndre Fischer            $onedir->{'uniquename'},
6089f91b7e3SAndre Fischer            $onedir->{'uniqueparentname'},
6099f91b7e3SAndre Fischer            $onedir->{'defaultdir'});
6109f91b7e3SAndre Fischer
6119f91b7e3SAndre Fischer		push @{$directorytableref}, $oneline;
612cdf0e10cSrcweir	}
613cdf0e10cSrcweir}
614cdf0e10cSrcweir
615cdf0e10cSrcweir###############################################
616cdf0e10cSrcweir# Defining the root installation structure
617cdf0e10cSrcweir###############################################
618cdf0e10cSrcweir
6199f91b7e3SAndre Fischersub process_root_directories ($$)
620cdf0e10cSrcweir{
6219f91b7e3SAndre Fischer	my ($allvariableshashref, $functor) = @_;
622cdf0e10cSrcweir
623cdf0e10cSrcweir	my $oneline = "";
624cdf0e10cSrcweir
625cdf0e10cSrcweir	if (( ! $installer::globals::patch ) && ( ! $installer::globals::languagepack ) && ( ! $allvariableshashref->{'DONTUSESTARTMENUFOLDER'} ))
626cdf0e10cSrcweir	{
627cdf0e10cSrcweir		my $productname = $allvariableshashref->{'PRODUCTNAME'};
628cdf0e10cSrcweir		my $productversion = $allvariableshashref->{'PRODUCTVERSION'};
629cdf0e10cSrcweir		my $baseproductversion = $productversion;
630cdf0e10cSrcweir
631cdf0e10cSrcweir		if (( $installer::globals::prepare_winpatch ) && ( $allvariableshashref->{'BASEPRODUCTVERSION'} ))
632cdf0e10cSrcweir		{
633cdf0e10cSrcweir			$baseproductversion = $allvariableshashref->{'BASEPRODUCTVERSION'};  # for example "2.0" for OOo
634cdf0e10cSrcweir		}
635cdf0e10cSrcweir
636cdf0e10cSrcweir		my $realproductkey = $productname . " " . $productversion;
637cdf0e10cSrcweir		my $productkey = $productname . " " . $baseproductversion;
638cdf0e10cSrcweir
639cdf0e10cSrcweir		if (( $allvariableshashref->{'POSTVERSIONEXTENSION'} ) && ( ! $allvariableshashref->{'DONTUSEEXTENSIONINDEFAULTDIR'} ))
640cdf0e10cSrcweir		{
641cdf0e10cSrcweir			$productkey = $productkey . " " . $allvariableshashref->{'POSTVERSIONEXTENSION'};
642cdf0e10cSrcweir			$realproductkey = $realproductkey . " " . $allvariableshashref->{'POSTVERSIONEXTENSION'};
643cdf0e10cSrcweir		}
644cdf0e10cSrcweir		if ( $allvariableshashref->{'NOSPACEINDIRECTORYNAME'} )
645cdf0e10cSrcweir		{
646cdf0e10cSrcweir			$productkey =~ s/\ /\_/g;
647cdf0e10cSrcweir			$realproductkey =~ s/\ /\_/g;
648cdf0e10cSrcweir		}
649cdf0e10cSrcweir
6509f91b7e3SAndre Fischer		my $shortproductkey = installer::windows::idtglobal::make_eight_three_conform($productkey, "dir", undef);
651cdf0e10cSrcweir		$shortproductkey =~ s/\s/\_/g;									# changing empty space to underline
652cdf0e10cSrcweir
6539f91b7e3SAndre Fischer        &$functor(
6549f91b7e3SAndre Fischer            $installer::globals::officemenufolder,
6559f91b7e3SAndre Fischer            $installer::globals::programmenufolder,
6569f91b7e3SAndre Fischer            $shortproductkey . "|". $realproductkey);
6579f91b7e3SAndre Fischer	}
658cdf0e10cSrcweir
6599f91b7e3SAndre Fischer	&$functor("TARGETDIR", "", "SourceDir");
6609f91b7e3SAndre Fischer	&$functor($installer::globals::programfilesfolder, "TARGETDIR", ".");
6619f91b7e3SAndre Fischer    &$functor($installer::globals::programmenufolder, "TARGETDIR", ".");
6629f91b7e3SAndre Fischer    &$functor($installer::globals::startupfolder, "TARGETDIR", ".");
6639f91b7e3SAndre Fischer	&$functor($installer::globals::desktopfolder, "TARGETDIR", ".");
6649f91b7e3SAndre Fischer	&$functor($installer::globals::startmenufolder, "TARGETDIR", ".");
6659f91b7e3SAndre Fischer	&$functor($installer::globals::commonfilesfolder, "TARGETDIR", ".");
6669f91b7e3SAndre Fischer	&$functor($installer::globals::commonappdatafolder, "TARGETDIR", ".");
6679f91b7e3SAndre Fischer	&$functor($installer::globals::localappdatafolder, "TARGETDIR", ".");
668cdf0e10cSrcweir
669cdf0e10cSrcweir	if ( $installer::globals::usesharepointpath )
670cdf0e10cSrcweir	{
6719f91b7e3SAndre Fischer		&$functor("SHAREPOINTPATH", "TARGETDIR", ".");
672cdf0e10cSrcweir	}
673cdf0e10cSrcweir
6749f91b7e3SAndre Fischer	&$functor($installer::globals::systemfolder, "TARGETDIR", ".");
675cdf0e10cSrcweir
676cdf0e10cSrcweir	my $localtemplatefoldername = $installer::globals::templatefoldername;
677cdf0e10cSrcweir	my $directorytableentry = $localtemplatefoldername;
678cdf0e10cSrcweir	my $shorttemplatefoldername = installer::windows::idtglobal::make_eight_three_conform($localtemplatefoldername, "dir");
6799f91b7e3SAndre Fischer	if ( $shorttemplatefoldername ne $localtemplatefoldername )
6809f91b7e3SAndre Fischer    {
6819f91b7e3SAndre Fischer        $directorytableentry = $shorttemplatefoldername . "|" . $localtemplatefoldername;
6829f91b7e3SAndre Fischer    }
6839f91b7e3SAndre Fischer	&$functor($installer::globals::templatefolder, "TARGETDIR", $directorytableentry);
684cdf0e10cSrcweir
685*4374bebbSAndre Fischer    $installer::logger::Info->printf("process_root_directories: fontsdirname=%s, fontsfoldername=%s\n",
686*4374bebbSAndre Fischer        $installer::globals::fontsdirname,
687*4374bebbSAndre Fischer        $installer::globals::fontsfoldername);
688cdf0e10cSrcweir	if ( $installer::globals::fontsdirname )
689cdf0e10cSrcweir	{
6909f91b7e3SAndre Fischer		&$functor(
6919f91b7e3SAndre Fischer             $installer::globals::fontsfolder,
6929f91b7e3SAndre Fischer             $installer::globals::fontsdirparent,
6939f91b7e3SAndre Fischer             $installer::globals::fontsfoldername . ":" . $installer::globals::fontsdirname);
694cdf0e10cSrcweir	}
695cdf0e10cSrcweir	else
696cdf0e10cSrcweir	{
6979f91b7e3SAndre Fischer		&$functor(
6989f91b7e3SAndre Fischer             $installer::globals::fontsfolder,
6999f91b7e3SAndre Fischer             "TARGETDIR",
7009f91b7e3SAndre Fischer             $installer::globals::fontsfoldername);
701cdf0e10cSrcweir	}
7029f91b7e3SAndre Fischer}
7039f91b7e3SAndre Fischer
7049f91b7e3SAndre Fischer
7059f91b7e3SAndre Fischer
7069f91b7e3SAndre Fischer
7079f91b7e3SAndre Fischersub find_missing_directories ($$)
7089f91b7e3SAndre Fischer{
7099f91b7e3SAndre Fischer    my ($directories, $allvariableshashref) = @_;
7109f91b7e3SAndre Fischer
7119f91b7e3SAndre Fischer    # Set up the list of target directories.
7129f91b7e3SAndre Fischer    my %target_directories = map {$_->{'uniquename'} => 1} @$directories;
7139f91b7e3SAndre Fischer    # Add special directories.
7149f91b7e3SAndre Fischer    process_root_directories(
7159f91b7e3SAndre Fischer        $allvariableshashref,
7169f91b7e3SAndre Fischer        sub($$$){
7179f91b7e3SAndre Fischer            my ($uniquename, $parentname, $defaultdir) = @_;
7189f91b7e3SAndre Fischer            $target_directories{$uniquename} = 1;
7199f91b7e3SAndre Fischer        }
7209f91b7e3SAndre Fischer    );
7219f91b7e3SAndre Fischer
7229f91b7e3SAndre Fischer    # Set up the list of source directories.
7239f91b7e3SAndre Fischer    my $source_directory_map = $installer::globals::source_msi->GetDirectoryMap();
7249f91b7e3SAndre Fischer    my $source_file_map = $installer::globals::source_msi->GetFileMap();
7259f91b7e3SAndre Fischer    my %source_directories = map {$_->{'unique_name'} => $_} values %$source_directory_map;
7269f91b7e3SAndre Fischer
7279f91b7e3SAndre Fischer    # Find the missing source directories.
7289f91b7e3SAndre Fischer    my @missing_directories = ();
7299f91b7e3SAndre Fischer    foreach my $source_uniquename (keys %source_directories)
7309f91b7e3SAndre Fischer    {
7319f91b7e3SAndre Fischer        if ( ! $target_directories{$source_uniquename})
7329f91b7e3SAndre Fischer        {
7339f91b7e3SAndre Fischer            push @missing_directories, $source_directories{$source_uniquename};
7349f91b7e3SAndre Fischer        }
7359f91b7e3SAndre Fischer    }
7369f91b7e3SAndre Fischer
7379f91b7e3SAndre Fischer    # Report the missing directories.
7389f91b7e3SAndre Fischer    $installer::logger::Info->printf("found %d missing directories\n", scalar @missing_directories);
7399f91b7e3SAndre Fischer    my $index = 0;
7409f91b7e3SAndre Fischer    foreach my $directory_item (@missing_directories)
7419f91b7e3SAndre Fischer    {
7429f91b7e3SAndre Fischer        # Print information about the directory.
7439f91b7e3SAndre Fischer        $installer::logger::Info->printf("missing directory %d: %s\n",
7449f91b7e3SAndre Fischer            ++$index,
7459f91b7e3SAndre Fischer            $directory_item->{'full_target_long_name'});
7469f91b7e3SAndre Fischer        while (my($key,$value) = each %$directory_item)
7479f91b7e3SAndre Fischer        {
7489f91b7e3SAndre Fischer            $installer::logger::Info->printf("    %s -> %s\n", $key, $value);
7499f91b7e3SAndre Fischer        }
7509f91b7e3SAndre Fischer
7519f91b7e3SAndre Fischer        # Print the referencing files.
7529f91b7e3SAndre Fischer        my @filenames = ();
7539f91b7e3SAndre Fischer        while (my ($key,$value) = each %$source_file_map)
7549f91b7e3SAndre Fischer        {
7559f91b7e3SAndre Fischer            if ($value->{'directory'}->{'unique_name'} eq $directory_item->{'unique_name'})
7569f91b7e3SAndre Fischer            {
7579f91b7e3SAndre Fischer                push @filenames, $key;
7589f91b7e3SAndre Fischer            }
7599f91b7e3SAndre Fischer        }
7609f91b7e3SAndre Fischer        $installer::logger::Info->printf("  referencing files are %s\n", join(", ", @filenames));
7619f91b7e3SAndre Fischer    }
7629f91b7e3SAndre Fischer
7639f91b7e3SAndre Fischer    foreach my $directory (@$directories)
7649f91b7e3SAndre Fischer    {
7659f91b7e3SAndre Fischer        $installer::logger::Lang->printf("target directory %s -> HN %s\n",
7669f91b7e3SAndre Fischer            $directory->{'uniquename'},
7679f91b7e3SAndre Fischer            $directory->{'HostName'});
7689f91b7e3SAndre Fischer        installer::scriptitems::print_script_item($directory);
7699f91b7e3SAndre Fischer    }
7709f91b7e3SAndre Fischer
7719f91b7e3SAndre Fischer    # Setup a map of directory uniquenames to verify that the new
7729f91b7e3SAndre Fischer    # entries don't use unique names that are already in use.
7739f91b7e3SAndre Fischer    my %unique_names = map {$_->{'uniquename'} => $_} @$directories;
7749f91b7e3SAndre Fischer
7759f91b7e3SAndre Fischer    # Create script items for the missing directories.
7769f91b7e3SAndre Fischer    my @new_source_directories = ();
7779f91b7e3SAndre Fischer    foreach my $source_directory_item (@missing_directories)
7789f91b7e3SAndre Fischer    {
7799f91b7e3SAndre Fischer        my $new_directory_item = {
7809f91b7e3SAndre Fischer            'uniquename' => $source_directory_item->{'unique_name'},
781677600b0SAndre Fischer            'uniqueparentname' => $source_directory_item->{'parent_name'},
7829f91b7e3SAndre Fischer            'defaultdir' => $source_directory_item->{'default_dir'},
7839f91b7e3SAndre Fischer            'HostName' => $source_directory_item->{'full_target_long_name'},
7849f91b7e3SAndre Fischer            'componentname' => $source_directory_item->{'component_name'},
7859f91b7e3SAndre Fischer        };
7869f91b7e3SAndre Fischer
7879f91b7e3SAndre Fischer        if (defined $unique_names{$new_directory_item->{'uniquename'}})
7889f91b7e3SAndre Fischer        {
7899f91b7e3SAndre Fischer            installer::logger::PrintError("newly created directory entry collides with existing directory");
7909f91b7e3SAndre Fischer            last;
7919f91b7e3SAndre Fischer        }
7929f91b7e3SAndre Fischer
7939f91b7e3SAndre Fischer        push @new_source_directories, $new_directory_item;
7949f91b7e3SAndre Fischer    }
7959f91b7e3SAndre Fischer
7969f91b7e3SAndre Fischer    return @new_source_directories;
7979f91b7e3SAndre Fischer}
7989f91b7e3SAndre Fischer
7999f91b7e3SAndre Fischer
8009f91b7e3SAndre Fischer
801cdf0e10cSrcweir
8029f91b7e3SAndre Fischersub prepare_directory_table_creation ($$)
8039f91b7e3SAndre Fischer{
8049f91b7e3SAndre Fischer	my ($directories, $allvariableshashref) = @_;
8059f91b7e3SAndre Fischer
8069f91b7e3SAndre Fischer    foreach my $directory (@$directories)
8079f91b7e3SAndre Fischer    {
8089f91b7e3SAndre Fischer        delete $directory->{'uniquename'};
8099f91b7e3SAndre Fischer    }
810cdf0e10cSrcweir
8119f91b7e3SAndre Fischer	overwrite_programfilesfolder($allvariableshashref);
8129f91b7e3SAndre Fischer	create_unique_directorynames($directories);
8139f91b7e3SAndre Fischer    check_unique_directorynames($directories);
8149f91b7e3SAndre Fischer	create_defaultdir_directorynames($directories);	# only destdir!
8159f91b7e3SAndre Fischer    setup_global_font_directory_name($directories);
8169f91b7e3SAndre Fischer	set_installlocation_directory($directories, $allvariableshashref);
8179f91b7e3SAndre Fischer
8189f91b7e3SAndre Fischer    if ($installer::globals::is_release)
8199f91b7e3SAndre Fischer    {
8209f91b7e3SAndre Fischer        my @new_directories = find_missing_directories($directories, $allvariableshashref);
8219f91b7e3SAndre Fischer        push @$directories, @new_directories;
8229f91b7e3SAndre Fischer    }
823cdf0e10cSrcweir}
824cdf0e10cSrcweir
8259f91b7e3SAndre Fischer
8269f91b7e3SAndre Fischer
8279f91b7e3SAndre Fischer
828cdf0e10cSrcweir###############################################
829cdf0e10cSrcweir# Creating the file Director.idt dynamically
830cdf0e10cSrcweir###############################################
831cdf0e10cSrcweir
8329f91b7e3SAndre Fischersub create_directory_table ($$$)
833cdf0e10cSrcweir{
8349f91b7e3SAndre Fischer	my ($directoryref, $basedir, $allvariableshashref) = @_;
835cdf0e10cSrcweir
836cdf0e10cSrcweir	# Structure of the directory table:
837cdf0e10cSrcweir	# Directory Directory_Parent DefaultDir
838cdf0e10cSrcweir	# Directory is a unique identifier
839cdf0e10cSrcweir	# Directory_Parent is the unique identifier of the parent
840cdf0e10cSrcweir	# DefaultDir is .:APPLIC~1|Application Data with
841cdf0e10cSrcweir	# Before ":" : [sourcedir]:[destdir] (not programmed yet)
842cdf0e10cSrcweir	# After ":" : 8+3 and not 8+3 the destination directory name
84319d58b3aSEike Rathke
844b274bc22SAndre Fischer	$installer::logger::Lang->add_timestamp("Performance Info: Directory Table start");
845cdf0e10cSrcweir
846cdf0e10cSrcweir	my @directorytable = ();
847cdf0e10cSrcweir	installer::windows::idtglobal::write_idt_header(\@directorytable, "directory");
8489f91b7e3SAndre Fischer
8499f91b7e3SAndre Fischer    # Add entries for the root directories (and a few special directories like that for fonts).
8509f91b7e3SAndre Fischer    process_root_directories(
8519f91b7e3SAndre Fischer        $allvariableshashref,
8529f91b7e3SAndre Fischer        sub($$$){
8539f91b7e3SAndre Fischer            push(@directorytable, join("\t", @_)."\n");
8549f91b7e3SAndre Fischer        }
8559f91b7e3SAndre Fischer    );
8569f91b7e3SAndre Fischer
8579f91b7e3SAndre Fischer    # Add entries for the non-root directories.
858cdf0e10cSrcweir	create_directorytable_from_collection(\@directorytable, $directoryref);
859cdf0e10cSrcweir
860cdf0e10cSrcweir	# Saving the file
861cdf0e10cSrcweir
862cdf0e10cSrcweir	my $directorytablename = $basedir . $installer::globals::separator . "Director.idt";
863cdf0e10cSrcweir	installer::files::save_file($directorytablename ,\@directorytable);
864b274bc22SAndre Fischer    $installer::logger::Lang->printf("Created idt file: %s\n", $directorytablename);
86519d58b3aSEike Rathke
866b274bc22SAndre Fischer	$installer::logger::Lang->add_timestamp("Performance Info: Directory Table end");
867cdf0e10cSrcweir}
868cdf0e10cSrcweir
8699f91b7e3SAndre Fischer
870cdf0e10cSrcweir1;
871