DDK提供了两种链表的数据结构,双向链表和单向链表,其定义如下:
typedef struct _LIST_ENTRY
{
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY,*PLIST_ENTRY;
typedef struct _SINGLE_LIST_ENTRY {
struct _SINGLE_LIST_ENTRY *Next;
} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
一.双向链表LIST_ENTRY
这个结构不能直接存进我们要的数据,如果要把我们的数据存进链表的结构里,需要重新定义一个结构体,结构体里必须要包括一个LIST_ENTRY类型的成员,这个成员可以放在结构体里的任何位置,如:
typedef struct _list
{
LIST_ENTRY List;
ULONG data;
} Node,*PNode;
或者:
typedef struct _list
{
ULONG data;
LIST_ENTRY List;
} Node,*PNode;
在使用链表时要定义一个链表头并初始化,其类型为LIST_ENTRY,
1.初始化链表函数为InitializeListHead(PLIST_ENTRY pListHeader);
2.插入链表函数
InsertHeadList(
PLIST_ENTRY pListHeader, //链头
PLIST_ENTRY MyListEntry); //结构体中的LIST_ENTRY类型的成员变量地址
这个函数是在链表的开头插入一个结点,第一个参数是链头,第二个参数也是一个PLIST_ENTRY类型,是我们自己定义的结构体中的LIST_ENTRY类型的成员变量地址。类似的还有从尾部插入链表函数InsertTailList,参数与InsertHeadList一致。
3.从链表删除结点
函数RemoveTailList(PLIST_ENTRY pListHeader)把链表的最后的结点删除,返回删除的结点的指针。
函数RemoveHeadList(PLIST_ENTRY pListHeader)把链表的第一个结点删除,返回删除的结点的指针。
一.单向链表SINGLE_LIST_ENTRY
1.初始化链表函数为InitializeListHead(PLIST_ENTRY pListHeader),与双向链表相同。
2.插入链表函数
FORCEINLINE
VOID
PushEntryList( //从头部插入,成为第一个结点
_Inout_ PSINGLE_LIST_ENTRY ListHead, //链头
_Inout_ __drv_aliasesMem PSINGLE_LIST_ENTRY Entry //结构体中的LIST_ENTRY类型的成员变量地址
)
{
Entry->Next = ListHead->Next;
ListHead->Next = Entry;
return;
}
3.从链表删除结点
FORCEINLINE
PSINGLE_LIST_ENTRY
PopEntryList( //从链表头下一个删除节点,删除第一个结点
_Inout_ PSINGLE_LIST_ENTRY ListHead //链头
)
{
PSINGLE_LIST_ENTRY FirstEntry;
FirstEntry = ListHead->Next;
if (FirstEntry != NULL) {
ListHead->Next = FirstEntry->Next;
}
return FirstEntry;
}
//bp ListEntry!DriverEntry NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
{
NTSTATUS Status = STATUS_SUCCESS;
PDEVICE_OBJECT DeviceObject = NULL;
DriverObject->DriverUnload = DriverUnload; SeListEntry();
SeSingleListEntry();
return Status;
}
VOID SeListEntry()
{
LIST_ENTRY ListHead;
PITEM Item = NULL;
ULONG i = 0;
//初始化链表
InitializeListHead(&ListHead);
for (i = 0; i < 10; i++)
{
Item = (PITEM)
ExAllocatePool(PagedPool, sizeof(ITEM));
Item->ItemData = i;
InsertHeadList(&ListHead, &Item->u.ListEntry);
}
while (!IsListEmpty(&ListHead))
{
PLIST_ENTRY ListEntry = RemoveTailList(&ListHead); KdPrint(("%d\n", ((PITEM)ListEntry)->ItemData));
ExFreePool((PITEM)ListEntry);
}
}
VOID SeSingleListEntry()
{
SINGLE_LIST_ENTRY ListHead;
PITEM Item = NULL;
ULONG i = 0;
//初始化链表
InitializeListHead(&ListHead);
for (i = 0; i < 10; i++)
{
Item = (PITEM)
ExAllocatePool(PagedPool, sizeof(ITEM));
Item->ItemData = i;
PushEntryList(&ListHead, &Item->u.SingleListEntry);
}
while (!IsListEmpty(&ListHead))
{
PSINGLE_LIST_ENTRY ListEntry = PopEntryList(&ListHead); KdPrint(("%d\n", ((PITEM)ListEntry)->ItemData));
ExFreePool((PITEM)ListEntry);
}
} VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
DbgPrint("DriverUnload()\r\n");
}