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 * Note: This needs to be like this to avoid overflows!
59 #define BYTES_TO_PAGES(Size) \
60 (((Size) >> PAGE_SHIFT) + (((Size) & (PAGE_SIZE - 1)) != 0))
66 #define PAGE_ALIGN(Va) \
67 ((PVOID) ((ULONG_PTR)(Va) & ~(PAGE_SIZE - 1)))
71 * _In_ ULONG_PTR Size)
73 #define ROUND_TO_PAGES(Size) \
74 (((ULONG_PTR) (Size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
77 * ADDRESS_AND_SIZE_TO_SPAN_PAGES(
81 #define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size) \
82 ((ULONG) ((((ULONG_PTR) (_Va) & (PAGE_SIZE - 1)) \
83 + (_Size) + (PAGE_SIZE - 1)) >> PAGE_SHIFT))
85 #define COMPUTE_PAGES_SPANNED(Va, Size) \
86 ADDRESS_AND_SIZE_TO_SPAN_PAGES(Va,Size)
93 #define MmGetMdlByteCount(_Mdl) \
101 #define MmGetMdlByteOffset(_Mdl) \
104 #define MmGetMdlBaseVa(Mdl) ((Mdl)->StartVa)
111 #define MmGetMdlPfnArray(_Mdl) \
112 ((PPFN_NUMBER) ((_Mdl) + 1))
116 * MmGetMdlVirtualAddress(
119 #define MmGetMdlVirtualAddress(_Mdl) \
120 ((PVOID) ((PCHAR) ((_Mdl)->StartVa) + (_Mdl)->ByteOffset))
122 #define MmGetProcedureAddress(Address) (Address)
123 #define MmLockPagableCodeSection(Address) MmLockPagableDataSection(Address)
125 /* PVOID MmGetSystemAddressForMdl(
128 #define MmGetSystemAddressForMdl(Mdl) \
129 (((Mdl)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | \
130 MDL_SOURCE_IS_NONPAGED_POOL)) ? \
131 ((Mdl)->MappedSystemVa) : \
132 (MmMapLockedPages((Mdl), KernelMode)))
135 * MmGetSystemAddressForMdlSafe(
137 * _In_ MM_PAGE_PRIORITY Priority)
139 #define MmGetSystemAddressForMdlSafe(_Mdl, _Priority) \
140 (((_Mdl)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA \
141 | MDL_SOURCE_IS_NONPAGED_POOL)) ? \
142 (_Mdl)->MappedSystemVa : \
143 (PVOID) MmMapLockedPagesSpecifyCache((_Mdl), \
144 KernelMode, MmCached, NULL, FALSE, (_Priority)))
149 * _In_ PMDL MemoryDescriptorList,
151 * _In_ SIZE_T Length)
153 #define MmInitializeMdl(_MemoryDescriptorList, \
157 (_MemoryDescriptorList)->Next = (PMDL) NULL; \
158 (_MemoryDescriptorList)->Size = (CSHORT) (sizeof(MDL) + \
159 (sizeof(PFN_NUMBER) * ADDRESS_AND_SIZE_TO_SPAN_PAGES(_BaseVa, _Length))); \
160 (_MemoryDescriptorList)->MdlFlags = 0; \
161 (_MemoryDescriptorList)->StartVa = (PVOID) PAGE_ALIGN(_BaseVa); \
162 (_MemoryDescriptorList)->ByteOffset = BYTE_OFFSET(_BaseVa); \
163 (_MemoryDescriptorList)->ByteCount = (ULONG) _Length; \
168 * MmPrepareMdlForReuse(
171 #define MmPrepareMdlForReuse(_Mdl) \
173 if (((_Mdl)->MdlFlags & MDL_PARTIAL_HAS_BEEN_MAPPED) != 0) { \
174 ASSERT(((_Mdl)->MdlFlags & MDL_PARTIAL) != 0); \
175 MmUnmapLockedPages((_Mdl)->MappedSystemVa, (_Mdl)); \
176 } else if (((_Mdl)->MdlFlags & MDL_PARTIAL) == 0) { \
177 ASSERT(((_Mdl)->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) == 0); \
189 //__assume_bound(TagBase); // FIXME
190 return ((ULONG
)((TagBase
) + ((Tag
) << HEAP_TAG_SHIFT
)));
194 #if (NTDDI_VERSION >= NTDDI_WIN2K)
196 _Must_inspect_result_
197 _IRQL_requires_max_(DISPATCH_LEVEL
)
198 _When_ (return != NULL
, _Post_writable_byte_size_ (NumberOfBytes
))
202 MmAllocateContiguousMemory(
203 _In_ SIZE_T NumberOfBytes
,
204 _In_ PHYSICAL_ADDRESS HighestAcceptableAddress
);
206 _Must_inspect_result_
207 _IRQL_requires_max_(DISPATCH_LEVEL
)
208 _When_ (return != NULL
, _Post_writable_byte_size_ (NumberOfBytes
))
212 MmAllocateContiguousMemorySpecifyCache(
213 _In_ SIZE_T NumberOfBytes
,
214 _In_ PHYSICAL_ADDRESS LowestAcceptableAddress
,
215 _In_ PHYSICAL_ADDRESS HighestAcceptableAddress
,
216 _In_opt_ PHYSICAL_ADDRESS BoundaryAddressMultiple
,
217 _In_ MEMORY_CACHING_TYPE CacheType
);
219 _Must_inspect_result_
220 _IRQL_requires_max_(DISPATCH_LEVEL
)
224 MmAllocatePagesForMdl(
225 _In_ PHYSICAL_ADDRESS LowAddress
,
226 _In_ PHYSICAL_ADDRESS HighAddress
,
227 _In_ PHYSICAL_ADDRESS SkipBytes
,
228 _In_ SIZE_T TotalBytes
);
230 _IRQL_requires_max_(DISPATCH_LEVEL
)
234 MmBuildMdlForNonPagedPool(
235 _Inout_ PMDL MemoryDescriptorList
);
237 //DECLSPEC_DEPRECATED_DDK
242 _Out_writes_bytes_opt_ (sizeof (MDL
) + (sizeof (PFN_NUMBER
) * ADDRESS_AND_SIZE_TO_SPAN_PAGES (Base
, Length
)))
243 PMDL MemoryDescriptorList
,
244 _In_reads_bytes_opt_ (Length
) PVOID Base
,
247 _IRQL_requires_max_(DISPATCH_LEVEL
)
251 MmFreeContiguousMemory(
252 _In_ PVOID BaseAddress
);
254 _IRQL_requires_max_ (DISPATCH_LEVEL
)
258 MmFreeContiguousMemorySpecifyCache(
259 _In_reads_bytes_ (NumberOfBytes
) PVOID BaseAddress
,
260 _In_ SIZE_T NumberOfBytes
,
261 _In_ MEMORY_CACHING_TYPE CacheType
);
263 _IRQL_requires_max_(DISPATCH_LEVEL
)
268 _Inout_ PMDL MemoryDescriptorList
);
270 _IRQL_requires_max_(PASSIVE_LEVEL
)
274 MmGetSystemRoutineAddress(
275 _In_ PUNICODE_STRING SystemRoutineName
);
281 _In_
struct _DRIVER_OBJECT
*DriverObject
);
283 _Must_inspect_result_
284 _IRQL_requires_max_(APC_LEVEL
)
288 MmLockPagableDataSection(
289 _In_ PVOID AddressWithinSection
);
291 _Must_inspect_result_
292 _IRQL_requires_max_(DISPATCH_LEVEL
)
293 _Out_writes_bytes_opt_ (NumberOfBytes
)
298 _In_ PHYSICAL_ADDRESS PhysicalAddress
,
299 _In_ SIZE_T NumberOfBytes
,
300 _In_ MEMORY_CACHING_TYPE CacheType
);
302 _Must_inspect_result_
303 _When_(AccessMode
==KernelMode
, _IRQL_requires_max_(DISPATCH_LEVEL
))
304 _When_(AccessMode
==UserMode
, _Maybe_raises_SEH_exception_
_IRQL_requires_max_(APC_LEVEL
))
309 _Inout_ PMDL MemoryDescriptorList
,
310 _In_
__drv_strictType(KPROCESSOR_MODE
/enum _MODE
,__drv_typeConst
)
311 KPROCESSOR_MODE AccessMode
);
313 _Post_writable_byte_size_(MemoryDescriptorList
->ByteCount
)
314 _When_(AccessMode
==KernelMode
, _IRQL_requires_max_(DISPATCH_LEVEL
))
315 _When_(AccessMode
==UserMode
, _Maybe_raises_SEH_exception_
_IRQL_requires_max_(APC_LEVEL
) _Post_notnull_
)
316 _At_(MemoryDescriptorList
->MappedSystemVa
, _Post_writable_byte_size_(MemoryDescriptorList
->ByteCount
))
317 _Must_inspect_result_
318 _Success_(return != NULL
)
322 MmMapLockedPagesSpecifyCache(
323 _Inout_ PMDL MemoryDescriptorList
,
324 _In_
__drv_strictType(KPROCESSOR_MODE
/enum _MODE
,__drv_typeConst
)
325 KPROCESSOR_MODE AccessMode
,
326 _In_
__drv_strictTypeMatch(__drv_typeCond
) MEMORY_CACHING_TYPE CacheType
,
327 _In_opt_ PVOID BaseAddress
,
328 _In_ ULONG BugCheckOnFailure
,
329 _In_ MM_PAGE_PRIORITY Priority
);
331 _IRQL_requires_max_(APC_LEVEL
)
336 _In_ PVOID AddressWithinSection
);
338 _IRQL_requires_max_(DISPATCH_LEVEL
)
339 _At_(MemoryDescriptorList
->StartVa
+ MemoryDescriptorList
->ByteOffset
,
340 _Field_size_bytes_opt_(MemoryDescriptorList
->ByteCount
))
345 _Inout_ PMDL MemoryDescriptorList
,
346 _In_ KPROCESSOR_MODE AccessMode
,
347 _In_ LOCK_OPERATION Operation
);
352 MmQuerySystemSize(VOID
);
354 _IRQL_requires_max_(APC_LEVEL
)
359 _In_ PVOID AddressWithinSection
);
365 _In_reads_bytes_opt_ (Length
) PVOID Base
,
368 _IRQL_requires_max_(DISPATCH_LEVEL
)
372 MmUnlockPagableImageSection(
373 _In_ PVOID ImageSectionHandle
);
375 _IRQL_requires_max_(DISPATCH_LEVEL
)
380 _Inout_ PMDL MemoryDescriptorList
);
382 _IRQL_requires_max_(DISPATCH_LEVEL
)
387 _In_reads_bytes_ (NumberOfBytes
) PVOID BaseAddress
,
388 _In_ SIZE_T NumberOfBytes
);
390 _IRQL_requires_max_ (APC_LEVEL
)
394 MmProbeAndLockProcessPages(
395 _Inout_ PMDL MemoryDescriptorList
,
396 _In_ PEPROCESS Process
,
397 _In_ KPROCESSOR_MODE AccessMode
,
398 _In_ LOCK_OPERATION Operation
);
400 _IRQL_requires_max_(DISPATCH_LEVEL
)
405 _In_ PVOID BaseAddress
,
406 _Inout_ PMDL MemoryDescriptorList
);
408 _Must_inspect_result_
409 _IRQL_requires_max_(DISPATCH_LEVEL
)
410 _When_ (return != NULL
, _Post_writable_byte_size_ (NumberOfBytes
))
414 MmAllocateContiguousMemorySpecifyCacheNode(
415 _In_ SIZE_T NumberOfBytes
,
416 _In_ PHYSICAL_ADDRESS LowestAcceptableAddress
,
417 _In_ PHYSICAL_ADDRESS HighestAcceptableAddress
,
418 _In_opt_ PHYSICAL_ADDRESS BoundaryAddressMultiple
,
419 _In_ MEMORY_CACHING_TYPE CacheType
,
420 _In_ NODE_REQUIREMENT PreferredNode
);
424 _IRQL_requires_max_ (PASSIVE_LEVEL
)
426 PPHYSICAL_MEMORY_RANGE
428 MmGetPhysicalMemoryRanges(VOID
);
433 MmGetPhysicalAddress(
434 _In_ PVOID BaseAddress
);
439 MmIsNonPagedSystemAddressValid(
440 _In_ PVOID VirtualAddress
);
442 _Must_inspect_result_
443 _IRQL_requires_max_(APC_LEVEL
)
444 _Out_writes_bytes_opt_(NumberOfBytes
)
448 MmAllocateNonCachedMemory(
449 _In_ SIZE_T NumberOfBytes
);
451 _IRQL_requires_max_(APC_LEVEL
)
455 MmFreeNonCachedMemory(
456 _In_reads_bytes_(NumberOfBytes
) PVOID BaseAddress
,
457 _In_ SIZE_T NumberOfBytes
);
462 MmGetVirtualForPhysical(
463 _In_ PHYSICAL_ADDRESS PhysicalAddress
);
465 _Must_inspect_result_
466 _IRQL_requires_max_(APC_LEVEL
)
470 MmMapUserAddressesToPage(
471 _In_reads_bytes_(NumberOfBytes
) PVOID BaseAddress
,
472 _In_ SIZE_T NumberOfBytes
,
473 _In_ PVOID PageAddress
);
475 _Must_inspect_result_
476 _IRQL_requires_max_(APC_LEVEL
)
477 _Out_writes_bytes_opt_(NumberOfBytes
)
482 _In_ PHYSICAL_ADDRESS PhysicalAddress
,
483 _In_ SIZE_T NumberOfBytes
,
484 _In_ MEMORY_CACHING_TYPE CacheType
);
486 _Must_inspect_result_
487 _IRQL_requires_max_(APC_LEVEL
)
491 MmMapViewInSessionSpace(
493 _Outptr_result_bytebuffer_(*ViewSize
) PVOID
*MappedBase
,
494 _Inout_ PSIZE_T ViewSize
);
496 _Must_inspect_result_
497 _IRQL_requires_max_(APC_LEVEL
)
501 MmMapViewInSystemSpace(
503 _Outptr_result_bytebuffer_(*ViewSize
) PVOID
*MappedBase
,
504 _Inout_ PSIZE_T ViewSize
);
506 _IRQL_requires_max_(DISPATCH_LEVEL
)
511 _In_ PVOID VirtualAddress
);
516 MmIsThisAnNtAsSystem(VOID
);
518 _IRQL_requires_max_(APC_LEVEL
)
522 MmLockPagableSectionByHandle(
523 _In_ PVOID ImageSectionHandle
);
525 _IRQL_requires_max_(APC_LEVEL
)
529 MmUnmapViewInSessionSpace(
530 _In_ PVOID MappedBase
);
532 _IRQL_requires_max_(APC_LEVEL
)
536 MmUnmapViewInSystemSpace(
537 _In_ PVOID MappedBase
);
539 _IRQL_requires_max_(APC_LEVEL
)
543 MmUnsecureVirtualMemory(
544 _In_ HANDLE SecureHandle
);
546 _IRQL_requires_max_ (PASSIVE_LEVEL
)
550 MmRemovePhysicalMemory(
551 _In_ PPHYSICAL_ADDRESS StartAddress
,
552 _Inout_ PLARGE_INTEGER NumberOfBytes
);
554 _Must_inspect_result_
555 _IRQL_requires_max_(APC_LEVEL
)
559 MmSecureVirtualMemory(
560 __in_data_source(USER_MODE
) _In_reads_bytes_ (Size
) PVOID Address
,
561 _In_
__in_data_source(USER_MODE
) SIZE_T Size
,
562 _In_ ULONG ProbeMode
);
564 _IRQL_requires_max_(APC_LEVEL
)
569 _In_reads_bytes_(NumberOfBytes
) PVOID BaseAddress
,
570 _In_ SIZE_T NumberOfBytes
);
572 _IRQL_requires_max_ (PASSIVE_LEVEL
)
577 _In_ PPHYSICAL_ADDRESS StartAddress
,
578 _Inout_ PLARGE_INTEGER NumberOfBytes
);
585 MmIsRecursiveIoFault(VOID
);
587 _IRQL_requires_max_ (APC_LEVEL
)
591 MmForceSectionClosed(
592 _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
,
593 _In_ BOOLEAN DelayClose
);
595 _IRQL_requires_max_ (APC_LEVEL
)
600 _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
,
601 _In_ MMFLUSH_TYPE FlushType
);
603 _IRQL_requires_max_ (APC_LEVEL
)
607 MmCanFileBeTruncated(
608 _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
,
609 _In_opt_ PLARGE_INTEGER NewFileSize
);
611 _IRQL_requires_max_ (APC_LEVEL
)
615 MmSetAddressRangeModified(
616 _In_reads_bytes_ (Length
) PVOID Address
,
620 #endif /* (NTDDI_VERSION >= NTDDI_WIN2K) */
622 $
if (_WDMDDK_
|| _NTIFS_
)
623 #if (NTDDI_VERSION >= NTDDI_WINXP)
624 $
endif (_WDMDDK_
|| _NTIFS_
)
627 _IRQL_requires_max_(DISPATCH_LEVEL
)
633 _In_ ULONG NumberOfBytes
);
635 _Must_inspect_result_
636 _IRQL_requires_max_(APC_LEVEL
)
637 _When_ (return != NULL
, _Out_writes_bytes_opt_ (NumberOfBytes
))
641 MmAllocateMappingAddress(
642 _In_ SIZE_T NumberOfBytes
,
645 _IRQL_requires_max_(APC_LEVEL
)
649 MmFreeMappingAddress(
650 _In_ PVOID BaseAddress
,
653 _IRQL_requires_max_ (APC_LEVEL
)
658 _Out_ PULONG VerifierFlags
);
660 _Post_writable_byte_size_(MemoryDescriptorList
->ByteCount
)
661 _IRQL_requires_max_(DISPATCH_LEVEL
)
662 _At_(MemoryDescriptorList
->MappedSystemVa
+ MemoryDescriptorList
->ByteOffset
,
663 _Post_writable_byte_size_(MemoryDescriptorList
->ByteCount
))
664 _Must_inspect_result_
665 _Success_(return != NULL
)
669 MmMapLockedPagesWithReservedMapping(
670 _In_ PVOID MappingAddress
,
672 _Inout_ PMDL MemoryDescriptorList
,
673 _In_
__drv_strictTypeMatch(__drv_typeCond
)
674 MEMORY_CACHING_TYPE CacheType
);
676 _Must_inspect_result_
677 _IRQL_requires_max_(DISPATCH_LEVEL
)
681 MmProtectMdlSystemAddress(
682 _In_ PMDL MemoryDescriptorList
,
683 _In_ ULONG NewProtect
);
685 _IRQL_requires_max_(DISPATCH_LEVEL
)
689 MmUnmapReservedMapping(
690 _In_ PVOID BaseAddress
,
692 _Inout_ PMDL MemoryDescriptorList
);
694 _IRQL_requires_max_ (APC_LEVEL
)
699 _In_reads_bytes_ (ThunkBufferSize
) PVOID ThunkBuffer
,
700 _In_ ULONG ThunkBufferSize
);
704 _IRQL_requires_max_ (PASSIVE_LEVEL
)
709 _In_ ULONG NumberOfLists
,
710 _In_reads_ (NumberOfLists
) PREAD_LIST
*ReadLists
);
713 $
if (_WDMDDK_
|| _NTIFS_
)
714 #endif /* (NTDDI_VERSION >= NTDDI_WINXP) */
715 $
endif (_WDMDDK_
|| _NTIFS_
)
716 $
if (_WDMDDK_
|| _NTDDK_
)
717 #if (NTDDI_VERSION >= NTDDI_WS03)
718 $
endif (_WDMDDK_
|| _NTDDK_
)
720 _IRQL_requires_max_ (DISPATCH_LEVEL
)
725 _In_ PHYSICAL_ADDRESS StartAddress
,
726 _In_ SIZE_T NumberOfBytes
);
730 _Must_inspect_result_
731 _IRQL_requires_max_(PASSIVE_LEVEL
)
735 MmCreateMirror(VOID
);
737 $
if (_WDMDDK_
|| _NTDDK_
)
738 #endif /* (NTDDI_VERSION >= NTDDI_WS03) */
739 $
endif (_WDMDDK_
|| _NTDDK_
)
741 #if (NTDDI_VERSION >= NTDDI_WS03SP1)
742 _Must_inspect_result_
743 _IRQL_requires_max_ (DISPATCH_LEVEL
)
747 MmAllocatePagesForMdlEx(
748 _In_ PHYSICAL_ADDRESS LowAddress
,
749 _In_ PHYSICAL_ADDRESS HighAddress
,
750 _In_ PHYSICAL_ADDRESS SkipBytes
,
751 _In_ SIZE_T TotalBytes
,
752 _In_ MEMORY_CACHING_TYPE CacheType
,
757 #if (NTDDI_VERSION >= NTDDI_VISTA)
759 _IRQL_requires_max_ (APC_LEVEL
)
763 MmIsDriverVerifyingByAddress(
764 _In_ PVOID AddressWithinSection
);
767 _Must_inspect_result_
768 _IRQL_requires_max_(APC_LEVEL
)
771 MmRotatePhysicalView(
772 _In_ PVOID VirtualAddress
,
773 _Inout_ PSIZE_T NumberOfBytes
,
774 _In_opt_ PMDLX NewMdl
,
775 _In_ MM_ROTATE_DIRECTION Direction
,
776 _In_ PMM_ROTATE_COPY_CALLBACK_FUNCTION CopyFunction
,
777 _In_opt_ PVOID Context
);
781 _IRQL_requires_max_ (APC_LEVEL
)
785 MmDoesFileHaveUserWritableReferences(
786 _In_ PSECTION_OBJECT_POINTERS SectionPointer
);
788 _Must_inspect_result_
789 _At_(*BaseAddress
, __drv_allocatesMem(Mem
))
794 NtAllocateVirtualMemory(
795 _In_ HANDLE ProcessHandle
,
796 _Inout_
_Outptr_result_buffer_(*RegionSize
) PVOID
*BaseAddress
,
797 _In_ ULONG_PTR ZeroBits
,
798 _Inout_ PSIZE_T RegionSize
,
799 _In_ ULONG AllocationType
,
803 _IRQL_requires_max_(PASSIVE_LEVEL
)
808 _In_ HANDLE ProcessHandle
,
809 _Inout_
__drv_freesMem(Mem
) PVOID
*BaseAddress
,
810 _Inout_ PSIZE_T RegionSize
,
811 _In_ ULONG FreeType
);
814 #endif /* (NTDDI_VERSION >= NTDDI_VISTA) */