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