/*++ Copyright (c) 1998-2001 Microsoft Corporation Module Name: mdlutil.cxx Abstract: This module implements general MDL utilities. Author: Keith Moore (keithmo) 25-Aug-1998 Revision History: --*/ #include "precomp.h" #ifdef ALLOC_PRAGMA #endif // ALLOC_PRAGMA #if 0 NOT PAGEABLE -- UlGetMdlChainByteCount NOT PAGEABLE -- UlCloneMdl NOT PAGEABLE -- UlFindLastMdlInChain #endif // // Public functions. // /***************************************************************************++ Routine Description: Calculates the total byte length of the specified MDL chain. Arguments: pMdlChain - Supplies the head of the MDL chain to scan. Return Value: ULONG_PTR - The total byte length of the chain. --***************************************************************************/ ULONG UlGetMdlChainByteCount( IN PMDL pMdlChain ) { ULONG totalLength; // // Simply scan through the MDL chain and sum the lengths. // totalLength = 0; do { totalLength += (ULONG)MmGetMdlByteCount( pMdlChain ); pMdlChain = pMdlChain->Next; } while (pMdlChain != NULL); return totalLength; } // UlGetMdlChainByteCount /***************************************************************************++ Routine Description: Clones the specified MDL, resulting in a new MDL that describes the exact same memory (pages, etc) as the original MDL. Arguments: pMdl - Supplies the MDL to clone. Return Value: PMDL - The newly cloned MDL if successful, NULL otherwise. --***************************************************************************/ PMDL UlCloneMdl( IN PMDL pMdl ) { PMDL pMdlClone; ULONG mdlLength; PVOID pMdlAddress; // // Ensure the incoming MDL is of the type we expect (either nonpaged // or already mapped into system space). // ASSERT( (pMdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL)) != 0); // // Snag the length & virtual address from the MDL. // mdlLength = MmGetMdlByteCount( pMdl ); ASSERT( mdlLength > 0 ); pMdlAddress = MmGetMdlVirtualAddress( pMdl ); ASSERT( pMdlAddress != NULL ); // // Allocate a new MDL, then initialize it with the incoming MDL. // pMdlClone = UlAllocateMdl( pMdlAddress, // VirtualAddress mdlLength, // Length FALSE, // SecondaryBuffer FALSE, // ChargeQuota NULL // Irp ); if (pMdlClone != NULL) { IoBuildPartialMdl( pMdl, // SourceMdl pMdlClone, // TargetMdl pMdlAddress, // VirtualAddress mdlLength // Length ); } return pMdlClone; } // UlCloneMdl /***************************************************************************++ Routine Description: Finds the last MDL in the specified MDL chain. Arguments: pMdlChain - Supplies the MDL chain to scan. Return Value: PMDL - Pointer to the last MDL in the MDL chain. --***************************************************************************/ PMDL UlFindLastMdlInChain( IN PMDL pMdlChain ) { while (pMdlChain->Next != NULL) { pMdlChain = pMdlChain->Next; } return pMdlChain; } // UlFindLastMdlInChain // // Private functions. //