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.
EXPORTS 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): 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.