From 688c7a99d2ce9dd60d39efb60138bdebb4fceace Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Wed, 4 Oct 2017 15:17:35 +0200 Subject: [PATCH] server: Return error for FSCTL_PIPE_PEEK calls on disconnected pipes. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/kernel32/tests/pipe.c | 37 +++++++++++++++++++++++++++++++++++++ server/named_pipe.c | 6 ++++++ 2 files changed, 43 insertions(+) diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c index 84db14e8143..18ffa7a5f17 100644 --- a/dlls/kernel32/tests/pipe.c +++ b/dlls/kernel32/tests/pipe.c @@ -209,6 +209,11 @@ static void test_CreateNamedPipe(int pipemode) ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); test_signaled(hnp); + ret = PeekNamedPipe(hnp, NULL, 0, NULL, &readden, NULL); + todo_wine + ok(!ret && GetLastError() == ERROR_BAD_PIPE, "PeekNamedPipe returned %x (%u)\n", + ret, GetLastError()); + ret = WaitNamedPipeA(PIPENAME, 2000); ok(ret, "WaitNamedPipe failed (%d)\n", GetLastError()); @@ -1387,10 +1392,20 @@ static int test_DisconnectNamedPipe(void) ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0 && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "ReadFile from disconnected pipe with bytes waiting\n"); + ok(!DisconnectNamedPipe(hnp) && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "DisconnectNamedPipe worked twice\n"); ret = WaitForSingleObject(hFile, 0); 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); + todo_wine + ok(!ret && GetLastError() == ERROR_BAD_PIPE, "PeekNamedPipe returned %x (%u)\n", + ret, GetLastError()); ok(CloseHandle(hFile), "CloseHandle\n"); } @@ -1501,6 +1516,11 @@ static void test_CloseHandle(void) ok(ret, "ReadFile failed with %u\n", GetLastError()); ok(numbytes == 0, "expected 0, got %u\n", numbytes); + numbytes = 0xdeadbeef; + ret = PeekNamedPipe(hfile, NULL, 0, NULL, &numbytes, NULL); + ok(ret, "PeekNamedPipe failed with %u\n", GetLastError()); + ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes); + numbytes = 0xdeadbeef; memset(buffer, 0, sizeof(buffer)); ret = ReadFile(hfile, buffer, sizeof(buffer), &numbytes, NULL); @@ -1518,6 +1538,12 @@ static void test_CloseHandle(void) ok(!ret, "ReadFile unexpectedly succeeded\n"); ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError()); + numbytes = 0xdeadbeef; + ret = PeekNamedPipe(hfile, NULL, 0, NULL, &numbytes, NULL); + ok(!ret && GetLastError() == ERROR_BROKEN_PIPE, "PeekNamedPipe returned %x (%u)\n", + ret, GetLastError()); + ok(numbytes == 0xdeadbeef, "numbytes = %u\n", numbytes); + SetLastError(0xdeadbeef); ret = WriteFile(hfile, testdata, sizeof(testdata), &numbytes, NULL); ok(!ret, "WriteFile unexpectedly succeeded\n"); @@ -1600,6 +1626,11 @@ static void test_CloseHandle(void) "ReadFile failed with %u\n", GetLastError()); ok(numbytes == 0, "expected 0, got %u\n", numbytes); + numbytes = 0xdeadbeef; + ret = PeekNamedPipe(hpipe, NULL, 0, NULL, &numbytes, NULL); + ok(ret, "PeekNamedPipe failed with %u\n", GetLastError()); + ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes); + numbytes = 0xdeadbeef; memset(buffer, 0, sizeof(buffer)); ret = ReadFile(hpipe, buffer, sizeof(buffer), &numbytes, NULL); @@ -1617,6 +1648,12 @@ static void test_CloseHandle(void) ok(!ret, "ReadFile unexpectedly succeeded\n"); ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError()); + numbytes = 0xdeadbeef; + ret = PeekNamedPipe(hpipe, NULL, 0, NULL, &numbytes, NULL); + ok(!ret && GetLastError() == ERROR_BROKEN_PIPE, "PeekNamedPipe returned %x (%u)\n", + ret, GetLastError()); + ok(numbytes == 0xdeadbeef, "numbytes = %u\n", numbytes); + SetLastError(0xdeadbeef); ret = WriteFile(hpipe, testdata, sizeof(testdata), &numbytes, NULL); ok(!ret, "WriteFile unexpectedly succeeded\n"); diff --git a/server/named_pipe.c b/server/named_pipe.c index d0ec38f36c6..1ec1ff4496c 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -922,6 +922,12 @@ static int pipe_end_peek( struct pipe_end *pipe_end ) } reply_size -= offsetof( FILE_PIPE_PEEK_BUFFER, Data ); + if (!pipe_end->connection && list_empty( &pipe_end->message_queue )) + { + set_error( STATUS_PIPE_BROKEN ); + return 0; + } + LIST_FOR_EACH_ENTRY( message, &pipe_end->message_queue, struct pipe_message, entry ) avail += message->iosb->in_size - message->read_pos;