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