ReactOS  0.4.15-dev-2700-g4b4ffa9
wdfpoolkm.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  wdfpoolkm.cpp
8 
9 Abstract:
10 
11  This module implements the driver frameworks pool routines
12  functionality only applicable in kernel mode
13 
14 Author:
15 
16 
17 
18 
19 Environment:
20 
21  Kernel mode only
22 
23 Revision History:
24 
25 
26 --*/
27 
28 #include "fxobjectpch.hpp"
29 
30 // We use DoTraceMessage
31 extern "C" {
32 #if defined(EVENT_TRACING)
33 #include "wdfpoolkm.tmh"
34 #endif
35 }
36 
37 // undo the previous masking
38 #undef IoAllocateMdl
39 #undef IoFreeMdl
40 
43 PMDL
44 STDCALL
51  );
52 
55 VOID
56 STDCALL
57 IoFreeMdl(
58  PMDL Mdl
59  );
60 
61 //
62 // Windows Driver Framework Pool Tracking
63 //
64 // This module implements a generic pool tracking mechanism
65 // if pool verifier mode is enabled.
66 //
67 // There can be multiple pools, each represented by a FX_POOL header.
68 //
69 // When the framework is supplied as a DLL, there is a global
70 // pool that represents allocations for the framework DLL itself. These
71 // allocations are pool allocations and object allocations.
72 //
73 // The driver's pool allocations are not currently tracked. If the driver needs
74 // to use pool outside of the framework objects, it calls the WDM
75 // ExAllocatePoolWithTag and ExFreePool(WithTag) APIs.
76 //
77 
78 
79 
80 PMDL
82  __in PFX_DRIVER_GLOBALS FxDriverGlobals,
88  __in PVOID CallersAddress
89  )
90 {
92  FxAllocatedMdls* pAllocated, **ppNext;
93  ULONG i;
94  PMDL pMdl;
95  KIRQL irql;
96 
97  pExtension = FxDriverGlobals->DebugExtension;
98  if (pExtension == NULL) {
100  Length,
102  ChargeQuota,
103  NULL);
104  }
105 
106  pAllocated = &pExtension->AllocatedMdls;
107  ppNext = NULL;
108  pMdl = NULL;
109 
110  KeAcquireSpinLock(&pExtension->AllocatedMdlsLock, &irql);
111 
112  while (pAllocated != NULL && pAllocated->Count == NUM_MDLS_IN_INFO) {
113  ppNext = &pAllocated->Next;
114  pAllocated = pAllocated->Next;
115  }
116 
117  if (pAllocated == NULL) {
118  //
119  // No more entries, allocate a new table
120  //
121  pAllocated = (FxAllocatedMdls*) ExAllocatePoolWithTag(
122  NonPagedPool, sizeof(FxAllocatedMdls), FxDriverGlobals->Tag);
123 
124  if (pAllocated != NULL) {
125  //
126  // Zero out the new buffer and link it in to the list
127  //
128  RtlZeroMemory(pAllocated, sizeof(*pAllocated));
129  *ppNext = pAllocated;
130  }
131  else {
132  //
133  // Could not allocate a new table, return error
134  //
136 
137  return NULL;
138  }
139  }
140 
141  for (i = 0; i < NUM_MDLS_IN_INFO; i++) {
142  if (pAllocated->Info[i].Mdl != NULL) {
143  continue;
144  }
145 
147  Length,
149  ChargeQuota,
150  NULL);
151 
152  if (pMdl != NULL) {
153  pAllocated->Info[i].Mdl = pMdl;
154  pAllocated->Info[i].Owner = Owner;
155  pAllocated->Info[i].Caller = CallersAddress;
156  pAllocated->Count++;
157  }
158  break;
159  }
160 
162 
163  return pMdl;
164 }
165 
166 VOID
168  __in PFX_DRIVER_GLOBALS FxDriverGlobals,
169  __in PMDL Mdl
170  )
171 {
172  FxDriverGlobalsDebugExtension* pExtension;
173  FxAllocatedMdls* pAllocated, **ppNext;
174  ULONG i;
175  KIRQL irql;
176  BOOLEAN found;
177 
178  pExtension = FxDriverGlobals->DebugExtension;
179  if (pExtension == NULL) {
180  IoFreeMdl(Mdl);
181  return;
182  }
183 
184  found = FALSE;
185 
186  pAllocated = &pExtension->AllocatedMdls;
187  ppNext = NULL;
188 
189  KeAcquireSpinLock(&pExtension->AllocatedMdlsLock, &irql);
190 
191  while (pAllocated != NULL) {
192  for (i = 0; i < NUM_MDLS_IN_INFO; i++) {
193  if (pAllocated->Info[i].Mdl != Mdl) {
194  continue;
195  }
196 
197  RtlZeroMemory(&pAllocated->Info[i],
198  sizeof(pAllocated->Info[i]));
199 
200  pAllocated->Count--;
201 
202  if (pAllocated->Count == 0 &&
203  pAllocated != &pExtension->AllocatedMdls) {
204  //
205  // Remove the current table from the chain
206  //
207  *ppNext = pAllocated->Next;
208 
209  //
210  // And free it
211  //
212  ExFreePool(pAllocated);
213  }
214 
215  IoFreeMdl(Mdl);
216  found = TRUE;
217  break;
218  }
219 
220  if (found) {
221  break;
222  }
223 
224  ppNext = &pAllocated->Next;
225  pAllocated = pAllocated->Next;
226  }
227 
229 
230  if (found == FALSE) {
231 
232 
233 
234  FxVerifierDbgBreakPoint(FxDriverGlobals);
235  }
236 }
237 
238 VOID
240  __in PFX_DRIVER_GLOBALS FxDriverGlobals
241  )
242 {
244  BOOLEAN leak;
245 
246  if (FxDriverGlobals->DebugExtension == NULL) {
247  return;
248  }
249 
250  leak = FALSE;
251 
252  for (pCur = &FxDriverGlobals->DebugExtension->AllocatedMdls;
253  pCur != NULL;
254  pCur = pCur->Next) {
255  ULONG i;
256 
257  for (i = 0; i < NUM_MDLS_IN_INFO; i++) {
258  if (pCur->Info[i].Mdl != NULL) {
259  leak = TRUE;
260 
262  FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
263  "PMDL 0x%p leaked, FxObject owner %p, Callers Address %p",
264  pCur->Info[i].Mdl, pCur->Info[i].Owner,
265  pCur->Info[i].Caller);
266  }
267  }
268  }
269 
270  if (leak) {
271  FxVerifierDbgBreakPoint(FxDriverGlobals);
272  }
273 }
274 
struct FxAllocatedMdls * Next
Definition: fxglobalskm.h:52
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
VOID FxMdlFreeDebug(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PMDL Mdl)
Definition: wdfpoolkm.cpp:167
#define __in_opt
Definition: dbghelp.h:38
#define TRUE
Definition: types.h:120
KIRQL irql
Definition: wave.h:1
#define __inout_opt
Definition: dbghelp.h:53
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)
Definition: wdfpoolkm.cpp:81
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
#define __drv_aliasesMem
Definition: btrfs_drv.h:205
unsigned char BOOLEAN
__in ULONG __in BOOLEAN SecondaryBuffer
Definition: wdfpoolkm.cpp:47
#define NTKERNELAPI
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
__drv_maxIRQL(DISPATCH_LEVEL) NTKERNELAPI PMDL STDCALL IoAllocateMdl(__in_opt __drv_aliasesMem PVOID VirtualAddress
__in ULONG __in BOOLEAN __in BOOLEAN ChargeQuota
Definition: wdfpoolkm.cpp:47
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#define STDCALL
Definition: wdf.h:45
FxMdlDebugInfo Info[NUM_MDLS_IN_INFO]
Definition: fxglobalskm.h:50
FxAllocatedMdls AllocatedMdls
Definition: fxglobals.h:124
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
VOID FxMdlDump(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: wdfpoolkm.cpp:239
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
FxObject * Owner
Definition: fxglobalskm.h:43
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
SINGLE_LIST_ENTRY * pCur
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID Owner
Definition: rtlfuncs.h:1556
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define __in
Definition: dbghelp.h:35
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
FxVerifierDbgBreakPoint(pFxDriverGlobals)
#define NUM_MDLS_IN_INFO
Definition: fxglobalskm.h:47