首页
社区
课程
招聘
[求助]Windows驱动中如何使用LIST_ENTRY结构
发表于: 2014-3-18 15:03 12035

[求助]Windows驱动中如何使用LIST_ENTRY结构

2014-3-18 15:03
12035
今天想直接使用Windows自己提供的LIST_ENTRY结构。前面还算用的很好的,但是唯独有一个在移除节点时,里面仅提供了 RemoveHeadList、RemoveTailList、RemoveEntryList三种函数,都是从结尾或者头部移除节点。这样如果我要搜索一个特定的节点后,然后移除这个节点就无法实现?

求问大牛们,如何使用LIST_ENTRY结构来实现移除特定节点。。。。(不考虑自己实现链表),而且Windows内部大多数使用LIST_ENTRY结构的,难道就没有移除特定节点的需求么

另外还有一点:因为我使用了自旋锁,然后中断级是Dispatch Level。所以要求头结点和List_entry节点都必须固定。msdn里面是这么解释的:

is called at IRQL >= DISPATCH_LEVEL, the storage for the list entries must be memory-resident.

我估计意思就是头结点和节点都必须是在不可分页内存中,以前头结点是全局变量,所以我修改了代码如下,在堆中分配内存给头结点:

PLIST_ENTRY  list_head;
KSPIN_LOCK  list_lock;

VOID InitKernelList()
{
        list_head =  (PLIST_ENTRY)ExAllocatePoolWithTag(NonPagedPool, sizeof(LIST_ENTRY), 'Tg89');
        InitializeListHead(list_head);
        KeInitializeSpinLock(list_lock);
}

但是后来的第一次插入节点没有问题,再次插入的时候就发生了0x50蓝屏,PAGE_FAULT_IN_NONPAGED_AREA,这是为什么呢。
上面的List_ENTRY代码都在一个单独的.h和.c文件中,在主程序中使用extern引入全局变量

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (13)
雪    币: 19
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
先CONTAINING_RECORD获取数据
然后断链不就行了么? 最后ExFreePool
2014-3-18 15:05
0
雪    币: 79
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
Windows自己提供的remove函数,意思也是断链吧!问题是这个还要我自己去断链么。。。如果有Windows自己提供的带自旋锁的函数就好了
2014-3-18 15:16
0
雪    币: 19
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
ExInterlocked系列函数
2014-3-18 15:18
0
雪    币: 79
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
这个我知道。。。但是可惜Windows不提供移除特定节点的函数啊!太可惜了
2014-3-18 15:19
0
雪    币: 236
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
windows 应该提供一分过所有保护的驱动。
2014-3-18 15:31
0
雪    币: 79
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
哈哈。。。莫黑。。最后我自己实现了下,只是表示可惜。。要有的话至少不用担心其他问题了,代码也好看点
2014-3-18 15:40
0
雪    币: 236
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
2014-3-18 15:45
0
雪    币: 155
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
谁说没提供,RemoveEntryList就可以移除特定节点啊,不看MSDN你看看源码也知道啊。

帮你写个吧:

    for (entry = ListHead.Flink;  entry != &ListHead;entry = entry->Flink)
   {
        data = CONTAINING_RECORD( entry, XXX_LIST, ListEntry );
        if (data == datatoremove)
        {
            RemoveEntryList( entry );
            entry = entry->Blink;
        }
    }
2014-3-18 20:20
0
雪    币: 478
活跃值: (50)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
楼主你是不是想要一个无需遍历,能直接删除指定节点的函数?
2014-3-18 20:22
0
雪    币: 79
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
好吧!我之前看过MSDN,To remove a specified entry from the list, use RemoveEntryList.
看到过这个函数,这个函数是可以移除节点么。。。。我自己实现了个差不多的
2014-3-18 20:47
0
雪    币: 79
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
不是的。。只要删除指定节点,遍历自己动手
2014-3-18 20:48
0
雪    币: 155
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
本来也没啥,RemoveEntryList就是个FORCEINLINE的简单函数。。。

FORCEINLINE
BOOLEAN
RemoveEntryList(
    __in PLIST_ENTRY Entry
    )
{
    PLIST_ENTRY Blink;
    PLIST_ENTRY Flink;

    Flink = Entry->Flink;
    Blink = Entry->Blink;
    Blink->Flink = Flink;
    Flink->Blink = Blink;
    return (BOOLEAN)(Flink == Blink);
}
2014-3-18 21:31
0
雪    币: 79
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
求问。。。解决了很久的蓝屏,不知道你以前遇到过否
另外还有一点:因为我使用了自旋锁,然后中断级是Dispatch Level。所以要求头结点和List_entry节点都必须固定。msdn里面是这么解释的:

is called at IRQL >= DISPATCH_LEVEL, the storage for the list entries must be memory-resident.

我估计意思就是头结点和节点都必须是在不可分页内存中,以前头结点是全局变量,所以我修改了代码如下,在堆中分配内存给头结点:

PLIST_ENTRY  list_head;
KSPIN_LOCK  list_lock;

VOID InitKernelList()
{
  list_head =  (PLIST_ENTRY)ExAllocatePoolWithTag(NonPagedPool, sizeof(LIST_ENTRY), 'Tg89');
  InitializeListHead(list_head);
  KeInitializeSpinLock(list_lock);
}

但是后来的第一次插入节点没有问题,再次插入的时候就发生了0x50蓝屏,PAGE_FAULT_IN_NONPAGED_AREA,这是为什么呢。
上面的List_ENTRY代码都在一个单独的.h和.c文件中,在主程序中使用extern引入全局变量
2014-3-18 21:53
0
游客
登录 | 注册 方可回帖
返回
//