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