1 /* 2 * Unit tests for named pipe functions in Wine 3 * 4 * Copyright (c) 2002 Dan Kegel 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include <stdarg.h> 22 #include <stdio.h> 23 24 #include "ntstatus.h" 25 #define WIN32_NO_STATUS 26 #include "windef.h" 27 #include "winbase.h" 28 #include "winternl.h" 29 #include "winioctl.h" 30 #include "wine/test.h" 31 32 #define PIPENAME "\\\\.\\PiPe\\tests_pipe.c" 33 #define PIPENAME_SPECIAL "\\\\.\\PiPe\\tests->pipe.c" 34 35 #define NB_SERVER_LOOPS 8 36 37 static HANDLE alarm_event; 38 static BOOL (WINAPI *pDuplicateTokenEx)(HANDLE,DWORD,LPSECURITY_ATTRIBUTES, 39 SECURITY_IMPERSONATION_LEVEL,TOKEN_TYPE,PHANDLE); 40 static DWORD (WINAPI *pQueueUserAPC)(PAPCFUNC pfnAPC, HANDLE hThread, ULONG_PTR dwData); 41 static BOOL (WINAPI *pCancelIoEx)(HANDLE handle, LPOVERLAPPED lpOverlapped); 42 43 static BOOL user_apc_ran; 44 static void CALLBACK user_apc(ULONG_PTR param) 45 { 46 user_apc_ran = TRUE; 47 } 48 49 50 enum rpcThreadOp 51 { 52 RPC_READFILE 53 }; 54 55 struct rpcThreadArgs 56 { 57 ULONG_PTR returnValue; 58 DWORD lastError; 59 enum rpcThreadOp op; 60 ULONG_PTR args[5]; 61 }; 62 63 static DWORD CALLBACK rpcThreadMain(LPVOID arg) 64 { 65 struct rpcThreadArgs *rpcargs = (struct rpcThreadArgs *)arg; 66 if (winetest_debug > 1) trace("rpcThreadMain starting\n"); 67 SetLastError( rpcargs->lastError ); 68 69 switch (rpcargs->op) 70 { 71 case RPC_READFILE: 72 rpcargs->returnValue = (ULONG_PTR)ReadFile( (HANDLE)rpcargs->args[0], /* hFile */ 73 (LPVOID)rpcargs->args[1], /* buffer */ 74 (DWORD)rpcargs->args[2], /* bytesToRead */ 75 (LPDWORD)rpcargs->args[3], /* bytesRead */ 76 (LPOVERLAPPED)rpcargs->args[4] ); /* overlapped */ 77 break; 78 79 default: 80 SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); 81 rpcargs->returnValue = 0; 82 break; 83 } 84 85 rpcargs->lastError = GetLastError(); 86 if (winetest_debug > 1) trace("rpcThreadMain returning\n"); 87 return 0; 88 } 89 90 /* Runs ReadFile(...) from a different thread */ 91 static BOOL RpcReadFile(HANDLE hFile, LPVOID buffer, DWORD bytesToRead, LPDWORD bytesRead, LPOVERLAPPED overlapped) 92 { 93 struct rpcThreadArgs rpcargs; 94 HANDLE thread; 95 DWORD threadId, ret; 96 97 rpcargs.returnValue = 0; 98 rpcargs.lastError = GetLastError(); 99 rpcargs.op = RPC_READFILE; 100 rpcargs.args[0] = (ULONG_PTR)hFile; 101 rpcargs.args[1] = (ULONG_PTR)buffer; 102 rpcargs.args[2] = (ULONG_PTR)bytesToRead; 103 rpcargs.args[3] = (ULONG_PTR)bytesRead; 104 rpcargs.args[4] = (ULONG_PTR)overlapped; 105 106 thread = CreateThread(NULL, 0, rpcThreadMain, (void *)&rpcargs, 0, &threadId); 107 ok(thread != NULL, "CreateThread failed. %d\n", GetLastError()); 108 ret = WaitForSingleObject(thread, INFINITE); 109 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed with %d.\n", GetLastError()); 110 CloseHandle(thread); 111 112 SetLastError(rpcargs.lastError); 113 return (BOOL)rpcargs.returnValue; 114 } 115 116 #define test_not_signaled(h) _test_not_signaled(__LINE__,h) 117 static void _test_not_signaled(unsigned line, HANDLE handle) 118 { 119 DWORD res = WaitForSingleObject(handle, 0); 120 ok_(__FILE__,line)(res == WAIT_TIMEOUT, "WaitForSingleObject returned %u (%u)\n", res, GetLastError()); 121 } 122 123 #define test_signaled(h) _test_signaled(__LINE__,h) 124 static void _test_signaled(unsigned line, HANDLE handle) 125 { 126 DWORD res = WaitForSingleObject(handle, 0); 127 ok_(__FILE__,line)(res == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", res); 128 } 129 130 #define test_pipe_info(a,b,c,d,e) _test_pipe_info(__LINE__,a,b,c,d,e) 131 static void _test_pipe_info(unsigned line, HANDLE pipe, DWORD ex_flags, DWORD ex_out_buf_size, DWORD ex_in_buf_size, DWORD ex_max_instances) 132 { 133 DWORD flags = 0xdeadbeef, out_buf_size = 0xdeadbeef, in_buf_size = 0xdeadbeef, max_instances = 0xdeadbeef; 134 BOOL res; 135 136 res = GetNamedPipeInfo(pipe, &flags, &out_buf_size, &in_buf_size, &max_instances); 137 ok_(__FILE__,line)(res, "GetNamedPipeInfo failed: %x\n", res); 138 ok_(__FILE__,line)(flags == ex_flags, "flags = %x, expected %x\n", flags, ex_flags); 139 ok_(__FILE__,line)(out_buf_size == ex_out_buf_size, "out_buf_size = %x, expected %u\n", out_buf_size, ex_out_buf_size); 140 ok_(__FILE__,line)(in_buf_size == ex_in_buf_size, "in_buf_size = %x, expected %u\n", in_buf_size, ex_in_buf_size); 141 ok_(__FILE__,line)(max_instances == ex_max_instances, "max_instances = %x, expected %u\n", max_instances, ex_max_instances); 142 } 143 144 static void test_CreateNamedPipe(int pipemode) 145 { 146 HANDLE hnp; 147 HANDLE hFile; 148 static const char obuf[] = "Bit Bucket"; 149 static const char obuf2[] = "More bits"; 150 char ibuf[32], *pbuf; 151 DWORD written; 152 DWORD readden; 153 DWORD avail; 154 DWORD left; 155 DWORD lpmode; 156 BOOL ret; 157 158 if (pipemode == PIPE_TYPE_BYTE) 159 trace("test_CreateNamedPipe starting in byte mode\n"); 160 else 161 trace("test_CreateNamedPipe starting in message mode\n"); 162 163 /* Wait for nonexistent pipe */ 164 ret = WaitNamedPipeA(PIPENAME, 2000); 165 ok(ret == 0, "WaitNamedPipe returned %d for nonexistent pipe\n", ret); 166 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError()); 167 168 /* Bad parameter checks */ 169 hnp = CreateNamedPipeA("not a named pipe", PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT, 170 /* nMaxInstances */ 1, 171 /* nOutBufSize */ 1024, 172 /* nInBufSize */ 1024, 173 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 174 /* lpSecurityAttrib */ NULL); 175 ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_NAME, 176 "CreateNamedPipe should fail if name doesn't start with \\\\.\\pipe\n"); 177 178 if (pipemode == PIPE_TYPE_BYTE) 179 { 180 /* Bad parameter checks */ 181 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE, 182 /* nMaxInstances */ 1, 183 /* nOutBufSize */ 1024, 184 /* nInBufSize */ 1024, 185 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 186 /* lpSecurityAttrib */ NULL); 187 ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER, 188 "CreateNamedPipe should fail with PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE\n"); 189 } 190 191 hnp = CreateNamedPipeA(NULL, 192 PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT, 193 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); 194 ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND, 195 "CreateNamedPipe should fail if name is NULL\n"); 196 197 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 198 ok(hFile == INVALID_HANDLE_VALUE 199 && GetLastError() == ERROR_FILE_NOT_FOUND, 200 "connecting to nonexistent named pipe should fail with ERROR_FILE_NOT_FOUND\n"); 201 202 /* Functional checks */ 203 204 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT, 205 /* nMaxInstances */ 1, 206 /* nOutBufSize */ 1024, 207 /* nInBufSize */ 1024, 208 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 209 /* lpSecurityAttrib */ NULL); 210 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 211 test_signaled(hnp); 212 213 ret = PeekNamedPipe(hnp, NULL, 0, NULL, &readden, NULL); 214 todo_wine 215 ok(!ret && GetLastError() == ERROR_BAD_PIPE, "PeekNamedPipe returned %x (%u)\n", 216 ret, GetLastError()); 217 218 ret = WaitNamedPipeA(PIPENAME, 2000); 219 ok(ret, "WaitNamedPipe failed (%d)\n", GetLastError()); 220 221 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 222 ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed (%d)\n", GetLastError()); 223 224 ok(!WaitNamedPipeA(PIPENAME, 100), "WaitNamedPipe succeeded\n"); 225 226 ok(GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %u\n", GetLastError()); 227 228 /* Test ConnectNamedPipe() in both directions */ 229 ok(!ConnectNamedPipe(hnp, NULL), "ConnectNamedPipe(server) succeeded\n"); 230 ok(GetLastError() == ERROR_PIPE_CONNECTED, "expected ERROR_PIPE_CONNECTED, got %u\n", GetLastError()); 231 ok(!ConnectNamedPipe(hFile, NULL), "ConnectNamedPipe(client) succeeded\n"); 232 ok(GetLastError() == ERROR_INVALID_FUNCTION, "expected ERROR_INVALID_FUNCTION, got %u\n", GetLastError()); 233 234 /* don't try to do i/o if one side couldn't be opened, as it hangs */ 235 if (hFile != INVALID_HANDLE_VALUE) { 236 HANDLE hFile2; 237 238 /* Make sure we can read and write a few bytes in both directions */ 239 memset(ibuf, 0, sizeof(ibuf)); 240 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile\n"); 241 ok(written == sizeof(obuf), "write file len\n"); 242 ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 243 ok(readden == sizeof(obuf), "read got %d bytes\n", readden); 244 ok(memcmp(obuf, ibuf, written) == 0, "content check\n"); 245 246 memset(ibuf, 0, sizeof(ibuf)); 247 ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), "WriteFile\n"); 248 ok(written == sizeof(obuf2), "write file len\n"); 249 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 250 ok(readden == sizeof(obuf2), "read got %d bytes\n", readden); 251 ok(memcmp(obuf2, ibuf, written) == 0, "content check\n"); 252 253 /* Now the same again, but with an additional call to PeekNamedPipe */ 254 memset(ibuf, 0, sizeof(ibuf)); 255 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile\n"); 256 ok(written == sizeof(obuf), "write file len 1\n"); 257 ok(PeekNamedPipe(hFile, NULL, 0, NULL, &avail, &left), "Peek\n"); 258 ok(avail == sizeof(obuf), "peek 1 got %d bytes\n", avail); 259 if (pipemode == PIPE_TYPE_BYTE) 260 ok(left == 0, "peek 1 got %d bytes left\n", left); 261 else 262 ok(left == sizeof(obuf), "peek 1 got %d bytes left\n", left); 263 ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 264 ok(readden == sizeof(obuf), "read 1 got %d bytes\n", readden); 265 ok(memcmp(obuf, ibuf, written) == 0, "content 1 check\n"); 266 267 memset(ibuf, 0, sizeof(ibuf)); 268 ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), "WriteFile\n"); 269 ok(written == sizeof(obuf2), "write file len 2\n"); 270 ok(PeekNamedPipe(hnp, NULL, 0, NULL, &avail, &left), "Peek\n"); 271 ok(avail == sizeof(obuf2), "peek 2 got %d bytes\n", avail); 272 if (pipemode == PIPE_TYPE_BYTE) 273 ok(left == 0, "peek 2 got %d bytes left\n", left); 274 else 275 ok(left == sizeof(obuf2), "peek 2 got %d bytes left\n", left); 276 ok(PeekNamedPipe(hnp, (LPVOID)1, 0, NULL, &avail, &left), "Peek\n"); 277 ok(avail == sizeof(obuf2), "peek 2 got %d bytes\n", avail); 278 if (pipemode == PIPE_TYPE_BYTE) 279 ok(left == 0, "peek 2 got %d bytes left\n", left); 280 else 281 ok(left == sizeof(obuf2), "peek 2 got %d bytes left\n", left); 282 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 283 ok(readden == sizeof(obuf2), "read 2 got %d bytes\n", readden); 284 ok(memcmp(obuf2, ibuf, written) == 0, "content 2 check\n"); 285 286 /* Test how ReadFile behaves when the buffer is not big enough for the whole message */ 287 memset(ibuf, 0, sizeof(ibuf)); 288 ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), "WriteFile\n"); 289 ok(written == sizeof(obuf2), "write file len\n"); 290 ok(PeekNamedPipe(hFile, ibuf, 4, &readden, &avail, &left), "Peek\n"); 291 ok(readden == 4, "peek got %d bytes\n", readden); 292 ok(avail == sizeof(obuf2), "peek got %d bytes available\n", avail); 293 if (pipemode == PIPE_TYPE_BYTE) 294 ok(left == -4, "peek got %d bytes left\n", left); 295 else 296 ok(left == sizeof(obuf2)-4, "peek got %d bytes left\n", left); 297 ok(ReadFile(hFile, ibuf, 4, &readden, NULL), "ReadFile\n"); 298 ok(readden == 4, "read got %d bytes\n", readden); 299 ok(ReadFile(hFile, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile\n"); 300 ok(readden == sizeof(obuf2) - 4, "read got %d bytes\n", readden); 301 ok(memcmp(obuf2, ibuf, written) == 0, "content check\n"); 302 303 memset(ibuf, 0, sizeof(ibuf)); 304 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile\n"); 305 ok(written == sizeof(obuf), "write file len\n"); 306 ok(PeekNamedPipe(hnp, ibuf, 4, &readden, &avail, &left), "Peek\n"); 307 ok(readden == 4, "peek got %d bytes\n", readden); 308 ok(avail == sizeof(obuf), "peek got %d bytes available\n", avail); 309 if (pipemode == PIPE_TYPE_BYTE) 310 { 311 ok(left == -4, "peek got %d bytes left\n", left); 312 ok(ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile\n"); 313 } 314 else 315 { 316 ok(left == sizeof(obuf)-4, "peek got %d bytes left\n", left); 317 SetLastError(0xdeadbeef); 318 ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile\n"); 319 ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n"); 320 } 321 ok(readden == 4, "read got %d bytes\n", readden); 322 ok(ReadFile(hnp, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile\n"); 323 ok(readden == sizeof(obuf) - 4, "read got %d bytes\n", readden); 324 ok(memcmp(obuf, ibuf, written) == 0, "content check\n"); 325 326 /* Similar to above, but use a read buffer size small enough to read in three parts */ 327 memset(ibuf, 0, sizeof(ibuf)); 328 ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), "WriteFile\n"); 329 ok(written == sizeof(obuf2), "write file len\n"); 330 if (pipemode == PIPE_TYPE_BYTE) 331 { 332 ok(ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile\n"); 333 ok(readden == 4, "read got %d bytes\n", readden); 334 ok(ReadFile(hnp, ibuf + 4, 4, &readden, NULL), "ReadFile\n"); 335 } 336 else 337 { 338 SetLastError(0xdeadbeef); 339 ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile\n"); 340 ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n"); 341 ok(readden == 4, "read got %d bytes\n", readden); 342 SetLastError(0xdeadbeef); 343 ok(!ReadFile(hnp, ibuf + 4, 4, &readden, NULL), "ReadFile\n"); 344 ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n"); 345 } 346 ok(readden == 4, "read got %d bytes\n", readden); 347 ok(ReadFile(hnp, ibuf + 8, sizeof(ibuf) - 8, &readden, NULL), "ReadFile\n"); 348 ok(readden == sizeof(obuf2) - 8, "read got %d bytes\n", readden); 349 ok(memcmp(obuf2, ibuf, written) == 0, "content check\n"); 350 351 /* Test reading of multiple writes */ 352 memset(ibuf, 0, sizeof(ibuf)); 353 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile3a\n"); 354 ok(written == sizeof(obuf), "write file len 3a\n"); 355 ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), " WriteFile3b\n"); 356 ok(written == sizeof(obuf2), "write file len 3b\n"); 357 ok(PeekNamedPipe(hFile, ibuf, 4, &readden, &avail, &left), "Peek3\n"); 358 ok(readden == 4, "peek3 got %d bytes\n", readden); 359 if (pipemode == PIPE_TYPE_BYTE) 360 ok(left == -4, "peek3 got %d bytes left\n", left); 361 else 362 ok(left == sizeof(obuf)-4, "peek3 got %d bytes left\n", left); 363 ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes available\n", avail); 364 ok(PeekNamedPipe(hFile, ibuf, sizeof(ibuf), &readden, &avail, &left), "Peek3\n"); 365 if (pipemode == PIPE_TYPE_BYTE) { 366 ok(readden == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes\n", readden); 367 ok(left == (DWORD) -(sizeof(obuf) + sizeof(obuf2)), "peek3 got %d bytes left\n", left); 368 } 369 else 370 { 371 ok(readden == sizeof(obuf), "peek3 got %d bytes\n", readden); 372 ok(left == 0, "peek3 got %d bytes left\n", left); 373 } 374 ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes available\n", avail); 375 pbuf = ibuf; 376 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "pipe content 3a check\n"); 377 if (pipemode == PIPE_TYPE_BYTE && readden >= sizeof(obuf)+sizeof(obuf2)) { 378 pbuf += sizeof(obuf); 379 ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "pipe content 3b check\n"); 380 } 381 ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 382 ok(readden == sizeof(obuf) + sizeof(obuf2), "read 3 got %d bytes\n", readden); 383 pbuf = ibuf; 384 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 3a check\n"); 385 pbuf += sizeof(obuf); 386 ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "content 3b check\n"); 387 388 /* Multiple writes in the reverse direction */ 389 memset(ibuf, 0, sizeof(ibuf)); 390 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile4a\n"); 391 ok(written == sizeof(obuf), "write file len 4a\n"); 392 ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), " WriteFile4b\n"); 393 ok(written == sizeof(obuf2), "write file len 4b\n"); 394 ok(PeekNamedPipe(hnp, ibuf, 4, &readden, &avail, &left), "Peek3\n"); 395 ok(readden == 4, "peek3 got %d bytes\n", readden); 396 if (pipemode == PIPE_TYPE_BYTE) 397 ok(left == -4, "peek3 got %d bytes left\n", left); 398 else 399 ok(left == sizeof(obuf)-4, "peek3 got %d bytes left\n", left); 400 ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes available\n", avail); 401 ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, &left), "Peek4\n"); 402 if (pipemode == PIPE_TYPE_BYTE) { 403 ok(readden == sizeof(obuf) + sizeof(obuf2), "peek4 got %d bytes\n", readden); 404 ok(left == (DWORD) -(sizeof(obuf) + sizeof(obuf2)), "peek4 got %d bytes left\n", left); 405 } 406 else 407 { 408 ok(readden == sizeof(obuf), "peek4 got %d bytes\n", readden); 409 ok(left == 0, "peek4 got %d bytes left\n", left); 410 } 411 ok(avail == sizeof(obuf) + sizeof(obuf2), "peek4 got %d bytes available\n", avail); 412 pbuf = ibuf; 413 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "pipe content 4a check\n"); 414 if (pipemode == PIPE_TYPE_BYTE && readden >= sizeof(obuf)+sizeof(obuf2)) { 415 pbuf += sizeof(obuf); 416 ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "pipe content 4b check\n"); 417 } 418 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 419 if (pipemode == PIPE_TYPE_BYTE) { 420 ok(readden == sizeof(obuf) + sizeof(obuf2), "read 4 got %d bytes\n", readden); 421 } 422 else { 423 ok(readden == sizeof(obuf), "read 4 got %d bytes\n", readden); 424 } 425 pbuf = ibuf; 426 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 4a check\n"); 427 if (pipemode == PIPE_TYPE_BYTE) { 428 pbuf += sizeof(obuf); 429 ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "content 4b check\n"); 430 } 431 432 /* Test reading of multiple writes after a mode change 433 (CreateFile always creates a byte mode pipe) */ 434 lpmode = PIPE_READMODE_MESSAGE; 435 if (pipemode == PIPE_TYPE_BYTE) { 436 /* trying to change the client end of a byte pipe to message mode should fail */ 437 ok(!SetNamedPipeHandleState(hFile, &lpmode, NULL, NULL), "Change mode\n"); 438 } 439 else { 440 ok(SetNamedPipeHandleState(hFile, &lpmode, NULL, NULL), "Change mode\n"); 441 442 memset(ibuf, 0, sizeof(ibuf)); 443 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile5a\n"); 444 ok(written == sizeof(obuf), "write file len 3a\n"); 445 ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), " WriteFile5b\n"); 446 ok(written == sizeof(obuf2), "write file len 3b\n"); 447 ok(PeekNamedPipe(hFile, ibuf, sizeof(ibuf), &readden, &avail, &left), "Peek5\n"); 448 ok(readden == sizeof(obuf), "peek5 got %d bytes\n", readden); 449 ok(avail == sizeof(obuf) + sizeof(obuf2), "peek5 got %d bytes available\n", avail); 450 ok(left == 0, "peek5 got %d bytes left\n", left); 451 pbuf = ibuf; 452 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 5a check\n"); 453 ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 454 ok(readden == sizeof(obuf), "read 5 got %d bytes\n", readden); 455 pbuf = ibuf; 456 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 5a check\n"); 457 if (readden <= sizeof(obuf)) 458 ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 459 460 /* Multiple writes in the reverse direction */ 461 /* the write of obuf2 from write4 should still be in the buffer */ 462 ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek6a\n"); 463 ok(readden == sizeof(obuf2), "peek6a got %d bytes\n", readden); 464 ok(avail == sizeof(obuf2), "peek6a got %d bytes available\n", avail); 465 if (avail > 0) { 466 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 467 ok(readden == sizeof(obuf2), "read 6a got %d bytes\n", readden); 468 pbuf = ibuf; 469 ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "content 6a check\n"); 470 } 471 memset(ibuf, 0, sizeof(ibuf)); 472 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile6a\n"); 473 ok(written == sizeof(obuf), "write file len 6a\n"); 474 ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), " WriteFile6b\n"); 475 ok(written == sizeof(obuf2), "write file len 6b\n"); 476 ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek6\n"); 477 ok(readden == sizeof(obuf), "peek6 got %d bytes\n", readden); 478 479 ok(avail == sizeof(obuf) + sizeof(obuf2), "peek6b got %d bytes available\n", avail); 480 pbuf = ibuf; 481 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 6a check\n"); 482 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 483 ok(readden == sizeof(obuf), "read 6b got %d bytes\n", readden); 484 pbuf = ibuf; 485 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 6a check\n"); 486 if (readden <= sizeof(obuf)) 487 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 488 489 /* Test how ReadFile behaves when the buffer is not big enough for the whole message */ 490 memset(ibuf, 0, sizeof(ibuf)); 491 ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), "WriteFile 7\n"); 492 ok(written == sizeof(obuf2), "write file len 7\n"); 493 SetLastError(0xdeadbeef); 494 ok(!ReadFile(hFile, ibuf, 4, &readden, NULL), "ReadFile 7\n"); 495 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 7\n"); 496 ok(readden == 4, "read got %d bytes 7\n", readden); 497 ok(ReadFile(hFile, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile 7\n"); 498 ok(readden == sizeof(obuf2) - 4, "read got %d bytes 7\n", readden); 499 ok(memcmp(obuf2, ibuf, written) == 0, "content check 7\n"); 500 501 memset(ibuf, 0, sizeof(ibuf)); 502 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile 8\n"); 503 ok(written == sizeof(obuf), "write file len 8\n"); 504 SetLastError(0xdeadbeef); 505 ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile 8\n"); 506 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 8\n"); 507 ok(readden == 4, "read got %d bytes 8\n", readden); 508 ok(ReadFile(hnp, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile 8\n"); 509 ok(readden == sizeof(obuf) - 4, "read got %d bytes 8\n", readden); 510 ok(memcmp(obuf, ibuf, written) == 0, "content check 8\n"); 511 512 /* The following test shows that when doing a partial read of a message, the rest 513 * is still in the pipe, and can be received from a second thread. This shows 514 * especially that the content is _not_ stored in thread-local-storage until it is 515 * completely transmitted. The same method works even across multiple processes. */ 516 memset(ibuf, 0, sizeof(ibuf)); 517 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile 9\n"); 518 ok(written == sizeof(obuf), "write file len 9\n"); 519 ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), "WriteFile 9\n"); 520 ok(written == sizeof(obuf2), "write file len 9\n"); 521 SetLastError(0xdeadbeef); 522 ok(!ReadFile(hFile, ibuf, 4, &readden, NULL), "ReadFile 9\n"); 523 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n"); 524 ok(readden == 4, "read got %d bytes 9\n", readden); 525 SetLastError(0xdeadbeef); 526 ret = RpcReadFile(hFile, ibuf + 4, 4, &readden, NULL); 527 ok(!ret, "RpcReadFile 9\n"); 528 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n"); 529 ok(readden == 4, "read got %d bytes 9\n", readden); 530 ret = RpcReadFile(hFile, ibuf + 8, sizeof(ibuf), &readden, NULL); 531 ok(ret, "RpcReadFile 9\n"); 532 ok(readden == sizeof(obuf) - 8, "read got %d bytes 9\n", readden); 533 ok(memcmp(obuf, ibuf, sizeof(obuf)) == 0, "content check 9\n"); 534 if (readden <= sizeof(obuf) - 8) /* blocks forever if second part was already received */ 535 { 536 memset(ibuf, 0, sizeof(ibuf)); 537 SetLastError(0xdeadbeef); 538 ret = RpcReadFile(hFile, ibuf, 4, &readden, NULL); 539 ok(!ret, "RpcReadFile 9\n"); 540 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n"); 541 ok(readden == 4, "read got %d bytes 9\n", readden); 542 SetLastError(0xdeadbeef); 543 ok(!ReadFile(hFile, ibuf + 4, 4, &readden, NULL), "ReadFile 9\n"); 544 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n"); 545 ok(readden == 4, "read got %d bytes 9\n", readden); 546 ret = RpcReadFile(hFile, ibuf + 8, sizeof(ibuf), &readden, NULL); 547 ok(ret, "RpcReadFile 9\n"); 548 ok(readden == sizeof(obuf2) - 8, "read got %d bytes 9\n", readden); 549 ok(memcmp(obuf2, ibuf, sizeof(obuf2)) == 0, "content check 9\n"); 550 } 551 552 /* Now the reverse direction */ 553 memset(ibuf, 0, sizeof(ibuf)); 554 ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), "WriteFile 10\n"); 555 ok(written == sizeof(obuf2), "write file len 10\n"); 556 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile 10\n"); 557 ok(written == sizeof(obuf), "write file len 10\n"); 558 SetLastError(0xdeadbeef); 559 ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile 10\n"); 560 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n"); 561 ok(readden == 4, "read got %d bytes 10\n", readden); 562 SetLastError(0xdeadbeef); 563 ret = RpcReadFile(hnp, ibuf + 4, 4, &readden, NULL); 564 ok(!ret, "RpcReadFile 10\n"); 565 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n"); 566 ok(readden == 4, "read got %d bytes 10\n", readden); 567 ret = RpcReadFile(hnp, ibuf + 8, sizeof(ibuf), &readden, NULL); 568 ok(ret, "RpcReadFile 10\n"); 569 ok(readden == sizeof(obuf2) - 8, "read got %d bytes 10\n", readden); 570 ok(memcmp(obuf2, ibuf, sizeof(obuf2)) == 0, "content check 10\n"); 571 if (readden <= sizeof(obuf2) - 8) /* blocks forever if second part was already received */ 572 { 573 memset(ibuf, 0, sizeof(ibuf)); 574 SetLastError(0xdeadbeef); 575 ret = RpcReadFile(hnp, ibuf, 4, &readden, NULL); 576 ok(!ret, "RpcReadFile 10\n"); 577 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n"); 578 ok(readden == 4, "read got %d bytes 10\n", readden); 579 SetLastError(0xdeadbeef); 580 ok(!ReadFile(hnp, ibuf + 4, 4, &readden, NULL), "ReadFile 10\n"); 581 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n"); 582 ok(readden == 4, "read got %d bytes 10\n", readden); 583 ret = RpcReadFile(hnp, ibuf + 8, sizeof(ibuf), &readden, NULL); 584 ok(ret, "RpcReadFile 10\n"); 585 ok(readden == sizeof(obuf) - 8, "read got %d bytes 10\n", readden); 586 ok(memcmp(obuf, ibuf, sizeof(obuf)) == 0, "content check 10\n"); 587 } 588 589 } 590 591 /* Picky conformance tests */ 592 593 /* Verify that you can't connect to pipe again 594 * until server calls DisconnectNamedPipe+ConnectNamedPipe 595 * or creates a new pipe 596 * case 1: other client not yet closed 597 */ 598 hFile2 = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 599 ok(hFile2 == INVALID_HANDLE_VALUE, 600 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n"); 601 ok(GetLastError() == ERROR_PIPE_BUSY, 602 "connecting to named pipe before other client closes should fail with ERROR_PIPE_BUSY\n"); 603 604 ok(CloseHandle(hFile), "CloseHandle\n"); 605 606 /* case 2: other client already closed */ 607 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 608 ok(hFile == INVALID_HANDLE_VALUE, 609 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n"); 610 ok(GetLastError() == ERROR_PIPE_BUSY, 611 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail with ERROR_PIPE_BUSY\n"); 612 613 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n"); 614 615 /* case 3: server has called DisconnectNamedPipe but not ConnectNamed Pipe */ 616 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 617 ok(hFile == INVALID_HANDLE_VALUE, 618 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n"); 619 ok(GetLastError() == ERROR_PIPE_BUSY, 620 "connecting to named pipe after other client closes but before ConnectNamedPipe should fail with ERROR_PIPE_BUSY\n"); 621 622 /* to be complete, we'd call ConnectNamedPipe here and loop, 623 * but by default that's blocking, so we'd either have 624 * to turn on the uncommon nonblocking mode, or 625 * use another thread. 626 */ 627 } 628 629 ok(CloseHandle(hnp), "CloseHandle\n"); 630 631 hnp = CreateNamedPipeA(PIPENAME_SPECIAL, PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT, 632 /* nMaxInstances */ 1, 633 /* nOutBufSize */ 1024, 634 /* nInBufSize */ 1024, 635 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 636 /* lpSecurityAttrib */ NULL); 637 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe with special characters failed\n"); 638 ok(CloseHandle(hnp), "CloseHandle\n"); 639 640 if (winetest_debug > 1) trace("test_CreateNamedPipe returning\n"); 641 } 642 643 static void test_CreateNamedPipe_instances_must_match(void) 644 { 645 HANDLE hnp, hnp2; 646 647 /* Check no mismatch */ 648 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 649 /* nMaxInstances */ 2, 650 /* nOutBufSize */ 1024, 651 /* nInBufSize */ 1024, 652 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 653 /* lpSecurityAttrib */ NULL); 654 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 655 656 hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 657 /* nMaxInstances */ 2, 658 /* nOutBufSize */ 1024, 659 /* nInBufSize */ 1024, 660 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 661 /* lpSecurityAttrib */ NULL); 662 ok(hnp2 != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 663 664 ok(CloseHandle(hnp), "CloseHandle\n"); 665 ok(CloseHandle(hnp2), "CloseHandle\n"); 666 667 /* Check nMaxInstances */ 668 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 669 /* nMaxInstances */ 1, 670 /* nOutBufSize */ 1024, 671 /* nInBufSize */ 1024, 672 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 673 /* lpSecurityAttrib */ NULL); 674 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 675 676 hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 677 /* nMaxInstances */ 1, 678 /* nOutBufSize */ 1024, 679 /* nInBufSize */ 1024, 680 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 681 /* lpSecurityAttrib */ NULL); 682 ok(hnp2 == INVALID_HANDLE_VALUE 683 && GetLastError() == ERROR_PIPE_BUSY, "nMaxInstances not obeyed\n"); 684 685 ok(CloseHandle(hnp), "CloseHandle\n"); 686 687 /* Check PIPE_ACCESS_* */ 688 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 689 /* nMaxInstances */ 2, 690 /* nOutBufSize */ 1024, 691 /* nInBufSize */ 1024, 692 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 693 /* lpSecurityAttrib */ NULL); 694 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 695 696 hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_WAIT, 697 /* nMaxInstances */ 2, 698 /* nOutBufSize */ 1024, 699 /* nInBufSize */ 1024, 700 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 701 /* lpSecurityAttrib */ NULL); 702 ok(hnp2 == INVALID_HANDLE_VALUE 703 && GetLastError() == ERROR_ACCESS_DENIED, "PIPE_ACCESS_* mismatch allowed\n"); 704 705 ok(CloseHandle(hnp), "CloseHandle\n"); 706 707 /* check everything else */ 708 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 709 /* nMaxInstances */ 4, 710 /* nOutBufSize */ 1024, 711 /* nInBufSize */ 1024, 712 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 713 /* lpSecurityAttrib */ NULL); 714 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 715 716 hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE, 717 /* nMaxInstances */ 3, 718 /* nOutBufSize */ 102, 719 /* nInBufSize */ 24, 720 /* nDefaultWait */ 1234, 721 /* lpSecurityAttrib */ NULL); 722 ok(hnp2 != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 723 724 ok(CloseHandle(hnp), "CloseHandle\n"); 725 ok(CloseHandle(hnp2), "CloseHandle\n"); 726 } 727 728 static void test_ReadFile(void) 729 { 730 HANDLE server, client; 731 OVERLAPPED overlapped; 732 DWORD size; 733 BOOL res; 734 735 static char buf[512]; 736 737 server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, 738 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 739 1, 1024, 1024, NMPWAIT_WAIT_FOREVER, NULL); 740 ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError()); 741 742 client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, 743 OPEN_EXISTING, 0, 0); 744 ok(client != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError()); 745 746 ok(WriteFile(client, buf, sizeof(buf), &size, NULL), "WriteFile\n"); 747 748 res = ReadFile(server, buf, 1, &size, NULL); 749 ok(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned %x(%u)\n", res, GetLastError()); 750 ok(size == 1, "size = %u\n", size); 751 752 /* pass both overlapped and ret read */ 753 memset(&overlapped, 0, sizeof(overlapped)); 754 res = ReadFile(server, buf, 1, &size, &overlapped); 755 ok(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned %x(%u)\n", res, GetLastError()); 756 ok(size == 0, "size = %u\n", size); 757 ok((NTSTATUS)overlapped.Internal == STATUS_BUFFER_OVERFLOW, "Internal = %lx\n", overlapped.Internal); 758 ok(overlapped.InternalHigh == 1, "InternalHigh = %lx\n", overlapped.InternalHigh); 759 760 DisconnectNamedPipe(server); 761 762 memset(&overlapped, 0, sizeof(overlapped)); 763 overlapped.InternalHigh = 0xdeadbeef; 764 res = ReadFile(server, buf, 1, &size, &overlapped); 765 ok(!res && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "ReadFile returned %x(%u)\n", res, GetLastError()); 766 ok(size == 0, "size = %u\n", size); 767 ok(overlapped.Internal == STATUS_PENDING, "Internal = %lx\n", overlapped.Internal); 768 ok(overlapped.InternalHigh == 0xdeadbeef, "InternalHigh = %lx\n", overlapped.InternalHigh); 769 770 memset(&overlapped, 0, sizeof(overlapped)); 771 overlapped.InternalHigh = 0xdeadbeef; 772 res = WriteFile(server, buf, 1, &size, &overlapped); 773 ok(!res && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "ReadFile returned %x(%u)\n", res, GetLastError()); 774 ok(size == 0, "size = %u\n", size); 775 ok(overlapped.Internal == STATUS_PENDING, "Internal = %lx\n", overlapped.Internal); 776 ok(overlapped.InternalHigh == 0xdeadbeef, "InternalHigh = %lx\n", overlapped.InternalHigh); 777 778 CloseHandle(server); 779 CloseHandle(client); 780 } 781 782 /** implementation of alarm() */ 783 static DWORD CALLBACK alarmThreadMain(LPVOID arg) 784 { 785 DWORD_PTR timeout = (DWORD_PTR) arg; 786 if (winetest_debug > 1) trace("alarmThreadMain\n"); 787 if (WaitForSingleObject( alarm_event, timeout ) == WAIT_TIMEOUT) 788 { 789 ok(FALSE, "alarm\n"); 790 ExitProcess(1); 791 } 792 return 1; 793 } 794 795 static HANDLE hnp = INVALID_HANDLE_VALUE; 796 797 /** Trivial byte echo server - disconnects after each session */ 798 static DWORD CALLBACK serverThreadMain1(LPVOID arg) 799 { 800 int i; 801 802 if (winetest_debug > 1) trace("serverThreadMain1 start\n"); 803 /* Set up a simple echo server */ 804 hnp = CreateNamedPipeA(PIPENAME "serverThreadMain1", PIPE_ACCESS_DUPLEX, 805 PIPE_TYPE_BYTE | PIPE_WAIT, 806 /* nMaxInstances */ 1, 807 /* nOutBufSize */ 1024, 808 /* nInBufSize */ 1024, 809 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 810 /* lpSecurityAttrib */ NULL); 811 812 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 813 for (i = 0; i < NB_SERVER_LOOPS; i++) { 814 char buf[512]; 815 DWORD written; 816 DWORD readden; 817 BOOL success; 818 819 /* Wait for client to connect */ 820 if (winetest_debug > 1) trace("Server calling ConnectNamedPipe...\n"); 821 ok(ConnectNamedPipe(hnp, NULL) 822 || GetLastError() == ERROR_PIPE_CONNECTED, "ConnectNamedPipe\n"); 823 if (winetest_debug > 1) trace("ConnectNamedPipe returned.\n"); 824 825 /* Echo bytes once */ 826 memset(buf, 0, sizeof(buf)); 827 828 if (winetest_debug > 1) trace("Server reading...\n"); 829 success = ReadFile(hnp, buf, sizeof(buf), &readden, NULL); 830 if (winetest_debug > 1) trace("Server done reading.\n"); 831 ok(success, "ReadFile\n"); 832 ok(readden, "short read\n"); 833 834 if (winetest_debug > 1) trace("Server writing...\n"); 835 ok(WriteFile(hnp, buf, readden, &written, NULL), "WriteFile\n"); 836 if (winetest_debug > 1) trace("Server done writing.\n"); 837 ok(written == readden, "write file len\n"); 838 839 /* finish this connection, wait for next one */ 840 ok(FlushFileBuffers(hnp), "FlushFileBuffers\n"); 841 if (winetest_debug > 1) trace("Server done flushing.\n"); 842 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n"); 843 if (winetest_debug > 1) trace("Server done disconnecting.\n"); 844 } 845 return 0; 846 } 847 848 /** Trivial byte echo server - closes after each connection */ 849 static DWORD CALLBACK serverThreadMain2(LPVOID arg) 850 { 851 int i; 852 HANDLE hnpNext = 0; 853 854 trace("serverThreadMain2\n"); 855 /* Set up a simple echo server */ 856 hnp = CreateNamedPipeA(PIPENAME "serverThreadMain2", PIPE_ACCESS_DUPLEX, 857 PIPE_TYPE_BYTE | PIPE_WAIT, 858 /* nMaxInstances */ 2, 859 /* nOutBufSize */ 1024, 860 /* nInBufSize */ 1024, 861 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 862 /* lpSecurityAttrib */ NULL); 863 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 864 865 for (i = 0; i < NB_SERVER_LOOPS; i++) { 866 char buf[512]; 867 DWORD written; 868 DWORD readden; 869 DWORD ret; 870 BOOL success; 871 872 873 user_apc_ran = FALSE; 874 if (i == 0 && pQueueUserAPC) { 875 if (winetest_debug > 1) trace("Queueing an user APC\n"); /* verify the pipe is non alerable */ 876 ret = pQueueUserAPC(&user_apc, GetCurrentThread(), 0); 877 ok(ret, "QueueUserAPC failed: %d\n", GetLastError()); 878 } 879 880 /* Wait for client to connect */ 881 if (winetest_debug > 1) trace("Server calling ConnectNamedPipe...\n"); 882 ok(ConnectNamedPipe(hnp, NULL) 883 || GetLastError() == ERROR_PIPE_CONNECTED, "ConnectNamedPipe\n"); 884 if (winetest_debug > 1) trace("ConnectNamedPipe returned.\n"); 885 886 /* Echo bytes once */ 887 memset(buf, 0, sizeof(buf)); 888 889 if (winetest_debug > 1) trace("Server reading...\n"); 890 success = ReadFile(hnp, buf, sizeof(buf), &readden, NULL); 891 if (winetest_debug > 1) trace("Server done reading.\n"); 892 ok(success, "ReadFile\n"); 893 894 if (winetest_debug > 1) trace("Server writing...\n"); 895 ok(WriteFile(hnp, buf, readden, &written, NULL), "WriteFile\n"); 896 if (winetest_debug > 1) trace("Server done writing.\n"); 897 ok(written == readden, "write file len\n"); 898 899 /* finish this connection, wait for next one */ 900 ok(FlushFileBuffers(hnp), "FlushFileBuffers\n"); 901 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n"); 902 903 ok(user_apc_ran == FALSE, "UserAPC ran, pipe using alertable io mode\n"); 904 905 if (i == 0 && pQueueUserAPC) 906 SleepEx(0, TRUE); /* get rid of apc */ 907 908 /* Set up next echo server */ 909 hnpNext = 910 CreateNamedPipeA(PIPENAME "serverThreadMain2", PIPE_ACCESS_DUPLEX, 911 PIPE_TYPE_BYTE | PIPE_WAIT, 912 /* nMaxInstances */ 2, 913 /* nOutBufSize */ 1024, 914 /* nInBufSize */ 1024, 915 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 916 /* lpSecurityAttrib */ NULL); 917 918 ok(hnpNext != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 919 920 ok(CloseHandle(hnp), "CloseHandle\n"); 921 hnp = hnpNext; 922 } 923 return 0; 924 } 925 926 /** Trivial byte echo server - uses overlapped named pipe calls */ 927 static DWORD CALLBACK serverThreadMain3(LPVOID arg) 928 { 929 int i; 930 HANDLE hEvent; 931 932 if (winetest_debug > 1) trace("serverThreadMain3\n"); 933 /* Set up a simple echo server */ 934 hnp = CreateNamedPipeA(PIPENAME "serverThreadMain3", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 935 PIPE_TYPE_BYTE | PIPE_WAIT, 936 /* nMaxInstances */ 1, 937 /* nOutBufSize */ 1024, 938 /* nInBufSize */ 1024, 939 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 940 /* lpSecurityAttrib */ NULL); 941 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 942 943 hEvent = CreateEventW(NULL, /* security attribute */ 944 TRUE, /* manual reset event */ 945 FALSE, /* initial state */ 946 NULL); /* name */ 947 ok(hEvent != NULL, "CreateEvent\n"); 948 949 for (i = 0; i < NB_SERVER_LOOPS; i++) { 950 char buf[512]; 951 DWORD written; 952 DWORD readden; 953 DWORD dummy; 954 BOOL success; 955 OVERLAPPED oOverlap; 956 int letWFSOEwait = (i & 2); 957 int letGORwait = (i & 1); 958 DWORD err; 959 960 memset(&oOverlap, 0, sizeof(oOverlap)); 961 oOverlap.hEvent = hEvent; 962 963 /* Wait for client to connect */ 964 if (i == 0) { 965 if (winetest_debug > 1) trace("Server calling non-overlapped ConnectNamedPipe on overlapped pipe...\n"); 966 success = ConnectNamedPipe(hnp, NULL); 967 err = GetLastError(); 968 ok(success || (err == ERROR_PIPE_CONNECTED), "ConnectNamedPipe failed: %d\n", err); 969 if (winetest_debug > 1) trace("ConnectNamedPipe operation complete.\n"); 970 } else { 971 if (winetest_debug > 1) trace("Server calling overlapped ConnectNamedPipe...\n"); 972 success = ConnectNamedPipe(hnp, &oOverlap); 973 err = GetLastError(); 974 ok(!success && (err == ERROR_IO_PENDING || err == ERROR_PIPE_CONNECTED), "overlapped ConnectNamedPipe\n"); 975 if (winetest_debug > 1) trace("overlapped ConnectNamedPipe returned.\n"); 976 if (!success && (err == ERROR_IO_PENDING)) { 977 if (letWFSOEwait) 978 { 979 DWORD ret; 980 do { 981 ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE); 982 } while (ret == WAIT_IO_COMPLETION); 983 ok(ret == 0, "wait ConnectNamedPipe returned %x\n", ret); 984 } 985 success = GetOverlappedResult(hnp, &oOverlap, &dummy, letGORwait); 986 if (!letGORwait && !letWFSOEwait && !success) { 987 ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n"); 988 success = GetOverlappedResult(hnp, &oOverlap, &dummy, TRUE); 989 } 990 } 991 ok(success || (err == ERROR_PIPE_CONNECTED), "GetOverlappedResult ConnectNamedPipe\n"); 992 if (winetest_debug > 1) trace("overlapped ConnectNamedPipe operation complete.\n"); 993 } 994 995 /* Echo bytes once */ 996 memset(buf, 0, sizeof(buf)); 997 998 if (winetest_debug > 1) trace("Server reading...\n"); 999 success = ReadFile(hnp, buf, sizeof(buf), &readden, &oOverlap); 1000 if (winetest_debug > 1) trace("Server ReadFile returned...\n"); 1001 err = GetLastError(); 1002 ok(success || err == ERROR_IO_PENDING, "overlapped ReadFile\n"); 1003 if (winetest_debug > 1) trace("overlapped ReadFile returned.\n"); 1004 if (!success && (err == ERROR_IO_PENDING)) { 1005 if (letWFSOEwait) 1006 { 1007 DWORD ret; 1008 do { 1009 ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE); 1010 } while (ret == WAIT_IO_COMPLETION); 1011 ok(ret == 0, "wait ReadFile returned %x\n", ret); 1012 } 1013 success = GetOverlappedResult(hnp, &oOverlap, &readden, letGORwait); 1014 if (!letGORwait && !letWFSOEwait && !success) { 1015 ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n"); 1016 success = GetOverlappedResult(hnp, &oOverlap, &readden, TRUE); 1017 } 1018 } 1019 if (winetest_debug > 1) trace("Server done reading.\n"); 1020 ok(success, "overlapped ReadFile\n"); 1021 1022 if (winetest_debug > 1) trace("Server writing...\n"); 1023 success = WriteFile(hnp, buf, readden, &written, &oOverlap); 1024 if (winetest_debug > 1) trace("Server WriteFile returned...\n"); 1025 err = GetLastError(); 1026 ok(success || err == ERROR_IO_PENDING, "overlapped WriteFile\n"); 1027 if (winetest_debug > 1) trace("overlapped WriteFile returned.\n"); 1028 if (!success && (err == ERROR_IO_PENDING)) { 1029 if (letWFSOEwait) 1030 { 1031 DWORD ret; 1032 do { 1033 ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE); 1034 } while (ret == WAIT_IO_COMPLETION); 1035 ok(ret == 0, "wait WriteFile returned %x\n", ret); 1036 } 1037 success = GetOverlappedResult(hnp, &oOverlap, &written, letGORwait); 1038 if (!letGORwait && !letWFSOEwait && !success) { 1039 ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n"); 1040 success = GetOverlappedResult(hnp, &oOverlap, &written, TRUE); 1041 } 1042 } 1043 if (winetest_debug > 1) trace("Server done writing.\n"); 1044 ok(success, "overlapped WriteFile\n"); 1045 ok(written == readden, "write file len\n"); 1046 1047 /* finish this connection, wait for next one */ 1048 ok(FlushFileBuffers(hnp), "FlushFileBuffers\n"); 1049 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n"); 1050 } 1051 return 0; 1052 } 1053 1054 /** Trivial byte echo server - uses i/o completion ports */ 1055 static DWORD CALLBACK serverThreadMain4(LPVOID arg) 1056 { 1057 int i; 1058 HANDLE hcompletion; 1059 BOOL ret; 1060 1061 if (winetest_debug > 1) trace("serverThreadMain4\n"); 1062 /* Set up a simple echo server */ 1063 hnp = CreateNamedPipeA(PIPENAME "serverThreadMain4", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 1064 PIPE_TYPE_BYTE | PIPE_WAIT, 1065 /* nMaxInstances */ 1, 1066 /* nOutBufSize */ 1024, 1067 /* nInBufSize */ 1024, 1068 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 1069 /* lpSecurityAttrib */ NULL); 1070 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 1071 1072 hcompletion = CreateIoCompletionPort(hnp, NULL, 12345, 1); 1073 ok(hcompletion != NULL, "CreateIoCompletionPort failed, error=%i\n", GetLastError()); 1074 1075 for (i = 0; i < NB_SERVER_LOOPS; i++) { 1076 char buf[512]; 1077 DWORD written; 1078 DWORD readden; 1079 DWORD dummy; 1080 BOOL success; 1081 OVERLAPPED oConnect; 1082 OVERLAPPED oRead; 1083 OVERLAPPED oWrite; 1084 OVERLAPPED *oResult; 1085 DWORD err; 1086 ULONG_PTR compkey; 1087 1088 memset(&oConnect, 0, sizeof(oConnect)); 1089 memset(&oRead, 0, sizeof(oRead)); 1090 memset(&oWrite, 0, sizeof(oWrite)); 1091 1092 /* Wait for client to connect */ 1093 if (winetest_debug > 1) trace("Server calling overlapped ConnectNamedPipe...\n"); 1094 success = ConnectNamedPipe(hnp, &oConnect); 1095 err = GetLastError(); 1096 ok(!success && (err == ERROR_IO_PENDING || err == ERROR_PIPE_CONNECTED), 1097 "overlapped ConnectNamedPipe got %u err %u\n", success, err ); 1098 if (!success && err == ERROR_IO_PENDING) { 1099 if (winetest_debug > 1) trace("ConnectNamedPipe GetQueuedCompletionStatus\n"); 1100 success = GetQueuedCompletionStatus(hcompletion, &dummy, &compkey, &oResult, 0); 1101 if (!success) 1102 { 1103 ok( GetLastError() == WAIT_TIMEOUT, 1104 "ConnectNamedPipe GetQueuedCompletionStatus wrong error %u\n", GetLastError()); 1105 success = GetQueuedCompletionStatus(hcompletion, &dummy, &compkey, &oResult, 10000); 1106 } 1107 ok(success, "ConnectNamedPipe GetQueuedCompletionStatus failed, errno=%i\n", GetLastError()); 1108 if (success) 1109 { 1110 ok(compkey == 12345, "got completion key %i instead of 12345\n", (int)compkey); 1111 ok(oResult == &oConnect, "got overlapped pointer %p instead of %p\n", oResult, &oConnect); 1112 } 1113 } 1114 if (winetest_debug > 1) trace("overlapped ConnectNamedPipe operation complete.\n"); 1115 1116 /* Echo bytes once */ 1117 memset(buf, 0, sizeof(buf)); 1118 1119 if (winetest_debug > 1) trace("Server reading...\n"); 1120 success = ReadFile(hnp, buf, sizeof(buf), &readden, &oRead); 1121 if (winetest_debug > 1) trace("Server ReadFile returned...\n"); 1122 err = GetLastError(); 1123 ok(success || err == ERROR_IO_PENDING, "overlapped ReadFile, err=%i\n", err); 1124 success = GetQueuedCompletionStatus(hcompletion, &readden, &compkey, 1125 &oResult, 10000); 1126 ok(success, "ReadFile GetQueuedCompletionStatus failed, errno=%i\n", GetLastError()); 1127 if (success) 1128 { 1129 ok(compkey == 12345, "got completion key %i instead of 12345\n", (int)compkey); 1130 ok(oResult == &oRead, "got overlapped pointer %p instead of %p\n", oResult, &oRead); 1131 } 1132 if (winetest_debug > 1) trace("Server done reading.\n"); 1133 1134 if (winetest_debug > 1) trace("Server writing...\n"); 1135 success = WriteFile(hnp, buf, readden, &written, &oWrite); 1136 if (winetest_debug > 1) trace("Server WriteFile returned...\n"); 1137 err = GetLastError(); 1138 ok(success || err == ERROR_IO_PENDING, "overlapped WriteFile failed, err=%u\n", err); 1139 success = GetQueuedCompletionStatus(hcompletion, &written, &compkey, 1140 &oResult, 10000); 1141 ok(success, "WriteFile GetQueuedCompletionStatus failed, errno=%i\n", GetLastError()); 1142 if (success) 1143 { 1144 ok(compkey == 12345, "got completion key %i instead of 12345\n", (int)compkey); 1145 ok(oResult == &oWrite, "got overlapped pointer %p instead of %p\n", oResult, &oWrite); 1146 ok(written == readden, "write file len\n"); 1147 } 1148 if (winetest_debug > 1) trace("Server done writing.\n"); 1149 1150 /* Client will finish this connection, the following ops will trigger broken pipe errors. */ 1151 1152 /* Wait for the pipe to break. */ 1153 while (PeekNamedPipe(hnp, NULL, 0, NULL, &written, &written)); 1154 1155 if (winetest_debug > 1) trace("Server writing on disconnected pipe...\n"); 1156 SetLastError(ERROR_SUCCESS); 1157 success = WriteFile(hnp, buf, readden, &written, &oWrite); 1158 err = GetLastError(); 1159 todo_wine_if (!success && err == ERROR_PIPE_NOT_CONNECTED) ok(!success && err == ERROR_NO_DATA, 1160 "overlapped WriteFile on disconnected pipe returned %u, err=%i\n", success, err); 1161 1162 /* No completion status is queued on immediate error. */ 1163 SetLastError(ERROR_SUCCESS); 1164 oResult = (OVERLAPPED *)0xdeadbeef; 1165 success = GetQueuedCompletionStatus(hcompletion, &written, &compkey, 1166 &oResult, 0); 1167 err = GetLastError(); 1168 ok(!success && err == WAIT_TIMEOUT && !oResult, 1169 "WriteFile GetQueuedCompletionStatus returned %u, err=%i, oResult %p\n", 1170 success, err, oResult); 1171 1172 if (winetest_debug > 1) trace("Server reading from disconnected pipe...\n"); 1173 SetLastError(ERROR_SUCCESS); 1174 success = ReadFile(hnp, buf, sizeof(buf), &readden, &oRead); 1175 if (winetest_debug > 1) trace("Server ReadFile from disconnected pipe returned...\n"); 1176 err = GetLastError(); 1177 ok(!success && err == ERROR_BROKEN_PIPE, 1178 "overlapped ReadFile on disconnected pipe returned %u, err=%i\n", success, err); 1179 1180 SetLastError(ERROR_SUCCESS); 1181 oResult = (OVERLAPPED *)0xdeadbeef; 1182 success = GetQueuedCompletionStatus(hcompletion, &readden, &compkey, 1183 &oResult, 0); 1184 err = GetLastError(); 1185 ok(!success && err == WAIT_TIMEOUT && !oResult, 1186 "ReadFile GetQueuedCompletionStatus returned %u, err=%i, oResult %p\n", 1187 success, err, oResult); 1188 1189 /* finish this connection, wait for next one */ 1190 ok(FlushFileBuffers(hnp), "FlushFileBuffers\n"); 1191 success = DisconnectNamedPipe(hnp); 1192 ok(success, "DisconnectNamedPipe failed, err %u\n", GetLastError()); 1193 } 1194 1195 ret = CloseHandle(hnp); 1196 ok(ret, "CloseHandle named pipe failed, err=%i\n", GetLastError()); 1197 ret = CloseHandle(hcompletion); 1198 ok(ret, "CloseHandle completion failed, err=%i\n", GetLastError()); 1199 1200 return 0; 1201 } 1202 1203 static int completion_called; 1204 static DWORD completion_errorcode; 1205 static DWORD completion_num_bytes; 1206 static LPOVERLAPPED completion_lpoverlapped; 1207 1208 static VOID WINAPI completion_routine(DWORD errorcode, DWORD num_bytes, LPOVERLAPPED lpoverlapped) 1209 { 1210 completion_called++; 1211 completion_errorcode = errorcode; 1212 completion_num_bytes = num_bytes; 1213 completion_lpoverlapped = lpoverlapped; 1214 SetEvent(lpoverlapped->hEvent); 1215 } 1216 1217 /** Trivial byte echo server - uses ReadFileEx/WriteFileEx */ 1218 static DWORD CALLBACK serverThreadMain5(LPVOID arg) 1219 { 1220 int i; 1221 HANDLE hEvent; 1222 1223 if (winetest_debug > 1) trace("serverThreadMain5\n"); 1224 /* Set up a simple echo server */ 1225 hnp = CreateNamedPipeA(PIPENAME "serverThreadMain5", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 1226 PIPE_TYPE_BYTE | PIPE_WAIT, 1227 /* nMaxInstances */ 1, 1228 /* nOutBufSize */ 1024, 1229 /* nInBufSize */ 1024, 1230 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 1231 /* lpSecurityAttrib */ NULL); 1232 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 1233 1234 hEvent = CreateEventW(NULL, /* security attribute */ 1235 TRUE, /* manual reset event */ 1236 FALSE, /* initial state */ 1237 NULL); /* name */ 1238 ok(hEvent != NULL, "CreateEvent\n"); 1239 1240 for (i = 0; i < NB_SERVER_LOOPS; i++) { 1241 char buf[512]; 1242 DWORD readden; 1243 BOOL success; 1244 OVERLAPPED oOverlap; 1245 DWORD err; 1246 1247 memset(&oOverlap, 0, sizeof(oOverlap)); 1248 oOverlap.hEvent = hEvent; 1249 1250 /* Wait for client to connect */ 1251 if (winetest_debug > 1) trace("Server calling ConnectNamedPipe...\n"); 1252 success = ConnectNamedPipe(hnp, NULL); 1253 err = GetLastError(); 1254 ok(success || (err == ERROR_PIPE_CONNECTED), "ConnectNamedPipe failed: %d\n", err); 1255 if (winetest_debug > 1) trace("ConnectNamedPipe operation complete.\n"); 1256 1257 /* Echo bytes once */ 1258 memset(buf, 0, sizeof(buf)); 1259 1260 if (winetest_debug > 1) trace("Server reading...\n"); 1261 completion_called = 0; 1262 ResetEvent(hEvent); 1263 success = ReadFileEx(hnp, buf, sizeof(buf), &oOverlap, completion_routine); 1264 if (winetest_debug > 1) trace("Server ReadFileEx returned...\n"); 1265 ok(success, "ReadFileEx failed, err=%i\n", GetLastError()); 1266 ok(completion_called == 0, "completion routine called before ReadFileEx return\n"); 1267 if (winetest_debug > 1) trace("ReadFileEx returned.\n"); 1268 if (success) { 1269 DWORD ret; 1270 do { 1271 ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE); 1272 } while (ret == WAIT_IO_COMPLETION); 1273 ok(ret == 0, "wait ReadFileEx returned %x\n", ret); 1274 } 1275 ok(completion_called == 1, "completion routine called %i times\n", completion_called); 1276 ok(completion_errorcode == ERROR_SUCCESS, "completion routine got error %d\n", completion_errorcode); 1277 ok(completion_num_bytes != 0, "read 0 bytes\n"); 1278 ok(completion_lpoverlapped == &oOverlap, "got wrong overlapped pointer %p\n", completion_lpoverlapped); 1279 readden = completion_num_bytes; 1280 if (winetest_debug > 1) trace("Server done reading.\n"); 1281 1282 if (winetest_debug > 1) trace("Server writing...\n"); 1283 completion_called = 0; 1284 ResetEvent(hEvent); 1285 success = WriteFileEx(hnp, buf, readden, &oOverlap, completion_routine); 1286 if (winetest_debug > 1) trace("Server WriteFileEx returned...\n"); 1287 ok(success, "WriteFileEx failed, err=%i\n", GetLastError()); 1288 ok(completion_called == 0, "completion routine called before ReadFileEx return\n"); 1289 if (winetest_debug > 1) trace("overlapped WriteFile returned.\n"); 1290 if (success) { 1291 DWORD ret; 1292 do { 1293 ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE); 1294 } while (ret == WAIT_IO_COMPLETION); 1295 ok(ret == 0, "wait WriteFileEx returned %x\n", ret); 1296 } 1297 if (winetest_debug > 1) trace("Server done writing.\n"); 1298 ok(completion_called == 1, "completion routine called %i times\n", completion_called); 1299 ok(completion_errorcode == ERROR_SUCCESS, "completion routine got error %d\n", completion_errorcode); 1300 ok(completion_num_bytes == readden, "read %i bytes wrote %i\n", readden, completion_num_bytes); 1301 ok(completion_lpoverlapped == &oOverlap, "got wrong overlapped pointer %p\n", completion_lpoverlapped); 1302 1303 /* finish this connection, wait for next one */ 1304 ok(FlushFileBuffers(hnp), "FlushFileBuffers\n"); 1305 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n"); 1306 } 1307 return 0; 1308 } 1309 1310 static void exercizeServer(const char *pipename, HANDLE serverThread) 1311 { 1312 int i; 1313 1314 if (winetest_debug > 1) trace("exercizeServer starting\n"); 1315 for (i = 0; i < NB_SERVER_LOOPS; i++) { 1316 HANDLE hFile=INVALID_HANDLE_VALUE; 1317 static const char obuf[] = "Bit Bucket"; 1318 char ibuf[32]; 1319 DWORD written; 1320 DWORD readden; 1321 int loop; 1322 1323 for (loop = 0; loop < 3; loop++) { 1324 DWORD err; 1325 if (winetest_debug > 1) trace("Client connecting...\n"); 1326 /* Connect to the server */ 1327 hFile = CreateFileA(pipename, GENERIC_READ | GENERIC_WRITE, 0, 1328 NULL, OPEN_EXISTING, 0, 0); 1329 if (hFile != INVALID_HANDLE_VALUE) 1330 break; 1331 err = GetLastError(); 1332 if (loop == 0) 1333 ok(err == ERROR_PIPE_BUSY || err == ERROR_FILE_NOT_FOUND, "connecting to pipe\n"); 1334 else 1335 ok(err == ERROR_PIPE_BUSY, "connecting to pipe\n"); 1336 if (winetest_debug > 1) trace("connect failed, retrying\n"); 1337 Sleep(200); 1338 } 1339 ok(hFile != INVALID_HANDLE_VALUE, "client opening named pipe\n"); 1340 1341 /* Make sure it can echo */ 1342 memset(ibuf, 0, sizeof(ibuf)); 1343 if (winetest_debug > 1) trace("Client writing...\n"); 1344 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile to client end of pipe\n"); 1345 ok(written == sizeof(obuf), "write file len\n"); 1346 if (winetest_debug > 1) trace("Client reading...\n"); 1347 ok(ReadFile(hFile, ibuf, sizeof(obuf), &readden, NULL), "ReadFile from client end of pipe\n"); 1348 ok(readden == sizeof(obuf), "read file len\n"); 1349 ok(memcmp(obuf, ibuf, written) == 0, "content check\n"); 1350 1351 if (winetest_debug > 1) trace("Client closing...\n"); 1352 ok(CloseHandle(hFile), "CloseHandle\n"); 1353 } 1354 1355 ok(WaitForSingleObject(serverThread,INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject\n"); 1356 CloseHandle(hnp); 1357 if (winetest_debug > 1) trace("exercizeServer returning\n"); 1358 } 1359 1360 static void test_NamedPipe_2(void) 1361 { 1362 HANDLE serverThread; 1363 DWORD serverThreadId; 1364 HANDLE alarmThread; 1365 DWORD alarmThreadId; 1366 1367 trace("test_NamedPipe_2 starting\n"); 1368 /* Set up a twenty second timeout */ 1369 alarm_event = CreateEventW( NULL, TRUE, FALSE, NULL ); 1370 SetLastError(0xdeadbeef); 1371 alarmThread = CreateThread(NULL, 0, alarmThreadMain, (void *) 20000, 0, &alarmThreadId); 1372 ok(alarmThread != NULL, "CreateThread failed: %d\n", GetLastError()); 1373 1374 /* The servers we're about to exercise do try to clean up carefully, 1375 * but to reduce the chance of a test failure due to a pipe handle 1376 * leak in the test code, we'll use a different pipe name for each server. 1377 */ 1378 1379 /* Try server #1 */ 1380 SetLastError(0xdeadbeef); 1381 serverThread = CreateThread(NULL, 0, serverThreadMain1, (void *)8, 0, &serverThreadId); 1382 ok(serverThread != NULL, "CreateThread failed: %d\n", GetLastError()); 1383 exercizeServer(PIPENAME "serverThreadMain1", serverThread); 1384 1385 /* Try server #2 */ 1386 SetLastError(0xdeadbeef); 1387 serverThread = CreateThread(NULL, 0, serverThreadMain2, 0, 0, &serverThreadId); 1388 ok(serverThread != NULL, "CreateThread failed: %d\n", GetLastError()); 1389 exercizeServer(PIPENAME "serverThreadMain2", serverThread); 1390 1391 /* Try server #3 */ 1392 SetLastError(0xdeadbeef); 1393 serverThread = CreateThread(NULL, 0, serverThreadMain3, 0, 0, &serverThreadId); 1394 ok(serverThread != NULL, "CreateThread failed: %d\n", GetLastError()); 1395 exercizeServer(PIPENAME "serverThreadMain3", serverThread); 1396 1397 /* Try server #4 */ 1398 SetLastError(0xdeadbeef); 1399 serverThread = CreateThread(NULL, 0, serverThreadMain4, 0, 0, &serverThreadId); 1400 ok(serverThread != NULL, "CreateThread failed: %d\n", GetLastError()); 1401 exercizeServer(PIPENAME "serverThreadMain4", serverThread); 1402 1403 /* Try server #5 */ 1404 SetLastError(0xdeadbeef); 1405 serverThread = CreateThread(NULL, 0, serverThreadMain5, 0, 0, &serverThreadId); 1406 ok(serverThread != NULL, "CreateThread failed: %d\n", GetLastError()); 1407 exercizeServer(PIPENAME "serverThreadMain5", serverThread); 1408 1409 ok(SetEvent( alarm_event ), "SetEvent\n"); 1410 CloseHandle( alarm_event ); 1411 if (winetest_debug > 1) trace("test_NamedPipe_2 returning\n"); 1412 } 1413 1414 static int test_DisconnectNamedPipe(void) 1415 { 1416 HANDLE hnp; 1417 HANDLE hFile; 1418 static const char obuf[] = "Bit Bucket"; 1419 char ibuf[32]; 1420 DWORD written; 1421 DWORD readden; 1422 DWORD ret; 1423 1424 SetLastError(0xdeadbeef); 1425 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 1426 /* nMaxInstances */ 1, 1427 /* nOutBufSize */ 1024, 1428 /* nInBufSize */ 1024, 1429 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 1430 /* lpSecurityAttrib */ NULL); 1431 if ((hnp == INVALID_HANDLE_VALUE /* Win98 */ || !hnp /* Win95 */) 1432 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { 1433 1434 win_skip("Named pipes are not implemented\n"); 1435 return 1; 1436 } 1437 1438 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL) == 0 1439 && GetLastError() == ERROR_PIPE_LISTENING, "WriteFile to not-yet-connected pipe\n"); 1440 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0 1441 && GetLastError() == ERROR_PIPE_LISTENING, "ReadFile from not-yet-connected pipe\n"); 1442 1443 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 1444 ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed\n"); 1445 1446 /* don't try to do i/o if one side couldn't be opened, as it hangs */ 1447 if (hFile != INVALID_HANDLE_VALUE) { 1448 1449 /* see what happens if server calls DisconnectNamedPipe 1450 * when there are bytes in the pipe 1451 */ 1452 1453 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile\n"); 1454 ok(written == sizeof(obuf), "write file len\n"); 1455 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe while messages waiting\n"); 1456 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL) == 0 1457 && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "WriteFile to disconnected pipe\n"); 1458 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0 1459 && GetLastError() == ERROR_PIPE_NOT_CONNECTED, 1460 "ReadFile from disconnected pipe with bytes waiting\n"); 1461 1462 ok(!DisconnectNamedPipe(hnp) && GetLastError() == ERROR_PIPE_NOT_CONNECTED, 1463 "DisconnectNamedPipe worked twice\n"); 1464 ret = WaitForSingleObject(hFile, 0); 1465 ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %X\n", ret); 1466 1467 ret = PeekNamedPipe(hFile, NULL, 0, NULL, &readden, NULL); 1468 todo_wine 1469 ok(!ret && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "PeekNamedPipe returned %x (%u)\n", 1470 ret, GetLastError()); 1471 ret = PeekNamedPipe(hnp, NULL, 0, NULL, &readden, NULL); 1472 todo_wine 1473 ok(!ret && GetLastError() == ERROR_BAD_PIPE, "PeekNamedPipe returned %x (%u)\n", 1474 ret, GetLastError()); 1475 ok(CloseHandle(hFile), "CloseHandle\n"); 1476 } 1477 1478 ok(CloseHandle(hnp), "CloseHandle\n"); 1479 1480 return 0; 1481 } 1482 static void test_CreatePipe(void) 1483 { 1484 SECURITY_ATTRIBUTES pipe_attr; 1485 HANDLE piperead, pipewrite; 1486 DWORD written; 1487 DWORD read; 1488 DWORD i, size; 1489 BYTE *buffer; 1490 char readbuf[32]; 1491 1492 user_apc_ran = FALSE; 1493 if (pQueueUserAPC) 1494 ok(pQueueUserAPC(user_apc, GetCurrentThread(), 0), "couldn't create user apc\n"); 1495 1496 pipe_attr.nLength = sizeof(SECURITY_ATTRIBUTES); 1497 pipe_attr.bInheritHandle = TRUE; 1498 pipe_attr.lpSecurityDescriptor = NULL; 1499 ok(CreatePipe(&piperead, &pipewrite, &pipe_attr, 0) != 0, "CreatePipe failed\n"); 1500 test_pipe_info(piperead, FILE_PIPE_SERVER_END, 4096, 4096, 1); 1501 test_pipe_info(pipewrite, 0, 4096, 4096, 1); 1502 1503 ok(WriteFile(pipewrite,PIPENAME,sizeof(PIPENAME), &written, NULL), "Write to anonymous pipe failed\n"); 1504 ok(written == sizeof(PIPENAME), "Write to anonymous pipe wrote %d bytes\n", written); 1505 ok(ReadFile(piperead,readbuf,sizeof(readbuf),&read, NULL), "Read from non empty pipe failed\n"); 1506 ok(read == sizeof(PIPENAME), "Read from anonymous pipe got %d bytes\n", read); 1507 ok(CloseHandle(pipewrite), "CloseHandle for the write pipe failed\n"); 1508 ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n"); 1509 1510 /* Now write another chunk*/ 1511 ok(CreatePipe(&piperead, &pipewrite, &pipe_attr, 0) != 0, "CreatePipe failed\n"); 1512 ok(WriteFile(pipewrite,PIPENAME,sizeof(PIPENAME), &written, NULL), "Write to anonymous pipe failed\n"); 1513 ok(written == sizeof(PIPENAME), "Write to anonymous pipe wrote %d bytes\n", written); 1514 /* and close the write end, read should still succeed*/ 1515 ok(CloseHandle(pipewrite), "CloseHandle for the Write Pipe failed\n"); 1516 ok(ReadFile(piperead,readbuf,sizeof(readbuf),&read, NULL), "Read from broken pipe with pending data failed\n"); 1517 ok(read == sizeof(PIPENAME), "Read from anonymous pipe got %d bytes\n", read); 1518 /* But now we need to get informed that the pipe is closed */ 1519 ok(ReadFile(piperead,readbuf,sizeof(readbuf),&read, NULL) == 0, "Broken pipe not detected\n"); 1520 ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n"); 1521 1522 /* Try bigger chunks */ 1523 size = 32768; 1524 buffer = HeapAlloc( GetProcessHeap(), 0, size ); 1525 for (i = 0; i < size; i++) buffer[i] = i; 1526 ok(CreatePipe(&piperead, &pipewrite, &pipe_attr, (size + 24)) != 0, "CreatePipe failed\n"); 1527 ok(WriteFile(pipewrite, buffer, size, &written, NULL), "Write to anonymous pipe failed\n"); 1528 ok(written == size, "Write to anonymous pipe wrote %d bytes\n", written); 1529 /* and close the write end, read should still succeed*/ 1530 ok(CloseHandle(pipewrite), "CloseHandle for the Write Pipe failed\n"); 1531 memset( buffer, 0, size ); 1532 ok(ReadFile(piperead, buffer, size, &read, NULL), "Read from broken pipe with pending data failed\n"); 1533 ok(read == size, "Read from anonymous pipe got %d bytes\n", read); 1534 for (i = 0; i < size; i++) ok( buffer[i] == (BYTE)i, "invalid data %x at %x\n", buffer[i], i ); 1535 /* But now we need to get informed that the pipe is closed */ 1536 ok(ReadFile(piperead,readbuf,sizeof(readbuf),&read, NULL) == 0, "Broken pipe not detected\n"); 1537 ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n"); 1538 HeapFree(GetProcessHeap(), 0, buffer); 1539 1540 ok(user_apc_ran == FALSE, "user apc ran, pipe using alertable io mode\n"); 1541 SleepEx(0, TRUE); /* get rid of apc */ 1542 1543 ok(CreatePipe(&piperead, &pipewrite, &pipe_attr, 1) != 0, "CreatePipe failed\n"); 1544 test_pipe_info(piperead, FILE_PIPE_SERVER_END, 1, 1, 1); 1545 test_pipe_info(pipewrite, 0, 1, 1, 1); 1546 ok(CloseHandle(pipewrite), "CloseHandle for the Write Pipe failed\n"); 1547 ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n"); 1548 } 1549 1550 static void test_CloseHandle(void) 1551 { 1552 static const char testdata[] = "Hello World"; 1553 DWORD state, numbytes; 1554 HANDLE hpipe, hfile; 1555 char buffer[32]; 1556 BOOL ret; 1557 1558 hpipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, 1559 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1560 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); 1561 ok(hpipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError()); 1562 1563 hfile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 1564 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError()); 1565 1566 numbytes = 0xdeadbeef; 1567 ret = WriteFile(hpipe, testdata, sizeof(testdata), &numbytes, NULL); 1568 ok(ret, "WriteFile failed with %u\n", GetLastError()); 1569 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes); 1570 1571 numbytes = 0xdeadbeef; 1572 ret = PeekNamedPipe(hfile, NULL, 0, NULL, &numbytes, NULL); 1573 ok(ret, "PeekNamedPipe failed with %u\n", GetLastError()); 1574 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes); 1575 1576 ret = CloseHandle(hpipe); 1577 ok(ret, "CloseHandle failed with %u\n", GetLastError()); 1578 1579 numbytes = 0xdeadbeef; 1580 memset(buffer, 0, sizeof(buffer)); 1581 ret = ReadFile(hfile, buffer, 0, &numbytes, NULL); 1582 ok(ret, "ReadFile failed with %u\n", GetLastError()); 1583 ok(numbytes == 0, "expected 0, got %u\n", numbytes); 1584 1585 numbytes = 0xdeadbeef; 1586 ret = PeekNamedPipe(hfile, NULL, 0, NULL, &numbytes, NULL); 1587 ok(ret, "PeekNamedPipe failed with %u\n", GetLastError()); 1588 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes); 1589 1590 numbytes = 0xdeadbeef; 1591 memset(buffer, 0, sizeof(buffer)); 1592 ret = ReadFile(hfile, buffer, sizeof(buffer), &numbytes, NULL); 1593 ok(ret, "ReadFile failed with %u\n", GetLastError()); 1594 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes); 1595 1596 ret = GetNamedPipeHandleStateA(hfile, &state, NULL, NULL, NULL, NULL, 0); 1597 ok(ret, "GetNamedPipeHandleState failed with %u\n", GetLastError()); 1598 state = PIPE_READMODE_MESSAGE | PIPE_WAIT; 1599 ret = SetNamedPipeHandleState(hfile, &state, NULL, NULL); 1600 ok(ret, "SetNamedPipeHandleState failed with %u\n", GetLastError()); 1601 1602 SetLastError(0xdeadbeef); 1603 ret = ReadFile(hfile, buffer, 0, &numbytes, NULL); 1604 ok(!ret, "ReadFile unexpectedly succeeded\n"); 1605 ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError()); 1606 1607 numbytes = 0xdeadbeef; 1608 ret = PeekNamedPipe(hfile, NULL, 0, NULL, &numbytes, NULL); 1609 ok(!ret && GetLastError() == ERROR_BROKEN_PIPE, "PeekNamedPipe returned %x (%u)\n", 1610 ret, GetLastError()); 1611 ok(numbytes == 0xdeadbeef, "numbytes = %u\n", numbytes); 1612 1613 SetLastError(0xdeadbeef); 1614 ret = WriteFile(hfile, testdata, sizeof(testdata), &numbytes, NULL); 1615 ok(!ret, "WriteFile unexpectedly succeeded\n"); 1616 todo_wine ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %u\n", GetLastError()); 1617 1618 CloseHandle(hfile); 1619 1620 hpipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, 1621 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1622 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); 1623 ok(hpipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError()); 1624 1625 hfile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 1626 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError()); 1627 1628 numbytes = 0xdeadbeef; 1629 ret = WriteFile(hpipe, testdata, 0, &numbytes, NULL); 1630 ok(ret, "WriteFile failed with %u\n", GetLastError()); 1631 ok(numbytes == 0, "expected 0, got %u\n", numbytes); 1632 1633 ret = CloseHandle(hpipe); 1634 ok(ret, "CloseHandle failed with %u\n", GetLastError()); 1635 1636 numbytes = 0xdeadbeef; 1637 memset(buffer, 0, sizeof(buffer)); 1638 ret = ReadFile(hfile, buffer, sizeof(buffer), &numbytes, NULL); 1639 ok(ret, "ReadFile failed with %u\n", GetLastError()); 1640 ok(numbytes == 0, "expected 0, got %u\n", numbytes); 1641 1642 SetLastError(0xdeadbeef); 1643 ret = ReadFile(hfile, buffer, 0, &numbytes, NULL); 1644 ok(!ret, "ReadFile unexpectedly succeeded\n"); 1645 ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError()); 1646 1647 ret = GetNamedPipeHandleStateA(hfile, &state, NULL, NULL, NULL, NULL, 0); 1648 ok(ret, "GetNamedPipeHandleState failed with %u\n", GetLastError()); 1649 state = PIPE_READMODE_MESSAGE | PIPE_WAIT; 1650 ret = SetNamedPipeHandleState(hfile, &state, NULL, NULL); 1651 ok(ret, "SetNamedPipeHandleState failed with %u\n", GetLastError()); 1652 1653 SetLastError(0xdeadbeef); 1654 ret = ReadFile(hfile, buffer, 0, &numbytes, NULL); 1655 ok(!ret, "ReadFile unexpectedly succeeded\n"); 1656 ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError()); 1657 1658 SetLastError(0xdeadbeef); 1659 ret = WriteFile(hfile, testdata, sizeof(testdata), &numbytes, NULL); 1660 ok(!ret, "WriteFile unexpectedly succeeded\n"); 1661 todo_wine ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %u\n", GetLastError()); 1662 1663 CloseHandle(hfile); 1664 1665 /* repeat test with hpipe <-> hfile swapped */ 1666 1667 hpipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, 1668 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1669 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); 1670 ok(hpipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError()); 1671 1672 hfile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 1673 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError()); 1674 1675 numbytes = 0xdeadbeef; 1676 ret = WriteFile(hfile, testdata, sizeof(testdata), &numbytes, NULL); 1677 ok(ret, "WriteFile failed with %u\n", GetLastError()); 1678 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes); 1679 1680 numbytes = 0xdeadbeef; 1681 ret = PeekNamedPipe(hpipe, NULL, 0, NULL, &numbytes, NULL); 1682 ok(ret, "PeekNamedPipe failed with %u\n", GetLastError()); 1683 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes); 1684 1685 ret = CloseHandle(hfile); 1686 ok(ret, "CloseHandle failed with %u\n", GetLastError()); 1687 1688 numbytes = 0xdeadbeef; 1689 memset(buffer, 0, sizeof(buffer)); 1690 ret = ReadFile(hpipe, buffer, 0, &numbytes, NULL); 1691 ok(ret || GetLastError() == ERROR_MORE_DATA /* >= Win 8 */, 1692 "ReadFile failed with %u\n", GetLastError()); 1693 ok(numbytes == 0, "expected 0, got %u\n", numbytes); 1694 1695 numbytes = 0xdeadbeef; 1696 ret = PeekNamedPipe(hpipe, NULL, 0, NULL, &numbytes, NULL); 1697 ok(ret, "PeekNamedPipe failed with %u\n", GetLastError()); 1698 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes); 1699 1700 numbytes = 0xdeadbeef; 1701 memset(buffer, 0, sizeof(buffer)); 1702 ret = ReadFile(hpipe, buffer, sizeof(buffer), &numbytes, NULL); 1703 ok(ret, "ReadFile failed with %u\n", GetLastError()); 1704 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes); 1705 1706 ret = GetNamedPipeHandleStateA(hpipe, &state, NULL, NULL, NULL, NULL, 0); 1707 ok(ret, "GetNamedPipeHandleState failed with %u\n", GetLastError()); 1708 state = PIPE_READMODE_MESSAGE | PIPE_WAIT; 1709 ret = SetNamedPipeHandleState(hpipe, &state, NULL, NULL); 1710 ok(ret, "SetNamedPipeHandleState failed with %u\n", GetLastError()); 1711 1712 SetLastError(0xdeadbeef); 1713 ret = ReadFile(hpipe, buffer, 0, &numbytes, NULL); 1714 ok(!ret, "ReadFile unexpectedly succeeded\n"); 1715 ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError()); 1716 1717 numbytes = 0xdeadbeef; 1718 ret = PeekNamedPipe(hpipe, NULL, 0, NULL, &numbytes, NULL); 1719 ok(!ret && GetLastError() == ERROR_BROKEN_PIPE, "PeekNamedPipe returned %x (%u)\n", 1720 ret, GetLastError()); 1721 ok(numbytes == 0xdeadbeef, "numbytes = %u\n", numbytes); 1722 1723 SetLastError(0xdeadbeef); 1724 ret = WriteFile(hpipe, testdata, sizeof(testdata), &numbytes, NULL); 1725 ok(!ret, "WriteFile unexpectedly succeeded\n"); 1726 todo_wine ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %u\n", GetLastError()); 1727 1728 CloseHandle(hpipe); 1729 1730 hpipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, 1731 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1732 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); 1733 ok(hpipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError()); 1734 1735 hfile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 1736 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError()); 1737 1738 numbytes = 0xdeadbeef; 1739 ret = WriteFile(hfile, testdata, 0, &numbytes, NULL); 1740 ok(ret, "WriteFile failed with %u\n", GetLastError()); 1741 ok(numbytes == 0, "expected 0, got %u\n", numbytes); 1742 1743 ret = CloseHandle(hfile); 1744 ok(ret, "CloseHandle failed with %u\n", GetLastError()); 1745 1746 numbytes = 0xdeadbeef; 1747 memset(buffer, 0, sizeof(buffer)); 1748 ret = ReadFile(hpipe, buffer, sizeof(buffer), &numbytes, NULL); 1749 ok(ret, "ReadFile failed with %u\n", GetLastError()); 1750 ok(numbytes == 0, "expected 0, got %u\n", numbytes); 1751 1752 SetLastError(0xdeadbeef); 1753 ret = ReadFile(hpipe, buffer, 0, &numbytes, NULL); 1754 ok(!ret, "ReadFile unexpectedly succeeded\n"); 1755 ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError()); 1756 1757 ret = GetNamedPipeHandleStateA(hpipe, &state, NULL, NULL, NULL, NULL, 0); 1758 ok(ret, "GetNamedPipeHandleState failed with %u\n", GetLastError()); 1759 state = PIPE_READMODE_MESSAGE | PIPE_WAIT; 1760 ret = SetNamedPipeHandleState(hpipe, &state, NULL, NULL); 1761 ok(ret, "SetNamedPipeHandleState failed with %u\n", GetLastError()); 1762 1763 SetLastError(0xdeadbeef); 1764 ret = ReadFile(hpipe, buffer, 0, &numbytes, NULL); 1765 ok(!ret, "ReadFile unexpectedly succeeded\n"); 1766 ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError()); 1767 1768 SetLastError(0xdeadbeef); 1769 ret = WriteFile(hpipe, testdata, sizeof(testdata), &numbytes, NULL); 1770 ok(!ret, "WriteFile unexpectedly succeeded\n"); 1771 todo_wine ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %u\n", GetLastError()); 1772 1773 CloseHandle(hpipe); 1774 } 1775 1776 struct named_pipe_client_params 1777 { 1778 DWORD security_flags; 1779 HANDLE token; 1780 BOOL revert; 1781 }; 1782 1783 #define PIPE_NAME "\\\\.\\pipe\\named_pipe_test" 1784 1785 static DWORD CALLBACK named_pipe_client_func(LPVOID p) 1786 { 1787 struct named_pipe_client_params *params = p; 1788 HANDLE pipe; 1789 BOOL ret; 1790 const char message[] = "Test"; 1791 DWORD bytes_read, bytes_written; 1792 char dummy; 1793 TOKEN_PRIVILEGES *Privileges = NULL; 1794 1795 if (params->token) 1796 { 1797 if (params->revert) 1798 { 1799 /* modify the token so we can tell if the pipe impersonation 1800 * token reverts to the process token */ 1801 ret = AdjustTokenPrivileges(params->token, TRUE, NULL, 0, NULL, NULL); 1802 ok(ret, "AdjustTokenPrivileges failed with error %d\n", GetLastError()); 1803 } 1804 ret = SetThreadToken(NULL, params->token); 1805 ok(ret, "SetThreadToken failed with error %d\n", GetLastError()); 1806 } 1807 else 1808 { 1809 DWORD Size = 0; 1810 HANDLE process_token; 1811 1812 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES, &process_token); 1813 ok(ret, "OpenProcessToken failed with error %d\n", GetLastError()); 1814 1815 ret = GetTokenInformation(process_token, TokenPrivileges, NULL, 0, &Size); 1816 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenPrivileges) failed with %d\n", GetLastError()); 1817 Privileges = HeapAlloc(GetProcessHeap(), 0, Size); 1818 ret = GetTokenInformation(process_token, TokenPrivileges, Privileges, Size, &Size); 1819 ok(ret, "GetTokenInformation(TokenPrivileges) failed with %d\n", GetLastError()); 1820 1821 ret = AdjustTokenPrivileges(process_token, TRUE, NULL, 0, NULL, NULL); 1822 ok(ret, "AdjustTokenPrivileges failed with error %d\n", GetLastError()); 1823 1824 CloseHandle(process_token); 1825 } 1826 1827 pipe = CreateFileA(PIPE_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, params->security_flags, NULL); 1828 ok(pipe != INVALID_HANDLE_VALUE, "CreateFile for pipe failed with error %d\n", GetLastError()); 1829 1830 ret = WriteFile(pipe, message, sizeof(message), &bytes_written, NULL); 1831 ok(ret, "WriteFile failed with error %d\n", GetLastError()); 1832 1833 ret = ReadFile(pipe, &dummy, sizeof(dummy), &bytes_read, NULL); 1834 ok(ret, "ReadFile failed with error %d\n", GetLastError()); 1835 1836 if (params->token) 1837 { 1838 if (params->revert) 1839 { 1840 ret = RevertToSelf(); 1841 ok(ret, "RevertToSelf failed with error %d\n", GetLastError()); 1842 } 1843 else 1844 { 1845 ret = AdjustTokenPrivileges(params->token, TRUE, NULL, 0, NULL, NULL); 1846 ok(ret, "AdjustTokenPrivileges failed with error %d\n", GetLastError()); 1847 } 1848 } 1849 else 1850 { 1851 HANDLE process_token; 1852 1853 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &process_token); 1854 ok(ret, "OpenProcessToken failed with error %d\n", GetLastError()); 1855 1856 ret = AdjustTokenPrivileges(process_token, FALSE, Privileges, 0, NULL, NULL); 1857 ok(ret, "AdjustTokenPrivileges failed with error %d\n", GetLastError()); 1858 1859 HeapFree(GetProcessHeap(), 0, Privileges); 1860 1861 CloseHandle(process_token); 1862 } 1863 1864 ret = WriteFile(pipe, message, sizeof(message), &bytes_written, NULL); 1865 ok(ret, "WriteFile failed with error %d\n", GetLastError()); 1866 1867 ret = ReadFile(pipe, &dummy, sizeof(dummy), &bytes_read, NULL); 1868 ok(ret, "ReadFile failed with error %d\n", GetLastError()); 1869 1870 CloseHandle(pipe); 1871 1872 return 0; 1873 } 1874 1875 static HANDLE make_impersonation_token(DWORD Access, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel) 1876 { 1877 HANDLE ProcessToken; 1878 HANDLE Token = NULL; 1879 BOOL ret; 1880 1881 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &ProcessToken); 1882 ok(ret, "OpenProcessToken failed with error %d\n", GetLastError()); 1883 1884 ret = pDuplicateTokenEx(ProcessToken, Access, NULL, ImpersonationLevel, TokenImpersonation, &Token); 1885 ok(ret, "DuplicateToken failed with error %d\n", GetLastError()); 1886 1887 CloseHandle(ProcessToken); 1888 1889 return Token; 1890 } 1891 1892 static void test_ImpersonateNamedPipeClient(HANDLE hClientToken, DWORD security_flags, BOOL revert, void (*test_func)(int, HANDLE)) 1893 { 1894 HANDLE hPipeServer; 1895 BOOL ret; 1896 DWORD dwTid; 1897 HANDLE hThread; 1898 char buffer[256]; 1899 DWORD dwBytesRead; 1900 DWORD error; 1901 struct named_pipe_client_params params; 1902 char dummy = 0; 1903 DWORD dwBytesWritten; 1904 HANDLE hToken = NULL; 1905 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; 1906 DWORD size; 1907 1908 hPipeServer = CreateNamedPipeA(PIPE_NAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 100, 100, NMPWAIT_USE_DEFAULT_WAIT, NULL); 1909 ok(hPipeServer != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with error %d\n", GetLastError()); 1910 1911 params.security_flags = security_flags; 1912 params.token = hClientToken; 1913 params.revert = revert; 1914 hThread = CreateThread(NULL, 0, named_pipe_client_func, ¶ms, 0, &dwTid); 1915 ok(hThread != NULL, "CreateThread failed with error %d\n", GetLastError()); 1916 1917 SetLastError(0xdeadbeef); 1918 ret = ImpersonateNamedPipeClient(hPipeServer); 1919 error = GetLastError(); 1920 ok(ret /* win2k3 */ || (error == ERROR_CANNOT_IMPERSONATE), 1921 "ImpersonateNamedPipeClient should have failed with ERROR_CANNOT_IMPERSONATE instead of %d\n", GetLastError()); 1922 1923 ret = ConnectNamedPipe(hPipeServer, NULL); 1924 ok(ret || (GetLastError() == ERROR_PIPE_CONNECTED), "ConnectNamedPipe failed with error %d\n", GetLastError()); 1925 1926 ret = ReadFile(hPipeServer, buffer, sizeof(buffer), &dwBytesRead, NULL); 1927 ok(ret, "ReadFile failed with error %d\n", GetLastError()); 1928 1929 ret = ImpersonateNamedPipeClient(hPipeServer); 1930 ok(ret, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError()); 1931 1932 ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken); 1933 ok(ret, "OpenThreadToken failed with error %d\n", GetLastError()); 1934 1935 (*test_func)(0, hToken); 1936 1937 ImpersonationLevel = 0xdeadbeef; /* to avoid false positives */ 1938 ret = GetTokenInformation(hToken, TokenImpersonationLevel, &ImpersonationLevel, sizeof(ImpersonationLevel), &size); 1939 ok(ret, "GetTokenInformation(TokenImpersonationLevel) failed with error %d\n", GetLastError()); 1940 ok(ImpersonationLevel == SecurityImpersonation, "ImpersonationLevel should have been SecurityImpersonation(%d) instead of %d\n", SecurityImpersonation, ImpersonationLevel); 1941 1942 CloseHandle(hToken); 1943 1944 RevertToSelf(); 1945 1946 ret = WriteFile(hPipeServer, &dummy, sizeof(dummy), &dwBytesWritten, NULL); 1947 ok(ret, "WriteFile failed with error %d\n", GetLastError()); 1948 1949 ret = ReadFile(hPipeServer, buffer, sizeof(buffer), &dwBytesRead, NULL); 1950 ok(ret, "ReadFile failed with error %d\n", GetLastError()); 1951 1952 ret = ImpersonateNamedPipeClient(hPipeServer); 1953 ok(ret, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError()); 1954 1955 ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken); 1956 ok(ret, "OpenThreadToken failed with error %d\n", GetLastError()); 1957 1958 (*test_func)(1, hToken); 1959 1960 CloseHandle(hToken); 1961 1962 RevertToSelf(); 1963 1964 ret = WriteFile(hPipeServer, &dummy, sizeof(dummy), &dwBytesWritten, NULL); 1965 ok(ret, "WriteFile failed with error %d\n", GetLastError()); 1966 1967 WaitForSingleObject(hThread, INFINITE); 1968 1969 ret = ImpersonateNamedPipeClient(hPipeServer); 1970 ok(ret, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError()); 1971 1972 RevertToSelf(); 1973 1974 CloseHandle(hThread); 1975 CloseHandle(hPipeServer); 1976 } 1977 1978 static BOOL are_all_privileges_disabled(HANDLE hToken) 1979 { 1980 BOOL ret; 1981 TOKEN_PRIVILEGES *Privileges = NULL; 1982 DWORD Size = 0; 1983 BOOL all_privs_disabled = TRUE; 1984 DWORD i; 1985 1986 ret = GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &Size); 1987 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER) 1988 { 1989 Privileges = HeapAlloc(GetProcessHeap(), 0, Size); 1990 ret = GetTokenInformation(hToken, TokenPrivileges, Privileges, Size, &Size); 1991 if (!ret) 1992 { 1993 HeapFree(GetProcessHeap(), 0, Privileges); 1994 return FALSE; 1995 } 1996 } 1997 else 1998 return FALSE; 1999 2000 for (i = 0; i < Privileges->PrivilegeCount; i++) 2001 { 2002 if (Privileges->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) 2003 { 2004 all_privs_disabled = FALSE; 2005 break; 2006 } 2007 } 2008 2009 HeapFree(GetProcessHeap(), 0, Privileges); 2010 2011 return all_privs_disabled; 2012 } 2013 2014 static DWORD get_privilege_count(HANDLE hToken) 2015 { 2016 TOKEN_STATISTICS Statistics; 2017 DWORD Size = sizeof(Statistics); 2018 BOOL ret; 2019 2020 ret = GetTokenInformation(hToken, TokenStatistics, &Statistics, Size, &Size); 2021 ok(ret, "GetTokenInformation(TokenStatistics)\n"); 2022 if (!ret) return -1; 2023 2024 return Statistics.PrivilegeCount; 2025 } 2026 2027 static void test_no_sqos_no_token(int call_index, HANDLE hToken) 2028 { 2029 DWORD priv_count; 2030 2031 switch (call_index) 2032 { 2033 case 0: 2034 priv_count = get_privilege_count(hToken); 2035 todo_wine 2036 ok(priv_count == 0, "privilege count should have been 0 instead of %d\n", priv_count); 2037 break; 2038 case 1: 2039 priv_count = get_privilege_count(hToken); 2040 ok(priv_count > 0, "privilege count should now be > 0 instead of 0\n"); 2041 ok(!are_all_privileges_disabled(hToken), "impersonated token should not have been modified\n"); 2042 break; 2043 default: 2044 ok(0, "shouldn't happen\n"); 2045 } 2046 } 2047 2048 static void test_no_sqos(int call_index, HANDLE hToken) 2049 { 2050 switch (call_index) 2051 { 2052 case 0: 2053 ok(!are_all_privileges_disabled(hToken), "token should be a copy of the process one\n"); 2054 break; 2055 case 1: 2056 todo_wine 2057 ok(are_all_privileges_disabled(hToken), "impersonated token should have been modified\n"); 2058 break; 2059 default: 2060 ok(0, "shouldn't happen\n"); 2061 } 2062 } 2063 2064 static void test_static_context(int call_index, HANDLE hToken) 2065 { 2066 switch (call_index) 2067 { 2068 case 0: 2069 ok(!are_all_privileges_disabled(hToken), "token should be a copy of the process one\n"); 2070 break; 2071 case 1: 2072 ok(!are_all_privileges_disabled(hToken), "impersonated token should not have been modified\n"); 2073 break; 2074 default: 2075 ok(0, "shouldn't happen\n"); 2076 } 2077 } 2078 2079 static void test_dynamic_context(int call_index, HANDLE hToken) 2080 { 2081 switch (call_index) 2082 { 2083 case 0: 2084 ok(!are_all_privileges_disabled(hToken), "token should be a copy of the process one\n"); 2085 break; 2086 case 1: 2087 todo_wine 2088 ok(are_all_privileges_disabled(hToken), "impersonated token should have been modified\n"); 2089 break; 2090 default: 2091 ok(0, "shouldn't happen\n"); 2092 } 2093 } 2094 2095 static void test_dynamic_context_no_token(int call_index, HANDLE hToken) 2096 { 2097 switch (call_index) 2098 { 2099 case 0: 2100 ok(are_all_privileges_disabled(hToken), "token should be a copy of the process one\n"); 2101 break; 2102 case 1: 2103 ok(!are_all_privileges_disabled(hToken), "process token modification should have been detected and impersonation token updated\n"); 2104 break; 2105 default: 2106 ok(0, "shouldn't happen\n"); 2107 } 2108 } 2109 2110 static void test_no_sqos_revert(int call_index, HANDLE hToken) 2111 { 2112 DWORD priv_count; 2113 switch (call_index) 2114 { 2115 case 0: 2116 priv_count = get_privilege_count(hToken); 2117 todo_wine 2118 ok(priv_count == 0, "privilege count should have been 0 instead of %d\n", priv_count); 2119 break; 2120 case 1: 2121 priv_count = get_privilege_count(hToken); 2122 ok(priv_count > 0, "privilege count should now be > 0 instead of 0\n"); 2123 ok(!are_all_privileges_disabled(hToken), "impersonated token should not have been modified\n"); 2124 break; 2125 default: 2126 ok(0, "shouldn't happen\n"); 2127 } 2128 } 2129 2130 static void test_static_context_revert(int call_index, HANDLE hToken) 2131 { 2132 switch (call_index) 2133 { 2134 case 0: 2135 todo_wine 2136 ok(are_all_privileges_disabled(hToken), "privileges should have been disabled\n"); 2137 break; 2138 case 1: 2139 todo_wine 2140 ok(are_all_privileges_disabled(hToken), "impersonated token should not have been modified\n"); 2141 break; 2142 default: 2143 ok(0, "shouldn't happen\n"); 2144 } 2145 } 2146 2147 static void test_dynamic_context_revert(int call_index, HANDLE hToken) 2148 { 2149 switch (call_index) 2150 { 2151 case 0: 2152 todo_wine 2153 ok(are_all_privileges_disabled(hToken), "privileges should have been disabled\n"); 2154 break; 2155 case 1: 2156 ok(!are_all_privileges_disabled(hToken), "impersonated token should now be process token\n"); 2157 break; 2158 default: 2159 ok(0, "shouldn't happen\n"); 2160 } 2161 } 2162 2163 static void test_impersonation(void) 2164 { 2165 HANDLE hClientToken; 2166 HANDLE hProcessToken; 2167 BOOL ret; 2168 2169 if( !pDuplicateTokenEx ) { 2170 skip("DuplicateTokenEx not found\n"); 2171 return; 2172 } 2173 2174 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hProcessToken); 2175 if (!ret) 2176 { 2177 skip("couldn't open process token, skipping impersonation tests\n"); 2178 return; 2179 } 2180 2181 if (!get_privilege_count(hProcessToken) || are_all_privileges_disabled(hProcessToken)) 2182 { 2183 skip("token didn't have any privileges or they were all disabled. token not suitable for impersonation tests\n"); 2184 CloseHandle(hProcessToken); 2185 return; 2186 } 2187 CloseHandle(hProcessToken); 2188 2189 test_ImpersonateNamedPipeClient(NULL, 0, FALSE, test_no_sqos_no_token); 2190 hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation); 2191 test_ImpersonateNamedPipeClient(hClientToken, 0, FALSE, test_no_sqos); 2192 CloseHandle(hClientToken); 2193 hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation); 2194 test_ImpersonateNamedPipeClient(hClientToken, 2195 SECURITY_SQOS_PRESENT | SECURITY_IMPERSONATION, FALSE, 2196 test_static_context); 2197 CloseHandle(hClientToken); 2198 hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation); 2199 test_ImpersonateNamedPipeClient(hClientToken, 2200 SECURITY_SQOS_PRESENT | SECURITY_CONTEXT_TRACKING | SECURITY_IMPERSONATION, 2201 FALSE, test_dynamic_context); 2202 CloseHandle(hClientToken); 2203 test_ImpersonateNamedPipeClient(NULL, 2204 SECURITY_SQOS_PRESENT | SECURITY_CONTEXT_TRACKING | SECURITY_IMPERSONATION, 2205 FALSE, test_dynamic_context_no_token); 2206 2207 hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation); 2208 test_ImpersonateNamedPipeClient(hClientToken, 0, TRUE, test_no_sqos_revert); 2209 CloseHandle(hClientToken); 2210 hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation); 2211 test_ImpersonateNamedPipeClient(hClientToken, 2212 SECURITY_SQOS_PRESENT | SECURITY_IMPERSONATION, TRUE, 2213 test_static_context_revert); 2214 CloseHandle(hClientToken); 2215 hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation); 2216 test_ImpersonateNamedPipeClient(hClientToken, 2217 SECURITY_SQOS_PRESENT | SECURITY_CONTEXT_TRACKING | SECURITY_IMPERSONATION, 2218 TRUE, test_dynamic_context_revert); 2219 CloseHandle(hClientToken); 2220 } 2221 2222 struct overlapped_server_args 2223 { 2224 HANDLE pipe_created; 2225 }; 2226 2227 static DWORD CALLBACK overlapped_server(LPVOID arg) 2228 { 2229 OVERLAPPED ol; 2230 HANDLE pipe; 2231 int ret, err; 2232 struct overlapped_server_args *a = arg; 2233 DWORD num; 2234 char buf[100]; 2235 2236 pipe = CreateNamedPipeA("\\\\.\\pipe\\my pipe", FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 1, 0, 0, 100000, NULL); 2237 ok(pipe != NULL, "pipe NULL\n"); 2238 2239 ol.hEvent = CreateEventA(0, 1, 0, 0); 2240 ok(ol.hEvent != NULL, "event NULL\n"); 2241 ret = ConnectNamedPipe(pipe, &ol); 2242 err = GetLastError(); 2243 ok(ret == 0, "ret %d\n", ret); 2244 ok(err == ERROR_IO_PENDING, "gle %d\n", err); 2245 SetEvent(a->pipe_created); 2246 2247 ret = WaitForSingleObjectEx(ol.hEvent, INFINITE, 1); 2248 ok(ret == WAIT_OBJECT_0, "ret %x\n", ret); 2249 2250 ret = GetOverlappedResult(pipe, &ol, &num, 1); 2251 ok(ret == 1, "ret %d\n", ret); 2252 2253 /* This should block */ 2254 ret = ReadFile(pipe, buf, sizeof(buf), &num, NULL); 2255 ok(ret == 1, "ret %d\n", ret); 2256 2257 DisconnectNamedPipe(pipe); 2258 2259 ret = ConnectNamedPipe(pipe, &ol); 2260 err = GetLastError(); 2261 ok(ret == 0, "ret %d\n", ret); 2262 ok(err == ERROR_IO_PENDING, "gle %d\n", err); 2263 CancelIo(pipe); 2264 ret = WaitForSingleObjectEx(ol.hEvent, INFINITE, 1); 2265 ok(ret == WAIT_OBJECT_0, "ret %x\n", ret); 2266 2267 ret = GetOverlappedResult(pipe, &ol, &num, 1); 2268 err = GetLastError(); 2269 ok(ret == 0, "ret %d\n", ret); 2270 ok(err == ERROR_OPERATION_ABORTED, "gle %d\n", err); 2271 2272 CloseHandle(ol.hEvent); 2273 CloseHandle(pipe); 2274 return 1; 2275 } 2276 2277 static void test_overlapped(void) 2278 { 2279 DWORD tid, num; 2280 HANDLE thread, pipe; 2281 BOOL ret; 2282 struct overlapped_server_args args; 2283 2284 args.pipe_created = CreateEventA(0, 1, 0, 0); 2285 thread = CreateThread(NULL, 0, overlapped_server, &args, 0, &tid); 2286 2287 WaitForSingleObject(args.pipe_created, INFINITE); 2288 pipe = CreateFileA("\\\\.\\pipe\\my pipe", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); 2289 ok(pipe != INVALID_HANDLE_VALUE, "cf failed\n"); 2290 2291 /* Sleep to try to get the ReadFile in the server to occur before the following WriteFile */ 2292 Sleep(1); 2293 2294 ret = WriteFile(pipe, "x", 1, &num, NULL); 2295 ok(ret, "WriteFile failed with error %d\n", GetLastError()); 2296 2297 WaitForSingleObject(thread, INFINITE); 2298 CloseHandle(pipe); 2299 CloseHandle(args.pipe_created); 2300 CloseHandle(thread); 2301 } 2302 2303 static void test_overlapped_error(void) 2304 { 2305 HANDLE pipe, file, event; 2306 DWORD err, numbytes; 2307 OVERLAPPED overlapped; 2308 BOOL ret; 2309 2310 event = CreateEventA(NULL, TRUE, FALSE, NULL); 2311 ok(event != NULL, "CreateEventA failed with %u\n", GetLastError()); 2312 2313 pipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 2314 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 2315 1, 1024, 1024, NMPWAIT_WAIT_FOREVER, NULL); 2316 ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError()); 2317 2318 memset(&overlapped, 0, sizeof(overlapped)); 2319 overlapped.hEvent = event; 2320 ret = ConnectNamedPipe(pipe, &overlapped); 2321 err = GetLastError(); 2322 ok(ret == FALSE, "ConnectNamedPipe succeeded\n"); 2323 ok(err == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", err); 2324 2325 file = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, 2326 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); 2327 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError()); 2328 2329 numbytes = 0xdeadbeef; 2330 ret = GetOverlappedResult(pipe, &overlapped, &numbytes, TRUE); 2331 ok(ret == TRUE, "GetOverlappedResult failed\n"); 2332 ok(numbytes == 0, "expected 0, got %u\n", numbytes); 2333 ok(overlapped.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08lx\n", overlapped.Internal); 2334 2335 CloseHandle(file); 2336 CloseHandle(pipe); 2337 2338 pipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 2339 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 2340 1, 1024, 1024, NMPWAIT_WAIT_FOREVER, NULL); 2341 ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError()); 2342 2343 file = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, 2344 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); 2345 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError()); 2346 2347 memset(&overlapped, 0, sizeof(overlapped)); 2348 overlapped.hEvent = event; 2349 ret = ConnectNamedPipe(pipe, &overlapped); 2350 err = GetLastError(); 2351 ok(ret == FALSE, "ConnectNamedPipe succeeded\n"); 2352 ok(err == ERROR_PIPE_CONNECTED, "expected ERROR_PIPE_CONNECTED, got %u\n", err); 2353 ok(overlapped.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %08lx\n", overlapped.Internal); 2354 2355 CloseHandle(file); 2356 CloseHandle(pipe); 2357 2358 CloseHandle(event); 2359 } 2360 2361 static void test_NamedPipeHandleState(void) 2362 { 2363 HANDLE server, client; 2364 BOOL ret; 2365 DWORD state, instances, maxCollectionCount, collectDataTimeout; 2366 char userName[MAX_PATH]; 2367 2368 server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, 2369 /* dwOpenMode */ PIPE_TYPE_BYTE | PIPE_WAIT, 2370 /* nMaxInstances */ 1, 2371 /* nOutBufSize */ 1024, 2372 /* nInBufSize */ 1024, 2373 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 2374 /* lpSecurityAttrib */ NULL); 2375 ok(server != INVALID_HANDLE_VALUE, "cf failed\n"); 2376 ret = GetNamedPipeHandleStateA(server, NULL, NULL, NULL, NULL, NULL, 0); 2377 ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError()); 2378 ret = GetNamedPipeHandleStateA(server, &state, &instances, NULL, NULL, NULL, 2379 0); 2380 ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError()); 2381 if (ret) 2382 { 2383 ok(state == 0, "unexpected state %08x\n", state); 2384 ok(instances == 1, "expected 1 instances, got %d\n", instances); 2385 } 2386 /* Some parameters have no meaning, and therefore can't be retrieved, 2387 * on a local pipe. 2388 */ 2389 SetLastError(0xdeadbeef); 2390 ret = GetNamedPipeHandleStateA(server, &state, &instances, 2391 &maxCollectionCount, &collectDataTimeout, userName, 2392 sizeof(userName) / sizeof(userName[0])); 2393 todo_wine 2394 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 2395 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 2396 /* A byte-mode pipe server can't be changed to message mode. */ 2397 state = PIPE_READMODE_MESSAGE; 2398 SetLastError(0xdeadbeef); 2399 ret = SetNamedPipeHandleState(server, &state, NULL, NULL); 2400 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 2401 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 2402 2403 client = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, NULL, 2404 OPEN_EXISTING, 0, NULL); 2405 ok(client != INVALID_HANDLE_VALUE, "cf failed\n"); 2406 2407 state = PIPE_READMODE_BYTE; 2408 ret = SetNamedPipeHandleState(client, &state, NULL, NULL); 2409 ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError()); 2410 /* A byte-mode pipe client can't be changed to message mode, either. */ 2411 state = PIPE_READMODE_MESSAGE; 2412 SetLastError(0xdeadbeef); 2413 ret = SetNamedPipeHandleState(server, &state, NULL, NULL); 2414 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 2415 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 2416 2417 CloseHandle(client); 2418 CloseHandle(server); 2419 2420 server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, 2421 /* dwOpenMode */ PIPE_TYPE_MESSAGE | PIPE_WAIT, 2422 /* nMaxInstances */ 1, 2423 /* nOutBufSize */ 1024, 2424 /* nInBufSize */ 1024, 2425 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 2426 /* lpSecurityAttrib */ NULL); 2427 ok(server != INVALID_HANDLE_VALUE, "cf failed\n"); 2428 ret = GetNamedPipeHandleStateA(server, NULL, NULL, NULL, NULL, NULL, 0); 2429 ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError()); 2430 ret = GetNamedPipeHandleStateA(server, &state, &instances, NULL, NULL, NULL, 2431 0); 2432 ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError()); 2433 if (ret) 2434 { 2435 ok(state == 0, "unexpected state %08x\n", state); 2436 ok(instances == 1, "expected 1 instances, got %d\n", instances); 2437 } 2438 /* In contrast to byte-mode pipes, a message-mode pipe server can be 2439 * changed to byte mode. 2440 */ 2441 state = PIPE_READMODE_BYTE; 2442 ret = SetNamedPipeHandleState(server, &state, NULL, NULL); 2443 ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError()); 2444 2445 client = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, NULL, 2446 OPEN_EXISTING, 0, NULL); 2447 ok(client != INVALID_HANDLE_VALUE, "cf failed\n"); 2448 2449 state = PIPE_READMODE_MESSAGE; 2450 ret = SetNamedPipeHandleState(client, &state, NULL, NULL); 2451 ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError()); 2452 /* A message-mode pipe client can also be changed to byte mode. 2453 */ 2454 state = PIPE_READMODE_BYTE; 2455 ret = SetNamedPipeHandleState(client, &state, NULL, NULL); 2456 ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError()); 2457 2458 CloseHandle(client); 2459 CloseHandle(server); 2460 } 2461 2462 static void test_GetNamedPipeInfo(void) 2463 { 2464 HANDLE server; 2465 2466 server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, 2467 /* dwOpenMode */ PIPE_TYPE_BYTE | PIPE_WAIT, 2468 /* nMaxInstances */ 1, 2469 /* nOutBufSize */ 1024, 2470 /* nInBufSize */ 1024, 2471 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 2472 /* lpSecurityAttrib */ NULL); 2473 ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 2474 2475 test_pipe_info(server, PIPE_SERVER_END | PIPE_TYPE_BYTE, 1024, 1024, 1); 2476 2477 CloseHandle(server); 2478 2479 server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, 2480 /* dwOpenMode */ PIPE_TYPE_MESSAGE | PIPE_NOWAIT, 2481 /* nMaxInstances */ 3, 2482 /* nOutBufSize */ 1024, 2483 /* nInBufSize */ 1024, 2484 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 2485 /* lpSecurityAttrib */ NULL); 2486 ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 2487 2488 test_pipe_info(server, PIPE_SERVER_END | PIPE_TYPE_MESSAGE, 1024, 1024, 3); 2489 2490 CloseHandle(server); 2491 2492 server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, 2493 /* dwOpenMode */ PIPE_TYPE_MESSAGE | PIPE_WAIT, 2494 /* nMaxInstances */ 1, 2495 /* nOutBufSize */ 0, 2496 /* nInBufSize */ 0, 2497 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 2498 /* lpSecurityAttrib */ NULL); 2499 ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 2500 2501 test_pipe_info(server, PIPE_SERVER_END | PIPE_TYPE_MESSAGE, 0, 0, 1); 2502 2503 CloseHandle(server); 2504 2505 server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, 2506 /* dwOpenMode */ PIPE_TYPE_MESSAGE | PIPE_WAIT, 2507 /* nMaxInstances */ 1, 2508 /* nOutBufSize */ 0xf000, 2509 /* nInBufSize */ 0xf000, 2510 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 2511 /* lpSecurityAttrib */ NULL); 2512 ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 2513 2514 test_pipe_info(server, PIPE_SERVER_END | PIPE_TYPE_MESSAGE, 0xf000, 0xf000, 1); 2515 2516 CloseHandle(server); 2517 } 2518 2519 static void test_readfileex_pending(void) 2520 { 2521 HANDLE server, client, event; 2522 BOOL ret; 2523 DWORD err, wait, num_bytes; 2524 OVERLAPPED overlapped; 2525 char read_buf[1024]; 2526 char write_buf[1024]; 2527 const char test_string[] = "test"; 2528 int i; 2529 2530 server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, 2531 /* dwOpenMode */ PIPE_TYPE_BYTE | PIPE_WAIT, 2532 /* nMaxInstances */ 1, 2533 /* nOutBufSize */ 1024, 2534 /* nInBufSize */ 1024, 2535 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 2536 /* lpSecurityAttrib */ NULL); 2537 ok(server != INVALID_HANDLE_VALUE, "cf failed\n"); 2538 2539 event = CreateEventA(NULL, TRUE, FALSE, NULL); 2540 ok(event != NULL, "CreateEventA failed\n"); 2541 2542 memset(&overlapped, 0, sizeof(overlapped)); 2543 overlapped.hEvent = event; 2544 2545 ret = ConnectNamedPipe(server, &overlapped); 2546 err = GetLastError(); 2547 ok(ret == FALSE, "ConnectNamedPipe succeeded\n"); 2548 ok(err == ERROR_IO_PENDING, "ConnectNamedPipe set error %i\n", err); 2549 2550 wait = WaitForSingleObject(event, 0); 2551 ok(wait == WAIT_TIMEOUT, "WaitForSingleObject returned %x\n", wait); 2552 2553 client = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, NULL, 2554 OPEN_EXISTING, 0, NULL); 2555 ok(client != INVALID_HANDLE_VALUE, "cf failed\n"); 2556 2557 wait = WaitForSingleObject(event, 0); 2558 ok(wait == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", wait); 2559 2560 /* Start a read that can't complete immediately. */ 2561 completion_called = 0; 2562 ResetEvent(event); 2563 ret = ReadFileEx(server, read_buf, sizeof(read_buf), &overlapped, completion_routine); 2564 ok(ret == TRUE, "ReadFileEx failed, err=%i\n", GetLastError()); 2565 ok(completion_called == 0, "completion routine called before ReadFileEx returned\n"); 2566 2567 ret = WriteFile(client, test_string, strlen(test_string), &num_bytes, NULL); 2568 ok(ret == TRUE, "WriteFile failed\n"); 2569 ok(num_bytes == strlen(test_string), "only %i bytes written\n", num_bytes); 2570 2571 ok(completion_called == 0, "completion routine called during WriteFile\n"); 2572 2573 wait = WaitForSingleObjectEx(event, 0, TRUE); 2574 ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObjectEx returned %x\n", wait); 2575 2576 ok(completion_called == 1, "completion not called after writing pipe\n"); 2577 ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode); 2578 ok(completion_num_bytes == strlen(test_string), "ReadFileEx returned only %d bytes\n", completion_num_bytes); 2579 ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n"); 2580 ok(!memcmp(test_string, read_buf, strlen(test_string)), "ReadFileEx read wrong bytes\n"); 2581 2582 /* Make writes until the pipe is full and the write fails */ 2583 memset(write_buf, 0xaa, sizeof(write_buf)); 2584 for (i=0; i<256; i++) 2585 { 2586 completion_called = 0; 2587 ResetEvent(event); 2588 ret = WriteFileEx(server, write_buf, sizeof(write_buf), &overlapped, completion_routine); 2589 err = GetLastError(); 2590 2591 ok(completion_called == 0, "completion routine called during WriteFileEx\n"); 2592 2593 wait = WaitForSingleObjectEx(event, 0, TRUE); 2594 2595 if (wait == WAIT_TIMEOUT) 2596 /* write couldn't complete immediately, presumably the pipe is full */ 2597 break; 2598 2599 ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", wait); 2600 2601 ok(ret == TRUE, "WriteFileEx failed, err=%i\n", err); 2602 ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode); 2603 ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n"); 2604 } 2605 2606 ok(ret == TRUE, "WriteFileEx failed, err=%i\n", err); 2607 ok(completion_called == 0, "completion routine called but wait timed out\n"); 2608 ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode); 2609 ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n"); 2610 2611 /* free up some space in the pipe */ 2612 for (i=0; i<256; i++) 2613 { 2614 ret = ReadFile(client, read_buf, sizeof(read_buf), &num_bytes, NULL); 2615 ok(ret == TRUE, "ReadFile failed\n"); 2616 2617 ok(completion_called == 0, "completion routine called during ReadFile\n"); 2618 2619 wait = WaitForSingleObjectEx(event, 0, TRUE); 2620 ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0 || wait == WAIT_TIMEOUT, 2621 "WaitForSingleObject returned %x\n", wait); 2622 if (wait != WAIT_TIMEOUT) break; 2623 } 2624 2625 ok(completion_called == 1, "completion routine not called\n"); 2626 ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode); 2627 ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n"); 2628 2629 num_bytes = 0xdeadbeef; 2630 SetLastError(0xdeadbeef); 2631 ret = ReadFile(INVALID_HANDLE_VALUE, read_buf, 0, &num_bytes, NULL); 2632 ok(!ret, "ReadFile should fail\n"); 2633 ok(GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError()); 2634 ok(num_bytes == 0, "expected 0, got %u\n", num_bytes); 2635 2636 S(U(overlapped)).Offset = 0; 2637 S(U(overlapped)).OffsetHigh = 0; 2638 overlapped.Internal = -1; 2639 overlapped.InternalHigh = -1; 2640 overlapped.hEvent = event; 2641 num_bytes = 0xdeadbeef; 2642 SetLastError(0xdeadbeef); 2643 ret = ReadFile(server, read_buf, 0, &num_bytes, &overlapped); 2644 ok(!ret, "ReadFile should fail\n"); 2645 ok(GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %d\n", GetLastError()); 2646 ok(num_bytes == 0, "bytes %u\n", num_bytes); 2647 ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %#lx\n", overlapped.Internal); 2648 ok(overlapped.InternalHigh == -1, "expected -1, got %lu\n", overlapped.InternalHigh); 2649 2650 wait = WaitForSingleObject(event, 100); 2651 ok(wait == WAIT_TIMEOUT, "WaitForSingleObject returned %x\n", wait); 2652 2653 num_bytes = 0xdeadbeef; 2654 ret = WriteFile(client, test_string, 1, &num_bytes, NULL); 2655 ok(ret, "WriteFile failed\n"); 2656 ok(num_bytes == 1, "bytes %u\n", num_bytes); 2657 2658 wait = WaitForSingleObject(event, 100); 2659 ok(wait == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", wait); 2660 2661 ok(num_bytes == 1, "bytes %u\n", num_bytes); 2662 ok((NTSTATUS)overlapped.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", overlapped.Internal); 2663 ok(overlapped.InternalHigh == 0, "expected 0, got %lu\n", overlapped.InternalHigh); 2664 2665 /* read the pending byte and clear the pipe */ 2666 num_bytes = 0xdeadbeef; 2667 ret = ReadFile(server, read_buf, 1, &num_bytes, &overlapped); 2668 ok(ret, "ReadFile failed\n"); 2669 ok(num_bytes == 1, "bytes %u\n", num_bytes); 2670 2671 CloseHandle(client); 2672 CloseHandle(server); 2673 CloseHandle(event); 2674 } 2675 2676 #define test_peek_pipe(a,b,c,d) _test_peek_pipe(__LINE__,a,b,c,d) 2677 static void _test_peek_pipe(unsigned line, HANDLE pipe, DWORD expected_read, DWORD expected_avail, DWORD expected_message_length) 2678 { 2679 DWORD bytes_read = 0xdeadbeed, avail = 0xdeadbeef, left = 0xdeadbeed; 2680 char buf[4000]; 2681 FILE_PIPE_PEEK_BUFFER *peek_buf = (void*)buf; 2682 IO_STATUS_BLOCK io; 2683 NTSTATUS status; 2684 BOOL r; 2685 2686 r = PeekNamedPipe(pipe, buf, sizeof(buf), &bytes_read, &avail, &left); 2687 ok_(__FILE__,line)(r, "PeekNamedPipe failed: %u\n", GetLastError()); 2688 ok_(__FILE__,line)(bytes_read == expected_read, "bytes_read = %u, expected %u\n", bytes_read, expected_read); 2689 ok_(__FILE__,line)(avail == expected_avail, "avail = %u, expected %u\n", avail, expected_avail); 2690 ok_(__FILE__,line)(left == expected_message_length - expected_read, "left = %d, expected %d\n", 2691 left, expected_message_length - expected_read); 2692 2693 status = NtFsControlFile(pipe, 0, NULL, NULL, &io, FSCTL_PIPE_PEEK, NULL, 0, buf, sizeof(buf)); 2694 ok_(__FILE__,line)(!status || status == STATUS_PENDING, "NtFsControlFile(FSCTL_PIPE_PEEK) failed: %x\n", status); 2695 ok_(__FILE__,line)(io.Information == FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[expected_read]), 2696 "io.Information = %lu\n", io.Information); 2697 ok_(__FILE__,line)(peek_buf->ReadDataAvailable == expected_avail, "ReadDataAvailable = %u, expected %u\n", 2698 peek_buf->ReadDataAvailable, expected_avail); 2699 ok_(__FILE__,line)(peek_buf->MessageLength == expected_message_length, "MessageLength = %u, expected %u\n", 2700 peek_buf->MessageLength, expected_message_length); 2701 2702 if (expected_read) 2703 { 2704 r = PeekNamedPipe(pipe, buf, 1, &bytes_read, &avail, &left); 2705 ok_(__FILE__,line)(r, "PeekNamedPipe failed: %u\n", GetLastError()); 2706 ok_(__FILE__,line)(bytes_read == 1, "bytes_read = %u, expected %u\n", bytes_read, expected_read); 2707 ok_(__FILE__,line)(avail == expected_avail, "avail = %u, expected %u\n", avail, expected_avail); 2708 ok_(__FILE__,line)(left == expected_message_length-1, "left = %d, expected %d\n", left, expected_message_length-1); 2709 } 2710 } 2711 2712 #define overlapped_read_sync(a,b,c,d,e) _overlapped_read_sync(__LINE__,a,b,c,d,e) 2713 static void _overlapped_read_sync(unsigned line, HANDLE reader, void *buf, DWORD buf_size, DWORD expected_result, BOOL partial_read) 2714 { 2715 DWORD read_bytes = 0xdeadbeef; 2716 OVERLAPPED overlapped; 2717 BOOL res; 2718 2719 memset(&overlapped, 0, sizeof(overlapped)); 2720 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 2721 res = ReadFile(reader, buf, buf_size, &read_bytes, &overlapped); 2722 if (partial_read) 2723 ok_(__FILE__,line)(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned: %x (%u)\n", res, GetLastError()); 2724 else 2725 ok_(__FILE__,line)(res, "ReadFile failed: %u\n", GetLastError()); 2726 if(partial_read) 2727 ok_(__FILE__,line)(!read_bytes, "read_bytes %u expected 0\n", read_bytes); 2728 else 2729 ok_(__FILE__,line)(read_bytes == expected_result, "read_bytes %u expected %u\n", read_bytes, expected_result); 2730 2731 read_bytes = 0xdeadbeef; 2732 res = GetOverlappedResult(reader, &overlapped, &read_bytes, FALSE); 2733 if (partial_read) 2734 ok_(__FILE__,line)(!res && GetLastError() == ERROR_MORE_DATA, 2735 "GetOverlappedResult returned: %x (%u)\n", res, GetLastError()); 2736 else 2737 ok_(__FILE__,line)(res, "GetOverlappedResult failed: %u\n", GetLastError()); 2738 ok_(__FILE__,line)(read_bytes == expected_result, "read_bytes %u expected %u\n", read_bytes, expected_result); 2739 CloseHandle(overlapped.hEvent); 2740 } 2741 2742 #define overlapped_read_async(a,b,c,d) _overlapped_read_async(__LINE__,a,b,c,d) 2743 static void _overlapped_read_async(unsigned line, HANDLE reader, void *buf, DWORD buf_size, OVERLAPPED *overlapped) 2744 { 2745 DWORD read_bytes = 0xdeadbeef; 2746 BOOL res; 2747 2748 memset(overlapped, 0, sizeof(*overlapped)); 2749 overlapped->hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 2750 res = ReadFile(reader, buf, buf_size, &read_bytes, overlapped); 2751 ok_(__FILE__,line)(!res && GetLastError() == ERROR_IO_PENDING, "ReadFile returned %x(%u)\n", res, GetLastError()); 2752 ok_(__FILE__,line)(!read_bytes, "read_bytes %u expected 0\n", read_bytes); 2753 2754 _test_not_signaled(line, overlapped->hEvent); 2755 } 2756 2757 #define overlapped_write_sync(a,b,c) _overlapped_write_sync(__LINE__,a,b,c) 2758 static void _overlapped_write_sync(unsigned line, HANDLE writer, void *buf, DWORD size) 2759 { 2760 DWORD written_bytes = 0xdeadbeef; 2761 OVERLAPPED overlapped; 2762 BOOL res; 2763 2764 memset(&overlapped, 0, sizeof(overlapped)); 2765 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 2766 res = WriteFile(writer, buf, size, &written_bytes, &overlapped); 2767 ok_(__FILE__,line)(res, "WriteFile returned %x(%u)\n", res, GetLastError()); 2768 ok_(__FILE__,line)(written_bytes == size, "WriteFile returned written_bytes = %u\n", written_bytes); 2769 2770 written_bytes = 0xdeadbeef; 2771 res = GetOverlappedResult(writer, &overlapped, &written_bytes, FALSE); 2772 ok_(__FILE__,line)(res, "GetOverlappedResult failed: %u\n", GetLastError()); 2773 ok_(__FILE__,line)(written_bytes == size, "GetOverlappedResult returned written_bytes %u expected %u\n", written_bytes, size); 2774 2775 CloseHandle(overlapped.hEvent); 2776 } 2777 2778 #define overlapped_write_async(a,b,c,d) _overlapped_write_async(__LINE__,a,b,c,d) 2779 static void _overlapped_write_async(unsigned line, HANDLE writer, void *buf, DWORD size, OVERLAPPED *overlapped) 2780 { 2781 DWORD written_bytes = 0xdeadbeef; 2782 BOOL res; 2783 2784 memset(overlapped, 0, sizeof(*overlapped)); 2785 overlapped->hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 2786 res = WriteFile(writer, buf, size, &written_bytes, overlapped); 2787 ok_(__FILE__,line)(!res && GetLastError() == ERROR_IO_PENDING, "WriteFile returned %x(%u)\n", res, GetLastError()); 2788 ok_(__FILE__,line)(!written_bytes, "written_bytes = %u\n", written_bytes); 2789 2790 _test_not_signaled(line, overlapped->hEvent); 2791 } 2792 2793 #define test_flush_sync(a) _test_flush_sync(__LINE__,a) 2794 static void _test_flush_sync(unsigned line, HANDLE pipe) 2795 { 2796 BOOL res; 2797 2798 res = FlushFileBuffers(pipe); 2799 ok_(__FILE__,line)(res, "FlushFileBuffers failed: %u\n", GetLastError()); 2800 } 2801 2802 static DWORD expected_flush_error; 2803 2804 static DWORD CALLBACK flush_proc(HANDLE pipe) 2805 { 2806 BOOL res; 2807 2808 res = FlushFileBuffers(pipe); 2809 if (expected_flush_error == ERROR_SUCCESS) 2810 ok(res, "FlushFileBuffers failed: %u\n", GetLastError()); 2811 else 2812 todo_wine ok(!res && GetLastError() == expected_flush_error, "FlushFileBuffers failed: %u\n", GetLastError()); 2813 return 0; 2814 } 2815 2816 #define test_flush_async(a,b) _test_flush_async(__LINE__,a,b) 2817 static HANDLE _test_flush_async(unsigned line, HANDLE pipe, DWORD error) 2818 { 2819 HANDLE thread; 2820 DWORD tid; 2821 2822 expected_flush_error = error; 2823 thread = CreateThread(NULL, 0, flush_proc, pipe, 0, &tid); 2824 ok_(__FILE__,line)(thread != NULL, "CreateThread failed: %u\n", GetLastError()); 2825 2826 Sleep(50); 2827 _test_not_signaled(line, thread); 2828 return thread; 2829 } 2830 2831 #define test_flush_done(a) _test_flush_done(__LINE__,a) 2832 static void _test_flush_done(unsigned line, HANDLE thread) 2833 { 2834 DWORD res = WaitForSingleObject(thread, 1000); 2835 ok_(__FILE__,line)(res == WAIT_OBJECT_0, "WaitForSingleObject returned %u (%u)\n", res, GetLastError()); 2836 CloseHandle(thread); 2837 } 2838 2839 #define test_overlapped_result(a,b,c,d) _test_overlapped_result(__LINE__,a,b,c,d) 2840 static void _test_overlapped_result(unsigned line, HANDLE handle, OVERLAPPED *overlapped, DWORD expected_result, BOOL partial_read) 2841 { 2842 DWORD result = 0xdeadbeef; 2843 BOOL res; 2844 2845 _test_signaled(line, overlapped->hEvent); 2846 2847 res = GetOverlappedResult(handle, overlapped, &result, FALSE); 2848 if (partial_read) 2849 ok_(__FILE__,line)(!res && GetLastError() == ERROR_MORE_DATA, "GetOverlappedResult returned: %x (%u)\n", res, GetLastError()); 2850 else 2851 ok_(__FILE__,line)(res, "GetOverlappedResult failed: %u\n", GetLastError()); 2852 ok_(__FILE__,line)(result == expected_result, "read_bytes = %u, expected %u\n", result, expected_result); 2853 CloseHandle(overlapped->hEvent); 2854 } 2855 2856 #define test_overlapped_failure(a,b,c) _test_overlapped_failure(__LINE__,a,b,c) 2857 static void _test_overlapped_failure(unsigned line, HANDLE handle, OVERLAPPED *overlapped, DWORD error) 2858 { 2859 DWORD result; 2860 BOOL res; 2861 2862 _test_signaled(line, overlapped->hEvent); 2863 2864 res = GetOverlappedResult(handle, overlapped, &result, FALSE); 2865 ok_(__FILE__,line)(!res && GetLastError() == error, "GetOverlappedResult returned: %x (%u), expected error %u\n", 2866 res, GetLastError(), error); 2867 ok_(__FILE__,line)(!result, "result = %u\n", result); 2868 CloseHandle(overlapped->hEvent); 2869 } 2870 2871 #define cancel_overlapped(a,b) _cancel_overlapped(__LINE__,a,b) 2872 static void _cancel_overlapped(unsigned line, HANDLE handle, OVERLAPPED *overlapped) 2873 { 2874 BOOL res; 2875 2876 res = pCancelIoEx(handle, overlapped); 2877 ok_(__FILE__,line)(res, "CancelIoEx failed: %u\n", GetLastError()); 2878 2879 _test_overlapped_failure(line, handle, overlapped, ERROR_OPERATION_ABORTED); 2880 } 2881 2882 static void test_blocking_rw(HANDLE writer, HANDLE reader, DWORD buf_size, BOOL msg_mode, BOOL msg_read) 2883 { 2884 OVERLAPPED read_overlapped, read_overlapped2, write_overlapped, write_overlapped2; 2885 char buf[10000], read_buf[10000]; 2886 HANDLE flush_thread; 2887 2888 memset(buf, 0xaa, sizeof(buf)); 2889 2890 /* test pending read with overlapped event */ 2891 overlapped_read_async(reader, read_buf, 1000, &read_overlapped); 2892 test_flush_sync(writer); 2893 test_peek_pipe(reader, 0, 0, 0); 2894 2895 /* write more data than needed for read */ 2896 overlapped_write_sync(writer, buf, 4000); 2897 test_overlapped_result(reader, &read_overlapped, 1000, msg_read); 2898 2899 /* test pending write with overlapped event */ 2900 overlapped_write_async(writer, buf, buf_size, &write_overlapped); 2901 2902 /* write one more byte */ 2903 overlapped_write_async(writer, buf, 1, &write_overlapped2); 2904 flush_thread = test_flush_async(writer, ERROR_SUCCESS); 2905 test_not_signaled(write_overlapped.hEvent); 2906 2907 /* empty write will not block */ 2908 overlapped_write_sync(writer, buf, 0); 2909 test_not_signaled(write_overlapped.hEvent); 2910 test_not_signaled(write_overlapped2.hEvent); 2911 2912 /* read remaining data from the first write */ 2913 overlapped_read_sync(reader, read_buf, 3000, 3000, FALSE); 2914 test_overlapped_result(writer, &write_overlapped, buf_size, FALSE); 2915 test_not_signaled(write_overlapped2.hEvent); 2916 test_not_signaled(flush_thread); 2917 2918 /* read one byte so that the next write fits the buffer */ 2919 overlapped_read_sync(reader, read_buf, 1, 1, msg_read); 2920 test_overlapped_result(writer, &write_overlapped2, 1, FALSE); 2921 2922 /* read the whole buffer */ 2923 overlapped_read_sync(reader, read_buf, buf_size, buf_size-msg_read, FALSE); 2924 2925 if(msg_read) 2926 overlapped_read_sync(reader, read_buf, 1000, 1, FALSE); 2927 2928 if(msg_mode) { 2929 /* we still have an empty message in queue */ 2930 overlapped_read_sync(reader, read_buf, 1000, 0, FALSE); 2931 } 2932 test_flush_done(flush_thread); 2933 2934 /* pipe is empty, the next read will block */ 2935 overlapped_read_async(reader, read_buf, 0, &read_overlapped); 2936 overlapped_read_async(reader, read_buf, 1000, &read_overlapped2); 2937 2938 /* write one byte */ 2939 overlapped_write_sync(writer, buf, 1); 2940 test_overlapped_result(reader, &read_overlapped, 0, msg_read); 2941 test_overlapped_result(reader, &read_overlapped2, 1, FALSE); 2942 2943 /* write a message larger than buffer */ 2944 overlapped_write_async(writer, buf, buf_size+2000, &write_overlapped); 2945 2946 /* read so that pending write is still larger than the buffer */ 2947 overlapped_read_sync(reader, read_buf, 1999, 1999, msg_read); 2948 test_not_signaled(write_overlapped.hEvent); 2949 2950 /* read one more byte */ 2951 overlapped_read_sync(reader, read_buf, 1, 1, msg_read); 2952 test_overlapped_result(writer, &write_overlapped, buf_size+2000, FALSE); 2953 2954 /* read remaining data */ 2955 overlapped_read_sync(reader, read_buf, buf_size+1, buf_size, FALSE); 2956 2957 /* simple pass of empty message */ 2958 overlapped_write_sync(writer, buf, 0); 2959 if(msg_mode) 2960 overlapped_read_sync(reader, read_buf, 1, 0, FALSE); 2961 2962 /* pipe is empty, the next read will block */ 2963 test_flush_sync(writer); 2964 overlapped_read_async(reader, read_buf, 0, &read_overlapped); 2965 overlapped_read_async(reader, read_buf, 1, &read_overlapped2); 2966 2967 /* 0 length write wakes one read in msg mode */ 2968 overlapped_write_sync(writer, buf, 0); 2969 if(msg_mode) 2970 test_overlapped_result(reader, &read_overlapped, 0, FALSE); 2971 else 2972 test_not_signaled(read_overlapped.hEvent); 2973 test_not_signaled(read_overlapped2.hEvent); 2974 overlapped_write_sync(writer, buf, 1); 2975 test_overlapped_result(reader, &read_overlapped2, 1, FALSE); 2976 2977 overlapped_write_sync(writer, buf, 20); 2978 test_peek_pipe(reader, 20, 20, msg_mode ? 20 : 0); 2979 overlapped_write_sync(writer, buf, 15); 2980 test_peek_pipe(reader, msg_mode ? 20 : 35, 35, msg_mode ? 20 : 0); 2981 overlapped_read_sync(reader, read_buf, 10, 10, msg_read); 2982 test_peek_pipe(reader, msg_mode ? 10 : 25, 25, msg_mode ? 10 : 0); 2983 overlapped_read_sync(reader, read_buf, 10, 10, FALSE); 2984 test_peek_pipe(reader, 15, 15, msg_mode ? 15 : 0); 2985 overlapped_read_sync(reader, read_buf, 15, 15, FALSE); 2986 2987 if(!pCancelIoEx) { 2988 win_skip("CancelIoEx not available\n"); 2989 return; 2990 } 2991 2992 /* add one more pending read, then cancel the first one */ 2993 overlapped_read_async(reader, read_buf, 1, &read_overlapped); 2994 overlapped_read_async(reader, read_buf, 1, &read_overlapped2); 2995 cancel_overlapped(reader, &read_overlapped2); 2996 test_not_signaled(read_overlapped.hEvent); 2997 overlapped_write_sync(writer, buf, 1); 2998 test_overlapped_result(reader, &read_overlapped, 1, FALSE); 2999 3000 /* make two async writes, cancel the first one and make sure that we read from the second one */ 3001 overlapped_write_async(writer, buf, buf_size+2000, &write_overlapped); 3002 overlapped_write_async(writer, buf, 1, &write_overlapped2); 3003 cancel_overlapped(writer, &write_overlapped); 3004 overlapped_read_sync(reader, read_buf, 1000, 1, FALSE); 3005 test_overlapped_result(writer, &write_overlapped2, 1, FALSE); 3006 3007 /* same as above, but parially read written data before canceling */ 3008 overlapped_write_async(writer, buf, buf_size+2000, &write_overlapped); 3009 overlapped_write_async(writer, buf, 1, &write_overlapped2); 3010 overlapped_read_sync(reader, read_buf, 10, 10, msg_read); 3011 test_not_signaled(write_overlapped.hEvent); 3012 cancel_overlapped(writer, &write_overlapped); 3013 overlapped_read_sync(reader, read_buf, 1000, 1, FALSE); 3014 test_overlapped_result(writer, &write_overlapped2, 1, FALSE); 3015 3016 /* empty queue by canceling write and make sure that flush is signaled */ 3017 overlapped_write_async(writer, buf, buf_size+2000, &write_overlapped); 3018 flush_thread = test_flush_async(writer, ERROR_SUCCESS); 3019 test_not_signaled(flush_thread); 3020 cancel_overlapped(writer, &write_overlapped); 3021 test_flush_done(flush_thread); 3022 } 3023 3024 static void child_process_write_pipe(HANDLE pipe) 3025 { 3026 OVERLAPPED overlapped; 3027 char buf[10000]; 3028 3029 memset(buf, 'x', sizeof(buf)); 3030 overlapped_write_async(pipe, buf, sizeof(buf), &overlapped); 3031 3032 /* sleep until parent process terminates this process */ 3033 Sleep(INFINITE); 3034 } 3035 3036 static HANDLE create_writepipe_process(HANDLE pipe) 3037 { 3038 STARTUPINFOA si = { sizeof(si) }; 3039 PROCESS_INFORMATION info; 3040 char **argv, buf[MAX_PATH]; 3041 BOOL res; 3042 3043 winetest_get_mainargs(&argv); 3044 sprintf(buf, "\"%s\" pipe writepipe %lx", argv[0], (UINT_PTR)pipe); 3045 res = CreateProcessA(NULL, buf, NULL, NULL, TRUE, 0L, NULL, NULL, &si, &info); 3046 ok(res, "CreateProcess failed: %u\n", GetLastError()); 3047 CloseHandle(info.hThread); 3048 3049 return info.hProcess; 3050 } 3051 3052 static void create_overlapped_pipe(DWORD mode, HANDLE *client, HANDLE *server) 3053 { 3054 SECURITY_ATTRIBUTES sec_attr = { sizeof(sec_attr), NULL, TRUE }; 3055 DWORD read_mode = mode & (PIPE_READMODE_BYTE | PIPE_READMODE_MESSAGE); 3056 OVERLAPPED overlapped; 3057 BOOL res; 3058 3059 *server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, 3060 PIPE_WAIT | mode, 1, 5000, 6000, NMPWAIT_USE_DEFAULT_WAIT, NULL); 3061 ok(&server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %u\n", GetLastError()); 3062 test_signaled(*server); 3063 3064 memset(&overlapped, 0, sizeof(overlapped)); 3065 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 3066 res = ConnectNamedPipe(*server, &overlapped); 3067 ok(!res && GetLastError() == ERROR_IO_PENDING, "WriteFile returned %x(%u)\n", res, GetLastError()); 3068 test_not_signaled(*server); 3069 test_not_signaled(overlapped.hEvent); 3070 3071 *client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, &sec_attr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); 3072 ok(*server != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError()); 3073 3074 res = SetNamedPipeHandleState(*client, &read_mode, NULL, NULL); 3075 ok(res, "SetNamedPipeHandleState failed: %u\n", GetLastError()); 3076 3077 test_signaled(*client); 3078 test_not_signaled(*server); 3079 test_overlapped_result(*server, &overlapped, 0, FALSE); 3080 } 3081 3082 static void test_overlapped_transport(BOOL msg_mode, BOOL msg_read_mode) 3083 { 3084 OVERLAPPED overlapped, overlapped2; 3085 HANDLE server, client, flush; 3086 DWORD read_bytes; 3087 HANDLE process; 3088 char buf[60000]; 3089 BOOL res; 3090 3091 DWORD create_flags = 3092 (msg_mode ? PIPE_TYPE_MESSAGE : PIPE_TYPE_BYTE) | 3093 (msg_read_mode ? PIPE_READMODE_MESSAGE : PIPE_READMODE_BYTE); 3094 3095 create_overlapped_pipe(create_flags, &client, &server); 3096 3097 trace("testing %s, %s server->client writes...\n", 3098 msg_mode ? "message mode" : "byte mode", msg_read_mode ? "message read" : "byte read"); 3099 test_blocking_rw(server, client, 5000, msg_mode, msg_read_mode); 3100 trace("testing %s, %s client->server writes...\n", 3101 msg_mode ? "message mode" : "byte mode", msg_read_mode ? "message read" : "byte read"); 3102 test_blocking_rw(client, server, 6000, msg_mode, msg_read_mode); 3103 3104 CloseHandle(client); 3105 CloseHandle(server); 3106 3107 /* close client with pending writes */ 3108 create_overlapped_pipe(create_flags, &client, &server); 3109 overlapped_write_async(server, buf, 7000, &overlapped); 3110 flush = test_flush_async(server, ERROR_BROKEN_PIPE); 3111 CloseHandle(client); 3112 test_overlapped_failure(server, &overlapped, ERROR_BROKEN_PIPE); 3113 test_flush_done(flush); 3114 CloseHandle(server); 3115 3116 /* close server with pending writes */ 3117 create_overlapped_pipe(create_flags, &client, &server); 3118 overlapped_write_async(client, buf, 7000, &overlapped); 3119 flush = test_flush_async(client, ERROR_BROKEN_PIPE); 3120 CloseHandle(server); 3121 test_overlapped_failure(client, &overlapped, ERROR_BROKEN_PIPE); 3122 test_flush_done(flush); 3123 CloseHandle(client); 3124 3125 /* disconnect with pending writes */ 3126 create_overlapped_pipe(create_flags, &client, &server); 3127 overlapped_write_async(client, buf, 7000, &overlapped); 3128 overlapped_write_async(server, buf, 7000, &overlapped2); 3129 flush = test_flush_async(client, ERROR_PIPE_NOT_CONNECTED); 3130 res = DisconnectNamedPipe(server); 3131 ok(res, "DisconnectNamedPipe failed: %u\n", GetLastError()); 3132 test_overlapped_failure(client, &overlapped, ERROR_PIPE_NOT_CONNECTED); 3133 test_overlapped_failure(client, &overlapped2, ERROR_PIPE_NOT_CONNECTED); 3134 test_flush_done(flush); 3135 CloseHandle(server); 3136 CloseHandle(client); 3137 3138 /* terminate process with pending write */ 3139 create_overlapped_pipe(create_flags, &client, &server); 3140 process = create_writepipe_process(client); 3141 /* successfully read part of write that is pending in child process */ 3142 res = ReadFile(server, buf, 10, &read_bytes, NULL); 3143 if(!msg_read_mode) 3144 ok(res, "ReadFile failed: %u\n", GetLastError()); 3145 else 3146 ok(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned: %x %u\n", res, GetLastError()); 3147 ok(read_bytes == 10, "read_bytes = %u\n", read_bytes); 3148 TerminateProcess(process, 0); 3149 winetest_wait_child_process(process); 3150 /* after terminating process, there is no pending write and pipe buffer is empty */ 3151 overlapped_read_async(server, buf, 10, &overlapped); 3152 overlapped_write_sync(client, buf, 1); 3153 test_overlapped_result(server, &overlapped, 1, FALSE); 3154 CloseHandle(process); 3155 CloseHandle(server); 3156 CloseHandle(client); 3157 } 3158 3159 START_TEST(pipe) 3160 { 3161 char **argv; 3162 int argc; 3163 HMODULE hmod; 3164 3165 hmod = GetModuleHandleA("advapi32.dll"); 3166 pDuplicateTokenEx = (void *) GetProcAddress(hmod, "DuplicateTokenEx"); 3167 hmod = GetModuleHandleA("kernel32.dll"); 3168 pQueueUserAPC = (void *) GetProcAddress(hmod, "QueueUserAPC"); 3169 pCancelIoEx = (void *) GetProcAddress(hmod, "CancelIoEx"); 3170 3171 argc = winetest_get_mainargs(&argv); 3172 3173 if (argc > 3 && !strcmp(argv[2], "writepipe")) 3174 { 3175 UINT_PTR handle; 3176 sscanf(argv[3], "%lx", &handle); 3177 child_process_write_pipe((HANDLE)handle); 3178 return; 3179 } 3180 3181 if (test_DisconnectNamedPipe()) 3182 return; 3183 test_CreateNamedPipe_instances_must_match(); 3184 test_NamedPipe_2(); 3185 test_CreateNamedPipe(PIPE_TYPE_BYTE); 3186 test_CreateNamedPipe(PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE); 3187 test_CreatePipe(); 3188 test_ReadFile(); 3189 test_CloseHandle(); 3190 test_impersonation(); 3191 test_overlapped(); 3192 test_overlapped_error(); 3193 test_NamedPipeHandleState(); 3194 test_GetNamedPipeInfo(); 3195 test_readfileex_pending(); 3196 test_overlapped_transport(TRUE, FALSE); 3197 test_overlapped_transport(TRUE, TRUE); 3198 test_overlapped_transport(FALSE, FALSE); 3199 } 3200