Module: wine Branch: master Commit: 5a1ad74a67bc48f4420a0e5e2f1199dbd72cb94f URL: http://source.winehq.org/git/wine.git/?a=commit;h=5a1ad74a67bc48f4420a0e5e2f...
Author: Alexandre Julliard julliard@winehq.org Date: Mon Jan 15 22:31:07 2007 +0100
ntdll: Implementation of inter-process NtFlushVirtualMemory.
---
dlls/ntdll/sync.c | 8 ++++++++ dlls/ntdll/virtual.c | 20 +++++++++++++++++--- include/wine/server_protocol.h | 18 ++++++++++++++++-- server/protocol.def | 16 +++++++++++++++- server/thread.c | 1 + server/trace.c | 9 +++++++++ 6 files changed, 66 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c index 8cfd1e5..eff643e 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c @@ -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; diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index 57cbb20..fe92383 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -2095,11 +2095,25 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HA 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 diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 890dabd..0f4d3f2 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -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 */ diff --git a/server/protocol.def b/server/protocol.def index 8c40e10..9987fd4 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -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;
/****************************************************************/ diff --git a/server/thread.c b/server/thread.c index 35484a4..6c53e5c 100644 --- a/server/thread.c +++ b/server/thread.c @@ -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 ))) { diff --git a/server/trace.c b/server/trace.c index b878c02..7422912 100644 --- a/server/trace.c +++ b/server/trace.c @@ -138,6 +138,10 @@ static void dump_apc_call( const apc_cal 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_r 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;