xref: /reactos/dll/win32/kernel32/client/virtmem.c (revision 8a978a17)
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
23 VirtualAllocEx(IN HANDLE hProcess,
24                IN LPVOID lpAddress,
25                IN SIZE_T dwSize,
26                IN DWORD flAllocationType,
27                IN DWORD flProtect)
28 {
29     NTSTATUS Status;
30 
31     /* Make sure the address is within the granularity of the system (64K) */
32     if ((lpAddress != NULL) &&
33         (lpAddress < UlongToPtr(BaseStaticServerData->SysInfo.AllocationGranularity)))
34     {
35         /* Fail the call */
36         SetLastError(ERROR_INVALID_PARAMETER);
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     }
51     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
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
74 VirtualAlloc(IN LPVOID lpAddress,
75              IN SIZE_T dwSize,
76              IN DWORD flAllocationType,
77              IN DWORD flProtect)
78 {
79     /* Call the extended API */
80     return VirtualAllocEx(GetCurrentProcess(),
81                           lpAddress,
82                           dwSize,
83                           flAllocationType,
84                           flProtect);
85 }
86 
87 /*
88  * @implemented
89  */
90 BOOL
91 NTAPI
92 VirtualFreeEx(IN HANDLE hProcess,
93               IN LPVOID lpAddress,
94               IN SIZE_T dwSize,
95               IN DWORD dwFreeType)
96 {
97     NTSTATUS Status;
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 */
119     BaseSetLastNTError(STATUS_INVALID_PARAMETER);
120     return FALSE;
121 }
122 
123 /*
124  * @implemented
125  */
126 BOOL
127 NTAPI
128 VirtualFree(IN LPVOID lpAddress,
129             IN SIZE_T dwSize,
130             IN DWORD dwFreeType)
131 {
132     /* Call the extended API */
133     return VirtualFreeEx(GetCurrentProcess(),
134                          lpAddress,
135                          dwSize,
136                          dwFreeType);
137 }
138 
139 /*
140  * @implemented
141  */
142 BOOL
143 NTAPI
144 VirtualProtect(IN LPVOID lpAddress,
145                IN SIZE_T dwSize,
146                IN DWORD flNewProtect,
147                OUT PDWORD lpflOldProtect)
148 {
149     /* Call the extended API */
150     return VirtualProtectEx(GetCurrentProcess(),
151                             lpAddress,
152                             dwSize,
153                             flNewProtect,
154                             lpflOldProtect);
155 }
156 
157 /*
158  * @implemented
159  */
160 BOOL
161 NTAPI
162 VirtualProtectEx(IN HANDLE hProcess,
163                  IN LPVOID lpAddress,
164                  IN SIZE_T dwSize,
165                  IN DWORD flNewProtect,
166                  OUT PDWORD lpflOldProtect)
167 {
168     NTSTATUS Status;
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
192 VirtualLock(IN LPVOID lpAddress,
193             IN SIZE_T dwSize)
194 {
195     NTSTATUS Status;
196     SIZE_T RegionSize = dwSize;
197     PVOID BaseAddress = lpAddress;
198 
199     /* Lock the memory */
200     Status = NtLockVirtualMemory(NtCurrentProcess(),
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
220 VirtualQuery(IN LPCVOID lpAddress,
221              OUT PMEMORY_BASIC_INFORMATION lpBuffer,
222              IN SIZE_T dwLength)
223 {
224     /* Call the extended API */
225     return VirtualQueryEx(NtCurrentProcess(),
226                           lpAddress,
227                           lpBuffer,
228                           dwLength);
229 }
230 
231 /*
232  * @implemented
233  */
234 SIZE_T
235 NTAPI
236 VirtualQueryEx(IN HANDLE hProcess,
237                IN LPCVOID lpAddress,
238                OUT PMEMORY_BASIC_INFORMATION lpBuffer,
239                IN SIZE_T dwLength)
240 {
241     NTSTATUS Status;
242     SIZE_T ResultLength;
243 
244     /* Query basic information */
245     Status = NtQueryVirtualMemory(hProcess,
246                                   (LPVOID)lpAddress,
247                                   MemoryBasicInformation,
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
267 VirtualUnlock(IN LPVOID lpAddress,
268               IN SIZE_T dwSize)
269 {
270     NTSTATUS Status;
271     SIZE_T RegionSize = dwSize;
272     PVOID BaseAddress = lpAddress;
273 
274     /* Lock the memory */
275     Status = NtUnlockVirtualMemory(NtCurrentProcess(),
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
295 GetWriteWatch(IN DWORD dwFlags,
296               IN PVOID lpBaseAddress,
297               IN SIZE_T dwRegionSize,
298               IN PVOID *lpAddresses,
299               OUT PULONG_PTR lpdwCount,
300               OUT PULONG lpdwGranularity)
301 {
302     NTSTATUS Status;
303 
304     Status = NtGetWriteWatch(GetCurrentProcess(),
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 {
328     NTSTATUS Status;
329 
330     Status = NtResetWriteWatch(NtCurrentProcess(),
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
347 AllocateUserPhysicalPages(IN HANDLE hProcess,
348                           IN PULONG_PTR NumberOfPages,
349                           OUT PULONG_PTR UserPfnArray)
350 {
351     NTSTATUS Status;
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
368 FreeUserPhysicalPages(IN HANDLE hProcess,
369                       IN PULONG_PTR NumberOfPages,
370                       IN PULONG_PTR PageArray)
371 {
372     NTSTATUS Status;
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
389 MapUserPhysicalPages(IN PVOID VirtualAddress,
390                      IN ULONG_PTR NumberOfPages,
391                      OUT PULONG_PTR PageArray OPTIONAL)
392 {
393     NTSTATUS Status;
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
410 MapUserPhysicalPagesScatter(IN PVOID *VirtualAddresses,
411                             IN ULONG_PTR NumberOfPages,
412                             OUT PULONG_PTR PageArray OPTIONAL)
413 {
414     NTSTATUS Status;
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 */
429