LIST_ENTRY和DPC计时器促进学习
应用单链表
单链表是驱动开发中经常遇到的算法设计,通常是双循环链表;需要单链表,需要LIST_ENTRY结构,概念如下:
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink; // 偏向下一个节点
struct _LIST_ENTRY *Blink; // 偏向前一个节点
} LIST_ENTRY, *PLIST_ENTRY;
在具体的编程中,我们应该定义自己的单链表节点,然后将节点的第一组成员设置为LIST_ENTRY类别的自变量(不一定是第一个,但通常是这样);除此之外,还需要LIST_ENTRY类单链表头;其他的都是靠下面的函数或宏操作的:
InitializeListHead,单链表头复位
IsListEmpty,区分单链表是否为空
InsertHeadList,将节点插入单链表头顶部
InsertTailList,将节点插入单链表末端
RemoveHeadList,节点从单链表头顶部删除
RemoveTailList,节点从单链表尾删除
CONTAINING_RECORD,从RemoveHeadList或Removetaillist返回数据,收集偏向于删除节点的表针
实例编码:
typedef struct _LIST_NODE
{
LIST_ENTRY ListEntry;
ULONG ulData;
} LIST_NODE, *PLIST_NODE;
VOID LinkListTest()
{
LIST_ENTRY listHead;
PLIST_NODE pListNode = NULL;
ULONG i = 0;
InitializeListHead(&listHead);
DebugPrint(("Begin insert to link list
"));
for (i = 0; i < 10; i)
{
pListNode = (PLIST_NODE)
ExAllocatePool(PagedPool, sizeof(LIST_NODE));
pListNode->ulData = i;
InsertHeadList(&listHead, &pListNode->ListEntry);
}
DebugPrint(("Begin remove from link list
"));
while (!IsListEmpty(&listHead))
{
PLIST_ENTRY pEntry = RemoveTailList(&listHead);
pListNode = CONTAINING_RECORD(pEntry,
LIST_NODE,
ListEntry);
DebugPrint(("Delete Node's Value: %d
", pListNode->ulData));
ExFreePool(pListNode);
}
}
应用DPC计时器
DPC计时器可以按时进行任意间隔,DPC计时器内部使用计时器目标KTIMER。在我们为计时器设置一个长间间隔后,计算机操作系统将DPC方法插入DPC序列。当计算机操作系统输入DPC序列时,强制执行相应的DPC方法。一些常用于DPC计时器的函数公式: