mirror of
https://github.com/reactos/reactos.git
synced 2025-03-09 17:54:55 +00:00

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
274 lines
6 KiB
C++
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);
|
|
}
|
|
}
|
|
|