/*--Copyright (c) 1999-2000 Microsoft Corporation Module Name: mdl2ndis.c Abstract: MDL <--> NDIS_BUFFER conversion Author: Bruce Johnson (bjohnson) 31-Aug-1999 --*/ #include #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