Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275/*++
Copyright (c) Microsoft Corporation
Module Name:
wdfpoolkm.cpp
Abstract:
This module implements the driver frameworks pool routines functionality only applicable in kernel mode
Author:
Environment:
Kernel mode only
Revision History:
--*/
#include "fxobjectpch.hpp"
// We use DoTraceMessageextern "C" {#if defined(EVENT_TRACING)#include "wdfpoolkm.tmh"#endif}
// undo the previous masking#undef IoAllocateMdl#undef IoFreeMdl
__drv_maxIRQL(DISPATCH_LEVEL)NTKERNELAPIPMDLNTAPIIoAllocateMdl( __in_opt __drv_aliasesMem PVOID VirtualAddress, __in ULONG Length, __in BOOLEAN SecondaryBuffer, __in BOOLEAN ChargeQuota, __inout_opt PIRP Irp );
__drv_maxIRQL(DISPATCH_LEVEL)NTKERNELAPIVOIDNTAPIIoFreeMdl( PMDL Mdl );
//// Windows Driver Framework Pool Tracking//// This module implements a generic pool tracking mechanism// if pool verifier mode is enabled.//// There can be multiple pools, each represented by a FX_POOL header.//// When the framework is supplied as a DLL, there is a global// pool that represents allocations for the framework DLL itself. These// allocations are pool allocations and object allocations.//// The driver's pool allocations are not currently tracked. If the driver needs// to use pool outside of the framework objects, it calls the WDM// ExAllocatePoolWithTag and ExFreePool(WithTag) APIs.//
PMDLFxMdlAllocateDebug( __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObject* Owner, __in PVOID VirtualAddress, __in ULONG Length, __in BOOLEAN SecondaryBuffer, __in BOOLEAN ChargeQuota, __in PVOID CallersAddress ){ FxDriverGlobalsDebugExtension* pExtension; FxAllocatedMdls* pAllocated, **ppNext; ULONG i; PMDL pMdl; KIRQL irql;
pExtension = FxDriverGlobals->DebugExtension; if (pExtension == NULL) { return IoAllocateMdl(VirtualAddress, Length, SecondaryBuffer, ChargeQuota, NULL); }
pAllocated = &pExtension->AllocatedMdls; ppNext = NULL; pMdl = NULL;
KeAcquireSpinLock(&pExtension->AllocatedMdlsLock, &irql);
while (pAllocated != NULL && pAllocated->Count == NUM_MDLS_IN_INFO) { ppNext = &pAllocated->Next; pAllocated = pAllocated->Next; }
if (pAllocated == NULL) { // // No more entries, allocate a new table // pAllocated = (FxAllocatedMdls*) ExAllocatePoolWithTag( NonPagedPool, sizeof(FxAllocatedMdls), FxDriverGlobals->Tag);
if (pAllocated != NULL) { // // Zero out the new buffer and link it in to the list // RtlZeroMemory(pAllocated, sizeof(*pAllocated)); *ppNext = pAllocated; } else { // // Could not allocate a new table, return error // KeReleaseSpinLock(&pExtension->AllocatedMdlsLock, irql);
return NULL; } }
for (i = 0; i < NUM_MDLS_IN_INFO; i++) { if (pAllocated->Info[i].Mdl != NULL) { continue; }
pMdl = IoAllocateMdl(VirtualAddress, Length, SecondaryBuffer, ChargeQuota, NULL);
if (pMdl != NULL) { pAllocated->Info[i].Mdl = pMdl; pAllocated->Info[i].Owner = Owner; pAllocated->Info[i].Caller = CallersAddress; pAllocated->Count++; } break; }
KeReleaseSpinLock(&pExtension->AllocatedMdlsLock, irql);
return pMdl;}
VOIDFxMdlFreeDebug( __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PMDL Mdl ){ FxDriverGlobalsDebugExtension* pExtension; FxAllocatedMdls* pAllocated, **ppNext; ULONG i; KIRQL irql; BOOLEAN found;
pExtension = FxDriverGlobals->DebugExtension; if (pExtension == NULL) { IoFreeMdl(Mdl); return; }
found = FALSE;
pAllocated = &pExtension->AllocatedMdls; ppNext = NULL;
KeAcquireSpinLock(&pExtension->AllocatedMdlsLock, &irql);
while (pAllocated != NULL) { for (i = 0; i < NUM_MDLS_IN_INFO; i++) { if (pAllocated->Info[i].Mdl != Mdl) { continue; }
RtlZeroMemory(&pAllocated->Info[i], sizeof(pAllocated->Info[i]));
pAllocated->Count--;
if (pAllocated->Count == 0 && pAllocated != &pExtension->AllocatedMdls) { // // Remove the current table from the chain // *ppNext = pAllocated->Next;
// // And free it // ExFreePool(pAllocated); }
IoFreeMdl(Mdl); found = TRUE; break; }
if (found) { break; }
ppNext = &pAllocated->Next; pAllocated = pAllocated->Next; }
KeReleaseSpinLock(&pExtension->AllocatedMdlsLock, irql);
if (found == FALSE) {
FxVerifierDbgBreakPoint(FxDriverGlobals); }}
VOIDFxMdlDump( __in PFX_DRIVER_GLOBALS FxDriverGlobals ){ FxAllocatedMdls *pCur; BOOLEAN leak;
if (FxDriverGlobals->DebugExtension == NULL) { return; }
leak = FALSE;
for (pCur = &FxDriverGlobals->DebugExtension->AllocatedMdls; pCur != NULL; pCur = pCur->Next) { ULONG i;
for (i = 0; i < NUM_MDLS_IN_INFO; i++) { if (pCur->Info[i].Mdl != NULL) { leak = TRUE;
DoTraceLevelMessage( FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, "PMDL 0x%p leaked, FxObject owner %p, Callers Address %p", pCur->Info[i].Mdl, pCur->Info[i].Owner, pCur->Info[i].Caller); } } }
if (leak) { FxVerifierDbgBreakPoint(FxDriverGlobals); }}