From a08cd0cbb65ca0c53857c35e40f6d3d910119b22 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
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 056f95b..a252bc8 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;
@@ -109,6 +119,33 @@ static BOOL RpcReadFile(HANDLE hFile, LPVOID buffer, DWORD bytesToRead, LPDWORD
     return (BOOL)rpcargs.returnValue;
 }
 
+/* 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;
@@ -118,6 +155,7 @@ static void test_CreateNamedPipe(int pipemode)
     char ibuf[32], *pbuf;
     DWORD written;
     DWORD readden;
+    DWORD leftmsg;
     DWORD avail;
     DWORD lpmode;
     BOOL ret;
@@ -232,9 +270,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");
@@ -447,6 +497,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");
@@ -460,6 +520,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
@@ -468,6 +538,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");
@@ -480,11 +558,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));
@@ -492,6 +586,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");
@@ -505,6 +609,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
@@ -513,6 +627,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");
@@ -525,11 +647,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.1.3

