diff options
author | Gurusamy Sarathy <gsar@cpan.org> | 2000-02-15 05:42:17 +0000 |
---|---|---|
committer | Gurusamy Sarathy <gsar@cpan.org> | 2000-02-15 05:42:17 +0000 |
commit | c4bbdec38b7d8acc8d248c7cddb7da8c7ed09205 (patch) | |
tree | a72077434f04cf9064b7c4266a85276bc2a03113 /win32/bin | |
parent | eb99164fe573f928a1e23c686cddfafdbe9ae10a (diff) | |
download | perl-c4bbdec38b7d8acc8d248c7cddb7da8c7ed09205.tar.gz |
update exetype.pl tool
p4raw-id: //depot/perl@5094
Diffstat (limited to 'win32/bin')
-rw-r--r-- | win32/bin/exetype.pl | 75 |
1 files changed, 61 insertions, 14 deletions
diff --git a/win32/bin/exetype.pl b/win32/bin/exetype.pl index 5846b3ee3b..27e3b94bc8 100644 --- a/win32/bin/exetype.pl +++ b/win32/bin/exetype.pl @@ -1,26 +1,60 @@ #!perl -w use strict; -unless (@ARGV == 2) { - print "Usage: $0 exefile [CONSOLE|WINDOWS]\n"; + +# All the IMAGE_* structures are defined in the WINNT.H file +# of the Microsoft Platform SDK. + +my %subsys = (NATIVE => 1, + WINDOWS => 2, + CONSOLE => 3, + POSIX => 7, + WINDOWSCE => 9); + +unless (0 < @ARGV && @ARGV < 3) { + printf "Usage: $0 exefile [%s]\n", join '|', sort keys %subsys; exit; } -unless ($ARGV[1] =~ /^(console|windows)$/i) { - print "Invalid subsystem $ARGV[1], please use CONSOLE or WINDOWS\n"; + +$ARGV[1] = uc $ARGV[1] if $ARGV[1]; +unless (@ARGV == 1 || defined $subsys{$ARGV[1]}) { + (my $subsys = join(', ', sort keys %subsys)) =~ s/, (\w+)$/ or $1/; + print "Invalid subsystem $ARGV[1], please use $subsys\n"; exit; } -my ($record,$magic,$offset,$size); -open EXE, "+< $ARGV[0]" or die "Cannot open $ARGV[0]: $!"; + +my ($record,$magic,$signature,$offset,$size); +open EXE, "+< $ARGV[0]" or die "Cannot open $ARGV[0]: $!\n"; binmode EXE; -read EXE, $record, 32*4; + +# read IMAGE_DOS_HEADER structure +read EXE, $record, 64; ($magic,$offset) = unpack "Sx58L", $record; -die "Not an MSDOS executable file" unless $magic == 0x5a4d; + +die "$ARGV[0] is not an MSDOS executable file.\n" + unless $magic == 0x5a4d; # "MZ" + +# read signature, IMAGE_FILE_HEADER and first WORD of IMAGE_OPTIONAL_HEADER seek EXE, $offset, 0; -read EXE, $record, 24; -($magic,$size) = unpack "Lx16S", $record; -die "PE header not found" unless $magic == 0x4550; -die "Optional header not in NT32 format" unless $size == 224; -seek EXE, $offset+24+68, 0; -print EXE pack "S", uc($ARGV[1]) eq 'CONSOLE' ? 3 : 2; +read EXE, $record, 4+20+2; +($signature,$size,$magic) = unpack "Lx16Sx2S", $record; + +die "PE header not found" unless $signature == 0x4550; # "PE\0\0" + +die "Optional header is neither in NT32 nor in NT64 format" + unless ($size == 224 && $magic == 0x10b) || # IMAGE_NT_OPTIONAL_HDR32_MAGIC + ($size == 240 && $magic == 0x20b); # IMAGE_NT_OPTIONAL_HDR64_MAGIC + +# Offset 68 in the IMAGE_OPTIONAL_HEADER(32|64) is the 16 bit subsystem code +seek EXE, $offset+4+20+68, 0; +if (@ARGV == 1) { + read EXE, $record, 2; + my ($subsys) = unpack "S", $record; + $subsys = {reverse %subsys}->{$subsys} || "UNKNOWN($subsys)"; + print "$ARGV[0] uses the $subsys subsystem.\n"; +} +else { + print EXE pack "S", $subsys{$ARGV[1]}; +} close EXE; __END__ @@ -52,6 +86,19 @@ use a console supplied by the operating system. The WINDOWS subsystem handles an application that does not require a console and creates its own windows, if required. +=item NATIVE + +The NATIVE subsystem handles a Windows NT device driver. + +=item WINDOWSCE + +The WINDOWSCE subsystem handles Windows CE consumer electronics +applications. + +=item POSIX + +The POSIX subsystem handles a POSIX application in Windows NT. + =back =head1 AUTHOR |