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