使用VS2005开发64位驱动程序需要注意的一些问题
1、首先在Autoexec.bat里边设置好
Set WDKDIR=L:\DDK\Vista
64位驱动使用Vista WDK来开发。
Include: $(WDKDIR)\inc\ddk;$(WDKDIR)\inc\api
Lib : $(WDKDIR)\lib\wnet\amd64
2、64位驱动,编译时记得设置相应标志:
删除:WIN32,_X86_=1
添加:_AMD64_;_WIN64
更改:_WIN32_WINNT=0x0400 -> _WIN32_WINNT=_WIN32_WINNT_WINXP,只有XP以上才支持64位驱动.
3、编译64位程序,要打开Detect 64 bit Portability Issues,尽量提前
发现兼容性问题。
4、对于64位驱动来说,很多例程都必须通过wdmsec.lib才能连接,所以这个lib
必须添加到项目的lib列表中。
5、对于32位驱动来说,如果是以Free模式连接,会提示无法找到“__SEH_epilog”。
解决方法是从2K3 DKK或者Vista WDK里边拷贝sehupd.lib到2K的DDK LIB目录
并添加到项目的LIB列表中。
如果是User mode程序,则把<VS2005DIR>\VC\PlatformSDK\Lib\sehprolg.obj
添加到项目中。
6、打开"C/C++\Code Generation\Buffer Security Check"时,还会提示无法找到
”__SEH_prolog4“、“__Security_Cookie”等符号。
Kernel Mode,这个符号在如下文件里边:
BufferOverflowk.lib
User Mode,这个符号在如下文件里边:
BufferOverflowu.dll
L:\VSNET2005ENG\VC\crt\src\intel\dll_lib\sehsupp.obj
L:\VSNET2005ENG\VC\crt\src\intel\dll_lib\sehprolg4.obj
L:\VSNET2005ENG\VC\crt\src\intel\mt_lib\sehprolg4.obj
L:\VSNET2005ENG\VC\crt\src\intel\mt_lib\sehsupp.obj
L:\VSNET2005ENG\VC\crt\src\intel\xdll_lib\sehprolg4.obj
要么把这个选项关掉,要么就把上面的文件加入项目中。
7、出现警告syntax option: “debugmode:full(mininal)”时,说明Linker
出现了额外的选项,在“Linker\Command Line”里边把多余的选项删除掉。
8、64位驱动不能使用__asm{}内嵌汇编,汇编必须放在独立的ASM文件中编译。
如果需要使用汇编指令又不想使用ASM文件,则可以使用VS2005封装内联
的汇编指令。头文件intrin.h不在DDK\Inc下面,需要从VS2005\VC\Include
下面拷贝过来。
编译时,可能提示:
error C2733: second C linkage of overloaded function '_interlockedbittestandset' not allowed L:\DDK\Vista\inc\ddk\intrin.h 912
error C2733: second C linkage of overloaded function '_interlockedbittestandreset' not allowed L:\DDK\Vista\inc\ddk\intrin.h 913
error C2733: second C linkage of overloaded function '_interlockedbittestandset64' not allowed L:\DDK\Vista\inc\ddk\intrin.h 918
error C2733: second C linkage of overloaded function '_interlockedbittestandreset64' not allowed L:\DDK\Vista\inc\ddk\intrin.h 919
到intrin.h里边去,注释掉相关四行代码即可:
//__MACHINEI(unsigned char _interlockedbittestandset(long *a, long b))
//__MACHINEI(unsigned char _interlockedbittestandreset(long *a, long b))
//__MACHINEX64(unsigned char _interlockedbittestandset64(__int64 *a, __int64 b))
//__MACHINEX64(unsigned char _interlockedbittestandreset64(__int64 *a, __int64 b))
上面只是让编译通过,想连接通过,还必须设置编译选项C/C++\Optimiztation: Enable Intrinsic Funcions,勾上。
如果想使用独立的ASM文件,则右击.sln项目,选“Custom Build Rule”,然后使用
“Microsoft Macro Assembler”编译ASM即可。注:
(1)、VS2005默认情况下的“Microsoft Macro Assembler”只支持32位汇编,想要编
译64位,必须另外建立一个X64汇编环境,方法是把masm.rules复制一份成masm64.rules,
并更改命令成ml64.exe即可。
(2)、ASM中使用条件编译时,这个条件编译指使必须同时在这个对话框中设置,
ASM不使用默认的项目编译条件指示。
(3)、在32位和64位汇编之间进行切换时,先到Custom Build Rule对话框里边切换,
然后再在界面上换到WIN32或者X64,否则VS2005可能不能正常编译(要重启)。
9、为了方便在32位和64位驱动之间进行移植,要注意三个问题:
1、凡是可能涉及到指针转换的,一律使用xxx_PTR,如DWORD_PTR,ULONG_PTR等,
这个类型在64位下面自动扩展成64位。
2、32位程序传递结构到64位驱动时,需要注意结构对齐的问题。
64位下面,指针是8字节对齐的,有时会导致64位结构的大小增长,
而32位传递进去的结构可能偏小,导致内存读取出问题。
3、指针转换成ULONG等类型之后,高32位已经被截断,因此不要再转换成指针类型。
4、打印指针,应该使用“%p”,不应该使用“%08X”。
10、64位不能使用swprintf()例程,要使用_vsnwprintf()例程,如下:
int _cdecl swprintf_64(WCHAR* wBuf,int wBufCount,LPCWSTR formatstring, ...)
{
va_list argsList;
va_start(argsList, formatstring);
int ret = _vsnwprintf( wBuf, wBufCount, formatstring, argsList);
va_end(argsList);
return ret;
};