random notes to myself

April 21, 2009

tell DDK to not do safeseh

Filed under: Uncategorized — dbgnotes @ 4:15 am

Using the new DDK (build 6002) to build stuff, you will sometimes get an error like this:

c:\winddk\6001.18002\lib\wxp\i386\sehupd.lib
engine.lib(engine.obj) : error LNK2026: module unsafe for SAFESEH image.
errors in directory c:blah\
c:\blah\engine.lib(engine.obj) : error LNK2026: module unsafe for SAFESEH image.
c:\blah\objchk_wxp_x86\i386\blah.exe : fatal error LNK1281: Unable to generate SAFESEH image.
c:\blah\objchk_wxp_x86\i386\blah.exe : error LNK1281: Unable to generate SAFESEH image.

SafeSEH is a security feature in new VC compilers… sometimes we don’t want/need them.  To make it so that we do not use SafeSEH, you need to pass in the option to the “sources” file:

NO_SAFESEH = 1

DO NOT put:

LINKER_FLAGS = /SafeSEH:NO

because it wont work.

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>
    int
    __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
    _NT_TARGET_VERSION SET TO WINXP
    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

    C:\blah>

  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>

    int
    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:

  4. TARGETNAME=msg
    TARGETTYPE=PROGRAM
    UMTYPE=windows #changed from "console"

    UMENTRY=winmain #changed from "main"
    USE_MSVCRT=1

    SOURCES=msg.c
    USER_C_FLAGS = /FAs
    MSC_OPTIMIZATION = /Od /Oi

  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>

    int
    __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
    TARGETTYPE=PROGRAM
    UMTYPE=console

    UMENTRY=main
    USE_MSVCRT=1

    SOURCES=getname.c
    USER_C_FLAGS = /FAs
    MSC_OPTIMIZATION = /Od /Oi
    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.

Blog at WordPress.com.