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