I have 2 structures declared:
struct irp_list {
IRP *irp;
LIST_ENTRY lh;
};
and
struct dev_info {
...
LIST_ENTRY lh;
...
};
Inside DriverWrite function (IRP_MJ_WRITE) I do:
struct irp_list *il;
struct dev_info *di = (struct dev_info*)device->DeviceExtension;
if (!(il = ExAllocatePool(NonPagedPool, sizeof(*il)))) {
ret = STATUS_NO_MEMORY;
DbgPrint("[uart] UartWrite can't handle irp...\n");
goto error;
}
il->irp = irp; // store DriverWrite irp
InsertTailList(&di->lh, &il->lh); // this insert is not failing...
irp->IoStatus.Information = 0;
IoMarkIrpPending(irp);
return STATUS_PENDING;
Inside a DPC function I try access the nonpaged memory of il with:
struct dev_info* di;
di = (struct dev_info*)device->DeviceExtension;
if(!IsListEmpty(&di->lh))
{
// code never reached
}
I know that a DPC can only read nonpaged memory, but why is !IsListEmpty always returning FALSE as if the insert failed?
This may not be a proper answer, but it's a bit too complicated for a comment, so I'm writing it as an answer, for proper formatting, etc:
Reading the docs for InsertTailList
:
VOID InsertTailList( _Inout_ PLIST_ENTRY ListHead, _Inout_ PLIST_ENTRY Entry );
InsertTailList
updatesListHead->Blink
to point toEntry
. It updatesEntry->Blink
to point to the old last entry in the list, and setsEntry->Flink
toListHead
. TheFlink
of the previous last entry is updated to point toEntry
as well.
Where IsListEmpty
says:
IsListEmpty
returnsTRUE
if there are currently no entries in the list and FALSE otherwise.Remarks
IsListEmpty
returnsTRUE
ifListHead->Flink
refers back toListHead
.
Now, I'm not sure if I understand all of this, but to me, it seems like ListHead->Flink
is not updated by InsertListTail
(which seems rather strange). Although the sentence
The
Flink
of the previous last entry is updated to point toEntry
as well.
may indicate that it does indeed update the head if it's the only thing in the list.
(Gah, just spotted the comment saying you've solved it).