内核中内存操作的一些函数
文章目录
内核下面分配内存很简单. 我倒. 比3环下面还简单呢. 3环还需要调用两次函数, 0环更加方便.. 呵呵! 当然这只是使用上了. 内核中比用户态多了个后备列表内存(LookasideList),这翻译真是差劲..不过我看kmdkit里面也是这样翻译. 就将就着用吧! 还有的中文书籍好像根本就不翻译.. 估计也是不知道应该怎么翻译吧!
内核中还有个舒服的双向链表可以供使用. 估计是因为链表太常用了. 自己倒腾出来的链表每次写项目都改一次. 悲剧.. 还是系统直接提供好啊!这个双向链表也是非常容易使用的, 只是在遍历的时候我没搞明白. 咋个都不说遍历这个问题呢? 难道链表不需要遍历的么? 后来请教了杀哥才知道. 我倒还是需要自己写遍历函数. 不过挺简单, 这个就不算了!
这个后备列表内存, 也是比较好用. 使用也简单, 还有一些内存操作的函数, 这些函数在Win32下面也是有的, 所以直接划过..
```c++
/*
Windows内核下链表和后备列表操作!
编译方法参见makefile.
*/
#include
typedef struct tagDATA { DWORD dwValue; LIST_ENTRY ListEntry; }DATA, *PDATA; //=========================================================================== // 内核中的链表使用. 非常舒服啊 #pragma code_seg( "INIT" ) VOID TestLinkList() { ULONG i; PDATA pData = NULL; PLIST_ENTRY pEntry; LIST_ENTRY ListHead; //初始化链表 InitializeListHead( &ListHead );
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
//在链表从头部开始插入10个元素 KdPrint(( "\nBegin insert to link list Head!\n"; )); for( i = 0; i <= 10; i++, pData = NULL ) { pData = (PDATA)ExAllocatePool( PagedPool, sizeof(DATA) ); if ( !pData ) { KdPrint(( "Memory Alloccation Error!\n"; )); return; } pData->dwValue = i; //在头部进行插入 InsertHeadList( &ListHead, &pData->ListEntry ); } |
//————————————————————————— //从链表尾部中取出, 并显示 KdPrint(( “\nBegin remove from link list Tail!\n” ));
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
for( ;!IsListEmpty(&ListHead); pData = NULL ) { pEntry = RemoveTailList( &ListHead ); //获取我们的数据指针 pData = CONTAINING_RECORD( pEntry, DATA, ListEntry ); if ( !pData ) { KdPrint(( "Get Data Error!\n" )); return; } KdPrint(( "%d\t", pData->dwValue )); ExFreePool( pData ); } |
//=========================================================================== //在链表尾部插入10个元素 KdPrint(( “\nBegin insert to link list Tail!\n”; )); for( i = 0; i <= 10; i++, pData = NULL ) { pData = (PDATA)ExAllocatePool( PagedPool, sizeof(DATA) ); if ( !pData ) { KdPrint(( “Memory Alloccation Error!\n”; )); return; }
1 2 3 4 5 |
pData->dwValue = i; //在尾部进行插入 InsertTailList( &ListHead, &pData->ListEntry ); } |
//=========================================================================== //遍历链表, 从头往后面遍历 KdPrint(( “\nTraverse the list!\n” )); for( pEntry = ListHead.Flink; pEntry != &ListHead; pEntry = pEntry->Flink, pData = NULL ) {
1 2 3 4 |
//获取数据指针 pData = CONTAINING_RECORD( pEntry,DATA, ListEntry ); KdPrint(( "%d\t", pData->dwValue )); } |
//=========================================================================== //从链表头部, 并显示 KdPrint(( “\nBegin remove from link list\n” ));
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
for( ;!IsListEmpty( &ListHead ); pData = NULL ) { //从链表头部进行删除 PLIST_ENTRY pEntry = RemoveHeadList( &ListHead ); //获取我们的数据指针 pData = CONTAINING_RECORD(pEntry, DATA, ListEntry ); if ( !pData ) { KdPrint(( "Get Data Error!\n" )); return; } KdPrint(( "%d \t", pData->dwValue )); ExFreePool( pData ); } |
} //=========================================================================== // 内核中的后备列表的使用.后备列表使用太简单了还没有kmdkit的例子号 #pragma code_seg( “INIT” ) VOID LookasideTest() { int i; PDATA MyDataArr[ARRAY_NUMBER] = {0}; PAGED_LOOKASIDE_LIST PageLookaside;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
KdPrint(( "Lookaside的使用!\n" )); //初始化分页后备列表,还有一个非分页的.. ExInitializePagedLookasideList( &PageLookaside,NULL,NULL,0,sizeof(DATA), "1234", 0 ); //模拟频繁申请内存 for ( i=0; i < ARRAY_NUMBER; i++ ) { MyDataArr[i] = (PDATA)ExAllocateFromPagedLookasideList( &PageLookaside ); RtlFillBytes( MyDataArr[i], sizeof(DATA), 0 ); MyDataArr[i]->dwValue = i; } //模拟频繁回收内存 for ( i = 0 ; i < ARRAY_NUMBER; i++ ) { KdPrint(( "%d\t", MyDataArr[i]->dwValue )); RtlZeroBytes( MyDataArr[i], sizeof(DATA) ); ExFreeToPagedLookasideList( &PageLookaside, MyDataArr[i] ); MyDataArr[i] = NULL; } //删除Lookaside对象 ExDeletePagedLookasideList( &PageLookaside ); KdPrint(( "\nLookaside 使用完成!\n" )); |
} //=========================================================================== //内核中一些内存方面的函数使用, Win32下面也是有的, 差不多了 #pragma code_seg( “INIT” ) VOID RtlTest() { PUCHAR pBuffer = NULL; PUCHAR pBuffer2 = NULL; ULONG ulRet;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
//分配分页内存, 并用0填充 pBuffer = (PUCHAR)ExAllocatePool(PagedPool,BUFFER_SIZE); RtlZeroMemory(pBuffer,BUFFER_SIZE); //分配分页内存, 并用0xAA填充 pBuffer2 = (PUCHAR)ExAllocatePool(PagedPool,BUFFER_SIZE); RtlFillMemory(pBuffer2,BUFFER_SIZE,0xAA); //内存拷贝 RtlCopyMemory( pBuffer, pBuffer2,BUFFER_SIZE ); //判断内存是否一致 ulRet = RtlCompareMemory( pBuffer,pBuffer2, BUFFER_SIZE ); if ( ulRet == BUFFER_SIZE ) { KdPrint(( "两块内存完全相等.\n" )); }else { KdPrint(( "两块内存并不完全相等.\n" )); } |
}
NTSTATUS DriverEntry( PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pUSzReg ) {
1 2 3 4 |
TestLinkList(); //链表测试 LookasideTest(); //后备列表内存测试 RtlTest(); //常用内存函数测试 return -1; |
}
文章作者 忆杰
上次更新 2011-10-10