MmGetSystemAddressForMdl in URB control transfer

Hi all

I’m writing a KMDF lower filter driver for a USB joystick, based on the source of a WDM driver. In the WDM version, the driver adds a completion routine for URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE, which basically replaces the report descriptor length value with its own value.

Early in the completion routine, the code sets up a pointer to the descriptor buffer as follows:

BufPtr=NULL;
if ((PUCHAR)pControlTransfer->TransferBuffer)
{
BufPtr=(PUCHAR)pControlTransfer->TransferBuffer;
}
else if (pControlTransfer->TransferBufferMDL)
{
BufPtr = (PUCHAR)MmGetSystemAddressForMdl(pControlTransfer->TransferBufferMDL);
}

Later on, near the end of the routine (and having made appropriate updates via BufPtr), the routine seems to be updating the buffer if it’s an MDL:

if ( Temp = (PUCHAR)MmGetSystemAddressForMdl(pControlTransfer->TransferBufferMDL) )
RtlCopyMemory(Temp,BufPtr,pControlTransfer->TransferBufferLength);

Now I’ve checked through the rest of the routine, and BufPtr isn’t modified anywhere, so I was wondering what the last section of quoted code achieves - it seems to be copying the modified buffer back onto itself. Is there something going on here that I’m missing?

Never ever use MmGetSystemAddressForMdl.

Use MmGetSystemAddressForMdlSafe instead and check for failures.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Friday, November 03, 2006 9:16 PM
Subject: [ntdev] MmGetSystemAddressForMdl in URB control transfer

> Hi all
>
> I’m writing a KMDF lower filter driver for a USB joystick, based on the
source of a WDM driver. In the WDM version, the driver adds a completion
routine for URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE, which basically replaces
the report descriptor length value with its own value.
>
> Early in the completion routine, the code sets up a pointer to the descriptor
buffer as follows:
>
> BufPtr=NULL;
> if ((PUCHAR)pControlTransfer->TransferBuffer)
> {
> BufPtr=(PUCHAR)pControlTransfer->TransferBuffer;
> }
> else if (pControlTransfer->TransferBufferMDL)
> {
> BufPtr =
(PUCHAR)MmGetSystemAddressForMdl(pControlTransfer->TransferBufferMDL);
> }
>
>
> Later on, near the end of the routine (and having made appropriate updates
via BufPtr), the routine seems to be updating the buffer if it’s an MDL:
>
> if ( Temp =
(PUCHAR)MmGetSystemAddressForMdl(pControlTransfer->TransferBufferMDL) )
> RtlCopyMemory(Temp,BufPtr,pControlTransfer->TransferBufferLength);
>
>
> Now I’ve checked through the rest of the routine, and BufPtr isn’t modified
anywhere, so I was wondering what the last section of quoted code achieves - it
seems to be copying the modified buffer back onto itself. Is there something
going on here that I’m missing?
>
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

OK, thanks, I had spotted that MmGetSystemAddressForMdl was deprecated. But would MmGetSystemAddressForMdlSafe do anything different? Is there any purpose to the second call to MmGetSystemAddressForMdl(Safe)? Or can I just write into the buffer using the returned pointer and then forget about it?