diff --git a/files/file.c b/files/file.c index 4dd4847cafe..06ea389c758 100644 --- a/files/file.c +++ b/files/file.c @@ -210,7 +210,7 @@ HANDLE FILE_DupUnixHandle( int fd, DWORD access, BOOL inherit ) * Retrieve the Unix handle corresponding to a file handle. * Returns -1 on failure. */ -int FILE_GetUnixHandleType( HANDLE handle, DWORD access, DWORD *type ) +static int FILE_GetUnixHandleType( HANDLE handle, DWORD access, enum fd_type *type, DWORD *flags ) { int ret, fd = -1; @@ -225,6 +225,7 @@ int FILE_GetUnixHandleType( HANDLE handle, DWORD access, DWORD *type ) fd = reply->fd; } if (type) *type = reply->type; + if (flags) *flags = reply->flags; } SERVER_END_REQ; if (ret) return -1; @@ -250,7 +251,7 @@ int FILE_GetUnixHandleType( HANDLE handle, DWORD access, DWORD *type ) */ int FILE_GetUnixHandle( HANDLE handle, DWORD access ) { - return FILE_GetUnixHandleType(handle, access, NULL); + return FILE_GetUnixHandleType( handle, access, NULL, NULL ); } /************************************************************************* @@ -1449,7 +1450,8 @@ BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead, LPDWORD bytesRead, LPOVERLAPPED overlapped ) { int unix_handle, result; - DWORD type; + enum fd_type type; + DWORD flags; TRACE("%d %p %ld %p %p\n", hFile, buffer, bytesToRead, bytesRead, overlapped ); @@ -1457,11 +1459,10 @@ BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead, if (bytesRead) *bytesRead = 0; /* Do this before anything else */ if (!bytesToRead) return TRUE; - unix_handle = FILE_GetUnixHandleType( hFile, GENERIC_READ, &type ); + unix_handle = FILE_GetUnixHandleType( hFile, GENERIC_READ, &type, &flags ); - switch (type) + if (flags & FD_FLAG_OVERLAPPED) { - case FD_TYPE_OVERLAPPED: if (unix_handle == -1) return FALSE; if ( (overlapped==NULL) || NtResetEvent( overlapped->hEvent, NULL ) ) { @@ -1506,13 +1507,16 @@ BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead, /* fail on return, with ERROR_IO_PENDING */ SetLastError(ERROR_IO_PENDING); return FALSE; - - case FD_TYPE_CONSOLE: - return ReadConsoleA(hFile, buffer, bytesToRead, bytesRead, NULL); - - case FD_TYPE_TIMEOUT: + } + if (flags & FD_FLAG_TIMEOUT) + { close(unix_handle); return FILE_TimeoutRead(hFile, buffer, bytesToRead, bytesRead); + } + switch(type) + { + case FD_TYPE_CONSOLE: + return ReadConsoleA(hFile, buffer, bytesToRead, bytesRead, NULL); default: /* normal unix files */ @@ -1668,7 +1672,8 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite, LPDWORD bytesWritten, LPOVERLAPPED overlapped ) { int unix_handle, result; - DWORD type; + enum fd_type type; + DWORD flags; TRACE("%d %p %ld %p %p\n", hFile, buffer, bytesToWrite, bytesWritten, overlapped ); @@ -1676,11 +1681,10 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite, if (bytesWritten) *bytesWritten = 0; /* Do this before anything else */ if (!bytesToWrite) return TRUE; - unix_handle = FILE_GetUnixHandleType( hFile, GENERIC_WRITE, &type ); + unix_handle = FILE_GetUnixHandleType( hFile, GENERIC_WRITE, &type, &flags ); - switch (type) + if (flags & FD_FLAG_OVERLAPPED) { - case FD_TYPE_OVERLAPPED: if (unix_handle == -1) return FALSE; if ( (overlapped==NULL) || NtResetEvent( overlapped->hEvent, NULL ) ) { @@ -1727,7 +1731,10 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite, /* fail on return, with ERROR_IO_PENDING */ SetLastError(ERROR_IO_PENDING); return FALSE; + } + switch(type) + { case FD_TYPE_CONSOLE: TRACE("%d %s %ld %p %p\n", hFile, debugstr_an(buffer, bytesToWrite), bytesToWrite, bytesWritten, overlapped ); diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 680285178dd..03c06b5853d 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -730,12 +730,16 @@ struct get_handle_fd_reply struct reply_header __header; int fd; int type; + int flags; }; -#define FD_TYPE_INVALID 0 -#define FD_TYPE_DEFAULT 1 -#define FD_TYPE_CONSOLE 2 -#define FD_TYPE_OVERLAPPED 3 -#define FD_TYPE_TIMEOUT 4 +enum fd_type +{ + FD_TYPE_INVALID, + FD_TYPE_DEFAULT, + FD_TYPE_CONSOLE +}; +#define FD_FLAG_OVERLAPPED 0x01 +#define FD_FLAG_TIMEOUT 0x02 @@ -3038,6 +3042,6 @@ union generic_reply struct get_window_properties_reply get_window_properties_reply; }; -#define SERVER_PROTOCOL_VERSION 68 +#define SERVER_PROTOCOL_VERSION 69 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/console.c b/server/console.c index 72717e76553..29f76e57770 100644 --- a/server/console.c +++ b/server/console.c @@ -25,7 +25,7 @@ static void console_input_destroy( struct object *obj ); static int console_input_signaled( struct object *obj, struct thread *thread ); /* common routine */ -static int console_get_file_info( struct object *obj, struct get_file_info_reply *reply ); +static int console_get_file_info( struct object *obj, struct get_file_info_reply *reply, int *flags ); static const struct object_ops console_input_ops = { @@ -785,7 +785,7 @@ static void console_input_dump( struct object *obj, int verbose ) console->active, console->evt ); } -static int console_get_file_info( struct object *obj, struct get_file_info_reply *reply ) +static int console_get_file_info( struct object *obj, struct get_file_info_reply *reply, int *flags ) { if (reply) { @@ -800,6 +800,7 @@ static int console_get_file_info( struct object *obj, struct get_file_info_reply reply->index_low = 0; reply->serial = 0; } + *flags = 0; return FD_TYPE_CONSOLE; } diff --git a/server/device.c b/server/device.c index c3601f22cda..872c243b895 100644 --- a/server/device.c +++ b/server/device.c @@ -29,7 +29,7 @@ struct device }; static void device_dump( struct object *obj, int verbose ); -static int device_get_info( struct object *obj, struct get_file_info_reply *reply ); +static int device_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ); static const struct object_ops device_ops = { @@ -65,7 +65,7 @@ static void device_dump( struct object *obj, int verbose ) fprintf( stderr, "Device id=%08x\n", dev->id ); } -static int device_get_info( struct object *obj, struct get_file_info_reply *reply ) +static int device_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ) { struct device *dev = (struct device *)obj; assert( obj->ops == &device_ops ); @@ -83,6 +83,7 @@ static int device_get_info( struct object *obj, struct get_file_info_reply *repl reply->index_low = 0; reply->serial = 0; } + *flags = 0; return FD_TYPE_DEFAULT; } diff --git a/server/file.c b/server/file.c index 351da8af49c..67805c2374b 100644 --- a/server/file.c +++ b/server/file.c @@ -53,7 +53,7 @@ static int file_get_poll_events( struct object *obj ); static void file_poll_event( struct object *obj, int event ); static int file_get_fd( struct object *obj ); static int file_flush( struct object *obj ); -static int file_get_info( struct object *obj, struct get_file_info_reply *reply ); +static int file_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ); static void file_destroy( struct object *obj ); static struct async_queue * file_queue_async(struct object *obj, struct async* async, int type, int count); @@ -303,7 +303,7 @@ static int file_flush( struct object *obj ) return ret; } -static int file_get_info( struct object *obj, struct get_file_info_reply *reply ) +static int file_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ) { struct stat st; struct file *file = (struct file *)obj; @@ -339,9 +339,8 @@ static int file_get_info( struct object *obj, struct get_file_info_reply *reply reply->index_low = st.st_ino; reply->serial = 0; /* FIXME */ } - - if (file->flags & FILE_FLAG_OVERLAPPED) return FD_TYPE_OVERLAPPED; - + *flags = 0; + if (file->flags & FILE_FLAG_OVERLAPPED) *flags |= FD_FLAG_OVERLAPPED; return FD_TYPE_DEFAULT; } @@ -587,7 +586,7 @@ DECL_HANDLER(get_handle_fd) if ((fd = obj->ops->get_fd( obj )) != -1) send_client_fd( current->process, fd, req->handle ); } - reply->type = obj->ops->get_file_info( obj, NULL ); + reply->type = obj->ops->get_file_info( obj, NULL, &reply->flags ); release_object( obj ); } } @@ -633,7 +632,8 @@ DECL_HANDLER(get_file_info) if ((obj = get_handle_obj( current->process, req->handle, 0, NULL ))) { - obj->ops->get_file_info( obj, reply ); + int flags; + obj->ops->get_file_info( obj, reply, &flags ); release_object( obj ); } } diff --git a/server/mapping.c b/server/mapping.c index a944d6a9fc3..2d63cc52aab 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -34,7 +34,7 @@ struct mapping }; static int mapping_get_fd( struct object *obj ); -static int mapping_get_info( struct object *obj, struct get_file_info_reply *reply ); +static int mapping_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ); static void mapping_dump( struct object *obj, int verbose ); static void mapping_destroy( struct object *obj ); @@ -264,9 +264,10 @@ static struct object *create_mapping( int size_high, int size_low, int protect, } if (!size_high && !size_low) { + int flags; struct get_file_info_reply reply; struct object *obj = (struct object *)mapping->file; - obj->ops->get_file_info( obj, &reply ); + obj->ops->get_file_info( obj, &reply, &flags ); size_high = reply.size_high; size_low = ROUND_SIZE( 0, reply.size_low ); } @@ -312,14 +313,14 @@ static int mapping_get_fd( struct object *obj ) return get_mmap_fd( mapping->file ); } -static int mapping_get_info( struct object *obj, struct get_file_info_reply *reply ) +static int mapping_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ) { struct mapping *mapping = (struct mapping *)obj; struct object *file = (struct object *)mapping->file; assert( obj->ops == &mapping_ops ); assert( file ); - return file->ops->get_file_info( file, reply ); + return file->ops->get_file_info( file, reply, flags ); } static void mapping_destroy( struct object *obj ) diff --git a/server/named_pipe.c b/server/named_pipe.c index 309407e5b01..bce7b233ace 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -87,7 +87,7 @@ static const struct object_ops named_pipe_ops = static void pipe_user_dump( struct object *obj, int verbose ); static void pipe_user_destroy( struct object *obj); static int pipe_user_get_fd( struct object *obj ); -static int pipe_user_get_info( struct object *obj, struct get_file_info_reply *reply ); +static int pipe_user_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ); static const struct object_ops pipe_user_ops = { @@ -182,7 +182,7 @@ static int pipe_user_get_fd( struct object *obj ) return user->obj.fd; } -static int pipe_user_get_info( struct object *obj, struct get_file_info_reply *reply ) +static int pipe_user_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ) { if (reply) { @@ -197,6 +197,7 @@ static int pipe_user_get_info( struct object *obj, struct get_file_info_reply *r reply->index_low = 0; reply->serial = 0; } + *flags = 0; return FD_TYPE_DEFAULT; } diff --git a/server/object.c b/server/object.c index 10770060ea1..2411eff5667 100644 --- a/server/object.c +++ b/server/object.c @@ -263,9 +263,10 @@ int no_flush( struct object *obj ) return 0; } -int no_get_file_info( struct object *obj, struct get_file_info_reply *info ) +int no_get_file_info( struct object *obj, struct get_file_info_reply *info, int *flags ) { set_error( STATUS_OBJECT_TYPE_MISMATCH ); + *flags = 0; return FD_TYPE_INVALID; } diff --git a/server/object.h b/server/object.h index 07230dadf0b..851c4462863 100644 --- a/server/object.h +++ b/server/object.h @@ -48,7 +48,7 @@ struct object_ops /* flush the object buffers */ int (*flush)(struct object *); /* get file information */ - int (*get_file_info)(struct object *,struct get_file_info_reply *); + int (*get_file_info)(struct object *,struct get_file_info_reply *, int *flags); /* queue an async operation */ struct async_queue* (*queue_async)(struct object *, struct async *async, int type, int count); /* destroy on refcount == 0 */ @@ -92,7 +92,7 @@ extern int no_add_queue( struct object *obj, struct wait_queue_entry *entry ); extern int no_satisfied( struct object *obj, struct thread *thread ); extern int no_get_fd( struct object *obj ); extern int no_flush( struct object *obj ); -extern int no_get_file_info( struct object *obj, struct get_file_info_reply *info ); +extern int no_get_file_info( struct object *obj, struct get_file_info_reply *info, int *flags ); extern void no_destroy( struct object *obj ); extern int default_poll_add_queue( struct object *obj, struct wait_queue_entry *entry ); extern void default_poll_remove_queue( struct object *obj, struct wait_queue_entry *entry ); diff --git a/server/pipe.c b/server/pipe.c index d1f02b174ea..5dccae2b8f8 100644 --- a/server/pipe.c +++ b/server/pipe.c @@ -37,7 +37,7 @@ struct pipe static void pipe_dump( struct object *obj, int verbose ); static int pipe_get_poll_events( struct object *obj ); static int pipe_get_fd( struct object *obj ); -static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply ); +static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ); static void pipe_destroy( struct object *obj ); static const struct object_ops pipe_ops = @@ -125,7 +125,7 @@ static int pipe_get_fd( struct object *obj ) return pipe->obj.fd; } -static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply ) +static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ) { if (reply) { @@ -140,6 +140,7 @@ static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply reply->index_low = 0; reply->serial = 0; } + *flags = 0; return FD_TYPE_DEFAULT; } diff --git a/server/protocol.def b/server/protocol.def index 76a3cf813db..6ab1f35ee3e 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -542,13 +542,17 @@ enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT }; unsigned int access; /* wanted access rights */ @REPLY int fd; /* file descriptor */ - int type; /* the type of file */ + int type; /* the type of file (see below) */ + int flags; /* file read/write flags (see below) */ @END -#define FD_TYPE_INVALID 0 -#define FD_TYPE_DEFAULT 1 -#define FD_TYPE_CONSOLE 2 -#define FD_TYPE_OVERLAPPED 3 -#define FD_TYPE_TIMEOUT 4 +enum fd_type +{ + FD_TYPE_INVALID, + FD_TYPE_DEFAULT, + FD_TYPE_CONSOLE +}; +#define FD_FLAG_OVERLAPPED 0x01 +#define FD_FLAG_TIMEOUT 0x02 /* Set a file current position */ diff --git a/server/serial.c b/server/serial.c index 110854aba59..59118768ff2 100644 --- a/server/serial.c +++ b/server/serial.c @@ -35,7 +35,7 @@ static void serial_dump( struct object *obj, int verbose ); static int serial_get_fd( struct object *obj ); -static int serial_get_info( struct object *obj, struct get_file_info_reply *reply ); +static int serial_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ); static int serial_get_poll_events( struct object *obj ); static struct async_queue * serial_queue_async(struct object *obj, struct async* async, int type, int count); static void destroy_serial(struct object *obj); @@ -189,7 +189,7 @@ static int serial_get_fd( struct object *obj ) return serial->obj.fd; } -static int serial_get_info( struct object *obj, struct get_file_info_reply *reply ) +static int serial_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ) { struct serial *serial = (struct serial *) obj; assert( obj->ops == &serial_ops ); @@ -208,14 +208,14 @@ static int serial_get_info( struct object *obj, struct get_file_info_reply *repl reply->serial = 0; } + *flags = 0; if(serial->attrib & FILE_FLAG_OVERLAPPED) - return FD_TYPE_OVERLAPPED; + *flags |= FD_FLAG_OVERLAPPED; + else if(!((serial->readinterval == MAXDWORD) && + (serial->readmult == 0) && (serial->readconst == 0)) ) + *flags |= FD_FLAG_TIMEOUT; - if( (serial->readinterval == MAXDWORD) && - (serial->readmult == 0) && (serial->readconst == 0) ) - return FD_TYPE_DEFAULT; - - return FD_TYPE_TIMEOUT; + return FD_TYPE_DEFAULT; } static void serial_poll_event(struct object *obj, int event) diff --git a/server/sock.c b/server/sock.c index 0cc4a3f3257..bc901f6cbed 100644 --- a/server/sock.c +++ b/server/sock.c @@ -59,7 +59,7 @@ static int sock_signaled( struct object *obj, struct thread *thread ); static int sock_get_poll_events( struct object *obj ); static void sock_poll_event( struct object *obj, int event ); static int sock_get_fd( struct object *obj ); -static int sock_get_info( struct object *obj, struct get_file_info_reply *reply ); +static int sock_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ); static void sock_destroy( struct object *obj ); static int sock_get_error( int err ); static void sock_set_error(void); @@ -273,7 +273,7 @@ static int sock_get_fd( struct object *obj ) return sock->obj.fd; } -static int sock_get_info( struct object *obj, struct get_file_info_reply *reply ) +static int sock_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags ) { if (reply) { @@ -288,6 +288,7 @@ static int sock_get_info( struct object *obj, struct get_file_info_reply *reply reply->index_low = 0; reply->serial = 0; } + *flags = 0; return FD_TYPE_DEFAULT; } diff --git a/server/trace.c b/server/trace.c index d162045501b..79ca059823f 100644 --- a/server/trace.c +++ b/server/trace.c @@ -722,7 +722,8 @@ 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, " fd=%d,", req->fd ); - fprintf( stderr, " type=%d", req->type ); + fprintf( stderr, " type=%d,", req->type ); + fprintf( stderr, " flags=%d", req->flags ); } static void dump_set_file_pointer_request( const struct set_file_pointer_request *req )