From 8930427b21d5c8615a3dc94c5031bcf1e1e72c45 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard <julliard@winehq.org> Date: Mon, 20 Nov 2006 14:14:04 +0100 Subject: [PATCH] server: Return an fd type in the get_handle_fd request. --- include/wine/server_protocol.h | 15 ++++++++++++++- server/change.c | 15 +++++---------- server/fd.c | 25 +++++++++++++++---------- server/file.c | 9 +++++---- server/file.h | 4 ++-- server/mailslot.c | 21 ++++++++++++--------- server/named_pipe.c | 29 ++++++++++++++--------------- server/protocol.def | 13 +++++++++++++ server/serial.c | 14 +++++++------- server/sock.c | 14 +++++++------- server/trace.c | 1 + 11 files changed, 95 insertions(+), 65 deletions(-) diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 09b8906cf65..d068d1f0ab3 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -844,8 +844,21 @@ struct get_handle_fd_request struct get_handle_fd_reply { struct reply_header __header; + int type; int flags; }; +enum server_fd_type +{ + FD_TYPE_INVALID, + FD_TYPE_FILE, + FD_TYPE_DIR, + FD_TYPE_SOCKET, + FD_TYPE_SERIAL, + FD_TYPE_PIPE, + FD_TYPE_MAILSLOT, + FD_TYPE_DEVICE, + FD_TYPE_NB_TYPES +}; #define FD_FLAG_OVERLAPPED 0x01 #define FD_FLAG_TIMEOUT 0x02 #define FD_FLAG_RECV_SHUTDOWN 0x04 @@ -4404,6 +4417,6 @@ union generic_reply struct query_symlink_reply query_symlink_reply; }; -#define SERVER_PROTOCOL_VERSION 259 +#define SERVER_PROTOCOL_VERSION 260 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/change.c b/server/change.c index 5468e85f8b9..c90adbe7da1 100644 --- a/server/change.c +++ b/server/change.c @@ -182,7 +182,7 @@ static const struct object_ops dir_ops = }; static int dir_get_poll_events( struct fd *fd ); -static int dir_get_info( struct fd *fd ); +static enum server_fd_type dir_get_info( struct fd *fd, int *flags ); static void dir_cancel_async( struct fd *fd ); static const struct fd_ops dir_fd_ops = @@ -372,9 +372,10 @@ static int dir_get_poll_events( struct fd *fd ) return 0; } -static int dir_get_info( struct fd *fd ) +static enum server_fd_type dir_get_info( struct fd *fd, int *flags ) { - return 0; + *flags = 0; + return FD_TYPE_DIR; } static void dir_cancel_async( struct fd *fd ) @@ -550,14 +551,13 @@ static struct inode *inode_from_name( struct inode *inode, const char *name ) static int inotify_get_poll_events( struct fd *fd ); static void inotify_poll_event( struct fd *fd, int event ); -static int inotify_get_info( struct fd *fd ); static const struct fd_ops inotify_fd_ops = { inotify_get_poll_events, /* get_poll_events */ inotify_poll_event, /* poll_event */ no_flush, /* flush */ - inotify_get_info, /* get_file_info */ + no_get_file_info, /* get_file_info */ default_fd_queue_async, /* queue_async */ default_fd_cancel_async, /* cancel_async */ }; @@ -823,11 +823,6 @@ static void inotify_poll_event( struct fd *fd, int event ) } } -static int inotify_get_info( struct fd *fd ) -{ - return 0; -} - static inline struct fd *create_inotify_fd( void ) { int unix_fd; diff --git a/server/fd.c b/server/fd.c index 3848d101a56..157db69f956 100644 --- a/server/fd.c +++ b/server/fd.c @@ -1774,9 +1774,10 @@ void fd_queue_async_timeout( struct fd *fd, void *apc, void *user, void *io_sb, const struct timeval *timeout ) { struct list *queue; - int events; + int events, flags; - if (!(fd->fd_ops->get_file_info( fd ) & (FD_FLAG_OVERLAPPED|FD_FLAG_TIMEOUT))) + fd->fd_ops->get_file_info( fd, &flags ); + if (!(flags & (FD_FLAG_OVERLAPPED|FD_FLAG_TIMEOUT))) { set_error( STATUS_INVALID_HANDLE ); return; @@ -1824,10 +1825,10 @@ int no_flush( struct fd *fd, struct event **event ) } /* default get_file_info() routine */ -int no_get_file_info( struct fd *fd ) +enum server_fd_type no_get_file_info( struct fd *fd, int *flags ) { - set_error( STATUS_OBJECT_TYPE_MISMATCH ); - return 0; + *flags = 0; + return FD_TYPE_INVALID; } /* default queue_async() routine */ @@ -1955,13 +1956,17 @@ DECL_HANDLER(get_handle_fd) if ((fd = get_handle_fd_obj( current->process, req->handle, req->access ))) { - if (!req->cached) + reply->type = fd->fd_ops->get_file_info( fd, &reply->flags ); + if (reply->type != FD_TYPE_INVALID) { - int unix_fd = get_unix_fd( fd ); - if (unix_fd != -1) send_client_fd( current->process, unix_fd, req->handle ); + if (fd->inode && fd->inode->device->removable) reply->flags |= FD_FLAG_REMOVABLE; + if (!req->cached) + { + int unix_fd = get_unix_fd( fd ); + if (unix_fd != -1) send_client_fd( current->process, unix_fd, req->handle ); + } } - reply->flags = fd->fd_ops->get_file_info( fd ); - if (fd->inode && fd->inode->device->removable) reply->flags |= FD_FLAG_REMOVABLE; + else set_error( STATUS_OBJECT_TYPE_MISMATCH ); release_object( fd ); } } diff --git a/server/file.c b/server/file.c index ec34295a171..d84e4f31c51 100644 --- a/server/file.c +++ b/server/file.c @@ -70,7 +70,7 @@ static void file_destroy( struct object *obj ); static int file_get_poll_events( struct fd *fd ); static int file_flush( struct fd *fd, struct event **event ); -static int file_get_info( struct fd *fd ); +static enum server_fd_type file_get_info( struct fd *fd, int *flags ); static const struct object_ops file_ops = { @@ -238,12 +238,13 @@ static int file_flush( struct fd *fd, struct event **event ) return ret; } -static int file_get_info( struct fd *fd ) +static enum server_fd_type file_get_info( struct fd *fd, int *flags ) { struct file *file = get_fd_user( fd ); - if (is_overlapped( file )) return FD_FLAG_OVERLAPPED; - else return 0; + *flags = 0; + if (is_overlapped( file )) *flags |= FD_FLAG_OVERLAPPED; + return FD_TYPE_FILE; } static struct fd *file_get_fd( struct object *obj ) diff --git a/server/file.h b/server/file.h index fc8b9041d20..6edb59f1600 100644 --- a/server/file.h +++ b/server/file.h @@ -37,7 +37,7 @@ struct fd_ops /* flush the object buffers */ int (*flush)(struct fd *, struct event **); /* get file information */ - int (*get_file_info)(struct fd *); + enum server_fd_type (*get_file_info)(struct fd *fd, int *flags); /* queue an async operation */ void (*queue_async)(struct fd *, void* apc, void* user, void* io_sb, int type, int count); /* cancel an async operation */ @@ -72,7 +72,7 @@ extern void fd_queue_async_timeout( struct fd *fd, void *apc, void *user, void * extern void default_fd_queue_async( struct fd *fd, void *apc, void *user, void *io_sb, int type, int count ); extern void default_fd_cancel_async( struct fd *fd ); extern int no_flush( struct fd *fd, struct event **event ); -extern int no_get_file_info( struct fd *fd ); +extern enum server_fd_type no_get_file_info( struct fd *fd, int *flags ); extern void no_queue_async( struct fd *fd, void* apc, void* user, void* io_sb, int type, int count); extern void no_cancel_async( struct fd *fd ); extern void main_loop(void); diff --git a/server/mailslot.c b/server/mailslot.c index 578f75131c6..d9537f42814 100644 --- a/server/mailslot.c +++ b/server/mailslot.c @@ -84,7 +84,7 @@ static const struct object_ops mailslot_ops = mailslot_destroy /* destroy */ }; -static int mailslot_get_info( struct fd * ); +static enum server_fd_type mailslot_get_info( struct fd *fd, int *flags ); static void mailslot_queue_async( struct fd *, void*, void*, void*, int, int ); static const struct fd_ops mailslot_fd_ops = @@ -128,7 +128,7 @@ static const struct object_ops mail_writer_ops = mail_writer_destroy /* destroy */ }; -static int mail_writer_get_info( struct fd *fd ); +static enum server_fd_type mail_writer_get_info( struct fd *fd, int *flags ); static const struct fd_ops mail_writer_fd_ops = { @@ -153,7 +153,7 @@ static struct fd *mailslot_device_get_fd( struct object *obj ); static struct object *mailslot_device_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ); static void mailslot_device_destroy( struct object *obj ); -static int mailslot_device_get_file_info( struct fd *fd ); +static enum server_fd_type mailslot_device_get_file_info( struct fd *fd, int *flags ); static const struct object_ops mailslot_device_ops = { @@ -212,11 +212,12 @@ static int mailslot_message_count(struct mailslot *mailslot) return (poll( &pfd, 1, 0 ) == 1) ? 1 : 0; } -static int mailslot_get_info( struct fd *fd ) +static enum server_fd_type mailslot_get_info( struct fd *fd, int *flags ) { struct mailslot *mailslot = get_fd_user( fd ); assert( mailslot->obj.ops == &mailslot_ops ); - return FD_FLAG_TIMEOUT | FD_FLAG_AVAILABLE; + *flags = FD_FLAG_TIMEOUT | FD_FLAG_AVAILABLE; + return FD_TYPE_MAILSLOT; } static struct fd *mailslot_get_fd( struct object *obj ) @@ -298,9 +299,10 @@ static void mailslot_device_destroy( struct object *obj ) free( device->mailslots ); } -static int mailslot_device_get_file_info( struct fd *fd ) +static enum server_fd_type mailslot_device_get_file_info( struct fd *fd, int *flags ) { - return 0; + *flags = 0; + return FD_TYPE_DEVICE; } void create_mailslot_device( struct directory *root, const struct unicode_str *name ) @@ -396,9 +398,10 @@ static void mail_writer_destroy( struct object *obj) release_object( writer->mailslot ); } -static int mail_writer_get_info( struct fd *fd ) +static enum server_fd_type mail_writer_get_info( struct fd *fd, int *flags ) { - return 0; + *flags = 0; + return FD_TYPE_MAILSLOT; } static struct fd *mail_writer_get_fd( struct object *obj ) diff --git a/server/named_pipe.c b/server/named_pipe.c index e58f5b07825..8cbd7e57df5 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -134,7 +134,7 @@ static void pipe_server_dump( struct object *obj, int verbose ); static struct fd *pipe_server_get_fd( struct object *obj ); static void pipe_server_destroy( struct object *obj); static int pipe_server_flush( struct fd *fd, struct event **event ); -static int pipe_server_get_info( struct fd *fd ); +static enum server_fd_type pipe_server_get_info( struct fd *fd, int *flags ); static const struct object_ops pipe_server_ops = { @@ -167,7 +167,7 @@ static void pipe_client_dump( struct object *obj, int verbose ); static struct fd *pipe_client_get_fd( struct object *obj ); static void pipe_client_destroy( struct object *obj ); static int pipe_client_flush( struct fd *fd, struct event **event ); -static int pipe_client_get_info( struct fd *fd ); +static enum server_fd_type pipe_client_get_info( struct fd *fd, int *flags ); static const struct object_ops pipe_client_ops = { @@ -200,7 +200,7 @@ static struct fd *named_pipe_device_get_fd( struct object *obj ); static struct object *named_pipe_device_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ); static void named_pipe_device_destroy( struct object *obj ); -static int named_pipe_device_get_file_info( struct fd *fd ); +static enum server_fd_type named_pipe_device_get_file_info( struct fd *fd, int *flags ); static const struct object_ops named_pipe_device_ops = { @@ -438,9 +438,10 @@ static void named_pipe_device_destroy( struct object *obj ) free( device->pipes ); } -static int named_pipe_device_get_file_info( struct fd *fd ) +static enum server_fd_type named_pipe_device_get_file_info( struct fd *fd, int *flags ) { - return 0; + *flags = 0; + return FD_TYPE_DEVICE; } void create_named_pipe_device( struct directory *root, const struct unicode_str *name ) @@ -545,24 +546,22 @@ static inline int is_overlapped( unsigned int options ) return !(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)); } -static int pipe_server_get_info( struct fd *fd ) +static enum server_fd_type pipe_server_get_info( struct fd *fd, int *flags ) { struct pipe_server *server = get_fd_user( fd ); - int flags = FD_FLAG_AVAILABLE; - - if (is_overlapped( server->options )) flags |= FD_FLAG_OVERLAPPED; - return flags; + *flags = FD_FLAG_AVAILABLE; + if (is_overlapped( server->options )) *flags |= FD_FLAG_OVERLAPPED; + return FD_TYPE_PIPE; } -static int pipe_client_get_info( struct fd *fd ) +static enum server_fd_type pipe_client_get_info( struct fd *fd, int *flags ) { struct pipe_client *client = get_fd_user( fd ); - int flags = FD_FLAG_AVAILABLE; - - if (is_overlapped( client->flags )) flags |= FD_FLAG_OVERLAPPED; - return flags; + *flags = FD_FLAG_AVAILABLE; + if (is_overlapped( client->flags )) *flags |= FD_FLAG_OVERLAPPED; + return FD_TYPE_PIPE; } static struct named_pipe *create_named_pipe( struct directory *root, const struct unicode_str *name, diff --git a/server/protocol.def b/server/protocol.def index 192b8a39cfb..e8f219642c3 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -661,8 +661,21 @@ enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT }; unsigned int access; /* wanted access rights */ int cached; /* is it cached on the client already? */ @REPLY + int type; /* file type (see below) */ int flags; /* file read/write flags (see below) */ @END +enum server_fd_type +{ + FD_TYPE_INVALID, /* invalid file (no associated fd) */ + FD_TYPE_FILE, /* regular file */ + FD_TYPE_DIR, /* directory */ + FD_TYPE_SOCKET, /* socket */ + FD_TYPE_SERIAL, /* serial port */ + FD_TYPE_PIPE, /* named pipe */ + FD_TYPE_MAILSLOT, /* mailslot */ + FD_TYPE_DEVICE, /* Windows device file */ + FD_TYPE_NB_TYPES +}; #define FD_FLAG_OVERLAPPED 0x01 /* fd opened in overlapped mode */ #define FD_FLAG_TIMEOUT 0x02 /* read/write is synchronous */ #define FD_FLAG_RECV_SHUTDOWN 0x04 diff --git a/server/serial.c b/server/serial.c index a7722565d91..03909d0710e 100644 --- a/server/serial.c +++ b/server/serial.c @@ -63,7 +63,7 @@ static void serial_destroy(struct object *obj); static int serial_get_poll_events( struct fd *fd ); static void serial_poll_event( struct fd *fd, int event ); -static int serial_get_info( struct fd *fd ); +static enum server_fd_type serial_get_info( struct fd *fd, int *flags ); static int serial_flush( struct fd *fd, struct event **event ); static void serial_queue_async( struct fd *fd, void *apc, void *user, void *iosb, int type, int count ); static void serial_cancel_async( struct fd *fd ); @@ -205,22 +205,22 @@ static int serial_get_poll_events( struct fd *fd ) return events; } -static int serial_get_info( struct fd *fd ) +static enum server_fd_type serial_get_info( struct fd *fd, int *flags ) { - int flags = 0; struct serial *serial = get_fd_user( fd ); assert( serial->obj.ops == &serial_ops ); + *flags = 0; if (!(serial->options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT))) - flags |= FD_FLAG_OVERLAPPED; + *flags |= FD_FLAG_OVERLAPPED; else if (!(serial->readinterval == MAXDWORD && serial->readmult == 0 && serial->readconst == 0)) - flags |= FD_FLAG_TIMEOUT; + *flags |= FD_FLAG_TIMEOUT; if (serial->readinterval == MAXDWORD && serial->readmult == 0 && serial->readconst == 0) - flags |= FD_FLAG_AVAILABLE; + *flags |= FD_FLAG_AVAILABLE; - return flags; + return FD_TYPE_SERIAL; } static void serial_poll_event(struct fd *fd, int event) diff --git a/server/sock.c b/server/sock.c index 963746938b4..a98057f17f0 100644 --- a/server/sock.c +++ b/server/sock.c @@ -95,7 +95,7 @@ static void sock_destroy( struct object *obj ); static int sock_get_poll_events( struct fd *fd ); static void sock_poll_event( struct fd *fd, int event ); -static int sock_get_info( struct fd *fd ); +static enum server_fd_type sock_get_info( struct fd *fd, int *flags ); static void sock_queue_async( struct fd *fd, void *apc, void *user, void *iosb, int type, int count ); static void sock_cancel_async( struct fd *fd ); @@ -493,19 +493,19 @@ static int sock_get_poll_events( struct fd *fd ) return ev; } -static int sock_get_info( struct fd *fd ) +static enum server_fd_type sock_get_info( struct fd *fd, int *flags ) { - int flags = FD_FLAG_AVAILABLE; struct sock *sock = get_fd_user( fd ); assert( sock->obj.ops == &sock_ops ); - if (sock->flags & WSA_FLAG_OVERLAPPED) flags |= FD_FLAG_OVERLAPPED; + *flags = FD_FLAG_AVAILABLE; + if (sock->flags & WSA_FLAG_OVERLAPPED) *flags |= FD_FLAG_OVERLAPPED; if ( sock->type != SOCK_STREAM || sock->state & FD_WINE_CONNECTED ) { - if ( !(sock->state & FD_READ ) ) flags |= FD_FLAG_RECV_SHUTDOWN; - if ( !(sock->state & FD_WRITE ) ) flags |= FD_FLAG_SEND_SHUTDOWN; + if ( !(sock->state & FD_READ ) ) *flags |= FD_FLAG_RECV_SHUTDOWN; + if ( !(sock->state & FD_WRITE ) ) *flags |= FD_FLAG_SEND_SHUTDOWN; } - return flags; + return FD_TYPE_SOCKET; } static void sock_queue_async( struct fd *fd, void *apc, void *user, void *iosb, diff --git a/server/trace.c b/server/trace.c index 50268f94222..0e07987ff6b 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1104,6 +1104,7 @@ static void dump_get_handle_fd_request( const struct get_handle_fd_request *req static void dump_get_handle_fd_reply( const struct get_handle_fd_reply *req ) { + fprintf( stderr, " type=%d,", req->type ); fprintf( stderr, " flags=%d", req->flags ); } -- GitLab