dev.nlited.com

>>

Kernel Drivers: Visual Studio SetUp

<<<< prev
next >>>>

2014-12-29 21:22:21 chip Page 1149 📢 PUBLIC

Using Visual Studio to build Device Drivers

I have been using Visual Studio to build Windows kernel mode drivers since Visual Studio 5. People who insist on using the WDK (nee DDK) command line build environment are masochists. Don't listen to them.

This document describes how to configure a VM-to-VM kernel debugging environment. Using this method, I can put my complete driver development environment on a portable USB drive and be up and running on any host PC in ten minutes.

The key to making Visual Studio work is to make all the configurations as closely identical as possible. Whenever changing the project properties, unless there is a strong and compelling reason not to, always select "All platforms" and "All configurations".

VS kernel config general
Note that all the output directories are under a single "Out" directory.

VS kernel config C general
The include path:
$(ProjectDir);
$(SolutionDir)Include;
"$(WDKPATH)Includekm";
"$(WDKPATH)Includeshared";
"$(VS12PATH)VCinclude"

Global environment variables:
WDKPATH=C:Program Files (x86)Windows Kits8.1 VS12PATH={VisualStudio installation directory}

VS kernel config C optimization
All modules are optimized, even in debug builds. I disable optimization on individual files I am actively debugging by adding these lines to the top of the source code, just after the #includes:

#pragma message(__FILE__": Optimizer disabled.") #pragma optimize("",off)
Using this strategy means that the optimized code, which will be the release version, will be constantly exercised while I am debugging. Disabling the optimizer globally leads to production release disasters, and is why so many companies ship debug builds.

VS kernel config C preprocessor
Note the very short list of defines! All the common defines have been moved out of the project configuration to NtBuild.h. Only symbols that are specific to this configuration should be included here.

NtBuild.h:

/*************************************************************************/ /** NtBuild.h: Defines WDK constants for selecting the target **/ /** OS and machine. This file is automatically included **/ /** first by Driver > Properties > Advanced > Force include **/ /** (C)2013 nlited systems inc, Chip Doran **/ /*************************************************************************/ #ifndef __NTBUILD_H__ #define __NTBUILD_H__ 0x0101 #define _WIN32_WINNT 0x0601 //Windows7 #define NTDDI_VERSION 0x06010000 //Windows7 #define KERNEL 1 #define _WINDOWS 1 #define STD_CALL 1 #define CONDITIONAL_HANDLING 1 #define NT_UP 1 #define NT_INST 0 #define WIN32 100 #define _NT1X_ 100 #define WINNT 1 #define WIN32_LEAN_AND_MEAN 1 #define DEVL 1 #define FPO 1 #define _IDWBUILD 1 #define NDIS_SUPPORT_NDIS6 1 #define i686 1 #ifdef _DEBUG #define DBGOUT 1 #elif defined(_RELEASE) #else #error("Must define either _DEBUG or _RELEASE !") #endif #ifdef _X86_ #elif defined(_AMD64_) #else #error("Must define either _X86_ or _AMD64_ !") #endif #endif

VS kernel config C code generation
Basic Runtime Checks are incompatible with full optimization. Between the two, I believe keeping the optimizer is the smarter choice.

VS kernel config C language

VS kernel config C precompiled headers
I never saw much advantage to using precompiled headers.

VS kernel config C output files
The Program Database file name must exactly match the entry in the Linker section.
It is a good practice to generate the assembly output and at least occasionally read through it. This helps when I find myself trying to step through assembly in the field, where source code may not be available.

VS kernel config C browser files

VS kernel config C advanced
Some warnings need to be disabled to let the driver build. No harm done.

VS kernel config C command line

VS kernel config linker general

VS kernel config Linker input files
$(IntDir)VerID.obj;ndis.lib;Fwpkclnt.lib;FltMgr.lib;uuid.lib;ntoskrnl.lib;NtDll.lib;hal.lib;BufferOverflow.lib
VerID.obj needs to be linked in explicitly since it is built during the pre-link step.

VS kernel config linker manifest
Even if the app needs Admin rights, it is better to not require it. This way the app can at least run enough to print an informative message to the user.

VS kernel config linker debug
The PDB file name must match the C Output file entry.
Always generate a map file, especially for release builds, and archive it with the binaries. It will be a lifesaver for problems in the field.

VS kernel config linker system

VS kernel config linker optimization

VS kernel config linker IDL

VS kernel config link meta

VS kernel config linker advanced

VS kernel config linker command line

VS kernel config resources

VS kernel config browser

VS kernel config prelink  VS kernel config VerID
This is where I update the version information.
Doing this during the prelink step means the version info won't be updated unless at least one other object file has been generated first. This eliminates pointless updates if nothing has changed.
VerID.c should be included in the project, but excluded from the build.
BldVerID.bat:

perl ../Bin/VerUpdate.pl VerFile.h prod=../Include/VerProd.h resource=Resource/NetMon.rc cl /I ..Include /I . /c /nologo /Fo%1VerID.obj VerID.c

VS kernel config post-build
This is where I sign the driver.
$(SolutionDir)BinBldSign.bat "$(TargetDir)$(TargetFileName)" "$(IntDir)SignTool.log"
BldSign.bat:
signtool sign /v /ac "MSCV_VSClass3.cer" /s MY /n "nlited systems inc." /t http://timestamp.VeriSign.com/scripts/timstamp.dll %1 > %2



Version Information

See: Version Information



WebV7 (C)2018 nlited | Rendered by tikope in 83.348ms | 44.220.184.63