It improves rendering performance in V-Ray.
From: Piotr Caban piotr@codeweavers.com
--- dlls/ntdll/unix/virtual.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 0d88315164a..ef206d58652 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -6025,7 +6025,26 @@ NTSTATUS WINAPI NtReadVirtualMemory( HANDLE process, const void *addr, void *buf { unsigned int status;
- if (virtual_check_buffer_for_write( buffer, size )) + if (!virtual_check_buffer_for_write( buffer, size )) + { + status = STATUS_ACCESS_VIOLATION; + size = 0; + } + else if (process == GetCurrentProcess()) + { + __TRY + { + memmove( buffer, addr, size ); + status = STATUS_SUCCESS; + } + __EXCEPT + { + status = STATUS_PARTIAL_COPY; + size = 0; + } + __ENDTRY + } + else { SERVER_START_REQ( read_process_memory ) { @@ -6036,11 +6055,6 @@ NTSTATUS WINAPI NtReadVirtualMemory( HANDLE process, const void *addr, void *buf } SERVER_END_REQ; } - else - { - status = STATUS_ACCESS_VIOLATION; - size = 0; - } if (bytes_read) *bytes_read = size; return status; }
From: Piotr Caban piotr@codeweavers.com
--- dlls/kernel32/tests/virtual.c | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+)
diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c index 5fa8a1b5266..12841133c05 100644 --- a/dlls/kernel32/tests/virtual.c +++ b/dlls/kernel32/tests/virtual.c @@ -4366,6 +4366,45 @@ static void test_PrefetchVirtualMemory(void) "PrefetchVirtualMemory unexpected status on 2 page-aligned entries: %ld\n", GetLastError() ); }
+static void test_ReadProcessMemory(void) +{ + BYTE buf[0x2000]; + DWORD old_prot; + SIZE_T copied; + HANDLE hproc; + void *ptr; + BOOL ret; + + ret = DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), + &hproc, 0, FALSE, DUPLICATE_SAME_ACCESS); + ok(ret, "DuplicateHandle failed %lu\n", GetLastError()); + ptr = VirtualAlloc(NULL, 2 * si.dwPageSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + ok(ptr != NULL, "Virtual failed %lu\n", GetLastError()); + ret = VirtualProtect(((BYTE *)ptr) + si.dwPageSize, si.dwPageSize, PAGE_NOACCESS, &old_prot); + ok(ret, "VirtualProtect failed %lu\n", GetLastError()); + + copied = 1; + ret = ReadProcessMemory(GetCurrentProcess(), ptr, buf, 2 * si.dwPageSize, &copied); + ok(!ret, "ReadProcessMemory succeeded\n"); + ok(!copied, "copied = %Id\n", copied); + ok(GetLastError() == ERROR_PARTIAL_COPY, "GetLastError() = %lu\n", GetLastError()); + + ret = ReadProcessMemory(GetCurrentProcess(), ptr, buf, si.dwPageSize, &copied); + ok(ret, "ReadProcessMemory failed %lu\n", GetLastError()); + ok(copied == si.dwPageSize, "copied = %Id\n", copied); + + ret = ReadProcessMemory(hproc, ptr, buf, 2 * si.dwPageSize, &copied); + todo_wine ok(!ret, "ReadProcessMemory succeeded\n"); + + ret = ReadProcessMemory(hproc, ptr, buf, si.dwPageSize, &copied); + ok(ret, "ReadProcessMemory failed %lu\n", GetLastError()); + ok(copied == si.dwPageSize, "copied = %Id\n", copied); + + ret = VirtualFree(ptr, 0, MEM_RELEASE); + ok(ret, "VirtualFree failed %lu\n", GetLastError()); + CloseHandle(hproc); +} + START_TEST(virtual) { int argc; @@ -4447,6 +4486,7 @@ START_TEST(virtual) test_IsBadCodePtr(); test_write_watch(); test_PrefetchVirtualMemory(); + test_ReadProcessMemory(); #if defined(__i386__) || defined(__x86_64__) test_stack_commit(); #endif