zoukankan      html  css  js  c++  java
  • [内核驱动] 链表LIST_ENTRY的操作(转)

    转载:https://www.cnblogs.com/forlina/archive/2011/08/11/2134610.html

    转载:http://www.xuebuyuan.com/1544347.html

    转载:http://blog.chinaunix.net/uid-24789420-id-3045264.html

    转载:https://www.cnblogs.com/nbsofer/archive/2013/02/25/2931980.html(☆)

     遍历:

    //list_entry.c
    #include <ntddk.h>
    
    
    //我的自定义数据类型,包含LIST_ENTRY结构体
    typedef struct{
        int num;
        LIST_ENTRY list;
    }MY_DATA,*PMY_DATA;
    
    void TestListEntry(void)
    {
        //定义一个头结点,不需要包含数据域,直接LIST_ENTRY就行了
        LIST_ENTRY list_head;
        PLIST_ENTRY p = NULL;
        int it;
        //初始化头结点,必须
        InitializeListHead(&list_head);
        //第1步:初始化测试数据
        for(it=0; it<16; it++){
            //循环调用ExAllocatePool分配内存
            PMY_DATA pmd = (PMY_DATA)ExAllocatePool(PagedPool,sizeof(MY_DATA));
            //数据域,我只定义了一个int类型变量,赋值
            pmd->num = it;
            //头插法,注意是&pmd->list
            //也可以换成InsertTailList从尾部插入结点
            //InsertTailList(&list_head,&pmd->list);
            InsertHeadList(&list_head,&pmd->list);
        }
        //第2步:遍历双向链表(结点不被移除),
        //p=list_head.Flink指向第1个结点
        //若链表为空:list_head.Flink/Blink == &list_head
        KdPrint(("顺序遍历双向链表:
    "));
      //注意是p!=&list_head,其实,<<楚狂人Windows驱动编程基础教程.pdf>>中
      //就把这个弄错了, 它是p!=&list_head.flink
        for(p=list_head.Flink; p!=&list_head; p=p->Flink){
            //用CONTAINING_RECORD得到MY_DATA的指针
            //有关CONTAINING_RECORD的详细解说见我的另一篇文章
            //http://~
            PMY_DATA pmd = CONTAINING_RECORD(p,MY_DATA,list);
            KdPrint(("pmd->num:%d
    ",pmd->num));
        }
        KdPrint(("反序遍历双向链表:
    "));
        for(p=list_head.Blink; p!=&list_head; p=p->Blink){
            PMY_DATA pmd = CONTAINING_RECORD(p,MY_DATA,list);
            KdPrint(("pmd->num:%d
    ",pmd->num));
        }
        //第3步:dump所有的结点指针(结点被移除)
        KdPrint(("Dump所有结点:
    "));
        while(!IsListEmpty(&list_head)){
            //得到MY_DATA指针中LIST_ENTRY成员list的指针
            //注意该结点已经被移除,list_head双向链表中已经不存在该结点
            //也可以换成RemoveTailList从尾部移除结点
            //PLIST_ENTRY plist = RemoveTailList(&list_head);
            PLIST_ENTRY plist = RemoveHeadList(&list_head);
    
            PMY_DATA pmd = CONTAINING_RECORD(plist,MY_DATA,list);
            //打印出保存的数据,并验证程序结果
            KdPrint(("pmd->num=%d
    ",pmd->num));
            //结点已经被移除,使用完就可释放了
            //注意释放的是整体的pmd指针,而不是plist
            ExFreePool(pmd);
        }
    }
    
    void DriverUnload(PDRIVER_OBJECT pDriverObject)
    {
    
    }
    
    NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pRegistryPath)
    {
        pDriverObject->DriverUnload = DriverUnload;
        TestListEntry();
        return STATUS_SUCCESS;
    }

    源代码下载:http://files.cnblogs.com/nbsofer/list_entry.7z

    链接:https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/nf-wdm-removeentrylist

    遍历链表找出指定字符串Remove:

    移除的时候用到函数:

    RemoveEntryList
    typedef struct{
        int num;
        LIST_ENTRY list;
    }MY_DATA,*PMY_DATA;
    
    void TestListEntry(int num)
    {
      //定义一个头结点,不需要包含数据域,直接LIST_ENTRY就行了
        LIST_ENTRY list_head;
        PLIST_ENTRY p = NULL;
        int it;
        //初始化头结点,必须
        InitializeListHead(&list_head);
        //第1步:初始化测试数据
        for(it=0; it<16; it++){
            //循环调用ExAllocatePool分配内存
            PMY_DATA pmd = (PMY_DATA)ExAllocatePool(PagedPool,sizeof(MY_DATA));
            //数据域,我只定义了一个int类型变量,赋值
            pmd->num = it;
            //头插法,注意是&pmd->list
            //也可以换成InsertTailList从尾部插入结点
            //InsertTailList(&list_head,&pmd->list);
            InsertHeadList(&list_head,&pmd->list);
        }
    
       //注意是p!=&list_head,其实,<<楚狂人Windows驱动编程基础教程.pdf>>中
      //就把这个弄错了, 它是p!=&list_head.flink
        for(p=list_head.Flink; p!=&list_head; p=p->Flink)
    {
    //用CONTAINING_RECORD得到MY_DATA的指针 //有关CONTAINING_RECORD的详细解说见我的另一篇文章 PMY_DATA pmd = CONTAINING_RECORD(p,MY_DATA,list); if(pmd->num==num) { KdPrint(("num1 and num2 are equal ")); RemoveEntryList(&pmd->list); } else { KdPrint(("num1 and num2 are NOT equal ")); } }
    }
  • 相关阅读:
    正则表达式:(?=a)是什么意思?
    炫酷的 CSS 形状(值得收藏)
    右边菜单侧拉框
    iframe的父子层跨域 用了百度的postMessage()方法
    二级联动菜单
    一个类似职位选择的二级多选
    iOS sharedk短信分享
    Xcode6新建项目没有.pch
    iOS An error was encountered while running (Domain = FBSOpenApplicationErrorDomain, Code = 4)
    转 UINavigationController标题文字颜色
  • 原文地址:https://www.cnblogs.com/chechen/p/8531995.html
Copyright © 2011-2022 走看看