From: Jacek Caban Subject: [PATCH 11/16] server: Added support for message mode named pipe reads. Message-Id: <5cd76274-e54f-6737-8467-1ad14a81d87e@codeweavers.com> Date: Thu, 26 Jan 2017 00:53:03 +0100 Signed-off-by: Jacek Caban --- dlls/kernel32/tests/pipe.c | 40 +++++----------------------------------- server/named_pipe.c | 22 ++++++++++++++++------ 2 files changed, 21 insertions(+), 41 deletions(-) diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c index 35ffe0e..cd4e207 100644 --- a/dlls/kernel32/tests/pipe.c +++ b/dlls/kernel32/tests/pipe.c @@ -255,9 +255,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); @@ -278,15 +276,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); @@ -352,9 +346,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"); @@ -385,7 +377,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)) @@ -394,10 +386,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); @@ -416,7 +406,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)) @@ -427,9 +417,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"); @@ -440,9 +428,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"); @@ -459,21 +445,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 */ @@ -482,12 +463,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); @@ -503,21 +482,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 */ @@ -525,15 +499,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); diff --git a/server/named_pipe.c b/server/named_pipe.c index 1ebcafe..f1314d24 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -697,15 +697,25 @@ static obj_handle_t pipe_client_flush( struct fd *fd, const async_data_t *async, 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 */