3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* $Id: virtual.c,v 1.63 2002/09/07 15:13:03 chorns Exp $
21 * PROJECT: ReactOS kernel
22 * FILE: ntoskrnl/mm/virtual.c
23 * PURPOSE: Implementing operations on virtual memory.
24 * PROGRAMMER: David Welch
27 /* INCLUDE *****************************************************************/
32 #include <internal/debug.h>
34 /* FUNCTIONS *****************************************************************/
37 NtFlushVirtualMemory(IN HANDLE ProcessHandle
,
39 IN ULONG NumberOfBytesToFlush
,
40 OUT PULONG NumberOfBytesFlushed OPTIONAL
)
42 * FUNCTION: Flushes virtual memory to file
44 * ProcessHandle = Points to the process that allocated the virtual
46 * BaseAddress = Points to the memory address
47 * NumberOfBytesToFlush = Limits the range to flush,
48 * NumberOfBytesFlushed = Actual number of bytes flushed
56 NtLockVirtualMemory(HANDLE ProcessHandle
,
58 ULONG NumberOfBytesToLock
,
59 PULONG NumberOfBytesLocked
)
65 NtQueryVirtualMemory (IN HANDLE ProcessHandle
,
67 IN CINT VirtualMemoryInformationClass
,
68 OUT PVOID VirtualMemoryInformation
,
70 OUT PULONG UnsafeResultLength
)
74 MEMORY_AREA
* MemoryArea
;
75 ULONG ResultLength
= 0;
76 PMADDRESS_SPACE AddressSpace
;
78 DPRINT("NtQueryVirtualMemory(ProcessHandle %x, Address %x, "
79 "VirtualMemoryInformationClass %d, VirtualMemoryInformation %x, "
80 "Length %lu ResultLength %x)\n",ProcessHandle
,Address
,
81 VirtualMemoryInformationClass
,VirtualMemoryInformation
,
84 Status
= ObReferenceObjectByHandle(ProcessHandle
,
85 PROCESS_QUERY_INFORMATION
,
91 if (!NT_SUCCESS(Status
))
93 DPRINT("NtQueryVirtualMemory() = %x\n",Status
);
97 AddressSpace
= &Process
->AddressSpace
;
98 MmLockAddressSpace(AddressSpace
);
99 MemoryArea
= MmOpenMemoryAreaByAddress(AddressSpace
,
101 switch(VirtualMemoryInformationClass
)
103 case MemoryBasicInformation
:
105 PMEMORY_BASIC_INFORMATION Info
=
106 (PMEMORY_BASIC_INFORMATION
)VirtualMemoryInformation
;
108 if (Length
!= sizeof(MEMORY_BASIC_INFORMATION
))
110 ObDereferenceObject(Process
);
111 return(STATUS_INFO_LENGTH_MISMATCH
);
114 if (MemoryArea
== NULL
)
116 Info
->State
= MEM_FREE
;
117 Info
->BaseAddress
= (PVOID
)PAGE_ROUND_DOWN(Address
);
118 Status
= STATUS_SUCCESS
;
119 ResultLength
= sizeof(MEMORY_BASIC_INFORMATION
);
121 else if (MemoryArea
->Type
== MEMORY_AREA_VIRTUAL_MEMORY
)
123 Status
= MmQueryAnonMem(MemoryArea
, Address
, Info
,
126 else if (MemoryArea
->Type
== MEMORY_AREA_SECTION_VIEW
)
128 Status
= MmQuerySectionView(MemoryArea
, Address
, Info
,
133 Status
= STATUS_UNSUCCESSFUL
;
141 Status
= STATUS_INVALID_INFO_CLASS
;
147 MmUnlockAddressSpace(AddressSpace
);
148 ObDereferenceObject(Process
);
149 if (UnsafeResultLength
!= NULL
)
151 MmCopyToCaller(UnsafeResultLength
, &ResultLength
, sizeof(ULONG
));
157 NtProtectVirtualMemory(IN HANDLE ProcessHandle
,
158 IN PVOID BaseAddress
,
159 IN ULONG NumberOfBytesToProtect
,
160 IN ULONG NewAccessProtection
,
161 OUT PULONG UnsafeOldAccessProtection
)
163 PMEMORY_AREA MemoryArea
;
166 PMADDRESS_SPACE AddressSpace
;
167 ULONG OldAccessProtection
;
169 NumberOfBytesToProtect
=
170 PAGE_ROUND_UP(BaseAddress
+ NumberOfBytesToProtect
) -
171 PAGE_ROUND_DOWN(BaseAddress
);
172 BaseAddress
= (PVOID
)PAGE_ROUND_DOWN(BaseAddress
);
174 Status
= ObReferenceObjectByHandle(ProcessHandle
,
175 PROCESS_VM_OPERATION
,
180 if (Status
!= STATUS_SUCCESS
)
182 DPRINT("NtProtectVirtualMemory() = %x\n",Status
);
186 AddressSpace
= &Process
->AddressSpace
;
188 MmLockAddressSpace(AddressSpace
);
189 MemoryArea
= MmOpenMemoryAreaByAddress(AddressSpace
,
191 if (MemoryArea
== NULL
)
193 MmUnlockAddressSpace(AddressSpace
);
194 ObDereferenceObject(Process
);
195 return(STATUS_UNSUCCESSFUL
);
198 if (MemoryArea
->Type
== MEMORY_AREA_VIRTUAL_MEMORY
)
200 Status
= MmProtectAnonMem(AddressSpace
, MemoryArea
, BaseAddress
,
201 NumberOfBytesToProtect
, NewAccessProtection
,
202 &OldAccessProtection
);
204 else if (MemoryArea
->Type
== MEMORY_AREA_SECTION_VIEW
)
206 Status
= MmProtectSectionView(AddressSpace
, MemoryArea
, BaseAddress
,
207 NumberOfBytesToProtect
,
209 &OldAccessProtection
);
212 MmUnlockAddressSpace(AddressSpace
);
213 ObDereferenceObject(Process
);
215 MmCopyToCaller(UnsafeOldAccessProtection
, &OldAccessProtection
,
222 NtReadVirtualMemory(IN HANDLE ProcessHandle
,
223 IN PVOID BaseAddress
,
225 IN ULONG NumberOfBytesToRead
,
226 OUT PULONG NumberOfBytesRead
)
233 DPRINT("NtReadVirtualMemory(ProcessHandle %x, BaseAddress %x, "
234 "Buffer %x, NumberOfBytesToRead %d)\n",ProcessHandle
,BaseAddress
,
235 Buffer
,NumberOfBytesToRead
);
237 Status
= ObReferenceObjectByHandle(ProcessHandle
,
243 if (Status
!= STATUS_SUCCESS
)
248 Mdl
= MmCreateMdl(NULL
,
250 NumberOfBytesToRead
);
251 MmProbeAndLockPages(Mdl
,
255 KeAttachProcess(Process
);
257 SystemAddress
= MmGetSystemAddressForMdl(Mdl
);
258 memcpy(SystemAddress
, BaseAddress
, NumberOfBytesToRead
);
262 if (Mdl
->MappedSystemVa
!= NULL
)
264 MmUnmapLockedPages(Mdl
->MappedSystemVa
, Mdl
);
269 ObDereferenceObject(Process
);
271 *NumberOfBytesRead
= NumberOfBytesToRead
;
272 return(STATUS_SUCCESS
);
276 NtUnlockVirtualMemory(HANDLE ProcessHandle
,
278 ULONG NumberOfBytesToUnlock
,
279 PULONG NumberOfBytesUnlocked OPTIONAL
)
286 NtWriteVirtualMemory(IN HANDLE ProcessHandle
,
287 IN PVOID BaseAddress
,
289 IN ULONG NumberOfBytesToWrite
,
290 OUT PULONG NumberOfBytesWritten
)
297 DPRINT("NtWriteVirtualMemory(ProcessHandle %x, BaseAddress %x, "
298 "Buffer %x, NumberOfBytesToWrite %d)\n",ProcessHandle
,BaseAddress
,
299 Buffer
,NumberOfBytesToWrite
);
301 Status
= ObReferenceObjectByHandle(ProcessHandle
,
307 if (Status
!= STATUS_SUCCESS
)
312 Mdl
= MmCreateMdl(NULL
,
314 NumberOfBytesToWrite
);
315 MmProbeAndLockPages(Mdl
,
319 KeAttachProcess(Process
);
321 SystemAddress
= MmGetSystemAddressForMdl(Mdl
);
322 memcpy(BaseAddress
, SystemAddress
, NumberOfBytesToWrite
);
326 ObDereferenceObject(Process
);
328 if (Mdl
->MappedSystemVa
!= NULL
)
330 MmUnmapLockedPages(Mdl
->MappedSystemVa
, Mdl
);
335 *NumberOfBytesWritten
= NumberOfBytesToWrite
;
337 return(STATUS_SUCCESS
);
341 MmSecureVirtualMemory (IN PVOID Address
,
351 MmUnsecureVirtualMemory (IN HANDLE SecureHandle
)