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 /* 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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