当前位置: 首页 > article >正文

IRP读写函数


驱动代码:

#include <ntddk.h>

#define DEVICE_NAME L"\\device\\MyDricer1" //设备对象名称
#define LINK_NAME L"\\dosdevices\\Goose" //符号链接名称

VOID UnDirver(PDRIVER_OBJECT pDriverObj)
{
	UNICODE_STRING uLinkName = RTL_CONSTANT_STRING(LINK_NAME);//初始化符号链接名称
	IoDeleteSymbolicLink(&uLinkName);//删除符号链接
	IoDeleteDevice(pDriverObj->DeviceObject);//删除设备对象
	DbgPrint("Driver Unloaded.\n");
}

NTSTATUS DisPatchFunc(PDEVICE_OBJECT Device, PIRP irp)
{
	irp->IoStatus.Information = 0;//设置返回的字节数
	irp->IoStatus.Status = STATUS_SUCCESS;//设置irp处理成功
	IoCompleteRequest(irp, IO_NO_INCREMENT);//结束irp处理流程
	return STATUS_SUCCESS;
}

NTSTATUS DisPatch_R3Read(PDEVICE_OBJECT Device, PIRP irp)
{
	UNICODE_STRING usBuffer = RTL_CONSTANT_STRING(L"Hello word");//初始化Unicode字符串
	PVOID ioBUffer = irp->AssociatedIrp.SystemBuffer;//因为是基于缓存的通信方式,所以SystemBuffer是专门用来读写的内存
	PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(irp);//获取当前设备对象栈结构(主函数创建的设备对象)
	ULONG ulReadLength = pStack->Parameters.Read.Length;//获取R3传进来想要读取的字节数
	ULONG ulActuallength = ulReadLength > usBuffer.Length ? usBuffer.Length : ulReadLength;//判断返回谁的字节数
	RtlCopyMemory(ioBUffer, usBuffer.Buffer, ulActuallength);//复制到R0专门准备的缓冲区里面

	irp->IoStatus.Information = ulActuallength;//设置返回的字节数
	irp->IoStatus.Status = STATUS_SUCCESS;//设置irp处理成功
	IoCompleteRequest(irp, IO_NO_INCREMENT);//结束irp处理流程
	return STATUS_SUCCESS;
}

NTSTATUS DisPatch_R3Write(PDEVICE_OBJECT Device, PIRP irp)
{
	PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(irp);
	PVOID ioBUffer = irp->AssociatedIrp.SystemBuffer;
	DbgPrint("%ws", (PCWCH)ioBUffer);
	irp->IoStatus.Information = pStack->Parameters.Write.Length;//设置返回的字节数
	irp->IoStatus.Status = STATUS_SUCCESS;//设置irp处理成功
	IoCompleteRequest(irp, IO_NO_INCREMENT);//结束irp处理流程
	return STATUS_SUCCESS;
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegPath) 
{
	pDriverObj->DriverUnload = UnDirver;

	UNICODE_STRING uDeviceName = RTL_CONSTANT_STRING(DEVICE_NAME);//初始化设备名称
	UNICODE_STRING uLinkName = RTL_CONSTANT_STRING(LINK_NAME);//初始化符号链接名称
	PDEVICE_OBJECT pDeviceObject = NULL;
	NTSTATUS ntStatus = IoCreateDevice(pDriverObj, 0, &uDeviceName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDeviceObject);//创建一个设备对象
	if (ntStatus != STATUS_SUCCESS)
	{
		DbgPrint("IoCreateDevice failed:%x\n", ntStatus);
		return ntStatus;
	}
	pDeviceObject->Flags |= DO_BUFFERED_IO;//设置设备对象的通信方式:1.基于缓存方式 2.直接读写方式 3.两者皆不方式
	ntStatus = IoCreateSymbolicLink(&uLinkName, &uDeviceName);//把设备对象和链接名称进行绑定,R3可以通过链接名称访问
	if (ntStatus != STATUS_SUCCESS)
	{
		IoDeleteDevice(pDeviceObject);//删除设备对象
		DbgPrint("IoCreateSymbolicLink failed:%x\n", ntStatus);
		return ntStatus;
	}
	for (size_t i = 0; i < IRP_MJ_MAXIMUM_FUNCTION + 1; i++)
	{
		pDriverObj->MajorFunction[i] = DisPatchFunc;
	}
	pDriverObj->MajorFunction[IRP_MJ_READ] = DisPatch_R3Read;//设置irp_read的回调函数
	pDriverObj->MajorFunction[IRP_MJ_WRITE] = DisPatch_R3Write;//设置irp_write的回调函数
	DbgPrint("Entry Driver");
	return STATUS_SUCCESS;
}

用户代码:

#include <iostream>
#include <windows.h>

#define LINK_NAME L"\\\\.\\Goose" //符号链接名称

int main()
{
	HANDLE hRet = CreateFile(LINK_NAME, GENERIC_ALL, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hRet == INVALID_HANDLE_VALUE)
	{
		printf("CreateFile failed:%x\n", GetLastError());
		system("pause");
		return 0;
	}
    DWORD dwRetSize = 0;
    WCHAR buffer[MAX_PATH] = {0};
    ReadFile(hRet, buffer, MAX_PATH, &dwRetSize, NULL);
    printf("收到数据大小:%d\n", dwRetSize);
    wprintf(L"%lS\n", buffer);

	WriteFile(hRet, buffer, dwRetSize, &dwRetSize, NULL);
	printf("写入数据大小:%d\n", dwRetSize);
    system("pause");
    return 0;
}



http://www.kler.cn/news/354804.html

相关文章:

  • 八股面试3(自用)
  • 机器学习与神经网络:物理学的新边疆
  • docker 复制文件,清除不再使用数据导出以及导出文件系统
  • 搜维尔科技:力反馈遥操作解决方案,五指灵巧手遥操作解决方案
  • Java初学者的学习顺序
  • 网络基础知识:六大交换机关键知识解析
  • 无人机之遥感影像处理篇
  • 国产 HDMI 发送芯片,兼容 HDMI1.4b 及 HDMI 1.4b 下的视频 3D 传输格式。
  • JavaScript 第9章:面向对象编程
  • 虎牙Android面试题及参考答案
  • C++ 方法积累
  • 【优选算法】(第三十六篇)
  • 【实战案例】Nacos从安装到服务注册发现再到配置中心(附常见问题解决方案)
  • 前端开发设计模式——状态模式
  • 【AIGC】寻找ChatGPT最佳推理步骤:CoT思维链技术的探索与应用
  • C# 将PDF文档转换为Markdown文档
  • Go语言Gin框架调用企业微信接口根据手机号获取userid
  • 滚雪球学Redis[7.3讲]:Redis在排行榜系统中的应用:高效构建与优化
  • 【C++刷题】力扣-#136-只出现一次的数字
  • FPGA基于SRIO Auraro 三速以太网 IIC SPI等多协议的高速传输处理项目