mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
ntdll: Implementation of inter-process VirtualAllocEx and VirtualFreeEx.
This commit is contained in:
parent
6ca1d1b081
commit
7a00142bc1
4 changed files with 65 additions and 25 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1380,10 +1380,26 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_
|
|||
|
||||
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( HANDLE process, PVOID *addr_ptr, SIZE_T *si
|
|||
|
||||
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 */
|
||||
|
|
Loading…
Reference in a new issue