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