2015-05-20 08:59:49 cenzmin 阅读数 544

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

 

2009-04-17 12:55:00 blueesoft 阅读数 832

   出自众目IT科技网(http://www.zmit.net) kill -9 pid DDK驱动开发入门篇

   在开发软件的过程中,做做应用层的程序觉得很不够,一至都想学学底层的东西驱动的设计,想学是回事,还没进门就碰壁了, 驱动环境的配置也是学习的一个进门环节,就是想用驱动和学用的Visual c++2003开发环境联系起来,这样编写驱动就像写C++基于SDK的程序 一些方便了,但是那些书上讲得太不明不白了,小众早就知道可以用DriverStudio3.2来开发驱动了,现在就向大家说说DDK开发环境与Visual C++2003的搭建方法。具体的操作不过以下几个步骤的了,相信大家一看便知,不知道的还是可以来问小众的,只要大家记得回访众目IT就可以 了。不多说废话,正题来了。
第一步:安装DDK开发环境,名称为“982KXPDDK.iso”此安ISO包含了2k、XP的所有驱动开发环境。(注:在安装时,最好将所以的工具安装完 ,如例程源码,都安装,这对于初学者来说是一件好事)
第二步:下载DriverStudio3.2安装好后,在“开始”-“程序”-“Computer DriverStudio“-”Develop“-“DDK source to vcproj Converter” 在打开发的窗口中选择“File”-“Open”在第一步安装好的DDK开发环境中找到“scr“目录下的一个实例驱动工程,如 “serenum”下面有一个名称为“sources”的文件,选择它并且打开。
第三步:在打开的“DDK source to vcproj Converter”窗口中选择“Build”窗口下面的任意一种编程方式,进行编译一次。作者是选择 “Build-cef”。
第四步:在选择“Convert“菜单项的“ConvertVisualStudio 6 workspance/Project”选择要输出的类型,作者的开发环境是2003就选择第二 种生成方式。单击“Convert”.
第五步:回到serenum目录下这时生成了一个名称为“SerEnum.sln“的文件,此文件就是VC2003打开的源文件,我们双击打开,就可以将2003 启动。
第六步:2003启动后试着编译一次,当然是编译不成功的,因为还在配置2003的开发环境,步骤马上详细道来。
1:打开“工具“-“选项”-“DriverStudio”-“DDK Build Settings”-“DDK Root Directory(BASEDIR)项的三点按钮,选择 “D:/WINDDK/2600”DDK根目录根据你安装的DDK目录进行选择,这是作者的DDK安装路径根。
2:选择“Search Paths”选择包含源搜索路径和全局搜索路径“D:/WINDDK/2600/LIB/wxp/i386”
第七步:大功告成了,这时你就可以顺意写你的驱动程序了。

2016-06-18 14:44:24 opshres169 阅读数 327
  
2011-11-18 11:44:00|  分类: windows驱动开发|字号 订阅
本文参照原文:
http://www.cppblog.com/guojingjia2006/archive/2011/03/19/142211.html
 
1.  安装VS2010,WDK7.60(GRMWDK_EN_7600_1)
      WDK下拉地址:http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=11800
2.  新建VC 控制台项目(选择为空项目)
 
3.  新建项目配置“driver” ,点击下拉按钮-点击(配置管理器)
    右键点击项目 --  属性  -- 配置管理器
 
 
输入名称(driver)点击确定就可以了,其他的不要动哦!
完成后的效果:
 
 
点击确定按钮之后呈现出来的画面
 
 
 
鼠标右击新建的driver属性,会弹出以下窗口!
  
 
4.  设置VC++路径   [注意:这些路径要放在原有路径的后面,否则会报错]
<我把wdk安装在D盘下> 
a.  配置可执行文件目录:   ;D:\WinDDK\7600.16385.1\bin\x86;
b.  配置包含目录:    ;C:\WinDDK\7600.16385.1\inc\ddk ;D:\WinDDK\7600.16385.1\inc\;D:\WinDDK\7600.16385.1\inc\api; 
c.  配置库目录:        ;D:\WinDDK\7600.16385.1\lib\win7\i386;
 (win7的填win7..XP的填wxp)
新建C/C++文件不然无C/C++设置选项
<刚开始我们创建了一个空的项目所以项目里没有c++文件,现在要做的就是在空的项目-源文件-添加一个新建项c++文件>
常规  
目标文件扩展名:.sys          //必选
  
6.  设置C/C++选项 
常规选项卡 
1 调试信息格式(C7 兼容(/Z7)        //可选 
2 警告等级     (2 级(/W2)          //可选 
3 将警告视为错误  (是(/wx)         //可选 
    
优化选项卡 
优化(禁用/Od)                          //可选 
  
预处理器 
预处理器定义:WIN32=100;_X86_=1;WINVER=0x501;DBG=1         //必选 
  
代码生成 
       启用最小重新生成:否                                        //可选   
       基本运行时检查:默认值                                     //可选 
       运行时库:多线程调试(/MTd)  或  多线程(/MT)                 //建议选<本人选择的是多线程调试(/MTd)> 
       缓冲区安全检查:否                                            //可选 
  (可避免出现  LINK : error LNK2001:  无法解析外部符号  __security_cookie)
  
高级 
     调用约定  __stdcall(/Gz)                                       //必选  
 
7.  链接器设置 
常规 
     启用增量链接:否(/INCREMENTAL:NO)                           //建议选上 
     忽略导入库:是                                                  // 可选  
     ( 设置为此值时,必须在附加库目录中加: E:\WinDDK\7600.16385.1\lib\win7\i386  这样项目就不会依赖 IDE 环境的设置)
     如果否  (  设置为此值时,将依赖  IDE  的环境的相关设置  ) 
  
输入 
附加依赖项  后面( %(AdditionalDependencies) 前面 )加入: 
               ;ntoskrnl.lib;Hal.lib;wdm.lib;wdmsec.lib;wmilib.lib;ndis.lib;MSVCRT.LIB;LIBCMT.LIB;        //必选  
【这一步在第一次操作时成功,再次操作时,报连接不上ntoskrnl.lib,去掉了,测试代码还是能生成的。】
            //NT式驱动  ntoskrnl.lib    WDM式驱动    wdm.lib 
( HalXXX函数在Hal.lib,WmiXXX函数在  wmilib.lib  ,NdisXXX函数在  ndis.lib ) 
(  必要时需要增加微软的标准库  MSVCRT.LIB MSVCRTD.LIB(调试库) LIBCMT.LIBIBCMTD.LIB(调试库) ) 
  (  如果源码中有  source  文件,那么该文件的  TARGETLIBS  字段会列出该项目需要的库  )
忽略所有默认库:    是 (/NODEFAULTLIB)                 //必选 
清单文件:
   生成清单                               否    //原文未提到,不选可能报错 
  启用用户账户控制(UAC)   否  //必选  
 
不然会出现  >LINK : fatal error LNK1295: “/MANIFESTUAC”与“/DRIVER”规范不兼容;链接时不使用“/MANIFESTUAC”   
  
    调试: 
生成调试信息  是(/DEBUG)                                              //可选 
生成映像文件:是(/MAP)                                               //可选 
映像文件名:$(TargetDir)$(TargetName).map                     //可选 
  
    系统(System) 
     子系统:  控制台(/SUBSYSTEM:CONSOLE)                                //必选 
     堆栈保留大小:4194304                                              //可选 
     堆栈提交大小:  4096                                                //可选 
     驱动程序:    驱动程序(/DRIVER)                                        //必选  
 
      高级: 
    入口点:DriverEntry                                                    //必选 
    随机基址:清空           //把框里的数据删掉。(yes也不是no也不是就是要一个干干净净的文本框)   //必选 
    不然会出现  e:\xxx.sys : fatal error LNK1295: 
“/DYNAMICBASE”与“/DRIVER”规范不兼容;链接时不使用“/DYNAMICBASE”

    数据执行保护(DEP):  清空 //把框里的数据删掉。(yes也不是no也不是就是要一个干干净净的文本框) //必选   
     不然会出现  e:\xxx.sys : fatal error LNK1295:        
“/NXCOMPAT:NO”与“/DRIVER”规范不兼容;链接时不使用“/NXCOMPAT:NO”  
 
设置校验和:是(/RELEASE)                              //可选
基址:0x10000                                           //建议选上  
    
命令行:/SECTION:INIT,D /IGNORE:4078        (建议不要写进去,会报错!)       
 
           
最后给出一个超级简单的代码来测试一下我们配置的是否成功??
#include "ntddk.h"
NTSTATUS 
DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRINGRegistryPath) 

return STATUS_UNSUCCESSFUL; 
}
 
如果没有报错那么恭喜你配置成功了!
在项目文件的上一级目录下,driver 文件夹下,生成 .sys 文件
2012-04-23 17:51:05 kfysck 阅读数 8120

对于我来说,最害怕的就是新接触一个IDE要去重新配置他的这个配置他的那个,搞得我有种想死的冲动,比如配置android模拟器,java环境变量等等,今天又遇到了另外一个难题,就是配置ddk的环境。我的开发环境是win7+VS2008+WDK 7600.16385.1。经过了多少次的查资料失败之后,终于配置成功了,特记录下来以备后用。

 

1.      在干净的系统上装vs2008

2.      wdk 7600.16385.1

3.      开始重点了。随便打开一个程序,让debug release等的解决方案配置管理器激活,然后新建一个活动解决方案配置,从此处复制设置为空

选择”工具“|”选项“菜单选择”项目和解决方案“选项卡:

  选择“VC++目录,选择”包含文件,添加C:\WinDDK\7600.16385.0\inc\ddk“和"C:\WinDDK\7600.16385.0\inc\api"

  选择”库文件,添加C:\WinDDK\7600.16385.0\lib\wxp\i386

接下来就是工程配置属性项

4、选择”项目“|”属性“弹出”属性页“对话框  选择”配置属性“选项卡   选择“C/C++”选项卡

     4.1、再选择”常规“选项卡

           1、”调试信息格式“  选择 C7兼容(/Z7)用Z7模式产生调试信息

           2、取消显示启动版权标志  选择    (/nologo)(默认)

           3、警告等级选择    3(/W3)

           4、将警告视为错误   选择是(/WX)

    4.2、选择”优化“选项

           1、优化选择  禁用(/Od)

             其他默认即可

    4.3    选择”预处理器“选项卡

           1、预处理定义  编辑   WIN32=100;_X86_=1;DBG=1  

              其他默认即可

    4.4    选择”高级“选项卡

        1、调用约定选择 __stdcall (/Gz)(驱动函数调用采用标准调用)

5、好了,轮到”连接器“选项卡了

          5.1 选择”常规“选项卡

                1、输出文件   编辑     MyDriver_Check/HelloDDK.sys

                2、启用增量链接选择    (/INCREMENTAL:NO)

                3、附加库目录编辑C:\WinDDK\7600.16385.0\lib\win7\i386   (因为等下要用到ntosknl.lib   如果是WDM驱动程序,则需要链接wdm.lib

                  其他选项默认

          5.2 选择“输入"选项卡

                 1、附加依赖项   编辑弹出”附加依赖项    “编辑框  编辑   ntoskrnl.lib   复选框”从父级或项目默认设置继承“的勾去掉   (免得调用用户层 lib 文件)

                 2、忽略所有默认库选择   (/NODEFAULTLIB)

                    其他选项默认

          5.3 选择”调试“选项卡

                   1、生成调试信息选择  (/DEBUG)

                   2、生成程序数据库文件  编辑MyDriver_Check/HelloDDK.pdb

          5.4  选择”系统“选项卡

                   1、子系统   选择   本机(/SUBSYSTEM:NATIVE)

                   2、堆栈保留大小编辑 40000

                   3、堆栈提交大小编辑 1000

                   4、驱动程序       选择    驱动程序(/DRIVER)

          5.5  选择”高级“选项卡

                  1、入口点  编辑    DriverEntry    (驱动的入口函数地址)

                  2、基址   编辑    0x10000

                  3、目标计算机    MachineX86 (/MACHINE:X86)    (一般是这个)

 

 

到这里之后还是不可以,他会说什么_In_  _Out_什么的找不到,我在这里看到了他好像是没有找到头文件crtdefs.h 在包含里面添加上这个  D:\WinDDK\7600.16385.1\inc\crt 

 

然后那么多错误就没有了,下面是link错误

启用用户账户控制(UAC)否 //必选不然会出现 >LINK : fatal error LNK1295:/MANIFESTUAC”与“/DRIVER”规范不兼容;链接时不使用“/MANIFESTUAC

随机基址:默认值    //必选不然会出现1>G:\event2008\check\event2008.exe : fatal error LNK1295:/DYNAMICBASE”与“/DRIVER”规范不兼容;链接时不使用“/DYNAMICBASE

数据执行保护(DEP): 默认值 //必选不然会出现 G:\event2008\check\event2008.sys : fatal error LNK1295:/NXCOMPAT:NO”与“/DRIVER”规范不兼容;链接时不使用“/NXCOMPAT:NO

 

    添加开关:/SECTION:INIT,D/IGNORE:4078 //建议填上

 

     可以避免以下错误提示

     LINK : warning LNK4078:找到多个“INIT”节,它们具有不同的属性(E2000020)

     LINK : error LNK2001: 无法解析的外部符号__load_config_used

 

 

 

天啊终于解决了。

2011-04-02 10:41:00 daiafei 阅读数 777

1.首先下载ddk开发包

Windows DDK 3790.1830 下载

安装DDK后,去http://ddkwizard.assarbad.net/ 下载ddkwizard_setup_v1.2.0a、ddkbuild_bat.zip、ddkbuild_cmd.zip。

2.拷贝 DDKBUILD.bat 和 DDKBUILD.cmd 到DDK安装根目录,如我的是D:/WinDDK.

3.. 将上述文件(DDKBUILD.bat 和 DDKBUILD.cmd )的路径添加到系统的path变量(右击我的电脑,系统属性/高级/环境变量/系统变量/path变量双击修改值)。

4. 根据你所安装的DDK的不同版本添加不同的变量到系统变量中。
  右击我的电脑,系统属性/高级/环境变量/系统变量/新建:
  2000 DDK则变量名为: W2KBASE
  XP DDK则变量名为: WXPBASE
  2003 sp1 DDK则变量名为: WNETBASE
  这里我的是WNETBASE(值为D:/WinDDK/3790.1830)

5.启动vs2008 打开菜单中的工具——选项,弹出选项对话框。选择左边的项目和解决方案——VC++目录,在右边的显示以下内容的目录下拉列表中选择可执行文件,在下面列表框中添加上面DDKBuild.bat文件所在的路径(这里是D:/WinDDK),同样设置包含文件和库文件 如下图:




设置可执行文件




设置包含文件(D:/WINDDK/3790.1830/inc/wnet D:/WINDDK/3790.1830/inc/ddk/wnet )




设置库文件(D:/WINDDK/3790.1830/lib/wnet/i386)



6. 开始安装DDKWizard,在安装的最后一步你可以选择编辑ddkwizard的配置文件。

7. 现在重新打开VC2008就会发现在新建项目里面有DDK Project的选项了,里面就可以建立驱动工程来编写驱动程序了。


8. 验证你做的工作,你可以直接新建一个Driver工程按F7编译,编译看看。

建立EmptyDriver时,

要在sources文件的第4行TARGETTYPE=后面加DRIVER

加入[源文件]后还要在sources文件里的SOURCES=后面加上[源文件名]。比如:
SOURCES=DriverDemo.cpp /
  DriverDemo.h

VS2008集成DDKWizard遇到的问题>>>>>>>>>>>>>>>>>>>>>
————————————————————————————
▲建立EmptyDriver时,

要在sources文件的第4行TARGETTYPE=后面加DRIVER

加入[源文件]后还要在sources文件里的SOURCES=后面加上[源文件名]。比如:
SOURCES=DriverDemo.cpp /
  DriverDemo.h

▲Cannot open include file: /'NTDDK.h/': No such file or directory
解决方案:VS2005/工具/选项/VC++目录/,
[显示以下内容的目录]为[包含文件],把DDK包含文件加进目录——
[D:/WINDDK/3790.1830/inc/ddk/wnet]和[D:/WINDDK/3790.1830/inc/wnet]。

[显示以下内容的目录]为[库文件],把DDK库文件加进目录——
[D:/WINDDK/3790.1830/LIB/WNET/I386]

以上DDK的路径要放到最先。

参考自:http://blog.csdn.net/jamesandy/archive/2008/03/17/2192267.aspx

结果:
▲编译提示错误:
BufferOverflowK.lib(gs_support.obj) : error LNK2019: unresolved external symbol _DriverEntry@8 referenced in function _GsDriverEntry@8
objchk_w2K_x86/i386/Helloworld.sys : fatal error LNK1120: 1 unresolved externals
解决方案:
把[入口函数DriverEntry]前加上extern "C":
extern "C"{
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{ /*DriverEntry函数内容*/ }
}//extern "C"
结果:OK。编译通过,才。我靠!终于啊!
另:据说改成.c文件也可。理论上是这样,但测试失败。

测试代码如下

// sources文件

# $Id$
TARGETNAME=HelloWorld
TARGETPATH=obj
TARGETTYPE=DRIVER

# Create browse info
#BROWSER_INFO=1
#BROWSERFILE=<some path>

# Additional defines for the C/C++ preprocessor
C_DEFINES=$(C_DEFINES)

SOURCES=HelloWorld.c

//makefile文件

#
# DO NOT EDIT THIS FILE!!! Edit ./sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the components of the Windows NT DDK
#

!INCLUDE $(NTMAKEENV)/makefile.def

//HelloWorld.h文件

#ifndef __HELLOWORLD_H__
#define __HELLOWORLD_H__
#include <ntddk.h>
#define DEVICE_HELLO_INDEX 0x860
#define START_HELLOWORLD CTL_CODE( FILE_DEVICE_UNKNOWN,DEVICE_HELLO_INDEX,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define STOP_HELLOWORLD CTL_CODE(FILE_DEVICE_UNKNOWN,DEVICE_HELLO_INDEX+1,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define NT_DEVICE_NAME L"//Device//HelloWorld"
#define DOS_DEVICE_NAME L"//DosDevices//HelloWorld"
NTSTATUS HelloWorldDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp);
VOID HelloWorldUnload(IN PDRIVER_OBJECT DriverObject);
#endif

// HelloWorld.c文件
#ifndef __HELLOWORLD_C__
#define __HELLOWORLD_C__
#define DEBUGMSG
#include "HelloWorld.h"

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
  NTSTATUS ntStatus=STATUS_SUCCESS;
  PDEVICE_OBJECT IpDeviceObject=NULL;
  UNICODE_STRING DeviceNameString;
  UNICODE_STRING DeviceLinkString;

  #ifdef DEBUGMSG
  DbgPrint("hi, Starting DriverEntry()/n");
  #endif
   
  RtlInitUnicodeString(&DeviceNameString,NT_DEVICE_NAME);
  ntStatus=IoCreateDevice(DriverObject,0,&DeviceNameString,FILE_DEVICE_UNKNOWN,0,FALSE,&IpDeviceObject);
  if(!NT_SUCCESS(ntStatus))
  {
  #ifdef DEBUGMSG
  DbgPrint("hi, Error IoCreateDevice()/n");
  #endif
  goto Error;
  }
  RtlInitUnicodeString(&DeviceLinkString,DOS_DEVICE_NAME);
  ntStatus=IoCreateSymbolicLink(&DeviceLinkString,&DeviceNameString);
  if(!NT_SUCCESS(ntStatus))
  {
  #ifdef DEBUGMSG
  DbgPrint("hi, Error IoCreateSymbolicLink()/n");
  #endif
  goto Error;
  }
  DriverObject->MajorFunction[IRP_MJ_CREATE]=HelloWorldDispatch;
  DriverObject->MajorFunction[IRP_MJ_CLOSE]=HelloWorldDispatch;
  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=HelloWorldDispatch;
  DriverObject->DriverUnload=HelloWorldUnload;
  return ntStatus;
Error:
  #ifdef DEBUGMSG
  DbgPrint("hi, Error DriverEntry()/n");
  #endif
  return ntStatus;
}
NTSTATUS HelloWorldDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp)
{
  NTSTATUS ntStatus=STATUS_SUCCESS;
  ULONG IoControlCodes=0;
  PIO_STACK_LOCATION IrpStack=NULL;
  pIrp->IoStatus.Status=STATUS_SUCCESS;
  pIrp->IoStatus.Information=0;
  #ifdef DEBUGMSG
  DbgPrint("hi, Starting HelloWorldDispatch()/n");
  #endif
  IrpStack=IoGetCurrentIrpStackLocation(pIrp);
  switch(IrpStack->MajorFunction)
  {
  case IRP_MJ_CREATE:
  #ifdef DEBUGMSG
  DbgPrint("hi, IRP_MJ_CREATE/n");
  #endif
  break;
  case IRP_MJ_CLOSE:
  #ifdef DEBUGMSG
  DbgPrint("hi, IRP_MJ_CLOSE/n");
  #endif
  break;
  case IRP_MJ_DEVICE_CONTROL:
  #ifdef DEBUGMSG
  DbgPrint("hi, IRP_MJ_DEVICE_CONTROL/n");
  #endif
  IoControlCodes=IrpStack->Parameters.DeviceIoControl.IoControlCode;
  switch(IoControlCodes)
  {
  case START_HELLOWORLD:
  DbgPrint("hi, Starting /"Hello World /"/n");
  break;
  case STOP_HELLOWORLD:
  DbgPrint("hi, Stoping /"Hello World /"/n");
  break;
  default:
  pIrp->IoStatus.Status=STATUS_INVALID_PARAMETER;
  break;
  }
  break;
  default:
  break;
  }
  ntStatus=pIrp->IoStatus.Status;
  IoCompleteRequest(pIrp,IO_NO_INCREMENT);
  return ntStatus;
}

VOID HelloWorldUnload(IN PDRIVER_OBJECT DriverObject)
{
  UNICODE_STRING DeviceLinkString;
  PDEVICE_OBJECT DeviceObjectTemp1=NULL;
  PDEVICE_OBJECT DeviceObjectTemp2=NULL;
  #ifdef DEBUGMSG
  DbgPrint("hi,Starting HelloWorldUnload()/n");
  #endif
  RtlInitUnicodeString(&DeviceLinkString,DOS_DEVICE_NAME);
  IoDeleteSymbolicLink(&DeviceLinkString);
  if(DriverObject)
  {
  DeviceObjectTemp1=DriverObject->DeviceObject;
  while(DeviceObjectTemp1)
  {
  DeviceObjectTemp2=DeviceObjectTemp1;
  DeviceObjectTemp1=DeviceObjectTemp1->NextDevice;
  IoDeleteDevice(DeviceObjectTemp2);
  }
  }
}
#endif

手动编译命令如下:


打开:开始/程序/……/Windows Server 2003 Checked x86 Build Environment
输入如下:
D:/WINDDK/3790~1.183>cd ..//uu
D:/WINDDK/uu>build

没有更多推荐了,返回首页