|
|
/*--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
|