Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

235 lines
4.8 KiB

/*--Copyright (c) 1999-2000 Microsoft Corporation
Module Name:
mdl2ndis.c
Abstract:
MDL <--> NDIS_BUFFER conversion
Author:
Bruce Johnson (bjohnson) 31-Aug-1999
--*/
#include <tcpipbase.h>
#if MILLEN
ULONG g_cConvertedNdisBuffers = 0;
ULONG g_cConvertedMdls = 0;
TDI_STATUS
ConvertMdlToNdisBuffer(
PIRP pIrp,
PMDL pMdl,
PNDIS_BUFFER *ppNdisBuffer
)
{
NDIS_STATUS NdisStatus;
PVOID VirtualAddress;
ULONG Length;
PNDIS_BUFFER pNdisBuffer;
TDI_STATUS TdiStatus = TDI_SUCCESS;
#ifdef DEBUG_MSG
PMDL pSavedMdl = pMdl;
#endif // DEBUG_MSG
//
// Allocate the NDIS_BUFFER chain describing the MDL chain.
//
*ppNdisBuffer = NULL;
pNdisBuffer = NULL;
do {
VirtualAddress = MmGetSystemAddressForMdl(pMdl);
Length = MmGetMdlByteCount(pMdl);
NdisAllocateBuffer(
&NdisStatus,
(pNdisBuffer == NULL) ? (&pNdisBuffer) : (&(pNdisBuffer->Next)),
NULL, //gBufferPool
VirtualAddress,
Length
);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
DEBUGMSG(DBG_ERROR,
(DTEXT("ConvertMdlToNdisBuffer failed to allocate NDIS_BUFFER.\n")));
break;
}
if (*ppNdisBuffer != NULL) {
pNdisBuffer = pNdisBuffer->Next;
}
else {
*ppNdisBuffer = pNdisBuffer;
}
pNdisBuffer->Next = NULL;
pMdl = pMdl->Next;
} while (pMdl != NULL);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
PNDIS_BUFFER pNext;
pNdisBuffer = *ppNdisBuffer;
while (pNdisBuffer) {
pNext = pNdisBuffer->Next;
NdisFreeBuffer(pNdisBuffer);
pNdisBuffer = pNext;
}
*ppNdisBuffer = NULL;
TdiStatus = TDI_NO_RESOURCES;
goto done;
}
InterlockedIncrement(&g_cConvertedNdisBuffers);
done:
// Ensure that it is initialized, either way.
pIrp->Tail.Overlay.DriverContext[0] = *ppNdisBuffer;
DEBUGMSG(DBG_INFO && DBG_TDI && DBG_VERBOSE,
(DTEXT("Convert IRP %x MDL %x NDIS_BUFFER %x\n"),
pIrp, pSavedMdl, *ppNdisBuffer));
return TdiStatus;
}
TDI_STATUS
FreeMdlToNdisBufferChain(
PIRP pIrp
)
{
PNDIS_BUFFER pNdisBuffer = pIrp->Tail.Overlay.DriverContext[0];
PNDIS_BUFFER pNext;
if (pNdisBuffer == NULL) {
goto done;
}
DEBUGMSG(DBG_INFO && DBG_TDI && DBG_VERBOSE,
(DTEXT("FreeConvert IRP %x NdisBuffer %x\n"), pIrp, pNdisBuffer));
do {
pNext = pNdisBuffer->Next;
NdisFreeBuffer(pNdisBuffer);
pNdisBuffer = pNext;
} while (pNdisBuffer);
pIrp->Tail.Overlay.DriverContext[0] = NULL;
InterlockedDecrement(&g_cConvertedNdisBuffers);
done:
return TDI_SUCCESS;
}
TDI_STATUS
ConvertNdisBufferToMdl(
PNDIS_BUFFER pNdisBuffer,
PMDL *ppMdl
)
{
NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
TDI_STATUS TdiStatus = TDI_SUCCESS;
PVOID VirtualAddress;
ULONG Length;
PMDL pMdl = NULL;
PMDL pLast = NULL;
#ifdef DEBUG_MSG
PNDIS_BUFFER pSavedNdisBuffer = pNdisBuffer;
#endif // DEBUG_MSG
*ppMdl = NULL;
do {
NdisQueryBuffer(
pNdisBuffer,
&VirtualAddress,
&Length);
pMdl = IoAllocateMdl(
VirtualAddress,
Length,
FALSE,
FALSE,
NULL);
if (pMdl == NULL) {
DEBUGMSG(DBG_ERROR,
(DTEXT("ConvertNdisBufferToMdl failed to allocate MDL.\n")));
NdisStatus = NDIS_STATUS_RESOURCES;
break;
}
if (*ppMdl != NULL) {
pLast->Next = pMdl;
} else {
*ppMdl = pMdl;
}
pMdl->Next = NULL;
pLast = pMdl;
pNdisBuffer = pNdisBuffer->Next;
} while (pNdisBuffer != NULL);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
PMDL pNext;
pMdl = *ppMdl;
while (pMdl) {
pNext = pMdl->Next;
IoFreeMdl(pMdl);
pMdl = pNext;
}
*ppMdl = NULL;
TdiStatus = TDI_NO_RESOURCES;
goto done;
}
InterlockedIncrement(&g_cConvertedMdls);
done:
DEBUGMSG(DBG_INFO && DBG_TDI && DBG_VERBOSE,
(DTEXT("Convert NDIS_BUFFER %x MDL %x\n"),
pSavedNdisBuffer, *ppMdl));
return TdiStatus;
}
TDI_STATUS
FreeNdisBufferToMdlChain(
PMDL pMdl
)
{
PMDL pNext;
DEBUGMSG(DBG_INFO && DBG_TDI && DBG_VERBOSE,
(DTEXT("FreeConvert MDL %x\n"), pMdl));
while (pMdl) {
pNext = pMdl->Next;
IoFreeMdl(pMdl);
pMdl = pNext;
}
InterlockedDecrement(&g_cConvertedMdls);
return TDI_SUCCESS;
}
#endif // MILLEN