Microsoft KB Archive/90493

{|
 * width="100%"|

HOWTO: How To Determine Whether an Application is Console or GUI

 * }

Q90493

-

The information in this article applies to:


 * Microsoft Win32 Application Programming Interface (API), used with:
 * the operating system: Microsoft Windows NT, versions 3.1, 3.5, 3.51, 4.0
 * Microsoft Windows 95
 * the operating system: Microsoft Windows 2000

-

SUMMARY
In order to determine whether an application is console or GUI, you must parse the EXEheader. The header contains a field called 'Subsystem'. This field determines both the subsystem the application is to run under and the type of interface it requires. The values consist of:

  IMAGE_SUBSYSTEM_NATIVE               1 IMAGE_SUBSYSTEM_WINDOWS_GUI         2 IMAGE_SUBSYSTEM_WINDOWS_CUI         3 IMAGE_SUBSYSTEM_OS2_CUI             5 IMAGE_SUBSYSTEM_POSIX_CUI           7 IMAGE_SUBSYSTEM_NATIVE_WINDOWS      8 IMAGE_SUBSYSTEM_WINDOWS_CE_GUI      9

Sample Code
#include 
 * 1) include 

VOID main(int, char **); DWORD AbsoluteSeek(HANDLE, DWORD); VOID ReadBytes(HANDLE, LPVOID, DWORD); VOID WriteBytes(HANDLE, LPVOID, DWORD); VOID CopySection(HANDLE, HANDLE, DWORD);


 * 1) define XFER_BUFFER_SIZE 2048

VOID main(int argc, char *argv[]) {   HANDLE hImage;

DWORD bytes; DWORD iSection; DWORD SectionOffset; DWORD CoffHeaderOffset; DWORD MoreDosHeader[16];

ULONG ntSignature;

IMAGE_DOS_HEADER     image_dos_header; IMAGE_FILE_HEADER    image_file_header; IMAGE_OPTIONAL_HEADER image_optional_header; IMAGE_SECTION_HEADER image_section_header;

if (argc != 2) {       printf(&quot;USAGE: %s program_file_name\n&quot;, argv[1]); exit(1); }

/*    *  Open the reference file. */    hImage = CreateFile(argv[1],                        GENERIC_READ,                        FILE_SHARE_READ,                        NULL,                        OPEN_EXISTING,                        FILE_ATTRIBUTE_NORMAL,                        NULL);

if (INVALID_HANDLE_VALUE == hImage) {       printf(&quot;Could not open %s, error %lu\n&quot;, argv[1], GetLastError); exit(1); }

/*    *  Read the MS-DOS image header. */    ReadBytes(hImage,              &image_dos_header,              sizeof(IMAGE_DOS_HEADER));

if (IMAGE_DOS_SIGNATURE != image_dos_header.e_magic) {       printf(&quot;Sorry, I do not understand this file.\n&quot;); exit(1); }

/*    *  Read more MS-DOS header. */    ReadBytes(hImage,              MoreDosHeader,              sizeof(MoreDosHeader));

/*    *  Get actual COFF header. */    CoffHeaderOffset = AbsoluteSeek(hImage, image_dos_header.e_lfanew) + sizeof(ULONG);

ReadBytes (hImage, &ntSignature, sizeof(ULONG));

if (IMAGE_NT_SIGNATURE != ntSignature) {    printf(&quot;Missing NT signature. Unknown file type.\n&quot;); exit(1); }

SectionOffset = CoffHeaderOffset + IMAGE_SIZEOF_FILE_HEADER + IMAGE_SIZEOF_NT_OPTIONAL_HEADER;

ReadBytes(hImage,             &image_file_header,              IMAGE_SIZEOF_FILE_HEADER);

/*    *  Read optional header. */    ReadBytes(hImage,              &image_optional_header,              IMAGE_SIZEOF_NT_OPTIONAL_HEADER);

switch (image_optional_header.Subsystem) {   case IMAGE_SUBSYSTEM_UNKNOWN: printf(&quot;Type is unknown.\n&quot;); break;

case IMAGE_SUBSYSTEM_NATIVE: printf(&quot;Type is native.\n&quot;); break;

case IMAGE_SUBSYSTEM_WINDOWS_GUI: printf(&quot;Type is Windows GUI.\n&quot;); break;

case IMAGE_SUBSYSTEM_WINDOWS_CUI: printf(&quot;Type is Windows CUI.\n&quot;); break;

case IMAGE_SUBSYSTEM_OS2_CUI: printf(&quot;Type is OS/2 CUI.\n&quot;); break;

case IMAGE_SUBSYSTEM_POSIX_CUI: printf(&quot;Type is POSIX CUI.\n&quot;); break;

case IMAGE_SUBSYSTEM_NATIVE_WINDOWS: printf(&quot;Type is native Win9x driver.\n&quot;); break;

case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI: printf(&quot;Type is Windows CE.\n&quot;); break;

default: printf(&quot;Unknown type %u.\n&quot;, image_optional_header.Subsystem); break; } }

DWORD AbsoluteSeek(HANDLE hFile,            DWORD  offset) {   DWORD newOffset;

if ((newOffset = SetFilePointer(hFile,                                   offset,                                    NULL,                                    FILE_BEGIN)) == 0xFFFFFFFF) {       printf(&quot;SetFilePointer failed, error %lu.\n&quot;, GetLastError); exit(1); }

return newOffset; }

VOID ReadBytes(HANDLE hFile,         LPVOID buffer,          DWORD  size) {   DWORD bytes;

if (!ReadFile(hFile, buffer, size, &bytes, NULL)) {       printf(&quot;ReadFile failed, error %lu.\n&quot;, GetLastError); exit(1); }   else if (size != bytes) {       printf(&quot;Read the wrong number of bytes, expected %lu, got %lu.\n&quot;,               size, bytes); exit(1); } } Additional query words: 3.10 3.50

Keywords : kbnokeyword kbConsole kbKernBase kbOSWinNT310 kbOSWinNT350 kbOSWinNT351 kbOSWinNT400 kbOSWin2000 kbOSWin95 kbDSupport kbGrpDSKernBase

Issue type : kbhowto

Technology : kbAudDeveloper kbWin32sSearch kbWin32API