236 lines
4.8 KiB
C
236 lines
4.8 KiB
C
/*--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
|
|
|