自学内容网 自学内容网

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



原文地址:https://blog.csdn.net/weixin_48257887/article/details/142913917

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!