diff --git a/server/device.c b/server/device.c index 975507e42f9..a7dce3bb78d 100644 --- a/server/device.c +++ b/server/device.c @@ -176,9 +176,9 @@ static int device_file_close_handle( struct object *obj, struct process *process 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, - file_pos_t pos ); + file_pos_t pos, struct iosb *iosb ); static obj_handle_t device_file_write( struct fd *fd, const async_data_t *async_data, int blocking, - file_pos_t pos, data_size_t *written ); + file_pos_t pos, struct iosb *iosb ); static obj_handle_t device_file_flush( struct fd *fd, const async_data_t *async_data, int blocking ); static obj_handle_t device_file_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data, int blocking ); @@ -246,8 +246,7 @@ static void irp_call_destroy( struct object *obj ) if (irp->thread) release_object( irp->thread ); } -static struct irp_call *create_irp( struct device_file *file, const irp_params_t *params, - const void *in_data, data_size_t in_size, data_size_t out_size ) +static struct irp_call *create_irp( struct device_file *file, const irp_params_t *params, struct iosb *iosb ) { struct irp_call *irp; @@ -264,7 +263,11 @@ static struct irp_call *create_irp( struct device_file *file, const irp_params_t irp->async = NULL; irp->params = *params; - if (!(irp->iosb = create_iosb( in_data, in_size, out_size ))) + if (iosb) + { + irp->iosb = (struct iosb *)grab_object( iosb ); + } + else if (!(irp->iosb = create_iosb( NULL, 0, 0 ))) { release_object( irp ); irp = NULL; @@ -381,7 +384,7 @@ static struct object *device_open_file( struct object *obj, unsigned int access, params.create.options = options; params.create.device = file->device->user_ptr; - if ((irp = create_irp( file, ¶ms, NULL, 0, 0 ))) + if ((irp = create_irp( file, ¶ms, NULL ))) { add_irp_to_queue( file, irp, NULL ); release_object( irp ); @@ -417,7 +420,7 @@ static int device_file_close_handle( struct object *obj, struct process *process params.close.major = IRP_MJ_CLOSE; params.close.file = file->user_ptr; - if ((irp = create_irp( file, ¶ms, NULL, 0, 0 ))) + if ((irp = create_irp( file, ¶ms, NULL ))) { add_irp_to_queue( file, irp, NULL ); release_object( irp ); @@ -489,7 +492,7 @@ 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, - file_pos_t pos ) + file_pos_t pos, struct iosb *iosb ) { struct device_file *file = get_fd_user( fd ); struct irp_call *irp; @@ -502,7 +505,7 @@ static obj_handle_t device_file_read( struct fd *fd, const async_data_t *async_d params.read.pos = pos; params.read.file = file->user_ptr; - irp = create_irp( file, ¶ms, NULL, 0, get_reply_max_size() ); + irp = create_irp( file, ¶ms, iosb ); if (!irp) return 0; handle = queue_irp( file, irp, async_data, blocking ); @@ -511,7 +514,7 @@ static obj_handle_t device_file_read( struct fd *fd, const async_data_t *async_d } static obj_handle_t device_file_write( struct fd *fd, const async_data_t *async_data, int blocking, - file_pos_t pos, data_size_t *written ) + file_pos_t pos, struct iosb *iosb ) { struct device_file *file = get_fd_user( fd ); struct irp_call *irp; @@ -524,7 +527,7 @@ static obj_handle_t device_file_write( struct fd *fd, const async_data_t *async_ params.write.pos = pos; params.write.file = file->user_ptr; - irp = create_irp( file, ¶ms, get_req_data(), get_req_data_size(), 0 ); + irp = create_irp( file, ¶ms, iosb ); if (!irp) return 0; handle = queue_irp( file, irp, async_data, blocking ); @@ -543,7 +546,7 @@ static obj_handle_t device_file_flush( struct fd *fd, const async_data_t *async_ params.flush.major = IRP_MJ_FLUSH_BUFFERS; params.flush.file = file->user_ptr; - irp = create_irp( file, ¶ms, NULL, 0, 0 ); + irp = create_irp( file, ¶ms, NULL ); if (!irp) return 0; handle = queue_irp( file, irp, async_data, blocking ); @@ -558,14 +561,17 @@ static obj_handle_t device_file_ioctl( struct fd *fd, ioctl_code_t code, const a struct irp_call *irp; obj_handle_t handle; irp_params_t params; + struct iosb *iosb; memset( ¶ms, 0, sizeof(params) ); params.ioctl.major = IRP_MJ_DEVICE_CONTROL; params.ioctl.code = code; params.ioctl.file = file->user_ptr; - irp = create_irp( file, ¶ms, get_req_data(), get_req_data_size(), - get_reply_max_size() ); + iosb = create_iosb( get_req_data(), get_req_data_size(), get_reply_max_size() ); + if (!iosb) return 0; + irp = create_irp( file, ¶ms, iosb ); + release_object(iosb); if (!irp) return 0; handle = queue_irp( file, irp, async_data, blocking ); diff --git a/server/fd.c b/server/fd.c index 3ccd0f89525..732a5b798f3 100644 --- a/server/fd.c +++ b/server/fd.c @@ -2163,7 +2163,7 @@ static void unmount_device( struct fd *device_fd ) } /* default read() routine */ -obj_handle_t no_fd_read( struct fd *fd, const async_data_t *async, int blocking, file_pos_t pos ) +obj_handle_t no_fd_read( struct fd *fd, const async_data_t *async, int blocking, file_pos_t pos, struct iosb *iosb ) { set_error( STATUS_OBJECT_TYPE_MISMATCH ); return 0; @@ -2171,7 +2171,7 @@ obj_handle_t no_fd_read( struct fd *fd, const async_data_t *async, int blocking, /* default write() routine */ obj_handle_t no_fd_write( struct fd *fd, const async_data_t *async, int blocking, - file_pos_t pos, data_size_t *written ) + file_pos_t pos, struct iosb *iosb ) { set_error( STATUS_OBJECT_TYPE_MISMATCH ); return 0; @@ -2446,26 +2446,34 @@ DECL_HANDLER(get_handle_fd) DECL_HANDLER(read) { struct fd *fd = get_handle_fd_obj( current->process, req->async.handle, FILE_READ_DATA ); + struct iosb *iosb; - if (fd) + if (!fd) return; + + if ((iosb = create_iosb( NULL, 0, get_reply_max_size() ))) { - reply->wait = fd->fd_ops->read( fd, &req->async, req->blocking, req->pos ); + reply->wait = fd->fd_ops->read( fd, &req->async, req->blocking, req->pos, iosb ); reply->options = fd->options; - release_object( fd ); + release_object( iosb ); } + release_object( fd ); } /* perform a write on a file object */ DECL_HANDLER(write) { struct fd *fd = get_handle_fd_obj( current->process, req->async.handle, FILE_WRITE_DATA ); + struct iosb *iosb; - if (fd) + if (!fd) return; + + if ((iosb = create_iosb( get_req_data(), get_req_data_size(), 0 ))) { - reply->wait = fd->fd_ops->write( fd, &req->async, req->blocking, req->pos, &reply->size ); + reply->wait = fd->fd_ops->write( fd, &req->async, req->blocking, req->pos, iosb ); reply->options = fd->options; - release_object( fd ); + release_object( iosb ); } + release_object( fd ); } /* perform an ioctl on a file */ diff --git a/server/file.h b/server/file.h index 94322c75dd4..c5867a670f6 100644 --- a/server/file.h +++ b/server/file.h @@ -30,29 +30,6 @@ struct mapping; struct async_queue; struct completion; -/* operations valid on file descriptor objects */ -struct fd_ops -{ - /* get the events we want to poll() for on this object */ - int (*get_poll_events)(struct fd *); - /* a poll() event occurred */ - void (*poll_event)(struct fd *,int event); - /* get file information */ - enum server_fd_type (*get_fd_type)(struct fd *fd); - /* perform a read on the file */ - obj_handle_t (*read)(struct fd *, const async_data_t *, int, file_pos_t ); - /* perform a write on the file */ - obj_handle_t (*write)(struct fd *, const async_data_t *, int, file_pos_t, data_size_t * ); - /* flush the object buffers */ - obj_handle_t (*flush)(struct fd *, const async_data_t *, int); - /* perform an ioctl on the file */ - obj_handle_t (*ioctl)(struct fd *fd, ioctl_code_t code, const async_data_t *async, int blocking ); - /* queue an async operation */ - void (*queue_async)(struct fd *, const async_data_t *data, int type, int count); - /* selected events for async i/o need an update */ - void (*reselect_async)( struct fd *, struct async_queue *queue ); -}; - /* server-side representation of I/O status block */ struct iosb { @@ -65,6 +42,29 @@ struct iosb void *out_data; /* output data */ }; +/* operations valid on file descriptor objects */ +struct fd_ops +{ + /* get the events we want to poll() for on this object */ + int (*get_poll_events)(struct fd *); + /* a poll() event occurred */ + void (*poll_event)(struct fd *,int event); + /* get file information */ + enum server_fd_type (*get_fd_type)(struct fd *fd); + /* perform a read on the file */ + obj_handle_t (*read)(struct fd *, const async_data_t *, int, file_pos_t, struct iosb * ); + /* perform a write on the file */ + obj_handle_t (*write)(struct fd *, const async_data_t *, int, file_pos_t, struct iosb * ); + /* flush the object buffers */ + obj_handle_t (*flush)(struct fd *, const async_data_t *, int); + /* perform an ioctl on the file */ + obj_handle_t (*ioctl)(struct fd *fd, ioctl_code_t code, const async_data_t *async, int blocking ); + /* queue an async operation */ + void (*queue_async)(struct fd *, const async_data_t *data, int type, int count); + /* selected events for async i/o need an update */ + void (*reselect_async)( struct fd *, struct async_queue *queue ); +}; + /* file descriptor functions */ extern struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *user, @@ -100,9 +100,10 @@ extern void default_poll_event( struct fd *fd, int event ); extern struct async *fd_queue_async( struct fd *fd, const async_data_t *data, struct iosb *iosb, int type ); extern void fd_async_wake_up( struct fd *fd, int type, unsigned int status ); extern void fd_reselect_async( struct fd *fd, struct async_queue *queue ); -extern obj_handle_t no_fd_read( struct fd *fd, const async_data_t *async, int blocking, file_pos_t pos ); +extern obj_handle_t no_fd_read( struct fd *fd, const async_data_t *async, int blocking, file_pos_t pos, + struct iosb *iosb ); extern obj_handle_t no_fd_write( struct fd *fd, const async_data_t *async, int blocking, - file_pos_t pos, data_size_t *written ); + file_pos_t pos, struct iosb *iosb ); extern obj_handle_t no_fd_flush( struct fd *fd, const async_data_t *async, int blocking ); extern obj_handle_t no_fd_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async, int blocking ); extern obj_handle_t default_fd_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async, int blocking );