zoukankan      html  css  js  c++  java
  • 驱动 内存管理 学习

    H头文件:

    #pragma once //只要在头文件的最开始加入这条杂注,
    			 //就能够保证头文件只被编译一次
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    #include <ntddk.h>
    #ifdef __cplusplus
    }
    #endif
    
    #define PAGECODE code_seg("PAGE")
    #define	LOCKEDCODE code_seg()
    #define	INITCODE code_seg("INIT")
    
    #define	PAGEDATA data_seg("PAGE")
    #define	LOCKEDDATA data_seg()
    #define	INITDATA data_seg("INIT")
    
    #define arraysize(p) (sizeof(p)/sizeof((p)[0]))
    
    typedef struct _DEVICE_EXTENSION
    {
    	PDEVICE_OBJECT pDevice;
    	UNICODE_STRING uStrDeviceName;
    	UNICODE_STRING uStrSymLinkName;
    } DEVICE_EXTENSION,*PDEVICE_EXTENSION;
    
    #define PRINTF(msg)
    {
    	KdPrint(("\\\\\\\\\\\\\\\
    "));
    	KdPrint((msg));
    	KdPrint(("\\\\\\\\\\\\\\\
    "));
    }
    
    VOID LookasideTest();
    VOID LinkListTest();
    VOID NewTest();
    NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject);
    VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject);
    NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp);
    VOID DisPlayItsProcessName();
    


    CPP文件:

    #include "DriverMemory.h"
    typedef struct _MYDATASTRUCT
    {
    	CHAR buffer[64];
    } MYDATASTRUCT, *PMYDATASTRUCT;
    
    #pragma INITCODE
    VOID LookasideTest()//管理内存的系列函数
    {
    	KdPrint(("初始化Lookaside对象
    "));
    	PAGED_LOOKASIDE_LIST pageList;
    	ExInitializePagedLookasideList(&pageList,NULL,NULL,0,
    		sizeof(MYDATASTRUCT),'1234',0);
    	PMYDATASTRUCT MyData[50];
    	KdPrint(("模拟频繁申请内存
    "));
    	for (int i=0;i<50;i++)
    	{
    		MyData[i] = (PMYDATASTRUCT)ExAllocateFromPagedLookasideList(&pageList);
    	}
    	//这里可以对内存进行操作了
    	for (int i=0;i<50;i++)
    	{
    		strcpy(MyData[i]->buffer,"实验");
    	}
    	for (int i=0;i<50;i++)
    	{
    		KdPrint(("%s",MyData[i]->buffer));
    	}
    		KdPrint(("模拟频繁回收内存"));
    	for (int i=0;i<50;i++)
    	{
    		ExFreeToPagedLookasideList(&pageList,MyData[i]);
    	}
    		KdPrint(("删除Lookaside对象"));
    		ExDeletePagedLookasideList(&pageList);
    
    		PRINTF("RTL 内存函数 开始
    ");
    	PUCHAR PData = (PUCHAR)ExAllocatePool(PagedPool,1024);
    	RtlZeroMemory(PData,1024);
    	
    	PUCHAR PData2 = (PUCHAR)ExAllocatePool(PagedPool,1024);
    	RtlFillMemory(PData2,1024,0x31);
    
    	RtlCopyBytes(PData2,PData,1024);
    
    	ULONG FLAG = RtlCompareMemory(PData,PData2,1024);
    	if (FLAG == 1024)
    	{
    		PRINTF("RtlCopyBytes 复制成功
    ");
    	}
    	else
    		PRINTF("RtlCopyBytes 复制不成功
    ");
    
    }
    typedef struct _MYDATASTRUCT2
    {
    	ULONG number;
    	LIST_ENTRY ListEntry;
    }MYDATASTRUCT2,*PMYDATASTRUCT2;
    
    #pragma INITCODE
    VOID LinkListTest()
    {
    	LIST_ENTRY linkListHead;
    
    	InitializeListHead(&linkListHead);
    
    
    	KdPrint(("我的实验:定义10个pData
    "));
    
    	PMYDATASTRUCT2 pData[10];
    	//在链表中插入10个元素
    	KdPrint(("在链表中插入10个元素
    "));
    	for (int i =0;i<10;i++)
    	{
    		pData[i] = (PMYDATASTRUCT2)ExAllocatePool(PagedPool,sizeof(MYDATASTRUCT2));
    		pData[i]->number =i;
    		InsertHeadList(&linkListHead,&pData[i]->ListEntry);
    	}
    
    	KdPrint(("读取这10个元素
    "));
    	for (int i =0;i<10;i++)
    	{
    		KdPrint(("pData 的 number = %d
    ",pData[i]->number));
    	}
    	
    	//从链表中取出,并显示
    	KdPrint(("从链表中取出数据 显示,并销毁
    "));
    	int i=0;
    	while (!IsListEmpty(&linkListHead))
    	{
    		KdPrint(("从链表头部删除
    "));
    		PLIST_ENTRY pEntry = RemoveHeadList(&linkListHead);
    		//只获得了PLIST_ENTRY  想要得到数据 就必须要这个函数: 第三个参数是我定义的结构体中的元素
    		pData[i] = CONTAINING_RECORD(pEntry,MYDATASTRUCT2,ListEntry);
    		
    		KdPrint(("%d
    ",pData[i]->number));
    		ExFreePool(pData[i]);
    		i++;
    	}
    
    	KdPrint(("书上实验:定义1个pMyData
    "));
    	PMYDATASTRUCT2 pMyData;
    
    	//在链表中插入10个元素
    	KdPrint(("在链表中插入10个元素
    "));
    	for (int i =0;i<10;i++)
    	{
    		pMyData = (PMYDATASTRUCT2)ExAllocatePool(PagedPool,sizeof(MYDATASTRUCT2));
    		pMyData->number =i;
    		InsertHeadList(&linkListHead,&pMyData->ListEntry);
    	}
    	
    	//从链表中取出,并显示
    	KdPrint(("从链表中取出数据 显示,并销毁
    "));
    	while (!IsListEmpty(&linkListHead))
    	{
    		KdPrint(("从链表尾部删除
    "));
    		PLIST_ENTRY pEntry = RemoveTailList(&linkListHead);
    		//只获得了PLIST_ENTRY  想要得到数据 就必须要这个函数: 第三个参数是我定义的结构体中的元素
    		pMyData = CONTAINING_RECORD(pEntry,MYDATASTRUCT2,ListEntry);
    		KdPrint(("%d
    ",pMyData->number));
    		ExFreePool(pMyData);
    	}
    
    }
    void * __cdecl operator new(size_t size,POOL_TYPE PoolType=PagedPool)
    {
    		KdPrint(("global operator new
    "));
    		KdPrint(("Allocate size : %d
    ",size));
    		return ExAllocatePool(PoolType,size);
    }
    void  __cdecl operator delete(void * pointer)
    {
    		KdPrint(("Global delete operator
    "));
    		ExFreePool(pointer);
    }
    class TestClass
    {
    public:
    	TestClass()
    	{
    		KdPrint(("TestClass:TestClass()
    "));
    	}
    	~TestClass()
    	{
    		KdPrint(("TestClass:~TestClass()
    "));
    	}
    	void * operator new(size_t size, POOL_TYPE PoolType = PagedPool)
    	{
    		KdPrint(("TestClass:new
    "));
    		KdPrint(("Allocate size : %d
    ",size));
    		return ExAllocatePool(PoolType,size);
    	}
    	void  operator delete(void * pointer)
    	{
    		KdPrint(("TestClass:delete
    "));
    		return ExFreePool(pointer);
    	}
    public:
    	char buffer[1024];
    };
    #pragma INITCODE
    VOID NewTest()
    {
    		KdPrint(("进入 NewText
    "));
    		
    		KdPrint(("类中  new delte:
    "));
    		TestClass *MyNewTest = new TestClass;
    		strcpy(MyNewTest->buffer,"第一次的buffer
    ");
    		KdPrint(("%s
    ",MyNewTest->buffer));
    		delete MyNewTest;
    
    		MyNewTest = new(NonPagedPool) TestClass;
    		strcpy(MyNewTest->buffer,"第二次的buffer
    ");
    		KdPrint(("%s
    ",MyNewTest->buffer));
    		delete MyNewTest;
    		
    		KdPrint(("全局重载   new delete:
    "));
    		char *pBuffer = new(PagedPool) char[100];
    		strcpy(pBuffer,"第一次的pBuffer
    ");
    		KdPrint(("%s
    ",pBuffer));
    		delete [] pBuffer;
    		
    		pBuffer = new(NonPagedPool) char[100];
    		strcpy(pBuffer,"第二次的pBuffer
    ");
    		KdPrint(("%s
    ",pBuffer));
    		delete [] pBuffer;
    		
    }
    #pragma INITCODE
    extern "C" NTSTATUS DriverEntry(
    		IN PDRIVER_OBJECT pDriverObject,
    		IN PUNICODE_STRING pRegistryPath
    								)
    {
    	NTSTATUS status;
    	KdPrint(("进入 DriverEntry
    "));
    
    	pDriverObject->DriverUnload = HelloDDKUnload;
    	pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine;
    	pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine;
    	pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;
    	pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine;
    
    	status = CreateDevice(pDriverObject);
    
    	PRINTF("显示进程
    ");
    	DisPlayItsProcessName();
    
    	PRINTF("内存管理
    ");
    	LookasideTest();
    
    	PRINTF("链表操作
    ");
    	LinkListTest();
    
    	PRINTF("new delte 重载学习
    ");
    
    	NewTest();
    	KdPrint(("DriverEntry end
    "));
    	return status;
    }
    
    
    
    #pragma INITCODE
    VOID DisPlayItsProcessName()//得到当前进程名称
    {
    	PEPROCESS PeProcess = PsGetCurrentProcess();
    	PTSTR ProcessName = (PTSTR)((ULONG)PeProcess + 0x174);
    	KdPrint(("%s
    ",ProcessName));
    }
    
    #pragma INITCODE
    NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject)
    {
    	NTSTATUS status;
    	PDEVICE_OBJECT pDevObj;
    	PDEVICE_EXTENSION pDevExt;
    
    		UNICODE_STRING strDev;
    	RtlInitUnicodeString(&strDev,L"\Device\MyDDK");
    
    
    	status = IoCreateDevice(pDriverObject,
    		sizeof(DEVICE_EXTENSION),
    		&(UNICODE_STRING)strDev,
    		FILE_DEVICE_UNKNOWN,
    		0,
    		TRUE,
    		&pDevObj);
    	if (!NT_SUCCESS(status))
    	{
    		KdPrint(("创建设备失败!
    "));
    		return status;
    	}
    	pDevObj->Flags |= DO_BUFFERED_IO;
    
    		pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
    		pDevExt->pDevice = pDevObj;
    		pDevExt->uStrDeviceName = strDev;
    
    	UNICODE_STRING strSymLinkName;
    	RtlInitUnicodeString(&strSymLinkName,L"\??\MyDDK");
    		pDevExt->uStrSymLinkName = strSymLinkName;
    
    	status = IoCreateSymbolicLink(&strSymLinkName,&strDev);
    
    	if (!NT_SUCCESS(status))
    	{
    			KdPrint(("创建符号失败!
    "));
    			IoDeleteDevice(pDevObj);
    			return status;
    	}
    
    
    	return STATUS_SUCCESS;
    }
    #pragma PAGECODE
    VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject)
    {
    	PDEVICE_OBJECT pNextObj;
    	
    	KdPrint(("Enter DriverUnload
    "));
    
    	pNextObj = pDriverObject->DeviceObject;
    
    	while (pNextObj != NULL)
    	{
    		PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
    			pNextObj->DeviceExtension;
    		UNICODE_STRING pLinkName = pDevExt->uStrSymLinkName;
    		
    		IoDeleteSymbolicLink(&pLinkName);
    		
    		pNextObj = pNextObj->NextDevice;
    		IoDeleteDevice(pDevExt->pDevice);
    	}
    }
    #pragma PAGECODE
    NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,
    								 IN PIRP pIrp)
    {
    	NTSTATUS status = STATUS_SUCCESS;
    	KdPrint(("Enter HelloDDKDispatchRoutine
    "));
    	
    	pIrp->IoStatus.Status = status;
    	pIrp->IoStatus.Information = 0;
    	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    	KdPrint(("Leave HelloDDKDispatchRoutine
    "));
    	return status;
    }




    下面是DriverMonitor  记录的 调试信息:

    00000000 0.00000000进入 DriverEntry

    00000001 0.00025925\\\\\\\
    00000002 0.00026791显示进程
    00000003 0.00027657\\\\\\\
    00000004 0.00028551System
    00000005 0.00029389\\\\\\\
    00000006 0.00035284内存管理
    00000007 0.00036122\\\\\\\
    00000008 0.00037016初始化Lookaside对象
    00000009 0.00037938模拟频繁申请内存
    00000052 0.00093252实验//`````````````
    00000053 0.00093978实验
    00000058 0.00097554实验
    00000059 0.00098253实验//`````````````一共50个 “实验” 这里省略显示
    00000060 0.00101577模拟频繁回收内存
    00000061 0.00112221删除Lookaside对象
    00000062 0.00113674\\\\\\\
    00000063 0.00114540RTL 内存函数 开始
    00000064 0.00115350\\\\\\\
    00000065 0.00117417\\\\\\\
    00000066 0.00118339RtlCopyBytes 复制成功
    00000067 0.00119149\\\\\\\
    00000068 0.00119987\\\\\\\
    00000069 0.00120742链表操作
    00000070 0.00121580\\\\\\\
    00000071 0.00122502我的实验:定义10个pData
    00000072 0.00123368在链表中插入10个元素
    00000073 0.00127111读取这10个元素
    00000074 0.00128117pData 的 number = 0
    00000075 0.00129039pData 的 number = 1
    00000076 0.00134123pData 的 number = 2
    00000077 0.00135213pData 的 number = 3
    00000078 0.00136107pData 的 number = 4
    00000079 0.00137001pData 的 number = 5
    00000080 0.00137895pData 的 number = 6
    00000081 0.00138761pData 的 number = 7
    00000082 0.00139655pData 的 number = 8
    00000083 0.00140549pData 的 number = 9
    00000084 0.00141526从链表中取出数据 显示,并销毁
    00000085 0.00142337从链表头部删除
    00000086 0.001431199
    00000087 0.00144013从链表头部删除
    00000088 0.001447678
    00000089 0.00145605从链表头部删除
    00000090 0.001463317
    00000091 0.00147142从链表头部删除
    00000092 0.001478686
    00000093 0.00148706从链表头部删除
    00000094 0.001494325
    00000095 0.00150270从链表头部删除
    00000096 0.001510254
    00000097 0.00151835从链表头部删除
    00000098 0.001525893
    00000099 0.00153399从链表头部删除
    00000100 0.001541542
    00000101 0.00154992从链表头部删除
    00000102 0.001557181
    00000103 0.00156584从链表头部删除
    00000104 0.001573100
    00000105 0.00158288书上实验:定义1个pMyData
    00000106 0.00159154在链表中插入10个元素
    00000107 0.00161250从链表中取出数据 显示,并销毁
    00000108 0.00162060从链表尾部删除
    00000109 0.001627860
    00000110 0.00163596从链表尾部删除
    00000111 0.001643231
    00000112 0.00165161从链表尾部删除
    00000113 0.001658872
    00000114 0.00166725从链表尾部删除
    00000115 0.001674513
    00000116 0.00168262从链表尾部删除
    00000117 0.001689884
    00000118 0.00169854从链表尾部删除
    00000119 0.001705805
    00000120 0.00171391从链表尾部删除
    00000121 0.001721456
    00000122 0.00172955从链表尾部删除
    00000123 0.001736817
    00000124 0.00174519从链表尾部删除
    00000125 0.001752468
    00000126 0.00176084从链表尾部删除
    00000127 0.001829569
    00000128 0.00184074\\\\\\\
    00000129 0.00184968new delte 重载学习
    00000130 0.00185778\\\\\\\
    00000131 0.00186616进入 NewText
    00000132 0.00187454类中  new delte:
    00000133 0.00188264TestClass:new
    00000134 0.00189270Allocate size : 1024
    00000135 0.00190695TestClass:TestClass()
    00000136 0.00191589第一次的buffer
    00000137 0.00192231
    00000138 0.00193153TestClass:~TestClass()
    00000139 0.00194019TestClass:delete
    00000140 0.00194857TestClass:new
    00000141 0.00195751Allocate size : 1024
    00000142 0.00199858TestClass:TestClass()
    00000143 0.00200724第二次的buffer
    00000144 0.00201366
    00000145 0.00202288TestClass:~TestClass()
    00000146 0.00203126TestClass:delete
    00000147 0.00204020全局重载   new delte:
    00000148 0.00204886global operator new
    00000149 0.00205808Allocate size : 100
    00000150 0.00206730第一次的pBuffer
    00000151 0.00207373
    00000152 0.00208267Global delete operator
    00000153 0.00209161global operator new
    00000154 0.00210055Allocate size : 100
    00000155 0.00210949第二次的pBuffer
    00000156 0.00211591
    00000157 0.00212485Global delete operator
    00000158 0.00213351DriverEntry end
    00000159 97.35410309Enter DriverUnload
  • 相关阅读:
    ASP.NET编程中非常有用的例子
    打包样式资源
    9.使用类的2个注意点
    面向对象案例
    super必须放到子类this之前
    PHP:根据二维数组中的某个字段进行排序
    Vuex的五个核心属性
    利用按钮控制listview的当前选择项,滚动条跟随动
    c#通过进程名字获取进程路径
    判断客户端是否安装realplayer
  • 原文地址:https://www.cnblogs.com/zcc1414/p/3982480.html
Copyright © 2011-2022 走看看