IoBuildPartialMdl function (wdm.h)

The IoBuildPartialMdl routine builds a new memory descriptor list (MDL) that represents part of a buffer that is described by an existing MDL.

Syntax

void IoBuildPartialMdl(
  [in]      PMDL  SourceMdl,
  [in, out] PMDL  TargetMdl,
  [in]      PVOID VirtualAddress,
  [in]      ULONG Length
);

Parameters

[in] SourceMdl

A pointer to an MDL that describes the original buffer, of which a subrange is to be mapped.

[in, out] TargetMdl

A pointer to a caller-allocated MDL. This MDL must be large enough to describe the pages in the subrange that are specified by VirtualAddress and Length.

[in] VirtualAddress

A pointer to the base virtual address for the subrange to be described by the TargetMdl.

[in] Length

Specifies the length, in bytes, to be mapped by the TargetMdl. This value, in combination with VirtualAddress, must specify a buffer that is a proper subrange of the buffer that is described by SourceMdl. If Length is zero, the subrange to be mapped starts at VirtualAddress and includes the remaining range described by the SourceMdl.

Return value

None

Remarks

This routine builds a target MDL that describes a subrange of the buffer that is described by the source MDL. This subrange is specified by the VirtualAddress and Length parameters. The SourceMdl and TargetMdl parameters point to the source MDL and target MDL.

A driver can use IoBuildPartialMdl to split a large transfer request into smaller transfer requests. The physical pages that the source MDL describes must be locked before the driver calls IoBuildPartialMdl. Typically, the source MDL describes a buffer in user address space, and the driver calls the MmProbeAndLockPages routine to lock the pages in this buffer. However, the driver can build the source MDL from nonpaged memory by calling the MmBuildMdlForNonPagedPool, MmAllocatePagesForMdlEx, or MmAllocatePagesForMdl routine.

When creating a partial MDL:

  • If the original MDL was already mapped in system space, the partial MDL shares that mapping and there is no need to map it again.
  • If the original MDL was not mapped in system space, the partial MDL is not either. If you need a system mode address, call MmGetSystemAddressForMdlSafe on the partial MDL.
  • If you do not know which of the above applies, it is safe to call MmGetSystemAddressForMdlSafe regardless. If a partial MDL is built from a source MDL that is already mapped into the system address space, MmGetSystemAddressForMdlSafe uses the existing source mapping. Otherwise, MmGetSystemAddressForMdlSafe creates a new mapping.

To prevent this new mapping from being leaked, drivers must call MmPrepareMdlForReuse before reusing a partial MDL. In addition, the IoFreeMdl routine releases the system-address-space mapping for a partial MDL, if such a mapping exists.

For more information about MDLs, see Using MDLs.

Requirements

Requirement Value
Minimum supported client Available starting with Windows 2000.
Target Platform Universal
Header wdm.h (include Wdm.h, Ntddk.h, Ntifs.h)
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL <=DISPATCH_LEVEL
DDI compliance rules MdlAfterReqCompletedIntIoctlA(kmdf), MdlAfterReqCompletedIoctlA(kmdf), MdlAfterReqCompletedReadA(kmdf), MdlAfterReqCompletedWriteA(kmdf)

See also

IoFreeMdl

MmAllocatePagesForMdl

MmAllocatePagesForMdlEx

MmBuildMdlForNonPagedPool

MmGetSystemAddressForMdlSafe

MmPrepareMdlForReuse

MmProbeAndLockPages