驱动程序调用驱动程序
好文章,来自【福优学苑@音视频+流媒体】
简介与章节概览:
驱动程序调用驱动程序的两种方式:
A、文件句柄方式
B、设备指针方式
l 文件的创建、打开、读、写:
ZwCreateFile(...), ZwReadFile(..),ZwWriteFile(...)
l 获取设备指针:
IoGetDeviceObjectPointer(...)
IoCreateDevice(...)
IoDeleteDevice(...)
l 手工创建IRP:
IoBuildSynchronousFsdRequest
IoBuildAsynchronousFsdRequest
IoBuildDeviceIoControlRequest
IoAllocateIrp/IoFreeIrp
l 具体步骤:
1、得到设备的指针
2、手工创建IRP
3、构造IRP的I/O堆栈:IO_STACK_LOCATION
4、调用IoCallDriver函数(pDev, pIrp)
以文件句柄形式调用其他驱动程序
准备一个标准驱动DriverA
目标驱动程序:
模拟一个设备,支持异步读取
IRP_MJ_READ:将IRP请求挂起
定时器:DPC例程
获得设备句柄
HANDLE hDevice;
IO_STATUS_BLOCK status_block;
//同步打开设备
//设定了FILE_SYNCHRONOUS_IO_NONALERT或者FILE_SYNCHRONOUS_IO_ALERT为同步打开设备
ntStatus = ZwCreateFile(&hDevice,
FILE_READ_ATTRIBUTES|SYNCHRONIZE,
&objectAttributes,
&status_block,
NULL,FILE_ATTRIBUTE_NORMAL,FILE_SHARE_READ,
FILE_OPEN_IF,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0);
同步调用
ZwCreateFile(...)
ZwReadFile(...)
异步调用方法一
完成例程
同步点:事件
异步调用方法二
同步点:文件对象
ObReferenceObjectByHandle
ObDereferenceObject
通过符号链接打开设备
ZwOpenSymbolicLinkObject
ZwQuerySymbolicLinkObject
通过设备指针调用其他驱动程序
用IoGetDeviceObjectPointer获得设备指针
NTSTATUS
IoGetDeviceObjectPointer(
_In_ PUNICODE_STRING ObjectName,
_In_ ACCESS_MASK DesiredAccess,
_Out_ PFILE_OBJECT *FileObject,
_Out_ PDEVICE_OBJECT *DeviceObject
);
创建IRP传递给驱动的派遣函数
IoBuildSynchronousFsdRequest
IoBuildAsynchronousFsdRequest
IoBuildDeviceIoControlRequest
IoAllocateIrp
IoCallDriver
步骤:
5、得到设备的指针
6、手工创建IRP
7、构造IRP的I/O堆栈
8、调用IoCallDriver函数
用IoBuildSynchronousFsdRequest创建irp
PIRP
IoBuildSynchronousFsdRequest(
_In_ ULONG MajorFunction,
_In_ PDEVICE_OBJECT DeviceObject,
PVOID Buffer,
_In_ ULONG Length,
_In_opt_ PLARGE_INTEGER StartingOffset,
_In_ PKEVENT Event,
_Out_ PIO_STATUS_BLOCK IoStatusBlock
);
用IoBuildAsynchronousFsdRequest创建irp
Irp->UserEvent
PIRP
IoBuildAsynchronousFsdRequest(
_In_ ULONG MajorFunction,
_In_ PDEVICE_OBJECT DeviceObject,
_Inout_opt_ PVOID Buffer,
_In_opt_ ULONG Length,
_In_opt_ PLARGE_INTEGER StartingOffset,
_In_opt_ PIO_STATUS_BLOCK IoStatusBlock
);
用IoAllocateIrp创建irp
PIRP
IoAllocateIrp(
_In_ CCHAR StackSize,
_In_ BOOLEAN ChargeQuota
);
IoFreeIrp(...)
其他方法获得设备指针
用ObReferenceObjectByName获得设备指针
剖析IoGetDeviceObjectPointer
***【在线视频教程】***