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