《Windows内核安全与驱动开发》 3.2 内存与链表
《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 内存与链表的更多相关文章
- Windows内核安全与驱动开发
这篇是计算机中Windows Mobile/Symbian类的优质预售推荐<Windows内核安全与驱动开发>. 编辑推荐 本书适合计算机安全软件从业人员.计算机相关专业院校学生以及有一定 ...
- 《windows内核安全与驱动开发》ctrl2cap中的ObReferenceObjectByName疑问
国内有关于windows内核驱动这块的书籍实在是甚少,不过好在<windows内核安全与驱动开发>这本书还算不错(内容方面),但是不得不说这本书在许多地方存在着一些细节上的问题.比如我今天 ...
- 《Windows内核安全与驱动开发》 7.1&7.2&7.3 串口的过滤
<Windows内核安全与驱动开发>阅读笔记 -- 索引目录 <Windows内核安全与驱动开发> 7.1&7.2&7.3 串口的过滤 一.设备绑定的内核API ...
- 《Windows内核安全与驱动开发》阅读笔记 -- 索引目录
<Windows内核安全与驱动开发>阅读笔记 -- 索引目录 一.内核上机指导 二.内核编程环境及其特殊性 2.1 内核编程的环境 2.2 数据类型 2.3 重要的数据结构 2.4 函数调 ...
- 《Windows内核安全与驱动开发》 2.3 重要的数据结构
<Windows内核安全与驱动开发>阅读笔记 -- 索引目录 <Windows内核安全与驱动开发> 2.3 重要的数据结构 一.驱动对象 Windows内核采用__的编程方式 ...
- 《Windows内核安全与驱动开发》 3.1 字符串操作
<Windows内核安全与驱动开发>阅读笔记 -- 索引目录 <Windows内核安全与驱动开发> 3.1 字符串操作 一.字符串的初始化 1. 判断下列代码为什么会蓝屏? U ...
- 《Windows内核安全与驱动开发》4.1 文件操作
<Windows内核安全与驱动开发>阅读笔记 -- 索引目录 <Windows内核安全与驱动开发>4.1 文件操作 从 C:\a.txt 中读取一部分内容并利用 DbgPrin ...
- 《Windows内核安全与驱动开发》4.3 时间与定时器
<Windows内核安全与驱动开发>阅读笔记 -- 索引目录 <Windows内核安全与驱动开发>4.3 时间与定时器 一.获取自系统启动以来的毫秒数 /* 函数作用:求自操 ...
- 《Windows内核安全与驱动开发》 4.4 线程与事件
<Windows内核安全与驱动开发>阅读笔记 -- 索引目录 <Windows内核安全与驱动开发> 4.4 线程与事件 一.开辟一个线程,参数为(打印内容+打印次数),利用线程 ...
随机推荐
- 1、Hibernate-入门
一.概述 1.什么是Hibernate: Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,h ...
- 使用Typescript重构axios(十二)——增加参数
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- Python类属性与实例属性理解
按理讲,类属性改变,类的实例对象这个属性也应该被改变,但是在python中实际却不是这样 class test(): name = 111 a = test() b = test() a.name = ...
- 误删tree命令如何恢复
误删tree命令如何恢复 考察rpm,yum的用法 一.删除tree命令,tree命令不可用 [root@centos7 ~]# which tree /usr/bin/tree [root@cent ...
- hash值生成表后缀(分表方案)
//businessId分表目标值,tableSize:表数量,tableSuffix:表后缀 public static String getTableSuffix(String businessI ...
- SpringBoot 源码解析 (五)----- Spring Boot的核心能力 - 自动配置源码解析
在上一篇博客中分析了springBoot启动流程,大体的轮廓只是冰山一角.今天就来看一下springBoot的亮点功能:自动化装配功能. 先从@SpringBootApplication开始.在启动流 ...
- pat 1035 Password(20 分)
1035 Password(20 分) To prepare for PAT, the judge sometimes has to generate random passwords for the ...
- ES6入门十二:Module(模块化)
webpack4打包配置babel7转码ES6 Module语法与API的使用 import() Module加载实现原理 Commonjs规范的模块与ES6模块的差异 ES6模块与Nodejs模块相 ...
- 结合源码,重温 Android View 的事件处理知多少 ?
前言 Android View 的 事件处理在我们的编程中,可谓是无处不在了.但对于大多数人而言,一直都是简单的使用,对其原理缺乏深入地认识. 学 Android 有一段时间了,最近发现,很多基础知识 ...
- Error: invalid "instanceof" keyword value Promise的解决方法
执行npm run dev 时,发现错误 Error: invalid "instanceof" keyword value Promise 经过一番查找,发现原因是webpack ...