ReactOS 0.4.15-dev-7953-g1f49173
wdfpool.cpp File Reference
#include "fxobjectpch.hpp"
Include dependency graph for wdfpool.cpp:

Go to the source code of this file.

Functions

BOOLEAN FxIsPagedPoolType (__in POOL_TYPE Type)
 
PVOID FxPoolAllocator (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PFX_POOL Pool, __in POOL_TYPE Type, __in SIZE_T Size, __in ULONG Tag, __in PVOID Caller)
 
VOID FxPoolFree (__in_xcount(ptr is at an offset from AllocationStart) PVOID ptr)
 
NTSTATUS FxPoolDump (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PFX_POOL Pool)
 
_Must_inspect_result_ NTSTATUS FxPoolInitialize (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PFX_POOL Pool)
 
VOID FxPoolDestroy (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PFX_POOL Pool)
 
_Must_inspect_result_ NTSTATUS FxPoolPackageInitialize (__in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
VOID FxPoolPackageDestroy (__in PFX_DRIVER_GLOBALS FxDriverGlobals)
 

Function Documentation

◆ FxIsPagedPoolType()

BOOLEAN FxIsPagedPoolType ( __in POOL_TYPE  Type)

Definition at line 43 of file wdfpool.cpp.

60{
61 //
62 // Cleaner than doing (Type & 0x01)
63 //
64 switch( Type & (~POOL_COLD_ALLOCATION) ) {
65 case PagedPool:
67 return TRUE;
68
69 default:
70 return FALSE;
71 }
72}
Type
Definition: Type.h:7
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define PagedPool
Definition: env_spec_w32.h:308
#define POOL_COLD_ALLOCATION
@ PagedPoolCacheAligned
Definition: ketypes.h:883

Referenced by FxMemoryObject::_Create(), FxMemoryBufferFromPool::_Create(), FxPoolAllocator(), FxPoolFree(), and FxMemoryBuffer::operator new().

◆ FxPoolAllocator()

PVOID FxPoolAllocator ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in PFX_POOL  Pool,
__in POOL_TYPE  Type,
__in SIZE_T  Size,
__in ULONG  Tag,
__in PVOID  Caller 
)

Definition at line 76 of file wdfpool.cpp.

125{
126 PVOID ptr;
127 PCHAR pTrueBase;
128 PFX_POOL_TRACKER pTracker;
131 SIZE_T allocationSize;
132
133
134 ptr = NULL;
135
136 //
137 // Allocations of a zero request size are invalid.
138 //
139 // Besides, with a zero request size, special pool could place us
140 // at the end of a page, and adding our header would give us a page
141 // aligned address, which is ambiguous with large allocations.
142 //
143 if (Size == 0) {
145 "Invalid Allocation Size of 0 requested");
146 FxVerifierDbgBreakPoint(FxDriverGlobals);
147 return NULL;
148 }
149
150 if (FxDriverGlobals->IsPoolTrackingOn()) {
151
152 if (FxDriverGlobals->FxVerifierOn &&
153 (FxDriverGlobals->WdfVerifierAllocateFailCount != -1L)) {
154
155 //
156 // If the registry key VerifierAllocateFailCount is set, all allocations
157 // after the specified count are failed.
158 //
159 // This is a brutal test, but also ensures the framework can cleanup
160 // under low memory conditions as well.
161 //
162 if (FxDriverGlobals->WdfVerifierAllocateFailCount == 0) {
164 "Allocation Fail Count exceeded");
165 return NULL;
166 }
167
168 // Decrement the count
169 InterlockedDecrement(&FxDriverGlobals->WdfVerifierAllocateFailCount);
170 }
171
172 //
173 // (Kernel mode only) PAGE_SIZE or greater allocations can not have our
174 // header since this would break the system allocators contract
175 // that PAGE_SIZE or greater allocations start on a whole page boundary
176 //
177
178 //
179 // For allocations less than a page size that will not fit with our
180 // header, we round up to a non-tracked whole page allocation so
181 // we don't burn two pages for this boundary condition.
182 //
183
184 // This if is the same as
185 // Size + sizeof(FX_POOL_TRACKER) + FX_POOL_HEADER_SIZE >= PAGE_SIZE
186 // BUT with no integer overflow
187 if (Mx::IsKM() &&
188 (Size >= PAGE_SIZE - sizeof(FX_POOL_TRACKER) - FX_POOL_HEADER_SIZE)
189 ) {
190
191 //
192 // Ensure that we ask for at least a page to ensure the
193 // allocation starts on a whole page.
194 //
195 if (Size < PAGE_SIZE) {
196 Size = PAGE_SIZE;
197 }
198
200
201 //
202 // The current system allocator returns paged aligned memory
203 // in this case, which we rely on to detect whether our header
204 // is present or not in FxPoolFree
205 //
206 ASSERT(((ULONG_PTR)ptr & (PAGE_SIZE-1)) == 0);
207 }
208 else {
209
210 status = RtlSIZETAdd(Size,
211 sizeof(FX_POOL_TRACKER) + FX_POOL_HEADER_SIZE,
212 &allocationSize);
213
214 if (!NT_SUCCESS(status)) {
216 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPOOL,
217 "overflow: allocation tracker (%d) + header (%d) + pool "
218 "request (%I64d)", sizeof(FX_POOL_TRACKER),
220
221 return NULL;
222 }
223
225 Type,
226 allocationSize,
227 Tag
228 );
229
230 if (pTrueBase == NULL) {
231 return NULL;
232 }
233
234 pTracker = (PFX_POOL_TRACKER) pTrueBase;
236 sizeof(FX_POOL_TRACKER),
238 pHeader->Base = pTrueBase;
239 pHeader->FxDriverGlobals = FxDriverGlobals;
240
241 //
242 // Adjust the pointer to what we return to the driver
243 //
244 ptr = &pHeader->AllocationStart[0];
245
246 //
247 // Ensure the pointer we are returning is aligned on the proper
248 // boundary.
249 //
251
252 //
253 // Ensure the pointer is still not page aligned after
254 // our adjustment. Otherwise the pool free code will
255 // get confused and call ExFreePool on the wrong ptr.
256 //
257 if (Mx::IsKM()) {
258 ASSERT(((ULONG_PTR)ptr & (PAGE_SIZE-1)) != 0 );
259 }
260
261 //
262 // We must separate paged and non-paged pool since
263 // the lock held differs as to whether we can accept
264 // page faults and block in the allocator.
265 //
266 if (FxIsPagedPoolType(Type)) {
267 //
268 // Format and insert the Tracker in the PagedHeader list.
269 //
271 pTracker,
272 Size,
273 Tag,
274 Caller);
275 }
276 else {
277 //
278 // Format and insert the Tracker in the NonPagedHeader list.
279 //
281 pTracker,
282 Size,
283 Tag,
284 Caller);
285 }
286 }
287 }
288 else {
289 //
290 // No pool tracking...
291 //
292
293 if ((Size < PAGE_SIZE) || Mx::IsUM())
294 {
295 //
296 // (Kernel mode only) See if adding our header promotes us past a
297 // page boundary
298 //
299 status = RtlSIZETAdd(Size,
301 &allocationSize);
302
303 if (!NT_SUCCESS(status)) {
305 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPOOL,
306 "overflow: header + pool request (%I64d)", Size);
307
308 return NULL;
309 }
310
311 }
312 else {
313 //
314 // Is the raw request for alloc >= PAGE_SIZE ? Then just use it.
315 //
316 allocationSize = Size;
317 }
318
319 //
320 // Is cooked size for alloc >= PAGE_SIZE ? Then just do it.
321 //
322 if (allocationSize >= PAGE_SIZE && Mx::IsKM())
323 {
324 //
325 // Important to use allocationSize so that we get a page aligned
326 // allocation so that we know to just free the memory pointer as is
327 // when it is freed.
328 //
329 ptr = MxMemory::MxAllocatePoolWithTag(Type, allocationSize, Tag);
330 ASSERT(((ULONG_PTR)ptr & (PAGE_SIZE-1)) == 0);
331 }
332 else {
334 allocationSize,
335 Tag);
336
337 if (pTrueBase != NULL) {
338
339 pHeader = (PFX_POOL_HEADER) pTrueBase;
340 pHeader->Base = pTrueBase;
341 pHeader->FxDriverGlobals = FxDriverGlobals;
342
343 ptr = &pHeader->AllocationStart[0];
344
345 if (Mx::IsKM()) {
346 //
347 // Ensure the pointer is still not page aligned after
348 // our adjustment. Otherwise the pool free code will
349 // get confused and call ExFreePool on the wrong ptr.
350 //
351 ASSERT( ((ULONG_PTR)ptr & (PAGE_SIZE-1)) != 0 );
352 }
353 }
354 }
355 }
356
357 return ptr;
358}
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
static __inline PVOID MxAllocatePoolWithTag(__in POOL_TYPE PoolType, __in SIZE_T NumberOfBytes, __in ULONG Tag)
Definition: mxmemorykm.h:30
static __inline BOOLEAN IsKM()
Definition: mxgeneralkm.h:53
static __inline BOOLEAN IsUM()
Definition: mxgeneralkm.h:45
Definition: bufpool.h:50
#define TRACINGPOOL
Definition: dbgtrace.h:62
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define PAGE_SIZE
Definition: env_spec_w32.h:49
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxVerifierDbgBreakPoint(pFxDriverGlobals)
#define FX_POOL_HEADER_SIZE
Definition: fxpool.h:53
FX_POOL_TRACKER * PFX_POOL_TRACKER
Definition: fxpool.h:109
FX_POOL_HEADER * PFX_POOL_HEADER
Definition: fxpool.h:51
VOID __inline FxPoolInsertNonPagedAllocateTracker(__in PFX_POOL Pool, __in PFX_POOL_TRACKER Tracker, __in SIZE_T Size, __in ULONG Tag, __in PVOID Caller)
VOID __inline FxPoolInsertPagedAllocateTracker(__in PFX_POOL Pool, __in PFX_POOL_TRACKER Tracker, __in SIZE_T Size, __in ULONG Tag, __in PVOID Caller)
FxContextHeader * pHeader
Definition: handleapi.cpp:604
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
static PVOID ptr
Definition: dispmode.c:27
#define MEMORY_ALLOCATION_ALIGNMENT
Definition: ntbasedef.h:90
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
Definition: ps.c:97
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
char * PCHAR
Definition: typedefs.h:51
#define WDF_PTR_ADD_OFFSET_TYPE(_ptr, _offset, _type)
Definition: wdfcore.h:141
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
BOOLEAN FxIsPagedPoolType(__in POOL_TYPE Type)
Definition: wdfpool.cpp:43

◆ FxPoolDestroy()

VOID FxPoolDestroy ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in PFX_POOL  Pool 
)

Definition at line 627 of file wdfpool.cpp.

643{
645 "Destroying Pool 0x%p", Pool);
646
647 if (FxDriverGlobals->IsPoolTrackingOn()) {
648 FxPoolDump(FxDriverGlobals, Pool);
649
650#if FX_CORE_MODE==FX_CORE_KERNEL_MODE
651 FxMdlDump(FxDriverGlobals);
652#endif
653 //
654 // We don't automatically free memory items since we don't
655 // know what they contain, and who is still referencing them.
656 //
657 }
658
659 Pool->PagedLock.Uninitialize();
660 Pool->NonPagedLock.Uninitialize();
661
662 return;
663}
VOID FxMdlDump(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: wdfpoolkm.cpp:239
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
NTSTATUS FxPoolDump(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PFX_POOL Pool)
Definition: wdfpool.cpp:459

Referenced by FxPoolPackageDestroy().

◆ FxPoolDump()

NTSTATUS FxPoolDump ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in PFX_POOL  Pool 
)

Definition at line 459 of file wdfpool.cpp.

478{
479 PFX_POOL_TRACKER pTracker;
481 KIRQL oldIrql;
482 BOOLEAN leak;
483
484 //
485 // Dump usage information
486 //
488 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
489 "FxPoolDump: "
490 "NonPagedBytes %I64d, PagedBytes %I64d, "
491 "NonPagedAllocations %d, PagedAllocations %d,"
492 "PeakNonPagedBytes %I64d, PeakPagedBytes %I64d,"
493 "FxPoolDump: PeakNonPagedAllocations %d, PeakPagedAllocations %d",
494 Pool->NonPagedBytes, Pool->PagedBytes,
495 Pool->NonPagedAllocations, Pool->PagedAllocations,
496 Pool->PeakNonPagedBytes, Pool->PeakPagedBytes,
497 Pool->PeakNonPagedAllocations, Pool->PeakPagedAllocations
498 );
499
500 leak = FALSE;
501
502 //
503 // Check paged pool for leaks
504 //
505 Pool->PagedLock.Acquire();
506
507 for (ple = Pool->PagedHead.Flink; ple != &Pool->PagedHead; ple = ple->Flink) {
508 pTracker = CONTAINING_RECORD(ple, FX_POOL_TRACKER, Link);
509
510 // Leaker
511 leak = TRUE;
512
514 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
515 "FX_POOL 0x%p leaked paged memory alloc 0x%p (tracking block %p)",
516 Pool, pTracker + 1, pTracker);
517 }
518
519 Pool->PagedLock.Release();
520
521 //
522 // Check non-paged pool for leaks
523 //
524
525 Pool->NonPagedLock.Acquire(&oldIrql);
526
527 for (ple = Pool->NonPagedHead.Flink;
528 ple != &Pool->NonPagedHead;
529 ple = ple->Flink) {
530 pTracker = CONTAINING_RECORD(ple, FX_POOL_TRACKER, Link );
531
532 // Leaker
533 leak = TRUE;
534
536 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
537 "FX_POOL 0x%p leaked non-paged memory alloc 0x%p (tracking block %p)",
538 Pool, pTracker+1, pTracker);
539 }
540
541 Pool->NonPagedLock.Release(oldIrql);
542
543 if (leak) {
544 FxVerifierDbgBreakPoint(FxDriverGlobals);
545 return STATUS_MORE_ENTRIES;
546 }
547 else {
548 return STATUS_SUCCESS;
549 }
550}
unsigned char BOOLEAN
#define TRACINGDEVICE
Definition: dbgtrace.h:58
UCHAR KIRQL
Definition: env_spec_w32.h:591
PSINGLE_LIST_ENTRY ple
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: typedefs.h:120
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_MORE_ENTRIES
Definition: udferr_usr.h:124
static int Link(const char **args)
Definition: vfdcmd.c:2414

Referenced by FxPoolDestroy().

◆ FxPoolFree()

VOID FxPoolFree ( __in_xcount(ptr is at an offset from AllocationStart) PVOID  ptr)

Definition at line 361 of file wdfpool.cpp.

386{
388 PVOID pTrueBase;
389 PFX_POOL_TRACKER pTracker;
390
391 //
392 // Null pointers are always bad
393 //
394 if( ptr == NULL ) {
395 ASSERTMSG("NULL pointer freed\n", FALSE);
401 );
402 }
403
404 //
405 // (Kernel mode only) If ptr is aligned on page boundry (indicates
406 // it was > PAGE_SIZE allocation)
407 // then there will be no common header...just free the memory without
408 // further processing.
409 //
410 if( Mx::IsKM() && ( ((ULONG_PTR)ptr & (PAGE_SIZE-1)) == 0 ) ) {
412 return;
413 }
414
415 //
416 // Ensure the pointer we are returning is aligned on the proper
417 // boundary.
418 //
420
421 //
422 // Dereference the Common header which all <PAGE_SIZE allcations will have.
423 //
424 pHeader = CONTAINING_RECORD(ptr, FX_POOL_HEADER, AllocationStart);
425 pTrueBase = pHeader->Base;
426
427 //
428 // If PoolTracker is on then Base must point to it's header.
429 // This is currently the only option for this area...may change later.
430 //
431 if (pHeader->FxDriverGlobals->IsPoolTrackingOn()) {
432
433 pTracker = (PFX_POOL_TRACKER) pTrueBase;
434
435 if (FxIsPagedPoolType(pTracker->PoolType)) {
436 //
437 // Decommission this Paged Allocation tracker
438 //
440 }
441 else {
442 //
443 // Decommission this NonPaged Allocation tracker
444 //
446 }
447
448 //
449 // Scrub the pool to zeros to catch destructed objects
450 // by NULL'ing the v-table ptr
451 //
452 RtlZeroMemory(pTracker, pTracker->Size + sizeof(FX_POOL_TRACKER));
453 }
454
455 MxMemory::MxFreePool(pTrueBase);
456}
static __inline VOID MxFreePool(__in PVOID Ptr)
Definition: mxmemorykm.h:41
static DECLSPEC_NORETURN VOID MxBugCheckEx(__in ULONG BugCheckCode, __in ULONG_PTR BugCheckParameter1, __in ULONG_PTR BugCheckParameter2, __in ULONG_PTR BugCheckParameter3, __in ULONG_PTR BugCheckParameter4)
Definition: mxgeneralkm.h:133
VOID __inline FxPoolRemoveNonPagedAllocateTracker(__in PFX_POOL_TRACKER Tracker)
VOID __inline FxPoolRemovePagedAllocateTracker(__in PFX_POOL_TRACKER Tracker)
#define _ReturnAddress()
Definition: intrin_arm.h:35
#define WDF_VIOLATION
Definition: mx.h:37
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
@ WDF_REQUIRED_PARAMETER_IS_NULL
Definition: wdfbugcodes.h:61

Referenced by AddEventHooksWdfDeviceCreate(), AddEventHooksWdfIoQueueCreate(), FxUsbDeviceStringContext::AllocateDescriptor(), FxUsbInterface::CleanUpAndDelete(), FxIoTargetRemoveOpenParams::Clear(), FxIoContext::ClearBuffer(), FxDevice::CreateSymbolicLink(), FxDevice::DeleteSymbolicLink(), FxDevice::Destroy(), FxIoQueue::Dispose(), FxIoTarget::FormatIoctlRequest(), FxIoTarget::FormatIoRequest(), FxVerifierLock::FreeThreadTable(), FxDuplicateUnicodeString(), FxGetDevicePropertyString(), FxObjectAllocateContext(), GetImageName(), FxUsbDevice::GetString(), FxUsbInterface::MakeAndConfigurePipes(), FxIoTargetRemote::Open(), FxObject::operator delete(), FxCallback::operator delete(), FxRelatedDeviceList::operator delete(), FxStump::operator delete(), FxDeviceText::operator delete(), FxStump::operator delete[](), FxObject::ProcessDestroy(), FxUsbDevice::SelectConfig(), FxUsbDevice::SelectConfigDescriptor(), FxUsbDevice::SelectConfigInterfaces(), FxUsbDevice::SelectConfigMulti(), FxUsbDevice::SelectConfigSingle(), FxUsbInterface::SelectSetting(), FxUsbInterface::SelectSettingByDescriptor(), FxUsbInterface::SelectSettingByIndex(), FxIoContext::SetBufferAndLength(), VfAddContextToHandle(), FxAutoString::~FxAutoString(), FxDevice::~FxDevice(), FxDeviceInterface::~FxDeviceInterface(), FxDeviceText::~FxDeviceText(), FxDriver::~FxDriver(), FxPagedObject::~FxPagedObject(), FxPkgPdo::~FxPkgPdo(), FxQueryInterface::~FxQueryInterface(), FxString::~FxString(), FxUsbDevice::~FxUsbDevice(), FxUsbDeviceStringContext::~FxUsbDeviceStringContext(), FxUsbInterface::~FxUsbInterface(), and FxIrpPreprocessInfo::Info::~Info().

◆ FxPoolInitialize()

_Must_inspect_result_ NTSTATUS FxPoolInitialize ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in PFX_POOL  Pool 
)

Definition at line 554 of file wdfpool.cpp.

570{
572
574 "Initializing Pool 0x%p, Tracking %d",
575 Pool, FxDriverGlobals->IsPoolTrackingOn());
576
577 Pool->NonPagedLock.Initialize();
578
579 InitializeListHead( &Pool->NonPagedHead );
580
581 status = Pool->PagedLock.Initialize();
582 if (!NT_SUCCESS(status)) {
584 "Initializing paged lock failed for Pool 0x%p, "
585 "status %!STATUS!",
586 Pool, status);
587 goto exit;
588 }
589
590 InitializeListHead( &Pool->PagedHead );
591
592 // Pool usage information
593 Pool->NonPagedBytes = 0;
594 Pool->PagedBytes = 0;
595
596 Pool->NonPagedAllocations = 0;
597 Pool->PagedAllocations = 0;
598
599 Pool->PeakNonPagedBytes = 0;
600 Pool->PeakPagedBytes = 0;
601
602 Pool->PeakNonPagedAllocations = 0;
603 Pool->PeakPagedAllocations = 0;
604
605exit:
606 if (!NT_SUCCESS(status)) {
607 //
608 // We disable pool tracking if we could not initialize the locks needed
609 //
610 // If we don't do this we would need another flag to make FxPoolDestroy
611 // not access the locks
612 //
613 FxDriverGlobals->FxPoolTrackingOn = FALSE;
614 }
615
616 //
617 // FxPoolDestroy will always be called even if we fail FxPoolInitialize
618 //
619 // FxPoolDestroy will uninitialize locks both in success and failure
620 // cases
621 //
622
623 return status;
624}
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define exit(n)
Definition: config.h:202

Referenced by FxPoolPackageInitialize().

◆ FxPoolPackageDestroy()

VOID FxPoolPackageDestroy ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals)

Definition at line 689 of file wdfpool.cpp.

706{
707 FxPoolDestroy(FxDriverGlobals, &FxDriverGlobals->FxPoolFrameworks);
708 return;
709}
VOID FxPoolDestroy(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PFX_POOL Pool)
Definition: wdfpool.cpp:627

Referenced by FxDestroy().

◆ FxPoolPackageInitialize()

_Must_inspect_result_ NTSTATUS FxPoolPackageInitialize ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals)

Definition at line 667 of file wdfpool.cpp.

684{
685 return FxPoolInitialize(FxDriverGlobals, &FxDriverGlobals->FxPoolFrameworks);
686}
_Must_inspect_result_ NTSTATUS FxPoolInitialize(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PFX_POOL Pool)
Definition: wdfpool.cpp:554

Referenced by FxInitialize().