mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-28 04:13:35 +00:00
[SDK][WDFLDR] Add kmdf loader driver [SDK][WDF] Add kmdf drver init static library [SDK][WDF] Modify kmdf driver for working with wdfldr driver [SDK][CDROM] Cdrom driver dynamically linking with kmdf [SDK][WDF] Add kmdfdriver module type [SDK][WDF][USBDEX][NTOSKRNL_VISTA] Fully enable KMDF [KMDF][WDFLDR][WDF01000] Fix Windows 10 Compatibility WDFLDR and WDF01000 [WDF01000] NO_KERNEL_LIST_ENTRY_CHECKS for wdf01000 3rd party code This PR is an accumulation of three peoples work, with the goal of the trying to get WDF to work like it should. This has been tested in combination with some extra NT6+ ntoskrnl against multiple drivers. --------- Co-authored-by: Max Korostil <[email protected]> Co-authored-by: Victor Perevertkin <[email protected]> Co-authored-by: Adam Słaboń <[email protected]> Co-authored-by: Hermès BÉLUSCA - MAÏTO <[email protected]>
275 lines
6.0 KiB
C++
275 lines
6.0 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
|
|
NTAPI
|
|
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
|
|
NTAPI
|
|
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);
|
|
}
|
|
}
|
|
|