server: Return an fd type in the get_handle_fd request.

This commit is contained in:
Alexandre Julliard 2006-11-20 14:14:04 +01:00
parent 0427c0ded3
commit 8930427b21
11 changed files with 95 additions and 65 deletions

View File

@ -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 */

View File

@ -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;

View File

@ -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 );
}
}

View File

@ -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 )

View File

@ -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);

View File

@ -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 )

View File

@ -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,

View File

@ -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

View File

@ -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)

View File

@ -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,

View File

@ -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 );
}