From dd1769a16a8977f2eb106d04f6530a590a77fdd6 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Sat, 20 Oct 2018 19:18:37 +0200 Subject: [PATCH] server: Improve error handling of disconnected named pipe clients. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/kernel32/tests/pipe.c | 1 - dlls/ntdll/tests/pipe.c | 4 ---- server/named_pipe.c | 10 ++++++++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c index b85e6ee71e4..7f77df1d0b3 100644 --- a/dlls/kernel32/tests/pipe.c +++ b/dlls/kernel32/tests/pipe.c @@ -1506,7 +1506,6 @@ static int test_DisconnectNamedPipe(void) ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %X\n", ret); ret = PeekNamedPipe(hFile, NULL, 0, NULL, &readden, NULL); - todo_wine ok(!ret && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "PeekNamedPipe returned %x (%u)\n", ret, GetLastError()); ret = PeekNamedPipe(hnp, NULL, 0, NULL, &readden, NULL); diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c index 51024a2921b..798df530c14 100644 --- a/dlls/ntdll/tests/pipe.c +++ b/dlls/ntdll/tests/pipe.c @@ -1348,7 +1348,6 @@ static void test_pipe_state(HANDLE pipe, BOOL is_server, DWORD state) expected_status = STATUS_PIPE_BROKEN; break; } - todo_wine_if(expected_status == STATUS_PIPE_DISCONNECTED) ok(status == expected_status, "status = %x, expected %x in %s state %u\n", status, expected_status, is_server ? "server" : "client", state); if (!status) @@ -1363,7 +1362,6 @@ static void test_pipe_state(HANDLE pipe, BOOL is_server, DWORD state) buf, 1, buf+1, 1); if (!status || status == STATUS_PENDING) status = io.Status; - todo_wine_if(expected_status == STATUS_PIPE_DISCONNECTED) ok(status == expected_status, "NtFsControlFile(FSCTL_PIPE_TRANSCEIVE) failed in %s state %u: %x\n", is_server ? "server" : "client", state, status); @@ -1373,7 +1371,6 @@ static void test_pipe_state(HANDLE pipe, BOOL is_server, DWORD state) status = NtFlushBuffersFile(pipe, &io); if (!is_server && state == FILE_PIPE_DISCONNECTED_STATE) { - todo_wine ok(status == STATUS_PIPE_DISCONNECTED, "status = %x in %s state %u\n", status, is_server ? "server" : "client", state); } @@ -1472,7 +1469,6 @@ static void test_pipe_with_data_state(HANDLE pipe, BOOL is_server, DWORD state) expected_status = STATUS_BUFFER_OVERFLOW; break; } - todo_wine_if(expected_status == STATUS_PIPE_DISCONNECTED) ok(status == expected_status, "status = %x, expected %x in %s state %u\n", status, expected_status, is_server ? "server" : "client", state); if (status == STATUS_BUFFER_OVERFLOW) diff --git a/server/named_pipe.c b/server/named_pipe.c index 0d98bf8db2b..ebd8c4f30c7 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -501,6 +501,12 @@ static int pipe_end_flush( struct fd *fd, struct async *async ) { struct pipe_end *pipe_end = get_fd_user( fd ); + if (!pipe_end->pipe) + { + set_error( STATUS_PIPE_DISCONNECTED ); + return 0; + } + if (pipe_end->connection && !list_empty( &pipe_end->connection->message_queue )) { fd_queue_async( pipe_end->fd, async, ASYNC_TYPE_WAIT ); @@ -888,7 +894,7 @@ static int pipe_end_peek( struct pipe_end *pipe_end ) set_error( STATUS_PIPE_BROKEN ); return 0; default: - set_error( STATUS_INVALID_PIPE_STATE ); + set_error( pipe_end->pipe ? STATUS_INVALID_PIPE_STATE : STATUS_PIPE_DISCONNECTED ); return 0; } @@ -932,7 +938,7 @@ static int pipe_end_transceive( struct pipe_end *pipe_end, struct async *async ) if (!pipe_end->connection) { - set_error( STATUS_INVALID_PIPE_STATE ); + set_error( pipe_end->pipe ? STATUS_INVALID_PIPE_STATE : STATUS_PIPE_DISCONNECTED ); return 0; }