wdf简介2--helloworld驱动开发


***【在线视频教程】***

好文章,来自【福优学苑@音视频+流媒体】

https://blog.csdn.net/hustd10/article/details/50532088?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param  


https://blog.csdn.net/weixin_34238633/article/details/92150946?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.channel_param


https://blog.csdn.net/chenchong_219/article/details/21655481?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-6.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-6.channel_param



1 简述

从今天开始,我们开始学习Windows下的驱动开发。与时俱进,我们采用的是WDF(Windows Driver Foundation)驱动框架。一方面,该框架对于简化了驱动,提供了PNP和电源管理的默认实现,使得我们暂时不必关注一些复杂的东西,简化了学习难度。另一方面,我们本着由浅入深的原则,一开始对于驱动框架中的东西不必要所有的都弄懂,先有一个概念,随着学习的深入,自己动手实践,有些东西慢慢地就理解了。


2 为什么选择Hello World

老实说,对于选择什么程序作为第一个学习的驱动程序,一直纠结于是否要用Hello World。最后还是决定使用它,一方面,这绝对是最简单的,简单到大家都不愿意看,也给刚刚起步的人一个驱动的直观印象。另一方面,也是最重要的,那就是第一个程序的重要性不在于这个程序本身。更重要的作用是帮助我们磨刀,我们要让这个简单的KMDF程序从编写到编译成功,并成功的安装运行。熟悉整个过程,熟悉工具的使用,毕竟,实践才是学习的最好方法。


Hello Word驱动源代码编写

这个驱动的功能就是在设备被安装的时候打印出“Hello World!”字符串,在驱动被卸载的时候打印出“Thanks For Using!”字符串。顺便说一下,对于代码,我并不会一句一句地讲那么详细,因为网上并不缺乏驱动教程。你在看本教程之前,应该先去看看相关的教程和书籍,本教程的使用的例子基本上都来自于相关书籍和教程。那么,我写下这个教程有什么意义?一方面,学习是需要整理的,经常需要理一理自己学过的东西,有助于自己进步,所以我把它整理出来便于自己学习进步。另一方面,网上的教程和书籍一下子灌输了太多的东西,看着看着就迷失了。在内核下写程序,很重要的功力就是对于内核的了解,但一开始我们知道的甚少,一下子灌输内核的许多东西会造成很难学习,迷失不知怎么进行下一步。而且,这些书籍中的实例对于初学者过于复杂,没有循序渐进的过程,难免打击学习信心。所以我在教程中尽量简化,一步一步深入,慢慢地体会驱动开发。这也是我自己的学习过程。


回到我们的Hello World驱动,再编写它之前,你应该对于设备堆栈和设备安装和移除的过程有一些了解,你可以看看《Windows 7设备驱动程序开发》第7章“即插即用和电源管理”的部分内容。在设备插入时,框架会调用EvtDriverDeviceAdd回调函数,在该函数中创建设备对象。驱动卸载时,框架调用EvtDriverUnload回调函数,所以,我们只需要自己实现这两个回调函数,然后向框架注册即可。


下面是完整的代码:


#include <ntddk.h>

#include <wdf.h>


// 添加设备回调函数

NTSTATUS EvtDriverDeviceAdd( IN WDFDRIVER Driver,

                            IN PWDFDEVICE_INIT DeviceInit);

// 驱动卸载回调函数

VOID EvtDriverUnload( IN WDFDRIVER Driver );



NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject,

                     IN PUNICODE_STRING RegistryPath )

{

    NTSTATUS status;

    WDF_DRIVER_CONFIG config;


    // 注册EvtDriverDeviceAdd回调函数

    WDF_DRIVER_CONFIG_INIT(&config, EvtDriverDeviceAdd);


    // 注册EvtDriverUnload回调函数

    config.EvtDriverUnload = EvtDriverUnload;


    // 创建驱动对象

    status = WdfDriverCreate( DriverObject, RegistryPath, 

        WDF_NO_OBJECT_ATTRIBUTES, &config, WDF_NO_HANDLE);


    return status;

}


NTSTATUS EvtDriverDeviceAdd(IN WDFDRIVER Driver, 

                            IN PWDFDEVICE_INIT DeviceInit)

{

    NTSTATUS status;

    WDFDEVICE hDevice;


    PAGED_CODE();


    // 创建设备对象

    status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &hDevice);

    if( !NT_SUCCESS(status) )

    {

        KdPrint(("EvtDriverDeviceAdd failed.\n"));


        return status;

    }


    KdPrint(("Hello World!\n"));


    return status;

}


VOID EvtDriverUnload( IN WDFDRIVER Driver )

{

    KdPrint(("Thanks For Using!\n"));

}


5 编译Hello World驱动

在编译驱动之前,除了源代码(.h和.c),还要一些用于编译的其它文件。这部分内容需要先涉及一些驱动安装相关的知识,了解驱动安装运行需要哪些文件,我们才好准备这些内容。这部分内容最完整的资料是WDK文档和MSDN文档,下面将一些重要内容做简单介绍,但是更详细的内容,读者还是要自己看文档。


MSDN给出了驱动开发和安装的七个步骤,如下:


了解Windows设备和驱动安装的基础知识。

了解驱动包及其组成。

了解INF文件。

创建你自己的驱动包。

开发和测试过程中给你的驱动包进行测试签名。

给你的驱动包进行发布签名。

发布驱动包。

也就是说,我们最后开发的所有东西都通过一个驱动包发布出去,商业的驱动包最后都打包成一个.exe,引导用户一步一步安装完成即可。最开始学习时,不需要做到这一步,但是我们需要提供一个最简单的驱动包。虽然不需要提供自安装功能,起码要包含安装运行所需要的所有内容。


根据MSDN,驱动包中包含以下文件:驱动文件、安装文件以及其它文件。其中驱动文件是由我们所写的源代码编译而成的.sys动态库,安装文件包含INF文件和签名文件(.cat),其它文件则是一些说明文件。测试签名本来是应该做的,但是这个过程并不简单,对于初学者来说,写INF文件已经是一个繁琐复杂的过程了。所以我们暂时先忽略它,相关的内容以后单独作一节来写。


现在我们就明确编译阶段的任务,生成.sys驱动,INF安装文件。与WDK中的示例一样,现在我们要编写几个文件:makefile,makefile.inc,sources,和INX。


Makefile和makefile.inc文件直接从示例中拷贝即可,基本保持不变,如果读者想弄清楚具体内容,需要知道makefile的相关知识。至于其中的一些宏定义,WDK中bin目录下有一个setenv.bat文件,从快捷方式打开WDK编译环境时会运行这个批处理文件(如图5.1),设置环境变量,这个文件中有一部分宏定义。



图5.1


下面的重点是INX文件的编写。INX文件实际上是一个包含字符串变量的INF文件,其中的字符串变量表示了版本信息,通过一个INX文件可以编译出用于不同平台和框架版本的INF文件。编译它的工具为Stampinf.exe,位于WDK中bin目录下。关于INF文件的中文最详尽清楚的教程,应该是张佩、马勇和董鉴源编著的《竹林蹊径 深入浅出Windows驱动开发》,里面对于驱动安装和测试有比较详细地描述。读者应该先看一下该书及相关文档。而且,读者一定要去看看该书,应用我的一些术语说法引用自该书,书中解释得很清楚,我只是教大家写一个完整的INX文件。


那么我们直接开始编写INX文件了,编写的过程中请参考WDK示例。此处说一下,第一个INX文件不要直接拷贝示例然后修改,最好从一个空白文件一行一行写起。你只有知道一个INX文件包含哪些部分,每部分如何组成的,以后拷贝出问题后才知道怎么修改。


INX文件与ini文件格式类似,因此,可以新建一个HelloWorld.ini文件,便于在Notepad++中提供语法高亮,阅读起来更容易,一般INX文件与驱动同名。不过,ini的注释为单行,而INX文件中的注释不需要另起一行。


先添加版本域,这也是一个必选的域:


----------------------------------------------------------------------------------

; 版本域

[Version]

Signature="$WINDOWS NT$"  ; 固定

Class=HUSTSample  ; 我们的驱动不属于已有的设备类,定义一个新的设备类

ClassGuid={FDA3877E-5FF3-4c18-8235-7FEA16EE04E2}  ; 设备类的GUID

Provider=%ProviderName%  ; 驱动的作者,由字符串域中的ProviderName指定

DriverVer=01/12/2016,21.12.36.570  ; 驱动版本


; 字符串域

[Strings]

ProviderName=”HUSTD10”  ; 驱动作者

----------------------------------------------------------------------------------


版本域中涉及到新添加的设备类,同样在《竹林蹊径 深入浅出Windows驱动开发》有比较详细的描述。Provider引用了字符串域中的内容,还有其它部分也在字符串域定义了相关内容,所以这里的字符串域并不是最后的内容,后面还会定义新的内容,读者需要把这些内容组合到一起。此处需要一个设备类的GUID,如果安装了Visual Studio,那么Tools目录下有一个guidgen.exe工具,可用来生成GUID,当然也可以去网站在线生成一个GUID,如http://www.guidgen.com/。


由于我们新添加了自己的设备类HUSTD10,需要在注册表的HKLM\SYSTEM\CurrentControlSet\Control\Class下添加相关注册表项,因此,INX文件要添加的下一个域为设备类安装域:


----------------------------------------------------------------------------------

; 设备类安装域

[ClassInstall32]

Addreg=SampleClassReg  ; 写注册表之类,要写入的内容放在SampleClassReg子域中

----------------------------------------------------------------------------------

----------------------------------------------------------------------------------

; SampleClassReg子域

[SampleClassReg]

HKR,,,0,%ClassName%  ; 设备类的名称,由字符串域的ClassName决定

HKR,,Icon,,-5  ; 设备管理器中显示的图标,使用5号系统图标


; 字符串域

[Strings]

ClassName=”HUST Sample Device”  ; 设备类的名称

----------------------------------------------------------------------------------


搞定了设备类之后,我们需要给我们的设备指定厂商、产品和设备本身的相关信息,先指定厂商域:


----------------------------------------------------------------------------------

; 厂商域

[Manufacturer]

%MfgName%=Standard,NT$ARCH$  ; 厂商名由字串串域MfgName决定,产品域有两个,

;一个为Standard,一个为Standard.NT$ARCH$(带版本信息)


; 字符串域

[Strings]

MfgName=”HUSTD10”  ; 厂商名称

----------------------------------------------------------------------------------


下面是两个产品域:


----------------------------------------------------------------------------------

; Standard产品域

[Standard]

%HelloWorld.DeviceDesc%=HelloWorld_Device, root\HelloWorld  ; 设备描述(可以等同理

;解为设备名)由字符串域中的HelloWorld.DeviceDesc指定,设备安装域为HelloWorld_Device,

;硬件ID为root\HelloWorld


; Standard.NT$ARCH$产品域

[Standard.NT$ARCH$]

%HelloWorld.DeviceDesc%=HelloWorld_Device, root\HelloWorld  ; 同上


; 字符串域

[Strings]

HelloWorld.DeviceDesc=”HelloWorld”  ; 设备描述(等同理解为设备名)

----------------------------------------------------------------------------------


写了厂商域和产品域之后,接下来就是设备本身的信息了,也就是设备域,或者设备安装域,是很重要的一个部分,也被称作DDInstall域。


----------------------------------------------------------------------------------

; 设备安装域

[HelloWorld_Device.NT]

CopyFiles=Drivers_Dir  ; 需要拷贝的文件列表,由Drivers_Dir子域指定,一般这个文件就

;是我们编写的驱动文件.sys了


; Drivers_Dir子域

[Drivers_Dir]

HelloWorld.sys  ; 我们编写的驱动文件

----------------------------------------------------------------------------------


有人会注意到前面产品域中定义的设备域为HelloWorld_Device,为什么后面却变成了HelloWorld_Device.NT?实际上我们不仅仅只有HelloWorld_Device.NT,还可以定义HelloWorld_Device.NTx86,HelloWorld_Device.NTIA64,或者HelloWorld_Device.NTAMD64域,它们表示不同的硬件平台版本,当然也可以不写版本,就写HelloWorld_Device,这与HelloWorld_Device.NT是相同的,表示与硬件平台无关。


下面定义设备安装域一个重要的子域——服务子域,用来向系统注册服务,为设备的运行提供支持。


----------------------------------------------------------------------------------

; 设备域服务子域

[HelloWorld_Device.NT.Services]

AddService=HelloWorld, %SPSVCINST_ASSOCSERVICE%, HelloWorld_Service_Inst  ; 添加服务

;指令,添加的服务名为HelloWorld,%SPSVCINST_ASSOCSERVICE%为一个标记,指定如何增加服

;务,在Setupapi.h中定义,HelloWorld_Service_Inst为服务安装子域


; 字符串域

[Strings]

SPSVCINST_ASSOCSERVICE = 0x00000002  ; 服务安装标记

----------------------------------------------------------------------------------


下面是服务安装子域:


----------------------------------------------------------------------------------

; HelloWorld_Service_Inst服务安装子域

[HelloWorld_Service_Inst]

DisplayName = %HelloWorld.SVCDESC%  ; 服务显示名称,与服务名不同

ServiceType = 1  ; 服务类型SERVICE_KERNEL_DRIVER

StartType = 3  ; 启动类型SERVICE_DEMAND_START

ErrorControl = 1  ; 错误控制级别SERVICE_ERROR_NORMAL

ServiceBinary = %12%\HelloWorld.sys  ; 镜像文件路径,即.sys文件路径


; 字符串域

[Strings]

HelloWorld.SVCDESC = “Hello World Service”  ; 服务显示名称

----------------------------------------------------------------------------------


接下来是设备安装域另一个重要的子域——辅助安装器子域(CoInstallers),该子域的作用是把一个或多个DLL文件记录到注册表中,并把它们拷贝到相关目录下。


----------------------------------------------------------------------------------

;设备域辅助安装器子域

[HelloWorld_Device.NT.CoInstallers]

AddReg = HelloWorld_Device_CoInstaller_AddReg  ; 写注册表子域

CopyFiles = HelloWorld_Device_CoInstaller_CopyFiles  ; 拷贝文件列表


; 写注册表子域

[HelloWorld_Device_CoInstaller_AddReg]

HKR,,CoInstallers32,0x00010000,"WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCo-

Installer"  ; 注册表项为CoInstallers32,WdfCoInstaller为入口函数


; 拷贝文件列表

[HelloWorld_Device_CoInstaller_CopyFiles]

WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll  ; 拷贝对应版本的.dll

----------------------------------------------------------------------------------


接着是Wdf域,安装框架的辅助安装程序之后,框架将在安装驱动程序时读取这部分。


----------------------------------------------------------------------------------

; Wdf域

[HelloWorld_Device.NT.Wdf]

KmdfService = HelloWorld, HelloWorld_wdfsect  ; HelloWorld为操作系统分配给驱动程序

;的内核模式服务的名称,HelloWorld_wdfsect是一个子域


; HelloWorld_wdfsect子域

[HelloWorld_wdfsect]

KmdfLibraryVersion = $KMDFVERSION$  ; KMDF库的版本号

----------------------------------------------------------------------------------


由于INX文件中包含了文件拷贝指令CopyFiles,需要几个额外的域来指定文件位置,它们是源磁盘域([SourceDisksNames])、源文件域([SourceDisksFiles])和目的域([DestinationDirs])。


----------------------------------------------------------------------------------

; 源磁盘域

[SourceDisksNames]

1 = %DiskId1%,,,””  ; 只有一个磁盘,ID为1,磁盘描述为字符串域中的DiskId1


; 源文件域

[SourceDisksFiles]

; 本INX文件CopyFiles涉及两个文件的拷贝,HelloWorld.sys和辅助安装器WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,分别指定它们

HelloWorld.sys = 1  ; 1号磁盘

WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll = 1  ; 1号磁盘


; 目的域

[DestinationDirs]

DefaultDestDir = 12  ; 默认目录,12是Windows定义的,等同于%SystemRoot%\system32\drivers

HelloWorld_Device_CoInstaller_CopyFiles  = 11  ; 除了默认目录外,还有一个CopyFiles子域,

;此子域不使用默认目录,定义为11,等同于%SystemRoot%\system32。其它没有特殊定义的

;CopyFiles子域则使用默认目录


; 字符串域

[Strings]

DiskId1 = “HUSTD10 HelloWorld Disk #1”  ; 1号磁盘描述

----------------------------------------------------------------------------------


好了,到此INX文件就写好了,下面给出一个完整版本的INX文件:


----------------------------------------------------------------------------------

; 完整的Hello Word驱动INX文件

; 参考WDK示例 echo.inx


;******************************************************************************

; 版本部分

;******************************************************************************


; 版本域

[Version]

Signature="$WINDOWS NT$"  ; 固定

Class=HUSTSample  ; 我们的驱动不属于已有的设备类,定义一个新的设备类

ClassGuid={FDA3877E-5FF3-4c18-8235-7FEA16EE04E2}  ; 设备类的GUID

Provider=%ProviderName%  ; 驱动的作者,由字符串域中的ProviderName指定

DriverVer=01/12/2016,21.12.36.570  ; 驱动版本


;******************************************************************************

; 设备类部分

;******************************************************************************


; 设备类安装域

[ClassInstall32]

Addreg=SampleClassReg  ; 写注册表之类,要写入的内容放在SampleClassReg子域中


; SampleClassReg子域

[SampleClassReg]

HKR,,,0,%ClassName%  ; 设备类的名称,由字符串域的ClassName决定

HKR,,Icon,,-5  ; 设备管理器中显示的图标,使用5号系统图标


;******************************************************************************

; 产商及设备安装部分

;******************************************************************************


; 厂商域

[Manufacturer]

%MfgName%=Standard,NT$ARCH$  ; 厂商名由字串串域MfgName决定,产品域有两个,一个

;为Standard,一个为Standard.NT$ARCH$(带版本信息)


; Standard产品域

[Standard]

%HelloWorld.DeviceDesc%=HelloWorld_Device, root\HelloWorld  ; 设备描述(可以等

;同理解为设备名)由字符串域中的HelloWorld.DeviceDesc指定,设备安装域为HelloWo-

;rld_Device,硬件ID为root\HelloWorld


; Standard.NT$ARCH$产品域

[Standard.NT$ARCH$]

%HelloWorld.DeviceDesc%=HelloWorld_Device, root\HelloWorld  ; 同上


; 设备安装域

[HelloWorld_Device.NT]

CopyFiles=Drivers_Dir  ; 需要拷贝的文件列表,由Drivers_Dir子域指定,一般这个文件

;就是我们编写的驱动文件.sys了


; Drivers_Dir子域

[Drivers_Dir]

HelloWorld.sys  ; 我们编写的驱动文件


; 设备域服务子域

[HelloWorld_Device.NT.Services]

AddService=HelloWorld, %SPSVCINST_ASSOCSERVICE%, HelloWorld_Service_Inst  ; 添加

;服务指令,添加的服务名为HelloWorld,%SPSVCINST_ASSOCSERVICE%为一个标记,指定如何

;增加服务,在Setupapi.h中定义,HelloWorld_Service_Inst为服务安装子域


; HelloWorld_Service_Inst服务安装子域

[HelloWorld_Service_Inst]

DisplayName = %HelloWorld.SVCDESC%  ; 服务显示名称,与服务名不同

ServiceType = 1  ; 服务类型SERVICE_KERNEL_DRIVER

StartType = 3  ; 启动类型SERVICE_DEMAND_START

ErrorControl = 1  ; 错误控制级别SERVICE_ERROR_NORMAL

ServiceBinary = %12%\HelloWorld.sys  ; 镜像文件路径,即.sys文件路径


;******************************************************************************

; 辅助安装器部分

;******************************************************************************


;设备域辅助安装器子域

[HelloWorld_Device.NT.CoInstallers]

AddReg = HelloWorld_Device_CoInstaller_AddReg  ; 写注册表子域

CopyFiles = HelloWorld_Device_CoInstaller_CopyFiles  ; 拷贝文件列表


; 写注册表子域

[HelloWorld_Device_CoInstaller_AddReg]

HKR,,CoInstallers32,0x00010000,"WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,

WdfCoInstalle-r"  ; 注册表项为CoInstallers32,WdfCoInstaller为入口函数


; 拷贝文件列表

[HelloWorld_Device_CoInstaller_CopyFiles]

WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll  ; 拷贝对应版本的.dll


; Wdf域

[HelloWorld_Device.NT.Wdf]

KmdfService = HelloWorld, HelloWorld_wdfsect  ; HelloWorld为操作系统分配给驱动

;程序的内核模式服务的名称,HelloWorld_wdfsect是一个子域


; HelloWorld_wdfsect子域

[HelloWorld_wdfsect]

KmdfLibraryVersion = $KMDFVERSION$  ; KMDF库的版本号


;******************************************************************************

; 文件域部分

;******************************************************************************


; 源磁盘域

[SourceDisksNames]

1 = %DiskId1%,,,””  ; 只有一个磁盘,ID为1,磁盘描述为字符串域中的DiskId1


; 源文件域

[SourceDisksFiles]

; 本INX文件CopyFiles涉及两个文件的拷贝,HelloWorld.sys和辅助安装器WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,分别指定它们

HelloWorld.sys = 1  ; 1号磁盘

WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll = 1  ; 1号磁盘


; 目的域

[DestinationDirs]

DefaultDestDir = 12  ; 默认目录,12是Windows定义的,等同于%SystemRoot%\system32\

;drivers

HelloWorld_Device_CoInstaller_CopyFiles  = 11  ; 除了默认目录外,还有一个Copy-

;Files子域,此子域不使用默认目录,定义为11,等同于%SystemRoot%\system32。其它没

;有特殊定义的CopyFiles子域则使用默认目录


;******************************************************************************

; 字符串部分

;******************************************************************************


; 字符串域

[Strings]

ProviderName="HUSTD10"  ; 驱动作者

ClassName="HUST Sample Device"  ; 设备类的名称

MfgName="HUSTD10"  ; 厂商名称

HelloWorld.DeviceDesc="HelloWorld"  ; 设备描述(等同理解为设备名)

SPSVCINST_ASSOCSERVICE = 0x00000002  ; 服务安装标记

HelloWorld.SVCDESC = "Hello World Service"  ; 服务显示名称

DiskId1 = "HUSTD10 HelloWorld Disk #1"  ; 1号磁盘描述

----------------------------------------------------------------------------------


该INX文件相对于最终的INF文件,多了表示版本的几个字符串变量,它们分别是:ARCH,KMDFCOINSTALLERVERSION和KMDFVERSION。ARCH表示硬件平台,使用x86编译环境,ARCH 会被替换为“x86”,KMDFCOINSTALLERVERSION表示辅助安装器(Co-installer)的版本,KMDFVERSION表示KMDF库的版本。它们都会在生成INF文件时被替换,读者可以自行比较。


INX文件生成INF文件是通过WDK中bin目录下的StampInf.exe工具完成的,后面我们通过批处理命令在makefile中调用它。现在,我们先手动运行它来看看。进入WDK编译环境,切换到HelloWorld.inx目录下,输入stampinf -?查看帮助。


Stampinf直接修改文件,因此我们把HelloWorld.inx复制一份,命名为HelloWorld.inf,输入命令: stampinf -f HelloWorld.inf -a x86 -k 1.9,命令表示x86硬件平台,KMDF主版本号为1,次版本号为9。Stampinf还可以给DriverVer打上时间戳。


可以使用另一个工具来检查生成的inf文件的语法,这个工具为ChkInf,位于tools\Chkinf目录下,是一个脚本。切换到tools\Chkinf目录下,输入:chkinf D:\HUSTD10\HelloWorld.inf /O D:\Temp 命令,chkinf会将结果放到d:\temp目录下,用浏览器查看即可。


好了,Inf文件就说这么多,接下来还有一个文件要编写,即sources文件,这个文件比较简单,就不一步一步写了。


----------------------------------------------------------------------------------

TARGETNAME=HelloWorld  # 编译后.sys文件名

TARGETTYPE=DRIVER  # 编译类型为驱动


KMDF_VERSION_MAJOR=1   # KMDF主版本


INF_NAME=HelloWorld  # 通过 INX生成的INF文件名,这个变量在makefile.inc中被引用

INCLUDES=$(INCLUDES);..\..\inc  #头文件目录

NTTARGETFILE0=$(OBJ_PATH)\$(O)\$(INF_NAME).inf

PASS0_BINPLACE=$(NTTARGETFILE0)  #通过INX生成的INF文件路径


C_DEFINES= $(C_DEFINES)  #一些编译器的开关


SOURCES=driver.c  # 源代码文件列表

 ----------------------------------------------------------------------------------


现在,编译所需的文件就都准备好了,打开编译环境,进入项目目录,输入build命令编译,编译生成了HelloWorld.sys,HelloWorld.inf以及用于调试的符号文件。下面我们来安装驱动。


6 安装Hello World驱动

由于HelloWorld驱动为纯软件驱动,所以驱动不能像我们插上U盘那样自动安装,因为即插即用管理器检测不到新的设备。而且驱动程序没有测试签名,只能用管理员身份,以批准驱动的安装。



好文章,来自【福优学苑@音视频+流媒体】
***【在线视频教程】***