创建虚拟设备(直接读写方式)-模拟文件读操作

来源:互联网 发布:hush puppies 知乎 编辑:程序博客网 时间:2024/06/02 23:08

驱动文件:

///////////////////////////////////////////////////////////////////////////////////// Copyright (c) 2014 - <company name here>////// Original filename: DirectIO.cpp/// Project          : DirectIO/// Date of creation : 2014-06-23/// Author(s)        : <author name(s)>////// Purpose          : <description>////// Revisions:///  0000 [2014-06-23] Initial revision.//////////////////////////////////////////////////////////////////////////////////// $Id$#ifdef __cplusplusextern "C" {#endif#include <ntddk.h>#include <string.h>#ifdef __cplusplus}; // extern "C"#endif#include "DirectIO.h"#ifdef __cplusplusnamespace { // anonymous namespace to limit the scope of this global variable!#endifPDRIVER_OBJECT pdoGlobalDrvObj = 0;#ifdef __cplusplus}; // anonymous namespace#endifNTSTATUS DIRECTIO_DispatchCreateClose(    IN PDEVICE_OBJECTDeviceObject,    IN PIRPIrp    ){    NTSTATUS status = STATUS_SUCCESS;    Irp->IoStatus.Status = status;    Irp->IoStatus.Information = 0;    IoCompleteRequest(Irp, IO_NO_INCREMENT);    return status;}NTSTATUS DIRECTIO_DispatchDeviceControl(    IN PDEVICE_OBJECTDeviceObject,    IN PIRPIrp    ){    NTSTATUS status = STATUS_SUCCESS;    PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);    switch(irpSp->Parameters.DeviceIoControl.IoControlCode)    {    case IOCTL_DIRECTIO_OPERATION:        // status = SomeHandlerFunction(irpSp);        break;    default:        Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;        Irp->IoStatus.Information = 0;        break;    }    status = Irp->IoStatus.Status;    IoCompleteRequest(Irp, IO_NO_INCREMENT);    return status;}VOID DIRECTIO_DriverUnload(    IN PDRIVER_OBJECTDriverObject    ){    PDEVICE_OBJECT pdoNextDeviceObj = pdoGlobalDrvObj->DeviceObject;    IoDeleteSymbolicLink(&usSymlinkName);    // Delete all the device objects    while(pdoNextDeviceObj)    {        PDEVICE_OBJECT pdoThisDeviceObj = pdoNextDeviceObj;        pdoNextDeviceObj = pdoThisDeviceObj->NextDevice;        IoDeleteDevice(pdoThisDeviceObj);    }}NTSTATUS DispatchRead(PDEVICE_OBJECT pdo,PIRP irp){NTSTATUS status = STATUS_SUCCESS;PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(irp);ULONG uReadLen = pStack->Parameters.Read.Length;ULONG uMdlLen = MmGetMdlByteCount(irp->MdlAddress);//锁定有效的缓冲区长度 bytecountULONG uMdlOffset = MmGetMdlByteOffset(irp->MdlAddress);//mdl的首地址是 StartVa,当前这段虚拟内存对于第一个页地址的偏移量PVOID pMdlAddress = MmGetMdlVirtualAddress(irp->MdlAddress);//当前虚拟内存的首地址 即 startVa+offsetif (uMdlLen != uReadLen){status = STATUS_FILE_INVALID;uReadLen = 0;}else{PVOID pKernalAddress = MmGetSystemAddressForMdlSafe(irp->MdlAddress,NormalPagePriority);//返回MDL映射的系统虚拟内存的地址memset(pKernalAddress,0xCC,uReadLen);}irp->IoStatus.Status = status;irp->IoStatus.Information = uReadLen;IoCompleteRequest(irp,IO_NO_INCREMENT);return status;}#ifdef __cplusplusextern "C" {#endifNTSTATUS DriverEntry(    IN OUT PDRIVER_OBJECT   DriverObject,    IN PUNICODE_STRING      RegistryPath    ){    PDEVICE_OBJECT pdoDeviceObj = 0;    NTSTATUS status = STATUS_UNSUCCESSFUL;    pdoGlobalDrvObj = DriverObject;    // Create the device object.    if(!NT_SUCCESS(status = IoCreateDevice(        DriverObject,        0,        &usDeviceName,        FILE_DEVICE_UNKNOWN,        FILE_DEVICE_SECURE_OPEN,        FALSE,        &pdoDeviceObj        )))    {        // Bail out (implicitly forces the driver to unload).        return status;    };pdoDeviceObj->Flags |= DO_DIRECT_IO;//设置直接读写方式    // Now create the respective symbolic link object    if(!NT_SUCCESS(status = IoCreateSymbolicLink(        &usSymlinkName,        &usDeviceName        )))    {        IoDeleteDevice(pdoDeviceObj);        return status;    }    // NOTE: You need not provide your own implementation for any major function that    //       you do not want to handle. I have seen code using DDKWizard that left the    //       *empty* dispatch routines intact. This is not necessary at all!    DriverObject->MajorFunction[IRP_MJ_CREATE] =    DriverObject->MajorFunction[IRP_MJ_CLOSE] = DIRECTIO_DispatchCreateClose;    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DIRECTIO_DispatchDeviceControl;DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;    DriverObject->DriverUnload = DIRECTIO_DriverUnload;    return STATUS_SUCCESS;}#ifdef __cplusplus}; // extern "C"#endif

测试代码:

// TestDevice.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include "TestDevice.h"#ifdef _DEBUG#define new DEBUG_NEW#endif// 唯一的应用程序对象CWinApp theApp;using namespace std;int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]){int nRetCode = 0;// 初始化 MFC 并在失败时显示错误if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)){// TODO: 更改错误代码以符合您的需要_tprintf(_T("错误: MFC 初始化失败\n"));nRetCode = 1;}else{// TODO: 在此处为应用程序的行为编写代码。}HANDLE hdl = CreateFile(L"\\\\.\\DIRECTIO_DeviceName",GENERIC_WRITE | GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);if (hdl == INVALID_HANDLE_VALUE){CString csLog;csLog.Format(L"CreateFile Error:%d",GetLastError());AfxMessageBox(csLog);return -1;}BYTE ReadArr[10]={0};DWORD dwRetLen = 0;BOOL bRetRead = ReadFile(hdl,ReadArr,10,&dwRetLen,NULL);if (bRetRead){for (int i =0;i<dwRetLen;i++){ cout<<hex<<(int)ReadArr[i]<<" ";}cout<<endl;}CloseHandle(hdl);system("PAUSE");return nRetCode;}


0 0
原创粉丝点击