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

我在自己的博客园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代码   收藏代码
  1. #ifdef __cplusplus  
  2. extern "C"  
  3. {  
  4. #endif  
  5. #include <NTDDK.h>  
  6. #ifdef __cplusplus  
  7. }  
  8. #endif   
  9.   
  10. #define PAGEDCODE code_seg("PAGE")  
  11. #define LOCKEDCODE code_seg()  
  12. #define INITCODE code_seg("INIT")  
  13.   
  14.   
  15. #define arraysize(p) (sizeof(p)/sizeof((p)[0]))  
  16.   
  17. typedef struct _DEVICE_EXTENSION {  
  18.     PDEVICE_OBJECT pDevice;  
  19.     UNICODE_STRING ustrDeviceName;  //设备名称  
  20.     UNICODE_STRING ustrSymLinkName; //符号链接名  
  21. } DEVICE_EXTENSION, *PDEVICE_EXTENSION;  
  22.   
  23.   
  24. /************************************************************************ 
  25. * 函数名称:CreateDevice 
  26. * 功能描述:初始化设备对象 
  27. * 参数列表: 
  28.       pDriverObject:从I/O管理器中传进来的驱动对象 
  29. * 返回 值:返回初始化状态 
  30. *************************************************************************/  
  31. #pragma INITCODE  
  32. NTSTATUS CreateDevice (  
  33.         IN PDRIVER_OBJECT   pDriverObject)   
  34. {  
  35.     NTSTATUS status;  
  36.     PDEVICE_OBJECT pDevObj;  
  37.     PDEVICE_EXTENSION pDevExt;  
  38.       
  39.     //创建设备名称  
  40.     UNICODE_STRING devName;  
  41.     RtlInitUnicodeString(&devName,L"\\Device\\MyDDKDevice");  
  42.       
  43.     //创建设备  
  44.     status = IoCreateDevice( pDriverObject,  
  45.                         sizeof(DEVICE_EXTENSION),  
  46.                         &(UNICODE_STRING)devName,  
  47.                         FILE_DEVICE_UNKNOWN,  
  48.                         0, TRUE,  
  49.                         &pDevObj );  
  50.     if (!NT_SUCCESS(status))  
  51.         return status;  
  52.   
  53.     pDevObj->Flags |= DO_BUFFERED_IO;  
  54.     pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;  
  55.     pDevExt->pDevice = pDevObj;  
  56.     pDevExt->ustrDeviceName = devName;  
  57.     //创建符号链接  
  58.     UNICODE_STRING symLinkName;  
  59.     RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDK");  
  60.     pDevExt->ustrSymLinkName = symLinkName;  
  61.     status = IoCreateSymbolicLink( &symLinkName,&devName );  
  62.     if (!NT_SUCCESS(status))   
  63.     {  
  64.         IoDeleteDevice( pDevObj );  
  65.         return status;  
  66.     }  
  67.     return STATUS_SUCCESS;  
  68. }  
  69.   
  70. /************************************************************************ 
  71. * 函数名称:HelloDDKUnload 
  72. * 功能描述:负责驱动程序的卸载操作 
  73. * 参数列表: 
  74.       pDriverObject:驱动对象 
  75. * 返回 值:返回状态 
  76. *************************************************************************/  
  77. #pragma PAGEDCODE  
  78. VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject)   
  79. {  
  80.     PDEVICE_OBJECT  pNextObj;  
  81.     KdPrint(("Enter DriverUnload\n"));  
  82.     pNextObj = pDriverObject->DeviceObject;  
  83.     while (pNextObj != NULL)   
  84.     {  
  85.         PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)  
  86.             pNextObj->DeviceExtension;  
  87.   
  88.         //删除符号链接  
  89.         UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;  
  90.         IoDeleteSymbolicLink(&pLinkName);  
  91.         pNextObj = pNextObj->NextDevice;  
  92.         IoDeleteDevice( pDevExt->pDevice );  
  93.     }  
  94. }  
  95.   
  96. /************************************************************************ 
  97. * 函数名称:HelloDDKDispatchRoutine 
  98. * 功能描述:对读IRP进行处理 
  99. * 参数列表: 
  100.       pDevObj:功能设备对象 
  101.       pIrp:从IO请求包 
  102. * 返回 值:返回状态 
  103. *************************************************************************/  
  104. #pragma PAGEDCODE  
  105. NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,  
  106.                                  IN PIRP pIrp)   
  107. {  
  108.     KdPrint(("Enter HelloDDKDispatchRoutine\n"));  
  109.     NTSTATUS status = STATUS_SUCCESS;  
  110.     // 完成IRP  
  111.     pIrp->IoStatus.Status = status;  
  112.     pIrp->IoStatus.Information = 0;  IoCompleteRequest( pIrp, IO_NO_INCREMENT );  
  113.     KdPrint(("Leave HelloDDKDispatchRoutine\n"));  
  114.     return status;  
  115. }  
  116.   
  117. /************************************************************************ 
  118. * 函数名称:DriverEntry 
  119. * 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象 
  120. * 参数列表: 
  121.       pDriverObject:从I/O管理器中传进来的驱动对象 
  122.       pRegistryPath:驱动程序在注册表的中的路径 
  123. * 返回 值:返回初始化驱动状态 
  124. *************************************************************************/  
  125. #pragma INITCODE  
  126. extern "C" NTSTATUS DriverEntry (  
  127.             IN PDRIVER_OBJECT pDriverObject,  
  128.             IN PUNICODE_STRING pRegistryPath    )   
  129. {  
  130.     NTSTATUS status;  
  131.     KdPrint(("Enter DriverEntry\n"));  
  132.   
  133.     //注册其他驱动调用函数入口  
  134.     pDriverObject->DriverUnload = HelloDDKUnload;  
  135.     pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine;  
  136.     pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine;  
  137.     pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;  
  138.     pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine;  
  139.       
  140.     //创建驱动设备对象  
  141.     status = CreateDevice(pDriverObject);  
  142.   
  143.     KdPrint(("DriverEntry end\n"));  
  144.     return status;  
  145. }  

 

  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,可以去我的百度空间和博客园看一下。不过建议初学者先别学那个,怎么一个痛苦了得

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值