diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 77d2d3265c7..c784ee61af3 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -2200,7 +2200,7 @@ static NTSTATUS server_get_file_info( HANDLE handle, IO_STATUS_BLOCK *io, void * io->Information = wine_server_reply_size( reply ); } SERVER_END_REQ; - if (io->u.Status == STATUS_OBJECT_TYPE_MISMATCH) + if (io->u.Status == STATUS_NOT_IMPLEMENTED) FIXME( "Unsupported info class %x\n", info_class ); return io->u.Status; @@ -2305,10 +2305,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, if (class <= 0 || class >= FileMaximumInformation) return io->u.Status = STATUS_INVALID_INFO_CLASS; if (!info_sizes[class]) - { - FIXME("Unsupported class (%d)\n", class); - return io->u.Status = STATUS_NOT_IMPLEMENTED; - } + return server_get_file_info( hFile, io, ptr, len, class ); if (len < info_sizes[class]) return io->u.Status = STATUS_INFO_LENGTH_MISMATCH; diff --git a/server/change.c b/server/change.c index 1f2f7c568ac..d00a885dd29 100644 --- a/server/change.c +++ b/server/change.c @@ -187,7 +187,7 @@ static const struct fd_ops dir_fd_ops = no_fd_read, /* read */ no_fd_write, /* write */ no_fd_flush, /* flush */ - no_fd_get_file_info, /* get_file_info */ + default_fd_get_file_info, /* get_file_info */ no_fd_get_volume_info, /* get_volume_info */ default_fd_ioctl, /* ioctl */ default_fd_queue_async, /* queue_async */ diff --git a/server/device.c b/server/device.c index dcc29461f57..081fd2d667f 100644 --- a/server/device.c +++ b/server/device.c @@ -209,7 +209,7 @@ static const struct fd_ops device_file_fd_ops = device_file_read, /* read */ device_file_write, /* write */ device_file_flush, /* flush */ - no_fd_get_file_info, /* get_file_info */ + default_fd_get_file_info, /* get_file_info */ no_fd_get_volume_info, /* get_volume_info */ device_file_ioctl, /* ioctl */ default_fd_queue_async, /* queue_async */ diff --git a/server/fd.c b/server/fd.c index 4d077972eb2..85d15d92dac 100644 --- a/server/fd.c +++ b/server/fd.c @@ -2175,6 +2175,12 @@ void no_fd_get_file_info( struct fd *fd, obj_handle_t handle, unsigned int info_ set_error( STATUS_OBJECT_TYPE_MISMATCH ); } +/* default get_file_info() routine */ +void default_fd_get_file_info( struct fd *fd, obj_handle_t handle, unsigned int info_class ) +{ + set_error( STATUS_NOT_IMPLEMENTED ); +} + /* default get_volume_info() routine */ void no_fd_get_volume_info( struct fd *fd, unsigned int info_class ) { diff --git a/server/file.c b/server/file.c index 446621a997d..37f7afe6553 100644 --- a/server/file.c +++ b/server/file.c @@ -107,7 +107,7 @@ static const struct fd_ops file_fd_ops = no_fd_read, /* read */ no_fd_write, /* write */ file_flush, /* flush */ - no_fd_get_file_info, /* get_file_info */ + default_fd_get_file_info, /* get_file_info */ no_fd_get_volume_info, /* get_volume_info */ default_fd_ioctl, /* ioctl */ default_fd_queue_async, /* queue_async */ diff --git a/server/file.h b/server/file.h index 8a47333b743..c30bc96255f 100644 --- a/server/file.h +++ b/server/file.h @@ -112,6 +112,7 @@ extern int no_fd_read( struct fd *fd, struct async *async, file_pos_t pos ); extern int no_fd_write( struct fd *fd, struct async *async, file_pos_t pos ); extern int no_fd_flush( struct fd *fd, struct async *async ); extern void no_fd_get_file_info( struct fd *fd, obj_handle_t handle, unsigned int info_class ); +extern void default_fd_get_file_info( struct fd *fd, obj_handle_t handle, unsigned int info_class ); extern void no_fd_get_volume_info( struct fd *fd, unsigned int info_class ); extern int no_fd_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ); extern int default_fd_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ); diff --git a/server/mailslot.c b/server/mailslot.c index f4c7007c142..95308c40b0f 100644 --- a/server/mailslot.c +++ b/server/mailslot.c @@ -104,7 +104,7 @@ static const struct fd_ops mailslot_fd_ops = no_fd_read, /* read */ no_fd_write, /* write */ no_fd_flush, /* flush */ - no_fd_get_file_info, /* get_file_info */ + default_fd_get_file_info, /* get_file_info */ no_fd_get_volume_info, /* get_volume_info */ default_fd_ioctl, /* ioctl */ mailslot_queue_async, /* queue_async */ @@ -159,7 +159,7 @@ static const struct fd_ops mail_writer_fd_ops = no_fd_read, /* read */ no_fd_write, /* write */ no_fd_flush, /* flush */ - no_fd_get_file_info, /* get_file_info */ + default_fd_get_file_info, /* get_file_info */ no_fd_get_volume_info, /* get_volume_info */ default_fd_ioctl, /* ioctl */ default_fd_queue_async, /* queue_async */ @@ -214,7 +214,7 @@ static const struct fd_ops mailslot_device_fd_ops = no_fd_read, /* read */ no_fd_write, /* write */ no_fd_flush, /* flush */ - no_fd_get_file_info, /* get_file_info */ + default_fd_get_file_info, /* get_file_info */ no_fd_get_volume_info, /* get_volume_info */ default_fd_ioctl, /* ioctl */ default_fd_queue_async, /* queue_async */ diff --git a/server/named_pipe.c b/server/named_pipe.c index ebd8c4f30c7..f643140637d 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -271,7 +271,7 @@ static const struct fd_ops named_pipe_device_fd_ops = no_fd_read, /* read */ no_fd_write, /* write */ no_fd_flush, /* flush */ - no_fd_get_file_info, /* get_file_info */ + default_fd_get_file_info, /* get_file_info */ no_fd_get_volume_info, /* get_volume_info */ named_pipe_device_ioctl, /* ioctl */ default_fd_queue_async, /* queue_async */ @@ -520,12 +520,6 @@ static void pipe_end_get_file_info( struct fd *fd, obj_handle_t handle, unsigned struct pipe_end *pipe_end = get_fd_user( fd ); struct named_pipe *pipe = pipe_end->pipe; - if (!pipe) - { - set_error( STATUS_PIPE_DISCONNECTED ); - return; - } - switch (info_class) { case FileNameInformation: @@ -540,13 +534,13 @@ static void pipe_end_get_file_info( struct fd *fd, obj_handle_t handle, unsigned return; } - name = get_object_name( &pipe->obj, &name_len ); /* FIXME: We should be able to return on unlinked pipe */ - if (!name) + if (!pipe || !(name = get_object_name( &pipe->obj, &name_len ))) { set_error( STATUS_PIPE_DISCONNECTED ); return; } + reply_size = offsetof( FILE_NAME_INFORMATION, FileName[name_len/sizeof(WCHAR) + 1] ); if (reply_size > get_reply_max_size()) { @@ -577,6 +571,12 @@ static void pipe_end_get_file_info( struct fd *fd, obj_handle_t handle, unsigned return; } + if (!pipe) + { + set_error( STATUS_PIPE_DISCONNECTED ); + return; + } + if (!(pipe_info = set_reply_data_size( sizeof(*pipe_info) ))) return; pipe_info->ReadMode = (pipe_end->flags & NAMED_PIPE_MESSAGE_STREAM_READ) ? FILE_PIPE_MESSAGE_MODE : FILE_PIPE_BYTE_STREAM_MODE; @@ -600,6 +600,12 @@ static void pipe_end_get_file_info( struct fd *fd, obj_handle_t handle, unsigned return; } + if (!pipe) + { + set_error( STATUS_PIPE_DISCONNECTED ); + return; + } + if (!(pipe_info = set_reply_data_size( sizeof(*pipe_info) ))) return; pipe_info->NamedPipeType = (pipe_end->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) != 0; switch (pipe->sharing) @@ -626,7 +632,7 @@ static void pipe_end_get_file_info( struct fd *fd, obj_handle_t handle, unsigned break; } default: - no_fd_get_file_info( fd, handle, info_class ); + default_fd_get_file_info( fd, handle, info_class ); } } diff --git a/server/serial.c b/server/serial.c index bb976a1d114..f0adf92f3a8 100644 --- a/server/serial.c +++ b/server/serial.c @@ -114,7 +114,7 @@ static const struct fd_ops serial_fd_ops = no_fd_read, /* read */ no_fd_write, /* write */ no_fd_flush, /* flush */ - no_fd_get_file_info, /* get_file_info */ + default_fd_get_file_info, /* get_file_info */ no_fd_get_volume_info, /* get_volume_info */ serial_ioctl, /* ioctl */ serial_queue_async, /* queue_async */ diff --git a/server/sock.c b/server/sock.c index 84f54f6f059..a8e6e28599b 100644 --- a/server/sock.c +++ b/server/sock.c @@ -167,7 +167,7 @@ static const struct fd_ops sock_fd_ops = no_fd_read, /* read */ no_fd_write, /* write */ no_fd_flush, /* flush */ - no_fd_get_file_info, /* get_file_info */ + default_fd_get_file_info, /* get_file_info */ no_fd_get_volume_info, /* get_volume_info */ sock_ioctl, /* ioctl */ sock_queue_async, /* queue_async */