Module: wine Branch: master Commit: 7a00142bc1469e4fcf7dce1a5f26bee0086878cc URL: http://source.winehq.org/git/wine.git/?a=commit;h=7a00142bc1469e4fcf7dce1a5f...
Author: Alexandre Julliard julliard@winehq.org Date: Mon Jan 15 22:27:40 2007 +0100
ntdll: Implementation of inter-process VirtualAllocEx and VirtualFreeEx.
---
dlls/kernel32/tests/process.c | 10 --------- dlls/kernel32/tests/virtual.c | 18 ++++++++-------- dlls/ntdll/sync.c | 20 +++++++++++++++++++ dlls/ntdll/virtual.c | 42 +++++++++++++++++++++++++++++++++++----- 4 files changed, 65 insertions(+), 25 deletions(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c index 8a15722..8e782f1 100644 --- a/dlls/kernel32/tests/process.c +++ b/dlls/kernel32/tests/process.c @@ -1311,7 +1311,6 @@ static void test_OpenProcess(void)
SetLastError(0xdeadbeef); addr1 = pVirtualAllocEx(hproc, 0, 0xFFFC, MEM_RESERVE, PAGE_NOACCESS); -todo_wine { ok(!addr1, "VirtualAllocEx should fail\n"); if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { /* Win9x */ @@ -1320,7 +1319,6 @@ todo_wine { return; } ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %d\n", GetLastError()); -}
read_bytes = 0xdeadbeef; SetLastError(0xdeadbeef); @@ -1334,11 +1332,7 @@ todo_wine { ok(hproc != NULL, "OpenProcess error %d\n", GetLastError());
addr1 = pVirtualAllocEx(hproc, 0, 0xFFFC, MEM_RESERVE, PAGE_NOACCESS); -todo_wine { ok(addr1 != NULL, "VirtualAllocEx error %d\n", GetLastError()); -} - if (addr1 == NULL) /* FIXME: remove once Wine is fixed */ - addr1 = pVirtualAllocEx(GetCurrentProcess(), 0, 0xFFFC, MEM_RESERVE, PAGE_NOACCESS);
/* without PROCESS_QUERY_INFORMATION */ SetLastError(0xdeadbeef); @@ -1374,18 +1368,14 @@ todo_wine { ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
SetLastError(0xdeadbeef); -todo_wine { ok(!pVirtualFreeEx(hproc, addr1, 0, MEM_RELEASE), "VirtualFreeEx without PROCESS_VM_OPERATION rights should fail\n"); ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %d\n", GetLastError()); -}
CloseHandle(hproc);
-todo_wine { ok(VirtualFree(addr1, 0, MEM_RELEASE), "VirtualFree failed\n"); } -}
START_TEST(process) { diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c index 8773765..d03ee7b 100644 --- a/dlls/kernel32/tests/virtual.c +++ b/dlls/kernel32/tests/virtual.c @@ -74,7 +74,7 @@ static void test_VirtualAllocEx(void) for (i = 0; i < alloc_size; i++) src[i] = 0xcafedead + i;
- todo_wine ok(addr1 != NULL, "VirtualAllocEx error %u\n", GetLastError()); + ok(addr1 != NULL, "VirtualAllocEx error %u\n", GetLastError()); b = WriteProcessMemory(hProcess, addr1, src, alloc_size, &bytes_written); ok(b && (bytes_written == alloc_size), "%lu bytes written\n", bytes_written); @@ -82,7 +82,7 @@ static void test_VirtualAllocEx(void) ok(b && (bytes_read == alloc_size), "%lu bytes read\n", bytes_read); ok(!memcmp(src, dst, alloc_size), "Data from remote process differs\n"); b = VirtualFreeEx(hProcess, addr1, 0, MEM_RELEASE); - todo_wine ok(b != 0, "VirtualFreeEx, error %u\n", GetLastError()); + ok(b != 0, "VirtualFreeEx, error %u\n", GetLastError());
HeapFree( GetProcessHeap(), 0, src ); HeapFree( GetProcessHeap(), 0, dst ); @@ -99,7 +99,7 @@ static void test_VirtualAllocEx(void) "got %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
addr1 = VirtualAllocEx(hProcess, 0, 0xFFFC, MEM_RESERVE, PAGE_NOACCESS); - todo_wine ok(addr1 != NULL, "VirtualAllocEx failed\n"); + ok(addr1 != NULL, "VirtualAllocEx failed\n");
/* test a not committed memory */ memset(&info, 'q', sizeof(info)); @@ -154,11 +154,13 @@ static void test_VirtualAllocEx(void) GetLastError() == ERROR_INVALID_PARAMETER, /* Win9x */ "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
+ old_prot = 0; todo_wine ok(VirtualProtectEx(hProcess, addr1, 0x1000, PAGE_READONLY, &old_prot), "VirtualProtectEx failed\n"); todo_wine ok(old_prot == PAGE_NOACCESS, "wrong old protection: got %04x instead of PAGE_NOACCESS\n", old_prot);
+ old_prot = 0; todo_wine ok(VirtualProtectEx(hProcess, addr1, 0x1000, PAGE_READWRITE, &old_prot), "VirtualProtectEx failed\n"); todo_wine ok(old_prot == PAGE_READONLY, @@ -166,20 +168,18 @@ static void test_VirtualAllocEx(void)
ok(!VirtualFreeEx(hProcess, addr1, 0x10000, 0), "VirtualFreeEx should fail with type 0\n"); - todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, + ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
- todo_wine ok(VirtualFreeEx(hProcess, addr1, 0x10000, MEM_DECOMMIT), - "VirtualFreeEx failed\n"); + ok(VirtualFreeEx(hProcess, addr1, 0x10000, MEM_DECOMMIT), "VirtualFreeEx failed\n");
/* if the type is MEM_RELEASE, size must be 0 */ ok(!VirtualFreeEx(hProcess, addr1, 1, MEM_RELEASE), "VirtualFreeEx should fail\n"); - todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, + ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
- todo_wine ok(VirtualFreeEx(hProcess, addr1, 0, MEM_RELEASE), - "VirtualFreeEx failed\n"); + ok(VirtualFreeEx(hProcess, addr1, 0, MEM_RELEASE), "VirtualFreeEx failed\n");
TerminateProcess(hProcess, 0); CloseHandle(hProcess); diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c index 2274e21..70dc4c9 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c @@ -706,6 +706,26 @@ static BOOL call_apcs( BOOL alertable ) NtCurrentTeb()->num_async_io--; call.async_io.func( call.async_io.user, call.async_io.sb, call.async_io.status ); break; + case APC_VIRTUAL_ALLOC: + result.type = call.type; + result.virtual_alloc.addr = call.virtual_alloc.addr; + result.virtual_alloc.size = call.virtual_alloc.size; + result.virtual_alloc.status = NtAllocateVirtualMemory( NtCurrentProcess(), + &result.virtual_alloc.addr, + call.virtual_alloc.zero_bits, + &result.virtual_alloc.size, + call.virtual_alloc.op_type, + call.virtual_alloc.prot ); + break; + case APC_VIRTUAL_FREE: + result.type = call.type; + result.virtual_free.addr = call.virtual_free.addr; + result.virtual_free.size = call.virtual_free.size; + result.virtual_free.status = NtFreeVirtualMemory( NtCurrentProcess(), + &result.virtual_free.addr, + &result.virtual_free.size, + call.virtual_free.op_type ); + break; default: server_protocol_error( "get_apc_request: bad type %d\n", call.type ); break; diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index 3ff6b42..9c613cc 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -1380,10 +1380,26 @@ NTSTATUS WINAPI NtAllocateVirtualMemory(
if (!size) return STATUS_INVALID_PARAMETER;
- if (!is_current_process( process )) + if (process != NtCurrentProcess()) { - ERR("Unsupported on other process\n"); - return STATUS_ACCESS_DENIED; + apc_call_t call; + apc_result_t result; + + call.virtual_alloc.type = APC_VIRTUAL_ALLOC; + call.virtual_alloc.addr = *ret; + call.virtual_alloc.size = *size_ptr; + call.virtual_alloc.zero_bits = zero_bits; + call.virtual_alloc.op_type = type; + call.virtual_alloc.prot = protect; + status = NTDLL_queue_process_apc( process, &call, &result ); + if (status != STATUS_SUCCESS) return status; + + if (result.virtual_alloc.status == STATUS_SUCCESS) + { + *ret = result.virtual_alloc.addr; + *size_ptr = result.virtual_alloc.size; + } + return result.virtual_alloc.status; }
/* Round parameters to a page boundary */ @@ -1485,10 +1501,24 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HAN
TRACE("%p %p %08lx %x\n", process, addr, size, type );
- if (!is_current_process( process )) + if (process != NtCurrentProcess()) { - ERR("Unsupported on other process\n"); - return STATUS_ACCESS_DENIED; + apc_call_t call; + apc_result_t result; + + call.virtual_free.type = APC_VIRTUAL_FREE; + call.virtual_free.addr = addr; + call.virtual_free.size = size; + call.virtual_free.op_type = type; + status = NTDLL_queue_process_apc( process, &call, &result ); + if (status != STATUS_SUCCESS) return status; + + if (result.virtual_free.status == STATUS_SUCCESS) + { + *addr_ptr = result.virtual_free.addr; + *size_ptr = result.virtual_free.size; + } + return result.virtual_free.status; }
/* Fix the parameters */