//ÛßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßÛ
//Û                                                       Û
//Û      Virtual Pascal Runtime Library.  Version 2.1.    Û
//Û      OS/2 & Win32 Executable Header Definitions       Û
//Û      ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÛ
//Û      Copyright (C) 1995-2000 vpascal.com              Û
//Û                                                       Û
//ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß

{&AlignRec+,Use32-}

unit ExeHdr;

interface

{----[ EXE ]----}

type
  bbmask    = Word;

  exe = packed record
    eid        : Word;  // contains EXEID, below
    elast      : Word;  // # of Bytes in last page
    epagsiz    : Word;  // # of pages in whole file
    erelcnt    : Word;  // # of relocation entrys
    ehdrsiz    : Word;  // size of header, in paragraphs
    eminfre    : Word;  // min # of free paragraphs needed
    emaxfre    : Word;  // max # of free paragraphs needed
    eiSS       : Word;  // initial SS value
    eiSP       : Word;  // initial SP value
    enegsum    : Word;  // negative sum of entire file
    eiIP       : Word;  // initial IP value
    eiCS       : Word;  // initial CS value
    ereloff    : Word;  // offset in file of relocation table
    eovlnum    : Word;  // number of the overlay

//     the following fields may not be present.
//              ereloff = 28            not present
//                      = 30            exe.ever present and valid
//                      = 32            exe.ever field contains garbage
//              ereloff > 32            exe.ever present and valid
//                                              = 0 if "don't know"
//

    ever       : Word;  // version # of producing linker
    dumy       : Word;  // unused

//     the following fields may not be present - if the exe.ereloff
//      value encompasses the fields then they are present and valid.

    ebb        : bbmask;                // behavior bits
    dumy2      : array[0..6] of Word;   // must be 0 until defined
  end;

const
  ExeId = $5A4D;        // Magic ID value


{----[ EXE386 ]----}

// Data structure definitions for the OS/2 executable file format (flat model)

const
  BitPerWord    = 16;
  BitPerByte    = 8;
  ObjPageLen    = 4096;
  E32Magic1     = 'L';      // New Magic number  "LX"
  E32Magic2     = 'X';      // New Magic number  "LX"
  E32Magic      = $584c;    // New Magic number  "LX"
  E32ResByteS1  = 0;        // First Bytes reserved
  E32ResByteS2  = 0;        // Second Bytes reserved
  E32ResByteS3  = 20;       // Third Bytes reserved
  E32LEBO       = $00;      // Little Endian Byte Order
  E32BEBO       = $01;      // Big Endian Byte Order
  E32LEWO       = $00;      // Little Endian Word Order
  E32BEWO       = $01;      // Big Endian Word Order
  E32Level      = 0;        // 32-bit EXE format Level
  E32CPU286     = $001;     // Intel 80286 or upwardly compatibile
  E32CPU386     = $002;     // Intel 80386 or upwardly compatibile
  E32CPU486     = $003;     // Intel 80486 or upwardly compatibile

type
  e32_exe = packed record           // New 32-bit .EXE header
    e32_Magic         : array[0..1] of Byte; // Magic number E32_Magic
    e32_border        : Byte;       // The Byte ordering for the .EXE
    e32_Worder        : Byte;       // The Word ordering for the .EXE
    e32_Level         : Longint;    // The EXE format Level for now = 0
    e32_cpu           : Word;       // The CPU type
    e32_os            : Word;       // The OS type
    e32_ver           : Longint;    // Module version
    e32_mflags        : Longint;    // Module flags
    e32_mpages        : Longint;    // Module # pages
    e32_startobj      : Longint;    // Object # for instruction pointer
    e32_eip           : Longint;    // Extended instruction pointer
    e32_stackobj      : Longint;    // Object # for stack pointer
    e32_esp           : Longint;    // Extended stack pointer
    e32_pagesize      : Longint;    // .EXE page size
    e32_pageshift     : Longint;    // Page alignment shift in .EXE
    e32_fixupsize     : Longint;    // Fixup section size
    e32_fixupsum      : Longint;    // Fixup section checksum
    e32_ldrsize       : Longint;    // Loader section size
    e32_ldrsum        : Longint;    // Loader section checksum
    e32_objtab        : Longint;    // Object table offset
    e32_objcnt        : Longint;    // Number of objects in module
    e32_objmap        : Longint;    // Object page map offset
    e32_itermap       : Longint;    // Object iterated data map offset
    e32_rsrctab       : Longint;    // Offset of Resource Table
    e32_rsrccnt       : Longint;    // Number of resource entries
    e32_restab        : Longint;    // Offset of resident name table
    e32_enttab        : Longint;    // Offset of Entry Table
    e32_dirtab        : Longint;    // Offset of Module Directive Table
    e32_dircnt        : Longint;    // Number of module directives
    e32_fpagetab      : Longint;    // Offset of Fixup Page Table
    e32_frectab       : Longint;    // Offset of Fixup Record Table
    e32_impmod        : Longint;    // Offset of Import Module Name Table
    e32_impmodcnt     : Longint;    // Number of entries in Import Module Name Table
    e32_impproc       : Longint;    // Offset of Import Procedure Name Table
    e32_pagesum       : Longint;    // Offset of Per-Page Checksum Table
    e32_datapage      : Longint;    // Offset of Enumerated Data Pages
    e32_preload       : Longint;    // Number of preload pages
    e32_nrestab       : Longint;    // Offset of Non-resident Names Table
    e32_cbnrestab     : Longint;    // Size of Non-resident Name Table
    e32_nressum       : Longint;    // Non-resident Name Table Checksum
    e32_autodata      : Longint;    // Object # for automatic data object
    e32_debuginfo     : Longint;    // Offset of the debugging information
    e32_debuglen      : Longint;    // The length of the debugging info. in Bytes
    e32_instpreload   : Longint;    // Number of instance pages in preload section of .EXE file
    e32_instdemand    : Longint;    // Number of instance pages in demand load section of .EXE file
    e32_heapsize      : Longint;    // Size of heap - for 16-bit apps
    e32_stacksize     : Longint;    // Size of stack
    e32_res3: array[0..E32RESByteS3-1] of Byte; // Pad structure to 196 Bytes
  end;

//  Format of E32_MFLAGS(x):
//
//  Low Word has the following format:
//
//  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0  - bit no
//   |     |          | |     | | | |
//   |     |          | |     | | | +------- Per-Process Library Initialization
//   |     |          | |     | | +--------- SystemDLL (internal fixups discarded)
//   |     |          | |     | +----------- No Internal Fixups for Module in .EXE
//   |     |          | |     +------------- No External Fixups for Module in .EXE
//   |     |          | +------------------- Incompatible with PM Windowing
//   |     |          +--------------------- Compatible with PM Windowing
//   |     |                                 Uses PM Windowing API
//   |     +-------------------------------- Module not Loadable
//   +-------------------------------------- Library Module

const
  E32NotP           = $8000;     // Library Module - used as NENOTP
  E32NoLoad         = $2000;     // Module not Loadable
  E32PMAPI          = $0300;     // Uses PM Windowing API
  E32PMW            = $0200;     // Compatible with PM Windowing
  E32NoPMW          = $0100;     // Incompatible with PM Windowing
  E32NoExtFix       = $0020;     // NO External Fixups in .EXE
  E32NoIntFix       = $0010;     // NO Internal Fixups in .EXE
  E32SysDll         = $0008;     // System DLL, Internal Fixups discarded
  E32LibInit        = $0004;     // Per-Process Library Initialization
  E32LibTerm        = $40000000; // Per-Process Library Termination
  E32AppMask        = $0300;     // Application Type Mask

//  Format of E32_MFLAGS(x):
//
//  High Word has the following format:
//
//  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0  - bit no
//                                    | |
//                                    | +--- Protected memory library module
//                                    +----- Device driver

  E32ProtDll        = $10000;   // Protected memory library module
  E32Device         = $20000;   // Device driver
  E32ModExe         = $00000;   // .EXE module
  E32ModDll         = $08000;   // .DLL module
  E32ModProtDll     = $18000;   // Protected memory library module
  E32ModPdev        = $20000;   // Physical device driver
  E32ModVdev        = $28000;   // Virtual device driver
  E32ModMask        = $38000;   // Module type mask

// RELOCATION DEFINITIONS - RUN-TIME FIXUPS

type
  Offset = packed record
    Offset16 : Word;
    Offset32 : Longint;
  end;                          // 16-bit or 32-bit offset

  //**ET+ r32_rlc - Relocation item

  r32_rlc = packed record      // Relocation item
    nr_stype    : Byte;        // Source type - field shared with new_rlc
    nr_flags    : Byte;        // Flag Byte - field shared with new_rlc
    r32_soff    : Integer;     // Source offset
    r32_objmod  : Word;        // Target object number or Module ordinal

    r23_target : packed record
      Case Byte of
        0 : ( IntRef : Longint );                // Internal fixup

        1 : ( ExtRef : packed record
                Case Boolean of
                  True  : ( Proc : Longint );    // Procedure name offset
                  False : ( Ord  : Longint );    // Procedure ordinal
              end );

        2 : ( Addfix : packed record
                Entry   : Word;                  // Entry ordinal
                Addval  : Longint;               // Value added to the address
              end );
    end;

    r32_srccount : Word;       // Number of chained fixup records
    r32_chain    : Word;       // Chain head
  end;

//  In 32-bit .EXE file run-time relocations are written as varying size
//  records, so we need many size definitions.

const
  RIntSize16      = 8;
  RIntSize32      = 10;
  ROrdSize        = 8;
  RNamSize16      = 8;
  RNamSize32      = 10;
  RAddSize16      = 10;
  RAddSize32      = 12;

//  Format of NR_SType(x)
//
//       7 6 5 4 3 2 1 0  - bit no
//           | | | | | |
//           | | +-+-+-+--- Source type
//           | +----------- Fixup to 16:16 alias
//           +------------- List of source offset follows fixup recOrd

 NRSrcMask       = $0f;            // Source type mask
 NRAlias         = $10;            // Fixup to alias
 NRChain         = $20;            // List of source offset follows
                                   // fixup recOrd, source offset field
                                   // in fixup recOrd contains number
                                   // of elements in list

//  Format of NR_Flags(x) and R32_Flags(x):
//
//       7 6 5 4 3 2 1 0  - bit no
//       | | | |   | | |
//       | | | |   | +-+--- Reference type
//       | | | |   +------- Additive fixup
//       | | | +----------- 32-bit Target Offset Flag (1 - 32-bit; 0 - 16-bit)
//       | | +------------- 32-bit Additive Flag (1 - 32-bit; 0 - 16-bit)
//       | +--------------- 16-bit Object/Module Ordinal (1 - 16-bit; 0 - 8-bit)
//       +----------------- 8-bit import Ordinal (1 - 8-bit;
//                                                0 - NR32BitOff toggles
//                                                    between 16 and 32 bit
//                                                    Ordinal)

  NRREnt          = $03;           // Internal entry table fixup
  NR32BitOff      = $10;           // 32-bit Target Offset
  NR32BitAdd      = $20;           // 32-bit Additive fixup
  NR16ObjMod      = $40;           // 16-bit Object/Module Ordinal
  NR8BitOrd       = $80;           // 8-bit import Ordinal

//  Data structures for storing run-time fixups in linker virtual memory.
//
//  Each object has a list of Object Page Directories which specify
//  fixups for given page. Each page has its own hash table which is
//  used to detect fixups to the same target.

  PagePerDir      = 62;
  LG2Dir          = 7;


type
  ObjPageDir = packed record
    Next : Longint;                // Virtual poInter to next dir on list
    Ht   : array[ 0..PagePerDir-1 ] of Word; // Pointers to individual hash tables
  end;

// OBJECT TABLE

//**ET+ o32_obj Object Table Entry

  o32_obj = packed record         // Flat .Exe object table entry
    o32_Size       : LongInt;     // Object virtual Size
    o32_base       : LongInt;     // Object base virtual Address
    o32_flags      : LongInt;     // Attribute flags
    o32_pagemap    : LongInt;     // Object page map index
    o32_mapSize    : LongInt;     // Number of entries in object page map
    o32_reserved   : LongInt;     // Reserved
  end;

//  Format of O32_Flags(x)
//
//  High Word of dWord flag field is not used for now.
//  Low Word has the following format:
//
//  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0  - bit no
//   |  |  |  |     | | | | | | | | | | |
//   |  |  |  |     | | | | | | | | | | +--- Readable Object
//   |  |  |  |     | | | | | | | | | +----- Writeable Object
//   |  |  |  |     | | | | | | | | +------- Executable Object
//   |  |  |  |     | | | | | | | +--------- Resource Object
//   |  |  |  |     | | | | | | +----------- Object is Discardable
//   |  |  |  |     | | | | | +------------- Object is Shared
//   |  |  |  |     | | | | +--------------- Object has preload pages
//   |  |  |  |     | | | +----------------- Object has invalid pages
//   |  |  |  |     | | +------------------- Object is permanent and swappable
//   |  |  |  |     | +--------------------- Object is permanent and resident
//   |  |  |  |     +----------------------- Object is permanent and long lockable
//   |  |  |  +----------------------------- 16:16 alias required (80x86 specific)
//   |  |  +-------------------------------- Big/Default bit setting (80x86 specific)
//   |  +----------------------------------- Object is conforming for code (80x86 specific)
//   +-------------------------------------- Object I/O privilege Level (80x86 specific)

const
  ObjRead         = $0001;  // Readable Object
  ObjWrite        = $0002;  // Writeable Object
  ObjRsrc         = $0008;  // Resource Object
  ObjInvalid      = $0080;  // Object has invalid pages
  LNKNonperm      = $0600;  // Object is nonpermanent - should be
  ObjNonperm      = $0000;  // zero in the .Exe but LINK386 uses 6
  ObjPerm         = $0100;  // Object is permanent and swappable
  ObjResident     = $0200;  // Object is permanent and resident
  ObjContig       = $0300;  // Object is resident and contiguous
  ObjDynamic      = $0400;  // Object is permanent and long locable
  ObjTypeMask     = $0700;  // Object type mask
  ObjAlias16      = $1000;  // 16:16 alias required (80x86 specific)
  ObjBigDef       = $2000;  // Big/Default bit setting (80x86 specific)
  ObjIOPL         = $8000;  // Object I/O privilege Level (80x86 specific)

  ObjDiscard       = $0010; // Object is Discardable
  ObjShared        = $0020; // Object is Shared
  ObjPreLoad       = $0040; // Object has preload pages
  ObjExec          = $0004; // Executable Object
  ObjConform       = $4000; // Object is conforming for code (80x86 specific)

  NSDiscard        = $0010;  // Object is Discardable
  NSMove           = NSDiscard; //{ Moveable object is for sure Discardable
  NSShared         = $0020;  // Object is Shared
  NSPreLoad        = $0040;  // Object has preload pages
  NSExRd           = $0004;  // Executable Object
  NSConform        = $4000;  // Object is conforming for code (80x86 specific)

//**ET+ o32_map - Object Page Map entry

type
  o32_map = packed record          { Object Page Table entry }
    o32_pagedataoffset  : Longint; { file offset of page }
    o32_pageSize        : Word;    { # Bytes of page data }
    o32_pageflags       : Word;    { Per-Page attributes }
  end;

const
  Valid            = $0000;  { Valid Physical Page in .Exe }
  IterData         = $0001;  { Iterated Data Page }
  Invalid          = $0002;  { Invalid Page }
  Zeroed           = $0003;  { Zero Filled Page }
  Range            = $0004;  { Range of pages }
  IterData2        = $0005;  { Iterated Data Page Type II }

{ RESOURCE TABLE }

{**ET+ rsrc32 - Resource Table Entry }

type
  rsrc32 = packed record           { Resource Table Entry }
    rType  : Word;                 { Resource type }
    Name   : Word;                 { Resource name }
    cb     : LongInt;              { Resource Size }
    Obj    : Word;                 { Object number }
    Offset : LongInt;              { Offset within object }
  end;

  { Iteration Record format for 'ExePACK'ed pages. }
  LX_Iter = packed record
    LX_nIter    : Word;            { number of iterations }
    LX_nBytes   : Word;            { number of Bytes }
    LX_Iterdata : Byte;            { iterated data Byte(s) }
  end;


{ ENTRY TABLE DEFINITIONS }

{**ET+ b32_bundle - Entry Table }

  b32_bundle = packed record
    b32_cnt  :  Byte;              { Number of entries in this bundle }
    b32_type :  Byte;              { Bundle type }
    b32_obj  :  Word;              { Object number }
  end;                             { Follows entry types }

  e32_entry = packed record
    e32_flags : Byte;              { Entry point flags }

    e32_variant  : packed record
      Case Byte of
        0 : ( e32_offset : Longint );     { 16-bit/32-bit offset entry }
        1 : ( e32_callgate: packed record { 286 (16-bit) call gate }
                Offset : Longint;         { Offset in segment }
                callgate : Longint
              end );     { Callgate selector }
        2 : ( e32_fwd: packed record      { Forwarder }
                ModOrd : Word;            { Module Ordinal number }
                Value  : LongInt;         { Proc name offset or Ordinal }
             end );
    end;
  end;

const
  FixEnt16        = 3;
  FixEnt32        = 5;
  GateEnt16       = 5;
  FwdEnt          = 7;

{ BUNDLE TYPES }

  Empty        = $00;             { Empty bundle }
  Entry16      = $01;             { 16-bit offset entry poInt }
  Gate16       = $02;             { 286 call gate (16-bit IOPL) }
  Entry32      = $03;             { 32-bit offset entry poInt }
  EntryFWD     = $04;             { Forwarder entry poInt }
  TypeInfo     = $80;             { Typing information present flag }

{
 *  Format for E32_EFlags(x)
 *
 *       7 6 5 4 3 2 1 0  - bit no
 *       | | | | | | | |
 *       | | | | | | | +--- exported entry
 *       | | | | | | +----- uses shared data
 *       +-+-+-+-+-+------- parameter Word count
 }

  E32Export       = $01;          { Exported entry }
  E32Shared       = $02;          { Uses shared data }
  E32Params       = $f8;          { Parameter Word count mask }

{ Flags for forwarders only: }

  Fwd_Ordinal     = $01;          { Imported by Ordinal }


{----[ NEWEXE ]----}

{ Data structure definitions for the DOS 4.0/Windows 2.0/OS-2 }
{ executable file format.  Includes WLO definitions. }

{ DOS 3 EXE HEADER }

const
  EMagic          = $5A4D;          { Old magic number }
                                    { Value of E_LFARLC for new .Exes }
  ENewHdr         = $003C;          { Offset in old hdr. of ptr. to new }
  EResWds         = $0010;          { No. of reserved wOrds (OLD) }
  ERes1Wds        = $0004;          { No. of reserved wOrds in e_res }
  ERes2Wds        = $000A;          { No. of reserved wOrds in e_res2 }
  ECp             = $0004;          { Offset in struct of E_CP }
  ECBLP           = $0002;          { Offset in struct of E_CBLP }
  EMinAlloc       = $000A;          { Offset in struct of E_MINAlloc }

type
  exe_hdr = packed record        { DOS 1, 2, 3 .Exe header }
    e_magic         : Word;      { Magic number }
    e_cblp          : Word;      { Bytes on last page of file }
    e_cp            : Word;      { Pages in file }
    e_crlc          : Word;      { Relocations }
    e_cparhdr       : Word;      { Size of header in paragraphs }
    e_minalloc      : Word;      { Minimum extra paragraphs needed }
    e_maxalloc      : Word;      { Maximum extra paragraphs needed }
    e_ss            : Word;      { Initial (relative) SS value }
    e_sp            : Word;      { Initial SP value }
    e_csum          : Word;      { Checksum }
    e_ip            : Word;      { Initial IP value }
    e_cs            : Word;      { Initial (relative) CS value }
    e_lfarlc        : Word;      { File Address of relocation table }
    e_ovno          : Word;      { Overlay number }
    e_res : Array[ 1..ERes1Wds ] of Word;  { Reserved wOrds }
    e_oemid         : Word;      { OEM identifier (for e_oeminfo) }
    e_oeminfo       : Word;      { OEM information; e_oemid specific }
    e_res2 : Array[ 1..ERes2Wds ] of Word; { Reserved wOrds }
    e_lfanew        : Longint;       { File Address of new exe header }
  end;

const
  ENewExe         = Sizeof(exe_hdr);

  {  OS/2 & WINDOWS .Exe FILE HEADER DEFINITION - 286 version      }

  NEMagic         = $454E;          { New magic number }
  NEResBytes      = 8;              { Eight bytes reserved (now) }
  NECrc           = 8;              { Offset Into new header of NE_CRC }

type
  new_exe  = packed record          { New .Exe header }
    ne_magic            : Word;     { Magic number NE_Magic }
    ne_ver              : Byte;     { Version number }
    ne_rev              : Byte;     { Revision number }
    ne_enttab           : Word;     { Offset of Entry Table }
    ne_cbenttab         : Word;     { Number of bytes in Entry Table }
    ne_crc              : LongInt;  { Checksum of whole file }
    ne_flags            : Word;     { Flag wOrd }
    ne_autodata         : Word;     { Automatic data segment number }
    ne_heap             : Word;     { Initial heap allocation }
    ne_stack            : Word;     { Initial stack allocation }
    ne_csip             : LongInt;  { Initial CS:IP setting }
    ne_sssp             : LongInt;  { Initial SS:SP setting }
    ne_cseg             : Word;     { Count of file segments }
    ne_cmod             : Word;     { Entries in Module Reference Table }
    ne_cbnrestab        : Word;     { Size of non-resident name table }
    ne_segtab           : Word;     { Offset of Segment Table }
    ne_rsrctab          : Word;     { Offset of Resource Table }
    ne_restab           : Word;     { Offset of resident name table }
    ne_modtab           : Word;     { Offset of Module Reference Table }
    ne_imptab           : Word;     { Offset of Imported Names Table }
    ne_nrestab          : LongInt;  { Offset of Non-resident Names Table }
    ne_cmovent          : Word;     { Count of movable entries }
    ne_align            : Word;     { Segment alignment shift count }
    ne_cres             : Word;     { Count of resource entries }
    ne_exetyp           : Byte;     { Target operating system }
    ne_flagsothers      : Byte;     { Other .Exe flags }
    ne_res              : Array[1..NERESBytes] of Byte; { Pad structure to 64 bytes }
  end;

{ Target operating systems }
const
  NE_Unknown    = $0;            { Unknown (any "new-format" OS) }
  NE_Os2        = $1;            { OS/2 (default)  }
  NE_Windows    = $2;            { Windows }
  NE_Dos4       = $3;            { DOS 4.x }
  NE_Dev386     = $4;            { Windows 386 }


{
 *  Format of NE_Flags(x):
 *
 *  p                                   Not-a-process
 *   x                                  Unused
 *    e                                 Errors in image
 *     x                                Unused
 *      b                               Bound Family/API
 *       ttt                            Application type
 *          f                           Floating-poInt instructions
 *           3                          386 instructions
 *            2                         286 instructions
 *             0                        8086 instructions
 *              P                       Protected mode only
 *               p                      Per-process library initialization
 *                i                     Instance data
 *                 s                    Solo data
 }
  NENotP         = $8000;         { Not a process }
  NEIErr         = $2000;         { Errors in image }
  NEBound        = $0800;         { Bound Family/API }
  NEAppTyp       = $0700;         { Application type mask }
  NENotWinCompat = $0100;         { Not compatible with P.M. Windowing }
  NEWincompat    = $0200;         { Compatible with P.M. Windowing }
  NEWinApi       = $0300;         { Uses P.M. Windowing API }
  NEFltP         = $0080;         { Floating-poInt instructions }
  NEi386         = $0040;         { 386 instructions }
  NEi286         = $0020;         { 286 instructions }
  NEi086         = $0010;         { 8086 instructions }
  NEProt         = $0008;         { Runs in Protected mode only }
  NEPpli         = $0004;         { Per-Process Library Initialization }
  NEInst         = $0002;         { Instance data }
  NESolo         = $0001;         { Solo data }

{
 *  Format of NE_FlagsOTHERS(x):
 *
 *      7 6 5 4 3 2 1 0  - bit no
 *      |         | | |
 *      |         | | +---------------- Support for long file names
 *      |         | +------------------ Windows 2.x app runs in Prot mode
 *      |         +-------------------- Windows 2.x app gets prop. font
 *      +------------------------------ WLO appl on OS/2 (markwlo.exe)
 *
 }

  NELongNames     = $01;
  NewInisProt     = $02;
  NewInGetPropFon = $04;
  NewLoAppl       = $80;


type
  new_seg = packed record      { New .Exe segment table entry }
    ns_sector   : Word;        { File sector of start of segment }
    ns_cbseg    : Word;        { Number of bytes in file }
    ns_flags    : Word;        { Attribute flags }
    ns_minalloc : Word;        { Minimum allocation in bytes }
  end;

{
 *  Format of NS_Flags(x)
 *
 *  Flag wOrd has the following format:
 *
 *      15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0  - bit no
 *          |  |  |  |  | | | | | | | | | | |
 *          |  |  |  |  | | | | | | | | +-+-+--- Segment type Data/Code
 *          |  |  |  |  | | | | | | | +--------- Iterated segment
 *          |  |  |  |  | | | | | | +----------- Movable segment
 *          |  |  |  |  | | | | | +------------- Segment can be shared
 *          |  |  |  |  | | | | +--------------- Preload segment
 *          |  |  |  |  | | | +----------------- Execute/read-only for code/data segment
 *          |  |  |  |  | | +------------------- Segment has relocations
 *          |  |  |  |  | +--------------------- Code conforming/Data is expand down
 *          |  |  |  +--+----------------------- I/O privilege level
 *          |  |  +----------------------------- Discardable segment
 *          |  +-------------------------------- 32-bit code segment
 *          +----------------------------------- Huge segment/GDT allocation requested
 *
 }

const
  neNSType       = $0007;         { Segment type mask }

  neNSCode       = $0000;         { Code segment }
  neNSData       = $0001;         { Data segment }
  neNSIter       = $0008;         { Iterated segment flag }
  neNSMove       = $0010;         { Movable segment flag }
  neNSShared     = $0020;         { Shared segment flag }
  neNSPreLoad    = $0040;         { Preload segment flag }
  neNSExRd       = $0080;         { Execute-only (code segment), or
                                        *  read-only (data segment)
                                        }
  neNSReloc      = $0100;         { Segment has relocations }
  neNSConform    = $0200;         { Conforming segment }
  neNSExpDown    = $0200;         { Data segment is expand down }
  neNSDPL        = $0C00;         { I/O privilege level (286 DPL bits) }
  neShiftDpl     = 10;            { Left shift count for SegDPL field }
  neNSDiscard    = $1000;         { Segment is discardable }
  neNS32Bit      = $2000;         { 32-bit code segment }
  neNSHuge       = $4000;         { Huge memory segment, length of
                                         * segment and minimum allocation
                                         * Size are in segment sector units
                                         }
  neNSGDT        = $8000;         { GDT allocation requested }

  neNSPure       = NSShared;      { For compatibility }

  neNSAlign      = 9;             { Segment data aligned on 512 byte boundaries }

  neNSLOADED     = $0004;         { ns_sector field contains memory Addr }

type
  new_segdata = packed record        { Segment data }
    Case Boolean of
      True : ( ns_iter : packed record
                 ns_niter    : Word; { number of iterations }
                 ns_nbytes   : Word; { number of bytes }
                 ns_iterdata : char; { iterated data bytes }
               end );
      False: ( ns_noniter : packed record
                ns_data      : char; { data bytes }
               end );
  end;

  new_rlcinfo = packed record        { Relocation info }
    nr_nreloc : Word;                { number of relocation items that }
  end;                               { follow }

  new_rlc = packed record            { Relocation item }
    nr_stype   : char;               { Source type }
    nr_flags   : char;               { Flag byte }
    nr_soff    : Word;               { Source offset }
    nr_union   : packed record
      Case Byte of
        0 : ( nr_Intref : packed record { Internal reference }
                nr_segno  : char;    { Target segment number }
                nr_res    : char;    { Reserved }
                nr_entry  : Word;    { Target Entry Table offset }
              end );
        1 : ( nr_import : packed record { Import }
                nr_mod    : Word;    { Index Into Module Reference Table }
                nr_proc   : Word;    { Procedure Ordinal or name offset }
              end );
        2 : ( nr_osfix : packed record { Operating system fixup }
                nr_ostype : Word;    { OSFixUP type }
                nr_osres  : Word;    { reserved }
              end );
      end;
   end;

const
{
 *  Format of NR_SType(x) and R32_SType(x):
 *
 *       7 6 5 4 3 2 1 0  - bit no
 *               | | | |
 *               +-+-+-+--- source type
 *
 }

  NRSTyp         = $0f;           { Source type mask }
  NRSByt         = $00;           { lo byte (8-bits)}
  NRSSeg         = $02;           { 16-bit segment (16-bits) }
  NRSPtr         = $03;           { 16:16 poInter (32-bits) }
  NRSOff         = $05;           { 16-bit offset (16-bits) }
  NRPtr48        = $06;           { 16:32 poInter (48-bits) }
  NROff32        = $07;           { 32-bit offset (32-bits) }
  NRSOff32       = $08;           { 32-bit self-relative offset (32-bits) }


{
 *  Format of NR_Flags(x) and R32_Flags(x):
 *
 *       7 6 5 4 3 2 1 0  - bit no
 *                 | | |
 *                 | +-+--- Reference type
 *                 +------- Additive fixup
 }

  NRAdd          = $04;           { Additive fixup }
  NRRTyp         = $03;           { Reference type mask }
  NRRInt         = $00;           { Internal reference }
  NRROrd         = $01;           { Import by Ordinal }
  NRRNam         = $02;           { Import by name }
  NRROSF         = $03;           { Operating system fixup }

type
  { Resource type or name string }
  rsrc_string = packed record
    rs_len      : Char;            { number of bytes in string }
    rs_string   : Array[ 1..1 ] of Char;    { text of string }
  end;

  { Resource type information block }
  rsrc_typeinfo = packed record
    rt_id   : Word;
    rt_nres : Word;
    rt_proc : LongInt;
  end;

  { Resource name information block }
  rsrc_nameinfo = packed record
    { The following two fields must be shifted left by the value of  }
    { the rs_align field to compute their actual value.  This allows }
    { resources to be larger than 64k, but they do not need to be    }
    { aligned on 512 byte boundaries, the way segments are           }
    rn_offset : Word; { file offset to resource data }
    rn_length : Word; { length of resource data }
    rn_flags  : Word; { resource flags }
    rn_id     : Word; { resource name id }
    rn_handle : Word; { If loaded, then global handle }
    rn_usage  : Word; { Initially zero.  Number of times }
                      { the handle for this resource has }
                      { been given out }
  end;

const
  RSOrdID    = $8000;     { if high bit of ID set then Integer id }
                          { otherwise ID is offset of string from
                          the beginning of the resource table }

                          { Ideally these are the same as the }
                          { corresponding segment flags }
  RNMove     = $0010;     { Moveable resource }
  RNPURE     = $0020;     { Pure (read-only) resource }
  RNPreLoad  = $0040;     { Preloaded resource }
  RNDiscard  = $F000;     { Discard priority level for resource }

type
  { Resource table }
  new_rsrc = packed record
    rs_align    : Word;   { alignment shift count for resources }
    rs_TypeInfo : rsrc_typeinfo;
  end;

// Declarations describing the format of PE executables
// Converted from WINNT.H

type
  DWord = Longint;
  PDWord = ^DWord;
  PByte = ^Byte;

// Image Format

const
  image_DOS_Signature                   = $5A4D;     // 'MZ'
  image_OS2_Signature                   = $454E;     // 'NE'
  image_OS2_Signature_LE                = $454C;     // 'LE'
  image_VXD_Signature                   = $454C;     // 'LE'
  image_NT_Signature                    = $00004550; // 'PE'#0#0

// DOS .EXE header

type
  PImageDosHeader = ^TImageDosHeader;
  TImageDosHeader = packed record
    e_magic:    Word;                   // Magic number
    e_cblp:     Word;                   // Bytes on last page of file
    e_cp:       Word;                   // Pages in file
    e_crlc:     Word;                   // Relocations
    e_cparhdr:  Word;                   // Size of header in paragraphs
    e_minalloc: Word;                   // Minimum extra paragraphs needed
    e_maxalloc: Word;                   // Maximum extra paragraphs needed
    e_ss:       Word;                   // Initial (relative) SS value
    e_sp:       Word;                   // Initial SP value
    e_csum:     Word;                   // Checksum
    e_ip:       Word;                   // Initial IP value
    e_cs:       Word;                   // Initial (relative) CS value
    e_lfarlc:   Word;                   // File address of relocation table
    e_ovno:     Word;                   // Overlay number
    e_res: packed array[0..3] of Word;  // Reserved words
    e_oemid:    Word;                   // OEM identifier (for e_oeminfo)
    e_oeminfo:  Word;                   // OEM information: e_oemid specific
    e_res2: packed array[0..9] of Word; // Reserved words
    e_lfanew:   Longint;                // File address of new exe header
  end;

// File header format

  PImageFileHeader = ^TImageFileHeader;
  TImageFileHeader = packed record
    Machine:              Word;
    NumberOfSections:     Word;
    TimeDateStamp:        DWord;
    PointerToSymbolTable: DWord;
    NumberOfSymbols:      DWord;
    SizeOfOptionalHeader: Word;
    Characteristics:      Word;
  end;

const
  image_SizeOf_File_Header              = 20;

  image_File_Relocs_Stripped            = $0001; // Relocation info stripped from file.
  image_File_Executable_Image           = $0002; // File is executable  (i.e. no unresolved externel references).
  image_File_Line_Nums_Stripped         = $0004; // Line nunbers stripped from file.
  image_File_Local_Syms_Stripped        = $0008; // Local symbols stripped from file.
  image_File_Aggresive_WS_Trim          = $0010; // Agressively trim working set
  image_File_Bytes_Reversed_Lo          = $0080; // Bytes of machine word are reversed.
  image_File_32Bit_Machine              = $0100; // 32 bit word machine.
  image_File_Debug_Stripped             = $0200; // Debugging info stripped from file in .DBG file
  image_File_Removable_Run_From_Swap    = $0400; // If Image is on removable media, copy and run from the swap file.
  image_File_Net_Run_From_Swap          = $0800; // If Image is on Net, copy and run from the swap file.
  image_File_System                     = $1000; // System File.
  image_File_Dll                        = $2000; // File is a DLL.
  image_File_Up_System_Only             = $4000; // File should only be run on a UP machine
  image_File_Bytes_Reversed_Hi          = $8000; // Bytes of machine word are reversed.

  image_File_Machine_Unknown            = $000;
  image_File_Machine_i386               = $14C;  // Intel 386.
  image_File_Machine_R3000              = $162;  // MIPS little-endian, 0x160 big-endian
  image_File_Machine_R4000              = $166;  // MIPS little-endian
  image_File_Machine_R10000             = $168;  // MIPS little-endian
  image_File_Machine_Alpha              = $184;  // Alpha_AXP
  image_File_Machine_PowerPC            = $1F0;  // IBM PowerPC Little-Endian

// Directory format

type
  PImageDataDirectory = ^TImageDataDirectory;
  TImageDataDirectory = packed record
    VirtualAddress: DWord;
    Size:           DWord;
  end;

const
  image_NumberOf_Directory_Entries      = 16;

// Optional header format

type
  PImageOptionalHeader = ^TImageOptionalHeader;
  TImageOptionalHeader = packed record
    // Standard fields
    Magic:                       Word;
    MajorLinkerVersion:          Byte;
    MinorLinkerVersion:          Byte;
    SizeOfCode:                  DWord;
    SizeOfInitializedData:       DWord;
    SizeOfUninitializedData:     DWord;
    AddressOfEntryPoint:         DWord;
    BaseOfCode:                  DWord;
    BaseOfData:                  DWord;
    // NT additional fields
    ImageBase:                   DWord;
    SectionAlignment:            DWord;
    FileAlignment:               DWord;
    MajorOperatingSystemVersion: Word;
    MinorOperatingSystemVersion: Word;
    MajorImageVersion:           Word;
    MinorImageVersion:           Word;
    MajorSubsystemVersion:       Word;
    MinorSubsystemVersion:       Word;
    Win32VersionValue:           DWord;
    SizeOfImage:                 DWord;
    SizeOfHeaders:               DWord;
    CheckSum:                    DWord;
    Subsystem:                   Word;
    DllCharacteristics:          Word;
    SizeOfStackReserve:          DWord;
    SizeOfStackCommit:           DWord;
    SizeOfHeapReserve:           DWord;
    SizeOfHeapCommit:            DWord;
    LoaderFlags:                 DWord;
    NumberOfRvaAndSizes:         DWord;
    DataDirectory: packed array[0..image_NumberOf_Directory_Entries-1] of TImageDataDirectory;
  end;

  PImageRomOptionalHeader = ^TImageRomOptionalHeader;
  TImageRomOptionalHeader = packed record
    Magic:                   Word;
    MajorLinkerVersion:      Byte;
    MinorLinkerVersion:      Byte;
    SizeOfCode:              DWord;
    SizeOfInitializedData:   DWord;
    SizeOfUninitializedData: DWord;
    AddressOfEntryPoint:     DWord;
    BaseOfCode:              DWord;
    BaseOfData:              DWord;
    BaseOfBss:               DWord;
    GprMask:                 DWord;
    CprMask:                 packed array[0..3] of DWord;
    GpValue:                 DWord;
  end;

const
  image_SizeOf_ROM_Optional_Header      = 56;
  image_SizeOf_Std_Optional_Header      = 28;
  image_SizeOf_NT_Optional_Header       = 224;

  image_NT_Optional_Hdr_Magic           = $010B;
  image_ROM_Optional_Hdr_Magic          = $0107;

type
  PImageNtHeaders = ^TImageNtHeaders;
  TImageNtHeaders = packed record
    Signature:      DWord;
    FileHeader:     TImageFileHeader;
    OptionalHeader: TImageOptionalHeader;
  end;

  PImageRomHeaders = ^TImageRomHeaders;
  TImageRomHeaders = packed record
    FileHeader:     TImageFileHeader;
    OptionalHeader: TImageRomOptionalHeader;
  end;

// Subsystem Values

const
  image_Subsystem_Unknown               = 0; // Unknown subsystem.
  image_Subsystem_Native                = 1; // Image doesn't require a subsystem.
  image_Subsystem_Windows_GUI           = 2; // Image runs in the Windows GUI subsystem.
  image_Subsystem_Windows_CUI           = 3; // Image runs in the Windows character subsystem.
  image_Subsystem_OS2_CUI               = 5; // image runs in the OS/2 character subsystem.
  image_Subsystem_Posix_CUI             = 7; // image run  in the Posix character subsystem.
  image_Subsystem_Reserved8             = 8; // image run  in the 8 subsystem.

// Directory Entries

  image_Directory_Entry_Export          = 0;  // Export Directory
  image_Directory_Entry_Import          = 1;  // Import Directory
  image_Directory_Entry_Resource        = 2;  // Resource Directory
  image_Directory_Entry_Exception       = 3;  // Exception Directory
  image_Directory_Entry_Security        = 4;  // Security Directory
  image_Directory_Entry_BaseReloc       = 5;  // Base Relocation Table
  image_Directory_Entry_Debug           = 6;  // Debug Directory
  image_Directory_Entry_Copyright       = 7;  // Description String
  image_Directory_Entry_GlobalPtr       = 8;  // Machine Value (MIPS GP)
  image_Directory_Entry_Tls             = 9;  // TLS Directory
  image_Directory_Entry_Load_Config     = 10; // Load Configuration Directory
  image_Directory_Entry_Bound_Import    = 11; // Bound Import Directory in headers
  image_Directory_Entry_IAT             = 12; // Import Address Table

// Section header format.

  image_SizeOf_Short_Name               = 8;

type
  TISHMisc = packed record
    case Integer of
      0: (PhysicalAddress: DWord);
      1: (VirtualSize:     DWord);
  end;

  PImageSectionHeader = ^TImageSectionHeader;
  TImageSectionHeader = packed record
    Name:                 packed array[0..image_SizeOf_Short_Name-1] of Byte;
    Misc:                 TISHMisc;
    VirtualAddress:       DWord;
    SizeOfRawData:        DWord;
    PointerToRawData:     DWord;
    PointerToRelocations: DWord;
    PointerToLinenumbers: DWord;
    NumberOfRelocations:  Word;
    NumberOfLinenumbers:  Word;
    Characteristics:      DWord;
  end;

const
  image_SizeOf_Section_Header           = 40;

// Section characteristics.

//image_Scn_Type_Reg                      $00000000  // Reserved.
//image_Scn_Type_DSect                    $00000001  // Reserved.
//image_Scn_Type_NoLoad                   $00000002  // Reserved.
//image_Scn_Type_Group                    $00000004  // Reserved.
  image_Scn_Type_No_Pad                 = $00000008; // Reserved.
//image_Scn_Type_Copy                     $00000010  // Reserved.

  image_Scn_Cnt_Code                    = $00000020; // Section contains code.
  image_Scn_Cnt_Initialized_Data        = $00000040; // Section contains initialized data.
  image_Scn_Cnt_Uninitialized_Data      = $00000080; // Section contains uninitialized data.

  image_Scn_Lnk_Other                   = $00000100; // Reserved.
  image_Scn_Lnk_Info                    = $00000200; // Section contains comments or some other type of information.
//image_Scn_Type_Over                     $00000400  // Reserved.
  image_Scn_Lnk_Remove                  = $00000800; // Section contents will not become part of image.
  image_Scn_Lnk_ComDat                  = $00001000; // Section contents comdat.
//                                        $00002000  // Reserved.

//image_Scn_Mem_Protected - Obsolete      $00004000
  image_Scn_Mem_FarData                 = $00008000;
//image_Scn_Mem_SYSHEAP  - Obsolete       $00010000
  image_Scn_Mem_Purgeable               = $00020000;
  image_Scn_Mem_16Bit                   = $00020000;
  image_Scn_Mem_Locked                  = $00040000;
  image_Scn_Mem_Preload                 = $00080000;

  image_Scn_Align_1Bytes                = $00100000;
  image_Scn_Align_2Bytes                = $00200000;
  image_Scn_Align_4Bytes                = $00300000;
  image_Scn_Align_8Bytes                = $00400000;
  image_Scn_Align_16Bytes               = $00500000; // Default alignment if no others are specified.
  image_Scn_Align_32Bytes               = $00600000;
  image_Scn_Align_64Bytes               = $00700000;
//Unused                                  $00800000

  image_Scn_Lnk_NReloc_Ovfl             = $01000000; // Section contains extended relocations.
  image_Scn_Mem_Discardable             = $02000000; // Section can be discarded.
  image_Scn_Mem_Not_Cached              = $04000000; // Section is not cachable.
  image_Scn_Mem_Not_Paged               = $08000000; // Section is not pageable.
  image_Scn_Mem_Shared                  = $10000000; // Section is shareable.
  image_Scn_Mem_Execute                 = $20000000; // Section is executable.
  image_Scn_Mem_Read                    = $40000000; // Section is readable.
  image_Scn_Mem_Write                   = $80000000; // Section is writeable.

// Relocation format.

type
  PImageRelocation = ^TImageRelocation;
  TImageRelocation = packed record
    case Integer of
      0: (VirtualAddress: DWord;
          SymbolTableIndex: DWord;
          _Type:            Word);  // renamed form Type
      1: (RelocCount:       DWord); // Set to the real count when image_Scn_Lnk_NReloc_Ovfl is set
  end;

const
  image_SizeOf_Relocation               = 10;

// I386 relocation types.

  image_Rel_i386_Absolute               = $0000; // Reference is absolute, no relocation is necessary
  image_Rel_i386_Dir16                  = $0001; // Direct 16-bit reference to the symbols virtual address
  image_Rel_i386_Rel16                  = $0002; // PC-relative 16-bit reference to the symbols virtual address
  image_Rel_i386_Dir32                  = $0006; // Direct 32-bit reference to the symbols virtual address
  image_Rel_i386_Dir32NB                = $0007; // Direct 32-bit reference to the symbols virtual address, base not included
  image_Rel_i386_Seg12                  = $0009; // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address
  image_Rel_i386_Section                = $000A;
  image_Rel_i386_SecRel                 = $000B;
  image_Rel_i386_Rel32                  = $0014; // PC-relative 32-bit reference to the symbols virtual address

// Based relocation format.

type
  PImageBaseRelocation = ^TImageBaseRelocation;
  TImageBaseRelocation = packed record
    VirtualAddress: DWord;
    SizeOfBlock:    DWord;
  //TypeOffset: array[0..X] of Word;
  end;

const
  image_SizeOf_Base_Relocation          = 8;

// Based relocation types.

  image_Rel_Based_Absolute              = 0;
  image_Rel_Based_High                  = 1;
  image_Rel_Based_Low                   = 2;
  image_Rel_Based_HighLow               = 3;
  image_Rel_Based_HighAdj               = 4;
  image_Rel_Based_MIPS_JmpAddr          = 5;

// Line number format.

type
  PImageLineNumber = ^TImageLineNumber;
  TImageLineNumber = packed record
    case Integer of
      0: (SymbolTableIndex: DWord;      // Symbol table index of function name if Linenumber is 0.
          Linenumber:       Word);      // Line number.
      1: (VirtualAddress:   DWord);     // Virtual address of line number.
  end;

const
  image_SizeOf_LineNumber               = 6;

// DLL support.
// Export Format

type
  PImageExportDirectory = ^TImageExportDirectory;
  TImageExportDirectory = packed record
    Characteristics:       DWord;
    TimeDateStamp:         DWord;
    MajorVersion:          Word;
    MinorVersion:          Word;
    Name:                  DWord;
    Base:                  DWord;
    NumberOfFunctions:     DWord;
    NumberOfNames:         DWord;
    case Integer of
     0: (AddressOfFunctions:    ^PDWord;
         AddressOfNames:        ^PDWord;
         AddressOfNameOrdinals: ^PDWord);

     1: (AddrOfFuncs: DWord; // Used in the linker to avoid ugly typecasts
         AddrOfNames: DWord;
         AddrOfNOrds: DWord)
  end;

// Import Format

  PImageImportByName = ^TImageImportByName;
  TImageImportByName = packed record
    Hint: Word;
    Name: packed array[0..0] of Char;
  end;

  PImageThunkData = ^TImageThunkData;
  TImageThunkData = packed record
    case Integer of
      0: (ForwarderString: PByte);
      1: (_Function:       PDWord); // renamed from Function
      2: (Ordinal:         DWord);
      3: (AddressOfData:   PImageImportByName);
  end;

const
  image_Ordinal_Flag                    = $80000000;

type
  PImageImportDescriptor = ^TImageImportDescriptor;
  TImageImportDescriptor = packed record
    OriginalFirstThunk: PImageThunkData; // RVA to original unbound IAT
    TimeDateStamp:      DWord;           // 0 if not bound,
                                         // -1 if bound, and real date\time stamp
                                         //     in image_Directory_Entry_Bound_Import (new BIND)
                                         // O.W. date/time stamp of DLL bound to (Old BIND)
    ForwarderChain:     DWord;           // -1 if no forwarders
    Name:               DWord;
    FirstThunk:         PImageThunkData; // RVA to IAT (if bound this IAT has actual addresses)
  end;

// New format import descriptors pointed to by DataDirectory[image_Directory_Entry_Bound_Import]

  PImageBoundImportDescriptor = ^TImageBoundImportDescriptor;
  TImageBoundImportDescriptor = packed record
    TimeDateStamp:               DWord;
    OffsetModuleName:            Word;
    NumberOfModuleForwarderRefs: Word;
  // Array of zero or more TImageBoundForwarderRef follows
  end;

  PImageBoundForwarderRef = ^TImageBoundForwarderRef;
  TImageBoundForwarderRef = packed record
    TimeDateStamp:    DWord;
    OffsetModuleName: Word;
    Reserved:         Word;
  end;

// Thread Local Storage

  TImageTLSCallBack = procedure(DllHandle: Pointer; Reason: DWord; Reserved: Pointer);

  PImageTLSDirectory = ^TImageTLSDirectory;
  TImageTLSDirectory = packed record
    StartAddressOfRawData: DWord;
    EndAddressOfRawData:   DWord;
    AddressOfIndex:        PDWord;
    AddressOfCallBacks:    ^TImageTLSCallBack;
    SizeOfZeroFill:        DWord;
    Characteristics:       DWord;
  end;

// Resource Format
//
// Resource directory consists of two counts, following by a variable length
// array of directory entries.  The first count is the number of entries at
// beginning of the array that have actual names associated with each entry.
// The entries are in ascending order, case insensitive strings.  The second
// count is the number of entries that immediately follow the named entries.
// This second count identifies the number of entries that have 16-bit integer
// Ids as their name.  These entries are also sorted in ascending order.
//
// This structure allows fast lookup by either name or number, but for any
// given resource entry only one form of lookup is supported, not both.
// This is consistant with the syntax of the .RC file and the .RES file.
//

  PImageResourceDirectory = ^TImageResourceDirectory;
  TImageResourceDirectory = packed record
    Characteristics:      DWord;
    TimeDateStamp:        DWord;
    MajorVersion:         Word;
    MinorVersion:         Word;
    NumberOfNamedEntries: Word;
    NumberOfIdEntries:    Word;
//  DirectoryEntries: array [0..X] of TImageResourceDirectoryEntry;
  end;

const
  image_Resource_Name_Is_String         = $80000000;
  image_Resource_Data_Is_Directory      = $80000000;

// Each directory contains the 32-bit Name of the entry and an offset,
// relative to the beginning of the resource directory of the data associated
// with this directory entry.  If the name of the entry is an actual text
// string instead of an integer Id, then the high order bit of the name field
// is set to one and the low order 31-bits are an offset, relative to the
// beginning of the resource directory of the string, which is of type
// IMAGE_RESOURCE_DIRECTORY_STRING.  Otherwise the high bit is clear and the
// low-order 16-bits are the integer Id that identify this resource directory
// entry. If the directory entry is yet another resource directory (i.e. a
// subdirectory), then the high order bit of the offset field will be
// set to indicate this.  Otherwise the high bit is clear and the offset
// field points to a resource data entry.
//

type
  PImageResourceDirectoryEntry = ^TImageResourceDirectoryEntry;
  TImageResourceDirectoryEntry = packed record
    case Integer of
      0: (Name:         DWord;
          OffsetToData: DWord);
      1: (Id:     Word);
  end;

// For resource directory entries that have actual string names, the Name
// field of the directory entry points to an object of the following type.
// All of these string objects are stored together after the last resource
// directory entry and before the first resource data object.  This minimizes
// the impact of these variable length objects on the alignment of the fixed
// size directory entry objects.
//

  PImageResourceDirectoryString = ^TImageResourceDirectoryString;
  TImageResourceDirectoryString = packed record
    Length: Word;
    NameString: packed array [0..0] of Char;
  end;

  PImageResourceDirStringU = ^TImageResourceDirStringU;
  TImageResourceDirStringU = packed record
    Length: Word;
    NameString: packed array[0..0] of Word;
  end;

// Each resource data entry describes a leaf node in the resource directory
// tree.  It contains an offset, relative to the beginning of the resource
// directory of the data for the resource, a size field that gives the number
// of bytes of data at that offset, a CodePage that should be used when
// decoding code point values within the resource data.  Typically for new
// applications the code page would be the unicode code page.

  PImageResourceDataEntry = ^TImageResourceDataEntry;
  TImageResourceDataEntry = packed record
    OffsetToData: DWord;
    Size:         DWord;
    CodePage:     DWord;
    Reserved:     DWord;
  end;

// Load Configuration Directory Entry

  PImageLoadConfigDirectory = ^TImageLoadConfigDirectory;
  TImageLoadConfigDirectory = packed record
    Characteristics:               DWord;
    TimeDateStamp:                 DWord;
    MajorVersion:                  Word;
    MinorVersion:                  Word;
    GlobalFlagsClear:              DWord;
    GlobalFlagsSet:                DWord;
    CriticalSectionDefaultTimeout: DWord;
    DeCommitFreeBlockThreshold:    DWord;
    DeCommitTotalFreeThreshold:    DWord;
    LockPrefixTable:               Pointer;
    MaximumAllocationSize:         DWord;
    VirtualMemoryThreshold:        DWord;
    ProcessHeapFlags:              DWord;
    ProcessAffinityMask:           DWord;
    Reserved:packed array[0..2] of DWord;
  end;

// Function table entry format for MIPS/ALPHA images.  Function table is
// pointed to by the IMAGE_DIRECTORY_ENTRY_EXCEPTION directory entry.

  PImageRuntimeFunctionEntry = ^TImageRuntimeFunctionEntry;
  TImageRuntimeFunctionEntry = packed record
    BeginAddress:       DWord;
    EndAddress:         DWord;
    ExceptionHandler:   Pointer;
    HandlerData:        Pointer;
    PrologEndAddress:   DWord;
  end;

// Debug Format

  PImageDebugDirectory = ^TImageDebugDirectory;
  TImageDebugDirectory = packed record
    Characteristics:    DWord;
    TimeDateStamp:      DWord;
    MajorVersion:       Word;
    MinorVersion:       Word;
    _Type:              DWord; // Renamed from Type
    SizeOfData:         DWord;
    AddressOfRawData:   DWord;
    PointerToRawData:   DWord;
  end;

const
  image_Debug_Type_Unknown              = 0;
  image_Debug_Type_Coff                 = 1;
  image_Debug_Type_CodeView             = 2;
  image_Debug_Type_FPO                  = 3;
  image_Debug_Type_Misc                 = 4;
  image_Debug_Type_Exception            = 5;
  image_Debug_Type_Fixup                = 6;
  image_Debug_Type_OMap_To_Src          = 7;
  image_Debug_Type_OMap_From_Src        = 8;

type
  PImageCOFFSymbolsHeader = ^TImageCOFFSymbolsHeader;
  TImageCOFFSymbolsHeader = packed record
    NumberOfSymbols:      DWord;
    LvaToFirstSymbol:     DWord;
    NumberOfLinenumbers:  DWord;
    LvaToFirstLinenumber: DWord;
    RvaToFirstByteOfCode: DWord;
    RvaToLastByteOfCode:  DWord;
    RvaToFirstByteOfData: DWord;
    RvaToLastByteOfData:  DWord;
  end;

const
  frame_FPO                             = 0;
  frame_Trap                            = 1;
  frame_TSS                             = 2;
  frame_NonFPO                          = 3;

type
  PFpoData = ^TFpoData;
  TFpoData = packed record
    ulOffStart:  DWord;                 // offset 1st byte of function code
    cbProcSize:  DWord;                 // # bytes in function
    cdwLocals:   DWord;                 // # bytes in locals/4
    cdwParams:   Word;                  // # bytes in params/4
{    WORD        cbProlog : 8;          // # bytes in prolog
     WORD        cbRegs   : 3;          // # regs saved
     WORD        fHasSEH  : 1;          // TRUE if SEH in func
     WORD        fUseBP   : 1;          // TRUE if EBP has been allocated
     WORD        reserved : 1;          // reserved for future use
     WORD        cbFrame  : 2;}         // frame type
     cbProlog:   Byte;
     OtherStuff: Byte;
  end;

const
  sizeof_RFPO_Data         = 16;
  image_Debug_Misc_ExeName = 1;

type
  PImageDebugMisc = ^TImageDebugMisc;
  TImageDebugMisc = packed record
    DataType:   DWord;                  // type of misc data, see defines
    Length:     DWord;                  // total length of record, rounded to four
                                        // byte multiple.
    Unicode:    ByteBool;               // TRUE if data is unicode string
    Reserved:   packed array[0..2] of Byte;
    Data:       packed array[0..0] of Byte;  // Actual data
  end;

// Function table extracted from MIPS/ALPHA images.  Does not contain
// information needed only for runtime support.  Just those fields for
// each entry needed by a debugger.

  PImageFunctionEntry = ^TImageFunctionEntry;
  TImageFunctionEntry = packed record
    StartingAddress: DWord;
    EndingAddress:   DWord;
    EndOfPrologue:   DWord;
  end;

// Debugging information can be stripped from an image file and placed
// in a separate .DBG file, whose file name part is the same as the
// image file name part (e.g. symbols for CMD.EXE could be stripped
// and placed in CMD.DBG).  This is indicated by the IMAGE_FILE_DEBUG_STRIPPED
// flag in the Characteristics field of the file header.  The beginning of
// the .DBG file contains the following structure which captures certain
// information from the image file.  This allows a debug to proceed even if
// the original image file is not accessable.  This header is followed by
// zero of more IMAGE_SECTION_HEADER structures, followed by zero or more
// IMAGE_DEBUG_DIRECTORY structures.  The latter structures and those in
// the image file contain file offsets relative to the beginning of the
// .DBG file.
//
// If symbols have been stripped from an image, the IMAGE_DEBUG_MISC structure
// is left in the image file, but not mapped.  This allows a debugger to
// compute the name of the .DBG file, from the name of the image in the
// IMAGE_DEBUG_MISC structure.

  PImageSeparateDebugHeader = ^TImageSeparateDebugHeader;
  TImageSeparateDebugHeader = packed record
    Signature:          Word;
    Flags:              Word;
    Machine:            Word;
    Characteristics:    Word;
    TimeDateStamp:      DWord;
    CheckSum:           DWord;
    ImageBase:          DWord;
    SizeOfImage:        DWord;
    NumberOfSections:   DWord;
    ExportedNamesSize:  DWord;
    DebugDirectorySize: DWord;
    Reserved: packed array[0..2] of DWord;  // Note: reserved[0] is actually the section alignment
  end;

const
  image_Separate_Debug_Signature        = $4944; // 'DI'

implementation

end.
