server: Infrastructure to return a wait handle for blocking ioctls.
diff --git a/server/fd.c b/server/fd.c
index c4a0288..11cf294 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1858,17 +1858,17 @@
}
/* default ioctl() routine */
-void default_fd_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async,
- const void *data, data_size_t size )
+obj_handle_t default_fd_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async,
+ const void *data, data_size_t size )
{
switch(code)
{
case FSCTL_DISMOUNT_VOLUME:
unmount_device( fd );
- break;
+ return 0;
default:
set_error( STATUS_NOT_SUPPORTED );
- break;
+ return 0;
}
}
@@ -1956,7 +1956,9 @@
if (fd)
{
- fd->fd_ops->ioctl( fd, req->code, &req->async, get_req_data(), get_req_data_size() );
+ reply->wait = fd->fd_ops->ioctl( fd, req->code, &req->async,
+ get_req_data(), get_req_data_size() );
+ reply->options = fd->options;
release_object( fd );
}
}
diff --git a/server/file.h b/server/file.h
index df5988d..4884c72 100644
--- a/server/file.h
+++ b/server/file.h
@@ -40,8 +40,8 @@
/* get file information */
enum server_fd_type (*get_fd_type)(struct fd *fd);
/* perform an ioctl on the file */
- void (*ioctl)(struct fd *fd, ioctl_code_t code, const async_data_t *async,
- const void *data, data_size_t size);
+ obj_handle_t (*ioctl)(struct fd *fd, ioctl_code_t code, const async_data_t *async,
+ const void *data, data_size_t size);
/* 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 */
@@ -79,8 +79,8 @@
extern struct async *fd_queue_async( struct fd *fd, const async_data_t *data, int type, int count );
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 void default_fd_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async,
- const void *data, data_size_t size );
+extern obj_handle_t default_fd_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async,
+ const void *data, data_size_t size );
extern void default_fd_queue_async( struct fd *fd, const async_data_t *data, int type, int count );
extern void default_fd_reselect_async( struct fd *fd, struct async_queue *queue );
extern void default_fd_cancel_async( struct fd *fd );
diff --git a/server/named_pipe.c b/server/named_pipe.c
index 801b4d7..9137bf6 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -139,8 +139,8 @@
static void pipe_server_destroy( struct object *obj);
static void pipe_server_flush( struct fd *fd, struct event **event );
static enum server_fd_type pipe_server_get_fd_type( struct fd *fd );
-static void pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async,
- const void *data, data_size_t size );
+static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async,
+ const void *data, data_size_t size );
static const struct object_ops pipe_server_ops =
{
@@ -215,8 +215,8 @@
unsigned int sharing, unsigned int options );
static void named_pipe_device_destroy( struct object *obj );
static enum server_fd_type named_pipe_device_get_fd_type( struct fd *fd );
-static void named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
- const void *data, data_size_t size );
+static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
+ const void *data, data_size_t size );
static const struct object_ops named_pipe_device_ops =
{
@@ -570,8 +570,8 @@
return FD_TYPE_PIPE;
}
-static void pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
- const void *data, data_size_t size )
+static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
+ const void *data, data_size_t size )
{
struct pipe_server *server = get_fd_user( fd );
struct async *async;
@@ -604,7 +604,7 @@
set_error( STATUS_INVALID_HANDLE );
break;
}
- break;
+ return 0;
case FSCTL_PIPE_DISCONNECT:
switch(server->state)
@@ -634,11 +634,10 @@
set_error( STATUS_PIPE_DISCONNECTED );
break;
}
- break;
+ return 0;
default:
- default_fd_ioctl( fd, code, async_data, data, size );
- break;
+ return default_fd_ioctl( fd, code, async_data, data, size );
}
}
@@ -809,8 +808,8 @@
return &client->obj;
}
-static void named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
- const void *data, data_size_t size )
+static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
+ const void *data, data_size_t size )
{
struct named_pipe_device *device = get_fd_user( fd );
@@ -827,14 +826,14 @@
size < FIELD_OFFSET(FILE_PIPE_WAIT_FOR_BUFFER, Name[buffer->NameLength/sizeof(WCHAR)]))
{
set_error( STATUS_INVALID_PARAMETER );
- break;
+ return 0;
}
name.str = buffer->Name;
name.len = (buffer->NameLength / sizeof(WCHAR)) * sizeof(WCHAR);
if (!(pipe = (struct named_pipe *)find_object( device->pipes, &name, OBJ_CASE_INSENSITIVE )))
{
set_error( STATUS_PIPE_NOT_AVAILABLE );
- break;
+ return 0;
}
if (!(server = find_available_server( pipe )))
{
@@ -843,7 +842,7 @@
if (!pipe->waiters && !(pipe->waiters = create_async_queue( NULL )))
{
release_object( pipe );
- break;
+ return 0;
}
if ((async = create_async( current, pipe->waiters, async_data )))
@@ -857,12 +856,11 @@
else release_object( server );
release_object( pipe );
- break;
+ return 0;
}
default:
- default_fd_ioctl( fd, code, async_data, data, size );
- break;
+ return default_fd_ioctl( fd, code, async_data, data, size );
}
}
diff --git a/server/protocol.def b/server/protocol.def
index 8e50119..dd59acb 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1973,6 +1973,8 @@
async_data_t async; /* async I/O parameters */
VARARG(in_data,bytes); /* ioctl input data */
@REPLY
+ obj_handle_t wait; /* handle to wait on for blocking ioctl */
+ unsigned int options; /* device open options */
VARARG(out_data,bytes); /* ioctl output data */
@END
diff --git a/server/trace.c b/server/trace.c
index 09af441..71e5cb0 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2418,6 +2418,8 @@
static void dump_ioctl_reply( const struct ioctl_reply *req )
{
+ fprintf( stderr, " wait=%p,", req->wait );
+ fprintf( stderr, " options=%08x,", req->options );
fprintf( stderr, " out_data=" );
dump_varargs_bytes( cur_size );
}