1 /******************************************************************************
2 * Memory manager Functions *
3 ******************************************************************************/
6 #define ALIGN_DOWN_BY(size, align) \
7 ((ULONG_PTR)(size) & ~((ULONG_PTR)(align) - 1))
9 #define ALIGN_UP_BY(size, align) \
10 (ALIGN_DOWN_BY(((ULONG_PTR)(size) + align - 1), align))
12 #define ALIGN_DOWN_POINTER_BY(ptr, align) \
13 ((PVOID)ALIGN_DOWN_BY(ptr, align))
15 #define ALIGN_UP_POINTER_BY(ptr, align) \
16 ((PVOID)ALIGN_UP_BY(ptr, align))
18 #define ALIGN_DOWN(size, type) \
19 ALIGN_DOWN_BY(size, sizeof(type))
21 #define ALIGN_UP(size, type) \
22 ALIGN_UP_BY(size, sizeof(type))
24 #define ALIGN_DOWN_POINTER(ptr, type) \
25 ALIGN_DOWN_POINTER_BY(ptr, sizeof(type))
27 #define ALIGN_UP_POINTER(ptr, type) \
28 ALIGN_UP_POINTER_BY(ptr, sizeof(type))
31 #define FIELD_OFFSET(type, field) ((ULONG)&(((type *)0)->field))
35 #define FIELD_SIZE(type, field) (sizeof(((type *)0)->field))
38 #define POOL_TAGGING 1
41 #define IF_DEBUG if (TRUE)
43 #define IF_DEBUG if (FALSE)
50 #define BYTE_OFFSET(Va) \
51 ((ULONG) ((ULONG_PTR) (Va) & (PAGE_SIZE - 1)))
57 #define BYTES_TO_PAGES(Size) \
58 (((Size) + PAGE_SIZE - 1) >> PAGE_SHIFT)
64 #define PAGE_ALIGN(Va) \
65 ((PVOID) ((ULONG_PTR)(Va) & ~(PAGE_SIZE - 1)))
71 #define ROUND_TO_PAGES(Size) \
72 (((ULONG_PTR) (Size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
75 * ADDRESS_AND_SIZE_TO_SPAN_PAGES(
79 #define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size) \
80 ((ULONG) ((((ULONG_PTR) (_Va) & (PAGE_SIZE - 1)) \
81 + (_Size) + (PAGE_SIZE - 1)) >> PAGE_SHIFT))
83 #define COMPUTE_PAGES_SPANNED(Va, Size) \
84 ADDRESS_AND_SIZE_TO_SPAN_PAGES(Va,Size)
91 #define MmGetMdlByteCount(_Mdl) \
99 #define MmGetMdlByteOffset(_Mdl) \
102 #define MmGetMdlBaseVa(Mdl) ((Mdl)->StartVa)
109 #define MmGetMdlPfnArray(_Mdl) \
110 ((PPFN_NUMBER) ((_Mdl) + 1))
114 * MmGetMdlVirtualAddress(
117 #define MmGetMdlVirtualAddress(_Mdl) \
118 ((PVOID) ((PCHAR) ((_Mdl)->StartVa) + (_Mdl)->ByteOffset))
120 #define MmGetProcedureAddress(Address) (Address)
121 #define MmLockPagableCodeSection(Address) MmLockPagableDataSection(Address)
123 /* PVOID MmGetSystemAddressForMdl(
126 #define MmGetSystemAddressForMdl(Mdl) \
127 (((Mdl)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | \
128 MDL_SOURCE_IS_NONPAGED_POOL)) ? \
129 ((Mdl)->MappedSystemVa) : \
130 (MmMapLockedPages((Mdl), KernelMode)))
133 * MmGetSystemAddressForMdlSafe(
135 * IN MM_PAGE_PRIORITY Priority)
137 #define MmGetSystemAddressForMdlSafe(_Mdl, _Priority) \
138 (((_Mdl)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA \
139 | MDL_SOURCE_IS_NONPAGED_POOL)) ? \
140 (_Mdl)->MappedSystemVa : \
141 (PVOID) MmMapLockedPagesSpecifyCache((_Mdl), \
142 KernelMode, MmCached, NULL, FALSE, (_Priority)))
147 * IN PMDL MemoryDescriptorList,
151 #define MmInitializeMdl(_MemoryDescriptorList, \
155 (_MemoryDescriptorList)->Next = (PMDL) NULL; \
156 (_MemoryDescriptorList)->Size = (CSHORT) (sizeof(MDL) + \
157 (sizeof(PFN_NUMBER) * ADDRESS_AND_SIZE_TO_SPAN_PAGES(_BaseVa, _Length))); \
158 (_MemoryDescriptorList)->MdlFlags = 0; \
159 (_MemoryDescriptorList)->StartVa = (PVOID) PAGE_ALIGN(_BaseVa); \
160 (_MemoryDescriptorList)->ByteOffset = BYTE_OFFSET(_BaseVa); \
161 (_MemoryDescriptorList)->ByteCount = (ULONG) _Length; \
166 * MmPrepareMdlForReuse(
169 #define MmPrepareMdlForReuse(_Mdl) \
171 if (((_Mdl)->MdlFlags & MDL_PARTIAL_HAS_BEEN_MAPPED) != 0) { \
172 ASSERT(((_Mdl)->MdlFlags & MDL_PARTIAL) != 0); \
173 MmUnmapLockedPages((_Mdl)->MappedSystemVa, (_Mdl)); \
174 } else if (((_Mdl)->MdlFlags & MDL_PARTIAL) == 0) { \
175 ASSERT(((_Mdl)->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) == 0); \
187 //__assume_bound(TagBase); // FIXME
188 return ((ULONG
)((TagBase
) + ((Tag
) << HEAP_TAG_SHIFT
)));
192 #if (NTDDI_VERSION >= NTDDI_WIN2K)
194 _Must_inspect_result_
195 _IRQL_requires_max_(DISPATCH_LEVEL
)
196 _When_ (return != NULL
, _Post_writable_byte_size_ (NumberOfBytes
))
200 MmAllocateContiguousMemory(
201 _In_ SIZE_T NumberOfBytes
,
202 _In_ PHYSICAL_ADDRESS HighestAcceptableAddress
);
204 _Must_inspect_result_
205 _IRQL_requires_max_(DISPATCH_LEVEL
)
206 _When_ (return != NULL
, _Post_writable_byte_size_ (NumberOfBytes
))
210 MmAllocateContiguousMemorySpecifyCache(
211 _In_ SIZE_T NumberOfBytes
,
212 _In_ PHYSICAL_ADDRESS LowestAcceptableAddress
,
213 _In_ PHYSICAL_ADDRESS HighestAcceptableAddress
,
214 _In_opt_ PHYSICAL_ADDRESS BoundaryAddressMultiple
,
215 _In_ MEMORY_CACHING_TYPE CacheType
);
217 _Must_inspect_result_
218 _IRQL_requires_max_(DISPATCH_LEVEL
)
222 MmAllocatePagesForMdl(
223 _In_ PHYSICAL_ADDRESS LowAddress
,
224 _In_ PHYSICAL_ADDRESS HighAddress
,
225 _In_ PHYSICAL_ADDRESS SkipBytes
,
226 _In_ SIZE_T TotalBytes
);
228 _IRQL_requires_max_(DISPATCH_LEVEL
)
232 MmBuildMdlForNonPagedPool(
233 _Inout_ PMDLX MemoryDescriptorList
);
235 //DECLSPEC_DEPRECATED_DDK
240 _Out_writes_bytes_opt_ (sizeof (MDL
) + (sizeof (PFN_NUMBER
) * ADDRESS_AND_SIZE_TO_SPAN_PAGES (Base
, Length
)))
241 PMDL MemoryDescriptorList
,
242 _In_reads_bytes_opt_ (Length
) PVOID Base
,
245 _IRQL_requires_max_(DISPATCH_LEVEL
)
249 MmFreeContiguousMemory(
250 _In_ PVOID BaseAddress
);
252 _IRQL_requires_max_ (DISPATCH_LEVEL
)
256 MmFreeContiguousMemorySpecifyCache(
257 _In_reads_bytes_ (NumberOfBytes
) PVOID BaseAddress
,
258 _In_ SIZE_T NumberOfBytes
,
259 _In_ MEMORY_CACHING_TYPE CacheType
);
261 _IRQL_requires_max_(DISPATCH_LEVEL
)
266 _Inout_ PMDLX MemoryDescriptorList
);
268 _IRQL_requires_max_(PASSIVE_LEVEL
)
272 MmGetSystemRoutineAddress(
273 _In_ PUNICODE_STRING SystemRoutineName
);
279 _In_
struct _DRIVER_OBJECT
*DriverObject
);
281 _Must_inspect_result_
282 _IRQL_requires_max_(APC_LEVEL
)
286 MmLockPagableDataSection(
287 _In_ PVOID AddressWithinSection
);
289 _Must_inspect_result_
290 _IRQL_requires_max_(DISPATCH_LEVEL
)
291 _Out_writes_bytes_opt_ (NumberOfBytes
)
296 _In_ PHYSICAL_ADDRESS PhysicalAddress
,
297 _In_ SIZE_T NumberOfBytes
,
298 _In_ MEMORY_CACHING_TYPE CacheType
);
300 _Must_inspect_result_
301 _When_(AccessMode
==KernelMode
, _IRQL_requires_max_(DISPATCH_LEVEL
))
302 _When_(AccessMode
==UserMode
, _Maybe_raises_SEH_exception_
_IRQL_requires_max_(APC_LEVEL
))
307 _Inout_ PMDL MemoryDescriptorList
,
308 _In_
__drv_strictType(KPROCESSOR_MODE
/enum _MODE
,__drv_typeConst
)
309 KPROCESSOR_MODE AccessMode
);
311 _Post_writable_byte_size_(MemoryDescriptorList
->ByteCount
)
312 _When_(AccessMode
==KernelMode
, _IRQL_requires_max_(DISPATCH_LEVEL
))
313 _When_(AccessMode
==UserMode
, _Maybe_raises_SEH_exception_
_IRQL_requires_max_(APC_LEVEL
) _Post_notnull_
)
314 _At_(MemoryDescriptorList
->MappedSystemVa
, _Post_writable_byte_size_(MemoryDescriptorList
->ByteCount
))
315 _Must_inspect_result_
316 _Success_(return != NULL
)
320 MmMapLockedPagesSpecifyCache(
321 _Inout_ PMDLX MemoryDescriptorList
,
322 _In_
__drv_strictType(KPROCESSOR_MODE
/enum _MODE
,__drv_typeConst
)
323 KPROCESSOR_MODE AccessMode
,
324 _In_
__drv_strictTypeMatch(__drv_typeCond
) MEMORY_CACHING_TYPE CacheType
,
325 _In_opt_ PVOID BaseAddress
,
326 _In_ ULONG BugCheckOnFailure
,
327 _In_ MM_PAGE_PRIORITY Priority
);
329 _IRQL_requires_max_(APC_LEVEL
)
334 _In_ PVOID AddressWithinSection
);
336 _IRQL_requires_max_(DISPATCH_LEVEL
)
337 _At_(MemoryDescriptorList
->StartVa
+ MemoryDescriptorList
->ByteOffset
,
338 _Field_size_bytes_opt_(MemoryDescriptorList
->ByteCount
))
343 _Inout_ PMDLX MemoryDescriptorList
,
344 _In_ KPROCESSOR_MODE AccessMode
,
345 _In_ LOCK_OPERATION Operation
);
350 MmQuerySystemSize(VOID
);
352 _IRQL_requires_max_(APC_LEVEL
)
357 _In_ PVOID AddressWithinSection
);
363 _In_reads_bytes_opt_ (Length
) PVOID Base
,
366 _IRQL_requires_max_(DISPATCH_LEVEL
)
370 MmUnlockPagableImageSection(
371 _In_ PVOID ImageSectionHandle
);
373 _IRQL_requires_max_(DISPATCH_LEVEL
)
378 _Inout_ PMDLX MemoryDescriptorList
);
380 _IRQL_requires_max_(DISPATCH_LEVEL
)
385 _In_reads_bytes_ (NumberOfBytes
) PVOID BaseAddress
,
386 _In_ SIZE_T NumberOfBytes
);
388 _IRQL_requires_max_ (APC_LEVEL
)
392 MmProbeAndLockProcessPages(
393 _Inout_ PMDL MemoryDescriptorList
,
394 _In_ PEPROCESS Process
,
395 _In_ KPROCESSOR_MODE AccessMode
,
396 _In_ LOCK_OPERATION Operation
);
398 _IRQL_requires_max_(DISPATCH_LEVEL
)
403 _In_ PVOID BaseAddress
,
404 _Inout_ PMDL MemoryDescriptorList
);
406 _Must_inspect_result_
407 _IRQL_requires_max_(DISPATCH_LEVEL
)
408 _When_ (return != NULL
, _Post_writable_byte_size_ (NumberOfBytes
))
412 MmAllocateContiguousMemorySpecifyCacheNode(
413 _In_ SIZE_T NumberOfBytes
,
414 _In_ PHYSICAL_ADDRESS LowestAcceptableAddress
,
415 _In_ PHYSICAL_ADDRESS HighestAcceptableAddress
,
416 _In_opt_ PHYSICAL_ADDRESS BoundaryAddressMultiple
,
417 _In_ MEMORY_CACHING_TYPE CacheType
,
418 _In_ NODE_REQUIREMENT PreferredNode
);
422 _IRQL_requires_max_ (PASSIVE_LEVEL
)
424 PPHYSICAL_MEMORY_RANGE
426 MmGetPhysicalMemoryRanges(VOID
);
431 MmGetPhysicalAddress(
432 _In_ PVOID BaseAddress
);
437 MmIsNonPagedSystemAddressValid(
438 _In_ PVOID VirtualAddress
);
440 _Must_inspect_result_
441 _IRQL_requires_max_(APC_LEVEL
)
442 _Out_writes_bytes_opt_(NumberOfBytes
)
446 MmAllocateNonCachedMemory(
447 _In_ SIZE_T NumberOfBytes
);
449 _IRQL_requires_max_(APC_LEVEL
)
453 MmFreeNonCachedMemory(
454 _In_reads_bytes_(NumberOfBytes
) PVOID BaseAddress
,
455 _In_ SIZE_T NumberOfBytes
);
460 MmGetVirtualForPhysical(
461 _In_ PHYSICAL_ADDRESS PhysicalAddress
);
463 _Must_inspect_result_
464 _IRQL_requires_max_(APC_LEVEL
)
468 MmMapUserAddressesToPage(
469 _In_reads_bytes_(NumberOfBytes
) PVOID BaseAddress
,
470 _In_ SIZE_T NumberOfBytes
,
471 _In_ PVOID PageAddress
);
473 _Must_inspect_result_
474 _IRQL_requires_max_(APC_LEVEL
)
475 _Out_writes_bytes_opt_(NumberOfBytes
)
480 _In_ PHYSICAL_ADDRESS PhysicalAddress
,
481 _In_ SIZE_T NumberOfBytes
,
482 _In_ MEMORY_CACHING_TYPE CacheType
);
484 _Must_inspect_result_
485 _IRQL_requires_max_(APC_LEVEL
)
489 MmMapViewInSessionSpace(
491 _Outptr_result_bytebuffer_(*ViewSize
) PVOID
*MappedBase
,
492 _Inout_ PSIZE_T ViewSize
);
494 _Must_inspect_result_
495 _IRQL_requires_max_(APC_LEVEL
)
499 MmMapViewInSystemSpace(
501 _Outptr_result_bytebuffer_(*ViewSize
) PVOID
*MappedBase
,
502 _Inout_ PSIZE_T ViewSize
);
504 _IRQL_requires_max_(DISPATCH_LEVEL
)
509 _In_ PVOID VirtualAddress
);
514 MmIsThisAnNtAsSystem(VOID
);
516 _IRQL_requires_max_(APC_LEVEL
)
520 MmLockPagableSectionByHandle(
521 _In_ PVOID ImageSectionHandle
);
523 _IRQL_requires_max_(APC_LEVEL
)
527 MmUnmapViewInSessionSpace(
528 _In_ PVOID MappedBase
);
530 _IRQL_requires_max_(APC_LEVEL
)
534 MmUnmapViewInSystemSpace(
535 _In_ PVOID MappedBase
);
537 _IRQL_requires_max_(APC_LEVEL
)
541 MmUnsecureVirtualMemory(
542 _In_ HANDLE SecureHandle
);
544 _IRQL_requires_max_ (PASSIVE_LEVEL
)
548 MmRemovePhysicalMemory(
549 _In_ PPHYSICAL_ADDRESS StartAddress
,
550 _Inout_ PLARGE_INTEGER NumberOfBytes
);
552 _Must_inspect_result_
553 _IRQL_requires_max_(APC_LEVEL
)
557 MmSecureVirtualMemory(
558 __in_data_source(USER_MODE
) _In_reads_bytes_ (Size
) PVOID Address
,
559 _In_
__in_data_source(USER_MODE
) SIZE_T Size
,
560 _In_ ULONG ProbeMode
);
562 _IRQL_requires_max_(APC_LEVEL
)
567 _In_reads_bytes_(NumberOfBytes
) PVOID BaseAddress
,
568 _In_ SIZE_T NumberOfBytes
);
570 _IRQL_requires_max_ (PASSIVE_LEVEL
)
575 _In_ PPHYSICAL_ADDRESS StartAddress
,
576 _Inout_ PLARGE_INTEGER NumberOfBytes
);
583 MmIsRecursiveIoFault(VOID
);
585 _IRQL_requires_max_ (APC_LEVEL
)
589 MmForceSectionClosed(
590 _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
,
591 _In_ BOOLEAN DelayClose
);
593 _IRQL_requires_max_ (APC_LEVEL
)
598 _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
,
599 _In_ MMFLUSH_TYPE FlushType
);
601 _IRQL_requires_max_ (APC_LEVEL
)
605 MmCanFileBeTruncated(
606 _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
,
607 _In_opt_ PLARGE_INTEGER NewFileSize
);
609 _IRQL_requires_max_ (APC_LEVEL
)
613 MmSetAddressRangeModified(
614 _In_reads_bytes_ (Length
) PVOID Address
,
618 #endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */
620 $
if (_WDMDDK_
|| _NTIFS_
)
621 #if (NTDDI_VERSION >= NTDDI_WINXP)
622 $
endif (_WDMDDK_
|| _NTIFS_
)
625 _IRQL_requires_max_(DISPATCH_LEVEL
)
631 _In_ ULONG NumberOfBytes
);
633 _Must_inspect_result_
634 _IRQL_requires_max_(APC_LEVEL
)
635 _When_ (return != NULL
, _Out_writes_bytes_opt_ (NumberOfBytes
))
639 MmAllocateMappingAddress(
640 _In_ SIZE_T NumberOfBytes
,
643 _IRQL_requires_max_(APC_LEVEL
)
647 MmFreeMappingAddress(
648 _In_ PVOID BaseAddress
,
651 _IRQL_requires_max_ (APC_LEVEL
)
656 _Out_ PULONG VerifierFlags
);
658 _Post_writable_byte_size_(MemoryDescriptorList
->ByteCount
)
659 _IRQL_requires_max_(DISPATCH_LEVEL
)
660 _At_(MemoryDescriptorList
->MappedSystemVa
+ MemoryDescriptorList
->ByteOffset
,
661 _Post_writable_byte_size_(MemoryDescriptorList
->ByteCount
))
662 _Must_inspect_result_
663 _Success_(return != NULL
)
667 MmMapLockedPagesWithReservedMapping(
668 _In_ PVOID MappingAddress
,
670 _Inout_ PMDLX MemoryDescriptorList
,
671 _In_
__drv_strictTypeMatch(__drv_typeCond
)
672 MEMORY_CACHING_TYPE CacheType
);
674 _Must_inspect_result_
675 _IRQL_requires_max_(DISPATCH_LEVEL
)
679 MmProtectMdlSystemAddress(
680 _In_ PMDLX MemoryDescriptorList
,
681 _In_ ULONG NewProtect
);
683 _IRQL_requires_max_(DISPATCH_LEVEL
)
687 MmUnmapReservedMapping(
688 _In_ PVOID BaseAddress
,
690 _Inout_ PMDLX MemoryDescriptorList
);
692 _IRQL_requires_max_ (APC_LEVEL
)
697 _In_reads_bytes_ (ThunkBufferSize
) PVOID ThunkBuffer
,
698 _In_ ULONG ThunkBufferSize
);
702 _IRQL_requires_max_ (PASSIVE_LEVEL
)
707 _In_ ULONG NumberOfLists
,
708 _In_reads_ (NumberOfLists
) PREAD_LIST
*ReadLists
);
711 $
if (_WDMDDK_
|| _NTIFS_
)
712 #endif /* (NTDDI_VERSION >= NTDDI_WINXP) */
713 $
endif (_WDMDDK_
|| _NTIFS_
)
714 $
if (_WDMDDK_
|| _NTDDK_
)
715 #if (NTDDI_VERSION >= NTDDI_WS03)
716 $
endif (_WDMDDK_
|| _NTDDK_
)
718 _IRQL_requires_max_ (DISPATCH_LEVEL
)
723 _In_ PHYSICAL_ADDRESS StartAddress
,
724 _In_ SIZE_T NumberOfBytes
);
728 _Must_inspect_result_
729 _IRQL_requires_max_(PASSIVE_LEVEL
)
733 MmCreateMirror(VOID
);
735 $
if (_WDMDDK_
|| _NTDDK_
)
736 #endif /* (NTDDI_VERSION >= NTDDI_WS03) */
737 $
endif (_WDMDDK_
|| _NTDDK_
)
739 #if (NTDDI_VERSION >= NTDDI_WS03SP1)
740 _Must_inspect_result_
741 _IRQL_requires_max_ (DISPATCH_LEVEL
)
745 MmAllocatePagesForMdlEx(
746 _In_ PHYSICAL_ADDRESS LowAddress
,
747 _In_ PHYSICAL_ADDRESS HighAddress
,
748 _In_ PHYSICAL_ADDRESS SkipBytes
,
749 _In_ SIZE_T TotalBytes
,
750 _In_ MEMORY_CACHING_TYPE CacheType
,
755 #if (NTDDI_VERSION >= NTDDI_VISTA)
757 _IRQL_requires_max_ (APC_LEVEL
)
761 MmIsDriverVerifyingByAddress(
762 _In_ PVOID AddressWithinSection
);
765 _Must_inspect_result_
766 _IRQL_requires_max_(APC_LEVEL
)
769 MmRotatePhysicalView(
770 _In_ PVOID VirtualAddress
,
771 _Inout_ PSIZE_T NumberOfBytes
,
772 _In_opt_ PMDLX NewMdl
,
773 _In_ MM_ROTATE_DIRECTION Direction
,
774 _In_ PMM_ROTATE_COPY_CALLBACK_FUNCTION CopyFunction
,
775 _In_opt_ PVOID Context
);
779 _IRQL_requires_max_ (APC_LEVEL
)
783 MmDoesFileHaveUserWritableReferences(
784 _In_ PSECTION_OBJECT_POINTERS SectionPointer
);
786 #endif /* (NTDDI_VERSION >= NTDDI_VISTA) */