random notes to myself

April 20, 2009

using WDK/DDK build environment for drivers and non-drivers

Filed under: Uncategorized — dbgnotes @ 2:22 am

I don’t use the WDK/DDK on a daily basis.  However, once in a while, I do not have access to the platform SDK and still need to use it to build a console/win32 app.  If you have never used the WDK build environment before, it can be painful and frustrating.  I always forget how to do it myself so I am going to document it here for myself and others who might find it useful.  Here it goes…

The WDK includes all of the libraries and header files needed to build everything from a simple console/GUI app to various types of Windows drivers in C/C++.  This means that you do not really need to download the Platform/Windows SDK for simple development needs.  The WDK and SDK are around 600mb and 1.3GB, respectively.  For most cases, we will be using the “sources” file to tell the WDK build environment what we want.  Basically, the “sources” file is just a plaintext file where each line is a “variable=value” format; each variable is like an option to the build tool.  In most cases, you just need to know a few of the variable names and you can build your app.

There are many target types that people want to build so I am going to try to enumerate and go through each one.  The list will be updated as I go along (or people can contribute).  The list will include these target types: console app, GUI app, DLL, and driver.

  • Building a CONSOLE APP with WDK’s build environment
  1. Create your .c file.  I am just going to do a simple “hello world” app.  I made a “hello.c” file and saved it in “c:\blah” and its content is like thus:
  2. #include <stdio.h>
    __cdecl main(void)
      printf("Hello World\n");
      return 0;

  3. I went to the build prompt (I used “Windows XP Free Build Environment”); then change to the c:\blah folder
  4. I made a new file called “sources” in that folder and its content is like thus:

  5. TARGETNAME=hello   # your program name (it'll compile to "hello.exe")
    TARGETTYPE=PROGRAM # PROGRAM means that it will be a normal executable program

    # other common choices for TARGETTYPE are: DYNLINK, LIBRARY, DRIVER
    UMTYPE=console     # usermode target type CONSOLE. this is a 32bit user-mode console app

    # the other common choice for UMTYPE is: WINDOWS (gui app)
    UMENTRY=main       # default entry point shoudl be "main"

    # other choices for UMENTRY are: WINMAIN, WMAIN, ...

    USE_MSVCRT=1        # use the multithreaded runtime library
    USER_C_FLAGS = /FAs # compiler flags (/FAs = produce a .asm file as well)

    # reading the .asm file is a good way to learn assembly
    MSC_OPTIMIZATION = /Od /Oi # optimization flags (/Od = disable all optimization)

    # i normally disable all optimization for debugging purposes

    SOURCES=hello.c     # the name of the source file

    You can read more about the details of these variables at http://msdn.microsoft.com/en-us/library/ms792396.aspx (or the WDK help file)

  6. Type “build” while inside the “c:\blah” dir and you should see the following:

  7. C:\blah>build
    BUILD: Compile and Link for x86
    BUILD: Loading c:\winddk\6001.18002\build.dat...
    BUILD: Computing Include file dependencies:
    BUILD: Start time: Sun Apr 19 17:54:50 2009
    BUILD: Examining c:\blah directory for files to compile.
    BUILD: Saving c:\winddk\6001.18002\build.dat...
    BUILD: Compiling and Linking c:\blah directory
    Compiling - hello.c
    Linking Executable - objfre_wxp_x86\i386\hello.exe
    BUILD: Finish time: Sun Apr 19 17:55:02 2009
    BUILD: Done

    3 files compiled
    1 executable built


  8. Now your executable files are in “C:\blah\objfre_wxp_x86\i386” (this can be different, depending on what platform you selected… here, I picked XP FREE BUILD). That’s it!

That’s all there is to it. You can just modify that template accordingly for your situation. If you have more than one source file, then just add them to the “SOURCE=” line, separated by spaces or tabs; for example, “SOURCES = hello.c file1.c file2.c”.

Now, we will move on to building a GUI APP. I am just going to make a simple app that displays a messagebox with an OK button. It will use the MessageBox function from USER32.

  • Building a GUI APP with WDK’s build environment
  1. I create a “msg.c” file in the “c:\blah” folder; the content is like thus:

  2. #include <tchar.h>
    #include <windows.h>

    WINAPI WinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow)
      int rval;
      rval = MessageBox(NULL, TEXT("this is text"), TEXT("this is caption"), MB_OK);
      return 0;

  3. Now I create the “sources” file for it; the content is like thus:

    UMTYPE=windows #changed from "console"

    UMENTRY=winmain #changed from "main"


  5. Now I type “build” and see that it is successful. That’s it. Note that all of the linking dependencies (USER32.LIB) are taken care for us. USER32.LIB is default for WINDOWS app; for other libraries like WS2_32.LIB, MPR.LIB, etc., we will need to explicitly specify it. I will cover that in the next section.

Now we are going to write a small app that uses WS2_32.LIB to get our hostname. The point of doing this app is to show how to tell the build environment that you need to link against some libraries. It’s simple, but I am just going to do it step by step to make sure it is clear.

  • Building a normal app that links against a library with the WDK’s build environment
  1. I am going to create a file called “getname.c” in the “c:\blah” folder as before. The content is like thus:

  2. #include <windows.h>
    #include <stdio.h>
    #include <winsock2.h>

    __cdecl main(void)
    char buf[128];
    int retval;
    WSADATA wsd;
    WSAStartup(MAKEWORD(2,2), &wsd);
    retval = gethostname(buf, 128);
    printf("hostname is %s\n", buf);
    return 0;

  3. The “sources” file is like thus:

  4. TARGETNAME=getname


    TARGETLIBS = $(SDK_LIB_PATH)\ws2_32.lib # the only new line...
    # if you need to link against more libraries, you can do it like this $(SDK_LIB_PATH)\blah2.lib $(SDK_LIB_PATH)\blah3.lib

  5. Now type “build” and see that it succeeds.
  6. What we did here was simply told “build” to link against WS2_32.LIB because gethostname() is part of that library. If you used routines in other libraries, you can add the .LIB file here as well (separated by spaces/tabs).

That’s all there is to it.


Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

Blog at WordPress.com.

%d bloggers like this: