Leaked source code of windows server 2003
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.
 
 
 
 
 
 

183 lines
4.0 KiB

/*++
Copyright (c) 1998-2002 Microsoft Corporation
Module Name:
mdlutil.c
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.
MdlLength - Supplies the length of the MDL to clone.
Return Value:
PMDL - The newly cloned MDL if successful, NULL otherwise.
--***************************************************************************/
PMDL
UlCloneMdl(
IN PMDL pMdl,
IN ULONG MdlLength
)
{
PMDL pMdlClone;
PVOID pMdlAddress;
//
// Ensure the incoming MDL is of the type we expect (either nonpaged
// or locked). For a response that doesn't need to goto the cache entry,
// there is no need to map the buffer as either the lower layer will map
// it or some miniport can handle it unmapped.
//
ASSERT( pMdl->MdlFlags & (MDL_PAGES_LOCKED | MDL_SOURCE_IS_NONPAGED_POOL) );
ASSERT( MdlLength > 0 );
//
// Snag the virtual address from the MDL. Note a MDL returned from
// MmAllocatePagesForMdl doesn't have the virtual address set.
//
pMdlAddress = MmGetMdlVirtualAddress( pMdl );
ASSERT( pMdlAddress != NULL || (pMdl->MdlFlags & MDL_PAGES_LOCKED) );
//
// 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.
//