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