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内核编程]>
也加入了自己对这个概念的理解。
------------------------------接着秀 一张 模板----------------------------------