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