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
:
187 Info
->Type
= MEM_PRIVATE
;
188 Info
->State
= MEM_RESERVE
;
189 Info
->Protect
= MemoryArea
->Protect
;
190 Info
->AllocationProtect
= MemoryArea
->Protect
;
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
:
199 Info
->Type
= MEM_PRIVATE
;
200 Info
->State
= MEM_COMMIT
;
201 Info
->Protect
= MemoryArea
->Protect
;
202 Info
->AllocationProtect
= MemoryArea
->Protect
;
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
->Protect
;
214 Info
->AllocationProtect
= MemoryArea
->Protect
;
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
->Protect
;
226 Info
->AllocationProtect
= MemoryArea
->Protect
;
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
->Protect
;
238 Info
->AllocationProtect
= MemoryArea
->Protect
;
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 MEMORY_INFORMATION_CLASS 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_CONFLICTING_ADDRESSES
;
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 if ((ULONG_PTR
)BaseAddress
+ NumberOfBytesToProtect
- 1 < (ULONG_PTR
)BaseAddress
||
484 (ULONG_PTR
)BaseAddress
+ NumberOfBytesToProtect
- 1 >= MmUserProbeAddress
)
486 /* Don't allow to change the protection of a kernel mode address */
487 return STATUS_INVALID_PARAMETER_2
;
490 /* (tMk 2004.II.5) in Microsoft SDK I read:
491 * 'if this parameter is NULL or does not point to a valid variable, the function fails'
493 if(UnsafeOldAccessProtection
== NULL
)
495 return(STATUS_INVALID_PARAMETER
);
498 Status
= ObReferenceObjectByHandle(ProcessHandle
,
499 PROCESS_VM_OPERATION
,
504 if (!NT_SUCCESS(Status
))
506 DPRINT("NtProtectVirtualMemory() = %x\n",Status
);
510 Status
= MiProtectVirtualMemory(Process
,
512 &NumberOfBytesToProtect
,
514 &OldAccessProtection
);
516 ObDereferenceObject(Process
);
518 if (PreviousMode
!= KernelMode
)
522 *UnsafeOldAccessProtection
= OldAccessProtection
;
523 *UnsafeBaseAddress
= BaseAddress
;
524 *UnsafeNumberOfBytesToProtect
= NumberOfBytesToProtect
;
528 Status
= _SEH_GetExceptionCode();
534 *UnsafeOldAccessProtection
= OldAccessProtection
;
535 *UnsafeBaseAddress
= BaseAddress
;
536 *UnsafeNumberOfBytesToProtect
= NumberOfBytesToProtect
;
545 * Called from ReadProcessMemory (lib\kernel32\mem\procmem.c) and KlInitPeb(lib\kernel32\process\create.c)
547 * NOTE: This function will be correct if MmProbeAndLockPages() would be fully IMPLEMENTED.
550 NtReadVirtualMemory(IN HANDLE ProcessHandle
,
551 IN PVOID BaseAddress
,
553 IN ULONG NumberOfBytesToRead
,
554 OUT PULONG NumberOfBytesRead OPTIONAL
)
558 KPROCESSOR_MODE PreviousMode
;
559 PEPROCESS Process
, CurrentProcess
;
560 NTSTATUS Status
= STATUS_SUCCESS
;
564 DPRINT("NtReadVirtualMemory(ProcessHandle %x, BaseAddress %x, "
565 "Buffer %x, NumberOfBytesToRead %d)\n",ProcessHandle
,BaseAddress
,
566 Buffer
,NumberOfBytesToRead
);
568 if ((ULONG_PTR
)BaseAddress
+ NumberOfBytesToRead
- 1 < (ULONG_PTR
)BaseAddress
||
569 (ULONG_PTR
)BaseAddress
+ NumberOfBytesToRead
- 1 >= MmUserProbeAddress
)
571 /* Don't allow to read from kernel space */
572 return STATUS_ACCESS_VIOLATION
;
575 PreviousMode
= ExGetPreviousMode();
577 if (PreviousMode
!= KernelMode
)
579 if ((ULONG_PTR
)Buffer
+ NumberOfBytesToRead
- 1 < (ULONG_PTR
)Buffer
||
580 (ULONG_PTR
)Buffer
+ NumberOfBytesToRead
- 1 >= MmUserProbeAddress
)
582 /* Don't allow to write into kernel space */
583 return STATUS_ACCESS_VIOLATION
;
587 Status
= ObReferenceObjectByHandle(ProcessHandle
,
593 if (!NT_SUCCESS(Status
))
598 CurrentProcess
= PsGetCurrentProcess();
600 if(PreviousMode
!= KernelMode
)
604 if(NumberOfBytesRead
!= NULL
)
606 ProbeForWriteUlong(NumberOfBytesRead
);
611 Status
= _SEH_GetExceptionCode();
615 if(!NT_SUCCESS(Status
))
622 if (Process
== CurrentProcess
)
626 RtlCopyMemory(Buffer
, BaseAddress
, NumberOfBytesToRead
);
630 Status
= _SEH_GetExceptionCode();
636 Mdl
= MmCreateMdl(NULL
,
638 NumberOfBytesToRead
);
641 ObDereferenceObject(Process
);
642 return(STATUS_NO_MEMORY
);
646 MmProbeAndLockPages(Mdl
,
652 Status
= _SEH_GetExceptionCode();
656 if(NT_SUCCESS(Status
))
658 KeAttachProcess(&Process
->Pcb
);
660 SystemAddress
= MmGetSystemAddressForMdl(Mdl
);
662 Status
= STATUS_SUCCESS
;
664 Status
= STATUS_PARTIAL_COPY
;
665 RtlCopyMemory(SystemAddress
, BaseAddress
, NumberOfBytesToRead
);
666 Status
= STATUS_SUCCESS
;
668 if(Status
!= STATUS_PARTIAL_COPY
)
669 Status
= _SEH_GetExceptionCode();
674 if (Mdl
->MappedSystemVa
!= NULL
)
676 MmUnmapLockedPages(Mdl
->MappedSystemVa
, Mdl
);
683 ObDereferenceObject(Process
);
685 if((NT_SUCCESS(Status
) || Status
== STATUS_PARTIAL_COPY
) &&
686 NumberOfBytesRead
!= NULL
)
690 *NumberOfBytesRead
= NumberOfBytesToRead
;
694 Status
= _SEH_GetExceptionCode();
703 * FUNCTION: THIS function doesn't make a sense...
704 * Called from VirtualUnlock (lib\kernel32\mem\virtual.c)
707 NtUnlockVirtualMemory(HANDLE ProcessHandle
,
709 ULONG NumberOfBytesToUnlock
,
710 PULONG NumberOfBytesUnlocked OPTIONAL
)
712 // AG [08-20-03] : I have *no* idea if this is correct, I just used the
713 // other functions as a template and made a few intelligent guesses...
719 DPRINT("NtUnlockVirtualMemory(ProcessHandle %x, BaseAddress %x, "
720 "NumberOfBytesToUnlock %d), NumberOfBytesUnlocked %x\n",ProcessHandle
,BaseAddress
,
721 NumberOfBytesToUnlock
, NumberOfBytesUnlocked
);
723 Status
= ObReferenceObjectByHandle(ProcessHandle
,
729 if (!NT_SUCCESS(Status
))
734 Mdl
= MmCreateMdl(NULL
,
736 NumberOfBytesToUnlock
);
739 ObDereferenceObject(Process
);
740 return(STATUS_NO_MEMORY
);
743 ObDereferenceObject(Process
);
745 if (Mdl
->MappedSystemVa
!= NULL
)
747 MmUnmapLockedPages(Mdl
->MappedSystemVa
, Mdl
);
752 *NumberOfBytesUnlocked
= NumberOfBytesToUnlock
;
754 return(STATUS_SUCCESS
);
760 * Called from WriteProcessMemory (lib\kernel32\mem\procmem.c) and KlInitPeb(lib\kernel32\process\create.c)
762 * NOTE: This function will be correct if MmProbeAndLockPages() would be fully IMPLEMENTED.
765 NtWriteVirtualMemory(IN HANDLE ProcessHandle
,
766 IN PVOID BaseAddress
,
768 IN ULONG NumberOfBytesToWrite
,
769 OUT PULONG NumberOfBytesWritten OPTIONAL
)
774 KPROCESSOR_MODE PreviousMode
;
775 NTSTATUS CopyStatus
, Status
= STATUS_SUCCESS
;
777 DPRINT("NtWriteVirtualMemory(ProcessHandle %x, BaseAddress %x, "
778 "Buffer %x, NumberOfBytesToWrite %d)\n",ProcessHandle
,BaseAddress
,
779 Buffer
,NumberOfBytesToWrite
);
781 if ((ULONG_PTR
)BaseAddress
+ NumberOfBytesToWrite
- 1 < (ULONG_PTR
)BaseAddress
||
782 (ULONG_PTR
)BaseAddress
+ NumberOfBytesToWrite
- 1 >= MmUserProbeAddress
)
784 /* Don't allow to write into kernel space */
785 return STATUS_ACCESS_VIOLATION
;
788 PreviousMode
= ExGetPreviousMode();
790 if (PreviousMode
!= KernelMode
)
792 if ((ULONG_PTR
)Buffer
+ NumberOfBytesToWrite
- 1 < (ULONG_PTR
)Buffer
||
793 (ULONG_PTR
)Buffer
+ NumberOfBytesToWrite
- 1 >= MmUserProbeAddress
)
795 /* Don't allow to read from kernel space */
796 return STATUS_ACCESS_VIOLATION
;
798 if (NumberOfBytesWritten
!= NULL
)
802 ProbeForWriteUlong(NumberOfBytesWritten
);
806 Status
= _SEH_GetExceptionCode();
810 if (!NT_SUCCESS(Status
))
817 Status
= ObReferenceObjectByHandle(ProcessHandle
,
823 if (!NT_SUCCESS(Status
))
828 CopyStatus
= STATUS_SUCCESS
;
831 if (Process
== PsGetCurrentProcess())
833 if (PreviousMode
!= KernelMode
)
837 memcpy(BaseAddress
, Buffer
, NumberOfBytesToWrite
);
841 CopyStatus
= _SEH_GetExceptionCode();
847 memcpy(BaseAddress
, Buffer
, NumberOfBytesToWrite
);
852 /* Create MDL describing the source buffer. */
853 Mdl
= MmCreateMdl(NULL
,
855 NumberOfBytesToWrite
);
858 ObDereferenceObject(Process
);
859 return(STATUS_NO_MEMORY
);
864 MmProbeAndLockPages(Mdl
,
870 CopyStatus
= _SEH_GetExceptionCode();
874 if (NT_SUCCESS(CopyStatus
))
876 /* Copy memory from the mapped MDL into the target buffer. */
877 KeAttachProcess(&Process
->Pcb
);
879 SystemAddress
= MmGetSystemAddressForMdl(Mdl
);
880 if (PreviousMode
!= KernelMode
)
884 memcpy(BaseAddress
, SystemAddress
, NumberOfBytesToWrite
);
888 CopyStatus
= _SEH_GetExceptionCode();
894 memcpy(BaseAddress
, SystemAddress
, NumberOfBytesToWrite
);
901 if (Mdl
->MappedSystemVa
!= NULL
)
903 MmUnmapLockedPages(Mdl
->MappedSystemVa
, Mdl
);
908 ObDereferenceObject(Process
);
910 if (NT_SUCCESS(CopyStatus
) && NumberOfBytesWritten
!= NULL
)
912 if (PreviousMode
!= KernelMode
)
916 *NumberOfBytesWritten
= NumberOfBytesToWrite
;
920 Status
= _SEH_GetExceptionCode();
926 *NumberOfBytesWritten
= NumberOfBytesToWrite
;
930 return(NT_SUCCESS(CopyStatus
) ? Status
: CopyStatus
);
939 MmGetVirtualForPhysical (
940 IN PHYSICAL_ADDRESS PhysicalAddress
948 * Called from EngSecureMem (subsys\win32k\eng\mem.c)
952 MmSecureVirtualMemory (PVOID Address
,
956 /* Only works for user space */
957 if (MmHighestUserAddress
< Address
)
969 * Called from EngUnsecureMem (subsys\win32k\eng\mem.c)
973 MmUnsecureVirtualMemory(PVOID SecureMem
)
975 if (NULL
== SecureMem
)
988 ProbeForRead (IN CONST VOID
*Address
,
994 ASSERT(Alignment
== 1 || Alignment
== 2 || Alignment
== 4 || Alignment
== 8);
996 if (((ULONG_PTR
)Address
& (Alignment
- 1)) != 0)
998 ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT
);
1000 else if ((ULONG_PTR
)Address
+ Length
- 1 < (ULONG_PTR
)Address
||
1001 (ULONG_PTR
)Address
+ Length
- 1 >= (ULONG_PTR
)MmUserProbeAddress
)
1003 ExRaiseStatus (STATUS_ACCESS_VIOLATION
);
1013 ProbeForWrite (IN PVOID Address
,
1017 volatile CHAR
*Current
;
1022 ASSERT(Alignment
== 1 || Alignment
== 2 || Alignment
== 4 || Alignment
== 8);
1024 if (((ULONG_PTR
)Address
& (Alignment
- 1)) != 0)
1026 ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT
);
1029 Last
= (PCHAR
)((ULONG_PTR
)Address
+ Length
- 1);
1030 if ((ULONG_PTR
)Last
< (ULONG_PTR
)Address
||
1031 (ULONG_PTR
)Last
>= (ULONG_PTR
)MmUserProbeAddress
)
1033 ExRaiseStatus (STATUS_ACCESS_VIOLATION
);
1036 /* Check for accessible pages, do *not* touch any memory outside of the
1038 Current
= (volatile CHAR
*)Address
;
1039 Last
= (PCHAR
)(PAGE_ROUND_DOWN(Last
));
1042 *Current
= *Current
;
1043 Current
= (volatile CHAR
*)(PAGE_ROUND_DOWN(Current
) + PAGE_SIZE
);
1044 } while (Current
<= Last
);