xref: /trunk/main/oowintool (revision edd74ba5)
1#!/usr/bin/perl -w
2# *************************************************************
3#
4#  Licensed to the Apache Software Foundation (ASF) under one
5#  or more contributor license agreements.  See the NOTICE file
6#  distributed with this work for additional information
7#  regarding copyright ownership.  The ASF licenses this file
8#  to you under the Apache License, Version 2.0 (the
9#  "License"); you may not use this file except in compliance
10#  with the License.  You may obtain a copy of the License at
11#
12#    http://www.apache.org/licenses/LICENSE-2.0
13#
14#  Unless required by applicable law or agreed to in writing,
15#  software distributed under the License is distributed on an
16#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17#  KIND, either express or implied.  See the License for the
18#  specific language governing permissions and limitations
19#  under the License.
20#
21# *************************************************************
22
23use File::Copy;
24
25my $output_format = 'u';
26my $aoo32OnWin64 = 0;
27
28
29sub reg_get_value($)
30{
31    # it is believed that the registry moves keys around
32    # depending on OS version, this will de-mangle that
33    my $key = shift;
34    my $fhandle;
35    my $value;
36
37    open ($fhandle, "/proc/registry/$key") || return;
38    # reg keys have 0x00 0x5c at the end
39    $value = (split /\0/, <$fhandle>)[0];
40    close ($fhandle);
41
42    if ( defined $value ) {
43        chomp ($value);
44        $value =~ s|\r\n||;
45#    print "Value '$value' at '$key'\n";
46    }
47
48    return $value;
49}
50
51sub reg_find_key($)
52{
53    # it is believed that the registry moves keys around
54    # depending on OS version, this will de-mangle that
55    my $key = shift;
56    $key =~ s| |\\ |;
57    $key = `cd /proc/registry/ ; ls $key`;
58
59    return $key;
60}
61
62sub print_syntax()
63{
64    print "oowintool [option] ...\n";
65    print " encoding options\n";
66    print "   -w   - windows form\n";
67    print "   -u   - unix form (default)\n";
68    print " commands:\n";
69    print "   --msvc-ver              - dump version of MSVC eg. 6.0\n";
70    print "   --msvc-copy-dlls <dest> - copy msvc[pr]??.dlls into <dest>/msvcp??/\n";
71    print "   --msvc-productdir       - dump productdir\n";
72    print "   --msvs-productdir       - dump productdir\n";
73    print "   --dotnetsdk-dir         - dump .Net SDK path\n";
74    print "   --csc-compilerdir       - dump .Net SDK compiler path\n";
75    print "   --psdk-home             - dump psdk install dir\n";
76    print "   --jdk-home              - dump the jdk install dir\n";
77    print "   --nsis-dir              - dump NSIS path\n";
78    print "   --help                  - this message\n";
79}
80
81sub cygpath($$$)
82{
83    my ($path, $input_format, $format) = @_;
84
85    return $path if ( ! defined $path );
86    # Strip trailing path separators
87    if ($input_format eq 'u') {
88	$path =~ s|/*\s*$||;
89    } else {
90	$path =~ s|\\*\s*$||;
91    }
92
93    # 'Unterminated quoted string errors' from 'ash' when
94    # forking cygpath  so - reimplement cygpath in perl [ gack ]
95    if ($format eq 'u' && $input_format eq 'w') {
96	$path =~ s|\\|/|g;
97	$path =~ s|([a-zA-Z]):/|/cygdrive/$1/|g;
98    }
99    elsif ($format eq 'w' && $input_format eq 'u') {
100	$path =~ s|/cygdrive/([a-zA-Z])/|/$1/|g;
101	$path =~ s|/|\\|g;
102    }
103
104    return $path;
105}
106
107sub print_path($$)
108{
109    my ($path, $unix) = @_;
110
111    $path = cygpath ($path, $unix, $output_format);
112
113    print $path;
114}
115
116sub print_psdk_home()
117{
118    my ($value, $key);
119    $value = reg_get_value ('HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Microsoft SDKs/Windows/v6.1/InstallationFolder');
120    if (!defined $value)
121    {
122        $value = reg_get_value ('HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Microsoft SDKs/Windows/CurrentInstallFolder');
123    }
124    if (!defined $value)
125    {
126	    $value = reg_get_value ('HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/MicrosoftSDK/Directories/Install Dir');
127    }
128    if (!defined $value)
129    {
130	    $key = reg_find_key ('HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/MicrosoftSDK/InstalledSDKs/*/Install Dir');
131	    $value = reg_get_value ($key);
132    }
133    if (!defined $value)
134    {
135        my $dir = cygpath (find_msvc()->{'product_dir'}, 'w', $output_format);
136		$value = `/bin/find "$dir" -iname platformsdk | head -n 1`;
137    }
138
139    defined $value || die "psdk not found";
140
141    print cygpath ($value, 'w', $output_format);
142}
143
144my %msvc_net_2003 = (
145    'ver' => '7.1',
146    'key' => 'Microsoft/VisualStudio/7.1/Setup/VC/ProductDir',
147    'dll_path' => '../Visual Studio .NET Professional 2003 - English',
148    'dll_suffix' => '71'
149);
150my %msvs_net_2003 = (
151    'ver' => '7.1',
152    'key' => 'Microsoft/VisualStudio/7.1/Setup/VS/ProductDir',
153    'dll_path' => 'Visual Studio .NET Professional 2003 - English',
154    'dll_suffix' => '71'
155);
156my %msvs_net_2003_ea = (
157    'ver' => '7.1',
158    'key' => 'Microsoft/VisualStudio/7.1/Setup/VS/ProductDir',
159    'dll_path' => 'Visual Studio .NET Enterprise Architect 2003 - English', # testme ...
160    'dll_suffix' => '71'
161);
162my %msvs_express_2005 = (
163    'ver' => '8.0',
164    'key' => 'Microsoft/VCExpress/8.0/Setup/VS/ProductDir',
165    'dll_path' => '../SDK/v2.0/Bin',
166    'dll_suffix' => '80'
167);
168my %msvc_express_2005 = (
169    'ver' => '8.0',
170    'key' => 'Microsoft/VCExpress/8.0/Setup/VC/ProductDir',
171    'dll_path' => '../SDK/v2.0/Bin',
172    'dll_suffix' => '80'
173);
174my %msvs_2005 = (
175    'ver' => '8.0',
176    'key' => 'Microsoft/VisualStudio/8.0/Setup/VS/ProductDir',
177    'dll_path' => 'Visual Studio .NET Professional 2005 - English',
178    'dll_suffix' => '80'
179);
180my %msvc_2005 = (
181    'ver' => '8.0',
182    'key' => 'Microsoft/VisualStudio/8.0/Setup/VC/ProductDir',
183    'dll_path' => '../SDK/v2.0/Bin',
184    'dll_suffix' => '80'
185);
186my %msvs_2008 = (
187    'ver' => '9.0',
188    'key' => 'Microsoft/VisualStudio/9.0/Setup/VS/ProductDir',
189    'dll_path' => 'VC/redist/x86/Microsoft.VC90.CRT',
190    'dll_suffix' => '90'
191);
192my %msvc_2008 = (
193    'ver' => '9.0',
194    'key' => 'Microsoft/VisualStudio/9.0/Setup/VC/ProductDir',
195    'dll_path' => 'redist/x86/Microsoft.VC90.CRT',
196    'dll_suffix' => '90'
197);
198my %msvs_express_2008 = (
199    'ver' => '9.0',
200    'key' => 'Microsoft/VCExpress/9.0/Setup/VS/ProductDir',
201    'dll_path' => 'VC/redist/x86/Microsoft.VC90.CRT',
202    'dll_suffix' => '90'
203);
204my %msvc_express_2008 = (
205    'ver' => '9.0',
206    'key' => 'Microsoft/VCExpress/9.0/Setup/VC/ProductDir',
207    'dll_path' => 'redist/x86/Microsoft.VC90.CRT',
208    'dll_suffix' => '90'
209);
210
211sub find_msvs()
212{
213    my @ms_versions = ( \%msvs_2008, \%msvs_express_2008, \%msvs_2005, \%msvs_express_2005, \%msvs_net_2003_ea, \%msvs_net_2003 );
214
215    for $ver (@ms_versions)
216    {
217	my $install = reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/" . $ver->{'key'});
218	if (defined $install && $install ne '') {
219	    $ver->{'product_dir'} = $install;
220	    return $ver;
221	}
222	$install = reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/Wow6432Node/" . $ver->{'key'});
223	if (defined $install && $install ne '') {
224	    $ver->{'product_dir'} = $install;
225	    return $ver;
226	}
227    }
228    die "Can't find MS Visual Studio / VC++";
229}
230
231sub find_msvc()
232{
233    my @ms_versions = ( \%msvc_2008, \%msvc_express_2008, \%msvc_2005, \%msvc_express_2005, \%msvc_net_2003 );
234
235    for $ver (@ms_versions)
236    {
237	my $install = reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/" . $ver->{'key'});
238	if (defined $install && $install ne '') {
239	    $ver->{'product_dir'} = $install;
240	    return $ver;
241	}
242	$install = reg_get_value("HKEY_LOCAL_MACHINE/SOFTWARE/Wow6432Node/" . $ver->{'key'});
243	if (defined $install && $install ne '') {
244	    $ver->{'product_dir'} = $install;
245	    return $ver;
246	}
247    }
248    die "Can't find MS Visual Studio / VC++";
249}
250
251sub print_msvc_ver()
252{
253    my $ver = find_msvc();
254    print $ver->{'ver'};
255}
256
257sub print_msvc_product_dir()
258{
259    my $ver = find_msvc();
260    print cygpath ($ver->{'product_dir'}, 'w', $output_format);
261}
262
263sub print_msvs_productdir()
264{
265    my $ver = find_msvs();
266    print cygpath ($ver->{'product_dir'}, 'w', $output_format);
267}
268
269sub print_csc_compiler_dir()
270{
271    my $dir = cygpath (reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/.NETFramework/InstallRoot"), 'w', $output_format);
272    my $csc_exe = `/bin/find "$dir" -iname csc.exe | grep "v2\." | head -n 1`;
273    print `dirname $csc_exe`;
274}
275
276sub print_dotnetsdk_dir()
277{
278    my $dir =
279          reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/.NETFramework/sdkInstallRootv1.1") ||
280          reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/.NETFramework/sdkInstallRootv2.0");
281    defined $dir || exit 1;
282    print cygpath ($dir, 'w', $output_format);
283}
284
285sub print_jdk_dir()
286{
287    my $softwareKey;
288    if ($aoo32OnWin64) {
289        $softwareKey = "HKEY_LOCAL_MACHINE/SOFTWARE/Wow6432Node/";
290    }  else {
291        $softwareKey = "HKEY_LOCAL_MACHINE/SOFTWARE/";
292    }
293    # Java 1.9 had to be different:
294    my $currentVersion = reg_get_value ($softwareKey . "JavaSoft/JDK/CurrentVersion");
295    if (defined $currentVersion) {
296        my $newDir = reg_get_value ($softwareKey . "JavaSoft/JDK/" . $currentVersion . "/JavaHome");
297        if (defined $newDir) {
298            print cygpath($newDir, 'w', $output_format);
299            return;
300        }
301    }
302    my $dir =
303	  reg_get_value ($softwareKey . "JavaSoft/Java\ Development\ Kit/1.8/JavaHome") ||
304	  reg_get_value ($softwareKey . "JavaSoft/Java\ Development\ Kit/1.7/JavaHome") ||
305	  reg_get_value ($softwareKey . "JavaSoft/Java\ Development\ Kit/1.6/JavaHome") ||
306	  reg_get_value ($softwareKey . "JavaSoft/Java\ Development\ Kit/1.5/JavaHome") ||
307	  reg_get_value ($softwareKey . "JavaSoft/Java\ Development\ Kit/1.4/JavaHome") ||
308	  reg_get_value ($softwareKey . "JavaSoft/Java\ Development\ Kit/1.3/JavaHome");
309    defined $dir || exit 1;
310    print cygpath($dir, 'w', $output_format);
311}
312
313sub print_nsis_dir()
314{
315    my $dir = reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/NSIS/@");
316    print cygpath ($dir, 'w', $output_format) if defined $dir;
317}
318
319sub copy_dll($$$)
320{
321    my ($src, $fname, $dest) = @_;
322
323    -f "$src/$fname" || die "can't find $src";
324    -d $dest || die "no directory $dest";
325
326	print STDERR "Copying $src/$fname to $dest\n";
327    copy ("$src/$fname", $dest) || die "copy failed: $!";
328    chmod (0755, "$dest/$fname") || die "failed to set dll executable: $!";
329}
330
331sub msvc_find_version($)
332{
333    my $checkpath = shift;
334    my $ver = find_msvc();
335    my $srcdir = (cygpath ($ver->{'product_dir'}, 'w', 'u') . '/' .
336		  $ver->{$checkpath});
337    -d $srcdir && return $ver;
338    $ver = find_msvs();
339    $srcdir = (cygpath ($ver->{'product_dir'}, 'w', 'u') . '/' .
340		  $ver->{$checkpath});
341    -d $srcdir && return $ver;
342    return undef;
343}
344
345sub msvc_copy_dlls($)
346{
347    my $dest = shift;
348    my $ver = msvc_find_version('dll_path');
349    defined $ver || return;
350    my $srcdir = (cygpath ($ver->{'product_dir'}, 'w', 'u') . '/' .
351		  $ver->{'dll_path'});
352
353    copy_dll ($srcdir, "msvcp" . $ver->{'dll_suffix'} . ".dll",
354	      $dest . $ver->{'dll_suffix'});
355    copy_dll ($srcdir, "msvcr" . $ver->{'dll_suffix'} . ".dll",
356	      $dest . $ver->{'dll_suffix'});
357    if ($ver->{'dll_suffix'} >= 90) {
358        copy_dll ($srcdir, "msvcm" . $ver->{'dll_suffix'} . ".dll",
359                  $dest . $ver->{'dll_suffix'});
360        copy_dll ($srcdir, "Microsoft.VC90.CRT.manifest", $dest . $ver->{'dll_suffix'});
361    }
362}
363
364if (!@ARGV) {
365    print_syntax();
366    exit 1;
367}
368
369my @commands = ();
370my $opt;
371while (@ARGV) {
372    $opt = shift @ARGV;
373
374    if ($opt eq '-w' || $opt eq '-u') {
375	$output_format = substr($opt, 1, 1);
376    } else {
377	push @commands, $opt;
378    }
379}
380
381while (@commands) {
382    $opt = shift @commands;
383
384    if ($opt eq '--aoo32-on-win64') {
385	$aoo32OnWin64 = 1;
386    } elsif ($opt eq '--msvc-ver') {
387	print_msvc_ver();
388    } elsif ($opt eq '--msvc-copy-dlls') {
389	my $dest = shift @commands;
390	defined $dest || die "copy-dlls requires a destination directory";
391	msvc_copy_dlls( $dest );
392    } elsif ($opt eq '--msvs-productdir') {
393	print_msvs_productdir();
394    } elsif ($opt eq '--msvc-productdir') {
395	print_msvc_product_dir();
396    } elsif ($opt eq '--dotnetsdk-dir') {
397	print_dotnetsdk_dir();
398    } elsif ($opt eq '--csc-compilerdir') {
399	print_csc_compiler_dir();
400    } elsif ($opt eq '--psdk-home') {
401	print_psdk_home();
402    } elsif ($opt eq '--jdk-home') {
403	print_jdk_dir();
404    } elsif ($opt eq '--nsis-dir') {
405	print_nsis_dir();
406    } elsif ($opt eq '--help' || $opt eq '/?') {
407	print_syntax();
408    } else {
409	print "Unknown option '$opt'\n";
410	print_syntax();
411	exit 1;
412    }
413}
414
415