分配Kernal記憶體
PVOID ExAllocatePool(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes);
PVOID ExAllocatePoolWithTag(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag);
PVOID ExAllocatePoolWithQuota(IN POOL_TYPE, IN SIZE_T);
PVOID ExAllocatePoolWithQuataTag(IN POOL_TYPE, IN SIZE_T, IN UNLONG);
釋放Kernal記憶體
VOID ExFreePool(IN PVOID P);
NTKERNELAPI VOID ExFreePoolWithTag(IN PVOID P, ULONG tag);
2.
Kernal使用link-list:
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY* Flink;
struct _LIST_ENTRY* Blink;
} LIST_ENTRY, *PLIST_ENTRY;
判斷 linked-list是否為空
IsListEmpty(PLIST_ENTRY);
插入element至 linked-list
InsertHeadList(PLIST_ENTRY head, PLIST_ENTRY entry);
InsertTailList(PLIST_ENTRY tail, PLIST_ENTRY entry);
從linked-list刪除element
RemoveHeadList(PLIST_ENTRY)
RemoveTailList(PLIST_ENTRY)
將element轉換成自訂資料結構
CONTAINING_RECORD(address, type, field) ;
address:自訂資料結構的位址
type:自訂的資料結構
filed:自訂資料結構中的pEntry
範例:
typedef struct _MYDATASTRUCT
{
ULONG number;
LIST_ENTRY ListEntry;
} MYDATASTRUCT, *PMYDATASTRUCT;
#pragma INITCODE
VOID LinkListTest()
{
LIST_ENTRY linkListHead;
//初始化鏈表
InitializeListHead(&linkListHead);
MYDATASTRUCT *pData;
ULONG i = 0;
//在鏈表中插入10個元素
KdPrint(("Begin insert to link list"));
for (i=0 ; i<5 ; i++)
{
pData = (MYDATASTRUCT *)ExAllocatePool(PagedPool,sizeof(MYDATASTRUCT));
pData->number = i;
InsertTailList(&linkListHead,&pData->ListEntry);
}
KdPrint(("Begin remove from link list\n"));
while(!IsListEmpty(&linkListHead))
{
PLIST_ENTRY pEntry = RemoveTailList(&linkListHead);
pData = CONTAINING_RECORD(pEntry,
MYDATASTRUCT,
ListEntry);
KdPrint(("%d\n",pData->number));
ExFreePool(pData);
}
}
3.
Lookaside結構:
避免頻繁配置及釋放記憶體,產生記憶體破碎的情況
使用前先要初始化,非分頁及分頁兩種方式
ExInitializeNPagedLookasideList (
IN PNPAGED_LOOKASIDE_LIST Lookaside,
IN PALLOCATE_FUNCTION Allocate,
IN PFREE_FUNCTION Free,
IN ULONG Flags,
IN SIZE_T Size,
IN ULONG Tag,
IN USHORT Depth
);
ExInitializePagedLookasideList (
IN PPAGED_LOOKASIDE_LIST Lookaside,
IN PALLOCATE_FUNCTION Allocate,
IN PFREE_FUNCTION Free,
IN ULONG Flags,
IN SIZE_T Size,
IN ULONG Tag,
IN USHORT Depth
);
配置記憶體
PVOID ExAllocateFromNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST);
PVOIDExAllocateFromPagedLookasideList(IN PPAGED_LOOKASIDE_LIST);
釋放記憶體
VOID ExFreeToNPagedLookasideList(IN PNPAGED_LOOKASIDE, IN PVOID);
VOID ExFreeToPagedLookasideList(IN PPAGED_LOOKASIDE, IN PVOID);
使用完需要刪除Lookaside物件
VOID ExDeleteNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST);
VOID ExDeletePagedLookasideList(IN PPAGED_LOOKASIDE_LIST);
範例:
typedef struct _MYDATASTRUCT
{
CHAR buffer[64];
} MYDATASTRUCT, *PMYDATASTRUCT;
#pragma INITCODE
VOID LookasideTest()
{
PAGED_LOOKASIDE_LIST pageList;
ExInitializePagedLookasideList(&pageList,NULL,NULL,0,sizeof(MYDATASTRUCT),'1234',0);
#define ARRAY_NUMBER 50
PMYDATASTRUCT MyObjectArray[ARRAY_NUMBER];
for (int i=0;i
MyObjectArray[i] = (PMYDATASTRUCT)ExAllocateFromPagedLookasideList(&pageList);
KdPrint(("Alloc MyObjectArray[%d]\n",i));
}
//模擬頻繁回收記憶體
for (i=0;i
KdPrint(("Free MyObjectArray[%d]\n",i));
ExFreeToPagedLookasideList(&pageList,MyObjectArray[i]);
MyObjectArray[i] = NULL;
}
ExDeletePagedLookasideList(&pageList);
//刪除Lookaside物件
}
沒有留言 :
張貼留言