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

驱动代码:

///
///
/// Copyright (c) 2014 - <company name here>
///
/// Original filename: BufferIO.cpp
/// Project          : BufferIO
/// Date of creation : 2014-06-23
/// Author(s)        : <author name(s)>
///
/// Purpose          : <description>
///
/// Revisions:
///  0000 [2014-06-23] Initial revision.
///
///

// $Id$

#ifdef __cplusplus
extern "C" {
#endif
#include <ntddk.h>
#include <string.h>
#ifdef __cplusplus
}; // extern "C"
#endif

#include "BufferIO.h"



typedef struct _DEVICE_EXTENSION{

	PDEVICE_OBJECT pDevice;
	UNICODE_STRING usDeviceName;
	UNICODE_STRING usSymLinkName;

	PUCHAR buffer;
	ULONG uFileLen; // must low MAX_FILE_LENGTH
}DEVICE_EXTENSION,*PDEVICE_EXTENSION;



#define MAX_FILE_LENGTH 1024

#ifdef __cplusplus
namespace { // anonymous namespace to limit the scope of this global variable!
#endif
PDRIVER_OBJECT pdoGlobalDrvObj = 0;
#ifdef __cplusplus
}; // anonymous namespace
#endif

NTSTATUS BUFFERIO_DispatchCreateClose(
    IN PDEVICE_OBJECT		DeviceObject,
    IN PIRP					Irp
    )
{
    NTSTATUS status = STATUS_SUCCESS;

	PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(Irp);

	if (pStack->MajorFunction == IRP_MJ_CREATE)
	{
		KdPrint(("DispatchCreate...."));

	}else if (pStack->MajorFunction == IRP_MJ_CLOSE)
	{
		KdPrint(("DispatchClose...."));
	}



    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);


    return status;
}

NTSTATUS BUFFERIO_DispatchDeviceControl(
    IN PDEVICE_OBJECT		DeviceObject,
    IN PIRP					Irp
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);

    switch(irpSp->Parameters.DeviceIoControl.IoControlCode)
    {
    case IOCTL_BUFFERIO_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);


	KdPrint(("DispatchDeviceControl...."));

    return status;
}

VOID BUFFERIO_DriverUnload(
    IN PDRIVER_OBJECT		DriverObject
    )
{

	KdPrint(("DriverUnload...."));
    PDEVICE_OBJECT pdoNextDeviceObj = pdoGlobalDrvObj->DeviceObject;

    // Delete all the device objects
    while(pdoNextDeviceObj)
    {
	

		//释放扩展设备结构
		PDEVICE_EXTENSION pDevExten = (PDEVICE_EXTENSION)pdoNextDeviceObj->DeviceExtension;
		if (pDevExten->buffer)
		{
			ExFreePool(pDevExten->buffer);
			pDevExten->buffer = NULL;
		}

		UNICODE_STRING usSymLinkName = pDevExten->usSymLinkName;
		IoDeleteSymbolicLink(&usSymLinkName);
        IoDeleteDevice(pDevExten->pDevice);


		pdoNextDeviceObj = pdoNextDeviceObj->NextDevice;

    }
}


NTSTATUS BufferID_DispathcRead(PDEVICE_OBJECT pdo,PIRP pIrp)
{
	NTSTATUS status = STATUS_SUCCESS;

	PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
	PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pdo->DeviceExtension;
	ULONG uReadLen = pStack->Parameters.Read.Length;
	ULONG uOffset = (ULONG)pStack->Parameters.Read.ByteOffset.QuadPart;
	
	if (uReadLen + uOffset> MAX_FILE_LENGTH )
	{
		uReadLen =0;
		status = STATUS_FILE_INVALID;

	}else
	{
		memcpy(pIrp->AssociatedIrp.SystemBuffer,pDevExt->buffer+uOffset,uReadLen);
		status = STATUS_SUCCESS;
		
	}

	pIrp->IoStatus.Status = status;
	pIrp->IoStatus.Information = uReadLen;

	IoCompleteRequest(pIrp,IO_NO_INCREMENT);

	KdPrint(("BufferID_DispathcRead...."));

	return status;
}


NTSTATUS BufferID_DispatchWrtie(PDEVICE_OBJECT pdo,PIRP irp)
{
	NTSTATUS status = STATUS_SUCCESS;

	PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(irp);
	ULONG uWriteLen = pStack->Parameters.Write.Length;

	PDEVICE_EXTENSION pDecExt = (PDEVICE_EXTENSION)pdo->DeviceExtension;
	ULONG uOffset = (ULONG)pStack->Parameters.Write.ByteOffset.QuadPart;//文件存储的偏移量,理解为当前文件指针所在位置
	if (uOffset+uWriteLen > MAX_FILE_LENGTH)
	{
		status = STATUS_FILE_INVALID;
		uWriteLen =0;
	}else
	{
		memcpy(pDecExt->buffer+uOffset,irp->AssociatedIrp.SystemBuffer,uWriteLen);
		status = STATUS_SUCCESS;
		if (uWriteLen + uOffset > pDecExt->uFileLen)
		{
			pDecExt->uFileLen = uWriteLen+uOffset;
		}
	}


	
	irp->IoStatus.Information = uWriteLen;
	irp->IoStatus.Status = status;

	IoCompleteRequest(irp,IO_NO_INCREMENT);

	KdPrint(("BufferID_DispatchWrtie...."));

	return status;

}


NTSTATUS BufferID_DispatchQUERYINFORMATION(PDEVICE_OBJECT pdo,PIRP irp)
{
	NTSTATUS status = STATUS_SUCCESS;
	PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(irp);
	PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pdo->DeviceExtension;

	FILE_INFORMATION_CLASS FileInfo = pStack->Parameters.QueryFile.FileInformationClass;

	//需要先判断查询的类别FILE_INFORMATION_CLASS 
	if (FileInfo == FileStandardInformation)
	{
		PFILE_STANDARD_INFORMATION pFSinfo = (PFILE_STANDARD_INFORMATION)irp->AssociatedIrp.SystemBuffer;//获取缓冲区指针
		pFSinfo->EndOfFile = RtlConvertLongToLargeInteger(pDevExt->uFileLen);//将查询的结果保存在此处缓冲区
	}

	status =STATUS_SUCCESS;

	irp->IoStatus.Information = pStack->Parameters.QueryFile.Length;//设置返回数据的长度
	irp->IoStatus.Status = status;

	IoCompleteRequest(irp,IO_NO_INCREMENT);

	KdPrint(("BufferID_DispatchQUERYINFORMATION..."));

	return status;
}


#ifdef __cplusplus
extern "C" {
#endif
NTSTATUS DriverEntry(
    IN OUT PDRIVER_OBJECT   DriverObject,
    IN PUNICODE_STRING      RegistryPath
    )
{
    PDEVICE_OBJECT pdoDeviceObj = 0;
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    pdoGlobalDrvObj = DriverObject;
	PDEVICE_EXTENSION pDevExt;

    // Create the device object.
    if(!NT_SUCCESS(status = IoCreateDevice(
        DriverObject,
        sizeof(DEVICE_EXTENSION),//0,
        &usDeviceName,
        FILE_DEVICE_UNKNOWN,
        FILE_DEVICE_SECURE_OPEN,
        FALSE,
        &pdoDeviceObj
        )))
    {
        // Bail out (implicitly forces the driver to unload).
        return status;
    };

	pdoDeviceObj->Flags |= DO_BUFFERED_IO;//设置缓冲读写方式


	//初始化扩展设备
	pDevExt = (PDEVICE_EXTENSION)pdoDeviceObj->DeviceExtension;
	pDevExt->pDevice = pdoDeviceObj;
	pDevExt->usDeviceName = usDeviceName;
	pDevExt->usSymLinkName = usSymlinkName;
	pDevExt->buffer = (PUCHAR)ExAllocatePool(PagedPool,MAX_FILE_LENGTH);
	pDevExt->uFileLen = 0;


    // 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] = BUFFERIO_DispatchCreateClose;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = BUFFERIO_DispatchDeviceControl;
	DriverObject->MajorFunction[IRP_MJ_READ] = BufferID_DispathcRead;
	DriverObject->MajorFunction[IRP_MJ_WRITE] = BufferID_DispatchWrtie;
	DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = BufferID_DispatchQUERYINFORMATION;
    
	DriverObject->DriverUnload = BUFFERIO_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"\\\\.\\BUFFERIO_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 WrtieArr[10]={0};

	for (int i=0;i<10;i++)
	{
		WrtieArr[i] = 0xDD;
	}

	DWORD dwWritenLen = 0;
	BOOL bRetWrite = WriteFile(hdl,WrtieArr,10,&dwWritenLen,NULL);
	if (!bRetWrite)
	{
		CString csLog;
		csLog.Format(L"WriteFile 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]<<" ";
			//printf("0x%x ",bArr[i]);
		}

		cout<<endl;
	}

	
	CloseHandle(hdl);

	system("PAUSE");

	return nRetCode;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值