I started a project to get a better understanding on how to compile a game for Windows 3.x. I tried to set up the build workflow so that it produce the byte-exact clone of a great open sourced Win16 game named Hyperoid. It took some time to get a working build for Windows 3.0 which I finally managed. However, no matter how I played with the compiler and linker options, I was not able to produce a similar EXE in some aspects.

One of them is related to the export of ___EXPORTEDSTUB which is obviously not in the original release but I was unable to get rid off which in my build.

What is that and how to set up the build process to avoid it getting exported?

(More details in the project link above.)


Quote from Windows Programmer's Guide to DLLs and Memory Management p. 137:

The stub statement is used to identify an application that is run when an attempt is made to run a Windows application under DOS. The default file normally used is WINSTUB.EXE, which prints a simple error and returns to the DOS prompt. In fact, the entry point of this application is responsible for the ___EXPORTEDSTUB statement that's visible when exehdr is run on a module or when you view a module's map file. The statement isn't required for libraries, and it saves a few bytes when removed.

This is all nice but the book does not tell how to remove it. Removing the STUB declaration entirely from the DEF file or setting its value to NONE removes the WINSTUB data which is certainly there in the original game file and working as intended: it prints This program requires Microsoft Windows message when the EXE is run from DOS.


Changing DEF like below only moves ___EXPORTEDSTUB from the Resident Names Table to the Non-resident Names Table and it also remains exported according to EXEHDR output. A small step ahead though.

    HyperoidWndProc     @1
    HyperoidAboutDlg    @2
    ___ExportedStub     @3 NODATA


I suspect I was not clear enough about the problem so here is a screenshot of the binary differences (this is prior the Edit 2): SCREENSHOT The problem is with the new file from 0x5DB highlighted with green. The other differences are due to different address values and are minor problem compared to this one. The increased NE header puts all other stuff ahead, thus removing it manually would corrupt the EXE file. Note that the DEF file tweak done in Edit 2 only moved the problematic green part a little lower.

There must be a way to tell the linker (or a reliable tool which removed it).


This is from the Digital Mars Compiler & Tools Guide:

Problem: _ExportedStub missing. The Microsoft C++ libraries provides the entry point _ExportStub, which can be exported by user .DEF files. Remove _ExportStub from your .DEF files; it is specific to Microsoft's implementation of its internal routine _GetGROUP. This change is unlikely to introduce any problems.

I was not able to find a DEF file with _ExportStub in it yet.

  • Given this wording: "The stub statement ..." -- where is the "statement" located? It sounds to me like it's an actual statement in some file of LINK directives, which I vaguely recall dealing with about 30 years ago. Sep 8 at 23:30
  • I fixed the wording sorry. The book refers both the declaration in the DEF file and the exported function in the MAP file as "statement". By removing the STUB declaration I meant removing the STB 'WINSTUB.EXE' line from the DEF file. Edited for clarification. Sep 9 at 0:17
  • "There must be a way to tell the linker (or a reliable tool which removed it)" Why?
    – Raffzahn
    Sep 9 at 2:03
  • Can you edit this tower of EDITs into something more coherent? Sep 11 at 13:17

Windows EXE programs do have to start with a STUB to avoid unintended consequences (crash etc.) when started in a non-Windows environment.

EXPORTEDSTUB is supplied by the MLIBCEW Lib used in your link statement.

IIRC it is possible to tell the linker (-stub?) to use a user supplied stub - which was, at one time, the standard way by using WINSTART.ASM (Faint Memory).

[I wouldn't be surprised if Stephen Kitt has the right documentation ready at hand :)]

As I understand, there is no access to the original source, so it might have been build a diferent way. What compiler/linker package is used?

  • No the WINSTUB.EXE is placed identically in both the original and the new version. Only the export statement got removed from the original EXE's Resident Names Table and export MAP. I compile and link with Ms C 6.0. Sep 9 at 0:34
  • @SzieberthAdam Not really sure what your comment should tell or what new version is. Look at your link statement where you include MLIBCEW - that's where the symbol gets imported from.
    – Raffzahn
    Sep 9 at 2:07
  • Thank you. Good lead with the MLIBCEW.LIB. I currently suspect a custom library was made based on that with LIB.EXE. It seems that windgrp.obj (and maybe windgrpx.obj) should be replaced in it. C/C++ 7.0 surely contains the sources of these object modules, I should review the C 6.0 installation whether it contains them too. Upvoted. Sep 10 at 12:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.