IRP读写函数

时间:2024-10-15 17:14:36


驱动代码:

#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;
}