Help need for MDL

Hello,

In a TDI client driver, I set an event handler which calls a routine each
time data is received. The routine is just below.
The DDK says that the TSDU parameter “Points to an MDL, possibly the
initial MDL in a chain, mapping the buffer containing the received TSDU
data”. However, I cannot access the buffer pointed by the MDL without
having a BSOD (IRQL_NOT_LESS_OR_EQUAL) when RtlCopyMemory() is called.
The documentation says that RtlCopyMemory() can be running at any IRQL if
both memory blocks are resident. How can I know if the memory blocks are
resident ? If the blocks are not resident, which function should I use to
copy my buffer ? Should I lock, probe, map or do anything else before
copying the buffer ?

Thanks for your help

NTSTATUS ClientEventReceiveDatagram(IN PDEVICE_EXTENSION
DeviceExtension,IN LONG SourceAddressLength,
IN PVOID SourceAddress,IN LONG
OptionsLength,IN PVOID Options,
IN ULONG ReceiveDatagramFlags,IN ULONG
BytesIndicated,
IN ULONG BytesAvailable,OUT ULONG
*BytesTaken,IN PVOID Tsdu,
OUT PIRP *IoRequestPacket)
{
NTSTATUS Status; // Return value
ULONG BytesToCopy, // Bytes to copy
BytesCopied, // Bytes truly copied
BufferSize; // MDL’s buffer size
PMDL MdlAddress; // MDL pointer
PUCHAR Buffer; // Buffer receiving the data

// Data reception
BytesToCopy=DeviceExtension->Read.Size -
DeviceExtension->Read.BytesReceived;
BytesToCopy=BytesToCopy>BytesIndicated ? BytesIndicated : BytesToCopy;
MdlAddress=(PMDL)Tsdu;
BytesCopied=0;
// Scan MDL buffers
while(MdlAddress!=NULL && BytesCopied {
Buffer=MmGetSystemAddressForMdl((PMDL)MdlAddress);
BufferSize=MmGetMdlByteCount(MdlAddress);

BufferSize=BufferSize
<=(BytesToCopy-BytesCopied) ? BufferSize : (BytesToCopy-BytesCopied);

RtlCopyMemory(&DeviceExtension->Read.Buffer[DeviceExtension->Read.BytesReceived],Buffer,BufferSize);

BytesCopied+=BufferSize;
MdlAddress=MdlAddress->Next;
}
DeviceExtension->Read.BytesReceived+=BytesCopied;
*BytesTaken=BytesCopied;
IoRequestPacket=NULL;
Status=STATUS_SUCCESS;



return Status;
}

I think there is a small documentation problem here.

The documentation for ClientEventReceiveDatagram says:

Tsdu
Pointer to a buffer containing the received TSDU data.

The documentation for ClientEventChainedReceiveDatagram says:

Tsdu
Pointer to an MDL, possibly the initial MDL in a chain, mapping the buffer
containing the received TSDU.

In summary:

1.) In ClientEventReceiveDatagram a “Tsdu” is just an ordinary pointer to an
array of bytes that are page locked - NOT a pointer to a MDL.

2.) In ClientEventChainedReceiveDatagram a “Tsdu” is a pointer to a MDL.

It isn’t easy to figure this sort of stuff out unless one also has shed
blood in development of lower-level NDIS components.

ClientEventReceiveDatagram is related to the TDI Provider’s NDIS
“ProtocolReceive” handler (lookup in DDK documentation).

ClientEventChainedReceiveDatagram is related to the TDI provider’s NDIS
“ProtocolReceivePacket” handler.

Good luck,

Thomas F. Divine

PCAUSA - Tools & Resources For Network Software Developers
NDIS Protocol/Intermediate/Hooking - TDI Client/Filter
http: - http:

“Nicolas Mugnier” wrote in message
news:xxxxx@ntdev…
>
> Hello,
>
> In a TDI client driver, I set an event handler which calls a routine each
> time data is received. The routine is just below.
> The DDK says that the TSDU parameter “Points to an MDL, possibly the
> initial MDL in a chain, mapping the buffer containing the received TSDU
> data”. However, I cannot access the buffer pointed by the MDL without
> having a BSOD (IRQL_NOT_LESS_OR_EQUAL) when RtlCopyMemory() is called.
> The documentation says that RtlCopyMemory() can be running at any IRQL if
> both memory blocks are resident. How can I know if the memory blocks are
> resident ? If the blocks are not resident, which function should I use to
> copy my buffer ? Should I lock, probe, map or do anything else before
> copying the buffer ?
>
> Thanks for your help
>
>
> NTSTATUS ClientEventReceiveDatagram(IN PDEVICE_EXTENSION
> DeviceExtension,IN LONG SourceAddressLength,
> IN PVOID SourceAddress,IN LONG
> OptionsLength,IN PVOID Options,
> IN ULONG ReceiveDatagramFlags,IN ULONG
> BytesIndicated,
> IN ULONG BytesAvailable,OUT ULONG
> *BytesTaken,IN PVOID Tsdu,
> OUT PIRP *IoRequestPacket)
> {
> NTSTATUS Status; // Return value
> ULONG BytesToCopy, // Bytes to copy
> BytesCopied, // Bytes truly copied
> BufferSize; // MDL’s buffer size
> PMDL MdlAddress; // MDL pointer
> PUCHAR Buffer; // Buffer receiving the data
>
> …
>
> // Data reception
> BytesToCopy=DeviceExtension->Read.Size -
> DeviceExtension->Read.BytesReceived;
> BytesToCopy=BytesToCopy>BytesIndicated ? BytesIndicated : BytesToCopy;
> MdlAddress=(PMDL)Tsdu;
> BytesCopied=0;
> // Scan MDL buffers
> while(MdlAddress!=NULL && BytesCopied> {
> Buffer=MmGetSystemAddressForMdl((PMDL)MdlAddress);
> BufferSize=MmGetMdlByteCount(MdlAddress);
>
> BufferSize=BufferSize
> <=(BytesToCopy-BytesCopied) ? BufferSize : (BytesToCopy-BytesCopied);
>
>
RtlCopyMemory(&DeviceExtension->Read.Buffer[DeviceExtension->Read.BytesRecei
ved],Buffer,BufferSize);
>
> BytesCopied+=BufferSize;
> MdlAddress=MdlAddress->Next;
> }
> DeviceExtension->Read.BytesReceived+=BytesCopied;
> *BytesTaken=BytesCopied;
> IoRequestPacket=NULL;
> Status=STATUS_SUCCESS;
>
> …
>
> return Status;
> }
>
></http:></http:>