The IoAllocateMdl routine allocates a memory descriptor list (MDL) large enough to map a buffer, given the buffer's starting address and length. Optionally, this routine associates the MDL with an IRP.
Syntax
C++
PMDL IoAllocateMdl(
_In_opt_ PVOID VirtualAddress,
_In_ ULONG Length,
_In_ BOOLEAN SecondaryBuffer,
_In_ BOOLEAN ChargeQuota,
_Inout_opt_ PIRP Irp
);
Parameters
VirtualAddress [in, optional]
Pointer to the base virtual address of the buffer the MDL is to describe.
Length [in]
Specifies the length, in bytes, of the buffer that the MDL is to describe. For more information, see the following Remarks section.
SecondaryBuffer [in]
Indicates whether the buffer is a primary or secondary buffer. This parameter determines how the MDL is to be linked to the IRP. All buffers except the first buffer described by an MDL in an IRP are considered secondary buffers. This field must be FALSE if no IRP is associated with the MDL. For more information, see the following Remarks section.
ChargeQuota [in]
Reserved for system use. Drivers must set this parameter to FALSE.
Irp [in, out, optional]
Pointer to an IRP to be associated with the MDL. If the Irp pointer is non-NULL, the allocated MDL is associated with the specified IRP's MDL list, according to the value of SecondaryBuffer.
Return value
IoAllocateMdl returns a pointer to an MDL, or, if the MDL cannot be allocated, it returns NULL.
Remarks
IoAllocateMdl can be used by a driver that needs to break a buffer into pieces, each mapped by a separate MDL, or to map a driver-allocated buffer. The driver should call MmBuildMdlForNonPagedPool with the MDL allocated by this call to set up an MDL describing a driver-allocated buffer in nonpaged pool.
The Length parameter specifies the size of the buffer that is to be described by the MDL. In Windows Server 2003, Windows XP, and Windows 2000, the maximum buffer size, in bytes, that this routine can allocate is PAGE_SIZE * (65535 - sizeof(MDL)) / sizeof(ULONG_PTR). In Windows Vista and Windows Server 2008, the maximum buffer size is (2 gigabytes - PAGE_SIZE). In Windows 7 and Windows Server 2008 R2, the maximum buffer size is (4 gigabytes - PAGE_SIZE).
If the SecondaryBuffer parameter is FALSE, the routine updates Irp->MdlAddress to point to the new MDL. IfSecondaryBuffer is TRUE, the routine adds the MDL to the end of the MDL chain that Irp->MdlAddress points to.
For more information about MDLs, see Using MDLs.
Requirements
| Version | Available in Windows 2000 and later versions of Windows. |
|---|---|
| Header | Wdm.h (include Wdm.h, Ntddk.h, or Ntifs.h) |
| Library | Contained in Ntoskrnl.lib. |
| IRQL | <= DISPATCH_LEVEL |
这里,需要注意的是第二个参数Length。计算公式Length ≤PAGE_SIZE * (65535 - sizeof(MDL)) / sizeof(ULONG_PTR),PAGE_SIZE在大多数Windows系统(包括win2003-x64、xp)中为4KB,sizeof(ULONG_PTR)在32bit系统中为4B,在64bit系统中为8B。因此,限制为32bit系统中length<64MB,64bit系统中length<32MB,否则函数返回值将会是NULL。
本文深入探讨了Windows系统中IoAllocateMdl函数的作用,如何分配内存描述符列表(MDL),并将其与IRP(内部请求程序)关联。重点介绍了函数参数解释、返回值、以及最大可分配缓冲区大小的计算方法。
2972

被折叠的 条评论
为什么被折叠?



