ntdll: Implementation of inter-process VirtualProtectEx.
This commit is contained in:
parent
3d00239586
commit
1ea968016f
|
@ -118,7 +118,7 @@ static void test_VirtualAllocEx(void)
|
|||
SetLastError(0xdeadbeef);
|
||||
ok(!VirtualProtectEx(hProcess, addr1, 0xFFFC, PAGE_READONLY, &old_prot),
|
||||
"VirtualProtectEx should fail on a not committed memory\n");
|
||||
todo_wine ok(GetLastError() == ERROR_INVALID_ADDRESS /* NT */ ||
|
||||
ok(GetLastError() == ERROR_INVALID_ADDRESS /* NT */ ||
|
||||
GetLastError() == ERROR_INVALID_PARAMETER, /* Win9x */
|
||||
"got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
|
||||
|
||||
|
@ -141,21 +141,17 @@ static void test_VirtualAllocEx(void)
|
|||
SetLastError(0xdeadbeef);
|
||||
ok(!VirtualProtectEx(hProcess, addr1, 0xFFFC, PAGE_READONLY, &old_prot),
|
||||
"VirtualProtectEx should fail on a not committed memory\n");
|
||||
todo_wine ok(GetLastError() == ERROR_INVALID_ADDRESS /* NT */ ||
|
||||
ok(GetLastError() == ERROR_INVALID_ADDRESS /* NT */ ||
|
||||
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);
|
||||
ok(VirtualProtectEx(hProcess, addr1, 0x1000, PAGE_READONLY, &old_prot), "VirtualProtectEx failed\n");
|
||||
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,
|
||||
"wrong old protection: got %04x instead of PAGE_READONLY\n", old_prot);
|
||||
ok(VirtualProtectEx(hProcess, addr1, 0x1000, PAGE_READWRITE, &old_prot), "VirtualProtectEx failed\n");
|
||||
ok(old_prot == PAGE_READONLY, "wrong old protection: got %04x instead of PAGE_READONLY\n", old_prot);
|
||||
|
||||
ok(!VirtualFreeEx(hProcess, addr1, 0x10000, 0),
|
||||
"VirtualFreeEx should fail with type 0\n");
|
||||
|
|
|
@ -746,6 +746,16 @@ static BOOL call_apcs( BOOL alertable )
|
|||
}
|
||||
break;
|
||||
}
|
||||
case APC_VIRTUAL_PROTECT:
|
||||
result.type = call.type;
|
||||
result.virtual_protect.addr = call.virtual_protect.addr;
|
||||
result.virtual_protect.size = call.virtual_protect.size;
|
||||
result.virtual_protect.status = NtProtectVirtualMemory( NtCurrentProcess(),
|
||||
&result.virtual_protect.addr,
|
||||
&result.virtual_protect.size,
|
||||
call.virtual_protect.prot,
|
||||
&result.virtual_protect.prot );
|
||||
break;
|
||||
default:
|
||||
server_protocol_error( "get_apc_request: bad type %d\n", call.type );
|
||||
break;
|
||||
|
|
|
@ -1597,10 +1597,25 @@ NTSTATUS WINAPI NtProtectVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T
|
|||
|
||||
TRACE("%p %p %08lx %08x\n", process, addr, size, new_prot );
|
||||
|
||||
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_protect.type = APC_VIRTUAL_PROTECT;
|
||||
call.virtual_protect.addr = addr;
|
||||
call.virtual_protect.size = size;
|
||||
call.virtual_protect.prot = new_prot;
|
||||
status = NTDLL_queue_process_apc( process, &call, &result );
|
||||
if (status != STATUS_SUCCESS) return status;
|
||||
|
||||
if (result.virtual_protect.status == STATUS_SUCCESS)
|
||||
{
|
||||
*addr_ptr = result.virtual_protect.addr;
|
||||
*size_ptr = result.virtual_protect.size;
|
||||
if (old_prot) *old_prot = result.virtual_protect.prot;
|
||||
}
|
||||
return result.virtual_protect.status;
|
||||
}
|
||||
|
||||
/* Fix the parameters */
|
||||
|
|
|
@ -217,7 +217,8 @@ enum apc_type
|
|||
APC_ASYNC_IO,
|
||||
APC_VIRTUAL_ALLOC,
|
||||
APC_VIRTUAL_FREE,
|
||||
APC_VIRTUAL_QUERY
|
||||
APC_VIRTUAL_QUERY,
|
||||
APC_VIRTUAL_PROTECT
|
||||
};
|
||||
|
||||
typedef union
|
||||
|
@ -265,6 +266,13 @@ typedef union
|
|||
enum apc_type type;
|
||||
const void *addr;
|
||||
} virtual_query;
|
||||
struct
|
||||
{
|
||||
enum apc_type type;
|
||||
void *addr;
|
||||
unsigned long size;
|
||||
unsigned int prot;
|
||||
} virtual_protect;
|
||||
} apc_call_t;
|
||||
|
||||
typedef union
|
||||
|
@ -296,6 +304,14 @@ typedef union
|
|||
unsigned int alloc_prot;
|
||||
unsigned int alloc_type;
|
||||
} virtual_query;
|
||||
struct
|
||||
{
|
||||
enum apc_type type;
|
||||
unsigned int status;
|
||||
void *addr;
|
||||
unsigned long size;
|
||||
unsigned int prot;
|
||||
} virtual_protect;
|
||||
} apc_result_t;
|
||||
|
||||
|
||||
|
@ -4517,6 +4533,6 @@ union generic_reply
|
|||
struct query_symlink_reply query_symlink_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 267
|
||||
#define SERVER_PROTOCOL_VERSION 268
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -233,7 +233,8 @@ enum apc_type
|
|||
APC_ASYNC_IO,
|
||||
APC_VIRTUAL_ALLOC,
|
||||
APC_VIRTUAL_FREE,
|
||||
APC_VIRTUAL_QUERY
|
||||
APC_VIRTUAL_QUERY,
|
||||
APC_VIRTUAL_PROTECT
|
||||
};
|
||||
|
||||
typedef union
|
||||
|
@ -281,6 +282,13 @@ typedef union
|
|||
enum apc_type type; /* APC_VIRTUAL_QUERY */
|
||||
const void *addr; /* requested address */
|
||||
} virtual_query;
|
||||
struct
|
||||
{
|
||||
enum apc_type type; /* APC_VIRTUAL_PROTECT */
|
||||
void *addr; /* requested address */
|
||||
unsigned long size; /* requested address */
|
||||
unsigned int prot; /* new protection flags */
|
||||
} virtual_protect;
|
||||
} apc_call_t;
|
||||
|
||||
typedef union
|
||||
|
@ -312,6 +320,14 @@ typedef union
|
|||
unsigned int alloc_prot;/* resulting allocation protection */
|
||||
unsigned int alloc_type;/* resulting region allocation type */
|
||||
} virtual_query;
|
||||
struct
|
||||
{
|
||||
enum apc_type type; /* APC_VIRTUAL_PROTECT */
|
||||
unsigned int status; /* status returned by call */
|
||||
void *addr; /* resulting address */
|
||||
unsigned long size; /* resulting size */
|
||||
unsigned int prot; /* old protection flags */
|
||||
} virtual_protect;
|
||||
} apc_result_t;
|
||||
|
||||
/****************************************************************/
|
||||
|
|
|
@ -1157,6 +1157,7 @@ DECL_HANDLER(queue_apc)
|
|||
case APC_VIRTUAL_ALLOC:
|
||||
case APC_VIRTUAL_FREE:
|
||||
case APC_VIRTUAL_QUERY:
|
||||
case APC_VIRTUAL_PROTECT:
|
||||
access = (apc->call.type == APC_VIRTUAL_QUERY) ? PROCESS_QUERY_INFORMATION : PROCESS_VM_OPERATION;
|
||||
if ((process = get_process_from_handle( req->process, access )))
|
||||
{
|
||||
|
|
|
@ -133,6 +133,11 @@ static void dump_apc_call( const apc_call_t *call )
|
|||
case APC_VIRTUAL_QUERY:
|
||||
fprintf( stderr, "APC_VIRTUAL_QUERY,addr=%p", call->virtual_query.addr );
|
||||
break;
|
||||
case APC_VIRTUAL_PROTECT:
|
||||
fprintf( stderr, "APC_VIRTUAL_PROTECT,addr=%p,size=%lu,prot=%x",
|
||||
call->virtual_protect.addr, call->virtual_protect.size,
|
||||
call->virtual_protect.prot );
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "type=%u", call->type );
|
||||
break;
|
||||
|
@ -165,6 +170,12 @@ static void dump_apc_result( const apc_result_t *result )
|
|||
result->virtual_query.prot, result->virtual_query.alloc_prot,
|
||||
result->virtual_query.alloc_type );
|
||||
break;
|
||||
case APC_VIRTUAL_PROTECT:
|
||||
fprintf( stderr, "APC_VIRTUAL_PROTECT,status=%s,addr=%p,size=%lu,prot=%x",
|
||||
get_status_name( result->virtual_protect.status ),
|
||||
result->virtual_protect.addr, result->virtual_protect.size,
|
||||
result->virtual_protect.prot );
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "type=%u", result->type );
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue