标签:
//
#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 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 ....
}
//
//
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)
//
// 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;
};
//
// InsertHeadList(&head, &mydata->ListEntry); //
// InsertTailList(&head, &mydata->ListEntry); //
// PLIST_ENTRY pEntry = RemoveHeadList(&head); PLIST_ENTRY pEntry = RemoveTailList(&tail); //
// PLIST_ENTRY pEntry = RemoveHeadList(&head); PIRP pIrp = CONTAINING_RECORD(pEntry, MYDATASTRUCT, ListEntry); //
// 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 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"));
}
标签:
原文地址:http://www.cnblogs.com/kuangke/p/5606867.html