134 if (!vad)
return NULL;
290 while (current && current->
LeftChild != NULL) {
300 IN uintptr_t StartVa,
327 if (StartVa <= Node->EndVa && EndVa >= Node->
StartVa) {
332 if (EndVa < Node->StartVa) {
337 else if (StartVa > Node->
EndVa) {
354 IN uintptr_t VirtualAddress
378 PMMVAD current = Process->VadRoot;
382 if (VirtualAddress < current->StartVa) {
387 else if (VirtualAddress > current->
EndVa) {
429 if (!Node)
return NewVad;
432 if (NewVad->StartVa < Node->StartVa) {
433 PMMVAD newLeft = MiInsertVadNode(Node->LeftChild, NewVad);
434 Node->LeftChild = newLeft;
435 if (newLeft) newLeft->
Parent = Node;
439 PMMVAD newRight = MiInsertVadNode(Node->RightChild, NewVad);
440 Node->RightChild = newRight;
441 if (newRight) newRight->
Parent = Node;
453 if (NewVad->StartVa < Node->LeftChild->StartVa) {
454 return MiRotateRight(Node);
458 Node->LeftChild = MiRotateLeft(Node->LeftChild);
459 return MiRotateRight(Node);
466 if (NewVad->StartVa > Node->RightChild->StartVa) {
467 return MiRotateLeft(Node);
471 Node->RightChild = MiRotateRight(Node->RightChild);
472 return MiRotateLeft(Node);
511 if (VadToDelete->StartVa < Root->StartVa) {
512 Root->LeftChild = MiDeleteVadNode(Root->LeftChild, VadToDelete);
514 else if (VadToDelete->StartVa > Root->StartVa) {
515 Root->RightChild = MiDeleteVadNode(Root->RightChild, VadToDelete);
519 if (Root->LeftChild == NULL || Root->RightChild == NULL) {
520 PMMVAD temp = Root->LeftChild ? Root->LeftChild : Root->RightChild;
537 PMMVAD successor = MiFindMinimumVad(Root->RightChild);
540 PMMVAD oldLeft = Root->LeftChild;
541 PMMVAD oldParent = Root->Parent;
547 Root->LeftChild = oldLeft;
555 Root->
RightChild = MiDeleteVadNode(Root->RightChild, successor);
569 return MiRotateRight(Root);
573 Root->LeftChild = MiRotateLeft(Root->LeftChild);
574 return MiRotateRight(Root);
582 return MiRotateLeft(Root);
586 Root->RightChild = MiRotateRight(Root->RightChild);
587 return MiRotateLeft(Root);
594#define MAX_VAD_DEPTH 64
600 IN size_t NumberOfBytes,
601 IN uintptr_t SearchStart,
602 IN uintptr_t SearchEnd
624 if (SearchStart >= SearchEnd)
return 0;
625 if (NumberOfBytes == 0)
return 0;
626 if (SearchStart == 0)
return 0;
634 PMMVAD current = Process->VadRoot;
638 uintptr_t lastEndVa = SearchStart - 1;
642 while (current != NULL || stackTop != -1) {
644 while (current != NULL) {
650 vadStack[++stackTop] = current;
655 current = vadStack[stackTop--];
658 if (current->
EndVa < SearchStart) {
660 if (current->
EndVa > lastEndVa) lastEndVa = current->
EndVa;
666 if (current->
StartVa >= SearchEnd) {
670 if (gapStart <= (uintptr_t)-1 - (size_needed - 1)) {
671 if (gapStart + size_needed <= SearchEnd) {
686 if (gapStart < current->StartVa) {
688 if (gapStart <= (uintptr_t)-1 - (size_needed - 1)) {
689 uintptr_t gapEndExclusive = gapStart + size_needed;
691 if (gapEndExclusive <= current->StartVa && gapEndExclusive <= SearchEnd) {
699 if (current->
EndVa > lastEndVa) lastEndVa = current->
EndVa;
709 if (finalGapStart <= (uintptr_t)-1 - (size_needed - 1)) {
710 if (finalGapStart + size_needed <= SearchEnd) {
712 return finalGapStart;
727 IN size_t NumberOfBytes,
728 IN uintptr_t SearchStart,
729 IN uintptr_t SearchEnd
733 if (Process && NumberOfBytes) {
734 return MiFindGap(Process, NumberOfBytes, SearchStart, SearchEnd);
743 IN size_t NumberOfBytes,
784 StartVa = (uintptr_t)*BaseAddress;
795 bool checkForOverlap =
true;
805 *BaseAddress = (
void*)StartVa;
814 checkForOverlap =
false;
829 if (checkForOverlap && MiCheckVadOverlap(Process->VadRoot, StartVa, EndVa)) {
835 PMMVAD newVad = MiAllocateVad();
842 newVad->
EndVa = EndVa;
843 newVad->
Flags = VadFlags;
849 Process->
VadRoot = MiInsertVadNode(Process->VadRoot, newVad);
867 return MiCheckVadOverlap(Process->
VadRoot, StartVa, EndVa);
895 uintptr_t va = (uintptr_t)BaseAddress;
908 if (VadToFree == NULL || VadToFree->
StartVa != va) {
914 for (uintptr_t virtualaddr = VadToFree->
StartVa; virtualaddr <= VadToFree->EndVa; virtualaddr +=
VirtualPageSize) {
926 Process->VadRoot = MiDeleteVadNode(Process->VadRoot, VadToFree);
928 MiFreeVad(VadToFree);
PMMPTE MiGetPtePointer(IN uintptr_t va)
void MiUnmapPte(IN PMMPTE pte)
FORCEINLINE PRIVILEGE_MODE MeGetPreviousMode(void)
#define PAGES_TO_BYTES(Pages)
FORCEINLINE void * kmemcpy(void *dest, const void *src, size_t len)
enum _PRIVILEGE_MODE PRIVILEGE_MODE
enum _VAD_FLAGS VAD_FLAGS
#define BYTES_TO_PAGES(Bytes)
#define ALIGN_UP(x, align)
#define MT_GENERAL_FAILURE
#define MT_FAILURE(Status)
#define MT_CONFLICTING_ADDRESSES
NOINLINE 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)
MTSTATUS ProbeForRead(IN const void *Address, IN size_t Length, IN uint32_t Alignment)
FORCEINLINE MTSTATUS GetExceptionCode(void)
void MsAcquirePushLockExclusive(IN PUSH_LOCK *Lock)
void MsAcquirePushLockShared(IN PUSH_LOCK *Lock)
void MsReleasePushLockExclusive(IN PUSH_LOCK *Lock)
void MsReleasePushLockShared(IN PUSH_LOCK *Lock)
bool MsAcquireRundownProtection(IN PRUNDOWN_REF rundown)
void MsReleaseRundownProtection(IN PRUNDOWN_REF rundown)
struct _MMPTE::@172372265215056352375070220246156106027174106113::@277354034164206104264133322054061025100052052376 Soft
struct _EPROCESS * OwningProcess
struct _MMVAD * LeftChild
struct _MMVAD * RightChild
MTSTATUS MmIsAddressRangeFree(PEPROCESS Process, uintptr_t StartVa, uintptr_t EndVa)
FORCEINLINE int MiGetBalanceFactor(IN PMMVAD Node)
FORCEINLINE int MiGetNodeHeight(IN PMMVAD Node)
MTSTATUS MmFreeVirtualMemory(IN PEPROCESS Process, IN void *BaseAddress)
PMMVAD MiFindVad(IN PEPROCESS Process, 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)