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

这里两者代码不小心写一块了,在这里,我的模拟文件代码就是在缓冲区读写上做的小扩展
 
文件模拟利用了驱动设备的扩展区,模拟对文件的读写
驱动从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

__EOF__

本文作者_TLSN
本文链接https://www.cnblogs.com/lordtianqiyi/articles/16098093.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   TLSN  阅读(116)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示