readwritedevice.cpp

来自「WindowsXP WDM驱动程序开发实例」· C++ 代码 · 共 259 行

CPP
259
字号
// 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) 
{
	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);

		// Allow only one request at a time	
		if ( CI != NULL )
			return I.PnpComplete(STATUS_DEVICE_BUSY);
		T << "Read\n";
		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) 
{
	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);

	CancelSpinLock::Acquire();
	if (CurrentIrp() == NULL) {
		CancelSpinLock::Release();
		return status;
	};

	KIrp Current = CurrentIrp();
	CurrentIrp() = NULL;
	if ( Current.WasCanceled() )
	{
		CancelSpinLock::Release();
		Current.PnpComplete(STATUS_CANCELLED);
		return status;
	}

	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 + =
减小字号Ctrl + -
显示快捷键?