133 if (!vad)
return NULL;
292 while (current && current->
LeftChild != NULL) {
302 IN uintptr_t StartVa,
329 if (StartVa <= Node->EndVa && EndVa >= Node->
StartVa) {
334 if (EndVa < Node->StartVa) {
339 else if (StartVa > Node->
EndVa) {
356 IN uintptr_t VirtualAddress
381 if (VirtualAddress < current->StartVa) {
386 else if (VirtualAddress > current->
EndVa) {
424 if (!Node)
return NewVad;
427 if (NewVad->StartVa < Node->StartVa) {
428 PMMVAD newLeft = MiInsertVadNode(Node->LeftChild, NewVad);
429 Node->LeftChild = newLeft;
430 if (newLeft) newLeft->
Parent = Node;
434 PMMVAD newRight = MiInsertVadNode(Node->RightChild, NewVad);
435 Node->RightChild = newRight;
436 if (newRight) newRight->
Parent = Node;
448 if (NewVad->StartVa < Node->LeftChild->StartVa) {
449 return MiRotateRight(Node);
453 Node->LeftChild = MiRotateLeft(Node->LeftChild);
454 return MiRotateRight(Node);
461 if (NewVad->StartVa > Node->RightChild->StartVa) {
462 return MiRotateLeft(Node);
466 Node->RightChild = MiRotateRight(Node->RightChild);
467 return MiRotateLeft(Node);
506 if (VadToDelete->StartVa < Root->StartVa) {
507 Root->LeftChild = MiDeleteVadNode(Root->LeftChild, VadToDelete);
509 else if (VadToDelete->StartVa > Root->StartVa) {
510 Root->RightChild = MiDeleteVadNode(Root->RightChild, VadToDelete);
514 if (Root->LeftChild == NULL || Root->RightChild == NULL) {
515 PMMVAD temp = Root->LeftChild ? Root->LeftChild : Root->RightChild;
532 PMMVAD successor = MiFindMinimumVad(Root->RightChild);
535 PMMVAD oldLeft = Root->LeftChild;
536 PMMVAD oldParent = Root->Parent;
542 Root->LeftChild = oldLeft;
550 Root->
RightChild = MiDeleteVadNode(Root->RightChild, successor);
564 return MiRotateRight(Root);
568 Root->LeftChild = MiRotateLeft(Root->LeftChild);
569 return MiRotateRight(Root);
577 return MiRotateLeft(Root);
581 Root->RightChild = MiRotateRight(Root->RightChild);
582 return MiRotateLeft(Root);
589#define MAX_VAD_DEPTH 64
597 IN size_t NumberOfBytes,
598 IN uintptr_t SearchStart,
599 IN uintptr_t SearchEnd
621 if (SearchStart >= SearchEnd)
return 0;
622 if (NumberOfBytes == 0)
return 0;
623 if (SearchStart == 0)
return 0;
629 uintptr_t lastEndVa = SearchStart - 1;
633 while (current != NULL ||
stackTop != -1) {
635 while (current != NULL) {
648 if (current->
EndVa < SearchStart) {
650 if (current->
EndVa > lastEndVa) lastEndVa = current->
EndVa;
656 if (current->
StartVa >= SearchEnd) {
660 if (gapStart <= (uintptr_t)-1 - (size_needed - 1)) {
661 if (gapStart + size_needed <= SearchEnd)
return gapStart;
672 if (gapStart < current->StartVa) {
674 if (gapStart <= (uintptr_t)-1 - (size_needed - 1)) {
675 uintptr_t gapEndExclusive = gapStart + size_needed;
677 if (gapEndExclusive <= current->StartVa && gapEndExclusive <= SearchEnd) {
684 if (current->
EndVa > lastEndVa) lastEndVa = current->
EndVa;
694 if (finalGapStart <= (uintptr_t)-1 - (size_needed - 1)) {
695 if (finalGapStart + size_needed <= SearchEnd) {
696 return finalGapStart;
710 IN size_t NumberOfBytes,
711 IN uintptr_t SearchStart,
712 IN uintptr_t SearchEnd
716 if (Process && NumberOfBytes) {
717 return MiFindGap(Process->VadRoot, NumberOfBytes, SearchStart, SearchEnd);
726 IN size_t NumberOfBytes,
751 uintptr_t StartVa = (uintptr_t)*BaseAddress;
755 bool checkForOverlap =
true;
759 bool KernelProcess = (Process->PID == 4) ?
true :
false;
770 checkForOverlap =
false;
786 if (checkForOverlap && MiCheckVadOverlap(Process->VadRoot, StartVa, EndVa)) {
792 PMMVAD newVad = MiAllocateVad();
799 newVad->
EndVa = EndVa;
800 newVad->
Flags = VadFlags;
806 Process->
VadRoot = MiInsertVadNode(Process->VadRoot, newVad);
841 uintptr_t va = (uintptr_t)BaseAddress;
855 if (VadToFree == NULL || VadToFree->
StartVa != va) {
861 for (uintptr_t virtualaddr = VadToFree->
StartVa; virtualaddr <= VadToFree->EndVa; virtualaddr +=
VirtualPageSize) {
873 Process->VadRoot = MiDeleteVadNode(Process->VadRoot, VadToFree);
875 MiFreeVad(VadToFree);
NORETURN void MeBugCheckEx(IN enum _BUGCHECK_CODES BugCheckCode, IN void *BugCheckParameter1, IN void *BugCheckParameter2, IN void *BugCheckParameter3, IN void *BugCheckParameter4)
PMMPTE MiGetPtePointer(IN uintptr_t va)
void MiUnmapPte(IN PMMPTE pte)
@ MANUALLY_INITIATED_CRASH
#define PAGES_TO_BYTES(Pages)
FORCEINLINE void * kmemcpy(void *dest, const void *src, size_t len)
FORCEINLINE void * kmemset(void *dest, int64_t val, uint64_t len)
enum _VAD_FLAGS VAD_FLAGS
#define BYTES_TO_PAGES(Bytes)
#define ALIGN_UP(x, align)
#define MT_GENERAL_FAILURE
#define MT_CONFLICTING_ADDRESSES
void MiReleasePhysicalPage(IN PAGE_INDEX PfnIndex)
void MmFreePool(IN void *buf)
void * MmAllocatePoolWithTag(IN enum _POOL_TYPE PoolType, IN size_t NumberOfBytes, IN uint32_t Tag)
bool MsAcquireRundownProtection(IN PRUNDOWN_REF rundown)
void MsReleaseRundownProtection(IN PRUNDOWN_REF rundown)
void MsAcquireSpinlock(IN PSPINLOCK lock, IN PIRQL OldIrql)
void MsReleaseSpinlock(IN PSPINLOCK lock, IN IRQL OldIrql)
struct _MMPTE::@172372265215056352375070220246156106027174106113::@277354034164206104264133322054061025100052052376 Soft
struct _EPROCESS * OwningProcess
struct _MMVAD * LeftChild
struct _MMVAD * RightChild
PMMVAD vadStack[MAX_VAD_DEPTH]
FORCEINLINE int MiGetBalanceFactor(IN PMMVAD Node)
FORCEINLINE int MiGetNodeHeight(IN PMMVAD Node)
MTSTATUS MmFreeVirtualMemory(IN PEPROCESS Process, IN void *BaseAddress)
PMMVAD MiFindVad(IN PMMVAD Root, IN uintptr_t VirtualAddress)
MTSTATUS MmAllocateVirtualMemory(IN PEPROCESS Process, _In_Opt _Out_Opt void **BaseAddress, IN size_t NumberOfBytes, IN VAD_FLAGS VadFlags)
uintptr_t MmFindFreeAddressSpace(IN PEPROCESS Process, IN size_t NumberOfBytes, IN uintptr_t SearchStart, IN uintptr_t SearchEnd)
FORCEINLINE void MiUpdateNodeHeight(IN PMMVAD Node)