《Windows内核安全与驱动开发》阅读笔记 -- 索引目录

《Windows内核安全与驱动开发》 3.2 内存与链表

1. 尝试生成一个链表头并将其初始化。

2. 尝试向内存中申请两个链表结点,并且初始化该结点,将该结点插入到链表中,其数据结构如下。

typedef struct {
LIST_ENTRY list_entry;
INT id;
}StuInfo,*PStuInfo;

3. 遍历“问题2”中生成的链表,并调用 DbgPrint 打印出来。

4. 将问题2中的链表清空(并释放内存),最后判断该链表是否为空。

5. 有几种删除链表结点的方法。

6. 遍历链表时,如果 LIST_ENTRY 成员不在开头,应该如何操作?


答案

1. 尝试生成一个链表头并将其初始化。

// 定义并初始化链表头
LIST_ENTRY my_list_entry;
InitializeListHead(&my_list_entry);

2. 尝试向内存中申请两个链表结点,并且初始化该结点,将该结点插入到链表中,其数据结构如下。

//
// 向内存中申请一个结点,并插入到链表中。
//
PStuInfo pStu1 = ExAllocatePoolWithTag(NonPagedPool, sizeof(StuInfo),MEN_NAME);
if (!pStu1) {
return STATUS_INSUFFICIENT_RESOURCES;
}
pStu1->id = ;
InsertHeadList(&my_list_entry, (PLIST_ENTRY) pStu1); PStuInfo pStu2 = ExAllocatePoolWithTag(NonPagedPool, sizeof(StuInfo), MEN_NAME);
if (!pStu2) {
return STATUS_INSUFFICIENT_RESOURCES;
}
pStu2->id = ;
InsertHeadList(&my_list_entry, (PLIST_ENTRY)pStu2);

3. 遍历“问题2”中生成的链表,并调用 DbgPrint 打印出来

//
// 遍历链表
//
for (PLIST_ENTRY p = my_list_entry.Flink; p != &my_list_entry; p = p->Flink) {
DbgPrint("%d\n", ((PStuInfo)p)->id);
}

4. 将问题2中的链表清空(并释放内存),最后判断该链表是否为空。

//
// 全部删除链表
//
PLIST_ENTRY p; while (!IsListEmpty(&my_list_entry)) {
p = RemoveHeadList(&my_list_entry); // 获取被移除链表元素
ExFreePool((PStuInfo)p); } // 判断链表是否为空
if (IsListEmpty(&my_list_entry)) {
DbgPrint("链表已空\n");
}
else {
DbgPrint("链表未空\n");
}

5. 三种方法,移除链表头(RemoveHeadList);移除链表尾(RemoveTailList);移除中间元素(RemoveEntryList)。

6. 使用一个宏 CONTAINING_RECORD.

完整代码:

 #include <ntifs.h>
#define MEN_NAME 'abc'
// 定义链表结构
typedef struct {
LIST_ENTRY list_entry;
INT id;
}StuInfo,*PStuInfo; //提供一个卸载函数,让程序能卸载,如果没有这个函数,驱动将不能卸载。
VOID UnDriver(PDRIVER_OBJECT driver)
{
KdPrint(("卸载驱动成功"));
}
//入口函数,相当于main。
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
// 定义并初始化链表头
LIST_ENTRY my_list_entry;
InitializeListHead(&my_list_entry); //
// 向内存中申请一个结点,并插入到链表中。
//
PStuInfo pStu1 = ExAllocatePoolWithTag(NonPagedPool, sizeof(StuInfo),MEN_NAME);
if (!pStu1) {
return STATUS_INSUFFICIENT_RESOURCES;
}
pStu1->id = ;
InsertHeadList(&my_list_entry, (PLIST_ENTRY) pStu1); PStuInfo pStu2 = ExAllocatePoolWithTag(NonPagedPool, sizeof(StuInfo), MEN_NAME);
if (!pStu2) {
return STATUS_INSUFFICIENT_RESOURCES;
}
pStu2->id = ;
InsertHeadList(&my_list_entry, (PLIST_ENTRY)pStu2); //
// 遍历链表
//
for (PLIST_ENTRY p = my_list_entry.Flink; p != &my_list_entry; p = p->Flink) {
DbgPrint("%d\n", ((PStuInfo)p)->id);
} //
// 全部删除链表
//
PLIST_ENTRY p; while (!IsListEmpty(&my_list_entry)) {
p = RemoveHeadList(&my_list_entry); // 获取被移除链表元素
ExFreePool((PStuInfo)p); } // 判断链表是否为空
if (IsListEmpty(&my_list_entry)) {
DbgPrint("链表已空\n");
}
else {
DbgPrint("链表未空\n");
} driver->DriverUnload = UnDriver;
return STATUS_SUCCESS;
}

《Windows内核安全与驱动开发》 3.2 内存与链表的更多相关文章

  1. Windows内核安全与驱动开发

    这篇是计算机中Windows Mobile/Symbian类的优质预售推荐<Windows内核安全与驱动开发>. 编辑推荐 本书适合计算机安全软件从业人员.计算机相关专业院校学生以及有一定 ...

  2. 《windows内核安全与驱动开发》ctrl2cap中的ObReferenceObjectByName疑问

    国内有关于windows内核驱动这块的书籍实在是甚少,不过好在<windows内核安全与驱动开发>这本书还算不错(内容方面),但是不得不说这本书在许多地方存在着一些细节上的问题.比如我今天 ...

  3. 《Windows内核安全与驱动开发》 7.1&7.2&7.3 串口的过滤

    <Windows内核安全与驱动开发>阅读笔记 -- 索引目录 <Windows内核安全与驱动开发> 7.1&7.2&7.3 串口的过滤 一.设备绑定的内核API ...

  4. 《Windows内核安全与驱动开发》阅读笔记 -- 索引目录

    <Windows内核安全与驱动开发>阅读笔记 -- 索引目录 一.内核上机指导 二.内核编程环境及其特殊性 2.1 内核编程的环境 2.2 数据类型 2.3 重要的数据结构 2.4 函数调 ...

  5. 《Windows内核安全与驱动开发》 2.3 重要的数据结构

    <Windows内核安全与驱动开发>阅读笔记 -- 索引目录 <Windows内核安全与驱动开发> 2.3 重要的数据结构 一.驱动对象  Windows内核采用__的编程方式 ...

  6. 《Windows内核安全与驱动开发》 3.1 字符串操作

    <Windows内核安全与驱动开发>阅读笔记 -- 索引目录 <Windows内核安全与驱动开发> 3.1 字符串操作 一.字符串的初始化 1. 判断下列代码为什么会蓝屏? U ...

  7. 《Windows内核安全与驱动开发》4.1 文件操作

    <Windows内核安全与驱动开发>阅读笔记 -- 索引目录 <Windows内核安全与驱动开发>4.1 文件操作 从 C:\a.txt 中读取一部分内容并利用 DbgPrin ...

  8. 《Windows内核安全与驱动开发》4.3 时间与定时器

    <Windows内核安全与驱动开发>阅读笔记 -- 索引目录 <Windows内核安全与驱动开发>4.3  时间与定时器 一.获取自系统启动以来的毫秒数 /* 函数作用:求自操 ...

  9. 《Windows内核安全与驱动开发》 4.4 线程与事件

    <Windows内核安全与驱动开发>阅读笔记 -- 索引目录 <Windows内核安全与驱动开发> 4.4 线程与事件 一.开辟一个线程,参数为(打印内容+打印次数),利用线程 ...

随机推荐

  1. Project Euler 56: Powerful digit sum

    一个古戈尔也就是\(10^{100}\)是一个天文数字,一后面跟着一百个零.\(100^{100}\)更是难以想像的大,一后面跟着两百个零.但是尽管这个数字很大,它们各位数字的和却只等于一.考虑两个自 ...

  2. 『题解』Codeforces220B Little Elephant and Array

    更好的阅读体验 Portal Portal1: Codeforces Portal2: Luogu Description The Little Elephant loves playing with ...

  3. JSP——底层原理

    都知道jsp就是在HTML文件中写java代码,以实现动态页面的效果,但是这种动态是如何实现的呢?今天就在研究一下. 首先,我写了一个简单的jsp文件: <%@page import=" ...

  4. php nginx反向代理获取真实ip的教程

    php nginx反向代理获取真实ip的教程 <pre> location /getip { proxy_pass http://newmiracle.cn/ip.php; } proxy ...

  5. 学习下ElasticSearch

    ElasticSearch基础概念 Elasticsearch的Head插件安装 Elasticsearch在Centos 7上的安装常见的问题 使用场景:比如分库的情况下,你想统计所有数据的报表,就 ...

  6. Eclipse添加自定义注释

    首先介绍几个常用的注解: @author 作者名 @date 日期 @version 版本标识 @parameter 参数及其意义 @return 返回值 @throws 异常类及抛出条件 @depr ...

  7. webpack 打包优化的四种方法(多进程打包,多进程压缩,资源 CDN,动态 polyfill)

    如今,webpack 毫无疑问是前端构建领域里最耀眼的一颗星,无论你前端走哪条路线,都需要有很强的webpack 知识.webpack 的基本用法这里就不展开讲了.主要探讨一下如何提高 webpack ...

  8. Mysql主从同步的实现原理与配置实战

    1.什么是mysql主从同步? 当master(主)库的数据发生变化的时候,变化会实时的同步到slave(从)库. 2.主从同步有什么好处? 水平扩展数据库的负载能力. 容错,高可用.Failover ...

  9. Test Complete 的自动化测试 --- 三角形

    Test Complete 的自动化测试 --- 三角形 PS:工具:Test Complete , OS:win 10 这里做三角形的测试与上一篇博客做计算器的测试大致一样,都是对.exe的执行文件 ...

  10. Kotlin Coroutines不复杂, 我来帮你理一理

    Coroutines 协程 最近在总结Kotlin的一些东西, 发现协程这块确实不容易说清楚. 之前的那篇就写得不好, 所以决定重写. 反复研究了官网文档和各种教程博客, 本篇内容是最基础也最主要的内 ...