LIST_ENTRY 是一个双向链表结构。它总是在使用的时候被插入到已有的数据结构中。Windows内核中使用LIST_ENTRY作为i链表,这个结构随处可见。
看看下面的代码,构建了一个链表,每个节点是又一个文件名和一个文件大小两个数据成员组成的结构。此外有一个FILE_OBJECT指针对象,在驱动中代表一个文件对象。该链表的作用是保存了文件的文件长度和文件名。
typedef struct{ LIST_ENTRY list_Entry, PFILE_OBJECT file_Object, UNICODE_STRING file_Name, LARGE_INTEGER file_Length }MY_FILE_INFO, *PMY_FILE_INFO;请注意:这个结构体中多了一个 LIST_ENTRY list_Entry,这样做是为了保证节点插入的位置无所谓。可以将待插入的节点放在任何位置。
LIST_ENTRY 如果是作为链表的头,在使用之前,必须调用InitializeListHead 来初始化。比如像下面这样:
///----链表头 LIST_ENTRY my_List_Head; ///---链表头初始化,一般地应该在程序入口处调用一下 void MyFileInfoInit() { InitializeListHead(&my_List_Head); } ///---节点:文件长度和文件名 typedef struct{ LIST_ENTRY list_Entry, PFILE_OBJECT file_Object, UNICODE_STRING file_Name, LARGE_INTEGER file_Length }MY_FILE_INFO, *PMY_FILE_INFO; ///---追加一条信息。也就是增加一个链表节点,请注意file_name是外面分配的 ///---内存由使用者管理,该链表不用管理它 NTSTATUS MyFileInfoAppendNode( PFILE_OBJECT file_Object, PUNICODE_STRING file_Name, PLARGE_INTEGER file_Length ) { PMY_FILE_INFO my_File_Info = (PMY_FILE_INFO)ExAllocatePoolWithTag( PagePool, sizeof(MY_FILE_INFO), MEM_TAG); if (NULL == my_File_Info) { return STATUS_INSUFFICIENT_RESOURES; } ///----填写数据成员 my_File_Info->file_Object = file_Object; my_File_Info->file_Name = file_Name; my_File_Info->file_Length = file_Length; ///---插入到链表尾,请注意这里没有使用任何锁,所以这个函数不是多线程安全的, InsertHeadList(&my_List_Head, (PLIST_ENTRY)&my_File_Info); return STATUS_SUCCESS; }上面的代码实现了插入。
下面是的代码,是关于计算LIST_ENTRY结构体的所在节点的地址的一个示例。
for (p = my_List_Head.Flink; p != &my_List_Head.Flink; p = p->Flink) { PMY_FILE_INFO elem = CONTAINTING_RECORD(p, MY_FILE_INFO, list_Entry); }CONTAINTING_RECORED是一个 WDK中已经定义的宏,作用是通过一个 LIST_ENTRY结构的指针找到这个结构体所在的节点的指针,定义如下:
PCHAR CONTAINING_RECORD( [in] PCHAR Address, [in] TYPE Type, [in] PCHAR Field );--------------------------------------------------------------------------
LIST_ENTRY中的数据成员Flink指向下一个LIST_ENTRY。整个链表的最后一个LIST_ENTRY的Flink不是空, 而是指向头节点(我下面使用红色标记出来啦):
for (p = my_List_Head.Flink; p != &my_List_Head.Flink;p = p->Flink)
{
///----do something
}
得到LIST_ENTRY之后,要用CONTAINTING_RECORD来得到链表节点中的数据。
------摘自<[天书夜读-从汇编到Windows内核编程]>
也加入了自己对这个概念的理解。
------------------------------接着秀 一张 模板----------------------------------