今天碰到一个比较棘手的内存处理问题。
首先来看一个数据结构:
typedef struct _IRP_AND_FILTER { PIRP pIrp; PMS_FILTER pFilter; ULONG OutputBufferLength; }IrpAndFilter, *PIrpAndFilter;
其中pIrp是一个IRP指针,pFilter指的是一个Filter Driver的实例,最后一个数字式OutputBuffer的长度。接着看代码:
pIrpFilter = (PIrpAndFilter)NdisAllocateMemoryWithTagPriority(pFilter->FilterHandle,sizeof(IrpAndFilter),FILTER_ALLOC_TAG, LowPoolPriority); if(pIrpFilter != NULL)
这里为这个结构分配了一个size为sizeof(IrpAndFilter)的空间。谁分配,谁释放的原则告诉我们等资源不再使用的时候需要释放。现在的问题是:pIrp在内核的调度函数执行完毕,调用IoCompleteRequest(pIrp, IO_NO_INCREMENT);之后仍然不能释放,因为里面还有一个OutputBuffer的数据需要传递给User层,而且估计会在程序关闭时Cleanup,释放这些资源。然后是pFilter这个是指向Filter实例的指针,用完也不能释放,因为其他部分程序会使用到,而且最后程序在FilterDetach()释放该资源,现在只剩下OutputBufferLength,这个用完就可以释放了。所以纠结的是现在这个资源怎么办啊?接着看这个资源是如何使用的:
Status = PsCreateSystemThread(&threadHandle, THREAD_ALL_ACCESS, NULL, NULL, NULL, (PKSTART_ROUTINE) sendMyOwnPacketThread, pIrpFilter );
以线程的方式传给sendMyOwnPacketThread函数,然后:
VOID sendMyOwnPacketThread( IN PIrpAndFilter pIrpAndFilter ) { NTSTATUS Status; //拿到这些资源 pFilter = (PMS_FILTER)pIrpAndFilter->pFilter;//get current filter instance pIrp = (PIRP)pIrpAndFilter->pIrp;//get current IPR OutputBuffer = (PUCHAR)pIrp->AssociatedIrp.SystemBuffer; OutputBufferLength = (ULONG)pIrpAndFilter->OutputBufferLength; //使用资源 //结束前 pIrp->IoStatus.Status = Status; pIrp->IoStatus.Information = bufSize; IoCompleteRequest(pIrp, IO_NO_INCREMENT); PsTerminateSystemThread(STATUS_SUCCESS);//end the thread //是否释放资源 //NdisFreeMemory(pIrpAndFilter,sizeof(IrpAndFilter),0); }
我测试过了,释放资源有问题,就如前面说的,两个指针都不能释放,这下就傻眼了,没有释放,程序倒是正常执行,释放反而错了。我知道那两个资源不能在这里释放,可是我Allocate一块空间了,难道就这样了...还是至少要释放ULONG那一块资源呢?不得而知!!望知道的指点一二。
网上有人回复说: