summaryrefslogtreecommitdiff
path: root/win32/bin
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>2000-02-15 05:42:17 +0000
committerGurusamy Sarathy <gsar@cpan.org>2000-02-15 05:42:17 +0000
commitc4bbdec38b7d8acc8d248c7cddb7da8c7ed09205 (patch)
treea72077434f04cf9064b7c4266a85276bc2a03113 /win32/bin
parenteb99164fe573f928a1e23c686cddfafdbe9ae10a (diff)
downloadperl-c4bbdec38b7d8acc8d248c7cddb7da8c7ed09205.tar.gz
update exetype.pl tool
p4raw-id: //depot/perl@5094
Diffstat (limited to 'win32/bin')
-rw-r--r--win32/bin/exetype.pl75
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