ReactOS  0.4.10-dev-486-g11b7619
virtmem.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Win32 Base API
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: dll/win32/kernel32/client/virtmem.c
5  * PURPOSE: Handles virtual memory APIs
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include <k32.h>
12 
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* FUNCTIONS ******************************************************************/
17 
18 /*
19  * @implemented
20  */
21 LPVOID
22 NTAPI
24  IN LPVOID lpAddress,
26  IN DWORD flAllocationType,
27  IN DWORD flProtect)
28 {
30 
31  /* Make sure the address is within the granularity of the system (64K) */
32  if ((lpAddress != NULL) &&
34  {
35  /* Fail the call */
37  return NULL;
38  }
39 
40  /* Handle any possible exceptions */
41  _SEH2_TRY
42  {
43  /* Allocate the memory */
44  Status = NtAllocateVirtualMemory(hProcess,
45  &lpAddress,
46  0,
47  &dwSize,
48  flAllocationType,
49  flProtect);
50  }
52  {
53  Status = _SEH2_GetExceptionCode();
54  }
55  _SEH2_END;
56 
57  /* Check for status */
58  if (!NT_SUCCESS(Status))
59  {
60  /* We failed */
61  BaseSetLastNTError(Status);
62  return NULL;
63  }
64 
65  /* Return the allocated address */
66  return lpAddress;
67 }
68 
69 /*
70  * @implemented
71  */
72 LPVOID
73 NTAPI
76  IN DWORD flAllocationType,
77  IN DWORD flProtect)
78 {
79  /* Call the extended API */
81  lpAddress,
82  dwSize,
83  flAllocationType,
84  flProtect);
85 }
86 
87 /*
88  * @implemented
89  */
90 BOOL
91 NTAPI
93  IN LPVOID lpAddress,
95  IN DWORD dwFreeType)
96 {
98 
99  /* Validate size and flags */
100  if (!(dwSize) || !(dwFreeType & MEM_RELEASE))
101  {
102  /* Free the memory */
103  Status = NtFreeVirtualMemory(hProcess,
104  &lpAddress,
105  &dwSize,
106  dwFreeType);
107  if (!NT_SUCCESS(Status))
108  {
109  /* We failed */
110  BaseSetLastNTError(Status);
111  return FALSE;
112  }
113 
114  /* Return success */
115  return TRUE;
116  }
117 
118  /* Invalid combo */
120  return FALSE;
121 }
122 
123 /*
124  * @implemented
125  */
126 BOOL
127 NTAPI
129  IN SIZE_T dwSize,
130  IN DWORD dwFreeType)
131 {
132  /* Call the extended API */
134  lpAddress,
135  dwSize,
136  dwFreeType);
137 }
138 
139 /*
140  * @implemented
141  */
142 BOOL
143 NTAPI
145  IN SIZE_T dwSize,
146  IN DWORD flNewProtect,
147  OUT PDWORD lpflOldProtect)
148 {
149  /* Call the extended API */
151  lpAddress,
152  dwSize,
153  flNewProtect,
154  lpflOldProtect);
155 }
156 
157 /*
158  * @implemented
159  */
160 BOOL
161 NTAPI
163  IN LPVOID lpAddress,
164  IN SIZE_T dwSize,
165  IN DWORD flNewProtect,
166  OUT PDWORD lpflOldProtect)
167 {
169 
170  /* Change the protection */
171  Status = NtProtectVirtualMemory(hProcess,
172  &lpAddress,
173  &dwSize,
174  flNewProtect,
175  (PULONG)lpflOldProtect);
176  if (!NT_SUCCESS(Status))
177  {
178  /* We failed */
179  BaseSetLastNTError(Status);
180  return FALSE;
181  }
182 
183  /* Return success */
184  return TRUE;
185 }
186 
187 /*
188  * @implemented
189  */
190 BOOL
191 NTAPI
193  IN SIZE_T dwSize)
194 {
197  PVOID BaseAddress = lpAddress;
198 
199  /* Lock the memory */
201  &BaseAddress,
202  &RegionSize,
203  MAP_PROCESS);
204  if (!NT_SUCCESS(Status))
205  {
206  /* We failed */
207  BaseSetLastNTError(Status);
208  return FALSE;
209  }
210 
211  /* Return success */
212  return TRUE;
213 }
214 
215 /*
216  * @implemented
217  */
218 SIZE_T
219 NTAPI
223 {
224  /* Call the extended API */
226  lpAddress,
227  lpBuffer,
228  dwLength);
229 }
230 
231 /*
232  * @implemented
233  */
234 SIZE_T
235 NTAPI
237  IN LPCVOID lpAddress,
240 {
243 
244  /* Query basic information */
245  Status = NtQueryVirtualMemory(hProcess,
246  (LPVOID)lpAddress,
248  lpBuffer,
249  dwLength,
250  &ResultLength);
251  if (!NT_SUCCESS(Status))
252  {
253  /* We failed */
254  BaseSetLastNTError(Status);
255  return 0;
256  }
257 
258  /* Return the length returned */
259  return ResultLength;
260 }
261 
262 /*
263  * @implemented
264  */
265 BOOL
266 NTAPI
268  IN SIZE_T dwSize)
269 {
272  PVOID BaseAddress = lpAddress;
273 
274  /* Lock the memory */
276  &BaseAddress,
277  &RegionSize,
278  MAP_PROCESS);
279  if (!NT_SUCCESS(Status))
280  {
281  /* We failed */
282  BaseSetLastNTError(Status);
283  return FALSE;
284  }
285 
286  /* Return success */
287  return TRUE;
288 }
289 
290 /*
291  * @implemented
292  */
293 UINT
294 WINAPI
296  IN PVOID lpBaseAddress,
297  IN SIZE_T dwRegionSize,
298  IN PVOID *lpAddresses,
299  OUT PULONG_PTR lpdwCount,
300  OUT PULONG lpdwGranularity)
301 {
303 
305  dwFlags,
306  lpBaseAddress,
307  dwRegionSize,
308  lpAddresses,
309  lpdwCount,
310  lpdwGranularity);
311  if (!NT_SUCCESS(Status))
312  {
313  BaseSetLastNTError(Status);
314  return -1;
315  }
316 
317  return 0;
318 }
319 
320 /*
321  * @implemented
322  */
323 UINT
324 WINAPI
325 ResetWriteWatch(IN LPVOID lpBaseAddress,
326  IN SIZE_T dwRegionSize)
327 {
329 
331  lpBaseAddress,
332  dwRegionSize);
333  if (!NT_SUCCESS(Status))
334  {
335  BaseSetLastNTError(Status);
336  return -1;
337  }
338 
339  return 0;
340 }
341 
342 /*
343  * @implemented
344  */
345 BOOL
346 WINAPI
348  IN PULONG_PTR NumberOfPages,
349  OUT PULONG_PTR UserPfnArray)
350 {
352 
353  Status = NtAllocateUserPhysicalPages(hProcess, NumberOfPages, UserPfnArray);
354  if (!NT_SUCCESS(Status))
355  {
356  BaseSetLastNTError(Status);
357  return FALSE;
358  }
359 
360  return TRUE;
361 }
362 
363 /*
364  * @implemented
365  */
366 BOOL
367 WINAPI
369  IN PULONG_PTR NumberOfPages,
370  IN PULONG_PTR PageArray)
371 {
373 
374  Status = NtFreeUserPhysicalPages(hProcess, NumberOfPages, PageArray);
375  if (!NT_SUCCESS(Status))
376  {
377  BaseSetLastNTError(Status);
378  return FALSE;
379  }
380 
381  return TRUE;
382 }
383 
384 /*
385  * @implemented
386  */
387 BOOL
388 WINAPI
390  IN ULONG_PTR NumberOfPages,
391  OUT PULONG_PTR PageArray OPTIONAL)
392 {
394 
395  Status = NtMapUserPhysicalPages(VirtualAddress, NumberOfPages, PageArray);
396  if (!NT_SUCCESS(Status))
397  {
398  BaseSetLastNTError(Status);
399  return FALSE;
400  }
401 
402  return TRUE;
403 }
404 
405 /*
406  * @implemented
407  */
408 BOOL
409 WINAPI
411  IN ULONG_PTR NumberOfPages,
412  OUT PULONG_PTR PageArray OPTIONAL)
413 {
415 
416  Status = NtMapUserPhysicalPagesScatter(VirtualAddresses,
417  NumberOfPages,
418  PageArray);
419  if (!NT_SUCCESS(Status))
420  {
421  BaseSetLastNTError(Status);
422  return FALSE;
423  }
424 
425  return TRUE;
426 }
427 
428 /* EOF */
DWORD *typedef PVOID
Definition: winlogon.h:60
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
BOOL WINAPI AllocateUserPhysicalPages(IN HANDLE hProcess, IN PULONG_PTR NumberOfPages, OUT PULONG_PTR UserPfnArray)
Definition: virtmem.c:347
PBASE_STATIC_SERVER_DATA BaseStaticServerData
Definition: dllmain.c:19
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
BOOL NTAPI VirtualLock(IN LPVOID lpAddress, IN SIZE_T dwSize)
Definition: virtmem.c:192
NTSTATUS NTAPI NtProtectVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID *UnsafeBaseAddress, IN OUT SIZE_T *UnsafeNumberOfBytesToProtect, IN ULONG NewAccessProtection, OUT PULONG UnsafeOldAccessProtection)
Definition: virtual.c:2986
BOOL WINAPI MapUserPhysicalPagesScatter(IN PVOID *VirtualAddresses, IN ULONG_PTR NumberOfPages, OUT PULONG_PTR PageArray OPTIONAL)
Definition: virtmem.c:410
NTSTATUS NTAPI NtMapUserPhysicalPagesScatter(IN PVOID *VirtualAddresses, IN ULONG_PTR NumberOfPages, IN OUT PULONG_PTR UserPfnArray)
Definition: procsup.c:1416
LPVOID NTAPI VirtualAllocEx(IN HANDLE hProcess, IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flAllocationType, IN DWORD flProtect)
Definition: virtmem.c:23
NTSTATUS NTAPI NtQueryVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN MEMORY_INFORMATION_CLASS MemoryInformationClass, OUT PVOID MemoryInformation, IN SIZE_T MemoryInformationLength, OUT PSIZE_T ReturnLength)
Definition: virtual.c:4284
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
NTSTATUS NTAPI NtFreeUserPhysicalPages(IN HANDLE ProcessHandle, IN OUT PULONG_PTR NumberOfPages, IN OUT PULONG_PTR UserPfnArray)
Definition: procsup.c:1426
NTSTATUS NTAPI NtResetWriteWatch(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN SIZE_T RegionSize)
Definition: virtual.c:4203
DWORD DWORD
Definition: winlogon.h:83
NTSTATUS NTAPI NtLockVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID *BaseAddress, IN OUT PSIZE_T NumberOfBytesToLock, IN ULONG MapType)
Definition: virtual.c:3404
_SEH2_TRY
Definition: create.c:4250
uint32_t ULONG_PTR
Definition: typedefs.h:63
LPVOID NTAPI VirtualAlloc(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flAllocationType, IN DWORD flProtect)
Definition: virtmem.c:74
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
BOOL NTAPI VirtualUnlock(IN LPVOID lpAddress, IN SIZE_T dwSize)
Definition: virtmem.c:267
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:163
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
NTSTATUS NTAPI NtAllocateUserPhysicalPages(IN HANDLE ProcessHandle, IN OUT PULONG_PTR NumberOfPages, IN OUT PULONG_PTR UserPfnArray)
Definition: procsup.c:1396
#define NtCurrentProcess()
Definition: nt_native.h:1657
SYSTEM_BASIC_INFORMATION SysInfo
Definition: base.h:122
SIZE_T NTAPI VirtualQueryEx(IN HANDLE hProcess, IN LPCVOID lpAddress, OUT PMEMORY_BASIC_INFORMATION lpBuffer, IN SIZE_T dwLength)
Definition: virtmem.c:236
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define UlongToPtr(ul)
Definition: basetsd.h:98
unsigned int BOOL
Definition: ntddk_ex.h:94
LONG NTSTATUS
Definition: precomp.h:26
static DWORD DWORD * dwLength
Definition: fusion.c:83
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
HANDLE WINAPI GetCurrentProcess(VOID)
Definition: proc.c:1195
BOOL NTAPI VirtualFreeEx(IN HANDLE hProcess, IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD dwFreeType)
Definition: virtmem.c:92
SIZE_T NTAPI VirtualQuery(IN LPCVOID lpAddress, OUT PMEMORY_BASIC_INFORMATION lpBuffer, IN SIZE_T dwLength)
Definition: virtmem.c:220
BOOL NTAPI VirtualProtect(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flNewProtect, OUT PDWORD lpflOldProtect)
Definition: virtmem.c:144
#define SetLastError(x)
Definition: compat.h:409
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
UINT WINAPI GetWriteWatch(IN DWORD dwFlags, IN PVOID lpBaseAddress, IN SIZE_T dwRegionSize, IN PVOID *lpAddresses, OUT PULONG_PTR lpdwCount, OUT PULONG lpdwGranularity)
Definition: virtmem.c:295
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3773
#define WINAPI
Definition: msvc.h:20
Status
Definition: gdiplustypes.h:24
BOOL NTAPI VirtualProtectEx(IN HANDLE hProcess, IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flNewProtect, OUT PDWORD lpflOldProtect)
Definition: virtmem.c:162
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define MAP_PROCESS
Definition: mmtypes.h:67
DWORD *typedef HANDLE
Definition: winlogon.h:60
_SEH2_END
Definition: create.c:4424
NTSTATUS NTAPI NtAllocateVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID *UBaseAddress, IN ULONG_PTR ZeroBits, IN OUT PSIZE_T URegionSize, IN ULONG AllocationType, IN ULONG Protect)
Definition: virtual.c:4367
NTSTATUS NTAPI NtGetWriteWatch(IN HANDLE ProcessHandle, IN ULONG Flags, IN PVOID BaseAddress, IN SIZE_T RegionSize, IN PVOID *UserAddressArray, OUT PULONG_PTR EntriesInUserAddressArray, OUT PULONG Granularity)
Definition: virtual.c:4032
NTSTATUS NTAPI NtMapUserPhysicalPages(IN PVOID VirtualAddresses, IN ULONG_PTR NumberOfPages, IN OUT PULONG_PTR UserPfnArray)
Definition: procsup.c:1406
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:172
NTSTATUS NTAPI NtUnlockVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID *BaseAddress, IN OUT PSIZE_T NumberOfBytesToUnlock, IN ULONG MapType)
Definition: virtual.c:3740
unsigned int * PULONG
Definition: retypes.h:1
unsigned int UINT
Definition: ndis.h:50
DWORD * PDWORD
Definition: pedump.c:68
CONST void * LPCVOID
Definition: windef.h:191
#define MEM_RELEASE
Definition: nt_native.h:1316
#define OUT
Definition: typedefs.h:39
BOOL WINAPI MapUserPhysicalPages(IN PVOID VirtualAddress, IN ULONG_PTR NumberOfPages, OUT PULONG_PTR PageArray OPTIONAL)
Definition: virtmem.c:389
uint32_t * PULONG_PTR
Definition: typedefs.h:63
BOOL NTAPI VirtualFree(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD dwFreeType)
Definition: virtmem.c:128
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
BOOL WINAPI FreeUserPhysicalPages(IN HANDLE hProcess, IN PULONG_PTR NumberOfPages, IN PULONG_PTR PageArray)
Definition: virtmem.c:368
UINT WINAPI ResetWriteWatch(IN LPVOID lpBaseAddress, IN SIZE_T dwRegionSize)
Definition: virtmem.c:325
IN HDEVINFO IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
Definition: devinst.c:44
NTSTATUS NTAPI NtFreeVirtualMemory(IN HANDLE ProcessHandle, IN PVOID *UBaseAddress, IN PSIZE_T URegionSize, IN ULONG FreeType)
Definition: virtual.c:5090
DWORD dwSize
Definition: wglext.h:734