Windows驱动开发小白入门
好文章,来自【福优学苑@音视频+流媒体】
欢迎进入Windows的驱动编程世界
驱动程序可以是针对某一特定硬件的,为系统提供管理硬件的各种功能;也可以是针对系统设备的,对系统的输入输出做一些处理,实现特定的功能,比如当软件要做的事用应用程序无法实现或者难以实现某种功能时,但驱动程序可以实现,则需要驱动程序。
驱动都是要加载入内核的,我们要做的很多事情也需要在内核下完成,要想在内核中实现功能就需要编写驱动模块。提到驱动可能会想到硬件,大家可能会简单地认为驱动程序是控制硬件设备的。
在Windows下驱动并不单单是用来控制硬件设备的。Windows中的驱动程序可以创建虚拟设备,也可以与设备无关。Windows是一个开放式的操作系统,这个开放式并不是指其开放源代码,而是指通过其提供的接口可以很容易和方便地对其内核进行扩展。
图书推荐:
环境配置:
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
配置DbgView.exe
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter]
"DEFAULT"=dword:0000000f
DbgView.exe默认无法捕获驱动层的输出信息
需要修改注册表。
第一个WDM式驱动程序
新建工程
即插即用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;
几个内核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"
好文章,来自【福优学苑@音视频+流媒体】
***【在线视频教程】***