📄 readwritedevice.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 + -