您的位置:首页 > 其它

详细讲解vc 6.0进行DDK驱动开发

2015-05-20 08:59 393 查看


详细讲解vc 6.0进行DDK驱动开发

VC++XP百度C++C

我在自己的博客园http://www.cnblogs.com/DotCpp/archive/2010/01/27/DotCpp.html和百度空间http://hi.baidu.com/anglecloudy/blog/item/9b8d841636c6b84321a4e901.html中已经讲的差不多了。只是内容有点乱,现在在这里面好好整理一下。为初学者提供学习方法及自己做个备份。【注:转载请注明出处,打这么多字不容易,呵呵:)】

一、开篇--工具下载与安装

1>> 我使用的是工具VC + XPDDK +DriverStudio 3.1(DriverStudio是为了用里面的几个测试工具,如DriverMonitor,而且还可以学一下WDM开发) 。很多人现在用的是DriverStudio 3.2,我开始也用的是3.2,只是有段时间学习武安河的那本《Windows 2000 XP WDM 开发》时他用的是3.1,与3.2界面差别有点大,而且当时对驱动不太了解,为了学习方便只能换3.1,找了很久的下载地址:http://blog.csdn.net/mobidogs/archive/2007/01/23/1491503.aspx

现在想想有些不值,武安河的那本书没能坚持下来。那本书一点都不适合初学者看。后来看的《Windows驱动开发技术详解》收获很大,学到了很多东西。建议初学者先那本书,再看其它书籍。

相关软件可以从网站http://www.moodisk.com/download_other_c.php下载,如:

(1)·DriverStudio_3.2_CR.rar(解压DriverStudio_3.2_CR.rar,进入解压后的目录DriverStudio_3.2_CR,再把其中 driverstudio.3.2.crack.rar解压,产生目录driverstudio.3.2.crack,里面有两个文件SN.txt和 compuware.dat,前者包含序列号,后者是证书文件,这两个文件在安装过程中会用到。)

(2)·Visual.C++.6.EN.zip;

(3)·winxp_ddk.rar;

(4)·ntstrsafe.lib+csq.lib.rar;

2>>安装,没啥好说的。安装顺序:--> VC6.0-->VC SP6补丁 --> WinXP_DDK (安装DDK时把Build Envirement里面的win 2000选中(默认的是没选中,要注意),不然以后编译DDK例子时,ntddk.h里面会出现很多错误,而且基本都是有些类型找不到定义,这时你把2000
DDK的头文件加在Directory的Include里面就行了,曾经我被搞的痛不欲生)-> DriverStudio3.x(1,2都行)

3>>配置:在Tool-> Options设置Include和Lib目录,注意是2000 DDK的(如果等下编译有什么问题,把XP DDK的一些头文件和LIB文件也加进来,基本就没问题了)。

我的设置是Include目录:

C:\WINDDK\2600\INC\W2K

C:\WINDDK\2600\INC\DDK\W2K

C:\WINDDK\2600\INC\DDK\WDM\W2K

Lib目录:

C:\WINDDK\2600\LIB\W2K\I386

二、测试代码

1>>自己写的HelloDDK,其实和《Windows驱动开发技术详解》差不多。呵呵,大鸟不要见怪,我说的重点是第二点。

Cpp代码


#ifdef __cplusplus

extern "C"

{

#endif

#include <NTDDK.h>

#ifdef __cplusplus

}

#endif

#define PAGEDCODE code_seg("PAGE")

#define LOCKEDCODE code_seg()

#define INITCODE code_seg("INIT")

#define arraysize(p) (sizeof(p)/sizeof((p)[0]))

typedef struct _DEVICE_EXTENSION {

PDEVICE_OBJECT pDevice;

UNICODE_STRING ustrDeviceName; //设备名称

UNICODE_STRING ustrSymLinkName; //符号链接名

} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

/************************************************************************

* 函数名称:CreateDevice

* 功能描述:初始化设备对象

* 参数列表:

pDriverObject:从I/O管理器中传进来的驱动对象

* 返回 值:返回初始化状态

*************************************************************************/

#pragma INITCODE

NTSTATUS CreateDevice (

IN PDRIVER_OBJECT pDriverObject)

{

NTSTATUS status;

PDEVICE_OBJECT pDevObj;

PDEVICE_EXTENSION pDevExt;

//创建设备名称

UNICODE_STRING devName;

RtlInitUnicodeString(&devName,L"\\Device\\MyDDKDevice");

//创建设备

status = IoCreateDevice( pDriverObject,

sizeof(DEVICE_EXTENSION),

&(UNICODE_STRING)devName,

FILE_DEVICE_UNKNOWN,

0, TRUE,

&pDevObj );

if (!NT_SUCCESS(status))

return status;

pDevObj->Flags |= DO_BUFFERED_IO;

pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;

pDevExt->pDevice = pDevObj;

pDevExt->ustrDeviceName = devName;

//创建符号链接

UNICODE_STRING symLinkName;

RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDK");

pDevExt->ustrSymLinkName = symLinkName;

status = IoCreateSymbolicLink( &symLinkName,&devName );

if (!NT_SUCCESS(status))

{

IoDeleteDevice( pDevObj );

return status;

}

return STATUS_SUCCESS;

}

/************************************************************************

* 函数名称:HelloDDKUnload

* 功能描述:负责驱动程序的卸载操作

* 参数列表:

pDriverObject:驱动对象

* 返回 值:返回状态

*************************************************************************/

#pragma PAGEDCODE

VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject)

{

PDEVICE_OBJECT pNextObj;

KdPrint(("Enter DriverUnload\n"));

pNextObj = pDriverObject->DeviceObject;

while (pNextObj != NULL)

{

PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)

pNextObj->DeviceExtension;

//删除符号链接

UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;

IoDeleteSymbolicLink(&pLinkName);

pNextObj = pNextObj->NextDevice;

IoDeleteDevice( pDevExt->pDevice );

}

}

/************************************************************************

* 函数名称:HelloDDKDispatchRoutine

* 功能描述:对读IRP进行处理

* 参数列表:

pDevObj:功能设备对象

pIrp:从IO请求包

* 返回 值:返回状态

*************************************************************************/

#pragma PAGEDCODE

NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,

IN PIRP pIrp)

{

KdPrint(("Enter HelloDDKDispatchRoutine\n"));

NTSTATUS status = STATUS_SUCCESS;

// 完成IRP

pIrp->IoStatus.Status = status;

pIrp->IoStatus.Information = 0; IoCompleteRequest( pIrp, IO_NO_INCREMENT );

KdPrint(("Leave HelloDDKDispatchRoutine\n"));

return status;

}

/************************************************************************

* 函数名称:DriverEntry

* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象

* 参数列表:

pDriverObject:从I/O管理器中传进来的驱动对象

pRegistryPath:驱动程序在注册表的中的路径

* 返回 值:返回初始化驱动状态

*************************************************************************/

#pragma INITCODE

extern "C" NTSTATUS DriverEntry (

IN PDRIVER_OBJECT pDriverObject,

IN PUNICODE_STRING pRegistryPath )

{

NTSTATUS status;

KdPrint(("Enter DriverEntry\n"));

//注册其他驱动调用函数入口

pDriverObject->DriverUnload = HelloDDKUnload;

pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine;

pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine;

pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;

pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine;

//创建驱动设备对象

status = CreateDevice(pDriverObject);

KdPrint(("DriverEntry end\n"));

return status;

}

2>>设置编译环境

*开始C/C++选项卡里的设置。

1)Preprocessor definitions中设置为:WIN32=100,_X86_=1,WINVER=0x500,DBG=1

WIN32=100:不是很清楚。

_X86_=1:这个最重要,否则无法编译通过。代表CPU类型为X86

WINVER=0x500,是因为你是for 2K的。XP的是0x501。

DGB=1表示调试版本。

2)C++ Language里面去掉Enable exeception handling,否则会出现error LNK2001: unresolved external symbol ___CxxFrameHandler。

3)Code Generation调用习俗设置成__stdcall。

4)Project Options中去掉/GZ【注意是大写的GZ,目的是编译的时候不会自动加入__chkesp。

5)Precompiled Headers里面选Not using Precompiled headers,毕竟驱动程序都不会太大,不在乎节省那点时间。

*设置Link选项卡

1)输出改成*.sys

2)lib添加ntoskrnl.lib

3)勾上Ignore all default libraries,否则会链接libc,报告没有main函数。

4)Base address:0x10000

Entry-point sysmbol:DriverEntry

Statck Reverse:0x400000,缺省是1MB,但为什么要设成4MB?

Commit:0x1000

5)Customize去掉Link incrementally,否则会和/RELEASE冲突。

6)link的 Project Options:加入/subsystem:native /driver /SECTION:INIT,D /RELEASE /IGNORE:4078

/subsystem:native:PE格式文件其中有个地方要填写这个。

/driver是对驱动做一些优化。

/SECTION:INIT,D:对INIT section进行discard

/RELEASE (Set the Checksum)

/IGNORE:4078 忽略4078错误,否则会出现LINK : warning LNK4078: multiple "INIT" sections found with different attributes (E2000020)

3>> 配置好后,生成相关的sys文件即可,用DriverMonitor加载一下就可以看到效果了。祝大家成功

附:本文没有讲WDM,如果学习WDM,可以去我的百度空间和博客园看一下。不过建议初学者先别学那个,怎么一个痛苦了得
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: