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.64 2002/09/08 10:23:37 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 *****************************************************************/
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
)