reactos/sdk/lib/drivers/wdf/shared/object/km/wdfpoolkm.cpp
Victor Perevertkin 1f377076d7
[WDF] Fix KMDF so it can compile with ReactOS SDK
Not all files are included, but these are necessary to compile cdrom driver.
So far it can only be statically linked with drivers, a proper
implementation requires wdfldr helper driver
2020-11-03 00:06:27 +03:00

274 lines
6 KiB
C++

/*++
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 DoTraceMessage
extern "C" {
#if defined(EVENT_TRACING)
#include "wdfpoolkm.tmh"
#endif
}
// undo the previous masking
#undef IoAllocateMdl
#undef IoFreeMdl
__drv_maxIRQL(DISPATCH_LEVEL)
NTKERNELAPI
PMDL
STDCALL
IoAllocateMdl(
__in_opt __drv_aliasesMem PVOID VirtualAddress,
__in ULONG Length,
__in BOOLEAN SecondaryBuffer,
__in BOOLEAN ChargeQuota,
__inout_opt PIRP Irp
);
__drv_maxIRQL(DISPATCH_LEVEL)
NTKERNELAPI
VOID
STDCALL
IoFreeMdl(
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.
//
PMDL
FxMdlAllocateDebug(
__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;
}
VOID
FxMdlFreeDebug(
__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);
}
}
VOID
FxMdlDump(
__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);
}
}