[Windows驱动开发](四)内存管理
1. 物理内存概念(Physical Memory Address)
- //
- #define PAGEDCODE code_seg("PAGE")
- #define LOCKEDCODE code_seg()
- #define INITCODE code_seg("INIT")
- #define PAGEDDATA code_seg("PAGE")
- #define LOCKEDDATA code_seg()
- #define INITDATA code_seg("INIT")
- //
//
#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")
#define PAGEDDATA code_seg("PAGE")
#define LOCKEDDATA code_seg()
#define INITDATA code_seg("INIT")
//
- //
- #pragma PAGEDCODE
- VOID SomeFunction()
- {
- PAGED_CODE();
- // Do any other things ....
- }
- //
// #pragma PAGEDCODE
VOID SomeFunction()
{
PAGED_CODE();
// Do any other things ....
} //
- //
- #pragma LOCKEDCODE
- VOID SomeFunction()
- {
- // Do any other things ....
- }
- //
// #pragma LOCKEDCODE
VOID SomeFunction()
{
// Do any other things ....
} //
- //
- #pragma INITCODE
- extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
- {
- // Do any other things ....
- }
- //
// #pragma INITCODE
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
{
// Do any other things ....
} //
- //
- NTKERNELAPI
- PVOID
- ExAllocatePool(
- __drv_strictTypeMatch(__drv_typeExpr) __in POOL_TYPE PoolType,
- __in SIZE_T NumberOfBytes
- );
- NTKERNELAPI
- PVOID
- NTAPI
- ExAllocatePoolWithTag(
- __in __drv_strictTypeMatch(__drv_typeExpr) POOL_TYPE PoolType,
- __in SIZE_T NumberOfBytes,
- __in ULONG Tag
- );
- NTKERNELAPI
- PVOID
- ExAllocatePoolWithQuota(
- __drv_strictTypeMatch(__drv_typeExpr) __in POOL_TYPE PoolType,
- __in SIZE_T NumberOfBytes
- );
- NTKERNELAPI
- PVOID
- ExAllocatePoolWithQuotaTag(
- __in __drv_strictTypeMatch(__drv_typeExpr) POOL_TYPE PoolType,
- __in SIZE_T NumberOfBytes,
- __in ULONG Tag
- );
- //
// NTKERNELAPI
PVOID
ExAllocatePool(
__drv_strictTypeMatch(__drv_typeExpr) __in POOL_TYPE PoolType,
__in SIZE_T NumberOfBytes
); NTKERNELAPI
PVOID
NTAPI
ExAllocatePoolWithTag(
__in __drv_strictTypeMatch(__drv_typeExpr) POOL_TYPE PoolType,
__in SIZE_T NumberOfBytes,
__in ULONG Tag
); NTKERNELAPI
PVOID
ExAllocatePoolWithQuota(
__drv_strictTypeMatch(__drv_typeExpr) __in POOL_TYPE PoolType,
__in SIZE_T NumberOfBytes
); NTKERNELAPI
PVOID
ExAllocatePoolWithQuotaTag(
__in __drv_strictTypeMatch(__drv_typeExpr) POOL_TYPE PoolType,
__in SIZE_T NumberOfBytes,
__in ULONG Tag
); //
- //
- NTKERNELAPI
- VOID
- ExFreePoolWithTag(
- __in __drv_freesMem(Mem) PVOID P, // 要释放的地址
- __in ULONG Tag
- );
- #define ExFreePool(a) ExFreePoolWithTag(a,0)
- //
// NTKERNELAPI
VOID
ExFreePoolWithTag(
__in __drv_freesMem(Mem) PVOID P, // 要释放的地址
__in ULONG Tag
); #define ExFreePool(a) ExFreePoolWithTag(a,0) //
- // WDK中定义的双向链表数据结构
- //
- // Doubly linked list structure. Can be used as either a list head, or
- // as link words.
- //
- typedef struct _LIST_ENTRY {
- struct _LIST_ENTRY *Flink;
- struct _LIST_ENTRY *Blink;
- } LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;
- //
- // Singly linked list structure. Can be used as either a list head, or
- // as link words.
- //
- typedef struct _SINGLE_LIST_ENTRY {
- struct _SINGLE_LIST_ENTRY *Next;
- } SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
- //
// WDK中定义的双向链表数据结构 //
// Doubly linked list structure. Can be used as either a list head, or
// as link words.
// typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY; //
// Singly linked list structure. Can be used as either a list head, or
// as link words.
// typedef struct _SINGLE_LIST_ENTRY {
struct _SINGLE_LIST_ENTRY *Next;
} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY; //
- //
- typedef struct _MYDATASTRUCT{
- // List Entry要作为_MYDATASTRUCT结构体的一部分
- LIST_ENTRY ListEntry;
- // 自己定义的数据
- ULONG x;
- ULONG y;
- };
- //
//
typedef struct _MYDATASTRUCT{
// List Entry要作为_MYDATASTRUCT结构体的一部分
LIST_ENTRY ListEntry;
// 自己定义的数据
ULONG x;
ULONG y;
};
//
- //
- InsertHeadList(&head, &mydata->ListEntry);
- //
// InsertHeadList(&head, &mydata->ListEntry); //
- //
- InsertTailList(&head, &mydata->ListEntry);
- //
// InsertTailList(&head, &mydata->ListEntry); //
- //
- PLIST_ENTRY pEntry = RemoveHeadList(&head);
- PLIST_ENTRY pEntry = RemoveTailList(&tail);
- //
// PLIST_ENTRY pEntry = RemoveHeadList(&head);
PLIST_ENTRY pEntry = RemoveTailList(&tail); //
- //
- PLIST_ENTRY pEntry = RemoveHeadList(&head);
- PIRP pIrp = CONTAINING_RECORD(pEntry, MYDATASTRUCT, ListEntry);
- //
// PLIST_ENTRY pEntry = RemoveHeadList(&head);
PIRP pIrp = CONTAINING_RECORD(pEntry, MYDATASTRUCT, ListEntry); //
三、 Lookaside结构
- // WDK提供的Lookaside初始化函数
- VOID ExInitializeNPagedLookasideList(
- IN PNPAGED_LOOKASIDE_LIST Lookaside,
- IN PALLOCATE_FUNCTION Allocate OPTIONAL,
- IN PFREE_FUNCTION Free OPTIONAL,
- IN ULONG Flags,
- IN SIZE_T Size,
- IN ULONG Tag,
- IN USHORT Depth);
- VOID ExInitializePagedLookasideList(
- IN PPAGED_LOOKASIDE_LIST Lookaside,
- IN PALLOCATE_FUNCTION Allocate OPTIONAL,
- IN PFREE_FUNCTION Free OPTIONAL,
- IN ULONG Flags,
- IN SIZE_T Size,
- IN ULONG Tag,
- IN USHORT Depth);
- //
// WDK提供的Lookaside初始化函数 VOID ExInitializeNPagedLookasideList(
IN PNPAGED_LOOKASIDE_LIST Lookaside,
IN PALLOCATE_FUNCTION Allocate OPTIONAL,
IN PFREE_FUNCTION Free OPTIONAL,
IN ULONG Flags,
IN SIZE_T Size,
IN ULONG Tag,
IN USHORT Depth); VOID ExInitializePagedLookasideList(
IN PPAGED_LOOKASIDE_LIST Lookaside,
IN PALLOCATE_FUNCTION Allocate OPTIONAL,
IN PFREE_FUNCTION Free OPTIONAL,
IN ULONG Flags,
IN SIZE_T Size,
IN ULONG Tag,
IN USHORT Depth); //
- //
- VOID
- ExFreeToNPagedLookasideList(
- IN PNPAGED_LOOKASIDE_LIST Lookaside,
- IN PVOID Entry);
- VOID
- ExFreeToPagedLookasideList(
- IN PPAGED_LOOKASIDE_LIST Lookaside,
- IN PVOID Entry);
- //
// VOID
ExFreeToNPagedLookasideList(
IN PNPAGED_LOOKASIDE_LIST Lookaside,
IN PVOID Entry); VOID
ExFreeToPagedLookasideList(
IN PPAGED_LOOKASIDE_LIST Lookaside,
IN PVOID Entry); //
- //
- VOID ExDeleteNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside);
- VOID ExDeletePagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside);
- //
// VOID ExDeleteNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside); VOID ExDeletePagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside); //
Lookaside结构
频繁的申请和回收内存,会导致在内存上产生大量的内存“空洞”,从而导致最终无法申请内存。DDK为程序员提供了Lookaside结构来解决这个问题。
我们可以将Lookaside对象看成是一个内存容器。在初始化的时候,它先向Windows申请了一块比较大的内存。以后程序员每次申请内存的时候,不是直接向Windows申请内存,而是想Lookaside对象申请内存。Looaside会智能的避免产生内存“空洞”。如果Lookaside对象内部内存不够用时,它会向操作系统申请更多的内存。
Lookaside一般会在以下情况下使用:
1. 程序员每次申请固定大小的内存。
2. 申请和回收的操作十分频繁。
要使用Looaside对象,首先要初始化Lookaside对象,有以下两个函数可以使用:
(1)VOID ExInitializeNPagedLookasideList( IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth );
(2)VOID ExInitializePagedLookasideList( IN PPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth );
初始化玩Lookaside对象后,可以进行申请内存的操作了:
(1)PVOID ExAllocateFromNPagedLookasideList( IN PNPAGED_LOOKASIDE_LIST Lookaside );
(2)PVOID ExAllocateFromPagedLookasideList( IN PPAGED_LOOKASIDE_LIST Lookaside );
对Lookaside对象回收内存:
(1)VOID ExFreeToNPagedLookasideList( IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PVOID Entry );
(2)VOID ExFreeToPagedLookasideList( IN PPAGED_LOOKASIDE_LIST Lookaside, IN PVOID Entry );
在使用完Lookaside对象后,要删除Lookaside对象:
(1)VOID ExDeleteNPagedLookasideList( IN PNPAGED_LOOKASIDE_LIST Lookaside );
(2) VOID ExDeletePagedLookasideList( IN PPAGED_LOOKASIDE_LIST Lookaside );
测试代码:
#pragma INITCODE
VOID LookasideTets()
{
KdPrint(("进入LookasideTest函数!\n"));
PAGED_LOOKASIDE_LIST Lookaside;
ExInitializePagedLookasideList(&Lookaside,NULL, NULL, 0, sizeof(MYDATASTRUCT), 'abcd', 0);
PMYDATASTRUCT pMyData[50];
for (inti=0; i<50; i++)
{
pMyData[i] = (PMYDATASTRUCT)ExAllocateFromPagedLookasideList(&Lookaside);
if ((i+1)%10 == 0)
{
KdPrint(("申请了 %d 个数据了!\n", ++i));
}
}
for (inti=0; i<50; i++)
{
ExFreeToPagedLookasideList(&Lookaside,pMyData[i]);
pMyData[i] =NULL;
if ((i+1)%10 == 0)
{
KdPrint(("释放了 %d 个数据的内存了!\n", ++i));
}
}
ExDeletePagedLookasideList(&Lookaside);
}
2.运行时函数
(1)内存间复制(非重叠)
VOID RtlCopyMemory( IN VOID UNALIGNED *Destination, IN CONST VOID UNALIGNED *Source, IN SIZE_T Length );
(2)内存间复制(可重叠)
VOID RtlMoveMemory( IN VOID UNALIGNED *Destination, IN CONST VOID UNALIGNED *Source, IN SIZE_T Length );
(3)填充内存
VOID RtlFillMemory( IN VOID UNALIGNED *Destination, IN SIZE_T Length, IN UCHAR Fill );
VOID RtlZeroMemory( IN VOID UNALIGNED *Destination, IN SIZE_T Length );
(4)内存比较
SIZE_T RtlCompareMemory( IN CONST VOID *Source1, IN CONST VOID *Source2, IN SIZE_T Length );
ULONG RtlEqualMemory( CONST VOID *Source1, CONST VOID *Source2, SIZE_T Length );
测试代码:
#define BUFFER_SIZE 1024
#pragma INITCODE
VOID RtlTest()
{
KdPrint(("进入RtlTest函数!\n"));
PUCHAR pBuffer1 = (PUCHAR)ExAllocatePool(PagedPool,BUFFER_SIZE);
RtlZeroMemory(pBuffer1,BUFFER_SIZE);
PUCHAR pBuffer2 = (PUCHAR)ExAllocatePool(PagedPool,BUFFER_SIZE);
RtlFillMemory(pBuffer2,BUFFER_SIZE, 0xAA);
RtlCopyMemory(pBuffer1,pBuffer2, BUFFER_SIZE);
if (RtlEqualMemory(pBuffer1,pBuffer2, BUFFER_SIZE))
{
KdPrint(("两块内存块数据一样!\n"));
for(inti=0; i<BUFFER_SIZE;i++)
{
KdPrint(("%02X", pBuffer1[i]));
}
}
else
{
KdPrint(("两块内存块数据不一样!\n"));
}
KdPrint(("离开RtlTest函数!\n"));
}
[Windows驱动开发](四)内存管理的更多相关文章
- Windows驱动开发(中间层)
Windows驱动开发 一.前言 依据<Windows内核安全与驱动开发>及MSDN等网络质料进行学习开发. 二.初步环境 1.下载安装WDK7.1.0(WinDDK\7600.16385 ...
- C++第三十三篇 -- 研究一下Windows驱动开发(一)内部构造介绍
因为工作原因,需要做一些与网卡有关的测试,其中涉及到了驱动这一块的知识,虽然程序可以运行,但是不搞清楚,心里总是不安,觉得没理解清楚.因此想看一下驱动开发.查了很多资料,看到有人推荐Windows驱动 ...
- windows 驱动开发入门——驱动中的数据结构
最近在学习驱动编程方面的内容,在这将自己的一些心得分享出来,供大家参考,与大家共同进步,本人学习驱动主要是通过两本书--<独钓寒江 windows安全编程> 和 <windows驱动 ...
- Windows驱动——读书笔记《Windows驱动开发技术详解》
=================================版权声明================================= 版权声明:原创文章 谢绝转载 请通过右侧公告中的“联系邮 ...
- [转载]对iOS开发中内存管理的一点总结与理解
对iOS开发中内存管理的一点总结与理解 做iOS开发也已经有两年的时间,觉得有必要沉下心去整理一些东西了,特别是一些基础的东西,虽然现在有ARC这种东西,但是我一直也没有去用过,个人觉得对内存操作 ...
- 高性能JAVA开发之内存管理
这几天在找一个程序的bug,主要是java虚拟机内存溢出的问题,调研了一些java内存管理的资料,现整理如下: 一.JVM中的对象生命周期 对象的生命周期一般分为7个阶段:创建阶段,应用阶段,不可视阶 ...
- [Windows驱动开发](一)序言
笔者学习驱动编程是从两本书入门的.它们分别是<寒江独钓——内核安全编程>和<Windows驱动开发技术详解>.两本书分别从不同的角度介绍了驱动程序的制作方法. 在我理解,驱动程 ...
- windows驱动开发推荐书籍
[作者] 猪头三 个人网站 :http://www.x86asm.com/ [序言] 很多人都对驱动开发有兴趣,但往往找不到正确的学习方式.当然这跟驱动开发的本土化资料少有关系.大多学的驱动开发资料都 ...
- Windows 驱动开发 - 5
上篇<Windows 驱动开发 - 4>我们已经完毕了硬件准备. 可是我们还没有详细的数据操作,比如接收读写操作. 在WDF中进行此类操作前须要进行设备的IO控制,已保持数据的完整性. 我 ...
- IOS开发的内存管理
关于IOS开发的内存管理的文章已经很多了,因此系统的知识点就不写了,这里我写点平时工作遇到的疑问以及解答做个总结吧,相信也会有人遇到相同的疑问呢,欢迎学习IOS的朋友请加ios技术交流群:190956 ...
随机推荐
- C++ 中超类化和子类化
超类化和子类化没有具体的代码,其实是一种编程技巧,在MFC和WTL中可以有不同的实现方法. 窗口子类化: 原理就是改变一个已创建窗口类的窗口过程函数.通过截获已创建窗口的消息,从而实现监视或修改已创建 ...
- Unity3d 怪物死亡燃烧掉效果
效果 BurnToFadeOut.shader代码 Shader "BurnToFadeOut" { Properties { _StartColor ("Start C ...
- Qt 改变图片大小
void Setting_TabProduct::changeImageSize(int width,int height,QString imgFile) { QPixmap pixmap(imgF ...
- FastReport经验
FastReport经验 1.FastReport中如果访问报表中的对象? 可以使用FindObject方法. TfrxMemoView(frxReport1.FindObject(’memo1′)) ...
- 一些笔试题(C/C++)
1.there are two variables, don't use if.. else or ?: or switch or other judgement statements,find ou ...
- 【转】Android Support v4、v7、v13的区别和应用场景
google提供了Android Support Library package 系列的包来保证来高版本sdk开发的向下兼容性,即我们用4.x开发时,在1.6等版本上,可以使用高版本的有些特性,如fr ...
- IOS-UIIamge初始化的几种方法的比较
一.imageNamed——方法介绍imageNamed:是UIImage的一个类方法,它做的事情比我们看到的要稍微多一些.它的加载流程如 下:1.系统回去检查系统缓存中是否存在该名字的图像,如果存在 ...
- js正则匹配以固定格式结尾的字符串并匹配是手机访问,则跳转
<script> //var pcUrl = "http://res.meadin.com/HotelData/98986_1.shtml"; var pcUrl = ...
- 如何用Endnote导入你要用的格式
在Google搜索某一个期刊名 ens格式的文件,下载,然后放入endnote的文件夹中(C:\Program Files (x86)\EndNote X7\Styles) 然后将其导入即可
- python基础——匿名函数
python基础——匿名函数 当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便. 在Python中,对匿名函数提供了有限支持.还是以map()函数为例,计算f(x)=x2时 ...