IoAllocateMdl
来源:互联网 发布:软件技术学校 编辑:程序博客网 时间:2024/05/17 04:04
PMDLIoAllocateMdl( IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN OUT PIRP Irp OPTIONAL )/*++Routine Description:分配一块内存描述符,由参数VirtualAddress和Length指定了MDL需要映射的大小。如果参数指定了一个IRP,那么将以合适的方式把该MDL挂接到IRP中。 如果例程没有指定IRP参数,那么由调用者负责设定需要申请MDL的IRP的MDL地址 如果没有指定一个IRP,由调用者负责将他写入为之申请的IRP中(如果需要)。 注意MDL的头部信息在调用成功后也会被初始化。Arguments: VirtualAddress - 将要映射的起始虚拟地址。 Length - 虚拟地址空间需要映射的长度,以字节为单位。 SecondaryBuffer - 此参数仅当指定了IRP时有效。如果SecondaryBuffer为TRUE,那么将链接MDL到IRP的MDL链表中(通过MDL->next),否则将申请到的MDL替换掉原来IRP的MDL(替换Irp->MdlAddress) ChargeQuota - 指定MDL的配额控制。注意,在WRK1.2中此参数被忽略。 Irp - 指定MDL服务的IRP,为可选的参数。Return Value: 返回申请的MDL,创建MDL失败返回NULL。如果是因为配额导致的MDL创建失败,由调用者负责捕捉这个异常。--*/{ ULONG allocateSize; USHORT fixedSize; PMDL mdl; ULONG size; PMDL tmpMdlPtr; ASSERT(Length);//在WRK1.2中配额参数被忽略。 UNREFERENCED_PARAMETER (ChargeQuota); // // 如果请求映射的长度超过2Gb,我们无法映射这个内存。因此请求失败。 // if (Length & 0x80000000) { return NULL; } // // 从lookaside列表或者是内存池分配一个Allocate。 // mdl = NULL; fixedSize = 0;//计算需要的页面数量 size = ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress, Length);//1.如果需要的页面数大于IOP_FIXED_SIZE_MDL_PFNS(0x17)那么计算需要申请的内存大小。并且从全局内存池中申请。//2.否则从LookasideList列表中申请一块MDL内存,在LookasideMdlList中申请的页面数是个固定大小IOP_FIXED_SIZE_MDL_PFNS(0x17)。及时需要的PFN数量<IOP_FIXED_SIZE_MDL_PFNS// 如果从LookasideList列表中申请失败,最后还是从内存池中分配内存。 if (size > IOP_FIXED_SIZE_MDL_PFNS) { allocateSize = sizeof(MDL) + (sizeof(PFN_NUMBER) * size); if (allocateSize > MAXUSHORT) { return NULL; } } else { fixedSize = MDL_ALLOCATED_FIXED_SIZE; allocateSize = sizeof(MDL) + (sizeof(PFN_NUMBER) * IOP_FIXED_SIZE_MDL_PFNS); mdl = (PMDL)ExAllocateFromPPLookasideList(LookasideMdlList); } if (!mdl) { mdl = ExAllocatePoolWithTag(NonPagedPool, allocateSize, ' ldM'); if (!mdl) { return NULL; } } // // 填充MDL的头部。如果是固定大小(从LookasideList中分配内存)设置标志位MDL_ALLOCATED_FIXED_SIZE。 // MmInitializeMdl(mdl, VirtualAddress, Length); mdl->MdlFlags |= (fixedSize); // // 最后,如果指定了一个IRP参数,那么将MDL填入到MDL中。 // 填充方式基于SecondaryBuffer的设定,如果为TRUE,挂入到IRP的MDL链表中。如果为FALSE,直接替换IRP->MdlAddress. // if (Irp) { if (!SecondaryBuffer) { Irp->MdlAddress = mdl; } else { tmpMdlPtr = Irp->MdlAddress; while (tmpMdlPtr->Next != NULL) { tmpMdlPtr = tmpMdlPtr->Next; } tmpMdlPtr->Next = mdl; } } return mdl;}
0 0
- IoAllocateMdl
- 内核API之IoAllocateMdl
- 内核API之IoAllocateMdl
- IoAllocateMdl,MmProbeAndLockPages的用法
- IoAllocateMdl,MmProbeAndLockPages的用法
- IoAllocateMdl,MmProbeAndLockPages的用法
- MDL的使用(一) IoAllocateMdl / MmInitializeMdl
- 交叉编译工具链安装
- HTML5的革新——语义化标签
- POJ_P2976 Dropping tests(01分数规划)
- FastFDS原理
- TOJ 3484.Stones
- IoAllocateMdl
- 我是如何学习计算机编程的
- C 结构体 内存分配
- python中的时间和时间格式转换
- 发现自己好久没有来到这里了
- weak_ptr基本用法
- 交叉编译工具链安装
- FastDFS安装
- 九九乘法表