From: Paul Gofman pgofman@codeweavers.com
--- dlls/ntdll/unix/virtual.c | 3 ++- server/mach.c | 4 +++- server/process.c | 7 ++++--- server/process.h | 3 ++- server/procfs.c | 4 +++- server/protocol.def | 2 ++ server/ptrace.c | 4 +++- 7 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 4b4d9d6cd7f..a6dd1f6eded 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -6604,7 +6604,8 @@ NTSTATUS WINAPI NtWriteVirtualMemory( HANDLE process, void *addr, const void *bu req->handle = wine_server_obj_handle( process ); req->addr = wine_server_client_ptr( addr ); wine_server_add_data( req, buffer, size ); - if ((status = wine_server_call( req ))) size = 0; + status = wine_server_call( req ); + size = reply->written; } SERVER_END_REQ; } diff --git a/server/mach.c b/server/mach.c index 19737fceef8..eceb53d1f98 100644 --- a/server/mach.c +++ b/server/mach.c @@ -415,7 +415,8 @@ int read_process_memory( struct process *process, client_ptr_t ptr, data_size_t }
/* write data to a process memory space */ -int write_process_memory( struct process *process, client_ptr_t ptr, data_size_t size, const char *src ) +int write_process_memory( struct process *process, client_ptr_t ptr, data_size_t size, const char *src, + data_size_t *written ) { kern_return_t ret; mach_port_t process_port = get_process_port( process ); @@ -538,6 +539,7 @@ int write_process_memory( struct process *process, client_ptr_t ptr, data_size_t out: free( (void *)data ); mach_set_error( ret ); + if (ret == KERN_SUCCESS && written) *written = size; return (ret == KERN_SUCCESS); }
diff --git a/server/process.c b/server/process.c index 8e0f9189a61..436694e592d 100644 --- a/server/process.c +++ b/server/process.c @@ -1143,8 +1143,8 @@ int set_process_debug_flag( struct process *process, int flag ) if (is_wow64_process( process )) peb32 = process->peb + 0x1000;
/* BeingDebugged flag is the byte at offset 2 in the PEB */ - if (peb32 && !write_process_memory( process, peb32 + 2, 1, &data )) return 0; - return write_process_memory( process, process->peb + 2, 1, &data ); + if (peb32 && !write_process_memory( process, peb32 + 2, 1, &data, NULL )) return 0; + return write_process_memory( process, process->peb + 2, 1, &data, NULL ); }
/* create a new process */ @@ -1798,7 +1798,8 @@ DECL_HANDLER(write_process_memory) if ((process = get_process_from_handle( req->handle, PROCESS_VM_WRITE ))) { data_size_t len = get_req_data_size(); - if (len) write_process_memory( process, req->addr, len, get_req_data() ); + reply->written = 0; + if (len) write_process_memory( process, req->addr, len, get_req_data(), &reply->written ); release_object( process ); } } diff --git a/server/process.h b/server/process.h index 251af45be79..2bf96abb55b 100644 --- a/server/process.h +++ b/server/process.h @@ -137,7 +137,8 @@ extern void init_tracing_mechanism(void); extern void init_process_tracing( struct process *process ); extern void finish_process_tracing( struct process *process ); extern int read_process_memory( struct process *process, client_ptr_t ptr, data_size_t size, char *dest ); -extern int write_process_memory( struct process *process, client_ptr_t ptr, data_size_t size, const char *src ); +extern int write_process_memory( struct process *process, client_ptr_t ptr, data_size_t size, const char *src, + data_size_t *written );
static inline process_id_t get_process_id( struct process *process ) { return process->id; }
diff --git a/server/procfs.c b/server/procfs.c index 6ae0a9006ed..17ff6b166a5 100644 --- a/server/procfs.c +++ b/server/procfs.c @@ -150,7 +150,8 @@ int read_process_memory( struct process *process, client_ptr_t ptr, size_t size, }
/* write data to a process memory space */ -int write_process_memory( struct process *process, client_ptr_t ptr, size_t size, const char *src ) +int write_process_memory( struct process *process, client_ptr_t ptr, size_t size, const char *src, + data_size_t *written ) { ssize_t ret; int fd; @@ -165,6 +166,7 @@ int write_process_memory( struct process *process, client_ptr_t ptr, size_t size
ret = pwrite( fd, src, size, (off_t)ptr ); close( fd ); + if (ret == size && written) *written = size; if (ret == size) return 1;
if (ret == -1) file_set_error(); diff --git a/server/protocol.def b/server/protocol.def index cf92cdbabaa..475a84652ff 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1994,6 +1994,8 @@ struct process_info obj_handle_t handle; /* process handle */ client_ptr_t addr; /* addr to write to */ VARARG(data,bytes); /* data to write */ +@REPLY + data_size_t written; /* number of bytes written */ @END
diff --git a/server/ptrace.c b/server/ptrace.c index 404c0a8d12f..e065da1f183 100644 --- a/server/ptrace.c +++ b/server/ptrace.c @@ -480,7 +480,8 @@ static int check_process_write_access( struct thread *thread, long *addr, data_s }
/* write data to a process memory space */ -int write_process_memory( struct process *process, client_ptr_t ptr, data_size_t size, const char *src ) +int write_process_memory( struct process *process, client_ptr_t ptr, data_size_t size, const char *src, + data_size_t *written ) { struct thread *thread = get_ptrace_thread( process ); int ret = 0; @@ -564,6 +565,7 @@ int write_process_memory( struct process *process, client_ptr_t ptr, data_size_t done: resume_after_ptrace( thread ); } + if (ret && written) *written = size; return ret; }