(十九)、分层驱动
驱动调用驱动算是分层驱动
一、遍历驱动设备
AttachedDevice :IO管理器通过这个成员找到顶层设备
NextDevice: 一个驱动可能包含很多设备对象,每个设备对象可能属于多个驱动,通过NextDevice枚举到所有设备,nextdevice都属于同一个驱动
二、驱动过滤
IoSkipCurrentIrpStackLocation
CurrentStackLocation++指向更底层的栈
IoAttachDeviceToDeviceStack
顶层驱动可以通过这个函数附载到底层驱动上,底层驱动的AttachedDevice将会记录这个上层驱动
DriverA
#include <ntddk.h> //作为底层驱动// KDPC dpc; KTIMER timer; LARGE_INTEGER timeout; VOID Unload(PDRIVER_OBJECT driver) { //IoStopTimer(driver->DeviceObject); UNICODE_STRING SymbolicName = RTL_CONSTANT_STRING(L"\\??\\MyDDKLink"); KeCancelTimer(&timer); DbgPrint("Driver Unload\n"); IoDeleteSymbolicLink(&SymbolicName); IoDeleteDevice(driver->DeviceObject); DbgPrint("driver unload\n"); } VOID IoTimer( PDEVICE_OBJECT pDeviceObject, PVOID pContext ) { DbgPrint("iO定时器\n"); } void DpcRoutine( struct _KDPC* Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2 ) { DbgPrint("进入DriverA Dpc Timer\n"); PIRP Irp = (PIRP)DeferredContext; Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); DbgPrint("离开DriverA Dpc Timer\n"); } NTSTATUS DispatchRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp) { DbgPrint("进入DispatchRoutine\n"); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); DbgPrint("离开DispatchRoutine\n"); return STATUS_SUCCESS; } NTSTATUS DispatchRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) { DbgPrint("进入DriverA: Read\n"); IoMarkIrpPending(Irp); timeout = RtlConvertLongToLargeInteger(-10 * 2000 * 1000);// 2s 一次// KeInitializeTimer(&timer); KeInitializeDpc(&dpc, DpcRoutine, Irp); KeSetTimer(&timer, timeout, &dpc); DbgPrint("离开驱动A Read\n"); return STATUS_PENDING; } NTSTATUS DriverEntry(PDRIVER_OBJECT driver) { DbgPrint("Driver Load\n"); UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\MyDDKLink"); UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName"); PDEVICE_OBJECT DeviceObject; NTSTATUS status; status = IoCreateDevice(driver, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject); if (!NT_SUCCESS(status)) { DbgPrint("设备创建失败\n"); return status; } status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName); if (!NT_SUCCESS(status)) { DbgPrint("符号链接创建失败\n"); IoDeleteDevice(DeviceObject); return status; } //IoInitializeTimer(DeviceObject, IoTimer, NULL); //IoStartTimer(DeviceObject);//启动定时器,默认1s一次// //timeout = RtlConvertLongToLargeInteger(-10 * 2000 * 1000);// 2s 一次// //KeInitializeTimer(&timer); //KeInitializeDpc(&dpc, DpcRoutine, NULL); //KeSetTimer(&timer, timeout, &dpc); driver->DriverUnload = Unload; driver->MajorFunction[IRP_MJ_CREATE] = DispatchRoutine; driver->MajorFunction[IRP_MJ_CLOSE] = DispatchRoutine; driver->MajorFunction[IRP_MJ_READ] = DispatchRead; DeviceObject->Flags |= DO_BUFFERED_IO; DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; //KeSetTimer(&timer, timeout, &dpc); return STATUS_SUCCESS; }
DriverB
#include <ntddk.h> typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT TargetDevice; }DEVICE_EXTENSION,*PDEVICE_EXTENSION; VOID Unload(PDRIVER_OBJECT driver) { PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)driver->DeviceObject->DeviceExtension; IoDetachDevice(pdx->TargetDevice); IoDeleteDevice(driver->DeviceObject); DbgPrint("DriverB Unload\n"); } NTSTATUS Read(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; NTSTATUS status; DbgPrint("进入DriverB :Read\n"); IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(pdx->TargetDevice, Irp); DbgPrint("离开DriverB :Read\n"); return status; } NTSTATUS Close(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; NTSTATUS status; DbgPrint("进入DriverB :Close\n"); IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(pdx->TargetDevice, Irp); DbgPrint("离开DriverB :Close\n"); return status; } NTSTATUS Create(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; NTSTATUS status; DbgPrint("进入DriverB :Create\n"); IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(pdx->TargetDevice, Irp); DbgPrint("离开DriverB :Create\n"); return status; } NTSTATUS DriverEntry(PDRIVER_OBJECT driver) { DbgPrint("DriverB Load\n"); PDEVICE_OBJECT pDeviceObject; NTSTATUS status; PDEVICE_EXTENSION pdx; PFILE_OBJECT FileObject; PDEVICE_OBJECT NextDevice; //目标设备// UNICODE_STRING TargetDeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName"); status = IoCreateDevice(driver, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_UNKNOWN, FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &pDeviceObject); if (!NT_SUCCESS(status)) { DbgPrint("设备创建失败\n"); return status; } pdx = (PDEVICE_EXTENSION)pDeviceObject->DeviceExtension; status = IoGetDeviceObjectPointer(&TargetDeviceName, FILE_ANY_ACCESS, &FileObject, &NextDevice); pdx->TargetDevice = IoAttachDeviceToDeviceStack(pDeviceObject, NextDevice); pdx->TargetDevice->Characteristics = pDeviceObject->Characteristics; pdx->TargetDevice->DeviceType = pDeviceObject->DeviceType; pdx->TargetDevice->Flags = pDeviceObject->Flags; pdx->TargetDevice->Flags &= ~DO_DEVICE_INITIALIZING; ObDereferenceObject(FileObject); driver->DriverUnload = Unload; driver->MajorFunction[IRP_MJ_READ] = Read; driver->MajorFunction[IRP_MJ_CREATE] = Create; driver->MajorFunction[IRP_MJ_CLOSE] = Close; return STATUS_SUCCESS; }
三环代码
// syn_asy三环代码.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <iostream> #include <stdio.h> #include <Windows.h> using namespace std; int main() { HANDLE hDevice = CreateFile(TEXT("\\\\.\\MyDDKLink"), GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL , NULL); if (hDevice == INVALID_HANDLE_VALUE) { printf("打开设备失败 %d\n", GetLastError()); return -1; } DWORD dwRet; ReadFile(hDevice, NULL, 0, &dwRet, NULL); CloseHandle(hDevice);//在内核会触发 MJ_cleanuP 与Close派遣函数// getchar(); return 0; }
三环代码调底层驱动DriverA,Irp请求会被DriverA的顶层DriverB所拦截...
三、完成函数
IoSetCompletionRoutine
驱动B代码
#include <ntddk.h> typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT TargetDevice; }DEVICE_EXTENSION,*PDEVICE_EXTENSION; VOID Unload(PDRIVER_OBJECT driver) { PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)driver->DeviceObject->DeviceExtension; IoDetachDevice(pdx->TargetDevice); IoDeleteDevice(driver->DeviceObject); DbgPrint("DriverB Unload\n"); } IO_COMPLETION_ROUTINE IoCompletionRoutine; NTSTATUS IoCompletionRoutine( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ) { DbgPrint("进入DriverB: IoCompletionRoutine\n"); if (Irp->PendingReturned) { IoMarkIrpPending(Irp); } DbgPrint("离开DriverB: IoCompletionRoutine\n"); return STATUS_CONTINUE_COMPLETION; } NTSTATUS Read(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; NTSTATUS status; DbgPrint("进入DriverB :Read\n"); //IoSkipCurrentIrpStackLocation(Irp);// IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE); status = IoCallDriver(pdx->TargetDevice, Irp); DbgPrint("离开DriverB :Read\n"); return status; } NTSTATUS Close(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; NTSTATUS status; DbgPrint("进入DriverB :Close\n"); IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(pdx->TargetDevice, Irp); DbgPrint("离开DriverB :Close\n"); return status; } NTSTATUS Create(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; NTSTATUS status; DbgPrint("进入DriverB :Create\n"); IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(pdx->TargetDevice, Irp); DbgPrint("离开DriverB :Create\n"); return status; } NTSTATUS DriverEntry(PDRIVER_OBJECT driver) { DbgPrint("DriverB Load\n"); PDEVICE_OBJECT pDeviceObject; NTSTATUS status; PDEVICE_EXTENSION pdx; PFILE_OBJECT FileObject; PDEVICE_OBJECT NextDevice; //目标设备// UNICODE_STRING TargetDeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName"); status = IoCreateDevice(driver, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_UNKNOWN, FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &pDeviceObject); if (!NT_SUCCESS(status)) { DbgPrint("设备创建失败\n"); return status; } pdx = (PDEVICE_EXTENSION)pDeviceObject->DeviceExtension; status = IoGetDeviceObjectPointer(&TargetDeviceName, FILE_ANY_ACCESS, &FileObject, &NextDevice); pdx->TargetDevice = IoAttachDeviceToDeviceStack(pDeviceObject, NextDevice); pdx->TargetDevice->Characteristics = pDeviceObject->Characteristics; pdx->TargetDevice->DeviceType = pDeviceObject->DeviceType; pdx->TargetDevice->Flags = pDeviceObject->Flags; pdx->TargetDevice->Flags &= ~DO_DEVICE_INITIALIZING; ObDereferenceObject(FileObject); driver->DriverUnload = Unload; driver->MajorFunction[IRP_MJ_READ] = Read; driver->MajorFunction[IRP_MJ_CREATE] = Create; driver->MajorFunction[IRP_MJ_CLOSE] = Close; return STATUS_SUCCESS; }
底层驱动DriverA完成Dpc定时器后会触发DriverA的完成函数,输出IoCompletionRoutine
四、多次对Irp有控制权
这里引入了事件
DriverB代码
#include <ntddk.h> typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT TargetDevice; }DEVICE_EXTENSION,*PDEVICE_EXTENSION; VOID Unload(PDRIVER_OBJECT driver) { PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)driver->DeviceObject->DeviceExtension; IoDetachDevice(pdx->TargetDevice); IoDeleteDevice(driver->DeviceObject); DbgPrint("DriverB Unload\n"); } IO_COMPLETION_ROUTINE IoCompletionRoutine; NTSTATUS IoCompletionRoutine( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ) { PKEVENT pEvent = (PKEVENT)Context; DbgPrint("进入DriverB: IoCompletionRoutine\n"); if (Irp->PendingReturned) { KeSetEvent(pEvent, IO_NO_INCREMENT, FALSE); } DbgPrint("离开DriverB: IoCompletionRoutine\n"); return STATUS_MORE_PROCESSING_REQUIRED; } NTSTATUS Read(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; NTSTATUS status; DbgPrint("进入DriverB :Read\n"); //IoSkipCurrentIrpStackLocation(Irp);// IoCopyCurrentIrpStackLocationToNext(Irp); KEVENT Event; KeInitializeEvent(&Event, NotificationEvent, FALSE); IoSetCompletionRoutine(Irp, IoCompletionRoutine, &Event, TRUE, TRUE, TRUE); status = IoCallDriver(pdx->TargetDevice, Irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); DbgPrint("等待结束\n"); } IoCompleteRequest(Irp, IO_NO_INCREMENT); DbgPrint("离开DriverB :Read\n"); return STATUS_SUCCESS; } NTSTATUS Close(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; NTSTATUS status; DbgPrint("进入DriverB :Close\n"); IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(pdx->TargetDevice, Irp); DbgPrint("离开DriverB :Close\n"); return status; } NTSTATUS Create(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; NTSTATUS status; DbgPrint("进入DriverB :Create\n"); IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(pdx->TargetDevice, Irp); DbgPrint("离开DriverB :Create\n"); return status; } NTSTATUS DriverEntry(PDRIVER_OBJECT driver) { DbgPrint("DriverB Load\n"); PDEVICE_OBJECT pDeviceObject; NTSTATUS status; PDEVICE_EXTENSION pdx; PFILE_OBJECT FileObject; PDEVICE_OBJECT NextDevice; //目标设备// UNICODE_STRING TargetDeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName"); status = IoCreateDevice(driver, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_UNKNOWN, FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &pDeviceObject); if (!NT_SUCCESS(status)) { DbgPrint("设备创建失败\n"); return status; } pdx = (PDEVICE_EXTENSION)pDeviceObject->DeviceExtension; status = IoGetDeviceObjectPointer(&TargetDeviceName, FILE_ANY_ACCESS, &FileObject, &NextDevice); pdx->TargetDevice = IoAttachDeviceToDeviceStack(pDeviceObject, NextDevice); pdx->TargetDevice->Characteristics = pDeviceObject->Characteristics; pdx->TargetDevice->DeviceType = pDeviceObject->DeviceType; pdx->TargetDevice->Flags = pDeviceObject->Flags; pdx->TargetDevice->Flags &= ~DO_DEVICE_INITIALIZING; ObDereferenceObject(FileObject); driver->DriverUnload = Unload; driver->MajorFunction[IRP_MJ_READ] = Read; driver->MajorFunction[IRP_MJ_CREATE] = Create; driver->MajorFunction[IRP_MJ_CLOSE] = Close; return STATUS_SUCCESS; }
__EOF__

本文作者:_TLSN
本文链接:https://www.cnblogs.com/lordtianqiyi/articles/16135937.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/lordtianqiyi/articles/16135937.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现