之前用着VisualDDK挺爽的,可以直接用VS来调试,但是只支持Visual2005以上版本,另外对VS2008中文旗舰版的支持不好,被迫无奈我下了个VS2010。无可置疑Visual DDK用起来真的挺爽的,起码能省去配置环境的时间。另外,搭配Visual KD双机调试,速度比用传统的串口调试速度快多了。
今天,想用VC6.0来写下驱动代码,VC6.0毕竟小巧灵活点,但奈何VisualDDK不大支持。好吧,只得自己配置一下环境了。参考了下网上其他的文章,结合自己的实践、理解终于搞定了。
VC6.0 + WDK 7600.16385.1,这里主要是为了开发XP下的NT式驱动程序,我这里就主要测试了这个,其他的类似。
1. 安装好VC6和WDK,先后顺序无关。
从开始菜单找到WDK的程序目录(Windows Driver Kits),进入相关的编译环境,这里选择“Windows XP Checked Build Environment”,输入命令"build",此时WDK将会把自己进行编译,大约需要1分钟。
2. VC6设置Include/Lib/Executable目录。
进入 菜单栏-->工程-->选项-->目录
PS:设置为自己需要编译的平台的各个目录即可, Include要确保找到ntddk.h等,Lib与Include对应,Executable 要确保能找到cl.exe等。
例如XP平台下设置为:
“Include Files”包含部分:
D:\WinDDK\7600.16385.1\inc\ddk D:\WinDDK\7600.16385.1\inc\api D:\WinDDK\7600.16385.1\inc\crt
嗯,还是说下吧CRT是C Runtime Library的简写
“Library Files”包含部分:
D:\WinDDK\7600.16385.1\lib\wxp\i386 D:\WinDDK\7600.16385.1\lib\Crt\i386
PS:这里选择自己平台的库吧,WXP表示XP的,I386是CPU架构。
“可执行文件”包含部分:
D:\WinDDK\7600.16385.1\bin\x86\x86
注意,将刚才添加的这些目录要将其移动最前面,按图示的上箭头就行了,否则可能会出现各种问题。
3. 保存配置,现在给这个空工程建一个c文件,复制以下内容:
要是一个个改,要改的地方不少,我们就来直接点吧。嗯,说明下,下面的配置的是调试版本Check。
清空C/C++和Link下面的Option文本框,按下面的填写。
C/C++选项的Option填写:
/nologo /Gz /MLd /W3 /WX /Z7 /Od /DWIN32=100 /D _X86_=1 /D WINVER=0x500 /D DBG=1 /Fo"MyDriver_Check/"/Fd"MyDriver_Check/" /FD /c
说明:
/nologo:表示不显示编译的版权信息
/Gz:默认函数调用采用标准调用方式,即__stdcall
/W3: 采用第三级的警告模式。
/WX: 将警告信息变成错误信息,最大程度地保证了代码的可靠性。代码运行在内核模式里,没有差错机制,出错就会蓝屏,这个选项很有必要。
/Z7:用C7模式产生调试信息。VC默认的Program Database for “Edit & Continue” 和link的/driver 选项冲突。
/Od:关闭调试模式。驱动程序不需要像Win32的应用程序那样用VC调试器调试,需要用内核调试器才能调试。
/D WIN32=100 /D _X86_=1 /D WINVER=0x500 /D DBG=1:定义一些宏,必需的。
/Fo"MyDriver_Check/":设置中间代码的生成路径。
/Fd"MyDriver_Check/":设置pdb文件的目录位置。pdb文件包含了大量的符号,对调试驱动程序的时候很有帮助。
/FD:生成文件依赖。
/c:只进行编译,而不连接。
LINK选项的Option填写:
NT式驱动:
ntoskrnl.libhal.lib usbd.lib /nologo /base:"0x10000" /stack:0x400000,0x1000/entry:"DriverEntry" /incremental:no/pdb:"MyDriver_Check/Driver1.pdb"/map:"MyDriver_Check/Driver1.map" /debug /machine:I386 /nodefaultlib/out:"MyDriver_Check/Driver1.sys" /subsystem:native /driver/SECTION:INIT,D /IGNORE:4078
说明:
ntoskrnl.lib hal.lib usbd.lib:qudong 驱动程序需要链接的库文件。根据需要增减。
/nologo:表示不显示链接的版权信息。
/base:"0x10000":加载驱动程序的基址。
/stack:0x400000,0x1000:设定使用的堆栈大小。
/entry:"DriverEntry":入口函数的地址,此函数必须是符号标准函数调用的。
/incremental:no:非递增式的链接。
/pdbtype:sept 选项可以使得调试信息各自保存在各自的PDB文件中,这样可以加快链接速度,不利的是调试信息分散,调试时需要多个PDB文件。[可选]
/pdb:"MyDriver_Check/Driver1.pdb":设置pdb文件的文件名。
/map:"MyDriver_Check/Driver1.map":设置map文件的文件名。[可选]
/debug:以Deubg方式链接。
/machine:I386:产生的代码是386兼容平台的。
/nodefaultlib:不使用默认库。
/out:"MyDriver_Check/Driver1.sys":输出的最终程序的名称。
/subsystem:native:子系统是内核系统。
/driver:编译驱动程序。
/SECTION:INIT,D:将INIT的段设置为可抛弃的。
/IGNORE:4078:忽略4078号警告错误。
WDN式驱动:
ntoskrnl.libhal.lib usbd.lib /nologo /base:"0x10000" /stack:0x400000,0x1000/entry:"DriverEntry" /subsystem:console /incremental:no /pdb:"MyDriver_Check/Driver1.pdb"/debug /machine:I386 /nodefaultlib /out:" MyDriver_Check/Driver1.sys"/subsystem:native /driver /SECTION:INIT,D /IGNORE:4078
4. 保存配置,测试。以NT式驱动为例。
现在给这个空工程建一个c文件,复制以下内容:
#include<ntddk.h> NTSTATUSDriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS status = STATUS_UNSUCCESSFUL; return status; }
如果是CPP文件,则拷贝下面这段:
#ifdef__cplusplus extern"C" { #endif #include<NTDDK.h> #ifdef__cplusplus }; #endif extern “C” NTSTATUSDriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS status = STATUS_UNSUCCESSFUL; return status; }
编译通过则配置成功!!!
编译通过后,在程序源代码目录的MyDriver_Check\子目录下会生成相关的驱动程序
每次新建工程都得重新配置,但可以配置好一个工程,以后写代码,拷贝这个工程,然后在上面做修改。
至此,配置完成。