This has been posted by me a while ago on NTDEV. I have slightly modified it for the blog.
If you tell BUILD from the WNET DDK to use the W2K settings to build a native application this fails with the reason that _NtProcessStartupForGS@4
could not be resolved. It does not matter whether you try to set UMENTRYABS
in the SOURCES
file, the problem persists. After some investigation I found that the file i386mk.inc
enforces buffer overflow checking by linking against bufferoverflow.lib
! However, the bufferoverflow.lib
in the W2K directory does not contain any implementation (verified by disassembling) of NtProcessStartupForGS
(the ones for WXP and WNET do!), while i386mk.inc
still insists to use this function as the entry point to the executable:
UMENTRY=-entry:NtProcessStartupForGS@4
What a mess. There are two possible solutions, each with their advantages and disadvantages.
- add the following line to your SOURCES file
BUFFER_OVERFLOW_CHECKS=0
This is the simpler of the two solutions, however you lose the advantage of buffer overflow checks …
- create a new .c/.cpp file and add it to the
SOURCES
line inside theSOURCES
file. In my case it is the file calledstartup.cpp
:extern "C" void NtProcessStartup(void * StartupArgument); extern "C" void NtProcessStartupForGS(void * StartupArgument); void NtProcessStartupForGS(void * StartupArgument) { NtProcessStartup(StartupArgument); }
The pointer arguments are intentionally untyped. There is no necessity to include any header file in this module if they are untyped. What we do is defining the
NtProcessStartupForGS()
using the proper linkage (so the linker will be happy) and callNtProcessStartup()
, forwarding the parameter.
Here the disadvantage is again that the buffer overflow checking is gone. However, putting the code in this module into ifdefs depending on the OS version for which the build is might be the way to make your project compatible among different target OS versions most easily.
Hope this is useful to someone else – now not being forced to investigate that long …
PS: The following were set in the SOURCES file:
TARGETTYPE=PROGRAM USE_NTDLL=1 UMTYPE=nt
… and I was using nt.lib for the convenience main()
function.
PPS: The error was:
LINK : error LNK2001: unresolved external symbol _NtProcessStartupForGS@4 objfre_w2k_x86\i386\smss.exe : error LNK1120: 1 unresolved externals
BTW: The main()
function is a wrapper around the NtProcessStartup()
function which should be preferred over the direct entry point. Despite it’s easier to handle 😉 …
Thanks for this post. I actually just ran into this problem yesterday, and you saved me a bit of investigating. I ended up using you 2nd suggestion to create a file called NtProcessStartupForGS_fix.c and I wrapped it in ifdefs so that it is only used when being compiled in the Win2K environment:
Very useful. Thanks!
Good to hear it has been useful for someone already 🙂
I have wrapped the code into pre and code tags so it will show with fixed font size, just in case you wonder.
Yes, thank you for posting this. I am proof that it continues to be useful. You saved me a lot of time today!
Just as a side-note: DDKWizard handles this case and creates the file described here for you.