From aa472f5eb50009c7f7e31526918119ed3f202de0 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Sun, 26 Mar 2017 12:52:39 +0200 Subject: [PATCH] server: Added support for message mode named pipe reads. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/kernel32/tests/pipe.c | 45 +++++--------------------------------- server/named_pipe.c | 26 ++++++++++++++-------- 2 files changed, 23 insertions(+), 48 deletions(-) diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c index 35ff1bd79cb..58bad06bd55 100644 --- a/dlls/kernel32/tests/pipe.c +++ b/dlls/kernel32/tests/pipe.c @@ -263,9 +263,7 @@ static void test_CreateNamedPipe(int pipemode) else { SetLastError(0xdeadbeef); - todo_wine ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile\n"); - todo_wine ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n"); } ok(readden == 4, "read got %d bytes\n", readden); @@ -286,15 +284,11 @@ static void test_CreateNamedPipe(int pipemode) else { SetLastError(0xdeadbeef); - todo_wine ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile\n"); - todo_wine ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n"); ok(readden == 4, "read got %d bytes\n", readden); SetLastError(0xdeadbeef); - todo_wine ok(!ReadFile(hnp, ibuf + 4, 4, &readden, NULL), "ReadFile\n"); - todo_wine ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n"); } ok(readden == 4, "read got %d bytes\n", readden); @@ -360,9 +354,7 @@ static void test_CreateNamedPipe(int pipemode) ok(readden == sizeof(obuf) + sizeof(obuf2), "read 4 got %d bytes\n", readden); } else { - todo_wine { - ok(readden == sizeof(obuf), "read 4 got %d bytes\n", readden); - } + ok(readden == sizeof(obuf), "read 4 got %d bytes\n", readden); } pbuf = ibuf; ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 4a check\n"); @@ -393,9 +385,7 @@ static void test_CreateNamedPipe(int pipemode) pbuf = ibuf; ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 5a check\n"); ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); - todo_wine { - ok(readden == sizeof(obuf), "read 5 got %d bytes\n", readden); - } + ok(readden == sizeof(obuf), "read 5 got %d bytes\n", readden); pbuf = ibuf; ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 5a check\n"); if (readden <= sizeof(obuf)) @@ -404,10 +394,8 @@ static void test_CreateNamedPipe(int pipemode) /* Multiple writes in the reverse direction */ /* the write of obuf2 from write4 should still be in the buffer */ ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek6a\n"); - todo_wine { - ok(readden == sizeof(obuf2), "peek6a got %d bytes\n", readden); - ok(avail == sizeof(obuf2), "peek6a got %d bytes available\n", avail); - } + ok(readden == sizeof(obuf2), "peek6a got %d bytes\n", readden); + ok(avail == sizeof(obuf2), "peek6a got %d bytes available\n", avail); if (avail > 0) { ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); ok(readden == sizeof(obuf2), "read 6a got %d bytes\n", readden); @@ -426,9 +414,7 @@ static void test_CreateNamedPipe(int pipemode) pbuf = ibuf; ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 6a check\n"); ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); - todo_wine { - ok(readden == sizeof(obuf), "read 6b got %d bytes\n", readden); - } + ok(readden == sizeof(obuf), "read 6b got %d bytes\n", readden); pbuf = ibuf; ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 6a check\n"); if (readden <= sizeof(obuf)) @@ -439,9 +425,7 @@ static void test_CreateNamedPipe(int pipemode) ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), "WriteFile 7\n"); ok(written == sizeof(obuf2), "write file len 7\n"); SetLastError(0xdeadbeef); - todo_wine ok(!ReadFile(hFile, ibuf, 4, &readden, NULL), "ReadFile 7\n"); - todo_wine ok(GetLastError() == ERROR_MORE_DATA, "wrong error 7\n"); ok(readden == 4, "read got %d bytes 7\n", readden); ok(ReadFile(hFile, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile 7\n"); @@ -452,9 +436,7 @@ static void test_CreateNamedPipe(int pipemode) ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile 8\n"); ok(written == sizeof(obuf), "write file len 8\n"); SetLastError(0xdeadbeef); - todo_wine ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile 8\n"); - todo_wine ok(GetLastError() == ERROR_MORE_DATA, "wrong error 8\n"); ok(readden == 4, "read got %d bytes 8\n", readden); ok(ReadFile(hnp, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile 8\n"); @@ -471,21 +453,16 @@ static void test_CreateNamedPipe(int pipemode) ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), "WriteFile 9\n"); ok(written == sizeof(obuf2), "write file len 9\n"); SetLastError(0xdeadbeef); - todo_wine ok(!ReadFile(hFile, ibuf, 4, &readden, NULL), "ReadFile 9\n"); - todo_wine ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n"); ok(readden == 4, "read got %d bytes 9\n", readden); SetLastError(0xdeadbeef); ret = RpcReadFile(hFile, ibuf + 4, 4, &readden, NULL); - todo_wine ok(!ret, "RpcReadFile 9\n"); - todo_wine ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n"); ok(readden == 4, "read got %d bytes 9\n", readden); ret = RpcReadFile(hFile, ibuf + 8, sizeof(ibuf), &readden, NULL); ok(ret, "RpcReadFile 9\n"); - todo_wine ok(readden == sizeof(obuf) - 8, "read got %d bytes 9\n", readden); ok(memcmp(obuf, ibuf, sizeof(obuf)) == 0, "content check 9\n"); if (readden <= sizeof(obuf) - 8) /* blocks forever if second part was already received */ @@ -494,12 +471,10 @@ static void test_CreateNamedPipe(int pipemode) SetLastError(0xdeadbeef); ret = RpcReadFile(hFile, ibuf, 4, &readden, NULL); ok(!ret, "RpcReadFile 9\n"); - todo_wine ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n"); ok(readden == 4, "read got %d bytes 9\n", readden); SetLastError(0xdeadbeef); ok(!ReadFile(hFile, ibuf + 4, 4, &readden, NULL), "ReadFile 9\n"); - todo_wine ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n"); ok(readden == 4, "read got %d bytes 9\n", readden); ret = RpcReadFile(hFile, ibuf + 8, sizeof(ibuf), &readden, NULL); @@ -515,21 +490,16 @@ static void test_CreateNamedPipe(int pipemode) ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile 10\n"); ok(written == sizeof(obuf), "write file len 10\n"); SetLastError(0xdeadbeef); - todo_wine ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile 10\n"); - todo_wine ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n"); ok(readden == 4, "read got %d bytes 10\n", readden); SetLastError(0xdeadbeef); ret = RpcReadFile(hnp, ibuf + 4, 4, &readden, NULL); - todo_wine ok(!ret, "RpcReadFile 10\n"); - todo_wine ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n"); ok(readden == 4, "read got %d bytes 10\n", readden); ret = RpcReadFile(hnp, ibuf + 8, sizeof(ibuf), &readden, NULL); ok(ret, "RpcReadFile 10\n"); - todo_wine ok(readden == sizeof(obuf2) - 8, "read got %d bytes 10\n", readden); ok(memcmp(obuf2, ibuf, sizeof(obuf2)) == 0, "content check 10\n"); if (readden <= sizeof(obuf2) - 8) /* blocks forever if second part was already received */ @@ -537,15 +507,11 @@ static void test_CreateNamedPipe(int pipemode) memset(ibuf, 0, sizeof(ibuf)); SetLastError(0xdeadbeef); ret = RpcReadFile(hnp, ibuf, 4, &readden, NULL); - todo_wine ok(!ret, "RpcReadFile 10\n"); - todo_wine ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n"); ok(readden == 4, "read got %d bytes 10\n", readden); SetLastError(0xdeadbeef); - todo_wine ok(!ReadFile(hnp, ibuf + 4, 4, &readden, NULL), "ReadFile 10\n"); - todo_wine ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n"); ok(readden == 4, "read got %d bytes 10\n", readden); ret = RpcReadFile(hnp, ibuf + 8, sizeof(ibuf), &readden, NULL); @@ -2944,4 +2910,5 @@ START_TEST(pipe) test_GetNamedPipeInfo(); test_readfileex_pending(); test_overlapped_transport(TRUE, FALSE); + test_overlapped_transport(TRUE, TRUE); } diff --git a/server/named_pipe.c b/server/named_pipe.c index 11e74573171..e5b6dd182a1 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -3,6 +3,7 @@ * * Copyright (C) 1998 Alexandre Julliard * Copyright (C) 2001 Mike McCormack + * Copyright 2016 Jacek Caban for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,9 +18,6 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - * TODO: - * message mode */ #include "config.h" @@ -691,15 +689,25 @@ static obj_handle_t pipe_client_flush( struct fd *fd, struct async *async, int b static void message_queue_read( struct pipe_end *pipe_end, struct iosb *iosb ) { struct pipe_message *message; - data_size_t avail = 0; - LIST_FOR_EACH_ENTRY( message, &pipe_end->message_queue, struct pipe_message, entry ) + if (pipe_end->flags & NAMED_PIPE_MESSAGE_STREAM_READ) { - avail += message->iosb->in_size - message->read_pos; - if (avail >= iosb->out_size) break; + message = LIST_ENTRY( list_head(&pipe_end->message_queue), struct pipe_message, entry ); + iosb->out_size = min( iosb->out_size, message->iosb->in_size - message->read_pos ); + iosb->status = message->read_pos + iosb->out_size < message->iosb->in_size + ? STATUS_BUFFER_OVERFLOW : STATUS_SUCCESS; + } + else + { + 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; + if (avail >= iosb->out_size) break; + } + iosb->out_size = min( iosb->out_size, avail ); + iosb->status = STATUS_SUCCESS; } - iosb->out_size = min( iosb->out_size, avail ); - iosb->status = STATUS_SUCCESS; message = LIST_ENTRY( list_head(&pipe_end->message_queue), struct pipe_message, entry ); if (!message->read_pos && message->iosb->in_size == iosb->out_size) /* fast path */