WDF_MEMORY_DESCRIPTOR was a tough one. It took me quite a while to get this to its current state. What we wanted to do with memory lifetime management was
-
for async requests, require the use of WDFMEMORY so we could manage the lifetime of the buffer. BUT, to help with porting and interacting with other parts of the OS that might allocate on your behalf, we have the Preallocated version which is a veneer object that lets you opt into the model
-
for sync requests, use any type of memory that the caller has on hand. Lifetime isn’t a problem since it is scoped to the callsite. In this case, WDFMEMORY / PVOID / PMDL are all valid. Either we created N*N sync APIs that could take any combination (C++ would have made that slightly more palatable, but not by much) or we created one version of the API that took all options for each buffer (WDF_MEMORY_DESCRIPTOR) and kept things relatively straightforward (and expandable if we ever needed more memory types)
d
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@osr.com
Sent: Monday, April 8, 2013 10:34 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] ExAllocatePoolWithTag Problem
If YOU find it slightly confusing, I’m SURE other members of the community find it confusing as well. I’ll add an item to our queue for The NT Insider, but in the meantime, let me hold forth a bit, and tell you how I explain this in class. It might not help, or maybe it’ll help one person. If that’s the case, at least I’ve tried:
There are three ways of describing allocated memory in WDF: Buffers, Memory Objects, and MDLs.
A memory buffer in WDF is just want it is in any system: A pointer and a length. You get a “buffer” directly when you call functions such as WdfRequestRetrieveInputBuffer (or friends) or when you use one of the WDM (M) functions such as ExAllocatePoolWithTag.
A buffer isn’t an object. It’s just some allocated memory. The buffer itself is not managed by the Framework. Now, don’t confuse this with an object (such as a WDFREQUEST) which might own a buffer and therefore manage its lifetime. But, if you consider JUST THE BUFFER, the buffer itself is not Framework managed.
Contrast this with a WDFMemory object. A WDFMemory object is an opaque object that is used to describe a buffer. That buffer might be associated with a Request, in which case you can call WdfRequestRetrieveInputMemory (or friends) or it may simply be a private allocation from one of the Pools (created with WdfMemoryCreate).
Just like with any WDF Object, Memory objects are managed by the Framework. They have a reference count, they can have a context, they can have cleanup callback methods… anything that any other WDF Object has.
Because it’s simple to get a buffer (pointer and length) from a WDF Memory object, in many cases a WDFMEMORY object merely offers a convenient way to allocate and track memory allocations using the same pattern by which you do ANY work in the Framework.
WDF Memory Objects also provide a handy way to pass along a description of a buffer for use by another WDF method. An added bonus is that if the function does something with a lifetime, the function can reference the WDF Memory object to ensure it’s not deallocated while being accessed.
By the way… a related structure that folks often find confusing is the WDF_MEMORY_DESCRIPTOR. This is just a data structure, and is used to provide a uniform way to describe a memory area… regardless of whether you have a buffer, a WDF Memory Object, or and MDL that describes that area of memory. While folks often see this structure as an annoyance (like when building USB Requests) it’s *really* a convenience, because you’re allowed to use ANY of the three possible types of memory descriptors to describe a data area, instead of having to use a specific one.
I hope that helps… at least some.
Peter
OSR
NTDEV is sponsored by OSR
OSR is HIRING!! See http://www.osr.com/careers
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer