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