今天碰到一個比較棘手的內存處理問題。
首先來看一個數據結構:
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那一塊資源呢?不得而知!!望知道的指點一二。
網上有人回覆說: