Jacek Caban : server: Pass file object handle in IRP_CALL_CREATE request.

Alexandre Julliard julliard at winehq.org
Fri May 3 15:46:17 CDT 2019


Module: wine
Branch: master
Commit: 29914d583fe098521472332687b8da69fc692690
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=29914d583fe098521472332687b8da69fc692690

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri May  3 15:40:40 2019 +0200

server: Pass file object handle in IRP_CALL_CREATE request.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 include/wine/server_protocol.h |  3 +-
 server/device.c                | 65 ++++++++++++++++++++++++++++--------------
 server/protocol.def            |  1 +
 server/trace.c                 |  2 +-
 4 files changed, 48 insertions(+), 23 deletions(-)

diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 9c5c196..17d2654 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -662,6 +662,7 @@ typedef union
         unsigned int     sharing;
         unsigned int     options;
         client_ptr_t     device;
+        obj_handle_t     file;
     } create;
     struct
     {
@@ -6694,6 +6695,6 @@ union generic_reply
     struct resume_process_reply resume_process_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 581
+#define SERVER_PROTOCOL_VERSION 582
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/device.c b/server/device.c
index 61831b4..e2364d2 100644
--- a/server/device.c
+++ b/server/device.c
@@ -539,32 +539,49 @@ static void device_file_destroy( struct object *obj )
     release_object( file->device );
 }
 
-static void fill_irp_params( struct device_manager *manager, struct irp_call *irp, irp_params_t *params )
+static int fill_irp_params( struct device_manager *manager, struct irp_call *irp, irp_params_t *params )
 {
-    *params = irp->params;
-
-    switch (params->type)
+    switch (irp->params.type)
     {
     case IRP_CALL_NONE:
-    case IRP_CALL_CREATE:
     case IRP_CALL_FREE:
         break;
+    case IRP_CALL_CREATE:
+        irp->params.create.file    = alloc_handle( current->process, irp->file,
+                                                   irp->params.create.access, 0 );
+        if (!irp->params.create.file) return 0;
+        break;
     case IRP_CALL_CLOSE:
-        params->close.file = get_kernel_object_ptr( manager, &irp->file->obj );
+        irp->params.close.file     = get_kernel_object_ptr( manager, &irp->file->obj );
         break;
     case IRP_CALL_READ:
-        params->read.file     = get_kernel_object_ptr( manager, &irp->file->obj );
-        params->read.out_size = irp->iosb->out_size;
+        irp->params.read.file      = get_kernel_object_ptr( manager, &irp->file->obj );
+        irp->params.read.out_size  = irp->iosb->out_size;
         break;
     case IRP_CALL_WRITE:
-        params->write.file = get_kernel_object_ptr( manager, &irp->file->obj );
+        irp->params.write.file     = get_kernel_object_ptr( manager, &irp->file->obj );
         break;
     case IRP_CALL_FLUSH:
-        params->flush.file = get_kernel_object_ptr( manager, &irp->file->obj );
+        irp->params.flush.file     = get_kernel_object_ptr( manager, &irp->file->obj );
         break;
     case IRP_CALL_IOCTL:
-        params->ioctl.file     = get_kernel_object_ptr( manager, &irp->file->obj );
-        params->ioctl.out_size = irp->iosb->out_size;
+        irp->params.ioctl.file     = get_kernel_object_ptr( manager, &irp->file->obj );
+        irp->params.ioctl.out_size = irp->iosb->out_size;
+        break;
+    }
+
+    *params = irp->params;
+    return 1;
+}
+
+static void free_irp_params( struct irp_call *irp )
+{
+    switch (irp->params.type)
+    {
+    case IRP_CALL_CREATE:
+        close_handle( current->process, irp->params.create.file );
+        break;
+    default:
         break;
     }
 }
@@ -875,15 +892,17 @@ DECL_HANDLER(get_next_device_request)
             close_handle( current->process, req->prev );  /* avoid an extra round-trip for close */
             release_object( irp );
         }
-        clear_error();
     }
 
     if (manager->current_call)
     {
+        free_irp_params( manager->current_call );
         release_object( manager->current_call );
         manager->current_call = NULL;
     }
 
+    clear_error();
+
     if ((ptr = list_head( &manager->requests )))
     {
         irp = LIST_ENTRY( ptr, struct irp_call, mgr_entry );
@@ -897,14 +916,18 @@ DECL_HANDLER(get_next_device_request)
         if (iosb->in_size > get_reply_max_size()) set_error( STATUS_BUFFER_OVERFLOW );
         else if (!irp->file || (reply->next = alloc_handle( current->process, irp, 0, 0 )))
         {
-            fill_irp_params( manager, irp, &reply->params );
-            set_reply_data_ptr( iosb->in_data, iosb->in_size );
-            iosb->in_data = NULL;
-            iosb->in_size = 0;
-            list_remove( &irp->mgr_entry );
-            list_init( &irp->mgr_entry );
-            if (irp->file) grab_object( irp ); /* we already own the object if it's only on manager queue */
-            manager->current_call = irp;
+            if (fill_irp_params( manager, irp, &reply->params ))
+            {
+                set_reply_data_ptr( iosb->in_data, iosb->in_size );
+                iosb->in_data = NULL;
+                iosb->in_size = 0;
+                list_remove( &irp->mgr_entry );
+                list_init( &irp->mgr_entry );
+                /* we already own the object if it's only on manager queue */
+                if (irp->file) grab_object( irp );
+                manager->current_call = irp;
+            }
+            else close_handle( current->process, reply->next );
         }
     }
     else set_error( STATUS_PENDING );
diff --git a/server/protocol.def b/server/protocol.def
index 15ee31d..fc7c4d0 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -678,6 +678,7 @@ typedef union
         unsigned int     sharing;   /* sharing flags */
         unsigned int     options;   /* file options */
         client_ptr_t     device;    /* opaque ptr for the device */
+        obj_handle_t     file;      /* file handle */
     } create;
     struct
     {
diff --git a/server/trace.c b/server/trace.c
index b5f3008..f149ed2 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -326,7 +326,7 @@ static void dump_irp_params( const char *prefix, const irp_params_t *data )
         fprintf( stderr, "%s{CREATE,access=%08x,sharing=%08x,options=%08x",
                  prefix, data->create.access, data->create.sharing, data->create.options );
         dump_uint64( ",device=", &data->create.device );
-        fputc( '}', stderr );
+        fprintf( stderr, ",file=%08x}", data->create.file );
         break;
     case IRP_CALL_CLOSE:
         fprintf( stderr, "%s{CLOSE", prefix );




More information about the wine-cvs mailing list