#include <irp.h>
Public Types | |
enum | { LowerDriverCalled = 0x01, IrpCompleted = 0x02, IrpMarkedPending = 0x04, IoStatusSet = 0x08, IsPowerIrp = 0x10, StartNextPowerIrp = 0x20, FromDispatchThread = 0x40, ValidFlags = 0x7F } |
Public Member Functions | |
bool | IsFromQueue () |
PIO_STATUS_BLOCK | GetIoStatus () |
void * | GetSystemBuffer () |
PMDL | GetMdlAddress () |
void * | GetUserBuffer () |
NTSTATUS | GetStatus () |
void | SetIoStatus (NTSTATUS Status, unsigned Information) |
void | SetIoStatus (NTSTATUS Status) |
void | CompleteRequest (CCHAR PriorityBoost=IO_NO_INCREMENT) |
void | MarkPending () |
Private Member Functions | |
IncomingIrp (IRP *pIrp, bool bIsPowerIrp, bool bStartNextPowerIrp) | |
IncomingIrp (IRP *pIrp, long Flags) | |
~IncomingIrp () | |
Private Attributes | |
IRP * | m_pIrp |
long | m_Flags |
Friends | |
class | Device |
A typical driver uses at least 4 different strategies for processing IRPs. We'll overview them here:
The fourth strategy can also be simply implemented using IrpQueue class. See "Queueing IRPs" section below.
The IncomingIRP class allows to implement such strategies smoothly:
The layout of the IncomingIRP class produces minimal overhead (4 extra DWORDs are allocated in stack per each IRP) and allows maintaining code readability.
The BazisLib::DDK framework provides a smooth way for managing IRP queues. You should take 3 simple steps to convert a synchronous driver to queue-based one:
CreateDeviceRequestQueue();This method creates a device IRP queue and starts dispatcher thread that dequeues and processes IRPs.
NTSTATUS YourDeviceClass::DispatchRoutine(IN IncomingIrp *Irp, IO_STACK_LOCATION *IrpSp) { switch (IrpSp->MajorFunction) { case IRP_MJ_XXX: case IRP_MJ_YYY: if (!Irp->IsFromQueue()) return EnqueuePacket(Irp); break; } return __super::DispatchRoutine(Irp, IrpSp); }This ensures that all IRP_MJ_XXX and IRP_MJ_YYY IRPs will be put into queue and dispatched only in the context of the dispatcher thread.
anonymous enum |
BazisLib::DDK::IncomingIrp::IncomingIrp | ( | IRP * | pIrp, | |
bool | bIsPowerIrp, | |||
bool | bStartNextPowerIrp | |||
) | [inline, private] |
BazisLib::DDK::IncomingIrp::IncomingIrp | ( | IRP * | pIrp, | |
long | Flags | |||
) | [inline, private] |
BazisLib::DDK::IncomingIrp::~IncomingIrp | ( | ) | [inline, private] |
void BazisLib::DDK::IncomingIrp::CompleteRequest | ( | CCHAR | PriorityBoost = IO_NO_INCREMENT |
) | [inline] |
PIO_STATUS_BLOCK BazisLib::DDK::IncomingIrp::GetIoStatus | ( | ) | [inline] |
PMDL BazisLib::DDK::IncomingIrp::GetMdlAddress | ( | ) | [inline] |
NTSTATUS BazisLib::DDK::IncomingIrp::GetStatus | ( | ) | [inline] |
void* BazisLib::DDK::IncomingIrp::GetSystemBuffer | ( | ) | [inline] |
void* BazisLib::DDK::IncomingIrp::GetUserBuffer | ( | ) | [inline] |
bool BazisLib::DDK::IncomingIrp::IsFromQueue | ( | ) | [inline] |
void BazisLib::DDK::IncomingIrp::MarkPending | ( | ) | [inline] |
void BazisLib::DDK::IncomingIrp::SetIoStatus | ( | NTSTATUS | Status | ) | [inline] |
void BazisLib::DDK::IncomingIrp::SetIoStatus | ( | NTSTATUS | Status, | |
unsigned | Information | |||
) | [inline] |
friend class Device [friend] |
long BazisLib::DDK::IncomingIrp::m_Flags [private] |
IRP* BazisLib::DDK::IncomingIrp::m_pIrp [private] |