boegehol@az33.informatik.uni-stuttgart.de (Harald Boegeholz) (02/10/90)
In article <1989@ncrcan.Toronto.NCR.COM> brian@ncrcan.Toronto.NCR.COM (Brian A. Onn) writes: But does anyone know which bit int the header changes? I don't have any of the PM toolkits, but I do have MSC5.1. If I knew which bit was the WINABLE bit, then I could flip it and all would be fine, n'est pas? I wrote a little program called exehdr that allows to modify the flag word in the new exe header. Starting it with EXEFLAGS x.EXE +200 sets the WINABLE bit of an exe file, but -- as opposed to the toolkit programs -- WITHOUT CHECKING if the program uses any calls that are not allowed. Since the program is only a few lines long, I appended the source below. For the programs you write yourself, there is a more elegant way to set the WINDOWABLE bit: use a DEF-file when linking. The minimum DEF file that will do the job contains the single line NAME WINDOWCOMPAT You can be slightly more elaborate, as in the exeflags program below. Hope that helps Harald Boegeholz ===== source file exeflags.c follows ... ==== /* this is exeflags.c. Exeflag modifies the flags in OS/2 executable files. (new header offset 0x0c) */ #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #define INCL_BASE #include <os2.h> static void check_error(int err, int line, char *file); static void error(char *, ...); int main(int, char **); #define chk(err) check_error(err, __LINE__, __FILE__) static void check_error(err, line, file) int err; int line; char *file; { if (err==0) return; error("OS/2 error occured: code %d. Sourcefile %s (line %d)\n", err, file, line); } static void error(fmt, ...) char *fmt; { va_list arg_ptr; va_start(arg_ptr,fmt); vprintf(fmt,arg_ptr); va_end(arg_ptr); exit(2); } struct _oldexehdr { USHORT mz; char dummy[0x3a]; long newhdradr; } oldexehdr; struct _newexehdr { USHORT ne; char dummy[0x0a]; USHORT flags; } newexehdr; int main(argc, argv) int argc; char **argv; { USHORT action, bytesread, byteswritten; HFILE exefile; long newpos; USHORT mask; printf("This is EXEFLAGS. (c) 1989 by Harald Boegeholz\n" "This program modifies the flags of an EXE-file\n"); if (argc!=3 || (argv[2][0]!='+' && argv[2][0]!='-')) error("usage: EXEFLAGS exefilename [+|-]mask\n" "example: set window compatibility flag: EXEFLAGS x.EXE +200\n"); if (sscanf(&argv[2][1], "%4hx", &mask)!=1) error("invalid mask: `%s'!\n", &argv[2][1]); chk(DosOpen(argv[1], &exefile, &action, 0L, 0, 1, 0x12, 0L)); chk(DosRead(exefile, &oldexehdr, sizeof oldexehdr, &bytesread)); if (bytesread!=sizeof oldexehdr) error("Invalid EXE-file: unexpected EOF\n"); if (oldexehdr.mz != 0x5a4d) error("Invalid EXE-file: error in old header\n"); chk(DosChgFilePtr(exefile, oldexehdr.newhdradr, 0, &newpos)); chk(DosRead(exefile, &newexehdr, sizeof newexehdr, &bytesread)); if (bytesread!=sizeof newexehdr) error("Invalid EXE-file: unexpected EOF\n"); if (newexehdr.ne != 0x454e) error("Invalid EXE-file: error in new header\n"); printf("Changing flags: %.4X", newexehdr.flags); if (argv[2][0]=='+') newexehdr.flags |= mask; else newexehdr.flags &= ~mask; printf(" to %.4X...\n", newexehdr.flags); chk(DosChgFilePtr(exefile, oldexehdr.newhdradr, 0, &newpos)); chk(DosWrite(exefile, &newexehdr, sizeof newexehdr, &byteswritten)); if (byteswritten!=sizeof newexehdr) error("Error writing to EXE-file. Disk full?\n"); chk(DosClose(exefile)); printf("done.\n"); return 0; } ====== file exeflags.def follows ... ===== ; Module definition file for EXEFLAGS program NAME Exeflags WINDOWCOMPAT DESCRIPTION 'Exeflags (c) 1989 by Harald Boegeholz' ====== make file exeflags follows ... ===== EXEFLAGS.OBJ: EXEFLAGS.C cl -W3 -c exeflags.c EXEFLAGS.EXE: EXEFLAGS.OBJ link exeflags,,,/NOD:slibce slibcep,exeflags