diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c index 072c3444c65..be2f30dfc7d 100644 --- a/dlls/ntdll/tests/pipe.c +++ b/dlls/ntdll/tests/pipe.c @@ -2081,6 +2081,7 @@ static void test_pipe_with_data_state(HANDLE pipe, BOOL is_server, DWORD state) IO_STATUS_BLOCK io; char buf[256] = "test"; NTSTATUS status, expected_status; + FILE_STANDARD_INFORMATION std_info; memset(&io, 0xcc, sizeof(io)); status = pNtQueryInformationFile(pipe, &io, &local_info, sizeof(local_info), FilePipeLocalInformation); @@ -2104,6 +2105,26 @@ static void test_pipe_with_data_state(HANDLE pipe, BOOL is_server, DWORD state) is_server ? "server" : "client", state); } + status = pNtQueryInformationFile(pipe, &io, &std_info, sizeof(std_info), FileStandardInformation); + if (!is_server && state == FILE_PIPE_DISCONNECTED_STATE) + ok(status == STATUS_PIPE_DISCONNECTED, + "NtQueryInformationFile(FileStandardInformation) failed in %s state %lu: %lx\n", + is_server ? "server" : "client", state, status); + else + ok(status == STATUS_SUCCESS, + "NtQueryInformationFile(FileStandardInformation) failed in %s state %lu: %lx\n", + is_server ? "server" : "client", state, status); + if (!status) + { + ok(std_info.AllocationSize.QuadPart == local_info.InboundQuota + local_info.OutboundQuota, + "got %I64u, expected %lu.\n", + std_info.AllocationSize.QuadPart, local_info.InboundQuota + local_info.OutboundQuota); + ok(std_info.EndOfFile.QuadPart == local_info.ReadDataAvailable, "got %I64u.\n", std_info.EndOfFile.QuadPart); + ok(std_info.NumberOfLinks == 1, "got %lu.\n", std_info.NumberOfLinks); + todo_wine ok(std_info.DeletePending, "got %d.\n", std_info.DeletePending); + ok(!std_info.Directory, "got %d.\n", std_info.Directory); + } + status = pNtQueryInformationFile(pipe, &io, &pipe_info, sizeof(pipe_info), FilePipeInformation); if (!is_server && state == FILE_PIPE_DISCONNECTED_STATE) ok(status == STATUS_PIPE_DISCONNECTED, diff --git a/server/named_pipe.c b/server/named_pipe.c index 3adc79068ab..f3404a33c3b 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -598,6 +598,17 @@ static void pipe_end_flush( struct fd *fd, struct async *async ) } } +static data_size_t pipe_end_get_avail( struct pipe_end *pipe_end ) +{ + struct pipe_message *message; + data_size_t avail = 0; + + LIST_FOR_EACH_ENTRY( message, &pipe_end->message_queue, struct pipe_message, entry ) + avail += message->iosb->in_size - message->read_pos; + + return avail; +} + 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 ); @@ -670,8 +681,6 @@ static void pipe_end_get_file_info( struct fd *fd, obj_handle_t handle, unsigned case FilePipeLocalInformation: { FILE_PIPE_LOCAL_INFORMATION *pipe_info; - struct pipe_message *message; - data_size_t avail = 0; if (!(get_handle_access( current->process, handle) & FILE_READ_ATTRIBUTES)) { @@ -709,9 +718,7 @@ static void pipe_end_get_file_info( struct fd *fd, obj_handle_t handle, unsigned pipe_info->CurrentInstances = pipe->instances; pipe_info->InboundQuota = pipe->insize; - LIST_FOR_EACH_ENTRY( message, &pipe_end->message_queue, struct pipe_message, entry ) - avail += message->iosb->in_size - message->read_pos; - pipe_info->ReadDataAvailable = avail; + pipe_info->ReadDataAvailable = pipe_end_get_avail( pipe_end ); pipe_info->OutboundQuota = pipe->outsize; pipe_info->WriteQuotaAvailable = 0; /* FIXME */ @@ -720,6 +727,36 @@ static void pipe_end_get_file_info( struct fd *fd, obj_handle_t handle, unsigned ? FILE_PIPE_SERVER_END : FILE_PIPE_CLIENT_END; break; } + case FileStandardInformation: + { + FILE_STANDARD_INFORMATION *std_info; + + if (!(get_handle_access( current->process, handle) & FILE_READ_ATTRIBUTES)) + { + set_error( STATUS_ACCESS_DENIED ); + return; + } + + if (get_reply_max_size() < sizeof(*std_info)) + { + set_error( STATUS_INFO_LENGTH_MISMATCH ); + return; + } + + if (!pipe) + { + set_error( STATUS_PIPE_DISCONNECTED ); + return; + } + + if (!(std_info = set_reply_data_size( sizeof(*std_info) ))) return; + std_info->AllocationSize.QuadPart = pipe->outsize + pipe->insize; + std_info->EndOfFile.QuadPart = pipe_end_get_avail( pipe_end ); + std_info->NumberOfLinks = 1; /* FIXME */ + std_info->DeletePending = 0; /* FIXME */ + std_info->Directory = 0; + break; + } default: default_fd_get_file_info( fd, handle, info_class ); }