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