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