创建虚拟设备(直接读写方式)-模拟文件读操作
来源:互联网 发布: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
- 创建虚拟设备(直接读写方式)-模拟文件读操作
- 创建虚拟设备(缓冲读写方式)-模拟文件读写操作
- 直接读写设备文件
- 设备读写 之 直接方式(Direct I/O)
- 文件创建、读写操作
- 应用程序读设备(直接方式)
- 驱动开发之 设备读写方式:直接方式
- GPIO设备虚拟文件结点的创建
- GPIO设备虚拟文件结点的创建
- GPIO设备虚拟文件结点的创建
- 通过文件的方式对硬盘扇区进行直接读写操作
- zz: 设备读写 之 直接方式(Direct I/O)MmGetMdlByteCount/MmGetMdlByteOffset/MmGetMdlVirtualAddress
- 文件操作-----图解文件的读写方式
- 在Solaris 文件系统上模拟测试ASM-(OS文件转化为虚拟设备)
- 直接方式读写
- Android数据存储方式(一)文件读写操作
- linux C复习:文件操作(创建、打开、读写)
- 创建 Android虚拟设备(AVD)
- Win7系统建立并开启Wifi热点的bat批处理
- zTree简单配置实例
- OCP-1Z0-051 补充题库 第24题 SYNONYM同义词
- zTree应用实例详讲(3)
- Android设置WebView背景透明
- 创建虚拟设备(直接读写方式)-模拟文件读操作
- c语言链表操作
- IOS Socket使用大全
- VC++ 6.0 File->open 时候,VC崩溃
- 手动生成Qt的moc文件的方法
- 火烧赤壁的故事
- SmartFoxServer搭建多人在线游戏技术方案
- HDU4366 Successor
- ACdreamoj 1011(树状数组维护字符串hash前缀和)