栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

5.Windows驱动开发链表常用函数

5.Windows驱动开发链表常用函数

目录

0.驱动开发链表常用函数

1.代码示例

.使用驱动函数操作双向链表"><1>.使用驱动函数操作双向链表

.示例<1>实现原理"><2>.示例<1>实现原理

.结构体成员相对偏移计算(拓展)"><3>.结构体成员相对偏移计算(拓展)


0.驱动开发链表常用函数

IsListEmpty          判断链表是否为空 官方文档

InitializeListHead  初始化双向链表头 官方文档

InsertHeadList      插入链表头部 官方文档

InsertTailList         插入链表尾部 官方文档

RemoveHeadList  移除头部节点 官方文档

RemoveTailList     移除尾部节点 官方文档 

RemoveEntryList  移除当前节点 官方文档

1.代码示例

<1>.使用驱动函数操作双向链表
#include 

typedef struct _TEST
{
    ULONG uIndex;
    ULONG UTemp;
    LIST_ENTRY node;

}TEST,*PTEST;

NTSTATUS DriverUnload(PDRIVER_OBJECT pDriver)
{
    DbgPrint("Driver Unloadrn");
}

VOID TestList()
{
    DbgBreakPoint();

    //测试结构
    TEST Test[5] = { 0 };
    for (size_t i = 0; i < sizeof(Test) / sizeof(Test[0]); i++)
    {
        Test[i].UTemp = i;
        Test[i].uIndex = i;
    }

    //初始化链表
    InitializeListHead(&Test[0].node);

    //判断链表是否为空
    if (IsListEmpty(&Test[0].node))
    {
        DbgPrint("ListEmpty rn");
    }

    //链表头部插入
    InsertHeadList(&Test[0].node, &Test[1].node);
    InsertHeadList(&Test[0].node, &Test[2].node);

    //链表尾部插入
    InsertTailList(&Test[0].node, &Test[3].node);
    InsertTailList(&Test[0].node, &Test[4].node);
   
    //删除头部链表
    RemoveHeadList(&Test[0].node);

    //删除尾部链表
    RemoveTailList(&Test[0].node);

    //删除当前链表
    RemoveEntryList(&Test[0].node);

}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
    DbgPrint("Driver Load rn");

    TestList();

    //IRP
    pDriver->DriverUnload = DriverUnload;

    return STATUS_SUCCESS;
}

1).执行初始化函数前

2).初始化函数执行后

Test[0].node.Blink = Test[0].node.Flink = &Test[0].node;

3).头部继续插入节点

当头节点上下节点都指向自身时

Test[0].node.Blink = Test[0].node.Flink = &Test[1].node;

Test[1].node.Blink = Test[1].node.Flink = &Test[0].node;

4).头部继续插入节点

Test[0].node.Flink = &Test[2].node;

Test[2].node.Blink = &Test[0].node;

Test[2].node.Flink = &Test[1].node;

Test[1].node.Blink = &Test[2].node;

5).尾部继续插入节点

Test[3].node.Flink = &Test[0].node;

Test[3].node.Blink = Test[0].node.Blink;

Test[0].node.Blink->Flink = &Test[3].node;

Test[0].node.Blink = &Test[3].node;

6).尾部继续插入节点

Test[4].node.Flink = &Test[0].node;

Test[4].node.Blink = Test[0].node.Blink;

Test[0].node.Blink->Flink = &Test[4].node;

Test[0].node.Blink = &Test[4].node;

7).头部删除节点

Test[0].node.Flink->Flink->Blink = Test[0].node.Flink->Blink;

Test[0].node.Flink->Blink->Flink = Test[0].node.Flink->Flink;

8).尾部删除节点

Test[0].node.Blink->Blink->Flink = &Test[0].node;

Test[0].node.Blink = Test[0].node.Blink->Blink;

9).移除当前节点

Test[0].node.Flink->Blink = Test[0].node.Blink;

Test[0].node.Blink->Flink = Test[0].node.Flink;

<2>.示例<1>实现原理
#include 

typedef struct _TEST
{
    ULONG uIndex;
    ULONG UTemp;
    LIST_ENTRY node;

}TEST,*PTEST;

NTSTATUS DriverUnload(PDRIVER_OBJECT pDriver)
{
    DbgPrint("Driver Unloadrn");
}

VOID TestList()
{
    DbgBreakPoint();

    //测试结构
    TEST Test[5] = { 0 };
    for (size_t i = 0; i < sizeof(Test) / sizeof(Test[0]); i++)
    {
        Test[i].UTemp = i;
        Test[i].uIndex = i;
    }

    //初始化链表
    Test[0].node.Blink = Test[0].node.Flink = &Test[0].node;

    //链表头部插入
    Test[0].node.Blink = Test[0].node.Flink = &Test[1].node;
    Test[1].node.Blink = Test[1].node.Flink = &Test[0].node;

    Test[0].node.Flink = &Test[2].node;
    Test[2].node.Blink = &Test[0].node;
    Test[2].node.Flink = &Test[1].node;
    Test[1].node.Blink = &Test[2].node;

    //链表尾部插入
    Test[3].node.Flink = &Test[0].node;
    Test[3].node.Blink = Test[0].node.Blink;
    Test[0].node.Blink->Flink = &Test[3].node;
    Test[0].node.Blink = &Test[3].node;

    Test[4].node.Flink = &Test[0].node;
    Test[4].node.Blink = Test[0].node.Blink;
    Test[0].node.Blink->Flink = &Test[4].node;
    Test[0].node.Blink = &Test[4].node;
   
    //删除头部链表
    Test[0].node.Flink->Flink->Blink = Test[0].node.Flink->Blink;
    Test[0].node.Flink->Blink->Flink = Test[0].node.Flink->Flink;

    //删除尾部链表
    Test[0].node.Blink->Blink->Flink = &Test[0].node;
    Test[0].node.Blink = Test[0].node.Blink->Blink;

    //删除当前链表
    Test[0].node.Flink->Blink = Test[0].node.Blink;
    Test[0].node.Blink->Flink = Test[0].node.Flink;

}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
    DbgPrint("Driver Load rn");
    
    TestList();

    //IRP
    pDriver->DriverUnload = DriverUnload;

    return STATUS_SUCCESS;
}

<3>.结构体成员相对偏移计算(拓展)

假设获取到结构体中链表指向且链表不是结构体首个成员时可使用下面代码获取结构体头部

#include 
#include 

typedef struct _LIST
{
  UCHAR uchar;
  ULONG ulong;
  PLIST_ENTRY node;

}LIST, * PLIST;

int main()
{
  LIST List = { 0 };

  //获取成员相对于结构体首地址偏移
  //OFFSET = 结构成员偏移 - 结构体首地址
  ULONG u = (ULONG)&List.node - (ULONG)&List.uchar;

  //CONTAINING_RECORD指回结构体头部
  PLIST p1 = CONTAINING_RECORd(&List.node, _LIST, node);

  //实现原理
  //获取结构成员当前内存地址
  ULONG ptr = (ULONG)&List.node;

  //&((_LIST*)0)->node 此步骤为结构体成员偏移量
  ULONG off = (ULONG)(&((_LIST*)0)->node);
  p1 = (PLIST)(ptr - off);

  return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/285995.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号