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))
734 }
while ((Va & (
PDE_MAPPED_VA - 1)) && (Va <= EndingAddress));
739 if (Va > EndingAddress)
return;
757 *HaveBadAddress =
FALSE;
779 *HaveBadAddress =
TRUE;
802 SIZE_T TotalSize, CurrentSize, RemainingSize;
818 CurrentSize = TotalSize;
824 while (RemainingSize > 0)
829 if (RemainingSize < CurrentSize) CurrentSize = RemainingSize;
856 FailedInProbe =
TRUE;
866 FailedInProbe =
FALSE;
920 FailedInProbe =
TRUE;
930 FailedInProbe =
FALSE;
936 RtlCopyMemory(CurrentTargetAddress, MdlAddress, CurrentSize);
996 RemainingSize -= CurrentSize;
997 CurrentAddress = (
PVOID)((
ULONG_PTR)CurrentAddress + CurrentSize);
998 CurrentTargetAddress = (
PVOID)((
ULONG_PTR)CurrentTargetAddress + CurrentSize);
1002 if (MdlAddress !=
NULL)
1026 SIZE_T TotalSize, CurrentSize, RemainingSize;
1036 DPRINT(
"Copying %Iu bytes from process %p (address %p) to process %p (Address %p)\n",
1044 CurrentSize = TotalSize;
1055 PoolAddress = (
PVOID)StackBuffer;
1064 HavePoolAddress =
TRUE;
1070 while (RemainingSize > 0)
1075 if (RemainingSize < CurrentSize) CurrentSize = RemainingSize;
1099 FailedInProbe =
TRUE;
1109 FailedInProbe =
FALSE;
1175 FailedInProbe =
TRUE;
1185 FailedInProbe =
FALSE;
1191 RtlCopyMemory(CurrentTargetAddress, PoolAddress, CurrentSize);
1245 RemainingSize -= CurrentSize;
1246 CurrentAddress = (
PVOID)((
ULONG_PTR)CurrentAddress + CurrentSize);
1255 if (HavePoolAddress)
1372 (
TempPte.u.Soft.Prototype == 1))
1475 PMMPTE PointerPte, ProtoPte;
1477#if (_MI_PAGING_LEVELS >= 3)
1480#if (_MI_PAGING_LEVELS >= 4)
1495#if (_MI_PAGING_LEVELS >= 3)
1498#if (_MI_PAGING_LEVELS >= 4)
1507#if (_MI_PAGING_LEVELS >= 4)
1509 if (PointerPxe->
u.
Long == 0)
1523#if (_MI_PAGING_LEVELS >= 3)
1525 if (PointerPpe->
u.
Long == 0)
1541 if (PointerPde->
u.
Long == 0)
1576 ((
TempPte.u.Soft.Prototype == 0) ||
1598 (
TempPte.u.Soft.Prototype == 1) &&
1599 (Vad->u.VadFlags.PrivateMemory == 0) &&
1617 if ((Vad->u.VadFlags.PrivateMemory == 0) && (Vad->ControlArea))
1630 TempProtoPte = *ProtoPte;
1631 if (TempProtoPte.
u.
Long)
1642 else if (Vad->u.VadFlags.MemCommit)
1740 (
PVOID*)&TargetProcess,
1764 DPRINT1(
"Process is dying\n");
1787 if (BaseVpn < Vad->StartingVpn)
1861 MemoryInfo.
Type = 0;
1911 DPRINT1(
"MmQuerySectionView failed. MemoryArea=%p (%p-%p), BaseAddress=%p\n",
1989 DPRINT(
"Base: %p AllocBase: %p AllocProtect: %lx Protect: %lx "
1990 "State: %lx Type: %lx Size: %lx\n",
2005 PMMPTE PointerPte, LastPte;
2008#if _MI_PAGING_LEVELS >= 3
2011#if _MI_PAGING_LEVELS == 4
2027 while (PointerPte <= LastPte)
2029#if _MI_PAGING_LEVELS == 4
2039 if (PointerPxe->
u.
Long != 0)
2048 if (!Vad->u.VadFlags.MemCommit)
return FALSE;
2057#if _MI_PAGING_LEVELS >= 3
2066 if (PointerPpe->
u.
Long != 0)
2075 if (!Vad->u.VadFlags.MemCommit)
return FALSE;
2079#if _MI_PAGING_LEVELS == 4
2091 if (PointerPde->
u.
Long != 0)
2103 if (!Vad->u.VadFlags.MemCommit)
return FALSE;
2108#if _MI_PAGING_LEVELS >= 3
2110#if _MI_PAGING_LEVELS == 4
2121 if (PointerPte->
u.
Long == 0)
2124 if (!Vad->u.VadFlags.MemCommit)
return FALSE;
2142#if _MI_PAGING_LEVELS >= 3
2144#if _MI_PAGING_LEVELS == 4
2164 ULONG OldAccessProtection_;
2179 if (OldAccessProtection ==
NULL) OldAccessProtection = &OldAccessProtection_;
2185 *NumberOfBytesToProtect,
2186 NewAccessProtection,
2187 OldAccessProtection);
2205 ULONG_PTR StartingAddress, EndingAddress;
2206 PMMPTE PointerPte, LastPte;
2210 ULONG ProtectionMask, OldProtect;
2224 DPRINT1(
"Invalid protection mask\n");
2235 NumberOfBytesToProtect,
2236 NewAccessProtection,
2237 OldAccessProtection);
2245 DPRINT1(
"Process is dying\n");
2257 DPRINT(
"Could not find a VAD for this allocation\n");
2275 DPRINT1(
"Illegal VAD for attempting to set protection\n");
2283 DPRINT1(
"Trying to change protection of a NoChange VAD\n");
2294 DPRINT1(
"Illegal VAD for attempting to set protection\n");
2302 DPRINT1(
"Illegal VAD for attempting to set protection\n");
2311 DPRINT1(
"Invalid protection flags for section\n");
2320 DPRINT1(
"Fixme: Not checking for valid protection\n");
2324 DPRINT1(
"Section protection not yet supported\n");
2333 DPRINT1(
"Invalid protection flags for private memory\n");
2349 DPRINT1(
"The entire range is not committed\n");
2364 if (PointerPte->
u.
Long != 0)
2377 while (PointerPte <= LastPte)
2387 PteContents = *PointerPte;
2388 if (PteContents.
u.
Long == 0)
2462 *NumberOfBytesToProtect = EndingAddress - StartingAddress + 1;
2464 *OldAccessProtection = OldProtect;
2480#if _MI_PAGING_LEVELS >= 3
2482#if _MI_PAGING_LEVELS == 4
2504 (PointerPde->u.Hard.Valid))
2523#if _MI_PAGING_LEVELS == 4
2534#if _MI_PAGING_LEVELS >= 3
2556 ASSERT(PointerPde->u.Hard.Valid == 1);
2564 !PointerPde->u.Hard.Valid);
2628 ULONG CommitReduction = 0;
2629 PMMPTE ValidPteList[256];
2649 while (PointerPte <= EndingPte)
2679 PteContents = *PointerPte;
2680 if (PteContents.
u.
Long)
2713 if (PteCount == 256)
2718 ValidPteList[PteCount++] = PointerPte;
2750 if (PointerPte > CommitPte) CommitReduction++;
2767 return CommitReduction;
2864 if (NumberOfBytesToRead)
2884 NumberOfBytesToRead,
2898 if (NumberOfBytesRead)
2978 if (NumberOfBytesToWrite)
2998 NumberOfBytesToWrite,
3012 if (NumberOfBytesWritten)
3112 ULONG OldAccessProtection;
3116 SIZE_T NumberOfBytesToProtect = 0;
3163 NumberOfBytesToProtect = *UnsafeNumberOfBytesToProtect;
3180 NumberOfBytesToProtect = *UnsafeNumberOfBytesToProtect;
3218 if (CurrentProcess !=
Process)
3232 &NumberOfBytesToProtect,
3233 NewAccessProtection,
3234 &OldAccessProtection);
3254 *UnsafeOldAccessProtection = OldAccessProtection;
3256 *UnsafeNumberOfBytesToProtect = NumberOfBytesToProtect;
3346 while (CurrentVa < *EndAddress)
3361 *EndAddress = CurrentVa;
3382 PVOID CurrentVa, EndAddress;
3383 PMMPTE PointerPte, LastPte;
3385#if (_MI_PAGING_LEVELS >= 3)
3388#if (_MI_PAGING_LEVELS == 4)
3418 while (CurrentVa < EndAddress)
3420 (
void)(*(
volatile CHAR*)CurrentVa);
3438#if (_MI_PAGING_LEVELS >= 3)
3441#if (_MI_PAGING_LEVELS == 4)
3503#if (_MI_PAGING_LEVELS >= 3)
3506#if (_MI_PAGING_LEVELS == 4)
3509 }
while (PointerPte <= LastPte);
3534 PVOID CapturedBaseAddress;
3535 SIZE_T CapturedBytesToLock;
3575 CapturedBytesToLock = *NumberOfBytesToLock;
3639 if (CurrentProcess !=
Process)
3652 &CapturedBytesToLock,
3674 *NumberOfBytesToLock = CapturedBytesToLock;
3702 PMMPTE PointerPte, LastPte;
3704#if (_MI_PAGING_LEVELS >= 3)
3707#if (_MI_PAGING_LEVELS == 4)
3739#if (_MI_PAGING_LEVELS >= 3)
3742#if (_MI_PAGING_LEVELS == 4)
3785 DPRINT1(
"FIXME: Should remove the page from WS\n");
3795#if (_MI_PAGING_LEVELS >= 3)
3798#if (_MI_PAGING_LEVELS == 4)
3801 }
while (PointerPte <= LastPte);
3806 goto CleanupWithWsLock;
3814#if (_MI_PAGING_LEVELS >= 3)
3817#if (_MI_PAGING_LEVELS == 4)
3833#if (_MI_PAGING_LEVELS >= 3)
3836#if (_MI_PAGING_LEVELS == 4)
3839 }
while (PointerPte <= LastPte);
3870 PVOID CapturedBaseAddress;
3871 SIZE_T CapturedBytesToUnlock;
3911 CapturedBytesToUnlock = *NumberOfBytesToUnlock;
3975 if (CurrentProcess !=
Process)
3988 &CapturedBytesToUnlock,
4010 *NumberOfBytesToUnlock = CapturedBytesToUnlock;
4037 PVOID CapturedBaseAddress;
4038 SIZE_T CapturedBytesToFlush;
4063 CapturedBytesToFlush = *NumberOfBytesToFlush;
4080 CapturedBytesToFlush = *NumberOfBytesToFlush;
4114 &CapturedBaseAddress,
4115 &CapturedBytesToFlush,
4132 *NumberOfBytesToFlush = 0;
4201 CapturedEntryCount = *EntriesInUserAddressArray;
4223 CapturedEntryCount *
sizeof(
PVOID),
4240 CapturedEntryCount = *EntriesInUserAddressArray;
4241 ASSERT(CapturedEntryCount != 0);
4299 *EntriesInUserAddressArray = 0;
4413 DPRINT(
"Querying class %d about address: %p\n", MemoryInformationClass,
BaseAddress);
4425 MemoryInformationLength,
4442 switch(MemoryInformationClass)
4454 MemoryInformationLength,
4468 MemoryInformationLength,
4474 DPRINT1(
"Unhandled memory information class %d\n", MemoryInformationClass);
4499 ULONG_PTR PRegionSize, StartingAddress, EndingAddress;
4505 ULONG ProtectionMask, QuotaCharge = 0, QuotaFree = 0;
4508 PMMPTE PointerPte, LastPte;
4516 DPRINT1(
"Too many zero bits\n");
4524 DPRINT1(
"Invalid Allocation Type\n");
4531 DPRINT1(
"No memory allocation base type\n");
4538 DPRINT1(
"Invalid use of MEM_RESET\n");
4548 DPRINT1(
"Must supply MEM_COMMIT with MEM_LARGE_PAGES\n");
4555 DPRINT1(
"Using illegal flags with MEM_LARGE_PAGES\n");
4563 DPRINT1(
"MEM_WRITE_WATCH used without MEM_RESERVE\n");
4573 DPRINT1(
"MEM_PHYSICAL used without MEM_RESERVE\n");
4580 DPRINT1(
"Using illegal flags with MEM_PHYSICAL\n");
4587 DPRINT1(
"MEM_PHYSICAL used without PAGE_READWRITE\n");
4596 DPRINT1(
"Invalid protection mask\n");
4612 PBaseAddress = *UBaseAddress;
4613 PRegionSize = *URegionSize;
4625 DPRINT1(
"Virtual allocation base above User Space\n");
4632 DPRINT1(
"Region size would overflow into kernel-memory\n");
4639 DPRINT1(
"Region size is invalid (zero)\n");
4665 if (CurrentProcess !=
Process)
4672 DPRINT(
"NtAllocateVirtualMemory: Process 0x%p, Address 0x%p, Zerobits %lu , RegionSize 0x%x, Allocation type 0x%x, Protect 0x%x.\n",
4683 DPRINT1(
"Privilege not held for MEM_LARGE_PAGES\n");
4685 goto FailPathNoLock;
4693 DPRINT1(
"MEM_LARGE_PAGES not supported\n");
4695 goto FailPathNoLock;
4699 DPRINT1(
"MEM_PHYSICAL not supported\n");
4701 goto FailPathNoLock;
4705 DPRINT1(
"MEM_WRITE_WATCH not supported\n");
4707 goto FailPathNoLock;
4721 DPRINT1(
"Copy on write not allowed through this path\n");
4723 goto FailPathNoLock;
4736 StartingAddress = 0;
4750 goto FailPathNoLock;
4763 StartingAddress = (
ULONG_PTR)PBaseAddress;
4771 goto FailPathNoLock;
4782 DPRINT1(
"Failed to allocate a VAD!\n");
4784 goto FailPathNoLock;
4804 DPRINT1(
"Failed to insert the VAD!\n");
4806 goto FailPathNoLock;
4825 *URegionSize = PRegionSize;
4826 *UBaseAddress = (
PVOID)StartingAddress;
4835 DPRINT(
"Reserved %x bytes at %p.\n", PRegionSize, StartingAddress);
4847 PRegionSize = EndingAddress - StartingAddress + 1;
4856 DPRINT1(
"Process is dying\n");
4870 DPRINT1(
"Could not find a VAD for this allocation\n");
4878 DPRINT(
"MEM_RESET not supported\n");
4887 if ((FoundVad->u.VadFlags.VadType ==
VadAwe) ||
4891 DPRINT1(
"Illegal VAD for attempting a MEM_COMMIT\n");
4899 if (((StartingAddress >>
PAGE_SHIFT) < FoundVad->StartingVpn) ||
4900 ((EndingAddress >>
PAGE_SHIFT) > FoundVad->EndingVpn))
4902 DPRINT1(
"Address range does not fit into the VAD\n");
4914 DPRINT1(
"Illegal commit of non-ARM3 section!\n");
4922 if (FoundVad->u.VadFlags.PrivateMemory ==
FALSE)
4929 DPRINT1(
"Large page sections cannot be VirtualAlloc'd\n");
4940 DPRINT1(
"Cannot use caching flags with anything but rotate VADs\n");