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);
|
SetLastError(0xdeadbeef);
|
||||||
ok(!VirtualProtectEx(hProcess, addr1, 0xFFFC, PAGE_READONLY, &old_prot),
|
ok(!VirtualProtectEx(hProcess, addr1, 0xFFFC, PAGE_READONLY, &old_prot),
|
||||||
"VirtualProtectEx should fail on a not committed memory\n");
|
"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 */
|
GetLastError() == ERROR_INVALID_PARAMETER, /* Win9x */
|
||||||
"got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
|
"got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
|
||||||
|
|
||||||
|
@ -141,21 +141,17 @@ static void test_VirtualAllocEx(void)
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ok(!VirtualProtectEx(hProcess, addr1, 0xFFFC, PAGE_READONLY, &old_prot),
|
ok(!VirtualProtectEx(hProcess, addr1, 0xFFFC, PAGE_READONLY, &old_prot),
|
||||||
"VirtualProtectEx should fail on a not committed memory\n");
|
"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 */
|
GetLastError() == ERROR_INVALID_PARAMETER, /* Win9x */
|
||||||
"got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
|
"got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
|
||||||
|
|
||||||
old_prot = 0;
|
old_prot = 0;
|
||||||
todo_wine ok(VirtualProtectEx(hProcess, addr1, 0x1000, PAGE_READONLY,
|
ok(VirtualProtectEx(hProcess, addr1, 0x1000, PAGE_READONLY, &old_prot), "VirtualProtectEx failed\n");
|
||||||
&old_prot), "VirtualProtectEx failed\n");
|
ok(old_prot == PAGE_NOACCESS, "wrong old protection: got %04x instead of PAGE_NOACCESS\n", old_prot);
|
||||||
todo_wine ok(old_prot == PAGE_NOACCESS,
|
|
||||||
"wrong old protection: got %04x instead of PAGE_NOACCESS\n", old_prot);
|
|
||||||
|
|
||||||
old_prot = 0;
|
old_prot = 0;
|
||||||
todo_wine ok(VirtualProtectEx(hProcess, addr1, 0x1000, PAGE_READWRITE,
|
ok(VirtualProtectEx(hProcess, addr1, 0x1000, PAGE_READWRITE, &old_prot), "VirtualProtectEx failed\n");
|
||||||
&old_prot), "VirtualProtectEx failed\n");
|
ok(old_prot == PAGE_READONLY, "wrong old protection: got %04x instead of PAGE_READONLY\n", old_prot);
|
||||||
todo_wine ok(old_prot == PAGE_READONLY,
|
|
||||||
"wrong old protection: got %04x instead of PAGE_READONLY\n", old_prot);
|
|
||||||
|
|
||||||
ok(!VirtualFreeEx(hProcess, addr1, 0x10000, 0),
|
ok(!VirtualFreeEx(hProcess, addr1, 0x10000, 0),
|
||||||
"VirtualFreeEx should fail with type 0\n");
|
"VirtualFreeEx should fail with type 0\n");
|
||||||
|
|
|
@ -746,6 +746,16 @@ static BOOL call_apcs( BOOL alertable )
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
server_protocol_error( "get_apc_request: bad type %d\n", call.type );
|
server_protocol_error( "get_apc_request: bad type %d\n", call.type );
|
||||||
break;
|
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 );
|
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");
|
apc_call_t call;
|
||||||
return STATUS_ACCESS_DENIED;
|
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 */
|
/* Fix the parameters */
|
||||||
|
|
|
@ -217,7 +217,8 @@ enum apc_type
|
||||||
APC_ASYNC_IO,
|
APC_ASYNC_IO,
|
||||||
APC_VIRTUAL_ALLOC,
|
APC_VIRTUAL_ALLOC,
|
||||||
APC_VIRTUAL_FREE,
|
APC_VIRTUAL_FREE,
|
||||||
APC_VIRTUAL_QUERY
|
APC_VIRTUAL_QUERY,
|
||||||
|
APC_VIRTUAL_PROTECT
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
|
@ -265,6 +266,13 @@ typedef union
|
||||||
enum apc_type type;
|
enum apc_type type;
|
||||||
const void *addr;
|
const void *addr;
|
||||||
} virtual_query;
|
} virtual_query;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
enum apc_type type;
|
||||||
|
void *addr;
|
||||||
|
unsigned long size;
|
||||||
|
unsigned int prot;
|
||||||
|
} virtual_protect;
|
||||||
} apc_call_t;
|
} apc_call_t;
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
|
@ -296,6 +304,14 @@ typedef union
|
||||||
unsigned int alloc_prot;
|
unsigned int alloc_prot;
|
||||||
unsigned int alloc_type;
|
unsigned int alloc_type;
|
||||||
} virtual_query;
|
} virtual_query;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
enum apc_type type;
|
||||||
|
unsigned int status;
|
||||||
|
void *addr;
|
||||||
|
unsigned long size;
|
||||||
|
unsigned int prot;
|
||||||
|
} virtual_protect;
|
||||||
} apc_result_t;
|
} apc_result_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -4517,6 +4533,6 @@ union generic_reply
|
||||||
struct query_symlink_reply query_symlink_reply;
|
struct query_symlink_reply query_symlink_reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 267
|
#define SERVER_PROTOCOL_VERSION 268
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -233,7 +233,8 @@ enum apc_type
|
||||||
APC_ASYNC_IO,
|
APC_ASYNC_IO,
|
||||||
APC_VIRTUAL_ALLOC,
|
APC_VIRTUAL_ALLOC,
|
||||||
APC_VIRTUAL_FREE,
|
APC_VIRTUAL_FREE,
|
||||||
APC_VIRTUAL_QUERY
|
APC_VIRTUAL_QUERY,
|
||||||
|
APC_VIRTUAL_PROTECT
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
|
@ -281,6 +282,13 @@ typedef union
|
||||||
enum apc_type type; /* APC_VIRTUAL_QUERY */
|
enum apc_type type; /* APC_VIRTUAL_QUERY */
|
||||||
const void *addr; /* requested address */
|
const void *addr; /* requested address */
|
||||||
} virtual_query;
|
} 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;
|
} apc_call_t;
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
|
@ -312,6 +320,14 @@ typedef union
|
||||||
unsigned int alloc_prot;/* resulting allocation protection */
|
unsigned int alloc_prot;/* resulting allocation protection */
|
||||||
unsigned int alloc_type;/* resulting region allocation type */
|
unsigned int alloc_type;/* resulting region allocation type */
|
||||||
} virtual_query;
|
} 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;
|
} apc_result_t;
|
||||||
|
|
||||||
/****************************************************************/
|
/****************************************************************/
|
||||||
|
|
|
@ -1157,6 +1157,7 @@ DECL_HANDLER(queue_apc)
|
||||||
case APC_VIRTUAL_ALLOC:
|
case APC_VIRTUAL_ALLOC:
|
||||||
case APC_VIRTUAL_FREE:
|
case APC_VIRTUAL_FREE:
|
||||||
case APC_VIRTUAL_QUERY:
|
case APC_VIRTUAL_QUERY:
|
||||||
|
case APC_VIRTUAL_PROTECT:
|
||||||
access = (apc->call.type == APC_VIRTUAL_QUERY) ? PROCESS_QUERY_INFORMATION : PROCESS_VM_OPERATION;
|
access = (apc->call.type == APC_VIRTUAL_QUERY) ? PROCESS_QUERY_INFORMATION : PROCESS_VM_OPERATION;
|
||||||
if ((process = get_process_from_handle( req->process, access )))
|
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:
|
case APC_VIRTUAL_QUERY:
|
||||||
fprintf( stderr, "APC_VIRTUAL_QUERY,addr=%p", call->virtual_query.addr );
|
fprintf( stderr, "APC_VIRTUAL_QUERY,addr=%p", call->virtual_query.addr );
|
||||||
break;
|
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:
|
default:
|
||||||
fprintf( stderr, "type=%u", call->type );
|
fprintf( stderr, "type=%u", call->type );
|
||||||
break;
|
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.prot, result->virtual_query.alloc_prot,
|
||||||
result->virtual_query.alloc_type );
|
result->virtual_query.alloc_type );
|
||||||
break;
|
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:
|
default:
|
||||||
fprintf( stderr, "type=%u", result->type );
|
fprintf( stderr, "type=%u", result->type );
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue