Windows 2003 SP1 DDK with a little annoyance …

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.

  1. 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 …

  2. create a new .c/.cpp file and add it to the SOURCES line inside the SOURCES file. In my case it is the file called startup.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 call NtProcessStartup(), 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 😉 …

This entry was posted in Programming. Bookmark the permalink.

4 Responses to Windows 2003 SP1 DDK with a little annoyance …

  1. CMK says:

    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:

    // only use this file if we are building under/for a Win2K environment
    #if _WIN32_WINNT == 0x500
    
    extern void NtProcessStartup(void * StartupArgument);
    
    extern void NtProcessStartupForGS(void * StartupArgument);
    
    void NtProcessStartupForGS(void * StartupArgument)
    {
    	NtProcessStartup(StartupArgument);
    }
    
    #endif

    Very useful. Thanks!

  2. Oliver says:

    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.

  3. Jeff says:

    Yes, thank you for posting this. I am proof that it continues to be useful. You saved me a lot of time today!

  4. Oliver says:

    Just as a side-note: DDKWizard handles this case and creates the file described here for you.

Leave a Reply

Your email address will not be published. Required fields are marked *