Windows驱动开发小白入门


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

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

欢迎进入Windows的驱动编程世界


    驱动程序可以是针对某一特定硬件的,为系统提供管理硬件的各种功能;也可以是针对系统设备的,对系统的输入输出做一些处理,实现特定的功能,比如当软件要做的事用应用程序无法实现或者难以实现某种功能时,但驱动程序可以实现,则需要驱动程序。


    驱动都是要加载入内核的,我们要做的很多事情也需要在内核下完成,要想在内核中实现功能就需要编写驱动模块。提到驱动可能会想到硬件,大家可能会简单地认为驱动程序是控制硬件设备的。

在Windows下驱动并不单单是用来控制硬件设备的。Windows中的驱动程序可以创建虚拟设备,也可以与设备无关。Windows是一个开放式的操作系统,这个开放式并不是指其开放源代码,而是指通过其提供的接口可以很容易和方便地对其内核进行扩展。

image.png

image.png

image.png


图书推荐:

image.png




环境配置:

Vs2015,

sdk10

Wd10

Vmware

Win10x64

驱动安装与调试工具





驱动类型:

NT式驱动

WDM

WDF



通篇概览:


驱动程序入门

Windows内核架构与驱动开发的基本概念

VS2015+WDK10+Vmware(win10x64)双机调试驱动程序

驱动程序的基本结构

Windows内核层的内存管理

Windows内核层的常用内核函数

IRP派遣函数

驱动程序的同步处理

IRP的同步

内核层的定时器

驱动程序调用驱动程序

分层驱动程序








第一个NT式驱动程序


#include <ntifs.h>


VOID UnloadDriver(PDRIVER_OBJECT pDriverObject) {

KdPrint(("Unload Driver success."));

}


/// 相当于main函数

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath) {

KdPrint(("DriverPath:%wZ", pRegistryPath));

KdPrint(("Hello,myDriver"));

pDriverObject->DriverUnload = UnloadDriver;//卸载例程routine


return STATUS_SUCCESS;

}





在虚拟机win10x64中安装NT驱动程序

禁用驱动程序强制签名

第一步:点击右下角的“通知”,选择“所有设置”

第二步:“更新和安全”

第三步:“恢复”

第四步:“重新启动”

第五步:“疑难解答”

第六步:“高级选项”

第七步:“重启”---

第八步:“7”:禁用驱动程序强制签名




驱动安装工具SRVINSTW.EXE

image.png

image.png

image.png







配置DbgView.exe

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter]

"DEFAULT"=dword:0000000f



DbgView.exe默认无法捕获驱动层的输出信息

需要修改注册表。


image.png


第一个WDM式驱动程序

新建工程

image.png



即插即用PnP

PnP全称Plug-and-Play,译文为即插即用。

PnP的作用是自动配置低层计算机中的板卡和其他设备,然后告诉对应设备都做了什么。PnP的任务是把物理设备和软件设备驱动程序相配合,并操作设备,在每个设备和它的驱动程序之间建立通信信道。

然后,PnP分配下列资源给设备和硬件:I/O地址、IRQ、DMA通道和内存段。


PNP是由Microsoft提出的,意思是系统自动侦测周边设备和板卡并自动安装设备驱动程序,做到插上就能用,无须人工干预,是Windows自带的一项技术。所谓即插即用是指将符合PNP标准的PC插卡等外围设备安装到电脑时,操作系统自动设定系统结构的技术。当用户安装新的硬件时,不必再设置任何跳线器开关,也不必用软件配置中断请求(IRQ)、内存地址或直接存储器存取(DMA)通道,Windows会向应用程序通知硬件设备的新变化,并会自动协调IRQ、内存地址和DMA通道之间的冲突。


在PnP技术出现之前,中断和I/O端口的分配是由人手工进行的,例如想要这块声卡占用中断5,就需要找一个小跳线在卡上标着中断5的针脚上一插。这样的操作需要用户了解中断和I/O端口的知识,并且能够自己分配中断地址而不发生冲突,对普通用户提出这样的要求是不切实际的。

代码详解


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

* 文件名称:HelloWDM.h   

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


#ifdef __cplusplus

extern "C"

{

#endif

#include <wdm.h>

#ifdef __cplusplus

}

#endif 


typedef struct _DEVICE_EXTENSION

{

    PDEVICE_OBJECT fdo;

    PDEVICE_OBJECT NextStackDevice;

UNICODE_STRING ustrDeviceName; // 设备名

UNICODE_STRING ustrSymLinkName; // 符号链接名

} DEVICE_EXTENSION, *PDEVICE_EXTENSION;


#define PAGEDCODE code_seg("PAGE")

#define LOCKEDCODE code_seg()

#define INITCODE code_seg("INIT")


#define PAGEDDATA data_seg("PAGE")

#define LOCKEDDATA data_seg()

#define INITDATA data_seg("INIT")


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


NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,

                           IN PDEVICE_OBJECT PhysicalDeviceObject);

NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,

                        IN PIRP Irp);

NTSTATUS HelloWDMDispatchRoutine(IN PDEVICE_OBJECT fdo,

IN PIRP Irp);

void HelloWDMUnload(IN PDRIVER_OBJECT DriverObject);


extern "C"

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,

                     IN PUNICODE_STRING RegistryPath);


Wdm驱动程序总结


DriverEntry(...)

///1.创建设备

pDriverObject->DriverExtension->AddDevice = HelloWDMAddDevice;


///2.分发例程

pDriverObject->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp;

pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = 

pDriverObject->MajorFunction[IRP_MJ_CREATE] = 

pDriverObject->MajorFunction[IRP_MJ_READ] = 

pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloWDMDispatchRoutine;


///3.卸载例程

pDriverObject->DriverUnload = HelloWDMUnload;


image.png

几个内核API函数:

IoCreateDevice

IoDeleteDevice


IoAttachDeviceToDeviceStack

IoSkipCurrentIrpStackLocation

IoDetachDevice

IoSkipCurrentIrpStackLocation

IoCompleteRequest




IoCreateSymbolicLink,

IoDeleteSymbolicLink







配置文件INF

;

; HelloWDM.inf

;


[Version]

Signature="$WINDOWS NT$"

Class=System

ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}

Provider=fyxy

DriverVer = 08/27/2020,16.42.47.674

CatalogFile=HelloWDM2.cat


[DestinationDirs]

DefaultDestDir = 12



[SourceDisksNames]

;1 = %DiskName%,,,""

;1 = "HelloWDM",Disk1,,

1 = %DiskName%,,,""


[SourceDisksFiles]

HelloWDM.sys = 1,,


[Manufacturer]

%ManufacturerName%=Standard,NTamd64


[Standard.NTamd64]

%HelloWDM.DeviceDesc%=HelloWDM, Root\HelloWDM ; TODO: edit hw-id



[Strings]

SPSVCINST_ASSOCSERVICE= 0x00000002

ManufacturerName="fyxy" ;TODO: Replace with your manufacturer name

ClassName="Samples"

DiskName="HelloWDM Source Disk"

HelloWDM.DeviceDesc = "HelloWDM Device"

HelloWDM.SVCDESC = "KMDF_Driver1 Service"





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