3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/mm/virtual.c
6 * PURPOSE: Implementing operations on virtual memory.
8 * PROGRAMMERS: David Welch
11 /* INCLUDE *****************************************************************/
16 #include <internal/debug.h>
18 /* FUNCTIONS *****************************************************************/
21 NtFlushVirtualMemory(IN HANDLE ProcessHandle
,
23 IN ULONG NumberOfBytesToFlush
,
24 OUT PULONG NumberOfBytesFlushed OPTIONAL
)
26 * FUNCTION: Flushes virtual memory to file
28 * ProcessHandle = Points to the process that allocated the virtual
30 * BaseAddress = Points to the memory address
31 * NumberOfBytesToFlush = Limits the range to flush,
32 * NumberOfBytesFlushed = Actual number of bytes flushed
36 /* This should be implemented once we support network filesystems */
37 DPRINT("NtFlushVirtualMemory is UNIMPLEMENTED\n");
38 return(STATUS_SUCCESS
);
43 MiLockVirtualMemory(HANDLE ProcessHandle
,
45 ULONG NumberOfBytesToLock
,
46 PULONG NumberOfBytesLocked
,
47 PObReferenceObjectByHandle pObReferenceObjectByHandle
,
48 PMmCreateMdl pMmCreateMdl
,
49 PObDereferenceObject pObDereferenceObject
,
50 PMmProbeAndLockPages pMmProbeAndLockPages
,
51 PExFreePool pExFreePool
)
57 Status
= pObReferenceObjectByHandle(ProcessHandle
,
63 if (!NT_SUCCESS(Status
))
66 Mdl
= pMmCreateMdl(NULL
,
71 pObDereferenceObject(Process
);
72 return(STATUS_NO_MEMORY
);
75 pMmProbeAndLockPages(Mdl
,
81 pObDereferenceObject(Process
);
83 *NumberOfBytesLocked
= NumberOfBytesToLock
;
84 return(STATUS_SUCCESS
);
89 NtLockVirtualMemory(HANDLE ProcessHandle
,
91 ULONG NumberOfBytesToLock
,
92 PULONG NumberOfBytesLocked
)
94 DPRINT("NtLockVirtualMemory(ProcessHandle %x, BaseAddress %x, "
95 "NumberOfBytesToLock %d, NumberOfBytesLocked %x)\n",
101 return MiLockVirtualMemory(ProcessHandle
,
105 ObReferenceObjectByHandle
,
107 ObfDereferenceObject
,
114 MiQueryVirtualMemory (IN HANDLE ProcessHandle
,
116 IN CINT VirtualMemoryInformationClass
,
117 OUT PVOID VirtualMemoryInformation
,
119 OUT PULONG ResultLength
)
123 MEMORY_AREA
* MemoryArea
;
124 PMADDRESS_SPACE AddressSpace
;
126 if (Address
< MmSystemRangeStart
)
128 Status
= ObReferenceObjectByHandle(ProcessHandle
,
129 PROCESS_QUERY_INFORMATION
,
135 if (!NT_SUCCESS(Status
))
137 DPRINT("NtQueryVirtualMemory() = %x\n",Status
);
140 AddressSpace
= &Process
->AddressSpace
;
144 AddressSpace
= MmGetKernelAddressSpace();
146 MmLockAddressSpace(AddressSpace
);
147 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, Address
);
148 switch(VirtualMemoryInformationClass
)
150 case MemoryBasicInformation
:
152 PMEMORY_BASIC_INFORMATION Info
=
153 (PMEMORY_BASIC_INFORMATION
)VirtualMemoryInformation
;
154 if (Length
!= sizeof(MEMORY_BASIC_INFORMATION
))
156 MmUnlockAddressSpace(AddressSpace
);
157 ObDereferenceObject(Process
);
158 return(STATUS_INFO_LENGTH_MISMATCH
);
161 if (MemoryArea
== NULL
)
164 Info
->State
= MEM_FREE
;
165 Info
->Protect
= PAGE_NOACCESS
;
166 Info
->AllocationProtect
= 0;
167 Info
->BaseAddress
= (PVOID
)PAGE_ROUND_DOWN(Address
);
168 Info
->AllocationBase
= NULL
;
169 Info
->RegionSize
= MmFindGapAtAddress(AddressSpace
, Info
->BaseAddress
);
170 Status
= STATUS_SUCCESS
;
171 *ResultLength
= sizeof(MEMORY_BASIC_INFORMATION
);
175 switch(MemoryArea
->Type
)
177 case MEMORY_AREA_VIRTUAL_MEMORY
:
178 case MEMORY_AREA_PEB_OR_TEB
:
179 Status
= MmQueryAnonMem(MemoryArea
, Address
, Info
,
182 case MEMORY_AREA_SECTION_VIEW
:
183 Status
= MmQuerySectionView(MemoryArea
, Address
, Info
,
186 case MEMORY_AREA_NO_ACCESS
:
188 Info
->State
= MEM_FREE
;
189 Info
->Protect
= MemoryArea
->Attributes
;
190 Info
->AllocationProtect
= MemoryArea
->Attributes
;
191 Info
->BaseAddress
= MemoryArea
->StartingAddress
;
192 Info
->AllocationBase
= MemoryArea
->StartingAddress
;
193 Info
->RegionSize
= (ULONG_PTR
)MemoryArea
->EndingAddress
-
194 (ULONG_PTR
)MemoryArea
->StartingAddress
;
195 Status
= STATUS_SUCCESS
;
196 *ResultLength
= sizeof(MEMORY_BASIC_INFORMATION
);
198 case MEMORY_AREA_SHARED_DATA
:
200 Info
->State
= MEM_COMMIT
;
201 Info
->Protect
= MemoryArea
->Attributes
;
202 Info
->AllocationProtect
= MemoryArea
->Attributes
;
203 Info
->BaseAddress
= MemoryArea
->StartingAddress
;
204 Info
->AllocationBase
= MemoryArea
->StartingAddress
;
205 Info
->RegionSize
= (ULONG_PTR
)MemoryArea
->EndingAddress
-
206 (ULONG_PTR
)MemoryArea
->StartingAddress
;
207 Status
= STATUS_SUCCESS
;
208 *ResultLength
= sizeof(MEMORY_BASIC_INFORMATION
);
210 case MEMORY_AREA_SYSTEM
:
212 Info
->State
= MEM_COMMIT
;
213 Info
->Protect
= MemoryArea
->Attributes
;
214 Info
->AllocationProtect
= MemoryArea
->Attributes
;
215 Info
->BaseAddress
= MemoryArea
->StartingAddress
;
216 Info
->AllocationBase
= MemoryArea
->StartingAddress
;
217 Info
->RegionSize
= (ULONG_PTR
)MemoryArea
->EndingAddress
-
218 (ULONG_PTR
)MemoryArea
->StartingAddress
;
219 Status
= STATUS_SUCCESS
;
220 *ResultLength
= sizeof(MEMORY_BASIC_INFORMATION
);
222 case MEMORY_AREA_KERNEL_STACK
:
224 Info
->State
= MEM_COMMIT
;
225 Info
->Protect
= MemoryArea
->Attributes
;
226 Info
->AllocationProtect
= MemoryArea
->Attributes
;
227 Info
->BaseAddress
= MemoryArea
->StartingAddress
;
228 Info
->AllocationBase
= MemoryArea
->StartingAddress
;
229 Info
->RegionSize
= (ULONG_PTR
)MemoryArea
->EndingAddress
-
230 (ULONG_PTR
)MemoryArea
->StartingAddress
;
231 Status
= STATUS_SUCCESS
;
232 *ResultLength
= sizeof(MEMORY_BASIC_INFORMATION
);
234 case MEMORY_AREA_PAGED_POOL
:
236 Info
->State
= MEM_COMMIT
;
237 Info
->Protect
= MemoryArea
->Attributes
;
238 Info
->AllocationProtect
= MemoryArea
->Attributes
;
239 Info
->BaseAddress
= MemoryArea
->StartingAddress
;
240 Info
->AllocationBase
= MemoryArea
->StartingAddress
;
241 Info
->RegionSize
= (ULONG_PTR
)MemoryArea
->EndingAddress
-
242 (ULONG_PTR
)MemoryArea
->StartingAddress
;
243 Status
= STATUS_SUCCESS
;
244 *ResultLength
= sizeof(MEMORY_BASIC_INFORMATION
);
247 DPRINT1("unhandled memory area type: 0x%x\n", MemoryArea
->Type
);
248 Status
= STATUS_UNSUCCESSFUL
;
257 Status
= STATUS_INVALID_INFO_CLASS
;
263 MmUnlockAddressSpace(AddressSpace
);
264 if (Address
< MmSystemRangeStart
)
266 ObDereferenceObject(Process
);
274 * Called from VirtualQueryEx (lib\kernel32\mem\virtual.c)
278 NtQueryVirtualMemory (IN HANDLE ProcessHandle
,
280 IN CINT VirtualMemoryInformationClass
,
281 OUT PVOID VirtualMemoryInformation
,
283 OUT PULONG UnsafeResultLength
)
285 NTSTATUS Status
= STATUS_SUCCESS
;
286 ULONG ResultLength
= 0;
287 KPROCESSOR_MODE PreviousMode
;
290 MEMORY_BASIC_INFORMATION BasicInfo
;
294 DPRINT("NtQueryVirtualMemory(ProcessHandle %x, Address %x, "
295 "VirtualMemoryInformationClass %d, VirtualMemoryInformation %x, "
296 "Length %lu ResultLength %x)\n",ProcessHandle
,Address
,
297 VirtualMemoryInformationClass
,VirtualMemoryInformation
,
298 Length
,ResultLength
);
300 PreviousMode
= ExGetPreviousMode();
302 if (PreviousMode
!= KernelMode
&& UnsafeResultLength
!= NULL
)
306 ProbeForWriteUlong(UnsafeResultLength
);
310 Status
= _SEH_GetExceptionCode();
314 if (!NT_SUCCESS(Status
))
320 if (Address
>= MmSystemRangeStart
)
322 DPRINT1("Invalid parameter\n");
323 return STATUS_INVALID_PARAMETER
;
326 Status
= MiQueryVirtualMemory ( ProcessHandle
,
328 VirtualMemoryInformationClass
,
333 if (NT_SUCCESS(Status
))
335 if (PreviousMode
!= KernelMode
)
339 if (ResultLength
> 0)
341 ProbeForWrite(VirtualMemoryInformation
,
344 RtlCopyMemory(VirtualMemoryInformation
,
348 if (UnsafeResultLength
!= NULL
)
350 *UnsafeResultLength
= ResultLength
;
355 Status
= _SEH_GetExceptionCode();
361 if (ResultLength
> 0)
363 RtlCopyMemory(VirtualMemoryInformation
,
368 if (UnsafeResultLength
!= NULL
)
370 *UnsafeResultLength
= ResultLength
;
380 MiProtectVirtualMemory(IN PEPROCESS Process
,
381 IN OUT PVOID
*BaseAddress
,
382 IN OUT PULONG NumberOfBytesToProtect
,
383 IN ULONG NewAccessProtection
,
384 OUT PULONG OldAccessProtection OPTIONAL
)
386 PMEMORY_AREA MemoryArea
;
387 PMADDRESS_SPACE AddressSpace
;
388 ULONG OldAccessProtection_
;
391 *NumberOfBytesToProtect
=
392 PAGE_ROUND_UP((*BaseAddress
) + (*NumberOfBytesToProtect
)) -
393 PAGE_ROUND_DOWN(*BaseAddress
);
394 *BaseAddress
= (PVOID
)PAGE_ROUND_DOWN(*BaseAddress
);
396 AddressSpace
= &Process
->AddressSpace
;
398 MmLockAddressSpace(AddressSpace
);
399 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, *BaseAddress
);
400 if (MemoryArea
== NULL
)
402 MmUnlockAddressSpace(AddressSpace
);
403 return STATUS_UNSUCCESSFUL
;
406 if (OldAccessProtection
== NULL
)
407 OldAccessProtection
= &OldAccessProtection_
;
409 if (MemoryArea
->Type
== MEMORY_AREA_VIRTUAL_MEMORY
)
411 Status
= MmProtectAnonMem(AddressSpace
, MemoryArea
, *BaseAddress
,
412 *NumberOfBytesToProtect
, NewAccessProtection
,
413 OldAccessProtection
);
415 else if (MemoryArea
->Type
== MEMORY_AREA_SECTION_VIEW
)
417 Status
= MmProtectSectionView(AddressSpace
, MemoryArea
, *BaseAddress
,
418 *NumberOfBytesToProtect
,
420 OldAccessProtection
);
424 /* FIXME: Should we return failure or success in this case? */
425 Status
= STATUS_SUCCESS
;
428 MmUnlockAddressSpace(AddressSpace
);
436 * Called from VirtualProtectEx (lib\kernel32\mem\virtual.c)
440 NtProtectVirtualMemory(IN HANDLE ProcessHandle
,
441 IN OUT PVOID
*UnsafeBaseAddress
,
442 IN OUT ULONG
*UnsafeNumberOfBytesToProtect
,
443 IN ULONG NewAccessProtection
,
444 OUT PULONG UnsafeOldAccessProtection
)
447 ULONG OldAccessProtection
;
448 PVOID BaseAddress
= NULL
;
449 ULONG NumberOfBytesToProtect
= 0;
450 KPROCESSOR_MODE PreviousMode
;
451 NTSTATUS Status
= STATUS_SUCCESS
;
453 PreviousMode
= ExGetPreviousMode();
455 if (PreviousMode
!= KernelMode
)
459 ProbeForWritePointer(UnsafeBaseAddress
);
460 ProbeForWriteUlong(UnsafeNumberOfBytesToProtect
);
461 ProbeForWriteUlong(UnsafeOldAccessProtection
);
463 BaseAddress
= *UnsafeBaseAddress
;
464 NumberOfBytesToProtect
= *UnsafeNumberOfBytesToProtect
;
468 Status
= _SEH_GetExceptionCode();
472 if (!NT_SUCCESS(Status
))
479 BaseAddress
= *UnsafeBaseAddress
;
480 NumberOfBytesToProtect
= *UnsafeNumberOfBytesToProtect
;
483 /* (tMk 2004.II.5) in Microsoft SDK I read:
484 * 'if this parameter is NULL or does not point to a valid variable, the function fails'
486 if(UnsafeOldAccessProtection
== NULL
)
488 return(STATUS_INVALID_PARAMETER
);
491 Status
= ObReferenceObjectByHandle(ProcessHandle
,
492 PROCESS_VM_OPERATION
,
497 if (!NT_SUCCESS(Status
))
499 DPRINT("NtProtectVirtualMemory() = %x\n",Status
);
503 Status
= MiProtectVirtualMemory(Process
,
505 &NumberOfBytesToProtect
,
507 &OldAccessProtection
);
509 ObDereferenceObject(Process
);
511 if (PreviousMode
!= KernelMode
)
515 *UnsafeOldAccessProtection
= OldAccessProtection
;
516 *UnsafeBaseAddress
= BaseAddress
;
517 *UnsafeNumberOfBytesToProtect
= NumberOfBytesToProtect
;
521 Status
= _SEH_GetExceptionCode();
527 *UnsafeOldAccessProtection
= OldAccessProtection
;
528 *UnsafeBaseAddress
= BaseAddress
;
529 *UnsafeNumberOfBytesToProtect
= NumberOfBytesToProtect
;
538 * Called from ReadProcessMemory (lib\kernel32\mem\procmem.c) and KlInitPeb(lib\kernel32\process\create.c)
540 * NOTE: This function will be correct if MmProbeAndLockPages() would be fully IMPLEMENTED.
543 NtReadVirtualMemory(IN HANDLE ProcessHandle
,
544 IN PVOID BaseAddress
,
546 IN ULONG NumberOfBytesToRead
,
547 OUT PULONG NumberOfBytesRead OPTIONAL
)
551 KPROCESSOR_MODE PreviousMode
;
552 PEPROCESS Process
, CurrentProcess
;
553 NTSTATUS Status
= STATUS_SUCCESS
;
557 PreviousMode
= ExGetPreviousMode();
559 if(PreviousMode
!= KernelMode
)
563 ProbeForWrite(Buffer
,
566 if(NumberOfBytesRead
!= NULL
)
568 ProbeForWriteUlong(NumberOfBytesRead
);
573 Status
= _SEH_GetExceptionCode();
577 if(!NT_SUCCESS(Status
))
583 DPRINT("NtReadVirtualMemory(ProcessHandle %x, BaseAddress %x, "
584 "Buffer %x, NumberOfBytesToRead %d)\n",ProcessHandle
,BaseAddress
,
585 Buffer
,NumberOfBytesToRead
);
587 Status
= ObReferenceObjectByHandle(ProcessHandle
,
593 if (!NT_SUCCESS(Status
))
598 CurrentProcess
= PsGetCurrentProcess();
600 if (Process
== CurrentProcess
)
604 RtlCopyMemory(Buffer
, BaseAddress
, NumberOfBytesToRead
);
608 Status
= _SEH_GetExceptionCode();
614 Mdl
= MmCreateMdl(NULL
,
616 NumberOfBytesToRead
);
619 ObDereferenceObject(Process
);
620 return(STATUS_NO_MEMORY
);
624 MmProbeAndLockPages(Mdl
,
630 Status
= _SEH_GetExceptionCode();
634 if(NT_SUCCESS(Status
))
636 KeAttachProcess(&Process
->Pcb
);
638 SystemAddress
= MmGetSystemAddressForMdl(Mdl
);
640 Status
= STATUS_SUCCESS
;
642 ProbeForRead(BaseAddress
, NumberOfBytesToRead
, 1);
643 Status
= STATUS_PARTIAL_COPY
;
644 RtlCopyMemory(SystemAddress
, BaseAddress
, NumberOfBytesToRead
);
645 Status
= STATUS_SUCCESS
;
647 if(Status
!= STATUS_PARTIAL_COPY
)
648 Status
= _SEH_GetExceptionCode();
653 if (Mdl
->MappedSystemVa
!= NULL
)
655 MmUnmapLockedPages(Mdl
->MappedSystemVa
, Mdl
);
662 ObDereferenceObject(Process
);
664 if((NT_SUCCESS(Status
) || Status
== STATUS_PARTIAL_COPY
) &&
665 NumberOfBytesRead
!= NULL
)
669 *NumberOfBytesRead
= NumberOfBytesToRead
;
673 Status
= _SEH_GetExceptionCode();
682 * FUNCTION: THIS function doesn't make a sense...
683 * Called from VirtualUnlock (lib\kernel32\mem\virtual.c)
686 NtUnlockVirtualMemory(HANDLE ProcessHandle
,
688 ULONG NumberOfBytesToUnlock
,
689 PULONG NumberOfBytesUnlocked OPTIONAL
)
691 // AG [08-20-03] : I have *no* idea if this is correct, I just used the
692 // other functions as a template and made a few intelligent guesses...
698 DPRINT("NtUnlockVirtualMemory(ProcessHandle %x, BaseAddress %x, "
699 "NumberOfBytesToUnlock %d), NumberOfBytesUnlocked %x\n",ProcessHandle
,BaseAddress
,
700 NumberOfBytesToUnlock
, NumberOfBytesUnlocked
);
702 Status
= ObReferenceObjectByHandle(ProcessHandle
,
708 if (!NT_SUCCESS(Status
))
713 Mdl
= MmCreateMdl(NULL
,
715 NumberOfBytesToUnlock
);
718 ObDereferenceObject(Process
);
719 return(STATUS_NO_MEMORY
);
722 ObDereferenceObject(Process
);
724 if (Mdl
->MappedSystemVa
!= NULL
)
726 MmUnmapLockedPages(Mdl
->MappedSystemVa
, Mdl
);
731 *NumberOfBytesUnlocked
= NumberOfBytesToUnlock
;
733 return(STATUS_SUCCESS
);
739 * Called from WriteProcessMemory (lib\kernel32\mem\procmem.c) and KlInitPeb(lib\kernel32\process\create.c)
741 * NOTE: This function will be correct if MmProbeAndLockPages() would be fully IMPLEMENTED.
744 NtWriteVirtualMemory(IN HANDLE ProcessHandle
,
745 IN PVOID BaseAddress
,
747 IN ULONG NumberOfBytesToWrite
,
748 OUT PULONG NumberOfBytesWritten OPTIONAL
)
753 ULONG OldProtection
= 0;
754 PVOID ProtectBaseAddress
;
755 ULONG ProtectNumberOfBytes
;
756 KPROCESSOR_MODE PreviousMode
;
757 NTSTATUS CopyStatus
, Status
= STATUS_SUCCESS
;
759 DPRINT("NtWriteVirtualMemory(ProcessHandle %x, BaseAddress %x, "
760 "Buffer %x, NumberOfBytesToWrite %d)\n",ProcessHandle
,BaseAddress
,
761 Buffer
,NumberOfBytesToWrite
);
763 PreviousMode
= ExGetPreviousMode();
765 if (PreviousMode
!= KernelMode
&& NumberOfBytesWritten
!= NULL
)
769 ProbeForWriteUlong(NumberOfBytesWritten
);
773 Status
= _SEH_GetExceptionCode();
777 if (!NT_SUCCESS(Status
))
783 Status
= ObReferenceObjectByHandle(ProcessHandle
,
789 if (!NT_SUCCESS(Status
))
794 /* We have to make sure the target memory is writable.
796 * I am not sure if it is correct to do this in any case, but it has to be
797 * done at least in some cases because you can use WriteProcessMemory to
798 * write into the .text section of a module where memcpy() would crash.
799 * -blight (2005/01/09)
801 ProtectBaseAddress
= BaseAddress
;
802 ProtectNumberOfBytes
= NumberOfBytesToWrite
;
804 CopyStatus
= STATUS_SUCCESS
;
807 if (Process
== PsGetCurrentProcess())
809 Status
= MiProtectVirtualMemory(Process
,
811 &ProtectNumberOfBytes
,
814 if (!NT_SUCCESS(Status
))
816 ObDereferenceObject(Process
);
820 if (PreviousMode
!= KernelMode
)
824 memcpy(BaseAddress
, Buffer
, NumberOfBytesToWrite
);
828 CopyStatus
= _SEH_GetExceptionCode();
834 memcpy(BaseAddress
, Buffer
, NumberOfBytesToWrite
);
839 /* Create MDL describing the source buffer. */
840 Mdl
= MmCreateMdl(NULL
,
842 NumberOfBytesToWrite
);
845 ObDereferenceObject(Process
);
846 return(STATUS_NO_MEMORY
);
849 /* Make the target area writable. */
850 Status
= MiProtectVirtualMemory(Process
,
852 &ProtectNumberOfBytes
,
855 if (!NT_SUCCESS(Status
))
857 ObDereferenceObject(Process
);
863 MmProbeAndLockPages(Mdl
,
867 /* Copy memory from the mapped MDL into the target buffer. */
868 KeAttachProcess(&Process
->Pcb
);
870 SystemAddress
= MmGetSystemAddressForMdl(Mdl
);
871 if (PreviousMode
!= KernelMode
)
875 memcpy(BaseAddress
, SystemAddress
, NumberOfBytesToWrite
);
879 CopyStatus
= _SEH_GetExceptionCode();
885 memcpy(BaseAddress
, SystemAddress
, NumberOfBytesToWrite
);
891 if (Mdl
->MappedSystemVa
!= NULL
)
893 MmUnmapLockedPages(Mdl
->MappedSystemVa
, Mdl
);
899 /* Reset the protection of the target memory. */
900 Status
= MiProtectVirtualMemory(Process
,
902 &ProtectNumberOfBytes
,
905 if (!NT_SUCCESS(Status
))
907 DPRINT1("Failed to reset protection of the target memory! (Status 0x%x)\n", Status
);
908 /* FIXME: Should we bugcheck here? */
911 ObDereferenceObject(Process
);
913 if (NumberOfBytesWritten
!= NULL
)
915 if (PreviousMode
!= KernelMode
)
919 *NumberOfBytesWritten
= NumberOfBytesToWrite
;
923 Status
= _SEH_GetExceptionCode();
929 *NumberOfBytesWritten
= NumberOfBytesToWrite
;
933 return(NT_SUCCESS(CopyStatus
) ? Status
: CopyStatus
);
942 MmGetVirtualForPhysical (
943 IN PHYSICAL_ADDRESS PhysicalAddress
951 * Called from EngSecureMem (subsys\win32k\eng\mem.c)
955 MmSecureVirtualMemory (PVOID Address
,
959 /* Only works for user space */
960 if (MmHighestUserAddress
< Address
)
972 * Called from EngUnsecureMem (subsys\win32k\eng\mem.c)
976 MmUnsecureVirtualMemory(PVOID SecureMem
)
978 if (NULL
== SecureMem
)
991 ProbeForRead (IN CONST VOID
*Address
,
995 ASSERT(Alignment
== 1 || Alignment
== 2 || Alignment
== 4 || Alignment
== 8);
1000 if (((ULONG_PTR
)Address
& (Alignment
- 1)) != 0)
1002 ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT
);
1004 else if ((ULONG_PTR
)Address
+ Length
- 1 < (ULONG_PTR
)Address
||
1005 (ULONG_PTR
)Address
+ Length
- 1 >= (ULONG_PTR
)MmUserProbeAddress
)
1007 ExRaiseStatus (STATUS_ACCESS_VIOLATION
);
1016 ProbeForWrite (IN CONST VOID
*Address
,
1020 volatile CHAR
*Current
;
1023 ASSERT(Alignment
== 1 || Alignment
== 2 || Alignment
== 4 || Alignment
== 8);
1028 if (((ULONG_PTR
)Address
& (Alignment
- 1)) != 0)
1030 ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT
);
1033 Last
= (PCHAR
)((ULONG_PTR
)Address
+ Length
- 1);
1034 if ((ULONG_PTR
)Last
< (ULONG_PTR
)Address
||
1035 (ULONG_PTR
)Last
>= (ULONG_PTR
)MmUserProbeAddress
)
1037 ExRaiseStatus (STATUS_ACCESS_VIOLATION
);
1040 /* Check for accessible pages */
1041 Current
= (CHAR
*)Address
;
1044 *Current
= *Current
;
1045 Current
= (CHAR
*)((ULONG_PTR
)Current
+ PAGE_SIZE
);
1046 } while (Current
<= Last
);