Support remote operations in wineserver
Alexander Yaworsky
yaworsky at migusoft.ru
Wed Sep 22 05:22:16 CDT 2004
Hello
I guess that original patch was too large.
I sent small pieces of it and they have been committed; however it seems that
this part cannot be downsized.
I do not include files touched by tools/make_requests in this patch.
ChangeLog:
Support remote operations in wineserver.
Index: server/process.c
===================================================================
RCS file: /home/wine/wine/server/process.c,v
retrieving revision 1.117
diff -u -r1.117 process.c
--- server/process.c 14 Jun 2004 17:02:00 -0000 1.117
+++ server/process.c 22 Sep 2004 08:13:45 -0000
@@ -1190,3 +1190,115 @@
release_object( process );
}
}
+
+/* Accept parameters for remote operation and start it */
+DECL_HANDLER(remote_operation)
+{
+ int access;
+ struct process *process;
+ struct event *event;
+
+ /* define required access rights */
+ switch( req->type )
+ {
+ case REMOTE_OP_NEW_THREAD:
+ access = PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION
+ | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE;
+ break;
+ case REMOTE_OP_VM_ALLOC: access = PROCESS_VM_OPERATION; break;
+ case REMOTE_OP_VM_FREE: access = PROCESS_VM_OPERATION; break;
+ case REMOTE_OP_VM_PROTECT: access = PROCESS_VM_OPERATION; break;
+ case REMOTE_OP_VM_QUERY: access = PROCESS_QUERY_INFORMATION; break;
+ case REMOTE_OP_VM_MAP: access = PROCESS_VM_OPERATION; break;
+ case REMOTE_OP_VM_UNMAP: access = PROCESS_VM_OPERATION; break;
+ case REMOTE_OP_VM_FLUSH: access = PROCESS_VM_OPERATION; break; /* FIXME: is access right? */
+ default:
+ set_error( STATUS_INVALID_PARAMETER );
+ return;
+ }
+
+ /* get process object */
+ if (!(process = get_process_from_handle( req->handle, access ))) return;
+
+ /* dispose result data buffer if allocated */
+ if (current->result_data)
+ {
+ free( current->result_data );
+ current->result_data = NULL;
+ }
+
+ /* create event object */
+ reply->event = NULL;
+ if (current->result_event)
+ {
+ release_object( current->result_event );
+ current->result_event = NULL;
+ }
+ if (!(event = create_event( NULL, 0, 1, 0 )))
+ goto error;
+
+ if (!(reply->event = alloc_handle( current->process, event, EVENT_ALL_ACCESS, FALSE )))
+ goto error;
+
+ /* FIXME: pass somehow operation type, params and originator thread id
+ for some thread in the process and force execution of operation */
+ set_error( STATUS_NOT_IMPLEMENTED );
+
+ /* save event object in thread structure for future set operation;
+ we do not release it here */
+ current->result_event = event;
+ release_object( process );
+ return;
+
+error:
+ if (reply->event) close_handle( current->process, reply->event, NULL );
+ if (event) release_object( event );
+ release_object( process );
+}
+
+/* save result of remote operation and wakeup originator */
+DECL_HANDLER(remote_operation_complete)
+{
+ struct thread *thread = get_thread_from_id( req->originator );
+
+ if (!thread) return;
+
+ /* save status */
+ thread->remote_status = req->status;
+
+ /* allocate buffer for result data, if required */
+ if (thread->result_data)
+ {
+ free( thread->result_data );
+ thread->result_data = NULL;
+ }
+ if ((thread->result_size = get_req_data_size()))
+ {
+ if ((thread->result_data = mem_alloc( thread->result_size )))
+ memcpy( thread->result_data, get_req_data(), thread->result_size );
+ else
+ thread->remote_status = get_error();
+ }
+
+ /* set event */
+ if (thread->result_event)
+ {
+ set_event( thread->result_event );
+ release_object( thread->result_event );
+ thread->result_event = NULL;
+ }
+ release_object( thread );
+}
+
+/* return status and result data from remote opertaion */
+DECL_HANDLER(remote_operation_result)
+{
+ reply->status = current->remote_status;
+
+ if (current->result_data)
+ {
+ void *result = current->result_data;
+ current->result_data = NULL;
+ set_reply_data_ptr( result, current->result_size );
+ }
+}
Index: server/protocol.def
===================================================================
RCS file: /home/wine/wine/server/protocol.def,v
retrieving revision 1.110
diff -u -r1.110 protocol.def
--- server/protocol.def 18 Aug 2004 00:04:58 -0000 1.110
+++ server/protocol.def 22 Sep 2004 08:13:52 -0000
@@ -2166,3 +2166,126 @@
#define SET_GLOBAL_SHELL_WINDOWS 0x01 /* set both main shell and listview windows */
#define SET_GLOBAL_PROGMAN_WINDOW 0x02
#define SET_GLOBAL_TASKMAN_WINDOW 0x04
+
+/* Accept parameters for remote operation and start it */
+ at REQ(remote_operation)
+ obj_handle_t handle; /* process handle */
+ int type; /* operation type (see below) */
+ VARARG(data,bytes); /* operation parameters (see below) */
+ at REPLY
+ obj_handle_t event; /* originator waits on it */
+ at END
+enum remote_op_type
+{
+ REMOTE_OP_NEW_THREAD,
+ REMOTE_OP_VM_ALLOC,
+ REMOTE_OP_VM_FREE,
+ REMOTE_OP_VM_PROTECT,
+ REMOTE_OP_VM_QUERY,
+ REMOTE_OP_VM_MAP,
+ REMOTE_OP_VM_UNMAP,
+ REMOTE_OP_VM_FLUSH
+};
+
+/* Notify that remote operation has been complete */
+ at REQ(remote_operation_complete)
+ thread_id_t originator; /* originator thread id */
+ unsigned int status; /* operation status */
+ VARARG(data,bytes); /* operation result data (see below) */
+ at END
+
+/* Get result of remote opertaion */
+ at REQ(remote_operation_result)
+ at REPLY
+ unsigned int status; /* operation status */
+ VARARG(data,bytes); /* operation result data (see below) */
+ at END
+
+struct remote_op_params_new_thread
+{
+ int suspend;
+ void *stack_addr;
+ unsigned int stack_reserve;
+ unsigned int stack_commit;
+ void *start;
+ void *param;
+};
+struct remote_op_result_new_thread
+{
+ obj_handle_t handle;
+ thread_id_t tid;
+};
+
+struct remote_op_params_vm_alloc
+{
+ void *addr;
+ unsigned long size;
+ unsigned long type;
+ unsigned long protect;
+};
+struct remote_op_result_vm_alloc
+{
+ void *base;
+ unsigned long size;
+};
+
+struct remote_op_params_vm_free
+{
+ void *addr;
+ unsigned long size;
+ unsigned long type;
+};
+struct remote_op_result_vm_free
+{
+ void *base;
+ unsigned long size;
+};
+
+struct remote_op_params_vm_protect
+{
+ void *addr;
+ unsigned long size;
+ unsigned long new_prot;
+};
+struct remote_op_result_vm_protect
+{
+ void *base;
+ unsigned long size;
+ unsigned long old_prot;
+};
+
+struct remote_op_params_vm_query
+{
+ void *addr;
+ int info_class;
+};
+
+struct remote_op_params_vm_map
+{
+ void *addr;
+ unsigned long zero_bits;
+ unsigned long commit_size;
+ unsigned long offset_low;
+ long offset_high;
+ unsigned long size;
+ int inherit;
+ unsigned long alloc_type;
+ unsigned long protect;
+};
+struct remote_op_result_vm_map
+{
+ void *base;
+ unsigned long size;
+};
+
+struct remote_op_params_vm_flush
+{
+ void *addr;
+ unsigned long size;
+ unsigned long unknown;
+};
+struct remote_op_result_vm_flush
+{
+ void *base;
+ unsigned long size;
+};
Index: server/thread.c
===================================================================
RCS file: /home/wine/wine/server/thread.c,v
retrieving revision 1.103
diff -u -r1.103 thread.c
--- server/thread.c 27 Oct 2003 22:10:22 -0000 1.103
+++ server/thread.c 22 Sep 2004 08:13:56 -0000
@@ -142,6 +142,8 @@
thread->suspend = 0;
thread->creation_time = time(NULL);
thread->exit_time = 0;
+ thread->result_data = NULL;
+ thread->result_event = NULL;
for (i = 0; i < MAX_INFLIGHT_FDS; i++)
thread->inflight[i].server = thread->inflight[i].client = -1;
@@ -210,6 +212,8 @@
if (thread->request_fd) release_object( thread->request_fd );
if (thread->reply_fd) release_object( thread->reply_fd );
if (thread->wait_fd) release_object( thread->wait_fd );
+ if (thread->result_data) free( thread->result_data );
+ if (thread->result_event) release_object( thread->result_event );
free_msg_queue( thread );
cleanup_clipboard_thread(thread);
destroy_thread_windows( thread );
@@ -226,6 +230,8 @@
thread->request_fd = NULL;
thread->reply_fd = NULL;
thread->wait_fd = NULL;
+ thread->result_data = NULL;
+ thread->result_event = NULL;
if (thread == booting_thread) /* killing booting thread */
{
Index: server/thread.h
===================================================================
RCS file: /home/wine/wine/server/thread.h,v
retrieving revision 1.56
diff -u -r1.56 thread.h
--- server/thread.h 10 Dec 2003 01:12:18 -0000 1.56
+++ server/thread.h 22 Sep 2004 08:13:57 -0000
@@ -94,6 +94,10 @@
time_t creation_time; /* Thread creation time */
time_t exit_time; /* Thread exit time */
struct token *token; /* security token associated with this thread */
+ unsigned int remote_status; /* error code from remote operation */
+ void *result_data; /* result data from remote operation */
+ int result_size; /* size of result data */
+ struct event *result_event; /* originator of remote operation waits on it */
};
struct thread_snapshot
More information about the wine-patches
mailing list