From d4918b4305a00a9c2b1818eef5b1d38a82344f4e Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Sat, 2 May 2020 10:09:40 -0500 Subject: [PATCH] kernel32-Named_Pipe: Remove patch set. We have had complete message mode named pipe support for multiple years now, and PIPE_NOWAIT for a while too. --- ...l32-tests-Only-allow-one-test-result.patch | 76 --- ...dd-tests-for-PeekNamedPipe-with-part.patch | 280 --------- ...dd-tests-for-sending-and-receiving-l.patch | 168 ----- ...ing-if-message-mode-is-not-supported.patch | 89 --- ...lar-code-in-NtReadFile-and-FILE_Asyn.patch | 171 ----- ...-to-check-for-broken-pipe-into-a-sep.patch | 107 ---- ...lar-code-in-NtWriteFile-and-FILE_Asy.patch | 130 ---- ...SEQPACKET-socket-in-combination-with.patch | 582 ------------------ ...ng-for-partially-received-messages-i.patch | 325 ---------- ...dd-more-tests-with-overlapped-IO-and.patch | 188 ------ ...e-tests-for-overlapped-partial-reads.patch | 85 --- ...est-sending-peeking-and-receiving-an.patch | 301 --------- ...ll-Add-support-for-nonblocking-pipes.patch | 52 -- ...dd-tests-for-PIPE_NOWAIT-in-message-.patch | 126 ---- ...o-set-PIPE_NOWAIT-on-byte-mode-pipes.patch | 112 ---- ...dd-additional-tests-for-PIPE_NOWAIT-.patch | 331 ---------- ...adDataAvailable-handling-in-FilePipe.patch | 46 -- ...ipeState-to-FILE_PIPE_CLOSING_STATE-.patch | 48 -- ...rrect-error-codes-for-NtWriteFile-wh.patch | 151 ----- ...file-descriptors-after-opening-a-fil.patch | 64 -- ...low-to-queue-async-operation-for-bro.patch | 39 -- patches/kernel32-Named_Pipe/definition | 6 - 22 files changed, 3477 deletions(-) delete mode 100644 patches/kernel32-Named_Pipe/0001-kernel32-tests-Only-allow-one-test-result.patch delete mode 100644 patches/kernel32-Named_Pipe/0002-kernel32-tests-Add-tests-for-PeekNamedPipe-with-part.patch delete mode 100644 patches/kernel32-Named_Pipe/0003-kernel32-tests-Add-tests-for-sending-and-receiving-l.patch delete mode 100644 patches/kernel32-Named_Pipe/0004-server-Show-warning-if-message-mode-is-not-supported.patch delete mode 100644 patches/kernel32-Named_Pipe/0005-ntdll-Unify-similar-code-in-NtReadFile-and-FILE_Asyn.patch delete mode 100644 patches/kernel32-Named_Pipe/0006-ntdll-Move-logic-to-check-for-broken-pipe-into-a-sep.patch delete mode 100644 patches/kernel32-Named_Pipe/0007-ntdll-Unify-similar-code-in-NtWriteFile-and-FILE_Asy.patch delete mode 100644 patches/kernel32-Named_Pipe/0008-server-Use-SOCK_SEQPACKET-socket-in-combination-with.patch delete mode 100644 patches/kernel32-Named_Pipe/0009-ntdll-Add-handling-for-partially-received-messages-i.patch delete mode 100644 patches/kernel32-Named_Pipe/0010-kernel32-tests-Add-more-tests-with-overlapped-IO-and.patch delete mode 100644 patches/kernel32-Named_Pipe/0011-ntdll-Fix-some-tests-for-overlapped-partial-reads.patch delete mode 100644 patches/kernel32-Named_Pipe/0012-kernel32-tests-Test-sending-peeking-and-receiving-an.patch delete mode 100644 patches/kernel32-Named_Pipe/0013-ntdll-Add-support-for-nonblocking-pipes.patch delete mode 100644 patches/kernel32-Named_Pipe/0014-kernel32-tests-Add-tests-for-PIPE_NOWAIT-in-message-.patch delete mode 100644 patches/kernel32-Named_Pipe/0015-ntdll-Allow-to-set-PIPE_NOWAIT-on-byte-mode-pipes.patch delete mode 100644 patches/kernel32-Named_Pipe/0016-kernel32-tests-Add-additional-tests-for-PIPE_NOWAIT-.patch delete mode 100644 patches/kernel32-Named_Pipe/0017-ntdll-Improve-ReadDataAvailable-handling-in-FilePipe.patch delete mode 100644 patches/kernel32-Named_Pipe/0018-ntdll-Set-NamedPipeState-to-FILE_PIPE_CLOSING_STATE-.patch delete mode 100644 patches/kernel32-Named_Pipe/0019-server-Return-correct-error-codes-for-NtWriteFile-wh.patch delete mode 100644 patches/kernel32-Named_Pipe/0020-ntdll-Pre-cache-file-descriptors-after-opening-a-fil.patch delete mode 100644 patches/kernel32-Named_Pipe/0021-server-Do-not-allow-to-queue-async-operation-for-bro.patch delete mode 100644 patches/kernel32-Named_Pipe/definition diff --git a/patches/kernel32-Named_Pipe/0001-kernel32-tests-Only-allow-one-test-result.patch b/patches/kernel32-Named_Pipe/0001-kernel32-tests-Only-allow-one-test-result.patch deleted file mode 100644 index 7cc7ed4f..00000000 --- a/patches/kernel32-Named_Pipe/0001-kernel32-tests-Only-allow-one-test-result.patch +++ /dev/null @@ -1,76 +0,0 @@ -From a483b0d4d6a16c07bcc7f65564974f5fc26c26d8 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Mon, 9 Nov 2015 17:19:42 +0100 -Subject: kernel32/tests: Only allow one test result. - -This reverts commit 3b7cdc0b8475f4eac910c5260c96c381ddbb630e. -Instead of hiding errors, update the todo_wine flags accordingly. ---- - dlls/kernel32/tests/pipe.c | 24 ++++++------------------ - 1 file changed, 6 insertions(+), 18 deletions(-) - -diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c -index ae09ef6..62ac77f 100644 ---- a/dlls/kernel32/tests/pipe.c -+++ b/dlls/kernel32/tests/pipe.c -@@ -294,14 +294,11 @@ static void test_CreateNamedPipe(int pipemode) - ok(written == sizeof(obuf2), "write file len 3b\n"); - ok(PeekNamedPipe(hFile, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek3\n"); - if (pipemode == PIPE_TYPE_BYTE) { -- /* currently the Wine behavior depends on the kernel version */ -- /* ok(readden == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes\n", readden); */ -- if (readden != sizeof(obuf) + sizeof(obuf2)) todo_wine ok(0, "peek3 got %d bytes\n", readden); -+ ok(readden == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes\n", readden); - } - 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); -+ todo_wine 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; -@@ -325,14 +322,11 @@ static void test_CreateNamedPipe(int pipemode) - ok(written == sizeof(obuf2), "write file len 4b\n"); - ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek4\n"); - if (pipemode == PIPE_TYPE_BYTE) { -- /* currently the Wine behavior depends on the kernel version */ -- /* ok(readden == sizeof(obuf) + sizeof(obuf2), "peek4 got %d bytes\n", readden); */ -- if (readden != sizeof(obuf) + sizeof(obuf2)) todo_wine ok(0, "peek4 got %d bytes\n", readden); -+ ok(readden == sizeof(obuf) + sizeof(obuf2), "peek4 got %d bytes\n", readden); - } - 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); -+ todo_wine 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; -@@ -373,10 +367,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); -- -+ todo_wine 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; - ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 5a check\n"); -@@ -408,10 +399,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); -- -+ todo_wine 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; - ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 6a check\n"); --- -2.6.2 - diff --git a/patches/kernel32-Named_Pipe/0002-kernel32-tests-Add-tests-for-PeekNamedPipe-with-part.patch b/patches/kernel32-Named_Pipe/0002-kernel32-tests-Add-tests-for-PeekNamedPipe-with-part.patch deleted file mode 100644 index fde60501..00000000 --- a/patches/kernel32-Named_Pipe/0002-kernel32-tests-Add-tests-for-PeekNamedPipe-with-part.patch +++ /dev/null @@ -1,280 +0,0 @@ -From 14bade0152141ee9ce78acd98b13d29abc450fea Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Thu, 31 Jul 2014 00:28:59 +0200 -Subject: kernel32/tests: Add tests for PeekNamedPipe with partial received - messages. - -This patch adds a couple more tests to ensure that PeekNamedPipe correctly -returns the number of remaining bytes which are part of the same message. -Moreover we have to be sure, that PeekNamedPipe also returns the same -information from all threads. - -Changes in v2: - * Also add tests for reverse direction. - -Changes in v3: - * Fix compiler warning on x86_64. ---- - dlls/kernel32/tests/pipe.c | 142 ++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 140 insertions(+), 2 deletions(-) - -diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c -index 7d89da5..13fdf60 100644 ---- a/dlls/kernel32/tests/pipe.c -+++ b/dlls/kernel32/tests/pipe.c -@@ -46,7 +46,8 @@ static void CALLBACK user_apc(ULONG_PTR param) - - enum rpcThreadOp - { -- RPC_READFILE -+ RPC_READFILE, -+ RPC_PEEKNAMEDPIPE - }; - - struct rpcThreadArgs -@@ -54,7 +55,7 @@ struct rpcThreadArgs - ULONG_PTR returnValue; - DWORD lastError; - enum rpcThreadOp op; -- ULONG_PTR args[5]; -+ ULONG_PTR args[6]; - }; - - static DWORD CALLBACK rpcThreadMain(LPVOID arg) -@@ -73,6 +74,15 @@ static DWORD CALLBACK rpcThreadMain(LPVOID arg) - (LPOVERLAPPED)rpcargs->args[4] ); /* overlapped */ - break; - -+ case RPC_PEEKNAMEDPIPE: -+ rpcargs->returnValue = (ULONG_PTR)PeekNamedPipe( (HANDLE)rpcargs->args[0], /* hPipe */ -+ (LPVOID)rpcargs->args[1], /* lpvBuffer */ -+ (DWORD)rpcargs->args[2], /* cbBuffer */ -+ (LPDWORD)rpcargs->args[3], /* lpcbRead */ -+ (LPDWORD)rpcargs->args[4], /* lpcbAvail */ -+ (LPDWORD)rpcargs->args[5] ); /* lpcbMessage */ -+ break; -+ - default: - SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); - rpcargs->returnValue = 0; -@@ -117,6 +127,33 @@ static void _test_signaled(unsigned line, HANDLE handle) - ok_(__FILE__,line)(res == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", res); - } - -+/* Runs PeekNamedPipe(...) from a different thread */ -+static BOOL RpcPeekNamedPipe(HANDLE hPipe, LPVOID lpvBuffer, DWORD cbBuffer, -+ LPDWORD lpcbRead, LPDWORD lpcbAvail, LPDWORD lpcbMessage) -+{ -+ struct rpcThreadArgs rpcargs; -+ HANDLE thread; -+ DWORD threadId; -+ -+ rpcargs.returnValue = 0; -+ rpcargs.lastError = GetLastError(); -+ rpcargs.op = RPC_PEEKNAMEDPIPE; -+ rpcargs.args[0] = (ULONG_PTR)hPipe; -+ rpcargs.args[1] = (ULONG_PTR)lpvBuffer; -+ rpcargs.args[2] = (ULONG_PTR)cbBuffer; -+ rpcargs.args[3] = (ULONG_PTR)lpcbRead; -+ rpcargs.args[4] = (ULONG_PTR)lpcbAvail; -+ rpcargs.args[5] = (ULONG_PTR)lpcbMessage; -+ -+ thread = CreateThread(NULL, 0, rpcThreadMain, (void *)&rpcargs, 0, &threadId); -+ ok(thread != NULL, "CreateThread failed. %d\n", GetLastError()); -+ ok(WaitForSingleObject(thread, INFINITE) == WAIT_OBJECT_0,"WaitForSingleObject failed with %d.\n", GetLastError()); -+ CloseHandle(thread); -+ -+ SetLastError(rpcargs.lastError); -+ return (BOOL)rpcargs.returnValue; -+} -+ - static void test_CreateNamedPipe(int pipemode) - { - HANDLE hnp; -@@ -126,6 +163,7 @@ static void test_CreateNamedPipe(int pipemode) - char ibuf[32], *pbuf; - DWORD written; - DWORD readden; -+ DWORD leftmsg; - DWORD avail; - DWORD lpmode; - BOOL ret; -@@ -241,9 +279,21 @@ static void test_CreateNamedPipe(int pipemode) - ok(written == sizeof(obuf2), "write file len\n"); - ok(ReadFile(hFile, ibuf, 4, &readden, NULL), "ReadFile\n"); - ok(readden == 4, "read got %d bytes\n", readden); -+ readden = leftmsg = -1; -+ ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "PeekNamedPipe\n"); -+ ok(readden == sizeof(obuf2) - 4, "peek got %d bytes total\n", readden); -+ if (pipemode == PIPE_TYPE_BYTE) -+ ok(leftmsg == 0, "peek got %d bytes left in message\n", leftmsg); -+ else -+ todo_wine -+ ok(leftmsg == sizeof(obuf2) - 4, "peek got %d bytes left in message\n", leftmsg); - ok(ReadFile(hFile, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile\n"); - ok(readden == sizeof(obuf2) - 4, "read got %d bytes\n", readden); - ok(memcmp(obuf2, ibuf, written) == 0, "content check\n"); -+ readden = leftmsg = -1; -+ ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "PeekNamedPipe\n"); -+ ok(readden == 0, "peek got %d bytes total\n", readden); -+ ok(leftmsg == 0, "peek got %d bytes left in message\n", leftmsg); - - memset(ibuf, 0, sizeof(ibuf)); - ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile\n"); -@@ -456,6 +506,16 @@ static void test_CreateNamedPipe(int pipemode) - ok(written == sizeof(obuf), "write file len 9\n"); - ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), "WriteFile 9\n"); - ok(written == sizeof(obuf2), "write file len 9\n"); -+ readden = leftmsg = -1; -+ ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "PeekNamedPipe 9\n"); -+ ok(readden == sizeof(obuf) + sizeof(obuf2), "peek got %d bytes total 9\n", readden); -+ todo_wine -+ ok(leftmsg == sizeof(obuf), "peek got %d bytes left in message 9\n", leftmsg); -+ readden = leftmsg = -1; -+ ok(RpcPeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "RpcPeekNamedPipe 9\n"); -+ ok(readden == sizeof(obuf) + sizeof(obuf2), "peek got %d bytes total 9\n", readden); -+ todo_wine -+ ok(leftmsg == sizeof(obuf), "peek got %d bytes left in message 9\n", leftmsg); - SetLastError(0xdeadbeef); - todo_wine - ok(!ReadFile(hFile, ibuf, 4, &readden, NULL), "ReadFile 9\n"); -@@ -469,6 +529,16 @@ static void test_CreateNamedPipe(int pipemode) - todo_wine - ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n"); - ok(readden == 4, "read got %d bytes 9\n", readden); -+ readden = leftmsg = -1; -+ ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "PeekNamedPipe 9\n"); -+ ok(readden == sizeof(obuf) - 8 + sizeof(obuf2), "peek got %d bytes total 9\n", readden); -+ todo_wine -+ ok(leftmsg == sizeof(obuf) - 8, "peek got %d bytes left in message 9\n", leftmsg); -+ readden = leftmsg = -1; -+ ok(RpcPeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "RpcPeekNamedPipe 9\n"); -+ ok(readden == sizeof(obuf) - 8 + sizeof(obuf2), "peek got %d bytes total 9\n", readden); -+ todo_wine -+ ok(leftmsg == sizeof(obuf) - 8, "peek got %d bytes left in message 9\n", leftmsg); - ret = RpcReadFile(hFile, ibuf + 8, sizeof(ibuf), &readden, NULL); - ok(ret, "RpcReadFile 9\n"); - todo_wine -@@ -477,6 +547,14 @@ static void test_CreateNamedPipe(int pipemode) - if (readden <= sizeof(obuf) - 8) /* blocks forever if second part was already received */ - { - memset(ibuf, 0, sizeof(ibuf)); -+ readden = leftmsg = -1; -+ ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "PeekNamedPipe 9\n"); -+ ok(readden == sizeof(obuf2), "peek got %d bytes total 9\n", readden); -+ ok(leftmsg == sizeof(obuf2), "peek got %d bytes left in message 9\n", leftmsg); -+ readden = leftmsg = -1; -+ ok(RpcPeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "RpcPeekNamedPipe 9\n"); -+ ok(readden == sizeof(obuf2), "peek got %d bytes total 9\n", readden); -+ ok(leftmsg == sizeof(obuf2), "peek got %d bytes left in message 9\n", leftmsg); - SetLastError(0xdeadbeef); - ret = RpcReadFile(hFile, ibuf, 4, &readden, NULL); - ok(!ret, "RpcReadFile 9\n"); -@@ -489,11 +567,27 @@ static void test_CreateNamedPipe(int pipemode) - todo_wine - ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n"); - ok(readden == 4, "read got %d bytes 9\n", readden); -+ readden = leftmsg = -1; -+ ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "PeekNamedPipe 9\n"); -+ ok(readden == sizeof(obuf2) - 8, "peek got %d bytes total 9\n", readden); -+ ok(leftmsg == sizeof(obuf2) - 8, "peek got %d bytes left in message 9\n", leftmsg); -+ readden = leftmsg = -1; -+ ok(RpcPeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "RpcPeekNamedPipe 9\n"); -+ ok(readden == sizeof(obuf2) - 8, "peek got %d bytes total 9\n", readden); -+ ok(leftmsg == sizeof(obuf2) - 8, "peek got %d bytes left in message 9\n", leftmsg); - ret = RpcReadFile(hFile, ibuf + 8, sizeof(ibuf), &readden, NULL); - ok(ret, "RpcReadFile 9\n"); - ok(readden == sizeof(obuf2) - 8, "read got %d bytes 9\n", readden); - ok(memcmp(obuf2, ibuf, sizeof(obuf2)) == 0, "content check 9\n"); - } -+ readden = leftmsg = -1; -+ ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "PeekNamedPipe 9\n"); -+ ok(readden == 0, "peek got %d bytes total 9\n", readden); -+ ok(leftmsg == 0, "peek got %d bytes left in message 9\n", leftmsg); -+ readden = leftmsg = -1; -+ ok(RpcPeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "RpcPeekNamedPipe 9\n"); -+ ok(readden == 0, "peek got %d bytes total 9\n", readden); -+ ok(leftmsg == 0, "peek got %d bytes left in message 9\n", leftmsg); - - /* Now the reverse direction */ - memset(ibuf, 0, sizeof(ibuf)); -@@ -501,6 +595,16 @@ static void test_CreateNamedPipe(int pipemode) - ok(written == sizeof(obuf2), "write file len 10\n"); - ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile 10\n"); - ok(written == sizeof(obuf), "write file len 10\n"); -+ readden = leftmsg = -1; -+ ok(PeekNamedPipe(hnp, NULL, 0, NULL, &readden, &leftmsg), "PeekNamedPipe 10\n"); -+ ok(readden == sizeof(obuf) + sizeof(obuf2), "peek got %d bytes total 10\n", readden); -+ todo_wine -+ ok(leftmsg == sizeof(obuf2), "peek got %d bytes left in message 10\n", leftmsg); -+ readden = leftmsg = -1; -+ ok(RpcPeekNamedPipe(hnp, NULL, 0, NULL, &readden, &leftmsg), "RpcPeekNamedPipe 10\n"); -+ ok(readden == sizeof(obuf) + sizeof(obuf2), "peek got %d bytes total 10\n", readden); -+ todo_wine -+ ok(leftmsg == sizeof(obuf2), "peek got %d bytes left in message 10\n", leftmsg); - SetLastError(0xdeadbeef); - todo_wine - ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile 10\n"); -@@ -514,6 +618,16 @@ static void test_CreateNamedPipe(int pipemode) - todo_wine - ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n"); - ok(readden == 4, "read got %d bytes 10\n", readden); -+ readden = leftmsg = -1; -+ ok(PeekNamedPipe(hnp, NULL, 0, NULL, &readden, &leftmsg), "PeekNamedPipe 10\n"); -+ ok(readden == sizeof(obuf2) - 8 + sizeof(obuf), "peek got %d bytes total 10\n", readden); -+ todo_wine -+ ok(leftmsg == sizeof(obuf2) - 8, "peek got %d bytes left in message 10\n", leftmsg); -+ readden = leftmsg = -1; -+ ok(RpcPeekNamedPipe(hnp, NULL, 0, NULL, &readden, &leftmsg), "RpcPeekNamedPipe 10\n"); -+ ok(readden == sizeof(obuf2) - 8 + sizeof(obuf), "peek got %d bytes total 10\n", readden); -+ todo_wine -+ ok(leftmsg == sizeof(obuf2) - 8, "peek got %d bytes left in message 10\n", leftmsg); - ret = RpcReadFile(hnp, ibuf + 8, sizeof(ibuf), &readden, NULL); - ok(ret, "RpcReadFile 10\n"); - todo_wine -@@ -522,6 +636,14 @@ static void test_CreateNamedPipe(int pipemode) - if (readden <= sizeof(obuf2) - 8) /* blocks forever if second part was already received */ - { - memset(ibuf, 0, sizeof(ibuf)); -+ readden = leftmsg = -1; -+ ok(PeekNamedPipe(hnp, NULL, 0, NULL, &readden, &leftmsg), "PeekNamedPipe 10\n"); -+ ok(readden == sizeof(obuf), "peek got %d bytes total 10\n", readden); -+ ok(leftmsg == sizeof(obuf), "peek got %d bytes left in message 10\n", leftmsg); -+ readden = leftmsg = -1; -+ ok(RpcPeekNamedPipe(hnp, NULL, 0, NULL, &readden, &leftmsg), "RpcPeekNamedPipe 10\n"); -+ ok(readden == sizeof(obuf), "peek got %d bytes total 10\n", readden); -+ ok(leftmsg == sizeof(obuf), "peek got %d bytes left in message 10\n", leftmsg); - SetLastError(0xdeadbeef); - ret = RpcReadFile(hnp, ibuf, 4, &readden, NULL); - ok(!ret, "RpcReadFile 10\n"); -@@ -534,11 +656,27 @@ static void test_CreateNamedPipe(int pipemode) - todo_wine - ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n"); - ok(readden == 4, "read got %d bytes 10\n", readden); -+ readden = leftmsg = -1; -+ ok(PeekNamedPipe(hnp, NULL, 0, NULL, &readden, &leftmsg), "PeekNamedPipe 10\n"); -+ ok(readden == sizeof(obuf) - 8, "peek got %d bytes total 10\n", readden); -+ ok(leftmsg == sizeof(obuf) - 8, "peek got %d bytes left in message 10\n", leftmsg); -+ readden = leftmsg = -1; -+ ok(RpcPeekNamedPipe(hnp, NULL, 0, NULL, &readden, &leftmsg), "RpcPeekNamedPipe 10\n"); -+ ok(readden == sizeof(obuf) - 8, "peek got %d bytes total 10\n", readden); -+ ok(leftmsg == sizeof(obuf) - 8, "peek got %d bytes left in message 10\n", leftmsg); - ret = RpcReadFile(hnp, ibuf + 8, sizeof(ibuf), &readden, NULL); - ok(ret, "RpcReadFile 10\n"); - ok(readden == sizeof(obuf) - 8, "read got %d bytes 10\n", readden); - ok(memcmp(obuf, ibuf, sizeof(obuf)) == 0, "content check 10\n"); - } -+ readden = leftmsg = -1; -+ ok(PeekNamedPipe(hnp, NULL, 0, NULL, &readden, &leftmsg), "PeekNamedPipe 10\n"); -+ ok(readden == 0, "peek got %d bytes total 10\n", readden); -+ ok(leftmsg == 0, "peek got %d bytes left in message 10\n", leftmsg); -+ readden = leftmsg = -1; -+ ok(RpcPeekNamedPipe(hnp, NULL, 0, NULL, &readden, &leftmsg), "RpcPeekNamedPipe 10\n"); -+ ok(readden == 0, "peek got %d bytes total 10\n", readden); -+ ok(leftmsg == 0, "peek got %d bytes left in message 10\n", leftmsg); - - } - --- -2.9.0 - diff --git a/patches/kernel32-Named_Pipe/0003-kernel32-tests-Add-tests-for-sending-and-receiving-l.patch b/patches/kernel32-Named_Pipe/0003-kernel32-tests-Add-tests-for-sending-and-receiving-l.patch deleted file mode 100644 index bf51f43c..00000000 --- a/patches/kernel32-Named_Pipe/0003-kernel32-tests-Add-tests-for-sending-and-receiving-l.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 695d78fbb48472fce38f103fba76f56c36a4cb5d Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sun, 3 Aug 2014 23:14:35 +0200 -Subject: kernel32/tests: Add tests for sending and receiving large messages. - -This set of tests seems to confirm that on Windows, there is no upper size -limit where messages are splitted. The kernel seems to temporarily allocate -additional buffers (or use existing buffers very efficient), so WriteFile() -can never fail because of size limitations. - -Changes in v2: - * Avoid compilation warning on x86_64. ---- - dlls/kernel32/tests/pipe.c | 124 +++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 124 insertions(+) - -diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c -index a252bc8..246ee30 100644 ---- a/dlls/kernel32/tests/pipe.c -+++ b/dlls/kernel32/tests/pipe.c -@@ -47,6 +47,7 @@ static void CALLBACK user_apc(ULONG_PTR param) - enum rpcThreadOp - { - RPC_READFILE, -+ RPC_WRITEFILE, - RPC_PEEKNAMEDPIPE - }; - -@@ -74,6 +75,14 @@ static DWORD CALLBACK rpcThreadMain(LPVOID arg) - (LPOVERLAPPED)rpcargs->args[4] ); /* overlapped */ - break; - -+ case RPC_WRITEFILE: -+ rpcargs->returnValue = (ULONG_PTR)WriteFile( (HANDLE)rpcargs->args[0], /* hFile */ -+ (LPCVOID)rpcargs->args[1], /* buffer */ -+ (DWORD)rpcargs->args[2], /* bytesToWrite */ -+ (LPDWORD)rpcargs->args[3], /* bytesWritten */ -+ (LPOVERLAPPED)rpcargs->args[4] ); /* overlapped */ -+ break; -+ - case RPC_PEEKNAMEDPIPE: - rpcargs->returnValue = (ULONG_PTR)PeekNamedPipe( (HANDLE)rpcargs->args[0], /* hPipe */ - (LPVOID)rpcargs->args[1], /* lpvBuffer */ -@@ -671,6 +680,121 @@ static void test_CreateNamedPipe(int pipemode) - - } - -+ /* Test behaviour for very huge messages (which don't fit completely in the buffer) */ -+ { -+ static char big_obuf[512 * 1024]; -+ static char big_ibuf[512 * 1024]; -+ struct rpcThreadArgs rpcargs; -+ HANDLE thread; -+ DWORD threadId; -+ memset(big_obuf, 0xAA, sizeof(big_obuf)); -+ -+ /* Ensure that both pipes are empty before we continue with the next test */ -+ while (PeekNamedPipe(hFile, NULL, 0, NULL, &readden, NULL) && readden > 0) -+ ok(ReadFile(hFile, big_ibuf, sizeof(big_ibuf), &readden, NULL) || -+ GetLastError() == ERROR_MORE_DATA, "ReadFile\n"); -+ -+ while (PeekNamedPipe(hnp, NULL, 0, NULL, &readden, NULL) && readden > 0) -+ ok(ReadFile(hnp, big_ibuf, sizeof(big_ibuf), &readden, NULL) || -+ GetLastError() == ERROR_MORE_DATA, "ReadFile\n"); -+ -+ readden = leftmsg = -1; -+ ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "PeekNamedPipe\n"); -+ ok(readden == 0, "peek got %d bytes total\n", readden); -+ ok(leftmsg == 0, "peek got %d bytes left in message\n", leftmsg); -+ -+ /* transmit big message, receive with buffer of equal size */ -+ memset(big_ibuf, 0, sizeof(big_ibuf)); -+ rpcargs.returnValue = 0; -+ rpcargs.lastError = GetLastError(); -+ rpcargs.op = RPC_WRITEFILE; -+ rpcargs.args[0] = (ULONG_PTR)hnp; -+ rpcargs.args[1] = (ULONG_PTR)big_obuf; -+ rpcargs.args[2] = (ULONG_PTR)sizeof(big_obuf); -+ rpcargs.args[3] = (ULONG_PTR)&written; -+ rpcargs.args[4] = (ULONG_PTR)NULL; -+ -+ thread = CreateThread(NULL, 0, rpcThreadMain, (void *)&rpcargs, 0, &threadId); -+ ok(thread != NULL, "CreateThread failed. %d\n", GetLastError()); -+ ret = WaitForSingleObject(thread, 200); -+ ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %d instead of %d.\n", ret, WAIT_TIMEOUT); -+ ok(ReadFile(hFile, big_ibuf, sizeof(big_ibuf), &readden, NULL), "ReadFile\n"); -+ todo_wine -+ ok(readden == sizeof(big_obuf), "read got %d bytes\n", readden); -+ todo_wine -+ ok(memcmp(big_ibuf, big_obuf, sizeof(big_obuf)) == 0, "content check\n"); -+ do -+ { -+ ret = WaitForSingleObject(thread, 1); -+ while (PeekNamedPipe(hFile, NULL, 0, NULL, &readden, NULL) && readden > 0) -+ ok(ReadFile(hFile, big_ibuf, sizeof(big_ibuf), &readden, NULL) || -+ GetLastError() == ERROR_MORE_DATA, "ReadFile\n"); -+ } -+ while (ret == WAIT_TIMEOUT); -+ ok(WaitForSingleObject(thread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed with %d.\n", GetLastError()); -+ ok((BOOL)rpcargs.returnValue, "WriteFile\n"); -+ ok(written == sizeof(big_obuf), "write file len\n"); -+ CloseHandle(thread); -+ -+ readden = leftmsg = -1; -+ ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "PeekNamedPipe\n"); -+ ok(readden == 0, "peek got %d bytes total\n", readden); -+ ok(leftmsg == 0, "peek got %d bytes left in message\n", leftmsg); -+ -+ /* same as above, but receive as multiple parts */ -+ memset(big_ibuf, 0, sizeof(big_ibuf)); -+ rpcargs.returnValue = 0; -+ rpcargs.lastError = GetLastError(); -+ -+ thread = CreateThread(NULL, 0, rpcThreadMain, (void *)&rpcargs, 0, &threadId); -+ ok(thread != NULL, "CreateThread failed. %d\n", GetLastError()); -+ ret = WaitForSingleObject(thread, 200); -+ ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %d instead of %d.\n", ret, WAIT_TIMEOUT); -+ if (pipemode == PIPE_TYPE_BYTE) -+ { -+ ok(ReadFile(hFile, big_ibuf, 32, &readden, NULL), "ReadFile\n"); -+ ok(readden == 32, "read got %d bytes\n", readden); -+ ok(ReadFile(hFile, big_ibuf + 32, 32, &readden, NULL), "ReadFile\n"); -+ } -+ else -+ { -+ SetLastError(0xdeadbeef); -+ todo_wine -+ ok(!ReadFile(hFile, big_ibuf, 32, &readden, NULL), "ReadFile\n"); -+ todo_wine -+ ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n"); -+ ok(readden == 32, "read got %d bytes\n", readden); -+ SetLastError(0xdeadbeef); -+ todo_wine -+ ok(!ReadFile(hFile, big_ibuf + 32, 32, &readden, NULL), "ReadFile\n"); -+ todo_wine -+ ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n"); -+ } -+ ok(readden == 32, "read got %d bytes\n", readden); -+ ok(ReadFile(hFile, big_ibuf + 64, sizeof(big_ibuf) - 64, &readden, NULL), "ReadFile\n"); -+ todo_wine -+ ok(readden == sizeof(big_obuf) - 64, "read got %d bytes\n", readden); -+ todo_wine -+ ok(memcmp(big_ibuf, big_obuf, sizeof(big_obuf)) == 0, "content check\n"); -+ do -+ { -+ ret = WaitForSingleObject(thread, 1); -+ while (PeekNamedPipe(hFile, NULL, 0, NULL, &readden, NULL) && readden > 0) -+ ok(ReadFile(hFile, big_ibuf, sizeof(big_ibuf), &readden, NULL) || -+ GetLastError() == ERROR_MORE_DATA, "ReadFile\n"); -+ } -+ while (ret == WAIT_TIMEOUT); -+ ok(WaitForSingleObject(thread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed with %d.\n", GetLastError()); -+ ok((BOOL)rpcargs.returnValue, "WriteFile\n"); -+ ok(written == sizeof(big_obuf), "write file len\n"); -+ CloseHandle(thread); -+ -+ readden = leftmsg = -1; -+ ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "PeekNamedPipe\n"); -+ ok(readden == 0, "peek got %d bytes total\n", readden); -+ ok(leftmsg == 0, "peek got %d bytes left in message\n", leftmsg); -+ } -+ - /* Picky conformance tests */ - - /* Verify that you can't connect to pipe again --- -2.1.3 - diff --git a/patches/kernel32-Named_Pipe/0004-server-Show-warning-if-message-mode-is-not-supported.patch b/patches/kernel32-Named_Pipe/0004-server-Show-warning-if-message-mode-is-not-supported.patch deleted file mode 100644 index b8c6a275..00000000 --- a/patches/kernel32-Named_Pipe/0004-server-Show-warning-if-message-mode-is-not-supported.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 630edc66479db789c7541e2c356a41090524d838 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Mon, 4 Aug 2014 00:29:26 +0200 -Subject: server: Show warning if message mode is not supported. - -This patch changes the create_named_pipe wineserver call to return -which flags were supported. This allows to show a FIXME in ntdll for -missing message mode support. ---- - dlls/ntdll/file.c | 14 ++++++++++---- - server/named_pipe.c | 2 ++ - server/protocol.def | 1 + - 3 files changed, 13 insertions(+), 4 deletions(-) - -diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index 3883e5a..9e98f36 100644 ---- a/dlls/ntdll/file.c -+++ b/dlls/ntdll/file.c -@@ -3507,6 +3507,7 @@ NTSTATUS WINAPI NtCreateNamedPipeFile( PHANDLE handle, ULONG access, - NTSTATUS status; - data_size_t len; - struct object_attributes *objattr; -+ unsigned int flags; - - TRACE("(%p %x %s %p %x %d %x %d %d %d %d %d %d %p)\n", - handle, access, debugstr_w(attr->ObjectName->Buffer), iosb, sharing, dispo, -@@ -3521,15 +3522,16 @@ NTSTATUS WINAPI NtCreateNamedPipeFile( PHANDLE handle, ULONG access, - - if ((status = alloc_object_attributes( attr, &objattr, &len ))) return status; - -+ flags = (pipe_type ? NAMED_PIPE_MESSAGE_STREAM_WRITE : 0) | -+ (read_mode ? NAMED_PIPE_MESSAGE_STREAM_READ : 0) | -+ (completion_mode ? NAMED_PIPE_NONBLOCKING_MODE : 0); -+ - SERVER_START_REQ( create_named_pipe ) - { - req->access = access; - req->options = options; - req->sharing = sharing; -- req->flags = -- (pipe_type ? NAMED_PIPE_MESSAGE_STREAM_WRITE : 0) | -- (read_mode ? NAMED_PIPE_MESSAGE_STREAM_READ : 0) | -- (completion_mode ? NAMED_PIPE_NONBLOCKING_MODE : 0); -+ req->flags = flags; - req->maxinstances = max_inst; - req->outsize = outbound_quota; - req->insize = inbound_quota; -@@ -3537,9 +3539,13 @@ NTSTATUS WINAPI NtCreateNamedPipeFile( PHANDLE handle, ULONG access, - wine_server_add_data( req, objattr, len ); - status = wine_server_call( req ); - if (!status) *handle = wine_server_ptr_handle( reply->handle ); -+ flags &= ~reply->flags; /* contains now all unsupported flags */ - } - SERVER_END_REQ; - -+ if (!status && (flags & (NAMED_PIPE_MESSAGE_STREAM_WRITE | NAMED_PIPE_MESSAGE_STREAM_READ))) -+ FIXME("Message mode not supported, falling back to byte mode.\n"); -+ - RtlFreeHeap( GetProcessHeap(), 0, objattr ); - return status; - } -diff --git a/server/named_pipe.c b/server/named_pipe.c -index 7a97e35..ee6008c 100644 ---- a/server/named_pipe.c -+++ b/server/named_pipe.c -@@ -934,6 +934,8 @@ DECL_HANDLER(create_named_pipe) - return; - } - -+ reply->flags = req->flags & ~(NAMED_PIPE_MESSAGE_STREAM_WRITE | NAMED_PIPE_MESSAGE_STREAM_READ); -+ - if (!name.len) /* pipes need a root directory even without a name */ - { - if (!objattr->rootdir) -diff --git a/server/protocol.def b/server/protocol.def -index a5a45eb..2d87f03 100644 ---- a/server/protocol.def -+++ b/server/protocol.def -@@ -2370,6 +2370,7 @@ enum message_type - unsigned int flags; - VARARG(objattr,object_attributes); /* object attributes */ - @REPLY -+ unsigned int flags; - obj_handle_t handle; /* handle to the pipe */ - @END - --- -2.7.0 - diff --git a/patches/kernel32-Named_Pipe/0005-ntdll-Unify-similar-code-in-NtReadFile-and-FILE_Asyn.patch b/patches/kernel32-Named_Pipe/0005-ntdll-Unify-similar-code-in-NtReadFile-and-FILE_Asyn.patch deleted file mode 100644 index 21deb317..00000000 --- a/patches/kernel32-Named_Pipe/0005-ntdll-Unify-similar-code-in-NtReadFile-and-FILE_Asyn.patch +++ /dev/null @@ -1,171 +0,0 @@ -From db2c7e03ab42dc8e97a02e8531948c86840b207a Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Fri, 15 Aug 2014 22:23:08 +0200 -Subject: ntdll: Unify similar code in NtReadFile and FILE_AsyncReadService. - -Please note that besides merging the functions (which makes the code much -more readable) this also fixes some inconsistencies. Basically the code -from a unix fd should do the same in both cases, but it didn't... - -Changes in FILE_AsyncReadService: - * Immediately retry on EINTR, chances are very good that it will - succeed in a second attempt, and its not worth to use different code - because of this small difference. - * When read(...) == 0 the result code was always STATUS_PIPE_BROKEN, - whereas NtReadFile uses different behaviour based on the fd type. - Now both implementations match, and behave the same way. ---- - dlls/ntdll/file.c | 107 +++++++++++++++++++++++------------------------------- - 1 file changed, 46 insertions(+), 61 deletions(-) - -diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index 1c23f9e..5dab5c9 100644 ---- a/dlls/ntdll/file.c -+++ b/dlls/ntdll/file.c -@@ -484,6 +484,45 @@ NTSTATUS FILE_GetNtStatus(void) - } - } - -+/* helper function for NtReadFile and FILE_AsyncReadService */ -+static NTSTATUS read_unix_fd(int fd, char *buf, ULONG *total, ULONG length, -+ enum server_fd_type type, BOOL avail_mode) -+{ -+ int result; -+ for(;;) -+ { -+ result = read( fd, buf + *total, length - *total ); -+ if (result >= 0) -+ { -+ *total += result; -+ if (!result || *total >= length || avail_mode) -+ { -+ if (*total) -+ return STATUS_SUCCESS; -+ switch (type) -+ { -+ case FD_TYPE_FILE: -+ case FD_TYPE_CHAR: -+ case FD_TYPE_DEVICE: -+ return length ? STATUS_END_OF_FILE : STATUS_SUCCESS; -+ case FD_TYPE_SERIAL: -+ return length ? STATUS_PENDING : STATUS_SUCCESS; -+ default: -+ return STATUS_PIPE_BROKEN; -+ } -+ } -+ else if (type != FD_TYPE_FILE) /* no async I/O on regular files */ -+ return STATUS_PENDING; -+ } -+ else if (errno != EINTR) -+ { -+ if (errno == EAGAIN) break; -+ return FILE_GetNtStatus(); -+ } -+ } -+ return STATUS_PENDING; -+} -+ - /*********************************************************************** - * FILE_AsyncReadService (INTERNAL) - */ -@@ -491,38 +530,19 @@ static NTSTATUS FILE_AsyncReadService( void *user, IO_STATUS_BLOCK *iosb, - NTSTATUS status, void **apc, void **arg ) - { - struct async_fileio_read *fileio = user; -- int fd, needs_close, result; -+ int fd, needs_close; -+ enum server_fd_type type; - - switch (status) - { - case STATUS_ALERTED: /* got some new data */ - /* check to see if the data is ready (non-blocking) */ - if ((status = server_get_unix_fd( fileio->io.handle, FILE_READ_DATA, &fd, -- &needs_close, NULL, NULL ))) -+ &needs_close, &type, NULL ))) - break; -- -- result = read(fd, &fileio->buffer[fileio->already], fileio->count - fileio->already); -+ status = read_unix_fd( fd, fileio->buffer, &fileio->already, fileio->count, -+ type, fileio->avail_mode ); - if (needs_close) close( fd ); -- -- if (result < 0) -- { -- if (errno == EAGAIN || errno == EINTR) -- status = STATUS_PENDING; -- else /* check to see if the transfer is complete */ -- status = FILE_GetNtStatus(); -- } -- else if (result == 0) -- { -- status = fileio->already ? STATUS_SUCCESS : STATUS_PIPE_BROKEN; -- } -- else -- { -- fileio->already += result; -- if (fileio->already >= fileio->count || fileio->avail_mode) -- status = STATUS_SUCCESS; -- else -- status = STATUS_PENDING; -- } - break; - - case STATUS_TIMEOUT: -@@ -769,7 +789,6 @@ static NTSTATUS get_io_avail_mode( HANDLE handle, enum server_fd_type type, BOOL - return status; - } - -- - /****************************************************************************** - * NtReadFile [NTDLL.@] - * ZwReadFile [NTDLL.@] -@@ -865,43 +884,9 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent, - - for (;;) - { -- if ((result = read( unix_handle, (char *)buffer + total, length - total )) >= 0) -- { -- total += result; -- if (!result || total == length) -- { -- if (total) -- { -- status = STATUS_SUCCESS; -- goto done; -- } -- switch (type) -- { -- case FD_TYPE_FILE: -- case FD_TYPE_CHAR: -- case FD_TYPE_DEVICE: -- status = length ? STATUS_END_OF_FILE : STATUS_SUCCESS; -- goto done; -- case FD_TYPE_SERIAL: -- if (!length) -- { -- status = STATUS_SUCCESS; -- goto done; -- } -- break; -- default: -- status = STATUS_PIPE_BROKEN; -- goto done; -- } -- } -- else if (type == FD_TYPE_FILE) continue; /* no async I/O on regular files */ -- } -- else if (errno != EAGAIN) -- { -- if (errno == EINTR) continue; -- if (!total) status = FILE_GetNtStatus(); -+ status = read_unix_fd( unix_handle, buffer, &total, length, type, FALSE ); -+ if (status != STATUS_PENDING) - goto done; -- } - - if (async_read) - { --- -2.7.1 - diff --git a/patches/kernel32-Named_Pipe/0006-ntdll-Move-logic-to-check-for-broken-pipe-into-a-sep.patch b/patches/kernel32-Named_Pipe/0006-ntdll-Move-logic-to-check-for-broken-pipe-into-a-sep.patch deleted file mode 100644 index 11368b8f..00000000 --- a/patches/kernel32-Named_Pipe/0006-ntdll-Move-logic-to-check-for-broken-pipe-into-a-sep.patch +++ /dev/null @@ -1,107 +0,0 @@ -From a469c846c5e2abc7a0a4c478b33aeaa83e53f6bb Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Fri, 15 Aug 2014 23:06:06 +0200 -Subject: ntdll: Move logic to check for broken pipe into a separate function. - ---- - dlls/ntdll/file.c | 75 +++++++++++++++++++++++++++++-------------------------- - 1 file changed, 39 insertions(+), 36 deletions(-) - -diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index 41dd1ae877..03864b7239 100644 ---- a/dlls/ntdll/file.c -+++ b/dlls/ntdll/file.c -@@ -490,6 +490,31 @@ NTSTATUS FILE_GetNtStatus(void) - } - } - -+/* helper function for FSCTL_PIPE_PEEK */ -+static NTSTATUS unix_fd_avail(int fd, int *avail) -+{ -+ struct pollfd pollfd; -+ int ret; -+ *avail = 0; -+ -+#ifdef FIONREAD -+ if (ioctl( fd, FIONREAD, avail ) != 0) -+ { -+ TRACE("FIONREAD failed reason: %s\n", strerror(errno)); -+ return FILE_GetNtStatus(); -+ } -+ if (*avail) -+ return STATUS_SUCCESS; -+#endif -+ -+ pollfd.fd = fd; -+ pollfd.events = POLLIN; -+ pollfd.revents = 0; -+ ret = poll( &pollfd, 1, 0 ); -+ return (ret == -1 || (ret == 1 && (pollfd.revents & (POLLHUP|POLLERR)))) ? -+ STATUS_PIPE_BROKEN : STATUS_SUCCESS; -+} -+ - /* helper function for NtReadFile and FILE_AsyncReadService */ - static NTSTATUS read_unix_fd(int fd, char *buf, ULONG *total, ULONG length, - enum server_fd_type type, BOOL avail_mode) -@@ -1719,44 +1744,22 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc - break; - } - --#ifdef FIONREAD -- if (ioctl( fd, FIONREAD, &avail ) != 0) -- { -- TRACE("FIONREAD failed reason: %s\n",strerror(errno)); -- if (needs_close) close( fd ); -- status = FILE_GetNtStatus(); -- break; -- } --#endif -- if (!avail) /* check for closed pipe */ -- { -- struct pollfd pollfd; -- int ret; -- -- pollfd.fd = fd; -- pollfd.events = POLLIN; -- pollfd.revents = 0; -- ret = poll( &pollfd, 1, 0 ); -- if (ret == -1 || (ret == 1 && (pollfd.revents & (POLLHUP|POLLERR)))) -- { -- if (needs_close) close( fd ); -- status = STATUS_PIPE_BROKEN; -- break; -- } -- } -- buffer->NamedPipeState = 0; /* FIXME */ -- buffer->ReadDataAvailable = avail; -- buffer->NumberOfMessages = 0; /* FIXME */ -- buffer->MessageLength = 0; /* FIXME */ -- io->Information = FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data ); -- status = STATUS_SUCCESS; -- if (avail) -+ status = unix_fd_avail( fd, &avail ); -+ if (!status) - { -- ULONG data_size = out_size - FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data ); -- if (data_size) -+ buffer->NamedPipeState = 0; /* FIXME */ -+ buffer->ReadDataAvailable = avail; -+ buffer->NumberOfMessages = 0; /* FIXME */ -+ buffer->MessageLength = 0; /* FIXME */ -+ io->Information = FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data ); -+ if (avail) - { -- int res = recv( fd, buffer->Data, data_size, MSG_PEEK ); -- if (res >= 0) io->Information += res; -+ ULONG data_size = out_size - FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data ); -+ if (data_size) -+ { -+ int res = recv( fd, buffer->Data, data_size, MSG_PEEK ); -+ if (res >= 0) io->Information += res; -+ } - } - } - if (needs_close) close( fd ); --- -2.11.0 - diff --git a/patches/kernel32-Named_Pipe/0007-ntdll-Unify-similar-code-in-NtWriteFile-and-FILE_Asy.patch b/patches/kernel32-Named_Pipe/0007-ntdll-Unify-similar-code-in-NtWriteFile-and-FILE_Asy.patch deleted file mode 100644 index 3db34361..00000000 --- a/patches/kernel32-Named_Pipe/0007-ntdll-Unify-similar-code-in-NtWriteFile-and-FILE_Asy.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 27b2dcf526597a12cfebcbc6bb53d45185b6f65f Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Mon, 18 Aug 2014 01:48:17 +0200 -Subject: ntdll: Unify similar code in NtWriteFile and FILE_AsyncWriteService. - -Changes in FILE_AsyncWriteService: - * Immediately retry on EINTR, chances are very good that it will - succeed in a second attempt, and its not worth to use different code - because of this small difference. - * Why is it STATUS_SUCCESS when we have a partial sync write, but - an error for async? Lets assume its always success... ---- - dlls/ntdll/file.c | 78 +++++++++++++++++++++++++------------------------------ - 1 file changed, 35 insertions(+), 43 deletions(-) - -diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index 54f31d6..f6679b1 100644 ---- a/dlls/ntdll/file.c -+++ b/dlls/ntdll/file.c -@@ -953,6 +953,37 @@ NTSTATUS WINAPI NtReadFileScatter( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap - return status; - } - -+/* helper function for NtWriteFile and FILE_AsyncWriteService */ -+static NTSTATUS write_unix_fd(int fd, const char *buf, ULONG *total, ULONG length, enum server_fd_type type) -+{ -+ int result; -+ for(;;) -+ { -+ if (!length && (type == FD_TYPE_MAILSLOT || type == FD_TYPE_PIPE || type == FD_TYPE_SOCKET)) -+ result = send( fd, buf, 0, 0 ); -+ else -+ result = write( fd, buf + *total, length - *total ); -+ if (result >= 0) -+ { -+ *total += result; -+ if (*total >= length) -+ return STATUS_SUCCESS; -+ else if (type != FD_TYPE_FILE) /* no async I/O on regular files */ -+ return STATUS_PENDING; -+ } -+ else if (errno != EINTR) -+ { -+ if (errno == EAGAIN) -+ break; -+ else if (*total) -+ return STATUS_SUCCESS; -+ else if (errno == EFAULT) -+ return STATUS_INVALID_USER_BUFFER; -+ return FILE_GetNtStatus(); -+ } -+ } -+ return STATUS_PENDING; -+} - - /*********************************************************************** - * FILE_AsyncWriteService (INTERNAL) -@@ -961,7 +992,7 @@ static NTSTATUS FILE_AsyncWriteService( void *user, IO_STATUS_BLOCK *iosb, - NTSTATUS status, void **apc, void **arg ) - { - struct async_fileio_write *fileio = user; -- int result, fd, needs_close; -+ int fd, needs_close; - enum server_fd_type type; - - switch (status) -@@ -971,24 +1002,8 @@ static NTSTATUS FILE_AsyncWriteService( void *user, IO_STATUS_BLOCK *iosb, - if ((status = server_get_unix_fd( fileio->io.handle, FILE_WRITE_DATA, &fd, - &needs_close, &type, NULL ))) - break; -- -- if (!fileio->count && (type == FD_TYPE_MAILSLOT || type == FD_TYPE_PIPE || type == FD_TYPE_SOCKET)) -- result = send( fd, fileio->buffer, 0, 0 ); -- else -- result = write( fd, &fileio->buffer[fileio->already], fileio->count - fileio->already ); -- -+ status = write_unix_fd( fd, fileio->buffer, &fileio->already, fileio->count, type ); - if (needs_close) close( fd ); -- -- if (result < 0) -- { -- if (errno == EAGAIN || errno == EINTR) status = STATUS_PENDING; -- else status = FILE_GetNtStatus(); -- } -- else -- { -- fileio->already += result; -- status = (fileio->already < fileio->count) ? STATUS_PENDING : STATUS_SUCCESS; -- } - break; - - case STATUS_TIMEOUT: -@@ -1150,32 +1165,9 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent, - - for (;;) - { -- /* zero-length writes on sockets may not work with plain write(2) */ -- if (!length && (type == FD_TYPE_MAILSLOT || type == FD_TYPE_PIPE || type == FD_TYPE_SOCKET)) -- result = send( unix_handle, buffer, 0, 0 ); -- else -- result = write( unix_handle, (const char *)buffer + total, length - total ); -- -- if (result >= 0) -- { -- total += result; -- if (total == length) -- { -- status = STATUS_SUCCESS; -- goto done; -- } -- if (type == FD_TYPE_FILE) continue; /* no async I/O on regular files */ -- } -- else if (errno != EAGAIN) -- { -- if (errno == EINTR) continue; -- if (!total) -- { -- if (errno == EFAULT) status = STATUS_INVALID_USER_BUFFER; -- else status = FILE_GetNtStatus(); -- } -+ status = write_unix_fd( unix_handle, buffer, &total, length, type ); -+ if (status != STATUS_PENDING) - goto done; -- } - - if (async_write) - { --- -2.3.0 - diff --git a/patches/kernel32-Named_Pipe/0008-server-Use-SOCK_SEQPACKET-socket-in-combination-with.patch b/patches/kernel32-Named_Pipe/0008-server-Use-SOCK_SEQPACKET-socket-in-combination-with.patch deleted file mode 100644 index 4a4f4bcd..00000000 --- a/patches/kernel32-Named_Pipe/0008-server-Use-SOCK_SEQPACKET-socket-in-combination-with.patch +++ /dev/null @@ -1,582 +0,0 @@ -From 104443cbb9a1087ec753af2462ccf41ba26eb444 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Mon, 4 Aug 2014 05:01:11 +0200 -Subject: server: Use SOCK_SEQPACKET socket in combination with SO_PEEK_OFF to - implement message mode on Unix. (rev 6) - -Based on ideas by Erich E. Hoover. - -Similar to Windows, when a pipe has been created with message mode flags, then all -sending operations always behave in "message mode". Currently the read mode isn't -handled yet, and the default is byte mode, to stay backwards compatible. - -Changes in v2: - * Show FIXME when message is too big and was splitted - * Simplify logic for FSCTL_PIPE_PEEK - -Changes in v3: - * Avoid changes in later patches, directly store pipe mode in signal attributes. - -Changes in v4: - * Moved changes into read_unix_fd function to make them available for async reads. - -Changes in v5: - * Rebased, merged with following patch. - -Changes in v6: - * When running on an older kernel make sure that ntdll doesn't try to use message mode features. ---- - dlls/kernel32/sync.c | 2 +- - dlls/kernel32/tests/pipe.c | 17 ++------ - dlls/ntdll/file.c | 106 ++++++++++++++++++++++++++++++++++++++------- - server/named_pipe.c | 103 ++++++++++++++++++++++++++++++++++++------- - server/sock.c | 4 +- - server/sock.h | 26 +++++++++++ - 6 files changed, 212 insertions(+), 46 deletions(-) - create mode 100644 server/sock.h - -diff --git a/dlls/kernel32/sync.c b/dlls/kernel32/sync.c -index 494db9c1a3..38aaccfa55 100644 ---- a/dlls/kernel32/sync.c -+++ b/dlls/kernel32/sync.c -@@ -1475,7 +1475,7 @@ BOOL WINAPI PeekNamedPipe( HANDLE hPipe, LPVOID lpvBuffer, DWORD cbBuffer, - ULONG read_size = io.Information - FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data ); - if (lpcbAvail) *lpcbAvail = buffer->ReadDataAvailable; - if (lpcbRead) *lpcbRead = read_size; -- if (lpcbMessage) *lpcbMessage = 0; /* FIXME */ -+ if (lpcbMessage) *lpcbMessage = buffer->MessageLength; - if (lpvBuffer) memcpy( lpvBuffer, buffer->Data, read_size ); - } - else SetLastError( RtlNtStatusToDosError(status) ); -diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c -index e7cfce4c00..71d75be90e 100644 ---- a/dlls/kernel32/tests/pipe.c -+++ b/dlls/kernel32/tests/pipe.c -@@ -294,7 +294,6 @@ static void test_CreateNamedPipe(int pipemode) - if (pipemode == PIPE_TYPE_BYTE) - ok(leftmsg == 0, "peek got %d bytes left in message\n", leftmsg); - else -- todo_wine - ok(leftmsg == sizeof(obuf2) - 4, "peek got %d bytes left in message\n", leftmsg); - ok(ReadFile(hFile, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile\n"); - ok(readden == sizeof(obuf2) - 4, "read got %d bytes\n", readden); -@@ -365,7 +364,7 @@ static void test_CreateNamedPipe(int pipemode) - } - else - { -- todo_wine ok(readden == sizeof(obuf), "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; -@@ -393,7 +392,7 @@ static void test_CreateNamedPipe(int pipemode) - } - else - { -- todo_wine ok(readden == sizeof(obuf), "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; -@@ -434,7 +433,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"); -- todo_wine ok(readden == sizeof(obuf), "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; - ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 5a check\n"); -@@ -466,7 +465,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"); -- todo_wine ok(readden == sizeof(obuf), "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; - ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 6a check\n"); -@@ -518,12 +517,10 @@ static void test_CreateNamedPipe(int pipemode) - readden = leftmsg = -1; - ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "PeekNamedPipe 9\n"); - ok(readden == sizeof(obuf) + sizeof(obuf2), "peek got %d bytes total 9\n", readden); -- todo_wine - ok(leftmsg == sizeof(obuf), "peek got %d bytes left in message 9\n", leftmsg); - readden = leftmsg = -1; - ok(RpcPeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "RpcPeekNamedPipe 9\n"); - ok(readden == sizeof(obuf) + sizeof(obuf2), "peek got %d bytes total 9\n", readden); -- todo_wine - ok(leftmsg == sizeof(obuf), "peek got %d bytes left in message 9\n", leftmsg); - SetLastError(0xdeadbeef); - todo_wine -@@ -541,12 +538,10 @@ static void test_CreateNamedPipe(int pipemode) - readden = leftmsg = -1; - ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "PeekNamedPipe 9\n"); - ok(readden == sizeof(obuf) - 8 + sizeof(obuf2), "peek got %d bytes total 9\n", readden); -- todo_wine - ok(leftmsg == sizeof(obuf) - 8, "peek got %d bytes left in message 9\n", leftmsg); - readden = leftmsg = -1; - ok(RpcPeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "RpcPeekNamedPipe 9\n"); - ok(readden == sizeof(obuf) - 8 + sizeof(obuf2), "peek got %d bytes total 9\n", readden); -- todo_wine - ok(leftmsg == sizeof(obuf) - 8, "peek got %d bytes left in message 9\n", leftmsg); - ret = RpcReadFile(hFile, ibuf + 8, sizeof(ibuf), &readden, NULL); - ok(ret, "RpcReadFile 9\n"); -@@ -607,12 +602,10 @@ static void test_CreateNamedPipe(int pipemode) - readden = leftmsg = -1; - ok(PeekNamedPipe(hnp, NULL, 0, NULL, &readden, &leftmsg), "PeekNamedPipe 10\n"); - ok(readden == sizeof(obuf) + sizeof(obuf2), "peek got %d bytes total 10\n", readden); -- todo_wine - ok(leftmsg == sizeof(obuf2), "peek got %d bytes left in message 10\n", leftmsg); - readden = leftmsg = -1; - ok(RpcPeekNamedPipe(hnp, NULL, 0, NULL, &readden, &leftmsg), "RpcPeekNamedPipe 10\n"); - ok(readden == sizeof(obuf) + sizeof(obuf2), "peek got %d bytes total 10\n", readden); -- todo_wine - ok(leftmsg == sizeof(obuf2), "peek got %d bytes left in message 10\n", leftmsg); - SetLastError(0xdeadbeef); - todo_wine -@@ -630,12 +623,10 @@ static void test_CreateNamedPipe(int pipemode) - readden = leftmsg = -1; - ok(PeekNamedPipe(hnp, NULL, 0, NULL, &readden, &leftmsg), "PeekNamedPipe 10\n"); - ok(readden == sizeof(obuf2) - 8 + sizeof(obuf), "peek got %d bytes total 10\n", readden); -- todo_wine - ok(leftmsg == sizeof(obuf2) - 8, "peek got %d bytes left in message 10\n", leftmsg); - readden = leftmsg = -1; - ok(RpcPeekNamedPipe(hnp, NULL, 0, NULL, &readden, &leftmsg), "RpcPeekNamedPipe 10\n"); - ok(readden == sizeof(obuf2) - 8 + sizeof(obuf), "peek got %d bytes total 10\n", readden); -- todo_wine - ok(leftmsg == sizeof(obuf2) - 8, "peek got %d bytes left in message 10\n", leftmsg); - ret = RpcReadFile(hnp, ibuf + 8, sizeof(ibuf), &readden, NULL); - ok(ret, "RpcReadFile 10\n"); -diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index 41d44c9af4..1b0eff02f2 100644 ---- a/dlls/ntdll/file.c -+++ b/dlls/ntdll/file.c -@@ -96,6 +96,10 @@ - # include - #endif - -+#ifndef SO_PEEK_OFF -+#define SO_PEEK_OFF 42 -+#endif -+ - #include "ntstatus.h" - #define WIN32_NO_STATUS - #define NONAMELESSUNION -@@ -515,18 +519,57 @@ static NTSTATUS unix_fd_avail(int fd, int *avail) - STATUS_PIPE_BROKEN : STATUS_SUCCESS; - } - -+/* returns the pipe flags for a file descriptor */ -+static inline int get_pipe_flags(int fd) -+{ -+#ifdef __linux__ -+ return fcntl( fd, F_GETSIG ); -+#else -+ return 0; -+#endif -+} -+ - /* helper function for NtReadFile and FILE_AsyncReadService */ - static NTSTATUS read_unix_fd(int fd, char *buf, ULONG *total, ULONG length, - enum server_fd_type type, BOOL avail_mode) - { -- int result; -+ struct msghdr msg; -+ struct iovec iov; -+ int pipe_flags = 0, result; -+ -+ if (type == FD_TYPE_PIPE) -+ pipe_flags = get_pipe_flags( fd ); -+ - for(;;) - { -- result = read( fd, buf + *total, length - *total ); -+ if (pipe_flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) -+ { -+ msg.msg_name = NULL; -+ msg.msg_namelen = 0; -+ msg.msg_iov = &iov; -+ msg.msg_iovlen = 1; -+ msg.msg_control = NULL; -+ msg.msg_controllen = 0; -+ msg.msg_flags = 0; -+ -+ iov.iov_base = buf + *total; -+ iov.iov_len = length - *total; -+ -+ result = recvmsg( fd, &msg, MSG_PEEK | (*total ? MSG_DONTWAIT : 0) ); -+ if (result >= 0 && !(msg.msg_flags & MSG_TRUNC)) -+ { -+ int ret; -+ while (!(ret = recv( fd, NULL, 0, MSG_TRUNC)) && result > 0); -+ if (ret < 0) ERR("dequeue message failed reason: %s\n", strerror(errno)); -+ } -+ } -+ else -+ result = read( fd, buf + *total, length - *total ); -+ - if (result >= 0) - { - *total += result; -- if (!result || *total >= length || avail_mode) -+ if (!result || *total >= length || (avail_mode && !(pipe_flags & NAMED_PIPE_MESSAGE_STREAM_WRITE))) - { - if (*total) - return STATUS_SUCCESS; -@@ -542,16 +585,17 @@ static NTSTATUS read_unix_fd(int fd, char *buf, ULONG *total, ULONG length, - return STATUS_PIPE_BROKEN; - } - } -+ else if (pipe_flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) -+ continue; - else if (type != FD_TYPE_FILE) /* no async I/O on regular files */ - return STATUS_PENDING; - } -+ else if (errno == EAGAIN) -+ return (avail_mode && *total) ? STATUS_SUCCESS : STATUS_PENDING; - else if (errno != EINTR) -- { -- if (errno == EAGAIN) break; - return FILE_GetNtStatus(); -- } - } -- return STATUS_PENDING; -+ return STATUS_UNSUCCESSFUL; /* never reached */ - } - - /*********************************************************************** -@@ -1127,13 +1171,14 @@ NTSTATUS WINAPI NtReadFileScatter( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap - /* helper function for NtWriteFile and FILE_AsyncWriteService */ - static NTSTATUS write_unix_fd(int fd, const char *buf, ULONG *total, ULONG length, enum server_fd_type type) - { -+ ULONG msgsize = (ULONG)-1; - int result; - for(;;) - { - if (!length && (type == FD_TYPE_MAILSLOT || type == FD_TYPE_PIPE || type == FD_TYPE_SOCKET)) - result = send( fd, buf, 0, 0 ); - else -- result = write( fd, buf + *total, length - *total ); -+ result = write( fd, buf + *total, min(length - *total, msgsize) ); - if (result >= 0) - { - *total += result; -@@ -1142,6 +1187,17 @@ static NTSTATUS write_unix_fd(int fd, const char *buf, ULONG *total, ULONG lengt - else if (type != FD_TYPE_FILE) /* no async I/O on regular files */ - return STATUS_PENDING; - } -+ else if (errno == EMSGSIZE && type == FD_TYPE_PIPE && msgsize > 4096) -+ { -+ static ULONG warn_msgsize; -+ if (msgsize == (ULONG)-1) msgsize = (length + 32 + 4095) & ~4095; -+ if (msgsize > warn_msgsize) -+ { -+ FIXME("Message is too big, try to increase /proc/sys/net/core/wmem_default to at least %d\n", msgsize); -+ warn_msgsize = msgsize; -+ } -+ msgsize -= 4096; /* FIXME: use more intelligent algorithm to discover msgsize */ -+ } - else if (errno != EINTR) - { - if (errno == EAGAIN) -@@ -1734,20 +1790,40 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc - status = unix_fd_avail( fd, &avail ); - if (!status) - { -+ ULONG data_size = out_size - FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data ); -+ int pipe_flags = get_pipe_flags( fd ); -+ - buffer->NamedPipeState = 0; /* FIXME */ - buffer->ReadDataAvailable = avail; -- buffer->NumberOfMessages = 0; /* FIXME */ -- buffer->MessageLength = 0; /* FIXME */ -+ buffer->NumberOfMessages = 0; -+ buffer->MessageLength = 0; - io->Information = FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data ); -- if (avail) -+ -+ if (pipe_flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) - { -- ULONG data_size = out_size - FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data ); -- if (data_size) -+ int peek_offset; -+ socklen_t sock_opt_len = sizeof(peek_offset); -+ if (getsockopt( fd, SOL_SOCKET, SO_PEEK_OFF, &peek_offset, &sock_opt_len )) -+ ERR("getsockopt(SO_PEEK_OFF) failed reason: %s\n", strerror(errno)); -+ else - { -- int res = recv( fd, buffer->Data, data_size, MSG_PEEK ); -- if (res >= 0) io->Information += res; -+ char *data = data_size ? buffer->Data : NULL; -+ int res = recv( fd, data, data_size, MSG_PEEK | MSG_TRUNC | MSG_DONTWAIT ); -+ if (res >= 0) io->Information += min(res, data_size); -+ -+ if (setsockopt( fd, SOL_SOCKET, SO_PEEK_OFF, &peek_offset, sizeof(peek_offset) )) -+ ERR("setsockopt(SO_PEEK_OFF) failed reason: %s\n", strerror(errno)); -+ -+ buffer->ReadDataAvailable = avail - peek_offset; -+ buffer->NumberOfMessages = avail > peek_offset; /* FIXME */ -+ buffer->MessageLength = max(0, res); - } - } -+ else if (avail && data_size) -+ { -+ int res = recv( fd, buffer->Data, data_size, MSG_PEEK | MSG_DONTWAIT ); -+ if (res >= 0) io->Information += res; -+ } - } - if (needs_close) close( fd ); - } -diff --git a/server/named_pipe.c b/server/named_pipe.c -index b215816650..74a9a44dcf 100644 ---- a/server/named_pipe.c -+++ b/server/named_pipe.c -@@ -42,6 +42,10 @@ - #include - #endif - -+#ifndef SO_PEEK_OFF -+#define SO_PEEK_OFF 42 -+#endif -+ - #include "ntstatus.h" - #define WIN32_NO_STATUS - #include "windef.h" -@@ -49,6 +53,7 @@ - #include "winioctl.h" - - #include "file.h" -+#include "sock.h" - #include "handle.h" - #include "thread.h" - #include "request.h" -@@ -804,14 +809,43 @@ static int named_pipe_link_name( struct object *obj, struct object_name *name, s - return 1; - } - -+/* check if message mode named pipes are supported */ -+static int is_messagemode_supported(void) -+{ -+#ifdef __linux__ -+ static const int zero = 0; -+ static int messagemode = -1; -+ int fd; -+ -+ if (messagemode < 0) -+ { -+ fd = socket( PF_UNIX, SOCK_SEQPACKET, 0 ); -+ messagemode = (fd != -1) && (setsockopt( fd, SOL_SOCKET, SO_PEEK_OFF, &zero, sizeof(zero) ) != -1); -+ if (fd != -1) close( fd ); -+ } -+ -+ return messagemode; -+#else -+ return 0; -+#endif -+} -+ -+static inline int messagemode_flags( int flags ) -+{ -+ if (!is_messagemode_supported()) -+ flags &= ~(NAMED_PIPE_MESSAGE_STREAM_WRITE | NAMED_PIPE_MESSAGE_STREAM_READ); -+ return flags; -+} -+ - static struct object *named_pipe_open_file( struct object *obj, unsigned int access, - unsigned int sharing, unsigned int options ) - { -+ static const int zero = 0; - struct named_pipe *pipe = (struct named_pipe *)obj; - struct pipe_server *server; - struct pipe_client *client; - unsigned int pipe_sharing; -- int fds[2]; -+ int fds[2], type; - - if (!(server = find_available_server( pipe ))) - { -@@ -830,6 +864,9 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc - - if ((client = create_pipe_client( options, pipe->flags, pipe->outsize ))) - { -+ type = ((pipe->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) && is_messagemode_supported()) ? -+ SOCK_SEQPACKET : SOCK_STREAM; -+ - if (use_server_io( &server->pipe_end )) - { - client->pipe_end.fd = alloc_pseudo_fd( &pipe_client_fd_ops, &client->pipe_end.obj, options ); -@@ -845,7 +882,7 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc - client = NULL; - } - } -- else if (!socketpair( PF_UNIX, SOCK_STREAM, 0, fds )) -+ else if (!socketpair( PF_UNIX, type, 0, fds )) - { - assert( !server->pipe_end.fd ); - -@@ -855,25 +892,48 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc - if (is_overlapped( options )) fcntl( fds[1], F_SETFL, O_NONBLOCK ); - if (is_overlapped( server->options )) fcntl( fds[0], F_SETFL, O_NONBLOCK ); - -- if (pipe->insize) -+ /* FIXME: For message mode we don't pay attention to the provided buffer size. -+ * Linux pipes cannot dynamically adjust size, so we leave the size to the system -+ * instead of using the application provided value. Please note that this will -+ * have the effect that the application doesn't block when sending very large -+ * messages. */ -+ if (type != SOCK_SEQPACKET) - { -- setsockopt( fds[0], SOL_SOCKET, SO_RCVBUF, &pipe->insize, sizeof(pipe->insize) ); -- setsockopt( fds[1], SOL_SOCKET, SO_RCVBUF, &pipe->insize, sizeof(pipe->insize) ); -- } -- if (pipe->outsize) -- { -- setsockopt( fds[0], SOL_SOCKET, SO_SNDBUF, &pipe->outsize, sizeof(pipe->outsize) ); -- setsockopt( fds[1], SOL_SOCKET, SO_SNDBUF, &pipe->outsize, sizeof(pipe->outsize) ); -+ if (pipe->insize) -+ { -+ setsockopt( fds[0], SOL_SOCKET, SO_RCVBUF, &pipe->insize, sizeof(pipe->insize) ); -+ setsockopt( fds[1], SOL_SOCKET, SO_RCVBUF, &pipe->insize, sizeof(pipe->insize) ); -+ } -+ if (pipe->outsize) -+ { -+ setsockopt( fds[0], SOL_SOCKET, SO_SNDBUF, &pipe->outsize, sizeof(pipe->outsize) ); -+ setsockopt( fds[1], SOL_SOCKET, SO_SNDBUF, &pipe->outsize, sizeof(pipe->outsize) ); -+ } - } - -- client->pipe_end.fd = create_anonymous_fd( &pipe_client_fd_ops, fds[1], &client->pipe_end.obj, options ); -- server->pipe_end.fd = create_anonymous_fd( &pipe_server_fd_ops, fds[0], &server->pipe_end.obj, server->options ); -- if (client->pipe_end.fd && server->pipe_end.fd) -+ if (type != SOCK_SEQPACKET || (setsockopt( fds[0], SOL_SOCKET, SO_PEEK_OFF, &zero, sizeof(zero) ) != -1 && -+ setsockopt( fds[1], SOL_SOCKET, SO_PEEK_OFF, &zero, sizeof(zero) ) != -1)) - { -- fd_copy_completion( server->ioctl_fd, server->pipe_end.fd ); -+ #ifdef __linux__ -+ fcntl( fds[0], F_SETSIG, messagemode_flags( server->pipe_end.flags ) ); -+ fcntl( fds[1], F_SETSIG, messagemode_flags( client->pipe_end.flags ) ); -+ #endif -+ -+ client->pipe_end.fd = create_anonymous_fd( &pipe_client_fd_ops, fds[1], &client->pipe_end.obj, options ); -+ server->pipe_end.fd = create_anonymous_fd( &pipe_server_fd_ops, fds[0], &server->pipe_end.obj, server->options ); -+ if (client->pipe_end.fd && server->pipe_end.fd) -+ { -+ fd_copy_completion( server->ioctl_fd, server->pipe_end.fd ); -+ } -+ else -+ { -+ release_object( client ); -+ client = NULL; -+ } - } - else - { -+ sock_set_error(); - release_object( client ); - client = NULL; - } -@@ -970,7 +1030,7 @@ DECL_HANDLER(create_named_pipe) - return; - } - -- reply->flags = req->flags & ~(NAMED_PIPE_MESSAGE_STREAM_WRITE | NAMED_PIPE_MESSAGE_STREAM_READ); -+ reply->flags = messagemode_flags(req->flags); - - if (!name.len) /* pipes need a root directory even without a name */ - { -@@ -1073,6 +1133,9 @@ DECL_HANDLER(set_named_pipe_info) - { - struct pipe_server *server; - struct pipe_client *client = NULL; -+#ifdef __linux__ -+ int unix_fd; -+#endif - - server = get_pipe_server_obj( current->process, req->handle, FILE_WRITE_ATTRIBUTES ); - if (!server) -@@ -1099,10 +1162,20 @@ DECL_HANDLER(set_named_pipe_info) - else if (client) - { - client->pipe_end.flags = server->pipe->flags | req->flags; -+ #ifdef __linux__ -+ if (client->pipe_end.fd && (unix_fd = get_unix_fd( client->pipe_end.fd )) != -1) -+ fcntl( unix_fd, F_SETSIG, messagemode_flags( client->pipe_end.flags ) ); -+ clear_error(); -+ #endif - } - else - { - server->pipe_end.flags = server->pipe->flags | req->flags; -+ #ifdef __linux__ -+ if (server->pipe_end.fd && (unix_fd = get_unix_fd( server->pipe_end.fd )) != -1) -+ fcntl( unix_fd, F_SETSIG, messagemode_flags( server->pipe_end.flags ) ); -+ clear_error(); -+ #endif - } - - if (client) -diff --git a/server/sock.c b/server/sock.c -index d6b4fb2fa5..49b6d3d575 100644 ---- a/server/sock.c -+++ b/server/sock.c -@@ -61,6 +61,7 @@ - - #include "process.h" - #include "file.h" -+#include "sock.h" - #include "handle.h" - #include "thread.h" - #include "request.h" -@@ -135,7 +136,6 @@ static void sock_reselect_async( struct fd *fd, struct async_queue *queue ); - - static int sock_get_ntstatus( int err ); - static int sock_get_error( int err ); --static void sock_set_error(void); - - static const struct object_ops sock_ops = - { -@@ -941,7 +941,7 @@ static int sock_get_ntstatus( int err ) - } - - /* set the last error depending on errno */ --static void sock_set_error(void) -+void sock_set_error(void) - { - set_error( sock_get_ntstatus( errno ) ); - } -diff --git a/server/sock.h b/server/sock.h -new file mode 100644 -index 0000000000..21551b42b1 ---- /dev/null -+++ b/server/sock.h -@@ -0,0 +1,26 @@ -+/* -+ * Server-side socket definitions -+ * -+ * Copyright (C) 2014 Sebastian Lackner -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * 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 -+ */ -+ -+#ifndef __WINE_SERVER_SOCK_H -+#define __WINE_SERVER_SOCK_H -+ -+extern void sock_set_error(void); -+ -+#endif /* __WINE_SERVER_SOCK_H */ --- -2.11.0 - diff --git a/patches/kernel32-Named_Pipe/0009-ntdll-Add-handling-for-partially-received-messages-i.patch b/patches/kernel32-Named_Pipe/0009-ntdll-Add-handling-for-partially-received-messages-i.patch deleted file mode 100644 index 5481dd50..00000000 --- a/patches/kernel32-Named_Pipe/0009-ntdll-Add-handling-for-partially-received-messages-i.patch +++ /dev/null @@ -1,325 +0,0 @@ -From ddcad4846ab1fe881bed762210f369c621bbb2de Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Mon, 11 Aug 2014 05:01:11 +0200 -Subject: ntdll: Add handling for partially received messages in NtReadFile. - -Changes in v2: - * Merged with final version of error code handling. - * Poll for broken pipe to distinguish between zero-byte messages and errors. - -Changes in v3: - * Rebased. Simplified check for broken pipe. - -Changes in v4: - * Include changes from later patch. ---- - dlls/kernel32/tests/pipe.c | 57 +++++++--------------------------------------- - dlls/ntdll/file.c | 28 ++++++++++++++++++----- - 2 files changed, 30 insertions(+), 55 deletions(-) - -diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c -index 71d75be90e8..ae37afd2ee7 100644 ---- a/dlls/kernel32/tests/pipe.c -+++ b/dlls/kernel32/tests/pipe.c -@@ -313,9 +313,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); -@@ -336,15 +334,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); -@@ -406,9 +400,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"); -@@ -438,9 +430,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)) -@@ -449,10 +439,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); -@@ -470,9 +458,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)) -@@ -483,9 +469,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"); -@@ -496,9 +480,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"); -@@ -523,16 +505,12 @@ static void test_CreateNamedPipe(int pipemode) - ok(readden == sizeof(obuf) + sizeof(obuf2), "peek got %d bytes total 9\n", readden); - ok(leftmsg == sizeof(obuf), "peek got %d bytes left in message 9\n", leftmsg); - 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); - readden = leftmsg = -1; -@@ -545,7 +523,6 @@ static void test_CreateNamedPipe(int pipemode) - ok(leftmsg == sizeof(obuf) - 8, "peek got %d bytes left in message 9\n", leftmsg); - 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 */ -@@ -562,13 +539,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); -- todo_wine - 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); - readden = leftmsg = -1; -@@ -608,16 +582,12 @@ static void test_CreateNamedPipe(int pipemode) - ok(readden == sizeof(obuf) + sizeof(obuf2), "peek got %d bytes total 10\n", readden); - ok(leftmsg == sizeof(obuf2), "peek got %d bytes left in message 10\n", leftmsg); - 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); - readden = leftmsg = -1; -@@ -630,7 +600,6 @@ static void test_CreateNamedPipe(int pipemode) - ok(leftmsg == sizeof(obuf2) - 8, "peek got %d bytes left in message 10\n", leftmsg); - 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 */ -@@ -647,13 +616,10 @@ static void test_CreateNamedPipe(int pipemode) - SetLastError(0xdeadbeef); - ret = RpcReadFile(hnp, ibuf, 4, &readden, NULL); - 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); - readden = leftmsg = -1; -@@ -759,15 +725,11 @@ static void test_CreateNamedPipe(int pipemode) - else - { - SetLastError(0xdeadbeef); -- todo_wine - ok(!ReadFile(hFile, big_ibuf, 32, &readden, NULL), "ReadFile\n"); -- todo_wine - ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n"); - ok(readden == 32, "read got %d bytes\n", readden); - SetLastError(0xdeadbeef); -- todo_wine - ok(!ReadFile(hFile, big_ibuf + 32, 32, &readden, NULL), "ReadFile\n"); -- todo_wine - ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n"); - } - ok(readden == 32, "read got %d bytes\n", readden); -@@ -1665,7 +1627,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; -@@ -1763,8 +1725,8 @@ 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 */, -- "ReadFile failed with %u\n", GetLastError()); -+ ok(ret || GetLastError() == ERROR_MORE_DATA /* >= Win 8 */, -+ "ReadFile failed with %u\n", GetLastError()); - ok(numbytes == 0, "expected 0, got %u\n", numbytes); - - numbytes = 0xdeadbeef; -@@ -2720,7 +2682,6 @@ static void test_readfileex_pending(void) - SetLastError(0xdeadbeef); - ret = ReadFile(server, read_buf, 0, &num_bytes, &overlapped); - ok(!ret, "ReadFile should fail\n"); --todo_wine - ok(GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %d\n", GetLastError()); - ok(num_bytes == 0, "bytes %u\n", num_bytes); - ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %#lx\n", overlapped.Internal); -@@ -2736,11 +2697,9 @@ todo_wine - ok(num_bytes == 1, "bytes %u\n", num_bytes); - - wait = WaitForSingleObject(event, 100); --todo_wine - ok(wait == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", wait); - - ok(num_bytes == 1, "bytes %u\n", num_bytes); --todo_wine - ok((NTSTATUS)overlapped.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", overlapped.Internal); - ok(overlapped.InternalHigh == 0, "expected 0, got %lu\n", overlapped.InternalHigh); - -diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index 4a736f42d6d..4347e419029 100644 ---- a/dlls/ntdll/file.c -+++ b/dlls/ntdll/file.c -@@ -492,7 +492,7 @@ NTSTATUS FILE_GetNtStatus(void) - } - } - --/* helper function for FSCTL_PIPE_PEEK */ -+/* helper function for FSCTL_PIPE_PEEK and read_unix_fd */ - static NTSTATUS unix_fd_avail(int fd, int *avail) - { - struct pollfd pollfd; -@@ -521,7 +521,14 @@ static NTSTATUS unix_fd_avail(int fd, int *avail) - static inline int get_pipe_flags(int fd) - { - #ifdef __linux__ -- return fcntl( fd, F_GETSIG ); -+ int flags = fcntl( fd, F_GETSIG ); -+ -+ /* NAMED_PIPE_MESSAGE_STREAM_READ only allowed in -+ * combination with NAMED_PIPE_MESSAGE_STREAM_WRITE. */ -+ if (!(flags & NAMED_PIPE_MESSAGE_STREAM_WRITE)) -+ flags &= ~NAMED_PIPE_MESSAGE_STREAM_READ; -+ -+ return flags; - #else - return 0; - #endif -@@ -567,10 +574,12 @@ static NTSTATUS read_unix_fd(int fd, char *buf, ULONG *total, ULONG length, - if (result >= 0) - { - *total += result; -- if (!result || *total >= length || (avail_mode && !(pipe_flags & NAMED_PIPE_MESSAGE_STREAM_WRITE))) -+ if (!result || *total >= length || (avail_mode && !(pipe_flags & NAMED_PIPE_MESSAGE_STREAM_WRITE)) || -+ ((pipe_flags & NAMED_PIPE_MESSAGE_STREAM_READ) && !(msg.msg_flags & MSG_TRUNC))) - { - if (*total) -- return STATUS_SUCCESS; -+ return ((pipe_flags & NAMED_PIPE_MESSAGE_STREAM_READ) && (msg.msg_flags & MSG_TRUNC)) ? -+ STATUS_BUFFER_OVERFLOW : STATUS_SUCCESS; - switch (type) - { - case FD_TYPE_FILE: -@@ -579,11 +588,18 @@ static NTSTATUS read_unix_fd(int fd, char *buf, ULONG *total, ULONG length, - return length ? STATUS_END_OF_FILE : STATUS_SUCCESS; - case FD_TYPE_SERIAL: - return length ? STATUS_PENDING : STATUS_SUCCESS; -+ case FD_TYPE_PIPE: -+ { -+ NTSTATUS status = unix_fd_avail( fd, &result ); -+ if (!status && !result && !length) status = STATUS_PENDING; -+ return status; -+ } - default: - return STATUS_PIPE_BROKEN; - } - } -- else if (pipe_flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) -+ else if ((pipe_flags & (NAMED_PIPE_MESSAGE_STREAM_WRITE | NAMED_PIPE_MESSAGE_STREAM_READ)) == -+ NAMED_PIPE_MESSAGE_STREAM_WRITE) - continue; - else if (type != FD_TYPE_FILE) /* no async I/O on regular files */ - return STATUS_PENDING; -@@ -1061,7 +1077,7 @@ done: - - err: - if (needs_close) close( unix_handle ); -- if (status == STATUS_SUCCESS || (status == STATUS_END_OF_FILE && !async_read)) -+ if (status == STATUS_SUCCESS || status == STATUS_BUFFER_OVERFLOW || (status == STATUS_END_OF_FILE && !async_read)) - { - io_status->u.Status = status; - io_status->Information = total; --- -2.11.0 - diff --git a/patches/kernel32-Named_Pipe/0010-kernel32-tests-Add-more-tests-with-overlapped-IO-and.patch b/patches/kernel32-Named_Pipe/0010-kernel32-tests-Add-more-tests-with-overlapped-IO-and.patch deleted file mode 100644 index ea95c994..00000000 --- a/patches/kernel32-Named_Pipe/0010-kernel32-tests-Add-more-tests-with-overlapped-IO-and.patch +++ /dev/null @@ -1,188 +0,0 @@ -From d94857ffb00c9e24dcaff68aed1e14a6b99745f5 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sun, 17 Aug 2014 00:47:26 +0200 -Subject: kernel32/tests: Add more tests with overlapped IO and partial reads - from named pipes. - ---- - dlls/kernel32/tests/pipe.c | 150 +++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 150 insertions(+) - -diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c -index 6a27826..ba49974 100644 ---- a/dlls/kernel32/tests/pipe.c -+++ b/dlls/kernel32/tests/pipe.c -@@ -2300,6 +2300,7 @@ static void test_readfileex_pending(void) - OVERLAPPED overlapped; - char read_buf[1024]; - char write_buf[1024]; -+ const char long_test_string[] = "12test3456ab"; - const char test_string[] = "test"; - int i; - -@@ -2339,6 +2340,9 @@ static void test_readfileex_pending(void) - ret = ReadFileEx(server, read_buf, sizeof(read_buf), &overlapped, completion_routine); - ok(ret == TRUE, "ReadFileEx failed, err=%i\n", GetLastError()); - ok(completion_called == 0, "completion routine called before ReadFileEx returned\n"); -+ wait = WaitForSingleObject(event, 100); -+ ok(wait == WAIT_TIMEOUT, "WaitForSingleObjectEx returned %x\n", wait); -+ ok(completion_called == 0, "completion routine called before WriteFile started\n"); - - ret = WriteFile(client, test_string, strlen(test_string), &num_bytes, NULL); - ok(ret == TRUE, "WriteFile failed\n"); -@@ -2449,6 +2453,152 @@ todo_wine - - CloseHandle(client); - CloseHandle(server); -+ -+ server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, -+ /* dwOpenMode */ PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, -+ /* nMaxInstances */ 1, -+ /* nOutBufSize */ 1024, -+ /* nInBufSize */ 1024, -+ /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, -+ /* lpSecurityAttrib */ NULL); -+ ok(server != INVALID_HANDLE_VALUE, "cf failed\n"); -+ -+ client = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, NULL, -+ OPEN_EXISTING, 0, NULL); -+ ok(client != INVALID_HANDLE_VALUE, "cf failed\n"); -+ -+ memset(&overlapped, 0, sizeof(overlapped)); -+ overlapped.hEvent = event; -+ -+ /* Start a call to ReadFileEx which cannot complete immediately */ -+ memset(read_buf, 0, sizeof(read_buf)); -+ completion_called = 0; -+ ResetEvent(event); -+ ret = ReadFileEx(server, read_buf, 4, &overlapped, completion_routine); -+ ok(ret == TRUE, "ReadFileEx failed, err=%i\n", GetLastError()); -+ ok(completion_called == 0, "completion routine called before ReadFileEx returned\n"); -+ wait = WaitForSingleObject(event, 100); -+ ok(wait == WAIT_TIMEOUT, "WaitForSingleObject returned %x\n", wait); -+ ok(completion_called == 0, "completion routine called before WriteFile started\n"); -+ -+ ret = WriteFile(client, long_test_string, strlen(long_test_string), &num_bytes, NULL); -+ ok(ret == TRUE, "WriteFile failed\n"); -+ ok(num_bytes == strlen(long_test_string), "only %i bytes written\n", num_bytes); -+ ok(completion_called == 0, "completion routine called during WriteFile\n"); -+ wait = WaitForSingleObjectEx(event, 0, TRUE); -+ ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObjectEx returned %x\n", wait); -+ -+ ok(completion_called == 1, "completion not called after writing pipe\n"); -+ todo_wine -+ ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode); -+ ok(completion_num_bytes == 4, "ReadFileEx returned only %d bytes\n", completion_num_bytes); -+ ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n"); -+ ok(!memcmp(long_test_string, read_buf, 4), "ReadFileEx read wrong bytes\n"); -+ -+ ret = ReadFile(server, read_buf + 4, 4, &num_bytes, NULL); -+ ok(ret == FALSE, "ReadFile succeeded\n"); -+ ok(num_bytes == 4, "ReadFile returned only %d bytes\n", num_bytes); -+ ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n"); -+ ret = ReadFile(server, read_buf + 8, sizeof(read_buf) - 8, &num_bytes, NULL); -+ ok(ret == TRUE, "ReadFile failed\n"); -+ ok(num_bytes == strlen(long_test_string)-8, "ReadFile returned only %d bytes\n", num_bytes); -+ ok(!memcmp(long_test_string, read_buf, strlen(long_test_string)), "ReadFile read wrong bytes\n"); -+ -+ /* Call ReadFileEx when there is already some content in the pipe */ -+ ret = WriteFile(client, long_test_string, strlen(long_test_string), &num_bytes, NULL); -+ ok(ret == TRUE, "WriteFile failed\n"); -+ ok(num_bytes == strlen(long_test_string), "only %i bytes written\n", num_bytes); -+ -+ memset(read_buf, 0, sizeof(read_buf)); -+ completion_called = 0; -+ ResetEvent(event); -+ ret = ReadFileEx(server, read_buf, 4, &overlapped, completion_routine); -+ todo_wine -+ ok(ret == TRUE, "ReadFileEx failed, err=%i\n", GetLastError()); -+ ok(completion_called == 0, "completion routine called before ReadFileEx returned\n"); -+ wait = WaitForSingleObjectEx(event, 0, TRUE); -+ todo_wine -+ ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObjectEx returned %x\n", wait); -+ todo_wine -+ ok(completion_called == 1, "completion not called after writing pipe\n"); -+ todo_wine -+ ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode); -+ ok(completion_num_bytes == 4, "ReadFileEx returned only %d bytes\n", completion_num_bytes); -+ ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n"); -+ ok(!memcmp(long_test_string, read_buf, 4), "ReadFileEx read wrong bytes\n"); -+ -+ ret = ReadFile(server, read_buf + 4, sizeof(read_buf) - 4, &num_bytes, NULL); -+ ok(ret == TRUE, "ReadFile failed\n"); -+ ok(num_bytes == strlen(long_test_string)-4, "ReadFile returned only %d bytes\n", num_bytes); -+ ok(!memcmp(long_test_string, read_buf, strlen(long_test_string)), "ReadFile read wrong bytes\n"); -+ -+ /* Check content of overlapped structure */ -+ memset(read_buf, 0, sizeof(read_buf)); -+ S(U(overlapped)).Offset = 0; -+ S(U(overlapped)).OffsetHigh = 0; -+ overlapped.Internal = -1; -+ overlapped.InternalHigh = -1; -+ overlapped.hEvent = event; -+ num_bytes = 0xdeadbeef; -+ SetLastError(0xdeadbeef); -+ ret = ReadFile(server, read_buf, 4, &num_bytes, &overlapped); -+ ok(GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %d\n", GetLastError()); -+ ok(num_bytes == 0, "bytes %u\n", num_bytes); -+ ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %#lx\n", overlapped.Internal); -+ todo_wine -+ ok(overlapped.InternalHigh == -1, "expected -1, got %lu\n", overlapped.InternalHigh); -+ wait = WaitForSingleObject(event, 100); -+ ok(wait == WAIT_TIMEOUT, "WaitForSingleObject returned %x\n", wait); -+ ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %#lx\n", overlapped.Internal); -+ -+ num_bytes = 0xdeadbeef; -+ ret = WriteFile(client, long_test_string, strlen(long_test_string), &num_bytes, NULL); -+ ok(ret, "WriteFile failed\n"); -+ ok(num_bytes == strlen(long_test_string), "bytes %u\n", num_bytes); -+ wait = WaitForSingleObject(event, 100); -+ ok(wait == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", wait); -+ ok(num_bytes == strlen(long_test_string), "bytes %u\n", num_bytes); -+ ok((NTSTATUS)overlapped.Internal == STATUS_BUFFER_OVERFLOW, "expected STATUS_BUFFER_OVERFLOW, got %#lx\n", overlapped.Internal); -+ ok(overlapped.InternalHigh == 4, "expected 4, got %lu\n", overlapped.InternalHigh); -+ -+ ret = ReadFile(server, read_buf + 4, sizeof(read_buf) - 4, &num_bytes, NULL); -+ ok(ret == TRUE, "ReadFile failed\n"); -+ ok(num_bytes == strlen(long_test_string)-4, "ReadFile returned only %d bytes\n", num_bytes); -+ ok(!memcmp(long_test_string, read_buf, strlen(long_test_string)), "ReadFile read wrong bytes\n"); -+ -+ /* Call ReadFile when there is already some content in the pipe */ -+ num_bytes = 0xdeadbeef; -+ ret = WriteFile(client, long_test_string, strlen(long_test_string), &num_bytes, NULL); -+ ok(ret, "WriteFile failed\n"); -+ ok(num_bytes == strlen(long_test_string), "bytes %u\n", num_bytes); -+ -+ memset(read_buf, 0, sizeof(read_buf)); -+ S(U(overlapped)).Offset = 0; -+ S(U(overlapped)).OffsetHigh = 0; -+ overlapped.Internal = -1; -+ overlapped.InternalHigh = -1; -+ overlapped.hEvent = event; -+ num_bytes = 0xdeadbeef; -+ SetLastError(0xdeadbeef); -+ ret = ReadFile(server, read_buf, 4, &num_bytes, &overlapped); -+ ok(ret == FALSE, "ReadFile succeeded\n"); -+ ok(GetLastError() == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %d\n", GetLastError()); -+ todo_wine -+ ok(num_bytes == 0, "ReadFile returned %d bytes\n", num_bytes); -+ wait = WaitForSingleObjectEx(event, 0, TRUE); -+ ok(wait == WAIT_OBJECT_0, "WaitForSingleObjectEx returned %x\n", wait); -+ todo_wine -+ ok(num_bytes == 0, "bytes %u\n", num_bytes); -+ ok((NTSTATUS)overlapped.Internal == STATUS_BUFFER_OVERFLOW, "expected STATUS_BUFFER_OVERFLOW, got %#lx\n", overlapped.Internal); -+ ok(overlapped.InternalHigh == 4, "expected 4, got %lu\n", overlapped.InternalHigh); -+ -+ ret = ReadFile(server, read_buf + 4, sizeof(read_buf) - 4, &num_bytes, NULL); -+ ok(ret == TRUE, "ReadFile failed\n"); -+ ok(num_bytes == strlen(long_test_string)-4, "ReadFile returned only %d bytes\n", num_bytes); -+ ok(!memcmp(long_test_string, read_buf, strlen(long_test_string)), "ReadFile read wrong bytes\n"); -+ -+ CloseHandle(client); -+ CloseHandle(server); - CloseHandle(event); - } - --- -2.1.3 - diff --git a/patches/kernel32-Named_Pipe/0011-ntdll-Fix-some-tests-for-overlapped-partial-reads.patch b/patches/kernel32-Named_Pipe/0011-ntdll-Fix-some-tests-for-overlapped-partial-reads.patch deleted file mode 100644 index ea29cd0c..00000000 --- a/patches/kernel32-Named_Pipe/0011-ntdll-Fix-some-tests-for-overlapped-partial-reads.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 87e6095901f7405efc256997f1e1d6f0338ab2b5 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sun, 17 Aug 2014 01:13:44 +0200 -Subject: ntdll: Fix some tests for overlapped partial reads. - -Windows also sends as APC user notification for STATUS_BUFFER_OVERFLOW. -Moreover in some cases STATUS_BUFFER_OVERFLOW is reported as success, not -as failure. ---- - dlls/kernel32/file.c | 7 ++++--- - dlls/kernel32/tests/pipe.c | 5 ----- - dlls/ntdll/file.c | 4 ++-- - 3 files changed, 6 insertions(+), 10 deletions(-) - -diff --git a/dlls/kernel32/file.c b/dlls/kernel32/file.c -index 006db1c..78cfdb7 100644 ---- a/dlls/kernel32/file.c -+++ b/dlls/kernel32/file.c -@@ -325,8 +325,9 @@ BOOL WINAPI AreFileApisANSI(void) - static void WINAPI FILE_ReadWriteApc(void* apc_user, PIO_STATUS_BLOCK io_status, ULONG reserved) - { - LPOVERLAPPED_COMPLETION_ROUTINE cr = apc_user; -- -- cr(RtlNtStatusToDosError(io_status->u.Status), io_status->Information, (LPOVERLAPPED)io_status); -+ NTSTATUS status = io_status->u.Status; -+ if (status == STATUS_BUFFER_OVERFLOW) status = STATUS_SUCCESS; -+ cr(RtlNtStatusToDosError(status), io_status->Information, (LPOVERLAPPED)io_status); - } - - -@@ -358,7 +359,7 @@ BOOL WINAPI ReadFileEx(HANDLE hFile, LPVOID buffer, DWORD bytesToRead, - status = NtReadFile(hFile, NULL, FILE_ReadWriteApc, lpCompletionRoutine, - io_status, buffer, bytesToRead, &offset, NULL); - -- if (status && status != STATUS_PENDING) -+ if (status && status != STATUS_PENDING && status != STATUS_BUFFER_OVERFLOW) - { - SetLastError( RtlNtStatusToDosError(status) ); - return FALSE; -diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c -index ba49974..53f8f30 100644 ---- a/dlls/kernel32/tests/pipe.c -+++ b/dlls/kernel32/tests/pipe.c -@@ -2489,7 +2489,6 @@ todo_wine - ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObjectEx returned %x\n", wait); - - ok(completion_called == 1, "completion not called after writing pipe\n"); -- todo_wine - ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode); - ok(completion_num_bytes == 4, "ReadFileEx returned only %d bytes\n", completion_num_bytes); - ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n"); -@@ -2513,15 +2512,11 @@ todo_wine - completion_called = 0; - ResetEvent(event); - ret = ReadFileEx(server, read_buf, 4, &overlapped, completion_routine); -- todo_wine - ok(ret == TRUE, "ReadFileEx failed, err=%i\n", GetLastError()); - ok(completion_called == 0, "completion routine called before ReadFileEx returned\n"); - wait = WaitForSingleObjectEx(event, 0, TRUE); -- todo_wine - ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObjectEx returned %x\n", wait); -- todo_wine - ok(completion_called == 1, "completion not called after writing pipe\n"); -- todo_wine - ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode); - ok(completion_num_bytes == 4, "ReadFileEx returned only %d bytes\n", completion_num_bytes); - ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n"); -diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index 81f941d..d3f0c0e 100644 ---- a/dlls/ntdll/file.c -+++ b/dlls/ntdll/file.c -@@ -885,8 +885,8 @@ err: - io_status->Information = total; - TRACE("= SUCCESS (%u)\n", total); - if (hEvent) NtSetEvent( hEvent, NULL ); -- if (apc && !status) NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)apc, -- (ULONG_PTR)apc_user, (ULONG_PTR)io_status, 0 ); -+ if (apc && status != STATUS_END_OF_FILE) NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)apc, -+ (ULONG_PTR)apc_user, (ULONG_PTR)io_status, 0 ); - } - else - { --- -2.1.3 - diff --git a/patches/kernel32-Named_Pipe/0012-kernel32-tests-Test-sending-peeking-and-receiving-an.patch b/patches/kernel32-Named_Pipe/0012-kernel32-tests-Test-sending-peeking-and-receiving-an.patch deleted file mode 100644 index 0c4e3436..00000000 --- a/patches/kernel32-Named_Pipe/0012-kernel32-tests-Test-sending-peeking-and-receiving-an.patch +++ /dev/null @@ -1,301 +0,0 @@ -From 8208e3f7c671c71b3b7d25d854e860aad7c45697 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Mon, 11 Aug 2014 00:56:46 +0200 -Subject: kernel32/tests: Test sending, peeking and receiving an empty message. - -Changes in v2: - * As async handling is now working correctly, it breaks some tests :/ - We need a lot of ugly code to prevent the tests from deadlocking... - * Fix issue in broken pipe check, should be moved into an earlier patch. ---- - dlls/kernel32/tests/pipe.c | 267 +++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 267 insertions(+) - -diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c -index 5f2c4d7..76cf018 100644 ---- a/dlls/kernel32/tests/pipe.c -+++ b/dlls/kernel32/tests/pipe.c -@@ -338,6 +338,146 @@ static void test_CreateNamedPipe(int pipemode) - ok(readden == sizeof(obuf2) - 8, "read got %d bytes\n", readden); - ok(memcmp(obuf2, ibuf, written) == 0, "content check\n"); - -+ /* Tests for sending empty messages */ -+ memset(ibuf, 0, sizeof(ibuf)); -+ ok(WriteFile(hnp, obuf, 0, &written, NULL), "WriteFile\n"); -+ ok(written == 0, "write file len\n"); -+ if (pipemode != PIPE_TYPE_BYTE) -+ { -+ ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); -+ ok(readden == 0, "read got %d bytes\n", readden); -+ } -+ -+ memset(ibuf, 0, sizeof(ibuf)); -+ ok(WriteFile(hFile, obuf, 0, &written, NULL), "WriteFile\n"); -+ ok(written == 0, "write file len\n"); -+ if (pipemode != PIPE_TYPE_BYTE) -+ { -+ ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); -+ ok(readden == 0, "read got %d bytes\n", readden); -+ } -+ -+ /* similar to above, but with an additional call to PeekNamedPipe inbetween */ -+ memset(ibuf, 0, sizeof(ibuf)); -+ ok(WriteFile(hnp, obuf, 0, &written, NULL), "WriteFile\n"); -+ ok(written == 0, "write file len\n"); -+ ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, NULL), "Peek\n"); -+ ok(readden == 0, "peek got %d bytes\n", readden); -+ if (pipemode != PIPE_TYPE_BYTE) -+ { -+ struct rpcThreadArgs rpcargs; -+ HANDLE thread; -+ DWORD threadId; -+ -+ rpcargs.returnValue = 0; -+ rpcargs.lastError = GetLastError(); -+ rpcargs.op = RPC_READFILE; -+ rpcargs.args[0] = (ULONG_PTR)hFile; -+ rpcargs.args[1] = (ULONG_PTR)ibuf; -+ rpcargs.args[2] = (ULONG_PTR)sizeof(ibuf); -+ rpcargs.args[3] = (ULONG_PTR)&readden; -+ rpcargs.args[4] = (ULONG_PTR)NULL; -+ -+ thread = CreateThread(NULL, 0, rpcThreadMain, (void *)&rpcargs, 0, &threadId); -+ ok(thread != NULL, "CreateThread failed. %d\n", GetLastError()); -+ ret = WaitForSingleObject(thread, 200); -+ todo_wine -+ ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d instead of %d.\n", ret, WAIT_OBJECT_0); -+ if (ret == WAIT_TIMEOUT) -+ { -+ ok(WriteFile(hnp, obuf, 0, &written, NULL), "WriteFile\n"); -+ ok(written == 0, "write file len\n"); -+ ret = WaitForSingleObject(thread, 200); -+ ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d instead of %d.\n", ret, WAIT_OBJECT_0); -+ } -+ CloseHandle(thread); -+ ok((BOOL)rpcargs.returnValue, "ReadFile\n"); -+ ok(readden == 0, "read got %d bytes\n", readden); -+ } -+ -+ memset(ibuf, 0, sizeof(ibuf)); -+ ok(WriteFile(hFile, obuf, 0, &written, NULL), "WriteFile\n"); -+ ok(written == 0, "write file len\n"); -+ ok(PeekNamedPipe(hnp, NULL, 0, NULL, &readden, NULL), "Peek\n"); -+ ok(readden == 0, "peek got %d bytes\n", readden); -+ if (pipemode != PIPE_TYPE_BYTE) -+ { -+ struct rpcThreadArgs rpcargs; -+ HANDLE thread; -+ DWORD threadId; -+ -+ rpcargs.returnValue = 0; -+ rpcargs.lastError = GetLastError(); -+ rpcargs.op = RPC_READFILE; -+ rpcargs.args[0] = (ULONG_PTR)hnp; -+ rpcargs.args[1] = (ULONG_PTR)ibuf; -+ rpcargs.args[2] = (ULONG_PTR)sizeof(ibuf); -+ rpcargs.args[3] = (ULONG_PTR)&readden; -+ rpcargs.args[4] = (ULONG_PTR)NULL; -+ -+ thread = CreateThread(NULL, 0, rpcThreadMain, (void *)&rpcargs, 0, &threadId); -+ ok(thread != NULL, "CreateThread failed. %d\n", GetLastError()); -+ ret = WaitForSingleObject(thread, 200); -+ todo_wine -+ ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d instead of %d.\n", ret, WAIT_OBJECT_0); -+ if (ret == WAIT_TIMEOUT) -+ { -+ ok(WriteFile(hFile, obuf, 0, &written, NULL), "WriteFile\n"); -+ ok(written == 0, "write file len\n"); -+ ret = WaitForSingleObject(thread, 200); -+ ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d instead of %d.\n", ret, WAIT_OBJECT_0); -+ } -+ CloseHandle(thread); -+ ok((BOOL)rpcargs.returnValue, "ReadFile\n"); -+ ok(readden == 0, "read got %d bytes\n", readden); -+ } -+ -+ /* similar to above, but now with PeekNamedPipe and multiple messages */ -+ memset(ibuf, 0, sizeof(ibuf)); -+ ok(WriteFile(hnp, obuf, 0, &written, NULL), "WriteFile\n"); -+ ok(written == 0, "write file len\n"); -+ ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile\n"); -+ ok(written == sizeof(obuf), "write file len\n"); -+ ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "Peek\n"); -+ ok(readden == sizeof(obuf), "peek got %d bytes\n", readden); -+ ok(leftmsg == 0, "peek got %d bytes left in msg\n", leftmsg); -+ ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "Peek\n"); -+ ok(readden == sizeof(obuf), "peek got %d bytes\n", readden); -+ if (pipemode != PIPE_TYPE_BYTE) -+ todo_wine -+ ok(leftmsg == 0, "peek got %d bytes left in msg\n", leftmsg); -+ else -+ ok(leftmsg == 0, "peek got %d bytes left in msg\n", leftmsg); -+ ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); -+ ok(readden == sizeof(obuf), "read got %d bytes\n", readden); -+ ok(memcmp(obuf, ibuf, sizeof(obuf)) == 0, "content check\n"); -+ -+ memset(ibuf, 0, sizeof(ibuf)); -+ ok(WriteFile(hFile, obuf2, 0, &written, NULL), "WriteFile\n"); -+ ok(written == 0, "write file len\n"); -+ ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), "WriteFile\n"); -+ ok(written == sizeof(obuf2), "write file len\n"); -+ ok(PeekNamedPipe(hnp, NULL, 0, NULL, &readden, &leftmsg), "Peek\n"); -+ ok(readden == sizeof(obuf2), "peek got %d bytes\n", readden); -+ ok(leftmsg == 0, "peek got %d bytes left in msg\n", leftmsg); -+ ok(PeekNamedPipe(hnp, NULL, 0, NULL, &readden, &leftmsg), "Peek\n"); -+ ok(readden == sizeof(obuf2), "peek got %d bytes\n", readden); -+ if (pipemode != PIPE_TYPE_BYTE) -+ todo_wine -+ ok(leftmsg == 0, "peek got %d bytes left in msg\n", leftmsg); -+ else -+ ok(leftmsg == 0, "peek got %d bytes left in msg\n", leftmsg); -+ ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); -+ if (pipemode != PIPE_TYPE_BYTE) -+ { -+ todo_wine -+ ok(readden == 0, "read got %d bytes\n", readden); -+ if (readden == 0) -+ ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); -+ } -+ ok(readden == sizeof(obuf2), "read got %d bytes\n", readden); -+ ok(memcmp(obuf2, ibuf, sizeof(obuf2)) == 0, "content check\n"); -+ - /* Test reading of multiple writes */ - memset(ibuf, 0, sizeof(ibuf)); - ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile3a\n"); -@@ -456,6 +596,133 @@ static void test_CreateNamedPipe(int pipemode) - if (readden <= sizeof(obuf)) - ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); - -+ /* Tests for sending empty messages */ -+ memset(ibuf, 0, sizeof(ibuf)); -+ ok(WriteFile(hnp, obuf, 0, &written, NULL), "WriteFile\n"); -+ ok(written == 0, "write file len\n"); -+ ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); -+ ok(readden == 0, "read got %d bytes\n", readden); -+ -+ memset(ibuf, 0, sizeof(ibuf)); -+ ok(WriteFile(hFile, obuf, 0, &written, NULL), "WriteFile\n"); -+ ok(written == 0, "write file len\n"); -+ ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); -+ ok(readden == 0, "read got %d bytes\n", readden); -+ -+ /* similar to above, but with an additional call to PeekNamedPipe inbetween */ -+ memset(ibuf, 0, sizeof(ibuf)); -+ ok(WriteFile(hnp, obuf, 0, &written, NULL), "WriteFile\n"); -+ ok(written == 0, "write file len\n"); -+ ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, NULL), "Peek\n"); -+ ok(readden == 0, "peek got %d bytes\n", readden); -+ { -+ struct rpcThreadArgs rpcargs; -+ HANDLE thread; -+ DWORD threadId; -+ -+ rpcargs.returnValue = 0; -+ rpcargs.lastError = GetLastError(); -+ rpcargs.op = RPC_READFILE; -+ rpcargs.args[0] = (ULONG_PTR)hFile; -+ rpcargs.args[1] = (ULONG_PTR)ibuf; -+ rpcargs.args[2] = (ULONG_PTR)sizeof(ibuf); -+ rpcargs.args[3] = (ULONG_PTR)&readden; -+ rpcargs.args[4] = (ULONG_PTR)NULL; -+ -+ thread = CreateThread(NULL, 0, rpcThreadMain, (void *)&rpcargs, 0, &threadId); -+ ok(thread != NULL, "CreateThread failed. %d\n", GetLastError()); -+ ret = WaitForSingleObject(thread, 200); -+ todo_wine -+ ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d instead of %d.\n", ret, WAIT_OBJECT_0); -+ if (ret == WAIT_TIMEOUT) -+ { -+ ok(WriteFile(hnp, obuf, 0, &written, NULL), "WriteFile\n"); -+ ok(written == 0, "write file len\n"); -+ ret = WaitForSingleObject(thread, 200); -+ ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d instead of %d.\n", ret, WAIT_OBJECT_0); -+ } -+ CloseHandle(thread); -+ ok((BOOL)rpcargs.returnValue, "ReadFile\n"); -+ ok(readden == 0, "read got %d bytes\n", readden); -+ } -+ -+ memset(ibuf, 0, sizeof(ibuf)); -+ ok(WriteFile(hFile, obuf, 0, &written, NULL), "WriteFile\n"); -+ ok(written == 0, "write file len\n"); -+ ok(PeekNamedPipe(hnp, NULL, 0, NULL, &readden, NULL), "Peek\n"); -+ ok(readden == 0, "peek got %d bytes\n", readden); -+ { -+ struct rpcThreadArgs rpcargs; -+ HANDLE thread; -+ DWORD threadId; -+ -+ rpcargs.returnValue = 0; -+ rpcargs.lastError = GetLastError(); -+ rpcargs.op = RPC_READFILE; -+ rpcargs.args[0] = (ULONG_PTR)hnp; -+ rpcargs.args[1] = (ULONG_PTR)ibuf; -+ rpcargs.args[2] = (ULONG_PTR)sizeof(ibuf); -+ rpcargs.args[3] = (ULONG_PTR)&readden; -+ rpcargs.args[4] = (ULONG_PTR)NULL; -+ -+ thread = CreateThread(NULL, 0, rpcThreadMain, (void *)&rpcargs, 0, &threadId); -+ ok(thread != NULL, "CreateThread failed. %d\n", GetLastError()); -+ ret = WaitForSingleObject(thread, 200); -+ todo_wine -+ ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d instead of %d.\n", ret, WAIT_OBJECT_0); -+ if (ret == WAIT_TIMEOUT) -+ { -+ ok(WriteFile(hFile, obuf, 0, &written, NULL), "WriteFile\n"); -+ ok(written == 0, "write file len\n"); -+ ret = WaitForSingleObject(thread, 200); -+ ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d instead of %d.\n", ret, WAIT_OBJECT_0); -+ } -+ CloseHandle(thread); -+ ok((BOOL)rpcargs.returnValue, "ReadFile\n"); -+ ok(readden == 0, "read got %d bytes\n", readden); -+ } -+ -+ /* similar to above, but now with PeekNamedPipe and multiple messages */ -+ memset(ibuf, 0, sizeof(ibuf)); -+ ok(WriteFile(hnp, obuf, 0, &written, NULL), "WriteFile\n"); -+ ok(written == 0, "write file len\n"); -+ ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile\n"); -+ ok(written == sizeof(obuf), "write file len\n"); -+ ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "Peek\n"); -+ ok(readden == sizeof(obuf), "peek got %d bytes\n", readden); -+ ok(leftmsg == 0, "peek got %d bytes left in msg\n", leftmsg); -+ ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, &leftmsg), "Peek\n"); -+ ok(readden == sizeof(obuf), "peek got %d bytes\n", readden); -+ todo_wine -+ ok(leftmsg == 0, "peek got %d bytes left in msg\n", leftmsg); -+ ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); -+ todo_wine -+ ok(readden == 0, "read got %d bytes\n", readden); -+ if (readden == 0) -+ ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); -+ ok(readden == sizeof(obuf), "read got %d bytes\n", readden); -+ ok(memcmp(obuf, ibuf, sizeof(obuf)) == 0, "content check\n"); -+ -+ memset(ibuf, 0, sizeof(ibuf)); -+ ok(WriteFile(hFile, obuf2, 0, &written, NULL), "WriteFile\n"); -+ ok(written == 0, "write file len\n"); -+ ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), "WriteFile\n"); -+ ok(written == sizeof(obuf2), "write file len\n"); -+ ok(PeekNamedPipe(hnp, NULL, 0, NULL, &readden, &leftmsg), "Peek\n"); -+ ok(readden == sizeof(obuf2), "peek got %d bytes\n", readden); -+ ok(leftmsg == 0, "peek got %d bytes left in msg\n", leftmsg); -+ ok(PeekNamedPipe(hnp, NULL, 0, NULL, &readden, &leftmsg), "Peek\n"); -+ ok(readden == sizeof(obuf2), "peek got %d bytes\n", readden); -+ todo_wine -+ ok(leftmsg == 0, "peek got %d bytes left in msg\n", leftmsg); -+ ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); -+ todo_wine -+ ok(readden == 0, "read got %d bytes\n", readden); -+ if (readden == 0) -+ ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); -+ ok(readden == sizeof(obuf2), "read got %d bytes\n", readden); -+ ok(memcmp(obuf2, ibuf, sizeof(obuf2)) == 0, "content check\n"); -+ - /* Test how ReadFile behaves when the buffer is not big enough for the whole message */ - memset(ibuf, 0, sizeof(ibuf)); - ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), "WriteFile 7\n"); --- -2.6.2 - diff --git a/patches/kernel32-Named_Pipe/0013-ntdll-Add-support-for-nonblocking-pipes.patch b/patches/kernel32-Named_Pipe/0013-ntdll-Add-support-for-nonblocking-pipes.patch deleted file mode 100644 index db472eaf..00000000 --- a/patches/kernel32-Named_Pipe/0013-ntdll-Add-support-for-nonblocking-pipes.patch +++ /dev/null @@ -1,52 +0,0 @@ -From fb6d82077a362f002300cd171547c292cbb5d0bd Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sun, 17 Aug 2014 01:29:06 +0200 -Subject: ntdll: Add support for nonblocking pipes. - ---- - dlls/ntdll/file.c | 15 +++++++++++++-- - 1 file changed, 13 insertions(+), 2 deletions(-) - -diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index d3f0c0e..ba3814e 100644 ---- a/dlls/ntdll/file.c -+++ b/dlls/ntdll/file.c -@@ -472,6 +472,10 @@ static NTSTATUS read_unix_fd(int fd, char *buf, ULONG *total, ULONG length, - { - if (pipe_flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) - { -+ int recvmsg_flags = MSG_PEEK; -+ if (*total || (pipe_flags & NAMED_PIPE_NONBLOCKING_MODE)) -+ recvmsg_flags |= MSG_DONTWAIT; -+ - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = &iov; -@@ -483,7 +487,7 @@ static NTSTATUS read_unix_fd(int fd, char *buf, ULONG *total, ULONG length, - iov.iov_base = buf + *total; - iov.iov_len = length - *total; - -- result = recvmsg( fd, &msg, MSG_PEEK | (*total ? MSG_DONTWAIT : 0) ); -+ result = recvmsg( fd, &msg, recvmsg_flags ); - if (result >= 0 && !(msg.msg_flags & MSG_TRUNC)) - { - int ret; -@@ -527,7 +531,14 @@ static NTSTATUS read_unix_fd(int fd, char *buf, ULONG *total, ULONG length, - return STATUS_PENDING; - } - else if (errno == EAGAIN) -- return (avail_mode && *total) ? STATUS_SUCCESS : STATUS_PENDING; -+ { -+ if (avail_mode && *total) -+ return STATUS_SUCCESS; -+ else if (pipe_flags & NAMED_PIPE_NONBLOCKING_MODE) -+ return *total ? STATUS_SUCCESS : STATUS_PIPE_EMPTY; -+ else -+ return STATUS_PENDING; -+ } - else if (errno != EINTR) - return FILE_GetNtStatus(); - } --- -2.1.3 - diff --git a/patches/kernel32-Named_Pipe/0014-kernel32-tests-Add-tests-for-PIPE_NOWAIT-in-message-.patch b/patches/kernel32-Named_Pipe/0014-kernel32-tests-Add-tests-for-PIPE_NOWAIT-in-message-.patch deleted file mode 100644 index 426884d7..00000000 --- a/patches/kernel32-Named_Pipe/0014-kernel32-tests-Add-tests-for-PIPE_NOWAIT-in-message-.patch +++ /dev/null @@ -1,126 +0,0 @@ -From c5fd5022f2e8a00a520f030919394f1b2b6559d4 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Mon, 11 Aug 2014 04:19:49 +0200 -Subject: kernel32/tests: Add tests for PIPE_NOWAIT in message mode. - ---- - dlls/kernel32/tests/pipe.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 96 insertions(+) - -diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c -index 81d4d39..18b371c 100644 ---- a/dlls/kernel32/tests/pipe.c -+++ b/dlls/kernel32/tests/pipe.c -@@ -2619,6 +2619,101 @@ static void test_overlapped_error(void) - CloseHandle(event); - } - -+static void test_nowait(void) -+{ -+ HANDLE hnp; -+ HANDLE hFile; -+ static const char obuf[] = "Bit Bucket"; -+ char ibuf[32]; -+ DWORD written; -+ DWORD readden; -+ DWORD lpmode; -+ -+ hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, -+ PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT, -+ /* nMaxInstances */ 1, -+ /* nOutBufSize */ 1024, -+ /* nInBufSize */ 1024, -+ /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, -+ /* lpSecurityAttrib */ NULL); -+ ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); -+ -+ hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); -+ ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed (%d)\n", GetLastError()); -+ -+ /* don't try to do i/o if one side couldn't be opened, as it hangs */ -+ if (hFile != INVALID_HANDLE_VALUE) -+ { -+ /* send message from client to server */ -+ ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile\n"); -+ ok(written == sizeof(obuf), "write file len\n"); -+ ok(PeekNamedPipe(hnp, NULL, 0, NULL, &readden, NULL), "Peek\n"); -+ ok(readden == sizeof(obuf), "got %d bytes\n", readden); -+ -+ memset(ibuf, 0, sizeof(ibuf)); -+ ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile() failed: %08x\n", GetLastError()); -+ ok(readden == sizeof(obuf), "got %d bytes\n", readden); -+ ok(memcmp(obuf, ibuf, sizeof(obuf)) == 0, "content check\n"); -+ -+ readden = 0xdeadbeef; -+ SetLastError(0xdeadbeef); -+ ok(!ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile() succeeded\n"); -+ ok(readden == 0, "got %d bytes\n", readden); -+ ok(GetLastError() == ERROR_NO_DATA, "GetLastError() returned %08x, expected ERROR_NO_DATA\n", GetLastError()); -+ -+ lpmode = PIPE_READMODE_MESSAGE | PIPE_NOWAIT; -+ ok(SetNamedPipeHandleState(hFile, &lpmode, NULL, NULL), "Change mode\n"); -+ -+ /* send message from server to client */ -+ ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile\n"); -+ ok(written == sizeof(obuf), "write file len\n"); -+ ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, NULL), "Peek\n"); -+ ok(readden == sizeof(obuf), "got %d bytes\n", readden); -+ -+ memset(ibuf, 0, sizeof(ibuf)); -+ ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile() failed: %08x\n", GetLastError()); -+ ok(readden == sizeof(obuf), "got %d bytes\n", readden); -+ ok(memcmp(obuf, ibuf, sizeof(obuf)) == 0, "content check\n"); -+ -+ readden = 0xdeadbeef; -+ SetLastError(0xdeadbeef); -+ ok(!ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile() succeeded\n"); -+ ok(readden == 0, "got %d bytes\n", readden); -+ ok(GetLastError() == ERROR_NO_DATA, "GetLastError() returned %08x, expected ERROR_NO_DATA\n", GetLastError()); -+ -+ /* now again the bad zero byte message test */ -+ ok(WriteFile(hFile, obuf, 0, &written, NULL), "WriteFile\n"); -+ ok(written == 0, "write file len\n"); -+ -+ ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile() failed: %08x\n", GetLastError()); -+ ok(readden == 0, "got %d bytes\n", readden); -+ -+ readden = 0xdeadbeef; -+ SetLastError(0xdeadbeef); -+ ok(!ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile() succeeded\n"); -+ ok(readden == 0, "got %d bytes\n", readden); -+ ok(GetLastError() == ERROR_NO_DATA, "GetLastError() returned %08x, expected ERROR_NO_DATA\n", GetLastError()); -+ -+ /* and the same for the reverse direction */ -+ ok(WriteFile(hnp, obuf, 0, &written, NULL), "WriteFile\n"); -+ ok(written == 0, "write file len\n"); -+ -+ ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile() failed: %08x\n", GetLastError()); -+ ok(readden == 0, "got %d bytes\n", readden); -+ -+ readden = 0xdeadbeef; -+ SetLastError(0xdeadbeef); -+ ok(!ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile() succeeded\n"); -+ ok(readden == 0, "got %d bytes\n", readden); -+ ok(GetLastError() == ERROR_NO_DATA, "GetLastError() returned %08x, expected ERROR_NO_DATA\n", GetLastError()); -+ -+ ok(CloseHandle(hFile), "CloseHandle\n"); -+ } -+ -+ ok(CloseHandle(hnp), "CloseHandle\n"); -+ -+} -+ - static void test_NamedPipeHandleState(void) - { - HANDLE server, client; -@@ -3114,6 +3209,7 @@ START_TEST(pipe) - test_impersonation(); - test_overlapped(); - test_overlapped_error(); -+ test_nowait(); - test_NamedPipeHandleState(); - test_GetNamedPipeInfo(); - test_readfileex_pending(); --- -2.9.0 - diff --git a/patches/kernel32-Named_Pipe/0015-ntdll-Allow-to-set-PIPE_NOWAIT-on-byte-mode-pipes.patch b/patches/kernel32-Named_Pipe/0015-ntdll-Allow-to-set-PIPE_NOWAIT-on-byte-mode-pipes.patch deleted file mode 100644 index 5f21fff5..00000000 --- a/patches/kernel32-Named_Pipe/0015-ntdll-Allow-to-set-PIPE_NOWAIT-on-byte-mode-pipes.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 8ce5ed62d1e49a3e738a8287e4611fe9f63437e0 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Mon, 11 Aug 2014 05:34:19 +0200 -Subject: ntdll: Allow to set PIPE_NOWAIT on byte-mode pipes. - -This patch implements the functionality to set PIPE_NOWAIT on regular bytemode -pipes. This patch also extends the test to show that the implemented behaviour -matches the native implementation. ---- - dlls/kernel32/tests/pipe.c | 37 +++++++++++++++++++++++++++++-------- - dlls/ntdll/file.c | 2 ++ - 2 files changed, 31 insertions(+), 8 deletions(-) - -diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c -index 18b371c..55f8d4f 100644 ---- a/dlls/kernel32/tests/pipe.c -+++ b/dlls/kernel32/tests/pipe.c -@@ -2619,7 +2619,7 @@ static void test_overlapped_error(void) - CloseHandle(event); - } - --static void test_nowait(void) -+static void test_nowait(int pipemode) - { - HANDLE hnp; - HANDLE hFile; -@@ -2630,7 +2630,7 @@ static void test_nowait(void) - DWORD lpmode; - - hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, -- PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT, -+ pipemode | PIPE_NOWAIT, - /* nMaxInstances */ 1, - /* nOutBufSize */ 1024, - /* nInBufSize */ 1024, -@@ -2661,7 +2661,7 @@ static void test_nowait(void) - ok(readden == 0, "got %d bytes\n", readden); - ok(GetLastError() == ERROR_NO_DATA, "GetLastError() returned %08x, expected ERROR_NO_DATA\n", GetLastError()); - -- lpmode = PIPE_READMODE_MESSAGE | PIPE_NOWAIT; -+ lpmode = (pipemode & PIPE_READMODE_MESSAGE) | PIPE_NOWAIT; - ok(SetNamedPipeHandleState(hFile, &lpmode, NULL, NULL), "Change mode\n"); - - /* send message from server to client */ -@@ -2685,8 +2685,18 @@ static void test_nowait(void) - ok(WriteFile(hFile, obuf, 0, &written, NULL), "WriteFile\n"); - ok(written == 0, "write file len\n"); - -- ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile() failed: %08x\n", GetLastError()); -- ok(readden == 0, "got %d bytes\n", readden); -+ if (pipemode != PIPE_TYPE_BYTE) -+ { -+ ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile() failed: %08x\n", GetLastError()); -+ ok(readden == 0, "got %d bytes\n", readden); -+ } -+ else -+ { -+ SetLastError(0xdeadbeef); -+ ok(!ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile() succeeded\n"); -+ ok(readden == 0, "got %d bytes\n", readden); -+ ok(GetLastError() == ERROR_NO_DATA, "GetLastError() returned %08x, expected ERROR_NO_DATA\n", GetLastError()); -+ } - - readden = 0xdeadbeef; - SetLastError(0xdeadbeef); -@@ -2698,8 +2708,18 @@ static void test_nowait(void) - ok(WriteFile(hnp, obuf, 0, &written, NULL), "WriteFile\n"); - ok(written == 0, "write file len\n"); - -- ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile() failed: %08x\n", GetLastError()); -- ok(readden == 0, "got %d bytes\n", readden); -+ if (pipemode != PIPE_TYPE_BYTE) -+ { -+ ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile() failed: %08x\n", GetLastError()); -+ ok(readden == 0, "got %d bytes\n", readden); -+ } -+ else -+ { -+ SetLastError(0xdeadbeef); -+ ok(!ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile() succeeded\n"); -+ ok(readden == 0, "got %d bytes\n", readden); -+ ok(GetLastError() == ERROR_NO_DATA, "GetLastError() returned %08x, expected ERROR_NO_DATA\n", GetLastError()); -+ } - - readden = 0xdeadbeef; - SetLastError(0xdeadbeef); -@@ -3209,7 +3229,8 @@ START_TEST(pipe) - test_impersonation(); - test_overlapped(); - test_overlapped_error(); -- test_nowait(); -+ test_nowait(PIPE_TYPE_BYTE); -+ test_nowait(PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE); - test_NamedPipeHandleState(); - test_GetNamedPipeInfo(); - test_readfileex_pending(); -diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index 622cc45..c27a13f 100644 ---- a/dlls/ntdll/file.c -+++ b/dlls/ntdll/file.c -@@ -573,6 +573,8 @@ static NTSTATUS read_unix_fd(int fd, char *buf, ULONG *total, ULONG length, - if (ret < 0) ERR("dequeue message failed reason: %s\n", strerror(errno)); - } - } -+ else if (pipe_flags & NAMED_PIPE_NONBLOCKING_MODE) -+ result = recv( fd, buf + *total, length - *total, MSG_DONTWAIT ); - else - result = read( fd, buf + *total, length - *total ); - --- -2.9.0 - diff --git a/patches/kernel32-Named_Pipe/0016-kernel32-tests-Add-additional-tests-for-PIPE_NOWAIT-.patch b/patches/kernel32-Named_Pipe/0016-kernel32-tests-Add-additional-tests-for-PIPE_NOWAIT-.patch deleted file mode 100644 index a3184e38..00000000 --- a/patches/kernel32-Named_Pipe/0016-kernel32-tests-Add-additional-tests-for-PIPE_NOWAIT-.patch +++ /dev/null @@ -1,331 +0,0 @@ -From 5f05e5517f75081777b26d6f0e300a12121d094a Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sun, 17 Aug 2014 02:56:57 +0200 -Subject: kernel32/tests: Add additional tests for PIPE_NOWAIT in overlapped - mode. - ---- - dlls/kernel32/tests/pipe.c | 293 ++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 292 insertions(+), 1 deletion(-) - -diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c -index 3f753f8..c3f0b19 100644 ---- a/dlls/kernel32/tests/pipe.c -+++ b/dlls/kernel32/tests/pipe.c -@@ -2748,7 +2748,7 @@ static void test_readfileex_pending(void) - { - HANDLE server, client, event; - BOOL ret; -- DWORD err, wait, num_bytes; -+ DWORD err, wait, num_bytes, lpmode; - OVERLAPPED overlapped; - char read_buf[1024]; - char write_buf[1024]; -@@ -2903,6 +2903,159 @@ todo_wine - CloseHandle(client); - CloseHandle(server); - -+ /* On Windows versions > 2000 it is not possible to add PIPE_NOWAIT to a byte-mode -+ * PIPE after creating. Create a new pipe for the following tests. */ -+ server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, -+ /* dwOpenMode */ PIPE_TYPE_BYTE | PIPE_NOWAIT, -+ /* nMaxInstances */ 1, -+ /* nOutBufSize */ 1024, -+ /* nInBufSize */ 1024, -+ /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, -+ /* lpSecurityAttrib */ NULL); -+ ok(server != INVALID_HANDLE_VALUE, "cf failed\n"); -+ -+ client = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, NULL, -+ OPEN_EXISTING, 0, NULL); -+ ok(client != INVALID_HANDLE_VALUE, "cf failed\n"); -+ -+ memset(&overlapped, 0, sizeof(overlapped)); -+ overlapped.hEvent = event; -+ -+ /* Initial check with empty pipe */ -+ memset(read_buf, 0, sizeof(read_buf)); -+ completion_called = 0; -+ ResetEvent(event); -+ ret = ReadFileEx(server, read_buf, 4, &overlapped, completion_routine); -+ ok(ret == FALSE, "ReadFileEx succeded\n"); -+ ok(completion_called == 0, "completion routine called before ReadFileEx returned\n"); -+ ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %d\n", GetLastError()); -+ wait = WaitForSingleObjectEx(event, 0, TRUE); -+ ok(wait == WAIT_TIMEOUT, "WaitForSingleObjectEx returned %x\n", wait); -+ ok(completion_called == 0, "completion routine called before writing to file\n"); -+ -+ /* Call ReadFileEx after writing content to the pipe */ -+ num_bytes = 0xdeadbeef; -+ ret = WriteFile(client, long_test_string, strlen(long_test_string), &num_bytes, NULL); -+ ok(ret, "WriteFile failed, err=%i\n", GetLastError()); -+ ok(num_bytes == strlen(long_test_string), "bytes %u\n", num_bytes); -+ -+ memset(read_buf, 0, sizeof(read_buf)); -+ completion_called = 0; -+ ResetEvent(event); -+ ret = ReadFileEx(server, read_buf, 4, &overlapped, completion_routine); -+ ok(ret == TRUE, "ReadFileEx failed, err=%i\n", GetLastError()); -+ ok(completion_called == 0, "completion routine called before ReadFileEx returned\n"); -+ wait = WaitForSingleObjectEx(event, 0, TRUE); -+ ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObjectEx returned %x\n", wait); -+ ok(completion_called == 1, "completion not called after writing pipe\n"); -+ ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode); -+ ok(completion_num_bytes == 4, "ReadFileEx returned only %d bytes\n", completion_num_bytes); -+ ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n"); -+ -+ ret = ReadFile(server, read_buf + 4, sizeof(read_buf) - 4, &num_bytes, NULL); -+ ok(ret == TRUE, "ReadFile succeeded\n"); -+ ok(num_bytes == strlen(long_test_string)-4, "ReadFile returned only %d bytes\n", num_bytes); -+ ok(!memcmp(long_test_string, read_buf, strlen(long_test_string)), "ReadFile read wrong bytes\n"); -+ -+ /* Same again, but read as a single part */ -+ num_bytes = 0xdeadbeef; -+ ret = WriteFile(client, long_test_string, strlen(long_test_string), &num_bytes, NULL); -+ ok(ret, "WriteFile failed, err=%i\n", GetLastError()); -+ ok(num_bytes == strlen(long_test_string), "bytes %u\n", num_bytes); -+ -+ memset(read_buf, 0, sizeof(read_buf)); -+ completion_called = 0; -+ ResetEvent(event); -+ ret = ReadFileEx(server, read_buf, sizeof(read_buf), &overlapped, completion_routine); -+ ok(ret == TRUE, "ReadFileEx failed, err=%i\n", GetLastError()); -+ ok(completion_called == 0, "completion routine called before ReadFileEx returned\n"); -+ wait = WaitForSingleObjectEx(event, 0, TRUE); -+ ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObjectEx returned %x\n", wait); -+ ok(completion_called == 1, "completion not called after writing pipe\n"); -+ ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode); -+ ok(completion_num_bytes == strlen(long_test_string), "ReadFileEx returned only %d bytes\n", completion_num_bytes); -+ ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n"); -+ ok(!memcmp(long_test_string, read_buf, strlen(long_test_string)), "ReadFile read wrong bytes\n"); -+ -+ /* Check content of overlapped structure */ -+ memset(read_buf, 0, sizeof(read_buf)); -+ S(U(overlapped)).Offset = 0; -+ S(U(overlapped)).OffsetHigh = 0; -+ overlapped.Internal = -1; -+ overlapped.InternalHigh = -1; -+ overlapped.hEvent = event; -+ num_bytes = 0xdeadbeef; -+ SetLastError(0xdeadbeef); -+ ret = ReadFile(server, read_buf, 4, &num_bytes, &overlapped); -+ ok(ret == FALSE, "ReadFile succeeded\n"); -+ ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %d\n", GetLastError()); -+ ok(num_bytes == 0, "bytes %u\n", num_bytes); -+ ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %#lx\n", overlapped.Internal); -+ todo_wine -+ ok(overlapped.InternalHigh == -1, "expected -1, got %lu\n", overlapped.InternalHigh); -+ wait = WaitForSingleObject(event, 100); -+ ok(wait == WAIT_TIMEOUT, "WaitForSingleObjectEx returned %x\n", wait); -+ ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %#lx\n", overlapped.Internal); -+ todo_wine -+ ok(overlapped.InternalHigh == -1, "expected -1, got %lu\n", overlapped.InternalHigh); -+ -+ /* Call ReadFile after writing to the pipe */ -+ num_bytes = 0xdeadbeef; -+ ret = WriteFile(client, long_test_string, strlen(long_test_string), &num_bytes, NULL); -+ ok(ret, "WriteFile failed, err=%i\n", GetLastError()); -+ ok(num_bytes == strlen(long_test_string), "bytes %u\n", num_bytes); -+ -+ memset(read_buf, 0, sizeof(read_buf)); -+ S(U(overlapped)).Offset = 0; -+ S(U(overlapped)).OffsetHigh = 0; -+ overlapped.Internal = -1; -+ overlapped.InternalHigh = -1; -+ overlapped.hEvent = event; -+ num_bytes = 0xdeadbeef; -+ SetLastError(0xdeadbeef); -+ ret = ReadFile(server, read_buf, 4, &num_bytes, &overlapped); -+ ok(ret == TRUE, "ReadFile failed, err=%i\n", GetLastError()); -+ ok(num_bytes == 4, "bytes %u\n", num_bytes); -+ ok((NTSTATUS)overlapped.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", overlapped.Internal); -+ ok(overlapped.InternalHigh == 4, "expected 4, got %lu\n", overlapped.InternalHigh); -+ wait = WaitForSingleObject(event, 100); -+ ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", wait); -+ ok((NTSTATUS)overlapped.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", overlapped.Internal); -+ ok(overlapped.InternalHigh == 4, "expected 4, got %lu\n", overlapped.InternalHigh); -+ -+ ret = ReadFile(server, read_buf + 4, sizeof(read_buf) - 4, &num_bytes, NULL); -+ ok(ret == TRUE, "ReadFile failed\n"); -+ ok(num_bytes == strlen(long_test_string)-4, "ReadFile returned only %d bytes\n", num_bytes); -+ ok(!memcmp(long_test_string, read_buf, strlen(long_test_string)), "ReadFile read wrong bytes\n"); -+ -+ /* Same again, but read as a single part */ -+ num_bytes = 0xdeadbeef; -+ ret = WriteFile(client, long_test_string, strlen(long_test_string), &num_bytes, NULL); -+ ok(ret, "WriteFile failed, err=%i\n", GetLastError()); -+ ok(num_bytes == strlen(long_test_string), "bytes %u\n", num_bytes); -+ -+ memset(read_buf, 0, sizeof(read_buf)); -+ S(U(overlapped)).Offset = 0; -+ S(U(overlapped)).OffsetHigh = 0; -+ overlapped.Internal = -1; -+ overlapped.InternalHigh = -1; -+ overlapped.hEvent = event; -+ num_bytes = 0xdeadbeef; -+ SetLastError(0xdeadbeef); -+ ret = ReadFile(server, read_buf, sizeof(read_buf), &num_bytes, &overlapped); -+ ok(ret == TRUE, "ReadFile failed, err=%i\n", GetLastError()); -+ ok(num_bytes == strlen(long_test_string), "bytes %u\n", num_bytes); -+ ok((NTSTATUS)overlapped.Internal == 0, "expected 0, got %#lx\n", overlapped.Internal); -+ ok(overlapped.InternalHigh == strlen(long_test_string), "expected %u, got %lu\n", (DWORD)strlen(long_test_string), overlapped.InternalHigh); -+ wait = WaitForSingleObject(event, 100); -+ ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", wait); -+ ok((NTSTATUS)overlapped.Internal == 0, "expected 0, got %#lx\n", overlapped.Internal); -+ ok(overlapped.InternalHigh == strlen(long_test_string), "expected %u, got %lu\n", (DWORD)strlen(long_test_string), overlapped.InternalHigh); -+ ok(!memcmp(long_test_string, read_buf, strlen(long_test_string)), "ReadFile read wrong bytes\n"); -+ -+ CloseHandle(client); -+ CloseHandle(server); -+ - server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, - /* dwOpenMode */ PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, - /* nMaxInstances */ 1, -@@ -3041,6 +3194,144 @@ todo_wine - ok(num_bytes == strlen(long_test_string)-4, "ReadFile returned only %d bytes\n", num_bytes); - ok(!memcmp(long_test_string, read_buf, strlen(long_test_string)), "ReadFile read wrong bytes\n"); - -+ /* Tests for PIPE_NOWAIT in message mode */ -+ lpmode = PIPE_READMODE_MESSAGE | PIPE_NOWAIT; -+ ok(SetNamedPipeHandleState(server, &lpmode, NULL, NULL), "Change mode\n"); -+ -+ /* Initial check with empty pipe */ -+ memset(read_buf, 0, sizeof(read_buf)); -+ completion_called = 0; -+ ResetEvent(event); -+ ret = ReadFileEx(server, read_buf, 4, &overlapped, completion_routine); -+ ok(ret == FALSE, "ReadFileEx succeded\n"); -+ ok(completion_called == 0, "completion routine called before ReadFileEx returned\n"); -+ ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %d\n", GetLastError()); -+ wait = WaitForSingleObjectEx(event, 0, TRUE); -+ ok(wait == WAIT_TIMEOUT, "WaitForSingleObjectEx returned %x\n", wait); -+ ok(completion_called == 0, "completion routine called before writing to file\n"); -+ -+ /* Call ReadFileEx after writing content to the pipe */ -+ num_bytes = 0xdeadbeef; -+ ret = WriteFile(client, long_test_string, strlen(long_test_string), &num_bytes, NULL); -+ ok(ret, "WriteFile failed, err=%i\n", GetLastError()); -+ ok(num_bytes == strlen(long_test_string), "bytes %u\n", num_bytes); -+ -+ memset(read_buf, 0, sizeof(read_buf)); -+ completion_called = 0; -+ ResetEvent(event); -+ ret = ReadFileEx(server, read_buf, 4, &overlapped, completion_routine); -+ ok(ret == TRUE, "ReadFileEx failed, err=%i\n", GetLastError()); -+ ok(completion_called == 0, "completion routine called before ReadFileEx returned\n"); -+ wait = WaitForSingleObjectEx(event, 0, TRUE); -+ ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObjectEx returned %x\n", wait); -+ ok(completion_called == 1, "completion not called after writing pipe\n"); -+ ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode); -+ ok(completion_num_bytes == 4, "ReadFileEx returned only %d bytes\n", completion_num_bytes); -+ ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n"); -+ -+ ret = ReadFile(server, read_buf + 4, sizeof(read_buf) - 4, &num_bytes, NULL); -+ ok(ret == TRUE, "ReadFile succeeded\n"); -+ ok(num_bytes == strlen(long_test_string)-4, "ReadFile returned only %d bytes\n", num_bytes); -+ ok(!memcmp(long_test_string, read_buf, strlen(long_test_string)), "ReadFile read wrong bytes\n"); -+ -+ /* Same again, but read as a single part */ -+ num_bytes = 0xdeadbeef; -+ ret = WriteFile(client, long_test_string, strlen(long_test_string), &num_bytes, NULL); -+ ok(ret, "WriteFile failed, err=%i\n", GetLastError()); -+ ok(num_bytes == strlen(long_test_string), "bytes %u\n", num_bytes); -+ -+ memset(read_buf, 0, sizeof(read_buf)); -+ completion_called = 0; -+ ResetEvent(event); -+ ret = ReadFileEx(server, read_buf, sizeof(read_buf), &overlapped, completion_routine); -+ ok(ret == TRUE, "ReadFileEx failed, err=%i\n", GetLastError()); -+ ok(completion_called == 0, "completion routine called before ReadFileEx returned\n"); -+ wait = WaitForSingleObjectEx(event, 0, TRUE); -+ ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObjectEx returned %x\n", wait); -+ ok(completion_called == 1, "completion not called after writing pipe\n"); -+ ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode); -+ ok(completion_num_bytes == strlen(long_test_string), "ReadFileEx returned only %d bytes\n", completion_num_bytes); -+ ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n"); -+ ok(!memcmp(long_test_string, read_buf, strlen(long_test_string)), "ReadFile read wrong bytes\n"); -+ -+ /* Check content of overlapped structure */ -+ memset(read_buf, 0, sizeof(read_buf)); -+ S(U(overlapped)).Offset = 0; -+ S(U(overlapped)).OffsetHigh = 0; -+ overlapped.Internal = -1; -+ overlapped.InternalHigh = -1; -+ overlapped.hEvent = event; -+ num_bytes = 0xdeadbeef; -+ SetLastError(0xdeadbeef); -+ ret = ReadFile(server, read_buf, 4, &num_bytes, &overlapped); -+ ok(ret == FALSE, "ReadFile succeeded\n"); -+ ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %d\n", GetLastError()); -+ ok(num_bytes == 0, "bytes %u\n", num_bytes); -+ ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %#lx\n", overlapped.Internal); -+ todo_wine -+ ok(overlapped.InternalHigh == -1, "expected -1, got %lu\n", overlapped.InternalHigh); -+ wait = WaitForSingleObject(event, 100); -+ ok(wait == WAIT_TIMEOUT, "WaitForSingleObjectEx returned %x\n", wait); -+ ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %#lx\n", overlapped.Internal); -+ todo_wine -+ ok(overlapped.InternalHigh == -1, "expected -1, got %lu\n", overlapped.InternalHigh); -+ -+ /* Call ReadFile after writing to the pipe */ -+ num_bytes = 0xdeadbeef; -+ ret = WriteFile(client, long_test_string, strlen(long_test_string), &num_bytes, NULL); -+ ok(ret, "WriteFile failed, err=%i\n", GetLastError()); -+ ok(num_bytes == strlen(long_test_string), "bytes %u\n", num_bytes); -+ -+ memset(read_buf, 0, sizeof(read_buf)); -+ S(U(overlapped)).Offset = 0; -+ S(U(overlapped)).OffsetHigh = 0; -+ overlapped.Internal = -1; -+ overlapped.InternalHigh = -1; -+ overlapped.hEvent = event; -+ num_bytes = 0xdeadbeef; -+ SetLastError(0xdeadbeef); -+ ret = ReadFile(server, read_buf, 4, &num_bytes, &overlapped); -+ ok(ret == FALSE, "ReadFile succeeded\n"); -+ ok(GetLastError() == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %d\n", GetLastError()); -+ todo_wine -+ ok(num_bytes == 0, "bytes %u\n", num_bytes); -+ ok((NTSTATUS)overlapped.Internal == STATUS_BUFFER_OVERFLOW, "expected STATUS_BUFFER_OVERFLOW, got %#lx\n", overlapped.Internal); -+ ok(overlapped.InternalHigh == 4, "expected 4, got %lu\n", overlapped.InternalHigh); -+ wait = WaitForSingleObject(event, 100); -+ ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", wait); -+ ok((NTSTATUS)overlapped.Internal == STATUS_BUFFER_OVERFLOW, "expected STATUS_BUFFER_OVERFLOW, got %#lx\n", overlapped.Internal); -+ ok(overlapped.InternalHigh == 4, "expected 4, got %lu\n", overlapped.InternalHigh); -+ -+ ret = ReadFile(server, read_buf + 4, sizeof(read_buf) - 4, &num_bytes, NULL); -+ ok(ret == TRUE, "ReadFile failed\n"); -+ ok(num_bytes == strlen(long_test_string)-4, "ReadFile returned only %d bytes\n", num_bytes); -+ ok(!memcmp(long_test_string, read_buf, strlen(long_test_string)), "ReadFile read wrong bytes\n"); -+ -+ /* Same again, but read as a single part */ -+ num_bytes = 0xdeadbeef; -+ ret = WriteFile(client, long_test_string, strlen(long_test_string), &num_bytes, NULL); -+ ok(ret, "WriteFile failed, err=%i\n", GetLastError()); -+ ok(num_bytes == strlen(long_test_string), "bytes %u\n", num_bytes); -+ -+ memset(read_buf, 0, sizeof(read_buf)); -+ S(U(overlapped)).Offset = 0; -+ S(U(overlapped)).OffsetHigh = 0; -+ overlapped.Internal = -1; -+ overlapped.InternalHigh = -1; -+ overlapped.hEvent = event; -+ num_bytes = 0xdeadbeef; -+ SetLastError(0xdeadbeef); -+ ret = ReadFile(server, read_buf, sizeof(read_buf), &num_bytes, &overlapped); -+ ok(ret == TRUE, "ReadFile failed, err=%i\n", GetLastError()); -+ ok(num_bytes == strlen(long_test_string), "bytes %u\n", num_bytes); -+ ok((NTSTATUS)overlapped.Internal == 0, "expected 0, got %#lx\n", overlapped.Internal); -+ ok(overlapped.InternalHigh == strlen(long_test_string), "expected %u, got %lu\n", (DWORD)strlen(long_test_string), overlapped.InternalHigh); -+ wait = WaitForSingleObject(event, 100); -+ ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", wait); -+ ok((NTSTATUS)overlapped.Internal == 0, "expected 0, got %#lx\n", overlapped.Internal); -+ ok(overlapped.InternalHigh == strlen(long_test_string), "expected %u, got %lu\n", (DWORD)strlen(long_test_string), overlapped.InternalHigh); -+ ok(!memcmp(long_test_string, read_buf, strlen(long_test_string)), "ReadFile read wrong bytes\n"); -+ - CloseHandle(client); - CloseHandle(server); - CloseHandle(event); --- -2.3.0 - diff --git a/patches/kernel32-Named_Pipe/0017-ntdll-Improve-ReadDataAvailable-handling-in-FilePipe.patch b/patches/kernel32-Named_Pipe/0017-ntdll-Improve-ReadDataAvailable-handling-in-FilePipe.patch deleted file mode 100644 index 3ebe483d..00000000 --- a/patches/kernel32-Named_Pipe/0017-ntdll-Improve-ReadDataAvailable-handling-in-FilePipe.patch +++ /dev/null @@ -1,46 +0,0 @@ -From b2c20a6b49fdd1ec392b8a7406401343555da73a Mon Sep 17 00:00:00 2001 -From: Qian Hong -Date: Mon, 30 Mar 2015 07:25:35 +0800 -Subject: ntdll: Improve ReadDataAvailable handling in FilePipeLocalInformation - class support. - ---- - dlls/ntdll/file.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index 0dc5c13..a1ca1d1 100644 ---- a/dlls/ntdll/file.c -+++ b/dlls/ntdll/file.c -@@ -2367,6 +2367,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, - case FilePipeLocalInformation: - { - FILE_PIPE_LOCAL_INFORMATION* pli = ptr; -+ int avail, fd, needs_close; - - SERVER_START_REQ( get_named_pipe_info ) - { -@@ -2390,12 +2391,19 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, - pli->MaximumInstances = reply->maxinstances; - pli->CurrentInstances = reply->instances; - pli->InboundQuota = reply->insize; -- pli->ReadDataAvailable = 0; /* FIXME */ -+ pli->ReadDataAvailable = 0; - pli->OutboundQuota = reply->outsize; - pli->WriteQuotaAvailable = 0; /* FIXME */ - pli->NamedPipeState = 0; /* FIXME */ - pli->NamedPipeEnd = (reply->flags & NAMED_PIPE_SERVER_END) ? - FILE_PIPE_SERVER_END : FILE_PIPE_CLIENT_END; -+ -+ if (!server_get_unix_fd( hFile, FILE_READ_DATA, &fd, &needs_close, NULL, NULL )) -+ { -+ if (!unix_fd_avail( fd, &avail )) -+ pli->ReadDataAvailable = min(avail, reply->outsize); /* FIXME */ -+ if (needs_close) close( fd ); -+ } - } - } - SERVER_END_REQ; --- -2.3.7 - diff --git a/patches/kernel32-Named_Pipe/0018-ntdll-Set-NamedPipeState-to-FILE_PIPE_CLOSING_STATE-.patch b/patches/kernel32-Named_Pipe/0018-ntdll-Set-NamedPipeState-to-FILE_PIPE_CLOSING_STATE-.patch deleted file mode 100644 index 1c41d32b..00000000 --- a/patches/kernel32-Named_Pipe/0018-ntdll-Set-NamedPipeState-to-FILE_PIPE_CLOSING_STATE-.patch +++ /dev/null @@ -1,48 +0,0 @@ -From a39228203e7fd6d24ac9cae794fc4903e2d67ad7 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Thu, 4 Jun 2015 00:02:13 +0200 -Subject: ntdll: Set NamedPipeState to FILE_PIPE_CLOSING_STATE on broken pipe - in NtQueryInformationFile. - ---- - dlls/ntdll/file.c | 6 +++++- - include/winternl.h | 5 +++++ - 2 files changed, 10 insertions(+), 1 deletion(-) - -diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index c1f5a7a..00b3ccd 100644 ---- a/dlls/ntdll/file.c -+++ b/dlls/ntdll/file.c -@@ -2625,8 +2625,12 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, - - if (!server_get_unix_fd( hFile, FILE_READ_DATA, &fd, &needs_close, NULL, NULL )) - { -- if (!unix_fd_avail( fd, &avail )) -+ NTSTATUS status = unix_fd_avail( fd, &avail ); -+ if (!status) - pli->ReadDataAvailable = min(avail, reply->outsize); /* FIXME */ -+ else if (status == STATUS_PIPE_BROKEN) -+ pli->NamedPipeState = FILE_PIPE_CLOSING_STATE; -+ - if (needs_close) close( fd ); - } - } -diff --git a/include/winternl.h b/include/winternl.h -index 0489395..41abff8 100644 ---- a/include/winternl.h -+++ b/include/winternl.h -@@ -713,6 +713,11 @@ typedef struct _FILE_REPARSE_POINT_INFORMATION { - ULONG Tag; - } FILE_REPARSE_POINT_INFORMATION, *PFILE_REPARSE_POINT_INFORMATION; - -+#define FILE_PIPE_DISCONNECTED_STATE 0x01 -+#define FILE_PIPE_LISTENING_STATE 0x02 -+#define FILE_PIPE_CONNECTED_STATE 0x03 -+#define FILE_PIPE_CLOSING_STATE 0x04 -+ - typedef struct _FILE_ALL_INFORMATION { - FILE_BASIC_INFORMATION BasicInformation; - FILE_STANDARD_INFORMATION StandardInformation; --- -2.8.0 - diff --git a/patches/kernel32-Named_Pipe/0019-server-Return-correct-error-codes-for-NtWriteFile-wh.patch b/patches/kernel32-Named_Pipe/0019-server-Return-correct-error-codes-for-NtWriteFile-wh.patch deleted file mode 100644 index a778a07e..00000000 --- a/patches/kernel32-Named_Pipe/0019-server-Return-correct-error-codes-for-NtWriteFile-wh.patch +++ /dev/null @@ -1,151 +0,0 @@ -From bb9a6f2fb4431cb18e2a835808c02156bbd9d709 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sat, 6 Jun 2015 01:21:05 +0200 -Subject: server: Return correct error codes for NtWriteFile when pipes are - closed without disconnecting. - ---- - dlls/kernel32/tests/pipe.c | 2 +- - dlls/ntdll/file.c | 3 +++ - server/named_pipe.c | 43 +++++++++++++++++++++++++++++++++++++++++-- - server/protocol.def | 1 + - 4 files changed, 46 insertions(+), 3 deletions(-) - -diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c -index ba365ed666..23f1a5f5f5 100644 ---- a/dlls/kernel32/tests/pipe.c -+++ b/dlls/kernel32/tests/pipe.c -@@ -1917,7 +1917,7 @@ static void test_CloseHandle(void) - SetLastError(0xdeadbeef); - ret = WriteFile(hfile, testdata, sizeof(testdata), &numbytes, NULL); - ok(!ret, "WriteFile unexpectedly succeeded\n"); -- todo_wine ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %u\n", GetLastError()); -+ ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %u\n", GetLastError()); - - CloseHandle(hfile); - -diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index 98a699e48f..25f59761cf 100644 ---- a/dlls/ntdll/file.c -+++ b/dlls/ntdll/file.c -@@ -1235,6 +1235,9 @@ static NTSTATUS write_unix_fd(int fd, const char *buf, ULONG *total, ULONG lengt - return STATUS_SUCCESS; - else if (errno == EFAULT) - return STATUS_INVALID_USER_BUFFER; -+ else if (type == FD_TYPE_PIPE && (errno == EPIPE || errno == ECONNRESET)) -+ return (get_pipe_flags( fd ) & NAMED_PIPE_CLOSED_HANDLE) ? -+ STATUS_PIPE_EMPTY : STATUS_PIPE_DISCONNECTED; - return FILE_GetNtStatus(); - } - } -diff --git a/server/named_pipe.c b/server/named_pipe.c -index d310740165..2775fcab51 100644 ---- a/server/named_pipe.c -+++ b/server/named_pipe.c -@@ -129,6 +129,8 @@ struct named_pipe_device - struct namespace *pipes; /* named pipe namespace */ - }; - -+static inline int messagemode_flags( int flags ); -+ - static void named_pipe_dump( struct object *obj, int verbose ); - static unsigned int named_pipe_map_access( struct object *obj, unsigned int access ); - static int named_pipe_link_name( struct object *obj, struct object_name *name, struct object *parent ); -@@ -167,6 +169,7 @@ static void pipe_end_reselect_async( struct fd *fd, struct async_queue *queue ); - /* server end functions */ - static void pipe_server_dump( struct object *obj, int verbose ); - static struct fd *pipe_server_get_fd( struct object *obj ); -+static int pipe_server_close_handle( struct object *obj, struct process *process, obj_handle_t handle ); - static void pipe_server_destroy( struct object *obj); - static obj_handle_t pipe_server_flush( struct fd *fd, struct async *async, int blocking ); - static enum server_fd_type pipe_server_get_fd_type( struct fd *fd ); -@@ -192,7 +195,7 @@ static const struct object_ops pipe_server_ops = - NULL, /* unlink_name */ - no_open_file, /* open_file */ - no_alloc_handle, /* alloc_handle */ -- fd_close_handle, /* close_handle */ -+ pipe_server_close_handle, /* close_handle */ - pipe_server_destroy /* destroy */ - }; - -@@ -213,6 +216,7 @@ static const struct fd_ops pipe_server_fd_ops = - static void pipe_client_dump( struct object *obj, int verbose ); - static int pipe_client_signaled( struct object *obj, struct wait_queue_entry *entry ); - static struct fd *pipe_client_get_fd( struct object *obj ); -+static int pipe_client_close_handle( struct object *obj, struct process *process, obj_handle_t handle ); - static void pipe_client_destroy( struct object *obj ); - static obj_handle_t pipe_client_flush( struct fd *fd, struct async *async, int blocking ); - static obj_handle_t pipe_client_ioctl( struct fd *fd, ioctl_code_t code, struct async *async, -@@ -238,7 +242,7 @@ static const struct object_ops pipe_client_ops = - NULL, /* unlink_name */ - no_open_file, /* open_file */ - no_alloc_handle, /* alloc_handle */ -- fd_close_handle, /* close_handle */ -+ pipe_client_close_handle, /* close_handle */ - pipe_client_destroy /* destroy */ - }; - -@@ -482,6 +486,23 @@ static void pipe_end_destroy( struct pipe_end *pipe_end ) - free_async_queue( pipe_end->write_q ); - } - -+static int pipe_server_close_handle( struct object *obj, struct process *process, obj_handle_t handle ) -+{ -+#ifdef __linux__ -+ struct pipe_server *server = (struct pipe_server *)obj; -+ struct pipe_client *client = server->client; -+ int unix_fd; -+ -+ assert( obj->ops == &pipe_server_ops ); -+ if (obj->handle_count == 1 && client && client->pipe_end.fd && (unix_fd = get_unix_fd( client->pipe_end.fd )) != -1) -+ { -+ /* set the NAMED_PIPE_CLOSED_HANDLE flag, to distinguish disconnect / closing pipe */ -+ fcntl( unix_fd, F_SETSIG, messagemode_flags( client->pipe_end.flags ) | NAMED_PIPE_CLOSED_HANDLE ); -+ } -+#endif -+ return 1; -+} -+ - static void pipe_server_destroy( struct object *obj) - { - struct pipe_server *server = (struct pipe_server *)obj; -@@ -511,6 +532,24 @@ static void pipe_server_destroy( struct object *obj) - release_object( server->pipe ); - } - -+static int pipe_client_close_handle( struct object *obj, struct process *process, obj_handle_t handle ) -+{ -+#ifdef __linux__ -+ struct pipe_client *client = (struct pipe_client *)obj; -+ struct pipe_server *server = client->server; -+ int unix_fd; -+ -+ assert( obj->ops == &pipe_client_ops ); -+ if (obj->handle_count == 1 && server && server->pipe_end.fd && -+ server->state != ps_wait_connect && (unix_fd = get_unix_fd( server->pipe_end.fd )) != -1) -+ { -+ /* set the NAMED_PIPE_CLOSED_HANDLE flag, to distinguish disconnect / closing pipe */ -+ fcntl( unix_fd, F_SETSIG, messagemode_flags( server->pipe_end.flags ) | NAMED_PIPE_CLOSED_HANDLE ); -+ } -+#endif -+ return 1; -+} -+ - static void pipe_client_destroy( struct object *obj) - { - struct pipe_client *client = (struct pipe_client *)obj; -diff --git a/server/protocol.def b/server/protocol.def -index 341a6f6085..9769bb9e7b 100644 ---- a/server/protocol.def -+++ b/server/protocol.def -@@ -2431,6 +2431,7 @@ enum message_type - #define NAMED_PIPE_MESSAGE_STREAM_WRITE 0x0001 - #define NAMED_PIPE_MESSAGE_STREAM_READ 0x0002 - #define NAMED_PIPE_NONBLOCKING_MODE 0x0004 -+#define NAMED_PIPE_CLOSED_HANDLE 0x0008 - #define NAMED_PIPE_SERVER_END 0x8000 - - /* Get named pipe information by handle */ --- -2.11.0 - diff --git a/patches/kernel32-Named_Pipe/0020-ntdll-Pre-cache-file-descriptors-after-opening-a-fil.patch b/patches/kernel32-Named_Pipe/0020-ntdll-Pre-cache-file-descriptors-after-opening-a-fil.patch deleted file mode 100644 index 35bd1722..00000000 --- a/patches/kernel32-Named_Pipe/0020-ntdll-Pre-cache-file-descriptors-after-opening-a-fil.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 91fcadbc95667961575d55cad728f7151a8766d7 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sat, 6 Jun 2015 01:21:05 +0200 -Subject: ntdll: Pre-cache file descriptors after opening a file. - ---- - dlls/kernel32/tests/pipe.c | 6 +++--- - dlls/ntdll/file.c | 12 +++++++++++- - 2 files changed, 14 insertions(+), 4 deletions(-) - -diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c -index 16a0aab928a..f0e2180ec83 100644 ---- a/dlls/kernel32/tests/pipe.c -+++ b/dlls/kernel32/tests/pipe.c -@@ -1946,7 +1946,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()); - - ret = GetNamedPipeHandleStateA(hfile, &state, NULL, NULL, NULL, NULL, 0); - ok(ret, "GetNamedPipeHandleState failed with %u\n", GetLastError()); -@@ -1957,12 +1957,12 @@ 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); - ok(!ret, "WriteFile unexpectedly succeeded\n"); -- todo_wine ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %u\n", GetLastError()); -+ ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %u\n", GetLastError()); - - CloseHandle(hfile); - -diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index e9efa92d60a..3b30c741433 100644 ---- a/dlls/ntdll/file.c -+++ b/dlls/ntdll/file.c -@@ -214,7 +214,17 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT - *handle = wine_server_ptr_handle( reply->handle ); - } - SERVER_END_REQ; -- if (io->u.Status == STATUS_SUCCESS) io->Information = FILE_OPENED; -+ if (io->u.Status == STATUS_SUCCESS) -+ { -+ /* pre-cache the file descriptor. this is necessary because the fd cannot be -+ * acquired anymore after one end of the pipe has been closed - see kernel32/pipe -+ * tests. */ -+ int unix_fd, needs_close; -+ int ret = server_get_unix_fd( *handle, 0, &unix_fd, &needs_close, NULL, NULL ); -+ if (!ret && needs_close) close( unix_fd ); -+ io->Information = FILE_OPENED; -+ } -+ - return io->u.Status; - } - --- -2.11.0 - diff --git a/patches/kernel32-Named_Pipe/0021-server-Do-not-allow-to-queue-async-operation-for-bro.patch b/patches/kernel32-Named_Pipe/0021-server-Do-not-allow-to-queue-async-operation-for-bro.patch deleted file mode 100644 index 5fcdee92..00000000 --- a/patches/kernel32-Named_Pipe/0021-server-Do-not-allow-to-queue-async-operation-for-bro.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 657d43d3027ea116d3348542eac23d1d915258f0 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Wed, 24 Feb 2016 15:45:09 +0100 -Subject: server: Do not allow to queue async operation for broken pipes. - ---- - server/named_pipe.c | 16 ++++++++++++++-- - 1 file changed, 14 insertions(+), 2 deletions(-) - -diff --git a/server/named_pipe.c b/server/named_pipe.c -index 2775fcab51..3542c91b4a 100644 ---- a/server/named_pipe.c -+++ b/server/named_pipe.c -@@ -811,8 +811,20 @@ static obj_handle_t pipe_end_write( struct fd *fd, struct async *async, int bloc - static void pipe_end_queue_async( struct fd *fd, struct async *async, int type, int count ) - { - struct pipe_end *pipe_end = get_fd_user( fd ); -- if (use_server_io( pipe_end )) no_fd_queue_async( fd, async, type, count ); -- else default_fd_queue_async( fd, async, type, count ); -+ -+ if (use_server_io( pipe_end )) -+ { -+ no_fd_queue_async( fd, async, type, count ); -+ return; -+ } -+ -+ if (!pipe_end->connection) -+ { -+ set_error( STATUS_PIPE_BROKEN ); -+ return; -+ } -+ -+ default_fd_queue_async( fd, async, type, count ); - } - - static void pipe_end_reselect_async( struct fd *fd, struct async_queue *queue ) --- -2.11.0 - diff --git a/patches/kernel32-Named_Pipe/definition b/patches/kernel32-Named_Pipe/definition deleted file mode 100644 index c42892fb..00000000 --- a/patches/kernel32-Named_Pipe/definition +++ /dev/null @@ -1,6 +0,0 @@ -# Fixes: [17195] Support for named pipe message mode (Linux only) -# Fixes: Improve ReadDataAvailable handling in FilePipeLocalInformation class -# Fixes: Set NamedPipeState to FILE_PIPE_CLOSING_STATE on broken pipe in NtQueryInformationFile -# Fixes: Return proper status codes when NtReadFile/NtWriteFile is called on closed (but not disconnected) pipe -Depends: server-Desktop_Refcount -Disabled: true