xref: /reactos/dll/win32/kernel32/client/virtmem.c (revision df7ab5d8)
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
VirtualAllocEx(IN HANDLE hProcess,IN LPVOID lpAddress,IN SIZE_T dwSize,IN DWORD flAllocationType,IN DWORD flProtect)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     /* Allocate the memory */
41     Status = NtAllocateVirtualMemory(hProcess,
42                                      &lpAddress,
43                                      0,
44                                      &dwSize,
45                                      flAllocationType,
46                                      flProtect);
47 
48     /* Check for status */
49     if (!NT_SUCCESS(Status))
50     {
51         /* We failed */
52         BaseSetLastNTError(Status);
53         return NULL;
54     }
55 
56     /* Return the allocated address */
57     return lpAddress;
58 }
59 
60 /*
61  * @implemented
62  */
63 LPVOID
64 NTAPI
VirtualAlloc(IN LPVOID lpAddress,IN SIZE_T dwSize,IN DWORD flAllocationType,IN DWORD flProtect)65 VirtualAlloc(IN LPVOID lpAddress,
66              IN SIZE_T dwSize,
67              IN DWORD flAllocationType,
68              IN DWORD flProtect)
69 {
70     /* Call the extended API */
71     return VirtualAllocEx(GetCurrentProcess(),
72                           lpAddress,
73                           dwSize,
74                           flAllocationType,
75                           flProtect);
76 }
77 
78 /*
79  * @implemented
80  */
81 BOOL
82 NTAPI
VirtualFreeEx(IN HANDLE hProcess,IN LPVOID lpAddress,IN SIZE_T dwSize,IN DWORD dwFreeType)83 VirtualFreeEx(IN HANDLE hProcess,
84               IN LPVOID lpAddress,
85               IN SIZE_T dwSize,
86               IN DWORD dwFreeType)
87 {
88     NTSTATUS Status;
89 
90     /* Validate size and flags */
91     if (!(dwSize) || !(dwFreeType & MEM_RELEASE))
92     {
93         /* Free the memory */
94         Status = NtFreeVirtualMemory(hProcess,
95                                      &lpAddress,
96                                      &dwSize,
97                                      dwFreeType);
98         if (!NT_SUCCESS(Status))
99         {
100             /* We failed */
101             BaseSetLastNTError(Status);
102             return FALSE;
103         }
104 
105         /* Return success */
106         return TRUE;
107     }
108 
109     /* Invalid combo */
110     BaseSetLastNTError(STATUS_INVALID_PARAMETER);
111     return FALSE;
112 }
113 
114 /*
115  * @implemented
116  */
117 BOOL
118 NTAPI
VirtualFree(IN LPVOID lpAddress,IN SIZE_T dwSize,IN DWORD dwFreeType)119 VirtualFree(IN LPVOID lpAddress,
120             IN SIZE_T dwSize,
121             IN DWORD dwFreeType)
122 {
123     /* Call the extended API */
124     return VirtualFreeEx(GetCurrentProcess(),
125                          lpAddress,
126                          dwSize,
127                          dwFreeType);
128 }
129 
130 /*
131  * @implemented
132  */
133 BOOL
134 NTAPI
VirtualProtect(IN LPVOID lpAddress,IN SIZE_T dwSize,IN DWORD flNewProtect,OUT PDWORD lpflOldProtect)135 VirtualProtect(IN LPVOID lpAddress,
136                IN SIZE_T dwSize,
137                IN DWORD flNewProtect,
138                OUT PDWORD lpflOldProtect)
139 {
140     /* Call the extended API */
141     return VirtualProtectEx(GetCurrentProcess(),
142                             lpAddress,
143                             dwSize,
144                             flNewProtect,
145                             lpflOldProtect);
146 }
147 
148 /*
149  * @implemented
150  */
151 BOOL
152 NTAPI
VirtualProtectEx(IN HANDLE hProcess,IN LPVOID lpAddress,IN SIZE_T dwSize,IN DWORD flNewProtect,OUT PDWORD lpflOldProtect)153 VirtualProtectEx(IN HANDLE hProcess,
154                  IN LPVOID lpAddress,
155                  IN SIZE_T dwSize,
156                  IN DWORD flNewProtect,
157                  OUT PDWORD lpflOldProtect)
158 {
159     NTSTATUS Status;
160 
161     /* Change the protection */
162     Status = NtProtectVirtualMemory(hProcess,
163                                     &lpAddress,
164                                     &dwSize,
165                                     flNewProtect,
166                                     (PULONG)lpflOldProtect);
167     if (!NT_SUCCESS(Status))
168     {
169         /* We failed */
170         BaseSetLastNTError(Status);
171         return FALSE;
172     }
173 
174     /* Return success */
175     return TRUE;
176 }
177 
178 /*
179  * @implemented
180  */
181 BOOL
182 NTAPI
VirtualLock(IN LPVOID lpAddress,IN SIZE_T dwSize)183 VirtualLock(IN LPVOID lpAddress,
184             IN SIZE_T dwSize)
185 {
186     NTSTATUS Status;
187     SIZE_T RegionSize = dwSize;
188     PVOID BaseAddress = lpAddress;
189 
190     /* Lock the memory */
191     Status = NtLockVirtualMemory(NtCurrentProcess(),
192                                  &BaseAddress,
193                                  &RegionSize,
194                                  MAP_PROCESS);
195     if (!NT_SUCCESS(Status))
196     {
197         /* We failed */
198         BaseSetLastNTError(Status);
199         return FALSE;
200     }
201 
202     /* Return success */
203     return TRUE;
204 }
205 
206 /*
207  * @implemented
208  */
209 SIZE_T
210 NTAPI
VirtualQuery(IN LPCVOID lpAddress,OUT PMEMORY_BASIC_INFORMATION lpBuffer,IN SIZE_T dwLength)211 VirtualQuery(IN LPCVOID lpAddress,
212              OUT PMEMORY_BASIC_INFORMATION lpBuffer,
213              IN SIZE_T dwLength)
214 {
215     /* Call the extended API */
216     return VirtualQueryEx(NtCurrentProcess(),
217                           lpAddress,
218                           lpBuffer,
219                           dwLength);
220 }
221 
222 /*
223  * @implemented
224  */
225 SIZE_T
226 NTAPI
VirtualQueryEx(IN HANDLE hProcess,IN LPCVOID lpAddress,OUT PMEMORY_BASIC_INFORMATION lpBuffer,IN SIZE_T dwLength)227 VirtualQueryEx(IN HANDLE hProcess,
228                IN LPCVOID lpAddress,
229                OUT PMEMORY_BASIC_INFORMATION lpBuffer,
230                IN SIZE_T dwLength)
231 {
232     NTSTATUS Status;
233     SIZE_T ResultLength;
234 
235     /* Query basic information */
236     Status = NtQueryVirtualMemory(hProcess,
237                                   (LPVOID)lpAddress,
238                                   MemoryBasicInformation,
239                                   lpBuffer,
240                                   dwLength,
241                                   &ResultLength);
242     if (!NT_SUCCESS(Status))
243     {
244         /* We failed */
245         BaseSetLastNTError(Status);
246         return 0;
247     }
248 
249     /* Return the length returned */
250     return ResultLength;
251 }
252 
253 /*
254  * @implemented
255  */
256 BOOL
257 NTAPI
VirtualUnlock(IN LPVOID lpAddress,IN SIZE_T dwSize)258 VirtualUnlock(IN LPVOID lpAddress,
259               IN SIZE_T dwSize)
260 {
261     NTSTATUS Status;
262     SIZE_T RegionSize = dwSize;
263     PVOID BaseAddress = lpAddress;
264 
265     /* Lock the memory */
266     Status = NtUnlockVirtualMemory(NtCurrentProcess(),
267                                    &BaseAddress,
268                                    &RegionSize,
269                                    MAP_PROCESS);
270     if (!NT_SUCCESS(Status))
271     {
272         /* We failed */
273         BaseSetLastNTError(Status);
274         return FALSE;
275     }
276 
277     /* Return success */
278     return TRUE;
279 }
280 
281 /*
282  * @implemented
283  */
284 UINT
285 WINAPI
GetWriteWatch(IN DWORD dwFlags,IN PVOID lpBaseAddress,IN SIZE_T dwRegionSize,IN PVOID * lpAddresses,OUT PULONG_PTR lpdwCount,OUT PULONG lpdwGranularity)286 GetWriteWatch(IN DWORD dwFlags,
287               IN PVOID lpBaseAddress,
288               IN SIZE_T dwRegionSize,
289               IN PVOID *lpAddresses,
290               OUT PULONG_PTR lpdwCount,
291               OUT PULONG lpdwGranularity)
292 {
293     NTSTATUS Status;
294 
295     Status = NtGetWriteWatch(GetCurrentProcess(),
296                              dwFlags,
297                              lpBaseAddress,
298                              dwRegionSize,
299                              lpAddresses,
300                              lpdwCount,
301                              lpdwGranularity);
302     if (!NT_SUCCESS(Status))
303     {
304         BaseSetLastNTError(Status);
305         return -1;
306     }
307 
308     return 0;
309 }
310 
311 /*
312  * @implemented
313  */
314 UINT
315 WINAPI
ResetWriteWatch(IN LPVOID lpBaseAddress,IN SIZE_T dwRegionSize)316 ResetWriteWatch(IN LPVOID lpBaseAddress,
317                 IN SIZE_T dwRegionSize)
318 {
319     NTSTATUS Status;
320 
321     Status = NtResetWriteWatch(NtCurrentProcess(),
322                                lpBaseAddress,
323                                dwRegionSize);
324     if (!NT_SUCCESS(Status))
325     {
326         BaseSetLastNTError(Status);
327         return -1;
328     }
329 
330     return 0;
331 }
332 
333 /*
334  * @implemented
335  */
336 BOOL
337 WINAPI
AllocateUserPhysicalPages(IN HANDLE hProcess,IN PULONG_PTR NumberOfPages,OUT PULONG_PTR UserPfnArray)338 AllocateUserPhysicalPages(IN HANDLE hProcess,
339                           IN PULONG_PTR NumberOfPages,
340                           OUT PULONG_PTR UserPfnArray)
341 {
342     NTSTATUS Status;
343 
344     Status = NtAllocateUserPhysicalPages(hProcess, NumberOfPages, UserPfnArray);
345     if (!NT_SUCCESS(Status))
346     {
347         BaseSetLastNTError(Status);
348         return FALSE;
349     }
350 
351     return TRUE;
352 }
353 
354 /*
355  * @implemented
356  */
357 BOOL
358 WINAPI
FreeUserPhysicalPages(IN HANDLE hProcess,IN PULONG_PTR NumberOfPages,IN PULONG_PTR PageArray)359 FreeUserPhysicalPages(IN HANDLE hProcess,
360                       IN PULONG_PTR NumberOfPages,
361                       IN PULONG_PTR PageArray)
362 {
363     NTSTATUS Status;
364 
365     Status = NtFreeUserPhysicalPages(hProcess, NumberOfPages, PageArray);
366     if (!NT_SUCCESS(Status))
367     {
368         BaseSetLastNTError(Status);
369         return FALSE;
370     }
371 
372     return TRUE;
373 }
374 
375 /*
376  * @implemented
377  */
378 BOOL
379 WINAPI
MapUserPhysicalPages(IN PVOID VirtualAddress,IN ULONG_PTR NumberOfPages,OUT PULONG_PTR PageArray OPTIONAL)380 MapUserPhysicalPages(IN PVOID VirtualAddress,
381                      IN ULONG_PTR NumberOfPages,
382                      OUT PULONG_PTR PageArray OPTIONAL)
383 {
384     NTSTATUS Status;
385 
386     Status = NtMapUserPhysicalPages(VirtualAddress, NumberOfPages, PageArray);
387     if (!NT_SUCCESS(Status))
388     {
389         BaseSetLastNTError(Status);
390         return FALSE;
391     }
392 
393     return TRUE;
394 }
395 
396 /*
397  * @implemented
398  */
399 BOOL
400 WINAPI
MapUserPhysicalPagesScatter(IN PVOID * VirtualAddresses,IN ULONG_PTR NumberOfPages,OUT PULONG_PTR PageArray OPTIONAL)401 MapUserPhysicalPagesScatter(IN PVOID *VirtualAddresses,
402                             IN ULONG_PTR NumberOfPages,
403                             OUT PULONG_PTR PageArray OPTIONAL)
404 {
405     NTSTATUS Status;
406 
407     Status = NtMapUserPhysicalPagesScatter(VirtualAddresses,
408                                            NumberOfPages,
409                                            PageArray);
410     if (!NT_SUCCESS(Status))
411     {
412         BaseSetLastNTError(Status);
413         return FALSE;
414     }
415 
416     return TRUE;
417 }
418 
419 /* EOF */
420