(十九)、分层驱动
驱动调用驱动算是分层驱动
一、遍历驱动设备
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; }