diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index b2749a6676f..41e330db3d2 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -2200,6 +2200,8 @@ 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) + FIXME( "Unsupported info class %x\n", info_class ); return io->u.Status; } @@ -2310,7 +2312,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, if (len < info_sizes[class]) return io->u.Status = STATUS_INFO_LENGTH_MISMATCH; - if (class != FilePipeInformation && class != FilePipeLocalInformation && class != FileAccessInformation) + if (class != FilePipeInformation && class != FileAccessInformation) { if ((io->u.Status = server_get_unix_fd( hFile, 0, &fd, &needs_close, NULL, NULL ))) { @@ -2458,43 +2460,6 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, SERVER_END_REQ; } break; - case FilePipeLocalInformation: - { - FILE_PIPE_LOCAL_INFORMATION* pli = ptr; - - SERVER_START_REQ( get_named_pipe_info ) - { - req->handle = wine_server_obj_handle( hFile ); - if (!(io->u.Status = wine_server_call( req ))) - { - pli->NamedPipeType = (reply->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) ? - FILE_PIPE_TYPE_MESSAGE : FILE_PIPE_TYPE_BYTE; - switch (reply->sharing) - { - case FILE_SHARE_READ: - pli->NamedPipeConfiguration = FILE_PIPE_OUTBOUND; - break; - case FILE_SHARE_WRITE: - pli->NamedPipeConfiguration = FILE_PIPE_INBOUND; - break; - case FILE_SHARE_READ | FILE_SHARE_WRITE: - pli->NamedPipeConfiguration = FILE_PIPE_FULL_DUPLEX; - break; - } - pli->MaximumInstances = reply->maxinstances; - pli->CurrentInstances = reply->instances; - pli->InboundQuota = reply->insize; - pli->ReadDataAvailable = 0; /* FIXME */ - pli->OutboundQuota = reply->outsize; - pli->WriteQuotaAvailable = 0; /* FIXME */ - pli->NamedPipeState = 0; /* FIXME */ - pli->NamedPipeEnd = (reply->flags & NAMED_PIPE_SERVER_END) ? - FILE_PIPE_SERVER_END : FILE_PIPE_CLIENT_END; - } - } - SERVER_END_REQ; - } - break; case FileNameInformation: { FILE_NAME_INFORMATION *info = ptr; diff --git a/server/fd.c b/server/fd.c index 6118f52dd54..b26b111d760 100644 --- a/server/fd.c +++ b/server/fd.c @@ -2170,7 +2170,7 @@ int no_fd_flush( struct fd *fd, struct async *async ) } /* default get_file_info() routine */ -void no_fd_get_file_info( struct fd *fd, unsigned int info_class ) +void no_fd_get_file_info( struct fd *fd, obj_handle_t handle, unsigned int info_class ) { set_error( STATUS_OBJECT_TYPE_MISMATCH ); } @@ -2391,7 +2391,7 @@ DECL_HANDLER(get_file_info) if (fd) { - fd->fd_ops->get_file_info( fd, req->info_class ); + fd->fd_ops->get_file_info( fd, req->handle, req->info_class ); release_object( fd ); } } diff --git a/server/file.h b/server/file.h index 8609db05c56..8a47333b743 100644 --- a/server/file.h +++ b/server/file.h @@ -63,7 +63,7 @@ struct fd_ops /* flush the object buffers */ int (*flush)(struct fd *, struct async *); /* query file info */ - void (*get_file_info)( struct fd *, unsigned int ); + void (*get_file_info)( struct fd *, obj_handle_t, unsigned int ); /* query volume info */ void (*get_volume_info)( struct fd *, unsigned int ); /* perform an ioctl on the file */ @@ -111,7 +111,7 @@ extern void fd_reselect_async( struct fd *fd, struct async_queue *queue ); 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, unsigned int info_class ); +extern void no_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/named_pipe.c b/server/named_pipe.c index ae2f2de17fd..a2cc52020a2 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -145,7 +145,7 @@ static int pipe_end_write( struct fd *fd, struct async *async_data, file_pos_t p static int pipe_end_flush( struct fd *fd, struct async *async ); static void pipe_end_get_volume_info( struct fd *fd, unsigned int info_class ); static void pipe_end_reselect_async( struct fd *fd, struct async_queue *queue ); -static void pipe_end_get_file_info( struct fd *fd, unsigned int info_class ); +static void pipe_end_get_file_info( struct fd *fd, obj_handle_t handle, unsigned int info_class ); /* server end functions */ static void pipe_server_dump( struct object *obj, int verbose ); @@ -509,7 +509,7 @@ static int pipe_end_flush( struct fd *fd, struct async *async ) return 1; } -static void pipe_end_get_file_info( struct fd *fd, unsigned int info_class ) +static void pipe_end_get_file_info( struct fd *fd, obj_handle_t handle, unsigned int info_class ) { struct pipe_end *pipe_end = get_fd_user( fd ); struct named_pipe *pipe = pipe_end->pipe; @@ -555,8 +555,49 @@ static void pipe_end_get_file_info( struct fd *fd, unsigned int info_class ) if (reply_size) memcpy( &name_info->FileName[1], name, reply_size ); break; } + case FilePipeLocalInformation: + { + FILE_PIPE_LOCAL_INFORMATION *pipe_info; + + if (!(get_handle_access( current->process, handle) & FILE_READ_ATTRIBUTES)) + { + set_error( STATUS_ACCESS_DENIED ); + return; + } + + if (get_reply_max_size() < sizeof(*pipe_info)) + { + set_error( STATUS_INFO_LENGTH_MISMATCH ); + 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) + { + case FILE_SHARE_READ: + pipe_info->NamedPipeConfiguration = FILE_PIPE_OUTBOUND; + break; + case FILE_SHARE_WRITE: + pipe_info->NamedPipeConfiguration = FILE_PIPE_INBOUND; + break; + case FILE_SHARE_READ | FILE_SHARE_WRITE: + pipe_info->NamedPipeConfiguration = FILE_PIPE_FULL_DUPLEX; + break; + } + pipe_info->MaximumInstances = pipe->maxinstances; + pipe_info->CurrentInstances = pipe->instances; + pipe_info->InboundQuota = pipe->insize; + pipe_info->ReadDataAvailable = 0; /* FIXME */ + pipe_info->OutboundQuota = pipe->outsize; + pipe_info->WriteQuotaAvailable = 0; /* FIXME */ + pipe_info->NamedPipeState = 0; /* FIXME */ + pipe_info->NamedPipeEnd = pipe_end->obj.ops == &pipe_server_ops + ? FILE_PIPE_SERVER_END : FILE_PIPE_CLIENT_END; + break; + } default: - no_fd_get_file_info( fd, info_class ); + no_fd_get_file_info( fd, handle, info_class ); } }