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 ObDereferenceObject(Process);
117 return(STATUS_INFO_LENGTH_MISMATCH);
120 if (MemoryArea == NULL)
122 Info->State = MEM_FREE;
123 Info->BaseAddress = (PVOID)PAGE_ROUND_DOWN(Address);
124 Status = STATUS_SUCCESS;
125 ResultLength = sizeof(MEMORY_BASIC_INFORMATION);
127 else if (MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY)
129 Status = MmQueryAnonMem(MemoryArea, Address, Info,
132 else if (MemoryArea->Type == MEMORY_AREA_SECTION_VIEW)
134 Status = MmQuerySectionView(MemoryArea, Address, Info,
139 Status = STATUS_UNSUCCESSFUL;
147 Status = STATUS_INVALID_INFO_CLASS;
153 MmUnlockAddressSpace(AddressSpace);
154 ObDereferenceObject(Process);
155 if (UnsafeResultLength != NULL)
157 MmCopyToCaller(UnsafeResultLength, &ResultLength, sizeof(ULONG));
163 NtProtectVirtualMemory(IN HANDLE ProcessHandle,
164 IN PVOID BaseAddress,
165 IN ULONG NumberOfBytesToProtect,
166 IN ULONG NewAccessProtection,
167 OUT PULONG UnsafeOldAccessProtection)
169 PMEMORY_AREA MemoryArea;
172 PMADDRESS_SPACE AddressSpace;
173 ULONG OldAccessProtection;
175 NumberOfBytesToProtect =
176 PAGE_ROUND_UP(BaseAddress + NumberOfBytesToProtect) -
177 PAGE_ROUND_DOWN(BaseAddress);
178 BaseAddress = (PVOID)PAGE_ROUND_DOWN(BaseAddress);
180 Status = ObReferenceObjectByHandle(ProcessHandle,
181 PROCESS_VM_OPERATION,
186 if (Status != STATUS_SUCCESS)
188 DPRINT("NtProtectVirtualMemory() = %x\n",Status);
192 AddressSpace = &Process->AddressSpace;
194 MmLockAddressSpace(AddressSpace);
195 MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace,
197 if (MemoryArea == NULL)
199 MmUnlockAddressSpace(AddressSpace);
200 ObDereferenceObject(Process);
201 return(STATUS_UNSUCCESSFUL);
204 if (MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY)
206 Status = MmProtectAnonMem(AddressSpace, MemoryArea, BaseAddress,
207 NumberOfBytesToProtect, NewAccessProtection,
208 &OldAccessProtection);
210 else if (MemoryArea->Type == MEMORY_AREA_SECTION_VIEW)
212 Status = MmProtectSectionView(AddressSpace, MemoryArea, BaseAddress,
213 NumberOfBytesToProtect,
215 &OldAccessProtection);
218 MmUnlockAddressSpace(AddressSpace);
219 ObDereferenceObject(Process);
221 MmCopyToCaller(UnsafeOldAccessProtection, &OldAccessProtection,
228 NtReadVirtualMemory(IN HANDLE ProcessHandle,
229 IN PVOID BaseAddress,
231 IN ULONG NumberOfBytesToRead,
232 OUT PULONG NumberOfBytesRead)
239 DPRINT("NtReadVirtualMemory(ProcessHandle %x, BaseAddress %x, "
240 "Buffer %x, NumberOfBytesToRead %d)\n",ProcessHandle,BaseAddress,
241 Buffer,NumberOfBytesToRead);
243 Status = ObReferenceObjectByHandle(ProcessHandle,
249 if (Status != STATUS_SUCCESS)
254 Mdl = MmCreateMdl(NULL,
256 NumberOfBytesToRead);
257 MmProbeAndLockPages(Mdl,
261 KeAttachProcess(Process);
263 SystemAddress = MmGetSystemAddressForMdl(Mdl);
264 memcpy(SystemAddress, BaseAddress, NumberOfBytesToRead);
268 if (Mdl->MappedSystemVa != NULL)
270 MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
275 ObDereferenceObject(Process);
277 *NumberOfBytesRead = NumberOfBytesToRead;
278 return(STATUS_SUCCESS);
282 NtUnlockVirtualMemory(HANDLE ProcessHandle,
284 ULONG NumberOfBytesToUnlock,
285 PULONG NumberOfBytesUnlocked OPTIONAL)
292 NtWriteVirtualMemory(IN HANDLE ProcessHandle,
293 IN PVOID BaseAddress,
295 IN ULONG NumberOfBytesToWrite,
296 OUT PULONG NumberOfBytesWritten)
303 DPRINT("NtWriteVirtualMemory(ProcessHandle %x, BaseAddress %x, "
304 "Buffer %x, NumberOfBytesToWrite %d)\n",ProcessHandle,BaseAddress,
305 Buffer,NumberOfBytesToWrite);
307 Status = ObReferenceObjectByHandle(ProcessHandle,
313 if (Status != STATUS_SUCCESS)
318 Mdl = MmCreateMdl(NULL,
320 NumberOfBytesToWrite);
321 MmProbeAndLockPages(Mdl,
325 KeAttachProcess(Process);
327 SystemAddress = MmGetSystemAddressForMdl(Mdl);
328 memcpy(BaseAddress, SystemAddress, NumberOfBytesToWrite);
332 ObDereferenceObject(Process);
334 if (Mdl->MappedSystemVa != NULL)
336 MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
341 *NumberOfBytesWritten = NumberOfBytesToWrite;
343 return(STATUS_SUCCESS);
347 MmSecureVirtualMemory (DWORD Unknown0,
357 MmUnsecureVirtualMemory (DWORD Unknown0)