A (long) while back, in this thread:
https://www.osronline.com/ShowThread.cfm?link=216562
… Doron alluded to being able to replace a WDFREQUEST’s WDFMEMORY ala:
“Then all you need to do is allocate a WDFMEMORY with the new expanded size, for
a write operation copy the caller’s buffer content into the new buffer, format
the request with your WDFMEMORY and adjusted size, and send the request down the
stack.”
I needed to do something similar, so I tried to follow that approach. When I reformat the request using my new WDFMEMORY, it returns STATUS_SUCCESS, but turning around and obtaining the request’s WDFMEMORY again returns the original WDFMEMORY, as if nothing was changed. There are no errors returned, and the wdf logs from windbg only show power operations (eg, no “read only” buffers or other errors).
Here’s what I’m doing (some irrelevant and error handling code removed for brevity):
//
// Write path function
//
WDF_REQUEST_PARAMETERS params;
WDFMEMORY origmem, newmem, newmem2;
NTSTATUS status;
PVOID origbuf, newbuf, newbuf2;
WDF_REQUEST_PARAMETERS_INIT(¶ms);
WdfRequestGetParameters(Request, ¶ms);
status = WdfRequestRetrieveInputMemory(Request, &origmem);
if (NT_SUCCESS(status)) {
origbuf = WdfMemoryGetBuffer(origmem, NULL);
} else {
// handle failure (code omitted)
}
status = WdfMemoryCreate(WDF_NO_OBJECT_ATTRIBUTES, NonPagedPool, ‘MyPl’, params.Parameters.Write.Length, &newmem, &newbuf);
if (!NT_SUCCESS(status)) {
// handle failure (code omitted)
}
//
// buffer modification code here (copy and modify from origbuf -> newbuf) omitted.
// this code works fine, in the debugger I can see both the original and modified data
// correctly, in origbuf and newbuf, respectively.
//
status = WdfIoTargetFormatRequestForWrite(WdfDeviceGetIoTarget(device), Request, newmem, NULL, NULL);
if (!NT_SUCCESS(status)) {
// handle failure (code omitted)
}
status = WdfRequestRetrieveInputMemory(Request, &newmem2);
if (!NT_SUCCESS(status)) {
// handle failure (code omitted)
}
newbuf2 = WdfMemoryGetBuffer(newmem2, NULL);
At this point, even though I think I’ve replaced “Request”'s WDFMEMORY with “newmem”, newmem2 still is == to origmem and newbuf2 == origbuf. None of the failure paths are being hit.
This makes it difficult to modify the write buffer before sending the request down.
I’ve temporarily worked around this by rolling a new WDFREQUEST and WDFMEMORY, copying all the parameters and info from the original request into the new one, and sending the new request down. But that seems wasteful and is quite a bit more code.
This is using VS2015 and a WS2016 TP4 KMDF target.
Cluestick? My guess is it’s related to the use of WdfIoTargetFormatRequestForWrite, but I re-read the docs a few more times and this seems like the correct function to use here.
Thanks.
-ml