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 ProbeForWrite(UnsafeResultLength
,
312 Status
= _SEH_GetExceptionCode();
316 if (!NT_SUCCESS(Status
))
322 if (Address
>= MmSystemRangeStart
)
324 DPRINT1("Invalid parameter\n");
325 return STATUS_INVALID_PARAMETER
;
328 Status
= MiQueryVirtualMemory ( ProcessHandle
,
330 VirtualMemoryInformationClass
,
335 if (NT_SUCCESS(Status
))
337 if (PreviousMode
!= KernelMode
)
341 if (ResultLength
> 0)
343 ProbeForWrite(VirtualMemoryInformation
,
346 RtlCopyMemory(VirtualMemoryInformation
,
350 if (UnsafeResultLength
!= NULL
)
352 *UnsafeResultLength
= ResultLength
;
357 Status
= _SEH_GetExceptionCode();
363 if (ResultLength
> 0)
365 RtlCopyMemory(VirtualMemoryInformation
,
370 if (UnsafeResultLength
!= NULL
)
372 *UnsafeResultLength
= ResultLength
;
382 MiProtectVirtualMemory(IN PEPROCESS Process
,
383 IN OUT PVOID
*BaseAddress
,
384 IN OUT PULONG NumberOfBytesToProtect
,
385 IN ULONG NewAccessProtection
,
386 OUT PULONG OldAccessProtection OPTIONAL
)
388 PMEMORY_AREA MemoryArea
;
389 PMADDRESS_SPACE AddressSpace
;
390 ULONG OldAccessProtection_
;
393 *NumberOfBytesToProtect
=
394 PAGE_ROUND_UP((*BaseAddress
) + (*NumberOfBytesToProtect
)) -
395 PAGE_ROUND_DOWN(*BaseAddress
);
396 *BaseAddress
= (PVOID
)PAGE_ROUND_DOWN(*BaseAddress
);
398 AddressSpace
= &Process
->AddressSpace
;
400 MmLockAddressSpace(AddressSpace
);
401 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, *BaseAddress
);
402 if (MemoryArea
== NULL
)
404 MmUnlockAddressSpace(AddressSpace
);
405 return STATUS_UNSUCCESSFUL
;
408 if (OldAccessProtection
== NULL
)
409 OldAccessProtection
= &OldAccessProtection_
;
411 if (MemoryArea
->Type
== MEMORY_AREA_VIRTUAL_MEMORY
)
413 Status
= MmProtectAnonMem(AddressSpace
, MemoryArea
, *BaseAddress
,
414 *NumberOfBytesToProtect
, NewAccessProtection
,
415 OldAccessProtection
);
417 else if (MemoryArea
->Type
== MEMORY_AREA_SECTION_VIEW
)
419 Status
= MmProtectSectionView(AddressSpace
, MemoryArea
, *BaseAddress
,
420 *NumberOfBytesToProtect
,
422 OldAccessProtection
);
426 /* FIXME: Should we return failure or success in this case? */
427 Status
= STATUS_SUCCESS
;
430 MmUnlockAddressSpace(AddressSpace
);
438 * Called from VirtualProtectEx (lib\kernel32\mem\virtual.c)
442 NtProtectVirtualMemory(IN HANDLE ProcessHandle
,
443 IN OUT PVOID
*UnsafeBaseAddress
,
444 IN OUT ULONG
*UnsafeNumberOfBytesToProtect
,
445 IN ULONG NewAccessProtection
,
446 OUT PULONG UnsafeOldAccessProtection
)
449 ULONG OldAccessProtection
;
450 PVOID BaseAddress
= NULL
;
451 ULONG NumberOfBytesToProtect
= 0;
452 KPROCESSOR_MODE PreviousMode
;
453 NTSTATUS Status
= STATUS_SUCCESS
;
455 PreviousMode
= ExGetPreviousMode();
457 if (PreviousMode
!= KernelMode
)
461 ProbeForWrite(UnsafeBaseAddress
,
464 ProbeForWrite(UnsafeBaseAddress
,
467 ProbeForWrite(UnsafeOldAccessProtection
,
471 BaseAddress
= *UnsafeBaseAddress
;
472 NumberOfBytesToProtect
= *UnsafeNumberOfBytesToProtect
;
476 Status
= _SEH_GetExceptionCode();
480 if (!NT_SUCCESS(Status
))
487 BaseAddress
= *UnsafeBaseAddress
;
488 NumberOfBytesToProtect
= *UnsafeNumberOfBytesToProtect
;
491 /* (tMk 2004.II.5) in Microsoft SDK I read:
492 * 'if this parameter is NULL or does not point to a valid variable, the function fails'
494 if(UnsafeOldAccessProtection
== NULL
)
496 return(STATUS_INVALID_PARAMETER
);
499 Status
= ObReferenceObjectByHandle(ProcessHandle
,
500 PROCESS_VM_OPERATION
,
505 if (!NT_SUCCESS(Status
))
507 DPRINT("NtProtectVirtualMemory() = %x\n",Status
);
511 Status
= MiProtectVirtualMemory(Process
,
513 &NumberOfBytesToProtect
,
515 &OldAccessProtection
);
517 ObDereferenceObject(Process
);
519 if (PreviousMode
!= KernelMode
)
523 *UnsafeOldAccessProtection
= OldAccessProtection
;
524 *UnsafeBaseAddress
= BaseAddress
;
525 *UnsafeNumberOfBytesToProtect
= NumberOfBytesToProtect
;
529 Status
= _SEH_GetExceptionCode();
535 *UnsafeOldAccessProtection
= OldAccessProtection
;
536 *UnsafeBaseAddress
= BaseAddress
;
537 *UnsafeNumberOfBytesToProtect
= NumberOfBytesToProtect
;
546 * Called from ReadProcessMemory (lib\kernel32\mem\procmem.c) and KlInitPeb(lib\kernel32\process\create.c)
548 * NOTE: This function will be correct if MmProbeAndLockPages() would be fully IMPLEMENTED.
551 NtReadVirtualMemory(IN HANDLE ProcessHandle
,
552 IN PVOID BaseAddress
,
554 IN ULONG NumberOfBytesToRead
,
555 OUT PULONG NumberOfBytesRead OPTIONAL
)
559 KPROCESSOR_MODE PreviousMode
;
560 PEPROCESS Process
, CurrentProcess
;
561 NTSTATUS Status
= STATUS_SUCCESS
;
565 PreviousMode
= ExGetPreviousMode();
567 if(PreviousMode
!= KernelMode
)
571 ProbeForWrite(Buffer
,
574 if(NumberOfBytesRead
!= NULL
)
576 ProbeForWrite(NumberOfBytesRead
,
583 Status
= _SEH_GetExceptionCode();
587 if(!NT_SUCCESS(Status
))
593 DPRINT("NtReadVirtualMemory(ProcessHandle %x, BaseAddress %x, "
594 "Buffer %x, NumberOfBytesToRead %d)\n",ProcessHandle
,BaseAddress
,
595 Buffer
,NumberOfBytesToRead
);
597 Status
= ObReferenceObjectByHandle(ProcessHandle
,
603 if (!NT_SUCCESS(Status
))
608 CurrentProcess
= PsGetCurrentProcess();
610 if (Process
== CurrentProcess
)
614 RtlCopyMemory(Buffer
, BaseAddress
, NumberOfBytesToRead
);
618 Status
= _SEH_GetExceptionCode();
624 Mdl
= MmCreateMdl(NULL
,
626 NumberOfBytesToRead
);
629 ObDereferenceObject(Process
);
630 return(STATUS_NO_MEMORY
);
634 MmProbeAndLockPages(Mdl
,
640 Status
= _SEH_GetExceptionCode();
644 if(NT_SUCCESS(Status
))
646 KeAttachProcess(&Process
->Pcb
);
648 SystemAddress
= MmGetSystemAddressForMdl(Mdl
);
650 Status
= STATUS_SUCCESS
;
652 ProbeForRead(BaseAddress
, NumberOfBytesToRead
, 1);
653 Status
= STATUS_PARTIAL_COPY
;
654 RtlCopyMemory(SystemAddress
, BaseAddress
, NumberOfBytesToRead
);
655 Status
= STATUS_SUCCESS
;
657 if(Status
!= STATUS_PARTIAL_COPY
)
658 Status
= _SEH_GetExceptionCode();
663 if (Mdl
->MappedSystemVa
!= NULL
)
665 MmUnmapLockedPages(Mdl
->MappedSystemVa
, Mdl
);
672 ObDereferenceObject(Process
);
674 if((NT_SUCCESS(Status
) || Status
== STATUS_PARTIAL_COPY
) &&
675 NumberOfBytesRead
!= NULL
)
679 *NumberOfBytesRead
= NumberOfBytesToRead
;
683 Status
= _SEH_GetExceptionCode();
692 * FUNCTION: THIS function doesn't make a sense...
693 * Called from VirtualUnlock (lib\kernel32\mem\virtual.c)
696 NtUnlockVirtualMemory(HANDLE ProcessHandle
,
698 ULONG NumberOfBytesToUnlock
,
699 PULONG NumberOfBytesUnlocked OPTIONAL
)
701 // AG [08-20-03] : I have *no* idea if this is correct, I just used the
702 // other functions as a template and made a few intelligent guesses...
708 DPRINT("NtUnlockVirtualMemory(ProcessHandle %x, BaseAddress %x, "
709 "NumberOfBytesToUnlock %d), NumberOfBytesUnlocked %x\n",ProcessHandle
,BaseAddress
,
710 NumberOfBytesToUnlock
, NumberOfBytesUnlocked
);
712 Status
= ObReferenceObjectByHandle(ProcessHandle
,
718 if (!NT_SUCCESS(Status
))
723 Mdl
= MmCreateMdl(NULL
,
725 NumberOfBytesToUnlock
);
728 ObDereferenceObject(Process
);
729 return(STATUS_NO_MEMORY
);
732 ObDereferenceObject(Process
);
734 if (Mdl
->MappedSystemVa
!= NULL
)
736 MmUnmapLockedPages(Mdl
->MappedSystemVa
, Mdl
);
741 *NumberOfBytesUnlocked
= NumberOfBytesToUnlock
;
743 return(STATUS_SUCCESS
);
749 * Called from WriteProcessMemory (lib\kernel32\mem\procmem.c) and KlInitPeb(lib\kernel32\process\create.c)
751 * NOTE: This function will be correct if MmProbeAndLockPages() would be fully IMPLEMENTED.
754 NtWriteVirtualMemory(IN HANDLE ProcessHandle
,
755 IN PVOID BaseAddress
,
757 IN ULONG NumberOfBytesToWrite
,
758 OUT PULONG NumberOfBytesWritten OPTIONAL
)
763 ULONG OldProtection
= 0;
764 PVOID ProtectBaseAddress
;
765 ULONG ProtectNumberOfBytes
;
766 KPROCESSOR_MODE PreviousMode
;
767 NTSTATUS CopyStatus
, Status
= STATUS_SUCCESS
;
769 DPRINT("NtWriteVirtualMemory(ProcessHandle %x, BaseAddress %x, "
770 "Buffer %x, NumberOfBytesToWrite %d)\n",ProcessHandle
,BaseAddress
,
771 Buffer
,NumberOfBytesToWrite
);
773 PreviousMode
= ExGetPreviousMode();
775 if (PreviousMode
!= KernelMode
&& NumberOfBytesWritten
!= NULL
)
779 ProbeForWrite(NumberOfBytesWritten
,
785 Status
= _SEH_GetExceptionCode();
789 if (!NT_SUCCESS(Status
))
795 Status
= ObReferenceObjectByHandle(ProcessHandle
,
801 if (!NT_SUCCESS(Status
))
806 /* We have to make sure the target memory is writable.
808 * I am not sure if it is correct to do this in any case, but it has to be
809 * done at least in some cases because you can use WriteProcessMemory to
810 * write into the .text section of a module where memcpy() would crash.
811 * -blight (2005/01/09)
813 ProtectBaseAddress
= BaseAddress
;
814 ProtectNumberOfBytes
= NumberOfBytesToWrite
;
816 CopyStatus
= STATUS_SUCCESS
;
819 if (Process
== PsGetCurrentProcess())
821 Status
= MiProtectVirtualMemory(Process
,
823 &ProtectNumberOfBytes
,
826 if (!NT_SUCCESS(Status
))
828 ObDereferenceObject(Process
);
832 if (PreviousMode
!= KernelMode
)
836 memcpy(BaseAddress
, Buffer
, NumberOfBytesToWrite
);
840 CopyStatus
= _SEH_GetExceptionCode();
846 memcpy(BaseAddress
, Buffer
, NumberOfBytesToWrite
);
851 /* Create MDL describing the source buffer. */
852 Mdl
= MmCreateMdl(NULL
,
854 NumberOfBytesToWrite
);
857 ObDereferenceObject(Process
);
858 return(STATUS_NO_MEMORY
);
861 /* Make the target area writable. */
862 Status
= MiProtectVirtualMemory(Process
,
864 &ProtectNumberOfBytes
,
867 if (!NT_SUCCESS(Status
))
869 ObDereferenceObject(Process
);
875 MmProbeAndLockPages(Mdl
,
879 /* Copy memory from the mapped MDL into the target buffer. */
880 KeAttachProcess(&Process
->Pcb
);
882 SystemAddress
= MmGetSystemAddressForMdl(Mdl
);
883 if (PreviousMode
!= KernelMode
)
887 memcpy(BaseAddress
, SystemAddress
, NumberOfBytesToWrite
);
891 CopyStatus
= _SEH_GetExceptionCode();
897 memcpy(BaseAddress
, SystemAddress
, NumberOfBytesToWrite
);
903 if (Mdl
->MappedSystemVa
!= NULL
)
905 MmUnmapLockedPages(Mdl
->MappedSystemVa
, Mdl
);
911 /* Reset the protection of the target memory. */
912 Status
= MiProtectVirtualMemory(Process
,
914 &ProtectNumberOfBytes
,
917 if (!NT_SUCCESS(Status
))
919 DPRINT1("Failed to reset protection of the target memory! (Status 0x%x)\n", Status
);
920 /* FIXME: Should we bugcheck here? */
923 ObDereferenceObject(Process
);
925 if (NumberOfBytesWritten
!= NULL
)
927 if (PreviousMode
!= KernelMode
)
931 *NumberOfBytesWritten
= NumberOfBytesToWrite
;
935 Status
= _SEH_GetExceptionCode();
941 *NumberOfBytesWritten
= NumberOfBytesToWrite
;
945 return(NT_SUCCESS(CopyStatus
) ? Status
: CopyStatus
);
954 MmGetVirtualForPhysical (
955 IN PHYSICAL_ADDRESS PhysicalAddress
963 * Called from EngSecureMem (subsys\win32k\eng\mem.c)
967 MmSecureVirtualMemory (PVOID Address
,
971 /* Only works for user space */
972 if (MmHighestUserAddress
< Address
)
984 * Called from EngUnsecureMem (subsys\win32k\eng\mem.c)
988 MmUnsecureVirtualMemory(PVOID SecureMem
)
990 if (NULL
== SecureMem
)
1003 ProbeForRead (IN CONST VOID
*Address
,
1007 ASSERT(Alignment
== 1 || Alignment
== 2 || Alignment
== 4 || Alignment
== 8);
1012 if (((ULONG_PTR
)Address
& (Alignment
- 1)) != 0)
1014 ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT
);
1016 else if ((ULONG_PTR
)Address
+ Length
- 1 < (ULONG_PTR
)Address
||
1017 (ULONG_PTR
)Address
+ Length
- 1 >= (ULONG_PTR
)MmUserProbeAddress
)
1019 ExRaiseStatus (STATUS_ACCESS_VIOLATION
);
1028 ProbeForWrite (IN CONST VOID
*Address
,
1032 volatile CHAR
*Current
;
1035 ASSERT(Alignment
== 1 || Alignment
== 2 || Alignment
== 4 || Alignment
== 8);
1040 if (((ULONG_PTR
)Address
& (Alignment
- 1)) != 0)
1042 ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT
);
1045 Last
= (PCHAR
)((ULONG_PTR
)Address
+ Length
- 1);
1046 if ((ULONG_PTR
)Last
< (ULONG_PTR
)Address
||
1047 (ULONG_PTR
)Last
>= (ULONG_PTR
)MmUserProbeAddress
)
1049 ExRaiseStatus (STATUS_ACCESS_VIOLATION
);
1052 /* Check for accessible pages */
1053 Current
= (CHAR
*)Address
;
1056 *Current
= *Current
;
1057 Current
= (CHAR
*)((ULONG_PTR
)Current
+ PAGE_SIZE
);
1058 } while (Current
<= Last
);