Module: wine Branch: master Commit: 350ee62ab4ea40904296dcf90cf052938ca4ae75 URL: http://source.winehq.org/git/wine.git/?a=commit;h=350ee62ab4ea40904296dcf90c...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Jul 8 18:05:04 2015 +0900
server: Queue an IRP_MJ_CLOSE request on file destruction.
---
include/wine/server_protocol.h | 8 +++++++- server/device.c | 24 +++++++++++++++++++++++- server/protocol.def | 6 ++++++ server/trace.c | 5 +++++ 4 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 8f18035..9807dcc 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -645,6 +645,12 @@ typedef union struct { unsigned int major; + int __pad; + client_ptr_t device; + } close; + struct + { + unsigned int major; unsigned int key; client_ptr_t device; file_pos_t pos; @@ -6089,6 +6095,6 @@ union generic_reply struct terminate_job_reply terminate_job_reply; };
-#define SERVER_PROTOCOL_VERSION 478 +#define SERVER_PROTOCOL_VERSION 479
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/device.c b/server/device.c index 021f11b..2bdf82a 100644 --- a/server/device.c +++ b/server/device.c @@ -170,6 +170,7 @@ struct device_file
static void device_file_dump( struct object *obj, int verbose ); static struct fd *device_file_get_fd( struct object *obj ); +static int device_file_close_handle( struct object *obj, struct process *process, obj_handle_t handle ); static void device_file_destroy( struct object *obj ); static enum server_fd_type device_file_get_fd_type( struct fd *fd ); static obj_handle_t device_file_read( struct fd *fd, const async_data_t *async_data, int blocking, @@ -196,7 +197,7 @@ static const struct object_ops device_file_ops = default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ no_open_file, /* open_file */ - no_close_handle, /* close_handle */ + device_file_close_handle, /* close_handle */ device_file_destroy /* destroy */ };
@@ -409,6 +410,27 @@ static struct fd *device_file_get_fd( struct object *obj ) return (struct fd *)grab_object( file->fd ); }
+static int device_file_close_handle( struct object *obj, struct process *process, obj_handle_t handle ) +{ + struct device_file *file = (struct device_file *)obj; + + if (file->device->manager && obj->handle_count == 1) /* last handle */ + { + struct irp_call *irp; + irp_params_t params; + + params.close.major = IRP_MJ_CLOSE; + params.close.device = file->device->user_ptr; + + if ((irp = create_irp( file, ¶ms, NULL, 0, 0 ))) + { + add_irp_to_queue( file, irp ); + release_object( irp ); + } + } + return 1; +} + static void device_file_destroy( struct object *obj ) { struct device_file *file = (struct device_file *)obj; diff --git a/server/protocol.def b/server/protocol.def index 5372c52..1578345 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -660,6 +660,12 @@ typedef union } create; struct { + unsigned int major; /* IRP_MJ_CLOSE */ + int __pad; + client_ptr_t device; /* opaque ptr for the device */ + } close; + struct + { unsigned int major; /* IRP_MJ_READ */ unsigned int key; /* driver key */ client_ptr_t device; /* opaque ptr for the device */ diff --git a/server/trace.c b/server/trace.c index 4c728ef..f24c368 100644 --- a/server/trace.c +++ b/server/trace.c @@ -322,6 +322,11 @@ static void dump_irp_params( const char *prefix, const irp_params_t *data ) dump_uint64( ",device=", &data->create.device ); fputc( '}', stderr ); break; + case IRP_MJ_CLOSE: + fprintf( stderr, "%s{major=CLOSE", prefix ); + dump_uint64( ",device=", &data->close.device ); + fputc( '}', stderr ); + break; case IRP_MJ_READ: fprintf( stderr, "%s{major=READ,key=%08x", prefix, data->read.key ); dump_uint64( ",pos=", &data->read.pos );