15#define MODULE_INVOLVED_IN_ARM3
18#define MI_MAPPED_COPY_PAGES 14
19#define MI_POOL_COPY_BYTES 512
20#define MI_MAX_TRANSFER_SIZE 64 * 1024
47 PMMPTE PointerPte, LastPte;
50#if _MI_PAGING_LEVELS >= 3
53#if _MI_PAGING_LEVELS == 4
61 ASSERT(EndingAddress >= StartingAddress);
72 while (PointerPte <= LastPte)
74#if _MI_PAGING_LEVELS == 4
84 if (PointerPxe->
u.
Long == 0)
97#if _MI_PAGING_LEVELS >= 3
106 if (PointerPpe->
u.
Long == 0)
110#if _MI_PAGING_LEVELS == 4
126 if (PointerPde->
u.
Long == 0)
130#if _MI_PAGING_LEVELS >= 3
132#if _MI_PAGING_LEVELS == 4
145 if (PointerPte->
u.
Long != 0)
154 if (Vad->u.VadFlags.MemCommit)
157 else if (!Vad->u.VadFlags.MemCommit)
168#if _MI_PAGING_LEVELS >= 3
170#if _MI_PAGING_LEVELS == 4
178 return CommittedPages;
294 if (PointerPte->u.Long)
297 if (PointerPte->u.Hard.Valid)
307 if (ValidPages) (*ValidPages)++;
332 ASSERT(PointerPte->u.Soft.Prototype == 0);
333 ASSERT(PointerPte->u.Soft.Transition == 0);
342 ASSERT(PointerPte->u.Soft.PageFileHigh == 0);
404 DPRINT(
"Pte %p is transitional!\n", PointerPte);
425 if (Pfn1->
u3.
e2.ReferenceCount == 0)
432 Pfn1->
u3.
e2.ReferenceCount++;
452#if (_MI_PAGING_LEVELS == 2)
464#if (_MI_PAGING_LEVELS == 2)
536#if (_MI_PAGING_LEVELS >= 3)
539#if (_MI_PAGING_LEVELS >= 4)
549 if ((Vad) && (Vad->u.VadFlags.Spare == 1))
return;
555 if (!(Vad) || (Vad->u.VadFlags.PrivateMemory) || !(Vad->FirstPrototypePte))
564 LastPrototypePte = Vad->FirstPrototypePte + 1;
571 while (Va <= EndingAddress)
573#if (_MI_PAGING_LEVELS >= 4)
579 if (!PointerPxe->
u.
Long)
593#if (_MI_PAGING_LEVELS >= 3)
599 if (!PointerPpe->
u.
Long)
615 if (!PointerPde->
u.
Long)
635 ASSERT(Va <= EndingAddress);
638 if ((AddressGap) && (LastPrototypePte))
673 if ((LastPrototypePte) && (
PrototypePte > LastPrototypePte))
694 (
TempPte.u.Soft.Prototype == 1))
736 }
while ((Va & (
PDE_MAPPED_VA - 1)) && (Va <= EndingAddress));
741 if (Va > EndingAddress)
return;
759 *HaveBadAddress =
FALSE;
781 *HaveBadAddress =
TRUE;
804 SIZE_T TotalSize, CurrentSize, RemainingSize;
820 CurrentSize = TotalSize;
826 while (RemainingSize > 0)
831 if (RemainingSize < CurrentSize) CurrentSize = RemainingSize;
858 FailedInProbe =
TRUE;
868 FailedInProbe =
FALSE;
922 FailedInProbe =
TRUE;
932 FailedInProbe =
FALSE;
938 RtlCopyMemory(CurrentTargetAddress, MdlAddress, CurrentSize);
998 RemainingSize -= CurrentSize;
999 CurrentAddress = (
PVOID)((
ULONG_PTR)CurrentAddress + CurrentSize);
1000 CurrentTargetAddress = (
PVOID)((
ULONG_PTR)CurrentTargetAddress + CurrentSize);
1004 if (MdlAddress !=
NULL)
1028 SIZE_T TotalSize, CurrentSize, RemainingSize;
1038 DPRINT(
"Copying %Iu bytes from process %p (address %p) to process %p (Address %p)\n",
1046 CurrentSize = TotalSize;
1057 PoolAddress = (
PVOID)StackBuffer;
1066 HavePoolAddress =
TRUE;
1072 while (RemainingSize > 0)
1077 if (RemainingSize < CurrentSize) CurrentSize = RemainingSize;
1101 FailedInProbe =
TRUE;
1111 FailedInProbe =
FALSE;
1177 FailedInProbe =
TRUE;
1187 FailedInProbe =
FALSE;
1193 RtlCopyMemory(CurrentTargetAddress, PoolAddress, CurrentSize);
1247 RemainingSize -= CurrentSize;
1248 CurrentAddress = (
PVOID)((
ULONG_PTR)CurrentAddress + CurrentSize);
1257 if (HavePoolAddress)
1374 (
TempPte.u.Soft.Prototype == 1))
1477 PMMPTE PointerPte, ProtoPte;
1479#if (_MI_PAGING_LEVELS >= 3)
1482#if (_MI_PAGING_LEVELS >= 4)
1497#if (_MI_PAGING_LEVELS >= 3)
1500#if (_MI_PAGING_LEVELS >= 4)
1509#if (_MI_PAGING_LEVELS >= 4)
1511 if (PointerPxe->
u.
Long == 0)
1525#if (_MI_PAGING_LEVELS >= 3)
1527 if (PointerPpe->
u.
Long == 0)
1543 if (PointerPde->
u.
Long == 0)
1578 ((
TempPte.u.Soft.Prototype == 0) ||
1600 (
TempPte.u.Soft.Prototype == 1) &&
1601 (Vad->u.VadFlags.PrivateMemory == 0) &&
1619 if ((Vad->u.VadFlags.PrivateMemory == 0) && (Vad->ControlArea))
1632 TempProtoPte = *ProtoPte;
1633 if (TempProtoPte.
u.
Long)
1644 else if (Vad->u.VadFlags.MemCommit)
1742 (
PVOID*)&TargetProcess,
1766 DPRINT1(
"Process is dying\n");
1789 if (BaseVpn < Vad->StartingVpn)
1863 MemoryInfo.
Type = 0;
1913 DPRINT1(
"MmQuerySectionView failed. MemoryArea=%p (%p-%p), BaseAddress=%p\n",
1991 DPRINT(
"Base: %p AllocBase: %p AllocProtect: %lx Protect: %lx "
1992 "State: %lx Type: %lx Size: %lx\n",
2007 PMMPTE PointerPte, LastPte;
2010#if _MI_PAGING_LEVELS >= 3
2013#if _MI_PAGING_LEVELS == 4
2029 while (PointerPte <= LastPte)
2031#if _MI_PAGING_LEVELS == 4
2041 if (PointerPxe->
u.
Long != 0)
2050 if (!Vad->u.VadFlags.MemCommit)
return FALSE;
2059#if _MI_PAGING_LEVELS >= 3
2068 if (PointerPpe->
u.
Long != 0)
2077 if (!Vad->u.VadFlags.MemCommit)
return FALSE;
2081#if _MI_PAGING_LEVELS == 4
2093 if (PointerPde->
u.
Long != 0)
2105 if (!Vad->u.VadFlags.MemCommit)
return FALSE;
2110#if _MI_PAGING_LEVELS >= 3
2112#if _MI_PAGING_LEVELS == 4
2123 if (PointerPte->
u.
Long == 0)
2126 if (!Vad->u.VadFlags.MemCommit)
return FALSE;
2144#if _MI_PAGING_LEVELS >= 3
2146#if _MI_PAGING_LEVELS == 4
2166 ULONG OldAccessProtection_;
2181 if (OldAccessProtection ==
NULL) OldAccessProtection = &OldAccessProtection_;
2187 *NumberOfBytesToProtect,
2188 NewAccessProtection,
2189 OldAccessProtection);
2207 ULONG_PTR StartingAddress, EndingAddress;
2208 PMMPTE PointerPte, LastPte;
2212 ULONG ProtectionMask, OldProtect;
2229 DPRINT1(
"Invalid protection mask\n");
2238 DPRINT1(
"Process is dying\n");
2251 NumberOfBytesToProtect,
2252 NewAccessProtection,
2253 OldAccessProtection);
2261 if (
Result != TableFoundNode)
2263 DPRINT(
"Could not find a VAD for this allocation\n");
2281 DPRINT1(
"Illegal VAD for attempting to set protection\n");
2289 DPRINT1(
"Trying to change protection of a NoChange VAD\n");
2300 DPRINT1(
"Illegal VAD for attempting to set protection\n");
2308 DPRINT1(
"Illegal VAD for attempting to set protection\n");
2317 DPRINT1(
"Invalid protection flags for section\n");
2326 DPRINT1(
"Fixme: Not checking for valid protection\n");
2330 DPRINT1(
"Section protection not yet supported\n");
2339 DPRINT1(
"Invalid protection flags for private memory\n");
2355 DPRINT1(
"The entire range is not committed\n");
2370 if (PointerPte->
u.
Long != 0)
2383 while (PointerPte <= LastPte)
2393 PteContents = *PointerPte;
2394 if (PteContents.
u.
Long == 0)
2468 *NumberOfBytesToProtect = EndingAddress - StartingAddress + 1;
2470 *OldAccessProtection = OldProtect;
2486#if _MI_PAGING_LEVELS >= 3
2488#if _MI_PAGING_LEVELS == 4
2510 (PointerPde->u.Hard.Valid))
2529#if _MI_PAGING_LEVELS == 4
2540#if _MI_PAGING_LEVELS >= 3
2562 ASSERT(PointerPde->u.Hard.Valid == 1);
2570 !PointerPde->u.Hard.Valid);
2634 ULONG CommitReduction = 0;
2635 PMMPTE ValidPteList[256];
2655 while (PointerPte <= EndingPte)
2685 PteContents = *PointerPte;
2686 if (PteContents.
u.
Long)
2719 if (PteCount == 256)
2724 ValidPteList[PteCount++] = PointerPte;
2756 if (PointerPte > CommitPte) CommitReduction++;
2773 return CommitReduction;
2870 if (NumberOfBytesToRead)
2890 NumberOfBytesToRead,
2904 if (NumberOfBytesRead)
2984 if (NumberOfBytesToWrite)
3004 NumberOfBytesToWrite,
3018 if (NumberOfBytesWritten)
3118 ULONG OldAccessProtection;
3122 SIZE_T NumberOfBytesToProtect = 0;
3169 NumberOfBytesToProtect = *UnsafeNumberOfBytesToProtect;
3186 NumberOfBytesToProtect = *UnsafeNumberOfBytesToProtect;
3224 if (CurrentProcess !=
Process)
3238 &NumberOfBytesToProtect,
3239 NewAccessProtection,
3240 &OldAccessProtection);
3260 *UnsafeOldAccessProtection = OldAccessProtection;
3262 *UnsafeNumberOfBytesToProtect = NumberOfBytesToProtect;
3352 while (CurrentVa < *EndAddress)
3367 *EndAddress = CurrentVa;
3388 PVOID CurrentVa, EndAddress;
3389 PMMPTE PointerPte, LastPte;
3391#if (_MI_PAGING_LEVELS >= 3)
3394#if (_MI_PAGING_LEVELS == 4)
3424 while (CurrentVa < EndAddress)
3426 (
void)(*(
volatile CHAR*)CurrentVa);
3444#if (_MI_PAGING_LEVELS >= 3)
3447#if (_MI_PAGING_LEVELS == 4)
3509#if (_MI_PAGING_LEVELS >= 3)
3512#if (_MI_PAGING_LEVELS == 4)
3515 }
while (PointerPte <= LastPte);
3540 PVOID CapturedBaseAddress;
3541 SIZE_T CapturedBytesToLock;
3581 CapturedBytesToLock = *NumberOfBytesToLock;
3645 if (CurrentProcess !=
Process)
3658 &CapturedBytesToLock,
3680 *NumberOfBytesToLock = CapturedBytesToLock;
3708 PMMPTE PointerPte, LastPte;
3710#if (_MI_PAGING_LEVELS >= 3)
3713#if (_MI_PAGING_LEVELS == 4)
3745#if (_MI_PAGING_LEVELS >= 3)
3748#if (_MI_PAGING_LEVELS == 4)
3791 DPRINT1(
"FIXME: Should remove the page from WS\n");
3801#if (_MI_PAGING_LEVELS >= 3)
3804#if (_MI_PAGING_LEVELS == 4)
3807 }
while (PointerPte <= LastPte);
3812 goto CleanupWithWsLock;
3820#if (_MI_PAGING_LEVELS >= 3)
3823#if (_MI_PAGING_LEVELS == 4)
3839#if (_MI_PAGING_LEVELS >= 3)
3842#if (_MI_PAGING_LEVELS == 4)
3845 }
while (PointerPte <= LastPte);
3876 PVOID CapturedBaseAddress;
3877 SIZE_T CapturedBytesToUnlock;
3917 CapturedBytesToUnlock = *NumberOfBytesToUnlock;
3981 if (CurrentProcess !=
Process)
3994 &CapturedBytesToUnlock,
4016 *NumberOfBytesToUnlock = CapturedBytesToUnlock;
4043 PVOID CapturedBaseAddress;
4044 SIZE_T CapturedBytesToFlush;
4069 CapturedBytesToFlush = *NumberOfBytesToFlush;
4086 CapturedBytesToFlush = *NumberOfBytesToFlush;
4120 &CapturedBaseAddress,
4121 &CapturedBytesToFlush,
4138 *NumberOfBytesToFlush = 0;
4207 CapturedEntryCount = *EntriesInUserAddressArray;
4229 CapturedEntryCount *
sizeof(
PVOID),
4246 CapturedEntryCount = *EntriesInUserAddressArray;
4247 ASSERT(CapturedEntryCount != 0);
4305 *EntriesInUserAddressArray = 0;
4419 DPRINT(
"Querying class %d about address: %p\n", MemoryInformationClass,
BaseAddress);
4431 MemoryInformationLength,
4448 switch(MemoryInformationClass)
4460 MemoryInformationLength,
4474 MemoryInformationLength,
4480 DPRINT1(
"Unhandled memory information class %d\n", MemoryInformationClass);
4505 ULONG_PTR PRegionSize, StartingAddress, EndingAddress;
4511 ULONG ProtectionMask, QuotaCharge = 0, QuotaFree = 0;
4514 PMMPTE PointerPte, LastPte;
4522 DPRINT1(
"Too many zero bits\n");
4530 DPRINT1(
"Invalid Allocation Type\n");
4537 DPRINT1(
"No memory allocation base type\n");
4544 DPRINT1(
"Invalid use of MEM_RESET\n");
4554 DPRINT1(
"Must supply MEM_COMMIT with MEM_LARGE_PAGES\n");
4561 DPRINT1(
"Using illegal flags with MEM_LARGE_PAGES\n");
4569 DPRINT1(
"MEM_WRITE_WATCH used without MEM_RESERVE\n");
4579 DPRINT1(
"MEM_PHYSICAL used without MEM_RESERVE\n");
4586 DPRINT1(
"Using illegal flags with MEM_PHYSICAL\n");
4593 DPRINT1(
"MEM_PHYSICAL used without PAGE_READWRITE\n");
4602 DPRINT1(
"Invalid protection mask\n");
4618 PBaseAddress = *UBaseAddress;
4619 PRegionSize = *URegionSize;
4631 DPRINT1(
"Virtual allocation base above User Space\n");
4638 DPRINT1(
"Region size would overflow into kernel-memory\n");
4645 DPRINT1(
"Region size is invalid (zero)\n");
4671 if (CurrentProcess !=
Process)
4678 DPRINT(
"NtAllocateVirtualMemory: Process 0x%p, Address 0x%p, Zerobits %lu , RegionSize 0x%x, Allocation type 0x%x, Protect 0x%x.\n",
4689 DPRINT1(
"Privilege not held for MEM_LARGE_PAGES\n");
4691 goto FailPathNoLock;
4699 DPRINT1(
"MEM_LARGE_PAGES not supported\n");
4701 goto FailPathNoLock;
4705 DPRINT1(
"MEM_PHYSICAL not supported\n");
4707 goto FailPathNoLock;
4711 DPRINT1(
"MEM_WRITE_WATCH not supported\n");
4713 goto FailPathNoLock;
4727 DPRINT1(
"Copy on write not allowed through this path\n");
4729 goto FailPathNoLock;
4742 StartingAddress = 0;
4756 goto FailPathNoLock;
4769 StartingAddress = (
ULONG_PTR)PBaseAddress;
4777 goto FailPathNoLock;
4788 DPRINT1(
"Failed to allocate a VAD!\n");
4790 goto FailPathNoLock;
4810 DPRINT1(
"Failed to insert the VAD!\n");
4812 goto FailPathNoLock;
4831 *URegionSize = PRegionSize;
4832 *UBaseAddress = (
PVOID)StartingAddress;
4841 DPRINT(
"Reserved %x bytes at %p.\n", PRegionSize, StartingAddress);
4853 PRegionSize = EndingAddress - StartingAddress + 1;
4862 DPRINT1(
"Process is dying\n");
4874 if (
Result != TableFoundNode)
4876 DPRINT1(
"Could not find a VAD for this allocation\n");
4884 DPRINT(
"MEM_RESET not supported\n");
4893 if ((FoundVad->u.VadFlags.VadType ==
VadAwe) ||
4897 DPRINT1(
"Illegal VAD for attempting a MEM_COMMIT\n");
4905 if (((StartingAddress >>
PAGE_SHIFT) < FoundVad->StartingVpn) ||
4906 ((EndingAddress >>
PAGE_SHIFT) > FoundVad->EndingVpn))
4908 DPRINT1(
"Address range does not fit into the VAD\n");
4920 DPRINT1(
"Illegal commit of non-ARM3 section!\n");
4928 if (FoundVad->u.VadFlags.PrivateMemory ==
FALSE)
4935 DPRINT1(
"Large page sections cannot be VirtualAlloc'd\n");