链表是驱动开发中经常使用的数据结构,以双向循环链表为主。WDK为我们提供了一个名为LIST_ENTRY的结构体,通过它我们可以使用链表。LIST_ENTRY的定义如下:
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink; // 指向下一个节点
struct _LIST_ENTRY *Blink; // 指向前一个节点
} LIST_ENTRY, *PLIST_ENTRY;
通过定义我们发现LIST_ENTRY结构体有两个子域,分别是指向下一个和上一个节点的指针,这个和我们平时使用的循环链表的节点定义类似。
然而实际编程中仅仅依靠这个结构体是不够的,因为这个结构体中并不包含我们自己的数据。实际中我们需要自定义节点,并把该节点的一个子域(通常是第一个子域)设置为LIST_ENTRY类型的变量。举例如下:
struct MYNODE{
LIST_ENTRY ListEntry;
int data;
};
MYNODE是我们自定义的节点,其中data是我们自己的数据,ListEntry则需要加入到由LIST_ENTRY类型变量组成的链表中。换言之,真正的链表中只包含了LIST_ENTRY类型的变量,通过链表找到特定的LIST_ENTRY变量,再获得包含这个变量的我们自定义的节点,进而获得该节点中的data数据。
我们需要一个LIST_ENTRY类型的链表头,然后利用WDK为我们定义好的函数或者宏来进行后续操作:
InitializeListHead,初始化链表头
IsListEmpty,判断链表是否为空
InsertHeadList,从链表头部插入节点
InsertTailList,从链表尾部插入节点
RemoveHeadList,从链表头部删除节点
RemoveTailList,从链表尾部删除节点
CONTAINING_RECORD,由指向LIST_ENTRY类型的指针获得指向自定义节点的指针(例如上面举例的指向MYNODE类型的指针)