《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. [2018-06-28] 创建第一个django项目

    1.创建一个名称为tmpl的项目 django-admin.py startproject tmpl 2.进入刚刚创建的tmpl目录 cd tmpl 3.创建一个名称为learn的应用 python ...

  2. Kong07-自定义 Kong 插件

    在进一步讨论之前,有必要简要说明 Kong 是如何构建的,特别是它是如何与 Nginx 集成的,以及 Lua 与它有什么关系. 在 Nginx 中,lua-nginx-module 模块支持 Lua ...

  3. 理解np.nonzero()函数

    举三个例子,就能清楚的看到 np.nonzero() 这个函数返回值的意义 一. #例1 一维数组 import numpy as np a = [0,1,2,0,3,0] b = np.nonzer ...

  4. 机器学习之Anaconda介绍

    Anaconda Distribution 最受欢迎的Python / R数据科学发行版 轻松安装1,400多个Python / R数据科学包并管理您的包,依赖项和 环境 - 只需单击一下按钮即可.免 ...

  5. getchar()用法 【转】

    1.从缓冲区读走一个字符,相当于清除缓冲区 2.前面的scanf()在读取输入时会在缓冲区中留下一个字符'\n'(输入完s[i]的值后按回车键所致),所以如果不在此加一个getchar()把这个回车符 ...

  6. dubbo监控安装

    tar xf dubbo-monitor-simple-2.8.4-assembly.tar.gz cd dubbo-monitor-simple-2.8.4 vi conf/dubbo.proper ...

  7. 你知道如何优化Join语句吗?

    join语句的两种算法,分别是:NLJ和BNL 测试数据: create table t1(id int primary key, a int, b int, index(a)); create ta ...

  8. jquery each循环遍历完再执行的方法

    jquery each循环遍历完再执行的方法 因为each是异步的 所以要加计数器. var eachcount=0; <pre> $(".emptytip").eac ...

  9. 关闭redis持久化功能

    关闭redis持久化功能持久化会报如下信息 会影响硬盘写入性能 所以没什么用 就关掉吧 修改redis配置文件,redis.conf 第115行左右. 1.注释掉原来的持久化规则 <pre> ...

  10. python——多线程

    多线程特点: • 线程的并发是利用cpu上下文的切换(是并发,不是并行) • 多线程执行的顺序是无序的 • 多线程共享全局变量 • 线程是继承在进程里的,没有进程就没有线程 • GIL全局解释器锁 • ...