(十九)、分层驱动

驱动调用驱动算是分层驱动
 

一、遍历驱动设备

 
0
AttachedDevice :IO管理器通过这个成员找到顶层设备
 
NextDevice: 一个驱动可能包含很多设备对象,每个设备对象可能属于多个驱动,通过NextDevice枚举到所有设备,nextdevice都属于同一个驱动
 
 
 
0
 
 
0
 
 

二、驱动过滤

IoSkipCurrentIrpStackLocation

0
0
 
0
CurrentStackLocation++指向更底层的栈
 
 

IoAttachDeviceToDeviceStack

顶层驱动可以通过这个函数附载到底层驱动上,底层驱动的AttachedDevice将会记录这个上层驱动
 
0
 
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;
}
 
0
三环代码调底层驱动DriverA,Irp请求会被DriverA的顶层DriverB所拦截...
 

三、完成函数

IoSetCompletionRoutine

0
 
驱动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;
}
 
0
底层驱动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;
}
 
0
 
posted @ 2022-04-12 16:54  TLSN  阅读(109)  评论(0编辑  收藏  举报