This can be done either by number, or by name. Most names are from the
documentation for LINK.EXE's /SUBSYSTEM option, but a few were made up
based on the constants and documentation on MS's PE Format document.
---
I wasn't sure about using strcasecmp, but I grepped and gendef uses it
without a configure check, so it must be relatively safe...
mingw-w64-tools/genpeimg/src/genpeimg.c | 69 +++++++++++++++++++++++++
mingw-w64-tools/genpeimg/src/img.h | 1 +
mingw-w64-tools/genpeimg/src/img_pe.c | 7 +++
3 files changed, 77 insertions(+)
diff --git a/mingw-w64-tools/genpeimg/src/genpeimg.c
b/mingw-w64-tools/genpeimg/src/genpeimg.c
index c18d9ab9f..af17129fa 100644
--- a/mingw-w64-tools/genpeimg/src/genpeimg.c
+++ b/mingw-w64-tools/genpeimg/src/genpeimg.c
@@ -21,16 +21,41 @@
#include "img.h"
+static const struct SUBSYSTEM_MAPPING {
+ const char * const name;
+ const unsigned short value;
+} SUBSYSTEMS[] = {
+ { "BOOT_APPLICATION", 16 },
+ { "CONSOLE", 3 },
+ { "EFI_APPLICATION", 10 },
+ { "EFI_BOOT_SERVICE_DRIVER", 11},
+ { "EFI_ROM", 13 },
+ { "EFI_RUNTIME_DRIVER", 12},
+ { "NATIVE", 1 },
+ { "POSIX", 7 },
+ { "WINDOWS", 2 },
+ /* not listed on MS doc page for /SUBSYSTEM option to LINK */
+ { "OS2", 5 },
+ { "NATIVE_WINDOWS9X", 8 },
+ { "WINDOWS_CE", 9 },
+ { "XBOX", 14 },
+ { "UNKNOWN", 0 },
+ { NULL, 0 }
+};
+
unsigned short set_pe_hdr_chara = 0;
unsigned short mask_pe_hdr_chara = 0xffff;
unsigned short set_pe_opt_hdr_dll_chara = 0;
unsigned short mask_pe_opt_hdr_dll_chara = 0xffff;
+unsigned short set_subsystem = 0xffff;
int dump_information = 0;
static char *file_name = NULL;
static void __attribute__((noreturn))
show_usage (void)
{
+ const struct SUBSYSTEM_MAPPING *p;
+
fprintf (stderr, "genpeimg [options] files...\n");
fprintf (stderr, "\nOptions:\n"
" -p Takes as addition argument one or more of the following\n"
@@ -58,6 +83,12 @@ show_usage (void)
" w: WDM-driver\n"
" c: control-flow-guard\n"
" t: terminal-server-aware\n");
+ fprintf (stderr,
+ " -s Sets the image subsystem to the specified value\n");
+ for (p = &SUBSYSTEMS[0]; p->name; ++p)
+ fprintf (stderr, " %s\n", p->name);
+ fprintf (stderr,
+ " or an integer value\n");
fprintf (stderr,
" -h: Show this page.\n"
" -x: Dump image information to stdout\n");
@@ -71,6 +102,7 @@ pass_args (int argc, char **argv)
int has_error = 0;
while (argc-- > 0)
{
+ const struct SUBSYSTEM_MAPPING *p;
int is_pos = 1;
char *h = *argv++;
if (h[0] != '-')
@@ -204,6 +236,41 @@ pass_args (int argc, char **argv)
++h;
}
break;
+ case 's':
+ if (h[2] != 0)
+ goto error_point;
+ if (argc == 0)
+ {
+ fprintf (stderr, "Missing argument for -s\n");
+ show_usage ();
+ }
+ h = *argv++; argc--;
+
+ for (p = &SUBSYSTEMS[0]; p->name; ++p)
+ {
+ if (0 == strcasecmp (h, p->name))
+ {
+ set_subsystem = p->value;
+ break;
+ }
+ }
+ if (p->name == NULL)
+ {
+ unsigned long ulparam = strtoul (h, &h, 0);
+ /* TODO: support ",major.minor" suffix? */
+ if (*h != 0)
+ {
+ fprintf (stderr, "Unknown subsystem '%s' for -s\n",
*(argv-1));
+ has_error = 1;
+ }
+ if (ulparam >= 0xffff)
+ {
+ fprintf (stderr, "Subsystem '%s' out of range for -s\n",
*(argv-1));
+ has_error = 1;
+ }
+ set_subsystem = (unsigned short)ulparam;
+ }
+ break;
case 'x':
if (h[2] == 0)
{
@@ -250,6 +317,8 @@ int main (int argc, char **argv)
/* First we need to do actions which aren't modifying image's size. */
peimg_set_hdr_characeristics (pe, set_pe_hdr_chara, mask_pe_hdr_chara);
peimg_set_hdr_opt_dll_characteristics (pe, set_pe_opt_hdr_dll_chara,
mask_pe_opt_hdr_dll_chara);
+ if (set_subsystem != 0xffff)
+ peimg_set_hdr_opt_subsystem (pe, set_subsystem);
if (pe->pimg->is_modified)
pe->pimg->want_save = 1;
peimg_free (pe);
diff --git a/mingw-w64-tools/genpeimg/src/img.h
b/mingw-w64-tools/genpeimg/src/img.h
index dc4944150..4a927c860 100644
--- a/mingw-w64-tools/genpeimg/src/img.h
+++ b/mingw-w64-tools/genpeimg/src/img.h
@@ -78,6 +78,7 @@ void peimg_show (pe_image *ppeimg, FILE *outfp);
void peimg_set_hdr_characeristics (pe_image *pe, unsigned short set, unsigned
short mask);
void peimg_set_hdr_opt_dll_characteristics (pe_image *pe, unsigned short set,
unsigned short mask);
+void peimg_set_hdr_opt_subsystem (pe_image *pe, unsigned short subsystem);
#define PEIMG_GET_UCHAR(PEIMG, POS) fimg_get_uchar_at ((PEIMG)->pimg,
((PEIMG)->start_pe + (POS)))
#define PEIMG_GET_USHORT(PEIMG, POS) fimg_get_ushort_at ((PEIMG)->pimg,
((PEIMG)->start_pe + (POS)), (PEIMG)->is_bigendian)
diff --git a/mingw-w64-tools/genpeimg/src/img_pe.c
b/mingw-w64-tools/genpeimg/src/img_pe.c
index 345fc4e44..71794abde 100644
--- a/mingw-w64-tools/genpeimg/src/img_pe.c
+++ b/mingw-w64-tools/genpeimg/src/img_pe.c
@@ -344,6 +344,13 @@ peimg_show (pe_image *ppeimg, FILE *outfp)
}
}
+void
+peimg_set_hdr_opt_subsystem (pe_image *pe, unsigned short subsystem)
+{
+ if (subsystem != PEIMG_GET_USHORT (pe, pe->optional_hdr_pos + 68))
+ PEIMG_SET_USHORT (pe, pe->optional_hdr_pos + 68, subsystem);
+}
+
void
peimg_set_hdr_opt_dll_characteristics (pe_image *pe, unsigned short set,
unsigned short mask)
{
--
2.32.0.windows.2
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public