IRP.Tail.ListEntry
2023-10-13
21
0
IRP.Tail.ListEntry 用于用户自定义LIST_ENTRY使用。
如我们对IRP进行链表管理:
VOID RecycleIrp(IN PFDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp)
{
KIRQL OldLevel;
KeAcquireSpinLock(&DeviceExtension->IrpRecyledListLock, &OldLevel);
InsertTailList(&DeviceExtension->IrpRecyledListHead, &Irp->Tail.Overlay.ListEntry);
KeReleaseSpinLock(&DeviceExtension->IrpRecyledListLock, OldLevel);
}
VOID ResetIrp(IN PFDO_DEVICE_EXTENSION DeviceExtension)
{
KIRQL OldLevel;
KeAcquireSpinLock(&DeviceExtension->IrpRecyledListLock, &OldLevel);
while (!IsListEmpty(&DeviceExtension->IrpRecyledListHead))
{
PLIST_ENTRY entry = RemoveHeadList(&DeviceExtension->IrpRecyledListHead);
IRP* irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.ListEntry);
IoFreeIrp(irp);
}
KeReleaseSpinLock(&DeviceExtension->IrpRecyledListLock, OldLevel);
}
PIRP
GetIrp(
IN PFDO_DEVICE_EXTENSION DeviceExtension)
{
KIRQL OldLevel;
PIRP Irp = NULL;
PLIST_ENTRY ListEntry;
KeAcquireSpinLock(&DeviceExtension->IrpRecyledListLock, &OldLevel);
if (!IsListEmpty(&DeviceExtension->IrpRecyledListHead))
{
ListEntry = RemoveHeadList(&DeviceExtension->IrpRecyledListHead);
Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.ListEntry);
}
KeReleaseSpinLock(&DeviceExtension->IrpRecyledListLock, OldLevel);
return Irp;
}
PIRP
BuildIrp(
IN PFDO_DEVICE_EXTENSION DeviceExtension)
{
PIRP Irp;
Irp = GetIrp(DeviceExtension);
if (!Irp)
{
Irp = IoAllocateIrp(DeviceExtension->NextDeviceObject->StackSize + 1, FALSE);
if (!Irp)
{
return NULL;
}
}
else
{
IoReuseIrp(Irp, STATUS_SUCCESS);
}
return Irp;
}
IRP关于 IRP.Tail.ListEntry的结构体如下:
struct {
//
// List entry - used to queue the packet to completion queue, among
// others.
//
LIST_ENTRY ListEntry;
union {
//
// Current stack location - contains a pointer to the current
// IO_STACK_LOCATION structure in the IRP stack. This field
// should never be directly accessed by drivers. They should
// use the standard functions.
//
struct _IO_STACK_LOCATION *CurrentStackLocation;
//
// Minipacket type.
//
ULONG PacketType;
};
};
//
// Original file object - pointer to the original file object
// that was used to open the file. This field is owned by the
// I/O system and should not be used by any other drivers.
//
PFILE_OBJECT OriginalFileObject;
} Overlay;
可参考代码如下: