⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readwritedevice.cpp

📁 windows 2000/xpWDM设备驱动程序开发光盘代码
💻 CPP
字号:
// ReadWriteDevice.cpp
// Implementation of ReadWriteDevice device class
//
// Generated by DriverWizard version DriverStudio 2.6.0 (Build 336)
// Requires Compuware's DriverWorks classes
//

#pragma warning(disable:4065) // Allow switch statement with no cases
		  
#include <vdw.h>
#include "..\ReadWriteDeviceinterface.h"

#include "ReadWrite.h"
#include "ReadWriteDevice.h"

#pragma hdrstop("ReadWrite.pch")

KTrace T("ReadWrite");

GUID ReadWriteDevice_Guid = ReadWriteDevice_CLASS_GUID;

ReadWriteDevice::ReadWriteDevice(PDEVICE_OBJECT Pdo, ULONG Unit) :
	KPnpDevice(Pdo, &ReadWriteDevice_Guid)
{

	// Check constructor status
    if ( ! NT_SUCCESS(m_ConstructorStatus) )
	{
	    return;
	}

	// Remember our unit number
	m_Unit = Unit;

	// Initialize the lower device
	m_Lower.Initialize(this, Pdo);

    // Inform the base class of the lower edge device object
	SetLowerDevice(&m_Lower);

	// Initialize the PnP Policy settings to the "standard" policy
	SetPnpPolicy();

// TODO:	Customize the PnP Policy for this device by setting
//			flags in m_Policies.
	CurrentIrp() = NULL;

}

ReadWriteDevice::~ReadWriteDevice()
{
	MY_LIST_ENTRY* pMyEntry;
	PUCHAR	pMyBuffer;
	while (m_List.Count() > 0)
	{	//删除队列中尚未显示的信息
		pMyEntry = m_List.RemoveHead();
		pMyBuffer = pMyEntry->Info;

		delete(pMyEntry);
		delete(pMyBuffer);
	}
}

NTSTATUS ReadWriteDevice::DefaultPnp(KIrp I) 
{
	I.ForceReuseOfCurrentStackLocationInCalldown();
	return m_Lower.PnpCall(this, I);
}

NTSTATUS ReadWriteDevice::DefaultPower(KIrp I) 
{
	I.IndicatePowerIrpProcessed();
	I.CopyParametersDown();
	return m_Lower.PnpPowerCall(this, I);
}

NTSTATUS ReadWriteDevice::SystemControl(KIrp I) 
{
	I.ForceReuseOfCurrentStackLocationInCalldown();
	return m_Lower.PnpCall(this, I);
}

NTSTATUS ReadWriteDevice::OnStartDevice(KIrp I)
{
	return STATUS_SUCCESS;
}

NTSTATUS ReadWriteDevice::OnStopDevice(KIrp I)
{
	return STATUS_SUCCESS;
}

NTSTATUS ReadWriteDevice::OnRemoveDevice(KIrp I)
{
	return STATUS_SUCCESS;
}

NTSTATUS ReadWriteDevice::Create(KIrp I)
{
	NTSTATUS status;

	status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);

	return status;
}

NTSTATUS ReadWriteDevice::Close(KIrp I)
{
	NTSTATUS status;

	status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);

    return status;
}

NTSTATUS ReadWriteDevice::Read(KIrp I) 
{	//对应应用程序DPMonitor的读请求
	if (I.ReadSize() == 0)
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_SUCCESS);
	}
	if (m_List.Count()==0) {//如果显示队列空
		PVOID CI = InterlockedCompareExchangePointer( (PVOID*)&CurrentIrp(), PVOID( PIRP(I)), NULL);
		//若CurrentIrp空,则将读IRP保存在CurrentIrp中,否则读失败
		// Allow only one request at a time	
		if ( CI != NULL )
			return I.PnpComplete(STATUS_DEVICE_BUSY);
		T << "Read\n";

		//读IRP设置取消例程
		CancelSpinLock::Acquire();
		if ( I.WasCanceled() )
		{
			CurrentIrp() = NULL;
			CancelSpinLock::Release();
			return I.PnpComplete(STATUS_CANCELLED);
		}

		I.SetCancelRoutine( LinkTo(Cancel) );
		CancelSpinLock::Release();
		I.MarkPending();
		return STATUS_PENDING;
	}

	//下面是显示队列有信息的执行情况
	PUCHAR	pBuffer		= (PUCHAR) I.BufferedReadDest();
	ULONG   dwTotalSize = I.ReadSize(CURRENT);	// Requested read size

	//从队列中取出头信息
	MY_LIST_ENTRY* pMyEntry = m_List.RemoveHead();
	PUCHAR	pMyBuffer = pMyEntry->Info;
	ULONG   dwBytesRead = pMyEntry->Len;
	//拷贝输出信息
	if ( dwTotalSize>=dwBytesRead )
	{
		RtlCopyMemory(pBuffer,pMyBuffer,dwBytesRead);
	}
	else
	{
		dwBytesRead=dwTotalSize;
		RtlCopyMemory(pBuffer,pMyBuffer,dwBytesRead);
	}

	delete(pMyEntry);
	delete(pMyBuffer);

	I.Information() = dwBytesRead;
	return I.PnpComplete(this, STATUS_SUCCESS);
}

NTSTATUS ReadWriteDevice::Write(KIrp I) 
{	//对应其它驱动程序(如FileThread)的写请求
	NTSTATUS status;

	PUCHAR	pBuffer	= (PUCHAR)I.BufferedWriteSource();
	ULONG   dwTotalSize = I.WriteSize(CURRENT);
	// Always ok to write 0 elements
	if (dwTotalSize == 0)
	{
		I.Information() = 0;
		return I.PnpComplete(STATUS_SUCCESS);
	}

	//创建队列信息和内存
	MY_LIST_ENTRY* pMyEntry = new (NonPagedPool) MY_LIST_ENTRY;
	if ( !pMyEntry )
	{
		I.Information() = 0;
		return I.PnpComplete(STATUS_INSUFFICIENT_RESOURCES);
	}
	PUCHAR pMyBuffer = new (NonPagedPool) UCHAR[dwTotalSize];
	if ( !pMyBuffer )
	{
		delete(pMyEntry);
		I.Information() = 0;
		return I.PnpComplete(STATUS_INSUFFICIENT_RESOURCES);
	}
	RtlCopyMemory(pMyBuffer,pBuffer,dwTotalSize); //拷贝显示信息
	pMyEntry->Info=pMyBuffer;
	pMyEntry->Len=dwTotalSize;
	m_List.InsertTail(pMyEntry); 	//将信息插入队列尾
	I.Information() = dwTotalSize;
	status = I.PnpComplete(STATUS_SUCCESS);

	//下面是有无读IRP的处理情况
	CancelSpinLock::Acquire();

	if (CurrentIrp() == NULL) {	//无读IRP
		CancelSpinLock::Release();
		return status;
	};

	KIrp Current = CurrentIrp();
	CurrentIrp() = NULL;
	if ( Current.WasCanceled() )
	{	//读IRP已取消
		CancelSpinLock::Release();
		Current.PnpComplete(STATUS_CANCELLED);
		return status;
	}

	//读IRP存在,置取消例程为空
	Current.SetCancelRoutine(NULL);
	CancelSpinLock::Release();

	pBuffer		= (PUCHAR) Current.BufferedReadDest();
	dwTotalSize = Current.ReadSize(CURRENT);	// Requested read size

	pMyEntry = m_List.RemoveHead();	//从队列中取出头信息
	pMyBuffer = pMyEntry->Info;
	ULONG   dwBytesRead = pMyEntry->Len;
	//拷贝输出信息
	if ( dwTotalSize>=dwBytesRead )
	{
		RtlCopyMemory(pBuffer,pMyBuffer,dwBytesRead);
	}
	else
	{
		dwBytesRead=dwTotalSize;
		RtlCopyMemory(pBuffer,pMyBuffer,dwBytesRead);
	}

	//删除队列信息和内存
	delete(pMyEntry);
	delete(pMyBuffer);

	Current.Information() = dwBytesRead;
	Current.PnpComplete(STATUS_SUCCESS);

	return status;
}

VOID ReadWriteDevice::Cancel(KIrp I)
{
	T << "Cancel\n";
	if ( (PIRP)I == CurrentIrp() )
	{
		T << "CancelCurrentIrp\n";
		CurrentIrp() = NULL;
		CancelSpinLock::Release(I.CancelIrql());
		I.Information() = 0;
		I.PnpComplete(STATUS_CANCELLED);
	}
	else
		CancelSpinLock::Release(I.CancelIrql());
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -