2

我声明了 2 个结构:

struct irp_list {
   IRP *irp;
   LIST_ENTRY lh;
};

struct dev_info {
...
   LIST_ENTRY lh;
...
};

在 DriverWrite 函数 (IRP_MJ_WRITE) 中我这样做:

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;

在 DPC 函数中,我尝试使用以下命令访问 il 的非分页内存:

struct dev_info* di;
di = (struct dev_info*)device->DeviceExtension;

if(!IsListEmpty(&di->lh))
{
// code never reached
}

我知道 DPC 只能读取非分页内存,但为什么 !IsListEmpty 总是返回 FALSE 就好像插入失败一样?

4

1 回答 1

1

这可能不是一个正确的答案,但对于评论来说有点太复杂了,所以我把它写成一个答案,以便正确格式化等:

阅读文档InsertTailList

VOID InsertTailList(
  _Inout_  PLIST_ENTRY ListHead,
  _Inout_  PLIST_ENTRY Entry
);

InsertTailList更新ListHead->Blink指向Entry. 它更新Entry->Blink为指向列表中旧的最后一个条目,并设置Entry->FlinkListHead. 上Flink一个条目的 也更新为指向Entry

哪里IsListEmpty说:

IsListEmptyTRUE如果列表中当前没有条目,则返回,否则返回 FALSE。

评论

IsListEmptyTRUE如果返回ListHead->FlinkListHead.

现在,我不确定我是否理解所有这些,但对我来说,似乎ListHead->Flink没有更新InsertListTail(这似乎很奇怪)。虽然这句话

Flink一个条目的 也更新为指向Entry

如果它是列表中唯一的东西,可能表明它确实更新了头部。

(Gah,刚刚发现评论说你已经解决了)。

于 2013-08-25T18:08:39.953 回答