ntdll: Implementation of inter-process NtFlushVirtualMemory.

This commit is contained in:
Alexandre Julliard 2007-01-15 22:31:07 +01:00
parent 1ea968016f
commit 5a1ad74a67
6 changed files with 66 additions and 6 deletions

View File

@ -756,6 +756,14 @@ static BOOL call_apcs( BOOL alertable )
call.virtual_protect.prot,
&result.virtual_protect.prot );
break;
case APC_VIRTUAL_FLUSH:
result.type = call.type;
result.virtual_flush.addr = call.virtual_flush.addr;
result.virtual_flush.size = call.virtual_flush.size;
result.virtual_flush.status = NtFlushVirtualMemory( NtCurrentProcess(),
&result.virtual_flush.addr,
&result.virtual_flush.size, 0 );
break;
default:
server_protocol_error( "get_apc_request: bad type %d\n", call.type );
break;

View File

@ -2095,11 +2095,25 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HANDLE process, LPCVOID *addr_ptr,
sigset_t sigset;
void *addr = ROUND_ADDR( *addr_ptr, page_mask );
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_flush.type = APC_VIRTUAL_FLUSH;
call.virtual_flush.addr = addr;
call.virtual_flush.size = *size_ptr;
status = NTDLL_queue_process_apc( process, &call, &result );
if (status != STATUS_SUCCESS) return status;
if (result.virtual_flush.status == STATUS_SUCCESS)
{
*addr_ptr = result.virtual_flush.addr;
*size_ptr = result.virtual_flush.size;
}
return result.virtual_flush.status;
}
server_enter_uninterrupted_section( &csVirtual, &sigset );
if (!(view = VIRTUAL_FindView( addr ))) status = STATUS_INVALID_PARAMETER;
else

View File

@ -218,7 +218,8 @@ enum apc_type
APC_VIRTUAL_ALLOC,
APC_VIRTUAL_FREE,
APC_VIRTUAL_QUERY,
APC_VIRTUAL_PROTECT
APC_VIRTUAL_PROTECT,
APC_VIRTUAL_FLUSH
};
typedef union
@ -273,6 +274,12 @@ typedef union
unsigned long size;
unsigned int prot;
} virtual_protect;
struct
{
enum apc_type type;
const void *addr;
unsigned long size;
} virtual_flush;
} apc_call_t;
typedef union
@ -312,6 +319,13 @@ typedef union
unsigned long size;
unsigned int prot;
} virtual_protect;
struct
{
enum apc_type type;
unsigned int status;
const void *addr;
unsigned long size;
} virtual_flush;
} apc_result_t;
@ -4533,6 +4547,6 @@ union generic_reply
struct query_symlink_reply query_symlink_reply;
};
#define SERVER_PROTOCOL_VERSION 268
#define SERVER_PROTOCOL_VERSION 269
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -234,7 +234,8 @@ enum apc_type
APC_VIRTUAL_ALLOC,
APC_VIRTUAL_FREE,
APC_VIRTUAL_QUERY,
APC_VIRTUAL_PROTECT
APC_VIRTUAL_PROTECT,
APC_VIRTUAL_FLUSH
};
typedef union
@ -289,6 +290,12 @@ typedef union
unsigned long size; /* requested address */
unsigned int prot; /* new protection flags */
} virtual_protect;
struct
{
enum apc_type type; /* APC_VIRTUAL_FLUSH */
const void *addr; /* requested address */
unsigned long size; /* requested address */
} virtual_flush;
} apc_call_t;
typedef union
@ -328,6 +335,13 @@ typedef union
unsigned long size; /* resulting size */
unsigned int prot; /* old protection flags */
} virtual_protect;
struct
{
enum apc_type type; /* APC_VIRTUAL_FLUSH */
unsigned int status; /* status returned by call */
const void *addr; /* resulting address */
unsigned long size; /* resulting size */
} virtual_flush;
} apc_result_t;
/****************************************************************/

View File

@ -1158,6 +1158,7 @@ DECL_HANDLER(queue_apc)
case APC_VIRTUAL_FREE:
case APC_VIRTUAL_QUERY:
case APC_VIRTUAL_PROTECT:
case APC_VIRTUAL_FLUSH:
access = (apc->call.type == APC_VIRTUAL_QUERY) ? PROCESS_QUERY_INFORMATION : PROCESS_VM_OPERATION;
if ((process = get_process_from_handle( req->process, access )))
{

View File

@ -138,6 +138,10 @@ static void dump_apc_call( const apc_call_t *call )
call->virtual_protect.addr, call->virtual_protect.size,
call->virtual_protect.prot );
break;
case APC_VIRTUAL_FLUSH:
fprintf( stderr, "APC_VIRTUAL_FLUSH,addr=%p,size=%lu",
call->virtual_flush.addr, call->virtual_flush.size );
break;
default:
fprintf( stderr, "type=%u", call->type );
break;
@ -176,6 +180,11 @@ static void dump_apc_result( const apc_result_t *result )
result->virtual_protect.addr, result->virtual_protect.size,
result->virtual_protect.prot );
break;
case APC_VIRTUAL_FLUSH:
fprintf( stderr, "APC_VIRTUAL_FLUSH,status=%s,addr=%p,size=%lu",
get_status_name( result->virtual_flush.status ),
result->virtual_flush.addr, result->virtual_flush.size );
break;
default:
fprintf( stderr, "type=%u", result->type );
break;