- //
- #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"));
}