RetroLinker
Linker for several 8-bit, 16-bit and 32-bit formats
Loading...
Searching...
No Matches
neexe.h
1#ifndef NEEXE_H
2#define NEEXE_H
3
4#include <array>
5#include "mzexe.h"
6#include "../common.h"
7#include "../dumper/dumper.h"
8#include "../linker/module.h"
9#include "../linker/options.h"
10#include "../linker/segment.h"
11#include "../linker/segment_manager.h"
12#include "../linker/writer.h"
13
14namespace Microsoft
15{
16 namespace Windows
17 {
19 enum
20 {
21 RT_CURSOR = 0x0001,
22 RT_BITMAP = 0x0002,
23 RT_ICON = 0x0003,
24 RT_MENU = 0x0004,
25 RT_DIALOG = 0x0005,
26 RT_STRING = 0x0006,
27 RT_FONTDIR = 0x0007,
28 RT_FONT = 0x0008,
29 RT_ACCELERATOR = 0x0009,
30 RT_RCDATA = 0x000A,
31 RT_MESSAGETABLE = 0x000B,
32 RT_GROUP_CURSOR = 0x000C,
33 RT_GROUP_ICON = 0x000E,
34 RT_VERSION = 0x0010,
35 RT_DLGINCLUDE = 0x0011,
36 RT_PLUGPLAY = 0x0013,
37 RT_VXD = 0x0014,
38 RT_ANICURSOR = 0x0015,
39 RT_ANIICON = 0x0016,
40 RT_HTML = 0x0017,
41 RT_MANIFEST = 0x0018,
42 };
43 }
44
45 namespace OS2
46 {
47 // based on OpenWatcom sources
48
50 enum
51 {
52 // cursor
53 RT_POINTER = 0x0001,
54 RT_BITMAP = 0x0002,
55 RT_MENU = 0x0003,
56 RT_DIALOG = 0x0004,
57 RT_STRING = 0x0005,
58 RT_FONTDIR = 0x0006,
59 RT_FONT = 0x0007,
60 RT_ACCELERATOR = 0x0008,
61 // binary data
62 RT_RCDATA = 0x0009,
63 // error message
64 RT_MESSAGE = 0x000A,
65 RT_DLGINCLUDE = 0x000B,
66 RT_VKEYTBL = 0x000C,
67 RT_KEYTBL = 0x000D,
68 RT_CHARTBL = 0x000E,
69 RT_DISPLAYINFO = 0x000F,
70 // function key area
71 RT_FKASHORT = 0x0010,
72 RT_FKALONG = 0x0011,
73 RT_HELPTABLE = 0x0012,
74 RT_HELPSUBTABLE = 0x0013,
75 RT_FDDIR = 0x0014,
76 RT_FD = 0x0015,
77 };
78 }
79
89 class NEFormat : public virtual Linker::SegmentManager, public std::enable_shared_from_this<NEFormat>
90 {
91 public:
92 /* * * General members * * */
93
95 struct Name
96 {
97 public:
98 std::string name;
99 uint16_t ordinal = 0;
100 };
101
104 {
105 public:
106 std::shared_ptr<Linker::Image> image;
107 offset_t data_offset = 0;
109 offset_t image_size = 0;
110 enum flag_type : uint16_t
111 {
112 Data = 1, Code = 0,
113 Allocated = 2,
114 Loaded = 4, /* RealMode = 4 */ /* TODO */
115 Iterated = 8, /* TODO */
116 Movable = 0x10, Fixed = 0,
117 Shareable = 0x20,
118 Preload = 0x40, LoadOnCall = 0,
119 ExecuteOnly = 0x80|Code, ReadOnly = 0x80|Data,
120 Relocations = 0x0100,
121 DebugInfo = 0x0200,
122 Discardable = 0x1000,
123 };
124 flag_type flags = flag_type(0);
126 uint32_t total_size = 0;
132
133 Segment()
134 {
135 }
136
137 Segment(std::shared_ptr<Linker::Segment> segment, unsigned flags)
138 : image(segment), flags(flag_type(flags))
139 {
140 }
141
142 enum
143 {
144 PrivilegeLevelShift = 10,
145 };
146
148 {
149 public:
193 std::vector<uint16_t> offsets;
195 uint16_t module = 0;
196 enum
197 {
198 FIARQQ = 1, FJARQQ = 1,
199 FISRQQ = 2, FJSRQQ = 2,
200 FICRQQ = 3, FJCRQQ = 3,
201 FIERQQ = 4,
202 FIDRQQ = 5,
203 FIWRQQ = 6,
204 };
207
209 std::string module_name;
211 std::string import_name;
213 uint8_t actual_segment = 0;
216
217 Relocation() = default;
218
219 Relocation(unsigned type, unsigned flags, uint16_t offset, uint16_t module, uint16_t target)
220 : type(source_type(type)), flags(flag_type(flags)), module(module), target(target)
221 {
222 offsets.push_back(offset);
223 }
224
225 static source_type GetType(Linker::Relocation& rel);
226 size_t GetSize() const;
227 };
228 std::vector<Relocation> relocations;
230 std::map<uint16_t, Relocation> relocations_map;
231
232 void AddRelocation(const Relocation& rel);
233 void Dump(Dumper::Dumper& dump, unsigned index, bool isos2) const;
234 };
235
240 class Resource : public Segment
241 {
242 public:
247 uint16_t type_id = 0;
249 std::string type_id_name;
254 uint16_t id = 0;
256 std::string id_name;
258 uint16_t handle = 0;
260 uint16_t usage = 0;
261
262 void Dump(Dumper::Dumper& dump, unsigned index, bool isos2) const;
263 };
264
267 {
268 public:
269 uint16_t type_id = 0;
270 std::string type_id_name;
271 std::vector<Resource> resources;
272 };
273
275 class Entry
276 {
277 public:
291 uint8_t segment = 0;
293 static constexpr uint8_t CONSTANT_VALUE = 0xFE;
295 enum flag_type : uint8_t
296 {
301 };
302 flag_type flags = flag_type(0);
304 uint16_t offset = 0;
305
306 // informational purposes
319 std::string entry_name;
320
321 enum
322 {
323 WordCountShift = 3,
324
326 INT_3Fh = 0x3FCD,
327 };
328
330 mutable bool same_bundle = false; // mutable because this isn't actually part of the entry state but the entire entry table
331
332 Entry() = default;
333
334 Entry(unsigned type, uint8_t segment, unsigned flags, uint16_t offset)
336 {
337 }
338
340 offset_t GetEntrySize() const;
341
343 uint8_t GetIndicatorByte() const;
344
346 static Entry ReadEntry(Linker::Reader& rd, uint8_t indicator_byte);
348 void WriteEntry(Linker::Writer& wr) const;
349 };
350
353 {
354 public:
356 uint16_t name_offset = 0;
358 std::string name;
359
360 ModuleReference(uint16_t name_offset, std::string name = "")
362 {
363 }
364 };
365
367 std::array<char, 2> signature{'N', 'E'};
368
370 struct version
371 {
372 uint8_t major, minor;
373 };
376
377 uint32_t crc32 = 0;
378
379 enum program_flag_type : uint8_t
380 {
393
394 GLOBAL_INITIALIZATION = 4,
395 PROTECTED_MODE_ONLY = 8,
396 CPU_8086 = 0x10, /* this is not how all systems handle this */
397 CPU_80286 = 0x20,
398 CPU_80386 = 0x40,
399 CPU_8087 = 0x80,
400 };
403
405 {
417 GUI = 3,
418
419 FAMILY_APPLICATION = 8, /* first segment loads application */
420 ERROR_IN_IMAGE = 0x20,
421
423 LIBRARY = 0x80,
424 };
427
429 uint16_t automatic_data = 0;
430
432 uint16_t stack_size = 0;
434 uint16_t heap_size = 0;
435
436 uint16_t ip = 0, cs = 0, sp = 0, ss = 0;
437
438 // The following fields are listed in the order the parts appearing in the binary instead of the fields in the header
439
445
446 std::vector<Segment> segments;
447
453
454 uint16_t resource_count = 0;
455
457 uint16_t resource_shift = 0;
458
460 std::vector<Resource> resources;
461
463 std::vector<ResourceType> resource_types;
464
466 std::vector<std::string> resource_strings;
467
473
474 std::vector<Name> resident_names;
475
481
482 std::vector<ModuleReference> module_references;
483
489
490 std::vector<std::string> imported_names;
491
497 uint32_t nonresident_name_table_length = 0;
498
499 std::vector<Name> nonresident_names;
500
505 uint32_t entry_table_offset = 0;
506
508 uint32_t entry_table_length = 0;
509
512
513 std::vector<Entry> entries;
514
516 uint16_t sector_shift = 9;
517
518 enum system_type : uint8_t
519 {
521 OS2 = 1,
526 Windows386,
527 BorlandOSS,
528 PharLap = 0x80,
529 };
530 system_type system = system_type(0);
531
532 enum additional_flag_type : uint8_t
533 {
534 SUPPORT_LONGFILENAME = 1,
535 WIN20_PROTECTED_MODE = 2,
536 WIN20_PROPORTIONAL_FONTS = 4,
537 FAST_LOAD_AREA = 8,
538 };
539 additional_flag_type additional_flags = additional_flag_type(0);
540
541 union
542 {
543 /* Windows */
544 uint16_t fast_load_area_offset;
545 /* OS/2 ? */
546 uint16_t return_thunks_offset;
547 };
548 union
549 {
550 /* Windows */
551 uint16_t fast_load_area_length;
552 /* OS/2 ? */
553 uint16_t segment_reference_thunks_offset;
554 };
555 uint16_t code_swap_area_length = 0;
556
557 version windows_version{0, 0};
558
559 offset_t file_size = offset_t(-1);
560
561 bool IsLibrary() const;
562
563 bool IsOS2() const;
564
565 void ReadFile(Linker::Reader& rd) override;
566
567 offset_t ImageSize() const override;
568
570 offset_t WriteFile(Linker::Writer& wr) const override;
571
572 void Dump(Dumper::Dumper& dump) const override;
573
574 explicit NEFormat()
575 {
576 }
577
578 NEFormat(system_type system, unsigned program_flags, unsigned application_flags)
580 fast_load_area_offset(0), fast_load_area_length(0)
581 {
582 }
583
584 /* * * Writer members * * */
585
587 {
588 public:
589 Linker::Option<std::string> stub{"stub", "Filename for stub that gets prepended to executable"};
590
592 {
593 InitializeFields(stub);
594 }
595 };
596
597 mutable MZStubWriter stub;
598 std::shared_ptr<Linker::Segment> stack, heap;
599 std::map<std::shared_ptr<Linker::Segment>, size_t> segment_index;
600 std::map<std::string, uint16_t> module_reference_offsets;
601 std::map<std::string, uint16_t> imported_name_offsets;
602 uint16_t imported_names_length = 0;
603
604 /*std::string stub_file;*/
605 std::string module_name;
606 std::string program_name;
607
608 bool option_capitalize_names = false; /* TODO: parametrize */
609 enum memory_model_t
610 {
611 MODEL_SMALL,
612 MODEL_LARGE,
613 };
614 memory_model_t memory_model = MODEL_SMALL;
615
616 bool FormatSupportsSegmentation() const override;
617
618 bool FormatIs16bit() const override;
619
620 bool FormatIsProtectedMode() const override;
621
622 bool FormatSupportsLibraries() const override;
623
624 unsigned FormatAdditionalSectionFlags(std::string section_name) const override;
625
626 enum compatibility_type
627 {
628 CompatibleNone,
629 CompatibleWatcom,
630 CompatibleMicrosoft, /* TODO */
631 CompatibleGNU, /* TODO */
632 };
633 compatibility_type compatibility = CompatibleNone;
634
635 std::shared_ptr<NEFormat> SimulateLinker(compatibility_type compatibility);
636
637 static std::shared_ptr<NEFormat> CreateConsoleApplication(system_type system = Windows);
638
639 static std::shared_ptr<NEFormat> CreateGUIApplication(system_type system = Windows);
640
641 static std::shared_ptr<NEFormat> CreateLibraryModule(system_type system = Windows);
642
643 unsigned GetCodeSegmentFlags() const;
644 unsigned GetDataSegmentFlags() const;
645 void AddSegment(const Segment& segment);
646 uint16_t FetchModule(std::string name);
647 uint16_t FetchImportedName(std::string name);
648 std::string MakeProcedureName(std::string name);
649 uint16_t MakeEntry(Linker::Position value);
650 uint16_t MakeEntry(uint16_t ordinal, Linker::Position value);
651 uint8_t CountBundles(size_t entry_index) const;
652
653 void SetModel(std::string model) override;
654 std::shared_ptr<Linker::OptionCollector> GetOptions() override;
655 void SetOptions(std::map<std::string, std::string>& options) override;
656 void OnNewSegment(std::shared_ptr<Linker::Segment> segment) override;
657 std::unique_ptr<Script::List> GetScript(Linker::Module& module);
658 void Link(Linker::Module& module);
659 void ProcessModule(Linker::Module& module) override;
660 void CalculateValues() override;
661 void GenerateFile(std::string filename, Linker::Module& module) override;
663 std::string GetDefaultExtension(Linker::Module& module, std::string filename) const override;
664 };
665}
666
667#endif /* NEEXE_H */
An abstract interface that separates structure and presentation of the data inside a file.
Definition dumper.h:586
offset_t WriteFile(Writer &wr) const override=0
Stores data in memory to file.
Encodes an object module file as a collection of sections, symbols and relocations.
Definition module.h:24
Helper class that contains the options interpreted by the format.
Definition options.h:467
Documents and handles command line options.
Definition options.h:303
virtual std::string GetDefaultExtension(Module &module, std::string filename) const
Appends a default extension to the filename.
Stores an absolute address along with the containing segment or address space.
Definition position.h:17
A helper class, encapsulating functionality needed to import binary data.
Definition reader.h:16
A representation of a value within some binary data that has to be fixed up once the exact position o...
Definition relocation.h:27
A helper class to collect sections into segments.
Definition segment_manager.h:32
A helper class, encapsulating functionality needed to export binary data.
Definition writer.h:15
Definition mzexe.h:300
Represents an entry into the binary, typically DLL exported procedures.
Definition neexe.h:276
offset_t GetEntrySize() const
Returns the size of an entry as stored in the file, without the first two bytes of the bundle.
Definition neexe.cc:299
uint8_t segment
The number of the segment, 1 based.
Definition neexe.h:291
void WriteEntry(Linker::Writer &wr) const
Writes an entry within a bundle.
Definition neexe.cc:355
flag_type
Flags present in an entry.
Definition neexe.h:296
@ Exported
Set if the entry is exported.
Definition neexe.h:298
@ SharedData
Set if the data segment used by the entry is global, used in SINGLEDATA modules (libraries)
Definition neexe.h:300
bool same_bundle
Convenience field to signify this entry is part of the same bundle as the previous one.
Definition neexe.h:330
uint16_t offset
Offset within the segment.
Definition neexe.h:304
export_type export_state
Whether the entry is exported. This is not actually stored in the entry table and its value is ignore...
Definition neexe.h:317
static Entry ReadEntry(Linker::Reader &rd, uint8_t indicator_byte)
Reads an entry within a bundle.
Definition neexe.cc:330
uint8_t GetIndicatorByte() const
Retrieves the segment indicator byte. For Fixed entries, this the same as the segment number.
Definition neexe.cc:315
export_type
Definition neexe.h:308
@ NotExported
The entry is not exported, the Exported bit is not set.
Definition neexe.h:310
@ ExportByOrdinal
The entry is exported by ordinal, it is referenced in the nonresident name table.
Definition neexe.h:314
@ ExportByName
The entry is exported by name, it is referenced in the resident name table.
Definition neexe.h:312
std::string entry_name
The name of an exported entry. This is not actually stored in the entry table and its value is ignore...
Definition neexe.h:319
@ INT_3Fh
Byte code for interrupt call that must be placed in the entry field.
Definition neexe.h:326
entry_type
This field represents the type of the entry.
Definition neexe.h:280
@ Fixed
The entry references a fixed segment.
Definition neexe.h:284
@ Movable
The entry references a movable segment.
Definition neexe.h:286
@ Unused
The entry is unused, the other fields are meaningless.
Definition neexe.h:282
static constexpr uint8_t CONSTANT_VALUE
Segment value to represent a constant in the module.
Definition neexe.h:293
entry_type type
The type of entry, based on the first byte in an entry bundle.
Definition neexe.h:289
Represents an imported module in the module reference table.
Definition neexe.h:353
std::string name
The name of the module, not actually used during program generation.
Definition neexe.h:358
uint16_t name_offset
Offset to the module name within the imported names table.
Definition neexe.h:356
Windows executables bundle their resources by resource type.
Definition neexe.h:267
Represents a resource entry.
Definition neexe.h:241
uint16_t handle
Reserved field, named so in Microsoft documentation.
Definition neexe.h:258
std::string type_id_name
Type name, used only by Windows.
Definition neexe.h:249
uint16_t usage
Reserved field, named so in Microsoft documentation.
Definition neexe.h:260
std::string id_name
Resource name, used only by Windows.
Definition neexe.h:256
uint16_t type_id
Type identifier, used by both Windows and OS/2.
Definition neexe.h:247
std::string import_name
Convenience field that stores the imported procedure name, if imported by name, also the name for an ...
Definition neexe.h:211
uint8_t actual_segment
Convenience field that stores the actual segment for an entry.
Definition neexe.h:213
flag_type flags
The type of target.
Definition neexe.h:191
source_type
The type of the field that needs to be updated in the binary image.
Definition neexe.h:152
@ Offset16
A 16-bit offset within its preferred segment.
Definition neexe.h:160
@ Selector16
A 16-bit segment selector value (or paragraph in real mode)
Definition neexe.h:156
@ Offset32
A 32-bit offset within its preferred segment.
Definition neexe.h:164
@ Pointer48
A 48-bit far pointer, 16-bit segment and 32-bit offset value.
Definition neexe.h:162
@ Offset8
Lower 8 bits of value.
Definition neexe.h:154
@ Pointer32
A 32-bit far pointer, 16-bit segment and 16-bit offset value.
Definition neexe.h:158
uint16_t target
This field is an offset or ordinal, depending on the flags.
Definition neexe.h:206
flag_type
Encodes what the type of the target is for this relocation.
Definition neexe.h:170
@ TargetTypeMask
Mask to get the type of the target.
Definition neexe.h:172
@ Internal
An internal segment:offset, or if segment is 0xFF, offset is the entry number.
Definition neexe.h:174
@ Additive
Whether the relocation has an added in the image or it is the first element in a relocation chain.
Definition neexe.h:188
@ ImportName
An imported module:offset where module is the module number and offset is an offset to the name.
Definition neexe.h:178
@ OSFixup
This is actually an 80x87 instruction sequence that needs to be fixed up for 80x87 emulation.
Definition neexe.h:180
@ ImportOrdinal
An imported module:ordinal where module is the module number.
Definition neexe.h:176
source_type type
The type of relocation.
Definition neexe.h:167
std::string module_name
Convenience field that stores the module name.
Definition neexe.h:209
std::vector< uint16_t > offsets
The offset to the relocation, or if the relocation is chained, a list of offsets (this is not possibl...
Definition neexe.h:193
uint16_t
This field is a segment (1 based) or module (1 based) or 80x87 instruction reference,...
Definition neexe.h:195
uint16_t actual_offset
Convenience field that stores the actual offset for an entry.
Definition neexe.h:215
Represents an NE segment as stored in the segment table and segment data.
Definition neexe.h:104
uint32_t total_size
Size of segment as stored in memory.
Definition neexe.h:126
offset_t image_size
Size of segment as stored in the file, only used during reading.
Definition neexe.h:109
std::map< uint16_t, Relocation > relocations_map
Used internally during output generation.
Definition neexe.h:230
uint16_t movable_entry_index
Entry number for movable segments (field not present in segment table)
Definition neexe.h:131
NE .EXE new executable file format.
Definition neexe.h:90
uint32_t imported_names_table_offset
Offset of imported names table, containing the names of imported modules and procedures imported by n...
Definition neexe.h:488
uint32_t segment_table_offset
Offset of segment table.
Definition neexe.h:444
std::vector< ResourceType > resource_types
For non-OS/2 targets, the resources get organized according to their types.
Definition neexe.h:463
uint16_t heap_size
Size of initial heap, added to the size of the automatic data segment.
Definition neexe.h:434
offset_t WriteFile(Linker::Writer &wr) const override
Stores data in memory to file.
Definition neexe.cc:789
uint32_t resident_name_table_offset
Offset of resident name table, containing this module's name and the names and ordinals of procedures...
Definition neexe.h:472
program_flag_type
Definition neexe.h:380
@ MULTIPLEDATA
There is an automatic data segment for each task instance, used for applications (EXE)
Definition neexe.h:392
@ NODATA
There are no automatic data segments.
Definition neexe.h:382
@ SINGLEDATA
There is a single, shared automatic segment, used for libraries (DLL)
Definition neexe.h:387
program_flag_type program_flags
Properties of the program during execution.
Definition neexe.h:402
application_flag_type
Definition neexe.h:405
@ GUI
Graphical application.
Definition neexe.h:417
@ GUI_AWARE
Application is well behaved when running in windowed mode.
Definition neexe.h:415
@ LIBRARY
Set for library modules (DLL)
Definition neexe.h:423
@ FULLSCREEN
Application can only run in full screen mode.
Definition neexe.h:410
void SetOptions(std::map< std::string, std::string > &options) override
Passes command line parameters as settings over to format object.
Definition neexe.cc:1473
bool FormatSupportsSegmentation() const override
Whether the format supports multiple segments.
Definition neexe.cc:1232
uint32_t resource_table_offset
Offset of resource table.
Definition neexe.h:452
uint16_t resource_shift
Specifies the shift count to get the actual offsets for the resource data.
Definition neexe.h:457
void CalculateValues() override
Intermediate step between processing module and generating output file to set up headers and manageme...
Definition neexe.cc:1833
std::shared_ptr< Linker::OptionCollector > GetOptions() override
Returns object containing a sequence of option fields provided with the -S command line flag.
Definition neexe.cc:1468
std::string GetDefaultExtension(Linker::Module &module, std::string filename) const override
Appends a default extension to the filename.
Definition neexe.cc:1981
uint32_t entry_table_length
Size of entry table in bytes.
Definition neexe.h:508
uint16_t automatic_data
Automatic data segment number, starting from 1, only used for SINGLEDATA/MULTIPLEDATA.
Definition neexe.h:429
uint16_t stack_size
Size of initial stack, added to the size of the automatic data segment.
Definition neexe.h:432
bool FormatIs16bit() const override
Whether the format is 16-bit or not.
Definition neexe.cc:1237
bool FormatIsProtectedMode() const override
Whether the format is in protected mode or not (x86 only)
Definition neexe.cc:1242
version linker_version
Version of the linker.
Definition neexe.h:375
void ReadFile(Linker::Reader &rd) override
Loads file into memory.
Definition neexe.cc:384
application_flag_type application_flags
Properties of the application.
Definition neexe.h:426
system_type
Definition neexe.h:519
@ OS2
Used for OS/2 1.0 - 1.3.
Definition neexe.h:521
@ MSDOS4
Signifies Multitasking MS-DOS 4.0.
Definition neexe.h:525
@ Windows
Used for Windows 1.0 - 3.11.
Definition neexe.h:523
uint16_t movable_entry_count
Number of movable entries in the entry table.
Definition neexe.h:511
offset_t ImageSize() const override
Retrieves size of stored data.
Definition neexe.cc:784
uint32_t entry_table_offset
Offset of entry table.
Definition neexe.h:505
std::array< char, 2 > signature
The signature, almost always "NE".
Definition neexe.h:367
bool FormatSupportsLibraries() const override
Whether the format supports libraries.
Definition neexe.cc:1248
std::vector< std::string > resource_strings
For non-OS/2 targets, this is a list of all the resource type strings and resource strings.
Definition neexe.h:466
void SetModel(std::string model) override
Sets the way memory is organized, typically modifying a built-in script.
Definition neexe.cc:1948
uint16_t sector_shift
Specifies the shift count to get the actual offsets of segments.
Definition neexe.h:516
void GenerateFile(std::string filename, Linker::Module &module) override
The main function that handles processing, calculating and generating the final image.
Definition neexe.cc:1965
void ProcessModule(Linker::Module &module) override
Processes the module object and initializes format fields.
Definition neexe.cc:1610
void Dump(Dumper::Dumper &dump) const override
Display file contents in a nice manner.
Definition neexe.cc:974
std::vector< Resource > resources
On OS/2, this is a sequence of resources, for non-OS/2 targets, this must be compiled into resource_t...
Definition neexe.h:460
uint32_t nonresident_name_table_offset
Offset of non-resident names table, containing this module's description and the names of procedures ...
Definition neexe.h:496
uint32_t module_reference_table_offset
Offset of module reference table, containing 16-bit offsets to the names of the imported modules in t...
Definition neexe.h:480
A name and ordinal pair, as used for resident and non-resident names.
Definition neexe.h:96
Version number.
Definition neexe.h:371