From: Jacek Caban Subject: [PATCH 10/13] server: Use server-side I/O for message mode named pipes. Message-Id: <77069831-4082-5f58-09ed-ed3401d90ed4@codeweavers.com> Date: Wed, 15 Mar 2017 23:26:37 +0100 Signed-off-by: Jacek Caban --- dlls/kernel32/tests/pipe.c | 28 +++++++++++----------------- dlls/ntdll/file.c | 7 +++++-- dlls/ntdll/tests/file.c | 2 +- server/named_pipe.c | 5 +++-- 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c index 45c6fd9..aafebd6 100644 --- a/dlls/kernel32/tests/pipe.c +++ b/dlls/kernel32/tests/pipe.c @@ -308,8 +308,7 @@ static void test_CreateNamedPipe(int pipemode) } else { - /* ok(readden == sizeof(obuf), "peek3 got %d bytes\n", readden); */ - if (readden != sizeof(obuf)) todo_wine ok(0, "peek3 got %d bytes\n", readden); + ok(readden == sizeof(obuf), "peek3 got %d bytes\n", readden); } ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes available\n", avail); pbuf = ibuf; @@ -339,8 +338,7 @@ static void test_CreateNamedPipe(int pipemode) } else { - /* ok(readden == sizeof(obuf), "peek4 got %d bytes\n", readden); */ - if (readden != sizeof(obuf)) todo_wine ok(0, "peek4 got %d bytes\n", readden); + ok(readden == sizeof(obuf), "peek4 got %d bytes\n", readden); } ok(avail == sizeof(obuf) + sizeof(obuf2), "peek4 got %d bytes available\n", avail); pbuf = ibuf; @@ -381,9 +379,7 @@ static void test_CreateNamedPipe(int pipemode) ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), " WriteFile5b\n"); ok(written == sizeof(obuf2), "write file len 3b\n"); ok(PeekNamedPipe(hFile, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek5\n"); - /* currently the Wine behavior depends on the kernel version */ - /* ok(readden == sizeof(obuf), "peek5 got %d bytes\n", readden); */ - if (readden != sizeof(obuf)) todo_wine ok(0, "peek5 got %d bytes\n", readden); + ok(readden == sizeof(obuf), "peek5 got %d bytes\n", readden); ok(avail == sizeof(obuf) + sizeof(obuf2), "peek5 got %d bytes available\n", avail); pbuf = ibuf; @@ -416,9 +412,7 @@ static void test_CreateNamedPipe(int pipemode) ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), " WriteFile6b\n"); ok(written == sizeof(obuf2), "write file len 6b\n"); ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek6\n"); - /* currently the Wine behavior depends on the kernel version */ - /* ok(readden == sizeof(obuf), "peek6 got %d bytes\n", readden); */ - if (readden != sizeof(obuf)) todo_wine ok(0, "peek6 got %d bytes\n", readden); + ok(readden == sizeof(obuf), "peek6 got %d bytes\n", readden); ok(avail == sizeof(obuf) + sizeof(obuf2), "peek6b got %d bytes available\n", avail); pbuf = ibuf; @@ -496,7 +490,6 @@ static void test_CreateNamedPipe(int pipemode) ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n"); ok(readden == 4, "read got %d bytes 9\n", readden); SetLastError(0xdeadbeef); - todo_wine ok(!ReadFile(hFile, ibuf + 4, 4, &readden, NULL), "ReadFile 9\n"); todo_wine ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n"); @@ -536,6 +529,7 @@ 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"); @@ -1424,7 +1418,7 @@ static void test_CloseHandle(void) numbytes = 0xdeadbeef; memset(buffer, 0, sizeof(buffer)); ret = ReadFile(hfile, buffer, 0, &numbytes, NULL); - todo_wine ok(ret, "ReadFile failed with %u\n", GetLastError()); + ok(ret, "ReadFile failed with %u\n", GetLastError()); ok(numbytes == 0, "expected 0, got %u\n", numbytes); numbytes = 0xdeadbeef; @@ -1470,13 +1464,13 @@ static void test_CloseHandle(void) numbytes = 0xdeadbeef; memset(buffer, 0, sizeof(buffer)); ret = ReadFile(hfile, buffer, sizeof(buffer), &numbytes, NULL); - todo_wine ok(ret, "ReadFile failed with %u\n", GetLastError()); + ok(ret, "ReadFile failed with %u\n", GetLastError()); ok(numbytes == 0, "expected 0, got %u\n", numbytes); SetLastError(0xdeadbeef); ret = ReadFile(hfile, buffer, 0, &numbytes, NULL); ok(!ret, "ReadFile unexpectedly succeeded\n"); - todo_wine ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError()); + ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError()); ret = GetNamedPipeHandleStateA(hfile, &state, NULL, NULL, NULL, NULL, 0); ok(ret, "GetNamedPipeHandleState failed with %u\n", GetLastError()); @@ -1487,7 +1481,7 @@ static void test_CloseHandle(void) SetLastError(0xdeadbeef); ret = ReadFile(hfile, buffer, 0, &numbytes, NULL); ok(!ret, "ReadFile unexpectedly succeeded\n"); - todo_wine ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError()); + ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError()); SetLastError(0xdeadbeef); ret = WriteFile(hfile, testdata, sizeof(testdata), &numbytes, NULL); @@ -1522,7 +1516,7 @@ static void test_CloseHandle(void) numbytes = 0xdeadbeef; memset(buffer, 0, sizeof(buffer)); ret = ReadFile(hpipe, buffer, 0, &numbytes, NULL); - todo_wine ok(ret || GetLastError() == ERROR_MORE_DATA /* >= Win 8 */, + ok(ret || GetLastError() == ERROR_MORE_DATA /* >= Win 8 */, "ReadFile failed with %u\n", GetLastError()); ok(numbytes == 0, "expected 0, got %u\n", numbytes); @@ -1569,7 +1563,7 @@ static void test_CloseHandle(void) numbytes = 0xdeadbeef; memset(buffer, 0, sizeof(buffer)); ret = ReadFile(hpipe, buffer, sizeof(buffer), &numbytes, NULL); - todo_wine ok(ret, "ReadFile failed with %u\n", GetLastError()); + ok(ret, "ReadFile failed with %u\n", GetLastError()); ok(numbytes == 0, "expected 0, got %u\n", numbytes); SetLastError(0xdeadbeef); diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index c2678d5..8738499 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -1726,8 +1726,11 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc break; } - if ((status = server_get_unix_fd( handle, FILE_READ_DATA, &fd, &needs_close, NULL, NULL ))) - break; + status = server_get_unix_fd( handle, FILE_READ_DATA, &fd, &needs_close, NULL, NULL ); + if (status == STATUS_BAD_DEVICE_TYPE) + return server_ioctl_file( handle, event, apc, apc_context, io, code, + in_buffer, in_size, out_buffer, out_size ); + if (status) break; #ifdef FIONREAD if (ioctl( fd, FIONREAD, &avail ) != 0) diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index a228d50..6df239a 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -1272,7 +1272,7 @@ static void test_iocp_fileio(HANDLE h) ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey ); ok( ioSb.Information == 0, "Invalid ioSb.Information: %ld\n", ioSb.Information ); /* wine sends wrong status here */ - todo_wine ok( U(ioSb).Status == STATUS_PIPE_BROKEN, "Invalid ioSb.Status: %x\n", U(ioSb).Status); + ok( U(ioSb).Status == STATUS_PIPE_BROKEN, "Invalid ioSb.Status: %x\n", U(ioSb).Status); ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue ); } } diff --git a/server/named_pipe.c b/server/named_pipe.c index 407d82e..13c2a4d 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 @@ -296,10 +297,10 @@ static const struct fd_ops named_pipe_device_fd_ops = default_fd_reselect_async /* reselect_async */ }; -/* Returns if we handle I/O via server calls. Currently disabled. */ +/* Returns if we handle I/O via server calls. Currently message-mode pipes are handled this way. */ static int use_server_io( struct pipe_end *pipe_end ) { - return 0; /* FIXME */ + return pipe_end->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE; } static void named_pipe_dump( struct object *obj, int verbose )