xref: /AOO41X/main/solenv/bin/modules/installer/windows/media.pm (revision 707fc0d4d52eb4f69d89a98ffec6918ca5de6326)
1#**************************************************************
2#
3#  Licensed to the Apache Software Foundation (ASF) under one
4#  or more contributor license agreements.  See the NOTICE file
5#  distributed with this work for additional information
6#  regarding copyright ownership.  The ASF licenses this file
7#  to you under the Apache License, Version 2.0 (the
8#  "License"); you may not use this file except in compliance
9#  with the License.  You may obtain a copy of the License at
10#
11#    http://www.apache.org/licenses/LICENSE-2.0
12#
13#  Unless required by applicable law or agreed to in writing,
14#  software distributed under the License is distributed on an
15#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16#  KIND, either express or implied.  See the License for the
17#  specific language governing permissions and limitations
18#  under the License.
19#
20#**************************************************************
21
22
23
24package installer::windows::media;
25
26use installer::exiter;
27use installer::files;
28use installer::globals;
29use installer::windows::idtglobal;
30
31##############################################################
32# Returning the diskid for the media table.
33##############################################################
34
35sub get_media_diskid
36{
37    my ($id) = @_;
38
39    return $id;
40}
41
42##############################################################
43# Returning the lastsequence for the media table.
44##############################################################
45
46sub get_media_lastsequence
47{
48    my ($fileref) = @_;
49
50    return $fileref->{'sequencenumber'};
51}
52
53##############################################################
54# Returning the diskprompt for the media table.
55##############################################################
56
57sub get_media_diskprompt
58{
59    return 1;
60}
61
62##############################################################
63# Returning the cabinet file name for the media table.
64##############################################################
65
66sub get_media_cabinet
67{
68    my ($id) = @_;
69
70    my $number = 1000 + $id;
71    my $filename = "f_" . $number . ".cab";
72
73    if ( $installer::globals::include_cab_in_msi ) { $filename = "\#" . $filename; }
74
75    return $filename;
76}
77
78##############################################################
79# Returning the volumelabel for the media table.
80##############################################################
81
82sub get_media_volumelabel
83{
84    return "DISK1";
85}
86
87##############################################################
88# Returning the source for the media table.
89##############################################################
90
91sub get_media_source
92{
93    return "";
94}
95
96##############################################################
97# Saving the cabinet file name in the files collector.
98# This is useful for making a list to connect the
99# source of each file with the destination cabinet file.
100##############################################################
101
102sub set_cabinetfilename_for_component_in_file_collector
103{
104    my ($cabinetfilename, $filesref, $componentname, $max) = @_;
105
106    for ( my $i = 0; $i <= $max; $i++ )
107    {
108        my $onefile = ${$filesref}[$i];
109        my $component = $onefile->{'componentname'};
110
111        if ( $component eq $componentname )
112        {
113            my $cabinet = "";
114
115            if ( $onefile->{'cabinet'} ) { $cabinet = $onefile->{'cabinet'}; }
116
117            if ( $cabinet eq "" )
118            {
119                $onefile->{'cabinet'} = $cabinetfilename;
120            }
121        }
122    }
123}
124
125#################################################
126# Creating the cab file name dynamically
127#################################################
128
129sub generate_cab_filename_for_some_cabs
130{
131    my ( $allvariables, $id ) = @_;
132
133    my $name = $allvariables->{'PRODUCTNAME'};
134
135    $name = lc($name);
136    $name =~ s/\.//g;
137    $name =~ s/\s//g;
138
139    # possibility to overwrite the name with variable CABFILENAME
140    if ( $allvariables->{'CABFILENAME'} ) { $name = $allvariables->{'CABFILENAME'}; }
141
142    $name = $name . $id . ".cab";
143
144    if ( $installer::globals::include_cab_in_msi ) { $name = "\#" . $name; }
145
146    return $name;
147}
148
149#################################################
150# Creating the cab file name for cab files
151# defined in packages.
152#################################################
153
154sub get_cabfilename
155{
156    my ($name) = @_;
157
158    if ( $installer::globals::include_cab_in_msi ) { $name = "\#" . $name; }
159
160    return $name;
161}
162
163#################################################
164# Creating the cab file name dynamically
165#################################################
166
167sub generate_cab_filename
168{
169    my ( $allvariables ) = @_;
170
171    my $name = $allvariables->{'PRODUCTNAME'};
172
173    $name = lc($name);
174    $name =~ s/\.//g;
175    $name =~ s/\s//g;
176
177    # possibility to overwrite the name with variable CABFILENAME
178    if ( $allvariables->{'CABFILENAME'} ) { $name = $allvariables->{'CABFILENAME'}; }
179
180    $name = $name . ".cab";
181
182    if ( $installer::globals::include_cab_in_msi ) { $name = "\#" . $name; }
183
184    return $name;
185}
186
187sub get_maximum_filenumber
188{
189    my ($allfiles, $maxcabfilenumber) = @_;
190
191    my $maxfile = 0;
192
193    while ( ! ( $allfiles%$maxcabfilenumber == 0 ))
194    {
195        $allfiles++;
196    }
197
198    $maxfile = $allfiles / $maxcabfilenumber;
199
200    $maxfile++;                 # for securitry
201
202    return $maxfile;
203}
204
205#################################################################################
206# Setting the last sequence for the cabinet files
207#################################################################################
208
209sub get_last_sequence
210{
211    my ( $cabfilename, $alludpatelastsequences ) = @_;
212
213    my $sequence = 0;
214
215    if (( $installer::globals::updatedatabase ) && ( exists($alludpatelastsequences->{$cabfilename}) ))
216    {
217        $sequence = $alludpatelastsequences->{$cabfilename};
218    }
219    else
220    {
221        $sequence = $installer::globals::lastsequence{$cabfilename};
222    }
223
224    return $sequence;
225}
226
227#################################################################################
228# Creating the file Media.idt dynamically
229# Content:
230# DiskId LastSequence DiskPrompt Cabinet VolumeLabel Source
231# Idea: Every component is packed into each own cab file
232#################################################################################
233
234sub create_media_table
235{
236    my ($filesref, $basedir, $allvariables, $alludpatelastsequences, $allupdatediskids) = @_;
237
238    my @mediatable = ();
239
240    my $diskid = 0;
241
242    installer::windows::idtglobal::write_idt_header(\@mediatable, "media");
243
244    if ( $allvariables->{'INCLUDE_CAB_IN_MSI'} ) { $installer::globals::include_cab_in_msi = 1; }
245
246    if ( $installer::globals::use_packages_for_cabs )
247    {
248        my $cabfile;
249        foreach $cabfile ( sort keys %installer::globals::lastsequence )
250        {
251            my %media = ();
252            $diskid++;
253
254            $media{'DiskId'} = get_media_diskid($diskid);
255            $media{'LastSequence'} = get_last_sequence($cabfile, $alludpatelastsequences);
256            $media{'DiskPrompt'} = get_media_diskprompt();
257            $media{'Cabinet'} = get_cabfilename($cabfile);
258            $media{'VolumeLabel'} = get_media_volumelabel();
259            $media{'Source'} = get_media_source();
260
261            my $oneline = $media{'DiskId'} . "\t" . $media{'LastSequence'} . "\t" . $media{'DiskPrompt'} . "\t"
262                        . $media{'Cabinet'} . "\t" . $media{'VolumeLabel'} . "\t" . $media{'Source'} . "\n";
263
264            push(@mediatable, $oneline);
265
266            # Comparing the disk id with the disk id from update database. Both have to be identical. New files have to be added
267            # to the new pff cabinet file. And existing cab files must not be removed.
268            if ( $installer::globals::updatedatabase )
269            {
270                # Comparing lines in new media table with line from media table in udpate database.
271                if ( exists($allupdatediskids->{$media{'Cabinet'}}) )
272                {
273                    if ( $media{'DiskId'} != $allupdatediskids->{$media{'Cabinet'}} )
274                    {
275                        installer::exiter::exit_program("ERROR: Different DiskIDs for cab file \"$media{'Cabinet'}\".\nCurrent installation set: \"$media{'DiskId'}\", but update database used \"$allupdatediskids->{$media{'Cabinet'}}\".\nWere cabinet files removed or added?", "create_media_table");
276                    }
277                }
278                else
279                {
280                    my $localinfoline = "Warning: Could not find cabinet file \"$media{'Cabinet'}}\" in update database. This seems to be an new cabinet file!?\n";
281                    push(@installer::globals::logfileinfo, $localinfoline);
282                }
283            }
284        }
285
286        # one new cabinet file for all files added after the final release
287        if (( $installer::globals::updatedatabase ) && ( $installer::globals::pfffileexists ))
288        {
289            my %media = ();
290            $diskid++;
291
292            $media{'DiskId'} = get_media_diskid($diskid) + $installer::globals::mergemodulenumber;  # Adding mergemodulenumber, because this files are included later
293            $media{'LastSequence'} = $installer::globals::updatesequencecounter;
294            $media{'DiskPrompt'} = get_media_diskprompt();
295            $media{'Cabinet'} = get_cabfilename($installer::globals::pffcabfilename);
296            $media{'VolumeLabel'} = get_media_volumelabel();
297            $media{'Source'} = get_media_source();
298
299            my $oneline = $media{'DiskId'} . "\t" . $media{'LastSequence'} . "\t" . $media{'DiskPrompt'} . "\t"
300                        . $media{'Cabinet'} . "\t" . $media{'VolumeLabel'} . "\t" . $media{'Source'} . "\n";
301
302            push(@mediatable, $oneline);
303        }
304
305    }
306    elsif ( $installer::globals::cab_file_per_component )
307    {
308        for ( my $i = 0; $i <= $#{$filesref}; $i++ )
309        {
310            my $onefile = ${$filesref}[$i];
311            my $nextfile = ${$filesref}[$i+1];
312
313            my $filecomponent = "";
314            my $nextcomponent = "";
315
316            if ( $onefile->{'componentname'} ) { $filecomponent = $onefile->{'componentname'}; }
317            if ( $nextfile->{'componentname'} ) { $nextcomponent = $nextfile->{'componentname'}; }
318
319            if ( $filecomponent eq $nextcomponent )
320            {
321                next;       # nothing to do, this is not the last file of a component
322            }
323
324            my %media = ();
325            $diskid++;
326
327            $media{'DiskId'} = get_media_diskid($diskid);
328            $media{'LastSequence'} = get_media_lastsequence($onefile);
329            $media{'DiskPrompt'} = get_media_diskprompt();
330            $media{'Cabinet'} = get_media_cabinet($diskid);
331            $media{'VolumeLabel'} = get_media_volumelabel();
332            $media{'Source'} = get_media_source();
333
334            my $oneline = $media{'DiskId'} . "\t" . $media{'LastSequence'} . "\t" . $media{'DiskPrompt'} . "\t"
335                    . $media{'Cabinet'} . "\t" . $media{'VolumeLabel'} . "\t" . $media{'Source'} . "\n";
336
337            push(@mediatable, $oneline);
338
339            $media{'Cabinet'} =~ s/^\s*\#//;    # removing leading hash
340            set_cabinetfilename_for_component_in_file_collector($media{'Cabinet'}, $filesref, $filecomponent, $i);
341        }
342    }
343    elsif ( $installer::globals::fix_number_of_cab_files )
344    {
345        # number of cabfiles
346        my $maxcabfilenumber = $installer::globals::number_of_cabfiles;
347        if ( $allvariables->{'CABFILENUMBER'} ) { $maxcabfilenumber = $allvariables->{'CABFILENUMBER'}; }
348        my $allfiles = $#{$filesref} + 1;
349        my $maxfilenumber = get_maximum_filenumber($allfiles, $maxcabfilenumber);
350        # my $maxfilenumber = 1000; # maximum 1000 files in each cabinet file
351        my $cabfilenumber = 0;
352        my $cabfull = 0;
353        my $counter = 0;
354
355        # Sorting of files collector files required !
356        # Attention: The order in the cab file is not guaranteed (especially in udpate process)
357
358        for ( my $i = 0; $i <= $#{$filesref}; $i++ )
359        {
360            if (( $counter >= $maxfilenumber ) || ( $i == $#{$filesref} )) { $cabfull = 1; }
361
362            $counter++;      # counting the files in the cab file
363
364            my $onefile = ${$filesref}[$i];
365            my $nextfile = ${$filesref}[$i+1];
366
367            my $filecomponent = "";
368            my $nextcomponent = "";
369
370            if ( $onefile->{'componentname'} ) { $filecomponent = $onefile->{'componentname'}; }
371            if ( $nextfile->{'componentname'} ) { $nextcomponent = $nextfile->{'componentname'}; }
372
373            if ( $filecomponent eq $nextcomponent ) # all files of one component have to be in one cab file
374            {
375                next;       # nothing to do, this is not the last file of a component
376            }
377
378            if ( $cabfull )
379            {
380                my %media = ();
381                $cabfilenumber++;
382
383                $media{'DiskId'} = get_media_diskid($cabfilenumber);
384                # $media{'LastSequence'} = get_media_lastsequence($onefile);
385                $media{'LastSequence'} = $i + 1;    # This should be correct, also for unsorted files collectors
386                $media{'DiskPrompt'} = get_media_diskprompt();
387                $media{'Cabinet'} = generate_cab_filename_for_some_cabs($allvariables, $cabfilenumber);
388                $media{'VolumeLabel'} = get_media_volumelabel();
389                $media{'Source'} = get_media_source();
390
391                my $oneline = $media{'DiskId'} . "\t" . $media{'LastSequence'} . "\t" . $media{'DiskPrompt'} . "\t"
392                        . $media{'Cabinet'} . "\t" . $media{'VolumeLabel'} . "\t" . $media{'Source'} . "\n";
393
394                push(@mediatable, $oneline);
395
396                # Saving the cabinet file name in the file collector
397
398                $media{'Cabinet'} =~ s/^\s*\#//;    # removing leading hash
399
400                for ( my $j = 0; $j <= $i; $j++ )
401                {
402                    my $onefile = ${$filesref}[$j];
403                    if ( ! $onefile->{'cabinet'} ) { $onefile->{'cabinet'} = $media{'Cabinet'}; }
404                }
405
406                $cabfull = 0;
407                $counter = 0;
408            }
409        }
410    }
411    elsif ( $installer::globals::one_cab_file )
412    {
413        my %media = ();
414        $diskid++;
415
416        my $maximumfile = $#{$filesref};
417
418        $media{'DiskId'} = get_media_diskid($diskid);
419        # $media{'LastSequence'} = ${$filesref}[$maximumfile]->{'sequencenumber'};  # sequence number of the last file
420        $media{'LastSequence'} = $maximumfile + 1; # This works also for unsorted file collector
421        $media{'DiskPrompt'} = get_media_diskprompt();
422        $media{'Cabinet'} = generate_cab_filename($allvariables);
423        $media{'VolumeLabel'} = get_media_volumelabel();
424        $media{'Source'} = get_media_source();
425
426        my $oneline = $media{'DiskId'} . "\t" . $media{'LastSequence'} . "\t" . $media{'DiskPrompt'} . "\t"
427                    . $media{'Cabinet'} . "\t" . $media{'VolumeLabel'} . "\t" . $media{'Source'} . "\n";
428
429        push(@mediatable, $oneline);
430
431        # Saving the cabinet file name in the file collector
432
433        $media{'Cabinet'} =~ s/^\s*\#//;    # removing leading hash
434
435        for ( my $i = 0; $i <= $#{$filesref}; $i++ )
436        {
437            my $onefile = ${$filesref}[$i];
438            $onefile->{'cabinet'} = $media{'Cabinet'};
439        }
440    }
441    else
442    {
443        installer::exiter::exit_program("ERROR: No cab file specification in globals.pm !", "create_media_table");
444    }
445
446    # Saving the file
447
448    my $mediatablename = $basedir . $installer::globals::separator . "Media.idt";
449    installer::files::save_file($mediatablename ,\@mediatable);
450    my $infoline = "Created idt file: $mediatablename\n";
451    push(@installer::globals::logfileinfo, $infoline);
452}
453
4541;
455