xref: /openbsd/gnu/usr.bin/perl/win32/bin/exetype.pl (revision 5759b3d2)
1#!perl -w
2use strict;
3
4# All the IMAGE_* structures are defined in the WINNT.H file
5# of the Microsoft Platform SDK.
6
7my %subsys = (NATIVE    => 1,
8              WINDOWS   => 2,
9              CONSOLE   => 3,
10              POSIX     => 7,
11              WINDOWSCE => 9);
12
13unless (0 < @ARGV && @ARGV < 3) {
14    printf "Usage: $0 exefile [%s]\n", join '|', sort keys %subsys;
15    exit;
16}
17
18$ARGV[1] = uc $ARGV[1] if $ARGV[1];
19unless (@ARGV == 1 || defined $subsys{$ARGV[1]}) {
20    (my $subsys = join(', ', sort keys %subsys)) =~ s/, (\w+)$/ or $1/;
21    print "Invalid subsystem $ARGV[1], please use $subsys\n";
22    exit;
23}
24
25my ($record,$magic,$signature,$offset,$size);
26open EXE, '+<', $ARGV[0] or die "Cannot open $ARGV[0]: $!\n";
27binmode EXE;
28
29# read IMAGE_DOS_HEADER structure
30read EXE, $record, 64;
31($magic,$offset) = unpack "Sx58L", $record;
32
33die "$ARGV[0] is not an MSDOS executable file.\n"
34    unless $magic == 0x5a4d; # "MZ"
35
36# read signature, IMAGE_FILE_HEADER and first WORD of IMAGE_OPTIONAL_HEADER
37seek EXE, $offset, 0;
38read EXE, $record, 4+20+2;
39($signature,$size,$magic) = unpack "Lx16Sx2S", $record;
40
41die "PE header not found" unless $signature == 0x4550; # "PE\0\0"
42
43die "Optional header is neither in NT32 nor in NT64 format"
44    unless ($size == 224 && $magic == 0x10b) || # IMAGE_NT_OPTIONAL_HDR32_MAGIC
45           ($size == 240 && $magic == 0x20b);   # IMAGE_NT_OPTIONAL_HDR64_MAGIC
46
47# Offset 68 in the IMAGE_OPTIONAL_HEADER(32|64) is the 16 bit subsystem code
48seek EXE, $offset+4+20+68, 0;
49if (@ARGV == 1) {
50    read EXE, $record, 2;
51    my ($subsys) = unpack "S", $record;
52    $subsys = {reverse %subsys}->{$subsys} || "UNKNOWN($subsys)";
53    print "$ARGV[0] uses the $subsys subsystem.\n";
54}
55else {
56    print EXE pack "S", $subsys{$ARGV[1]};
57}
58close EXE;
59__END__
60
61=head1 NAME
62
63exetype - Change executable subsystem type between "Console" and "Windows"
64
65=head1 SYNOPSIS
66
67	C:\perl\bin> copy perl.exe guiperl.exe
68	C:\perl\bin> exetype guiperl.exe windows
69
70=head1 DESCRIPTION
71
72This program edits an executable file to indicate which subsystem the
73operating system must invoke for execution.
74
75You can specify any of the following subsystems:
76
77=over
78
79=item CONSOLE
80
81The CONSOLE subsystem handles a Win32 character-mode application that
82use a console supplied by the operating system.
83
84=item WINDOWS
85
86The WINDOWS subsystem handles an application that does not require a
87console and creates its own windows, if required.
88
89=item NATIVE
90
91The NATIVE subsystem handles a Windows NT device driver.
92
93=item WINDOWSCE
94
95The WINDOWSCE subsystem handles Windows CE consumer electronics
96applications.
97
98=item POSIX
99
100The POSIX subsystem handles a POSIX application in Windows NT.
101
102=back
103
104=head1 AUTHOR
105
106Jan Dubois <jand@activestate.com>
107
108=cut
109