(十二)、驱动通信之缓冲区读写与模拟文件

这里两者代码不小心写一块了,在这里,我的模拟文件代码就是在缓冲区读写上做的小扩展
 
文件模拟利用了驱动设备的扩展区,模拟对文件的读写
驱动从3环获得数据,存放在缓冲区里,驱动扩展通过拷贝得到驱动缓冲区数据,不同的是驱动扩展引入了offset偏移,可以在某固定偏移处读取或写入数据

代码

三环代码

// 缓冲区读写三环代码.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <Windows.h>
#include <stdio.h>
using namespace std;
int main()
{
    HANDLE hDevice = 
        CreateFile(TEXT("\\\\.\\MyDDK"),
        GENERIC_ALL,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    if (hDevice == INVALID_HANDLE_VALUE)
    {
        cout << "设备打开失败\n";
        getchar();
        return -1;
    }
    DWORD dwRet;
    CHAR Buff[1024] = { 0 };

    OVERLAPPED overLd;
    overLd.Offset = 0xFFFFFFFF;
    overLd.OffsetHigh = 0xFFFFFFFF;

///    WriteFile(hDevice, "03环通信\n", strlen("03环通信"), &dwRet, NULL);
    WriteFile(hDevice, "1433223", strlen("1433223"), &dwRet, NULL);
    ReadFile(hDevice, Buff, sizeof(Buff), &dwRet, NULL);
    printf("读回的数据%s\n", Buff);
    printf("读回的数据个数:%d\n", dwRet);

    
    DWORD dwSize = GetFileSize(hDevice, NULL);
    printf("文件长度%d\n", dwSize);
    getchar();
    return 0;
 }

驱动代码

#include <ntddk.h>

typedef struct _DEVICE_EXTENSION
{
    PCHAR Buffer;
    ULONG Length;
#define MAX_FILE_LEN    4096
}DEVICE_EXTENSION,*PDEVICE_EXTENSION;

VOID Unload(PDRIVER_OBJECT driver)
{
    UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\MyDDK");

    IoDeleteSymbolicLink(&SymbolicLinkName);
    IoDeleteDevice(driver->DeviceObject);
    DbgPrint("Driver Unload\n");
}


NTSTATUS DisPatchRoutine(IN PDEVICE_OBJECT DeciceObject, IN PIRP Irp)
{
    static CHAR* irpname[] = {
    " IRP_MJ_CREATE                    " ,
    " IRP_MJ_CREATE_NAMED_PIPE        " ,
    " IRP_MJ_CLOSE                    " ,
    " IRP_MJ_READ                    " ,
    " IRP_MJ_WRITE                    " ,
    " IRP_MJ_QUERY_INFORMATION        " ,
    " IRP_MJ_SET_INFORMATION        "     ,
    " IRP_MJ_QUERY_EA                " ,
    " IRP_MJ_SET_EA                    " ,
    " IRP_MJ_FLUSH_BUFFERS            " ,
    " IRP_MJ_QUERY_VOLUME_INFORMATI    " ,
    " IRP_MJ_SET_VOLUME_INFORMATION    " ,
    " IRP_MJ_DIRECTORY_CONTROL        " ,
    " IRP_MJ_FILE_SYSTEM_CONTROL    "     ,
    " IRP_MJ_DEVICE_CONTROL            " ,
    " IRP_MJ_INTERNAL_DEVICE_CONTRO    " ,
    " IRP_MJ_SHUTDOWN                " ,
    " IRP_MJ_LOCK_CONTROL            " ,
    " IRP_MJ_CLEANUP                "     ,
    " IRP_MJ_CREATE_MAILSLOT        "     ,
    " IRP_MJ_QUERY_SECURITY            " ,
    " IRP_MJ_SET_SECURITY            " ,
    " IRP_MJ_POWER                    " ,
    " IRP_MJ_SYSTEM_CONTROL            " ,
    " IRP_MJ_DEVICE_CHANGE            " ,
    " IRP_MJ_QUERY_QUOTA            " ,
    " IRP_MJ_SET_QUOTA                " ,
    " IRP_MJ_PNP                    "
    };
    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);//IRP栈单元//
    DbgPrint("%s\n", irpname[stack->MajorFunction]);
    Irp->IoStatus.Information = 0;        //返回状态//
    Irp->IoStatus.Status = STATUS_SUCCESS;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);//优先级不改变//
    return STATUS_SUCCESS;
}

NTSTATUS DispatchRead(IN PDEVICE_OBJECT DeciceObject, IN PIRP Irp)
{
    NTSTATUS status;
    
    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
    DbgPrint("读异常\n");
    ULONG length;
    CHAR re[] = "Hello ring3";

    ULONG offset;
    ULONG ReadLength;
    PDEVICE_EXTENSION pdx = DeciceObject->DeviceExtension;

    __try
    {
        length = stack->Parameters.Read.Length;
        offset = stack->Parameters.Read.ByteOffset.LowPart;
        DbgPrint("offect值为%x\n", offset);
        if (length + offset < MAX_FILE_LEN)
        {
            if (length + offset > pdx->Length)
            {
                ReadLength = pdx->Length - offset;
            }
            else
            {
                ReadLength = length;
            }
            RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, pdx->Buffer + offset, ReadLength);
        }
        else
        {
            status = STATUS_BUFFER_TOO_SMALL;
            ReadLength = 0;
        }
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        status = GetExceptionCode();
        DbgPrint("读异常触发,%x\n", status);
    }
    Irp->IoStatus.Information = length;
    Irp->IoStatus.Status = status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return status;
}

NTSTATUS DispatchWrite(IN PDEVICE_OBJECT DeciceObject, IN PIRP Irp)
{
    NTSTATUS status;
    ULONG Length;
    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);//获取IRP栈单元//
    DbgPrint("写异常\n");
    ULONG offect;
    ULONG WriteLength;
    PDEVICE_EXTENSION pdx = DeciceObject->DeviceExtension;
    
    __try
    {
        offect = stack->Parameters.Write.ByteOffset.LowPart;
        DbgPrint("offect值为%x\n", offect);
        Length = stack->Parameters.Write.Length;

        if (Length + offect <= MAX_FILE_LEN)
        {
            if (Length + offect > pdx->Length)
            {
                pdx->Length = Length + offect;
            }
            RtlCopyMemory(pdx->Buffer + offect, Irp->AssociatedIrp.SystemBuffer, Length);
            WriteLength = Length;
        }
        else
        {
            status = STATUS_BUFFER_TOO_SMALL;
            DbgPrint("STATUS_BUFFER_TOO_SMALL\n");
            WriteLength = 0;
            
        }
    //    stack->Parameters.Write.ByteOffset.LowPart += WriteLength;
        
    }
    __except (EXCEPTION_EXECUTE_HANDLER)//如果出现异常,不让操作系统接管,我们自己接管//
    {
        status = GetExceptionCode();
        DbgPrint("写异常触发,%x\n",status);
        Length = 0;
    }
    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = Length;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return status;
}

NTSTATUS DisPatchQueryInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    NTSTATUS status;
    ULONG Length;
    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);

    PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;

    DbgPrint("查询异常\n");
    __try
    {
        Length = stack->Parameters.QueryFile.Length;
        if (stack->Parameters.QueryFile.FileInformationClass == FileStandardInformation && Length >= sizeof(FILE_STANDARD_INFORMATION))
        {
            PFILE_STANDARD_INFORMATION pfsi = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
            pfsi->EndOfFile.LowPart = pdx->Length;
            status = STATUS_SUCCESS;
            Length = sizeof(FILE_STANDARD_INFORMATION);
        }
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        status = STATUS_BUFFER_TOO_SMALL;
        Length = 0;
    }
    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = Length;
        
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;

}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver,  PUNICODE_STRING RegistryPath)
{

    
    
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\HelloDDK");
    UNICODE_STRING SymblicLink = RTL_CONSTANT_STRING(L"\\??\\MyDDK");
    NTSTATUS status;
    PDEVICE_OBJECT DeviceObject;
    driver->DriverUnload = Unload;

    DbgPrint("Driver Load\n");

    PDEVICE_EXTENSION pdx;//设备扩展//

    status = IoCreateDevice(driver, sizeof(DEVICE_EXTENSION), &DeviceName, FILE_DEVICE_UNKNOWN,0, FALSE, &DeviceObject);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("创建设备失败\n");
        return status;
    }
    status = IoCreateSymbolicLink(&SymblicLink, &DeviceName);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("创建符号链接失败\n");
        IoDeleteDevice(DeviceObject);
        return status;
    }
    DeviceObject->Flags |= DO_BUFFERED_IO;    //缓冲区读写//    出错原因,DeviceObject写成了driver//
    DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

    for (ULONG i = 0; i < IRP_MJ_MAXIMUM_FUNCTION + 1; i++)
    {
        driver->MajorFunction[i] = DisPatchRoutine;
    }

    driver->MajorFunction[IRP_MJ_READ] = DispatchRead;
    driver->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
    driver->MajorFunction[IRP_MJ_QUERY_INFORMATION] = DisPatchQueryInfo;

    pdx = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
    pdx->Buffer = (PCHAR)ExAllocatePool(PagedPool, 4096);
    pdx->Length = 0;

    return STATUS_SUCCESS;
}

实验

0
posted @ 2022-04-03 23:44  TLSN  阅读(88)  评论(0编辑  收藏  举报