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.
21 * PROJECT: ReactOS kernel
22 * FILE: ntoskrnl/mm/virtual.c
23 * PURPOSE: Implementing operations on virtual memory.
24 * PROGRAMMER: David Welch
27 /* INCLUDE *****************************************************************/
29 #include <ddk/ntddk.h>
30 #include <internal/mm.h>
31 #include <internal/ob.h>
32 #include <internal/io.h>
33 #include <internal/ps.h>
34 #include <internal/pool.h>
35 #include <internal/safe.h>
38 #include <internal/debug.h>
40 /* FUNCTIONS *****************************************************************/
43 NtFlushVirtualMemory(IN HANDLE ProcessHandle,
45 IN ULONG NumberOfBytesToFlush,
46 OUT PULONG NumberOfBytesFlushed OPTIONAL)
48 * FUNCTION: Flushes virtual memory to file
50 * ProcessHandle = Points to the process that allocated the virtual
52 * BaseAddress = Points to the memory address
53 * NumberOfBytesToFlush = Limits the range to flush,
54 * NumberOfBytesFlushed = Actual number of bytes flushed
62 NtLockVirtualMemory(HANDLE ProcessHandle,
64 ULONG NumberOfBytesToLock,
65 PULONG NumberOfBytesLocked)
71 NtQueryVirtualMemory (IN HANDLE ProcessHandle,
73 IN CINT VirtualMemoryInformationClass,
74 OUT PVOID VirtualMemoryInformation,
76 OUT PULONG UnsafeResultLength)
80 MEMORY_AREA* MemoryArea;
81 ULONG ResultLength = 0;
82 PMADDRESS_SPACE AddressSpace;
84 DPRINT("NtQueryVirtualMemory(ProcessHandle %x, Address %x, "
85 "VirtualMemoryInformationClass %d, VirtualMemoryInformation %x, "
86 "Length %lu ResultLength %x)\n",ProcessHandle,Address,
87 VirtualMemoryInformationClass,VirtualMemoryInformation,
90 Status = ObReferenceObjectByHandle(ProcessHandle,
91 PROCESS_QUERY_INFORMATION,
97 if (!NT_SUCCESS(Status))
99 DPRINT("NtQueryVirtualMemory() = %x\n",Status);
103 AddressSpace = &Process->AddressSpace;
104 MmLockAddressSpace(AddressSpace);
105 MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace,
107 switch(VirtualMemoryInformationClass)
109 case MemoryBasicInformation:
111 PMEMORY_BASIC_INFORMATION Info =
112 (PMEMORY_BASIC_INFORMATION)VirtualMemoryInformation;
114 if (Length != sizeof(MEMORY_BASIC_INFORMATION))
116 MmUnlockAddressSpace(AddressSpace);
117 ObDereferenceObject(Process);
118 return(STATUS_INFO_LENGTH_MISMATCH);
121 if (MemoryArea == NULL)
123 Info->State = MEM_FREE;
124 Info->BaseAddress = (PVOID)PAGE_ROUND_DOWN(Address);
125 Status = STATUS_SUCCESS;
126 ResultLength = sizeof(MEMORY_BASIC_INFORMATION);
128 else if (MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY)
130 Status = MmQueryAnonMem(MemoryArea, Address, Info,
133 else if (MemoryArea->Type == MEMORY_AREA_SECTION_VIEW)
135 Status = MmQuerySectionView(MemoryArea, Address, Info,
140 Status = STATUS_UNSUCCESSFUL;
148 Status = STATUS_INVALID_INFO_CLASS;
154 MmUnlockAddressSpace(AddressSpace);
155 ObDereferenceObject(Process);
156 if (UnsafeResultLength != NULL)
158 MmCopyToCaller(UnsafeResultLength, &ResultLength, sizeof(ULONG));
164 NtProtectVirtualMemory(IN HANDLE ProcessHandle,
165 IN PVOID BaseAddress,
166 IN ULONG NumberOfBytesToProtect,
167 IN ULONG NewAccessProtection,
168 OUT PULONG UnsafeOldAccessProtection)
170 PMEMORY_AREA MemoryArea;
173 PMADDRESS_SPACE AddressSpace;
174 ULONG OldAccessProtection;
176 NumberOfBytesToProtect =
177 PAGE_ROUND_UP(BaseAddress + NumberOfBytesToProtect) -
178 PAGE_ROUND_DOWN(BaseAddress);
179 BaseAddress = (PVOID)PAGE_ROUND_DOWN(BaseAddress);
181 Status = ObReferenceObjectByHandle(ProcessHandle,
182 PROCESS_VM_OPERATION,
187 if (Status != STATUS_SUCCESS)
189 DPRINT("NtProtectVirtualMemory() = %x\n",Status);
193 AddressSpace = &Process->AddressSpace;
195 MmLockAddressSpace(AddressSpace);
196 MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace,
198 if (MemoryArea == NULL)
200 MmUnlockAddressSpace(AddressSpace);
201 ObDereferenceObject(Process);
202 return(STATUS_UNSUCCESSFUL);
205 if (MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY)
207 Status = MmProtectAnonMem(AddressSpace, MemoryArea, BaseAddress,
208 NumberOfBytesToProtect, NewAccessProtection,
209 &OldAccessProtection);
211 else if (MemoryArea->Type == MEMORY_AREA_SECTION_VIEW)
213 Status = MmProtectSectionView(AddressSpace, MemoryArea, BaseAddress,
214 NumberOfBytesToProtect,
216 &OldAccessProtection);
219 MmUnlockAddressSpace(AddressSpace);
220 ObDereferenceObject(Process);
222 MmCopyToCaller(UnsafeOldAccessProtection, &OldAccessProtection,
229 NtReadVirtualMemory(IN HANDLE ProcessHandle,
230 IN PVOID BaseAddress,
232 IN ULONG NumberOfBytesToRead,
233 OUT PULONG NumberOfBytesRead)
240 DPRINT("NtReadVirtualMemory(ProcessHandle %x, BaseAddress %x, "
241 "Buffer %x, NumberOfBytesToRead %d)\n",ProcessHandle,BaseAddress,
242 Buffer,NumberOfBytesToRead);
244 Status = ObReferenceObjectByHandle(ProcessHandle,
250 if (Status != STATUS_SUCCESS)
255 Mdl = MmCreateMdl(NULL,
257 NumberOfBytesToRead);
258 MmProbeAndLockPages(Mdl,
262 KeAttachProcess(Process);
264 SystemAddress = MmGetSystemAddressForMdl(Mdl);
265 memcpy(SystemAddress, BaseAddress, NumberOfBytesToRead);
269 if (Mdl->MappedSystemVa != NULL)
271 MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
276 ObDereferenceObject(Process);
278 *NumberOfBytesRead = NumberOfBytesToRead;
279 return(STATUS_SUCCESS);
283 NtUnlockVirtualMemory(HANDLE ProcessHandle,
285 ULONG NumberOfBytesToUnlock,
286 PULONG NumberOfBytesUnlocked OPTIONAL)
293 NtWriteVirtualMemory(IN HANDLE ProcessHandle,
294 IN PVOID BaseAddress,
296 IN ULONG NumberOfBytesToWrite,
297 OUT PULONG NumberOfBytesWritten)
304 DPRINT("NtWriteVirtualMemory(ProcessHandle %x, BaseAddress %x, "
305 "Buffer %x, NumberOfBytesToWrite %d)\n",ProcessHandle,BaseAddress,
306 Buffer,NumberOfBytesToWrite);
308 Status = ObReferenceObjectByHandle(ProcessHandle,
314 if (Status != STATUS_SUCCESS)
319 Mdl = MmCreateMdl(NULL,
321 NumberOfBytesToWrite);
322 MmProbeAndLockPages(Mdl,
326 KeAttachProcess(Process);
328 SystemAddress = MmGetSystemAddressForMdl(Mdl);
329 memcpy(BaseAddress, SystemAddress, NumberOfBytesToWrite);
333 ObDereferenceObject(Process);
335 if (Mdl->MappedSystemVa != NULL)
337 MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
342 *NumberOfBytesWritten = NumberOfBytesToWrite;
344 return(STATUS_SUCCESS);
348 MmSecureVirtualMemory (DWORD Unknown0,
358 MmUnsecureVirtualMemory (DWORD Unknown0)