Alexandre Julliard : server: Return irp size separately from the output data.

Alexandre Julliard julliard at wine.codeweavers.com
Wed May 6 09:29:04 CDT 2015


Module: wine
Branch: master
Commit: fc4a94c0e2997771acfeba4c704239f34c4f43c5
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=fc4a94c0e2997771acfeba4c704239f34c4f43c5

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue May  5 13:35:27 2015 +0900

server: Return irp size separately from the output data.

---

 dlls/ntoskrnl.exe/ntoskrnl.c   |  7 +++++--
 include/wine/server_protocol.h |  6 +++++-
 server/device.c                | 14 +++++++++-----
 server/protocol.def            |  2 ++
 server/request.h               |  6 ++++--
 server/trace.c                 |  4 +++-
 6 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index fbea0f4..5443aa7 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -1028,8 +1028,11 @@ VOID WINAPI IoCompleteRequest( IRP *irp, UCHAR priority_boost )
             req->manager = wine_server_obj_handle( manager );
             req->handle  = wine_server_obj_handle( handle );
             req->status  = irp->IoStatus.u.Status;
-            if (irp->IoStatus.u.Status >= 0 && out_buff)
-                wine_server_add_data( req, out_buff, irp->IoStatus.Information );
+            if (irp->IoStatus.u.Status >= 0)
+            {
+                req->size = irp->IoStatus.Information;
+                if (out_buff) wine_server_add_data( req, out_buff, irp->IoStatus.Information );
+            }
             wine_server_call( req );
         }
         SERVER_END_REQ;
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index b09ca13..ef0d181 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -3134,7 +3134,9 @@ struct set_irp_result_request
     obj_handle_t manager;
     obj_handle_t handle;
     unsigned int status;
+    data_size_t  size;
     /* VARARG(data,bytes); */
+    char __pad_28[4];
 };
 struct set_irp_result_reply
 {
@@ -3152,7 +3154,9 @@ struct get_irp_result_request
 struct get_irp_result_reply
 {
     struct reply_header __header;
+    data_size_t    size;
     /* VARARG(out_data,bytes); */
+    char __pad_12[4];
 };
 
 
@@ -5973,6 +5977,6 @@ union generic_reply
     struct terminate_job_reply terminate_job_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 470
+#define SERVER_PROTOCOL_VERSION 471
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/device.c b/server/device.c
index f7fa970..aabff79 100644
--- a/server/device.c
+++ b/server/device.c
@@ -47,6 +47,7 @@ struct irp_call
     unsigned int           type;          /* request type (IRP_MJ_*) */
     unsigned int           status;        /* resulting status (or STATUS_PENDING) */
     ioctl_code_t           code;          /* ioctl code */
+    data_size_t            result;        /* size of result (input or output depending on the type) */
     data_size_t            in_size;       /* size of input data */
     void                  *in_data;       /* input data */
     data_size_t            out_size;      /* size of output data */
@@ -203,6 +204,7 @@ static struct irp_call *create_irp( struct device *device, unsigned int type, co
         irp->type     = type;
         irp->code     = 0;
         irp->status   = STATUS_PENDING;
+        irp->result   = 0;
         irp->in_size  = in_size;
         irp->in_data  = NULL;
         irp->out_size = out_size;
@@ -218,7 +220,7 @@ static struct irp_call *create_irp( struct device *device, unsigned int type, co
 }
 
 static void set_irp_result( struct irp_call *irp, unsigned int status,
-                            const void *out_data, data_size_t out_size )
+                            const void *out_data, data_size_t out_size, data_size_t result )
 {
     struct device *device = irp->device;
 
@@ -226,6 +228,7 @@ static void set_irp_result( struct irp_call *irp, unsigned int status,
 
     /* FIXME: handle the STATUS_PENDING case */
     irp->status = status;
+    irp->result = result;
     irp->out_size = min( irp->out_size, out_size );
     if (irp->out_size && !(irp->out_data = memdup( out_data, irp->out_size )))
         irp->out_size = 0;
@@ -233,7 +236,7 @@ static void set_irp_result( struct irp_call *irp, unsigned int status,
     irp->device = NULL;
     if (irp->async)
     {
-        if (irp->out_size) status = STATUS_ALERTED;
+        if (result) status = STATUS_ALERTED;
         async_terminate( irp->async, status );
         release_object( irp->async );
         irp->async = NULL;
@@ -385,7 +388,7 @@ static void delete_device( struct device *device )
     LIST_FOR_EACH_ENTRY_SAFE( irp, next, &device->requests, struct irp_call, dev_entry )
     {
         list_remove( &irp->mgr_entry );
-        set_irp_result( irp, STATUS_FILE_DELETED, NULL, 0 );
+        set_irp_result( irp, STATUS_FILE_DELETED, NULL, 0, 0 );
     }
     unlink_named_object( &device->obj );
     list_remove( &device->entry );
@@ -503,7 +506,7 @@ DECL_HANDLER(get_next_device_request)
         if ((irp = (struct irp_call *)get_handle_obj( current->process, req->prev,
                                                           0, &irp_call_ops )))
         {
-            set_irp_result( irp, req->status, NULL, 0 );
+            set_irp_result( irp, req->status, NULL, 0, 0 );
             close_handle( current->process, req->prev );  /* avoid an extra round-trip for close */
             release_object( irp );
         }
@@ -548,7 +551,7 @@ DECL_HANDLER(set_irp_result)
 
     if ((irp = (struct irp_call *)get_handle_obj( current->process, req->handle, 0, &irp_call_ops )))
     {
-        set_irp_result( irp, req->status, get_req_data(), get_req_data_size() );
+        set_irp_result( irp, req->status, get_req_data(), get_req_data_size(), req->size );
         close_handle( current->process, req->handle );  /* avoid an extra round-trip for close */
         release_object( irp );
     }
@@ -576,6 +579,7 @@ DECL_HANDLER(get_irp_result)
                 irp->out_data = NULL;
             }
         }
+        reply->size = irp->result;
         set_error( irp->status );
         list_remove( &irp->dev_entry );
         release_object( irp );  /* no longer on the device queue */
diff --git a/server/protocol.def b/server/protocol.def
index 7e4737a..51ad56b 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2267,6 +2267,7 @@ enum message_type
     obj_handle_t manager;         /* handle to the device manager */
     obj_handle_t handle;          /* handle to the irp */
     unsigned int status;          /* status of the irp */
+    data_size_t  size;            /* result size (input or output depending on the operation) */
     VARARG(data,bytes);           /* output data of the irp */
 @END
 
@@ -2276,6 +2277,7 @@ enum message_type
     obj_handle_t   handle;        /* handle to the device */
     client_ptr_t   user_arg;      /* user arg used to identify the request */
 @REPLY
+    data_size_t    size;          /* result size (input or output depending on the operation) */
     VARARG(out_data,bytes);       /* irp output data */
 @END
 
diff --git a/server/request.h b/server/request.h
index bce80a1..0a6096c 100644
--- a/server/request.h
+++ b/server/request.h
@@ -1530,11 +1530,13 @@ C_ASSERT( sizeof(struct ioctl_reply) == 16 );
 C_ASSERT( FIELD_OFFSET(struct set_irp_result_request, manager) == 12 );
 C_ASSERT( FIELD_OFFSET(struct set_irp_result_request, handle) == 16 );
 C_ASSERT( FIELD_OFFSET(struct set_irp_result_request, status) == 20 );
-C_ASSERT( sizeof(struct set_irp_result_request) == 24 );
+C_ASSERT( FIELD_OFFSET(struct set_irp_result_request, size) == 24 );
+C_ASSERT( sizeof(struct set_irp_result_request) == 32 );
 C_ASSERT( FIELD_OFFSET(struct get_irp_result_request, handle) == 12 );
 C_ASSERT( FIELD_OFFSET(struct get_irp_result_request, user_arg) == 16 );
 C_ASSERT( sizeof(struct get_irp_result_request) == 24 );
-C_ASSERT( sizeof(struct get_irp_result_reply) == 8 );
+C_ASSERT( FIELD_OFFSET(struct get_irp_result_reply, size) == 8 );
+C_ASSERT( sizeof(struct get_irp_result_reply) == 16 );
 C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, access) == 12 );
 C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, attributes) == 16 );
 C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, options) == 20 );
diff --git a/server/trace.c b/server/trace.c
index e9127b4..27180ed 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2745,6 +2745,7 @@ static void dump_set_irp_result_request( const struct set_irp_result_request *re
     fprintf( stderr, " manager=%04x", req->manager );
     fprintf( stderr, ", handle=%04x", req->handle );
     fprintf( stderr, ", status=%08x", req->status );
+    fprintf( stderr, ", size=%u", req->size );
     dump_varargs_bytes( ", data=", cur_size );
 }
 
@@ -2756,7 +2757,8 @@ static void dump_get_irp_result_request( const struct get_irp_result_request *re
 
 static void dump_get_irp_result_reply( const struct get_irp_result_reply *req )
 {
-    dump_varargs_bytes( " out_data=", cur_size );
+    fprintf( stderr, " size=%u", req->size );
+    dump_varargs_bytes( ", out_data=", cur_size );
 }
 
 static void dump_create_named_pipe_request( const struct create_named_pipe_request *req )




More information about the wine-cvs mailing list