Alexandre Julliard : ntdll:
Implementation of inter-process VirtualAllocEx and VirtualFreeEx.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Jan 16 05:22:15 CST 2007
Module: wine
Branch: master
Commit: 7a00142bc1469e4fcf7dce1a5f26bee0086878cc
URL: http://source.winehq.org/git/wine.git/?a=commit;h=7a00142bc1469e4fcf7dce1a5f26bee0086878cc
Author: Alexandre Julliard <julliard at 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 */
More information about the wine-cvs
mailing list