Reactos
at master 4409 lines 185 kB view raw
1/* 2 * Unit tests for named pipe functions in Wine 3 * 4 * Copyright (c) 2002 Dan Kegel 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21#include <stdarg.h> 22#include <stdio.h> 23 24#include "ntstatus.h" 25#define WIN32_NO_STATUS 26#include "windef.h" 27#include "winbase.h" 28#include "winternl.h" 29#include "winioctl.h" 30#include "wine/test.h" 31 32#define PIPENAME "\\\\.\\PiPe\\tests_pipe.c" 33 34#define NB_SERVER_LOOPS 8 35 36static HANDLE alarm_event; 37static BOOL (WINAPI *pDuplicateTokenEx)(HANDLE,DWORD,LPSECURITY_ATTRIBUTES, 38 SECURITY_IMPERSONATION_LEVEL,TOKEN_TYPE,PHANDLE); 39static BOOL (WINAPI *pCancelIoEx)(HANDLE handle, LPOVERLAPPED lpOverlapped); 40static BOOL (WINAPI *pCancelSynchronousIo)(HANDLE handle); 41static BOOL (WINAPI *pGetNamedPipeClientProcessId)(HANDLE,ULONG*); 42static BOOL (WINAPI *pGetNamedPipeServerProcessId)(HANDLE,ULONG*); 43static BOOL (WINAPI *pGetNamedPipeClientSessionId)(HANDLE,ULONG*); 44static BOOL (WINAPI *pGetNamedPipeServerSessionId)(HANDLE,ULONG*); 45static BOOL (WINAPI *pGetOverlappedResultEx)(HANDLE,OVERLAPPED *,DWORD *,DWORD,BOOL); 46 47static BOOL user_apc_ran; 48static void CALLBACK user_apc(ULONG_PTR param) 49{ 50 user_apc_ran = TRUE; 51} 52 53 54enum rpcThreadOp 55{ 56 RPC_READFILE 57}; 58 59struct rpcThreadArgs 60{ 61 ULONG_PTR returnValue; 62 DWORD lastError; 63 enum rpcThreadOp op; 64 ULONG_PTR args[5]; 65}; 66 67static DWORD CALLBACK rpcThreadMain(LPVOID arg) 68{ 69 struct rpcThreadArgs *rpcargs = (struct rpcThreadArgs *)arg; 70 if (winetest_debug > 1) trace("rpcThreadMain starting\n"); 71 SetLastError( rpcargs->lastError ); 72 73 switch (rpcargs->op) 74 { 75 case RPC_READFILE: 76 rpcargs->returnValue = (ULONG_PTR)ReadFile( (HANDLE)rpcargs->args[0], /* hFile */ 77 (LPVOID)rpcargs->args[1], /* buffer */ 78 (DWORD)rpcargs->args[2], /* bytesToRead */ 79 (LPDWORD)rpcargs->args[3], /* bytesRead */ 80 (LPOVERLAPPED)rpcargs->args[4] ); /* overlapped */ 81 break; 82 83 default: 84 SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); 85 rpcargs->returnValue = 0; 86 break; 87 } 88 89 rpcargs->lastError = GetLastError(); 90 if (winetest_debug > 1) trace("rpcThreadMain returning\n"); 91 return 0; 92} 93 94/* Runs ReadFile(...) from a different thread */ 95static BOOL RpcReadFile(HANDLE hFile, LPVOID buffer, DWORD bytesToRead, LPDWORD bytesRead, LPOVERLAPPED overlapped) 96{ 97 struct rpcThreadArgs rpcargs; 98 HANDLE thread; 99 DWORD threadId, ret; 100 101 rpcargs.returnValue = 0; 102 rpcargs.lastError = GetLastError(); 103 rpcargs.op = RPC_READFILE; 104 rpcargs.args[0] = (ULONG_PTR)hFile; 105 rpcargs.args[1] = (ULONG_PTR)buffer; 106 rpcargs.args[2] = (ULONG_PTR)bytesToRead; 107 rpcargs.args[3] = (ULONG_PTR)bytesRead; 108 rpcargs.args[4] = (ULONG_PTR)overlapped; 109 110 thread = CreateThread(NULL, 0, rpcThreadMain, (void *)&rpcargs, 0, &threadId); 111 ok(thread != NULL, "CreateThread failed. %ld\n", GetLastError()); 112 ret = WaitForSingleObject(thread, INFINITE); 113 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed with %ld.\n", GetLastError()); 114 CloseHandle(thread); 115 116 SetLastError(rpcargs.lastError); 117 return (BOOL)rpcargs.returnValue; 118} 119 120#define test_not_signaled(h) _test_not_signaled(__LINE__,h) 121static void _test_not_signaled(unsigned line, HANDLE handle) 122{ 123 DWORD res = WaitForSingleObject(handle, 0); 124 ok_(__FILE__,line)(res == WAIT_TIMEOUT, "WaitForSingleObject returned %lu (%lu)\n", res, GetLastError()); 125} 126 127#define test_signaled(h) _test_signaled(__LINE__,h) 128static void _test_signaled(unsigned line, HANDLE handle) 129{ 130 DWORD res = WaitForSingleObject(handle, 0); 131 ok_(__FILE__,line)(res == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", res); 132} 133 134#define test_pipe_info(a,b,c,d,e) _test_pipe_info(__LINE__,a,b,c,d,e) 135static 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) 136{ 137 DWORD flags = 0xdeadbeef, out_buf_size = 0xdeadbeef, in_buf_size = 0xdeadbeef, max_instances = 0xdeadbeef; 138 BOOL res; 139 140 res = GetNamedPipeInfo(pipe, &flags, &out_buf_size, &in_buf_size, &max_instances); 141 ok_(__FILE__,line)(res, "GetNamedPipeInfo failed: %x\n", res); 142 ok_(__FILE__,line)(flags == ex_flags, "flags = %lx, expected %lx\n", flags, ex_flags); 143 ok_(__FILE__,line)(out_buf_size == ex_out_buf_size, "out_buf_size = %lx, expected %lu\n", out_buf_size, ex_out_buf_size); 144 ok_(__FILE__,line)(in_buf_size == ex_in_buf_size, "in_buf_size = %lx, expected %lu\n", in_buf_size, ex_in_buf_size); 145 ok_(__FILE__,line)(max_instances == ex_max_instances, "max_instances = %lx, expected %lu\n", max_instances, ex_max_instances); 146} 147 148#define test_file_access(a,b) _test_file_access(__LINE__,a,b) 149static void _test_file_access(unsigned line, HANDLE handle, DWORD expected_access) 150{ 151 FILE_ACCESS_INFORMATION info; 152 IO_STATUS_BLOCK io; 153 NTSTATUS status; 154 155 memset(&info, 0x11, sizeof(info)); 156 status = NtQueryInformationFile(handle, &io, &info, sizeof(info), FileAccessInformation); 157 ok_(__FILE__,line)(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08lx\n", status); 158 ok_(__FILE__,line)(info.AccessFlags == expected_access, "got access %08lx expected %08lx\n", 159 info.AccessFlags, expected_access); 160} 161 162static void test_CreateNamedPipe(int pipemode) 163{ 164 HANDLE hnp; 165 HANDLE hFile; 166 static const char obuf[] = "Bit Bucket"; 167 static const char obuf2[] = "More bits"; 168 char ibuf[32], *pbuf; 169 DWORD written; 170 DWORD readden; 171 DWORD avail; 172 DWORD left; 173 DWORD lpmode; 174 BOOL ret; 175 176 if (pipemode == PIPE_TYPE_BYTE) 177 trace("test_CreateNamedPipe starting in byte mode\n"); 178 else 179 trace("test_CreateNamedPipe starting in message mode\n"); 180 181 /* Wait for nonexistent pipe */ 182 ret = WaitNamedPipeA(PIPENAME, 2000); 183 ok(ret == 0, "WaitNamedPipe returned %d for nonexistent pipe\n", ret); 184 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %lu\n", GetLastError()); 185 186 /* Bad parameter checks */ 187 hnp = CreateNamedPipeA("not a named pipe", PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT, 188 /* nMaxInstances */ 1, 189 /* nOutBufSize */ 1024, 190 /* nInBufSize */ 1024, 191 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 192 /* lpSecurityAttrib */ NULL); 193 ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_NAME, 194 "CreateNamedPipe should fail if name doesn't start with \\\\.\\pipe\n"); 195 196 if (pipemode == PIPE_TYPE_BYTE) 197 { 198 /* Bad parameter checks */ 199 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE, 200 /* nMaxInstances */ 1, 201 /* nOutBufSize */ 1024, 202 /* nInBufSize */ 1024, 203 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 204 /* lpSecurityAttrib */ NULL); 205 ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER, 206 "CreateNamedPipe should fail with PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE\n"); 207 } 208 209 hnp = CreateNamedPipeA(NULL, 210 PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT, 211 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); 212 ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND, 213 "CreateNamedPipe should fail if name is NULL\n"); 214 215 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 216 ok(hFile == INVALID_HANDLE_VALUE 217 && GetLastError() == ERROR_FILE_NOT_FOUND, 218 "connecting to nonexistent named pipe should fail with ERROR_FILE_NOT_FOUND\n"); 219 220 /* Functional checks */ 221 222 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT, 223 /* nMaxInstances */ 1, 224 /* nOutBufSize */ 1024, 225 /* nInBufSize */ 1024, 226 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 227 /* lpSecurityAttrib */ NULL); 228 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 229 test_signaled(hnp); 230 231 test_file_access(hnp, SYNCHRONIZE | READ_CONTROL | FILE_WRITE_ATTRIBUTES 232 | FILE_READ_ATTRIBUTES | FILE_WRITE_PROPERTIES | FILE_READ_PROPERTIES 233 | FILE_APPEND_DATA | FILE_WRITE_DATA | FILE_READ_DATA); 234 235 ret = PeekNamedPipe(hnp, NULL, 0, NULL, &readden, NULL); 236 ok(!ret && GetLastError() == ERROR_BAD_PIPE, "PeekNamedPipe returned %x (%lu)\n", 237 ret, GetLastError()); 238 239 ret = WaitNamedPipeA(PIPENAME, 2000); 240 ok(ret, "WaitNamedPipe failed (%ld)\n", GetLastError()); 241 242 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 243 ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError()); 244 245 ok(!WaitNamedPipeA(PIPENAME, 100), "WaitNamedPipe succeeded\n"); 246 247 ok(GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %lu\n", GetLastError()); 248 249 /* Test ConnectNamedPipe() in both directions */ 250 ok(!ConnectNamedPipe(hnp, NULL), "ConnectNamedPipe(server) succeeded\n"); 251 ok(GetLastError() == ERROR_PIPE_CONNECTED, "expected ERROR_PIPE_CONNECTED, got %lu\n", GetLastError()); 252 ok(!ConnectNamedPipe(hFile, NULL), "ConnectNamedPipe(client) succeeded\n"); 253 ok(GetLastError() == ERROR_INVALID_FUNCTION, "expected ERROR_INVALID_FUNCTION, got %lu\n", GetLastError()); 254 255 /* don't try to do i/o if one side couldn't be opened, as it hangs */ 256 if (hFile != INVALID_HANDLE_VALUE) { 257 HANDLE hFile2; 258 259 /* Make sure we can read and write a few bytes in both directions */ 260 memset(ibuf, 0, sizeof(ibuf)); 261 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile\n"); 262 ok(written == sizeof(obuf), "write file len\n"); 263 ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 264 ok(readden == sizeof(obuf), "read got %ld bytes\n", readden); 265 ok(memcmp(obuf, ibuf, written) == 0, "content check\n"); 266 267 memset(ibuf, 0, sizeof(ibuf)); 268 ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), "WriteFile\n"); 269 ok(written == sizeof(obuf2), "write file len\n"); 270 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 271 ok(readden == sizeof(obuf2), "read got %ld bytes\n", readden); 272 ok(memcmp(obuf2, ibuf, written) == 0, "content check\n"); 273 274 /* Now the same again, but with an additional call to PeekNamedPipe */ 275 memset(ibuf, 0, sizeof(ibuf)); 276 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile\n"); 277 ok(written == sizeof(obuf), "write file len 1\n"); 278 ok(PeekNamedPipe(hFile, NULL, 0, NULL, &avail, &left), "Peek\n"); 279 ok(avail == sizeof(obuf), "peek 1 got %ld bytes\n", avail); 280 if (pipemode == PIPE_TYPE_BYTE) 281 ok(left == 0, "peek 1 got %ld bytes left\n", left); 282 else 283 ok(left == sizeof(obuf), "peek 1 got %ld bytes left\n", left); 284 ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 285 ok(readden == sizeof(obuf), "read 1 got %ld bytes\n", readden); 286 ok(memcmp(obuf, ibuf, written) == 0, "content 1 check\n"); 287 288 memset(ibuf, 0, sizeof(ibuf)); 289 ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), "WriteFile\n"); 290 ok(written == sizeof(obuf2), "write file len 2\n"); 291 ok(PeekNamedPipe(hnp, NULL, 0, NULL, &avail, &left), "Peek\n"); 292 ok(avail == sizeof(obuf2), "peek 2 got %ld bytes\n", avail); 293 if (pipemode == PIPE_TYPE_BYTE) 294 ok(left == 0, "peek 2 got %ld bytes left\n", left); 295 else 296 ok(left == sizeof(obuf2), "peek 2 got %ld bytes left\n", left); 297 ok(PeekNamedPipe(hnp, (LPVOID)1, 0, NULL, &avail, &left), "Peek\n"); 298 ok(avail == sizeof(obuf2), "peek 2 got %ld bytes\n", avail); 299 if (pipemode == PIPE_TYPE_BYTE) 300 ok(left == 0, "peek 2 got %ld bytes left\n", left); 301 else 302 ok(left == sizeof(obuf2), "peek 2 got %ld bytes left\n", left); 303 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 304 ok(readden == sizeof(obuf2), "read 2 got %ld bytes\n", readden); 305 ok(memcmp(obuf2, ibuf, written) == 0, "content 2 check\n"); 306 307 /* Test how ReadFile behaves when the buffer is not big enough for the whole message */ 308 memset(ibuf, 0, sizeof(ibuf)); 309 ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), "WriteFile\n"); 310 ok(written == sizeof(obuf2), "write file len\n"); 311 ok(PeekNamedPipe(hFile, ibuf, 4, &readden, &avail, &left), "Peek\n"); 312 ok(readden == 4, "peek got %ld bytes\n", readden); 313 ok(avail == sizeof(obuf2), "peek got %ld bytes available\n", avail); 314 if (pipemode == PIPE_TYPE_BYTE) 315 ok(left == -4, "peek got %ld bytes left\n", left); 316 else 317 ok(left == sizeof(obuf2)-4, "peek got %ld bytes left\n", left); 318 ok(ReadFile(hFile, ibuf, 4, &readden, NULL), "ReadFile\n"); 319 ok(readden == 4, "read got %ld bytes\n", readden); 320 ok(ReadFile(hFile, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile\n"); 321 ok(readden == sizeof(obuf2) - 4, "read got %ld bytes\n", readden); 322 ok(memcmp(obuf2, ibuf, written) == 0, "content check\n"); 323 324 memset(ibuf, 0, sizeof(ibuf)); 325 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile\n"); 326 ok(written == sizeof(obuf), "write file len\n"); 327 ok(PeekNamedPipe(hnp, ibuf, 4, &readden, &avail, &left), "Peek\n"); 328 ok(readden == 4, "peek got %ld bytes\n", readden); 329 ok(avail == sizeof(obuf), "peek got %ld bytes available\n", avail); 330 if (pipemode == PIPE_TYPE_BYTE) 331 { 332 ok(left == -4, "peek got %ld bytes left\n", left); 333 ok(ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile\n"); 334 } 335 else 336 { 337 ok(left == sizeof(obuf)-4, "peek got %ld bytes left\n", left); 338 SetLastError(0xdeadbeef); 339 ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile\n"); 340 ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n"); 341 } 342 ok(readden == 4, "read got %ld bytes\n", readden); 343 ok(ReadFile(hnp, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile\n"); 344 ok(readden == sizeof(obuf) - 4, "read got %ld bytes\n", readden); 345 ok(memcmp(obuf, ibuf, written) == 0, "content check\n"); 346 347 /* Similar to above, but use a read buffer size small enough to read in three parts */ 348 memset(ibuf, 0, sizeof(ibuf)); 349 ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), "WriteFile\n"); 350 ok(written == sizeof(obuf2), "write file len\n"); 351 if (pipemode == PIPE_TYPE_BYTE) 352 { 353 ok(ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile\n"); 354 ok(readden == 4, "read got %ld bytes\n", readden); 355 ok(ReadFile(hnp, ibuf + 4, 4, &readden, NULL), "ReadFile\n"); 356 } 357 else 358 { 359 SetLastError(0xdeadbeef); 360 ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile\n"); 361 ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n"); 362 ok(readden == 4, "read got %ld bytes\n", readden); 363 SetLastError(0xdeadbeef); 364 ok(!ReadFile(hnp, ibuf + 4, 4, &readden, NULL), "ReadFile\n"); 365 ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n"); 366 } 367 ok(readden == 4, "read got %ld bytes\n", readden); 368 ok(ReadFile(hnp, ibuf + 8, sizeof(ibuf) - 8, &readden, NULL), "ReadFile\n"); 369 ok(readden == sizeof(obuf2) - 8, "read got %ld bytes\n", readden); 370 ok(memcmp(obuf2, ibuf, written) == 0, "content check\n"); 371 372 /* Test reading of multiple writes */ 373 memset(ibuf, 0, sizeof(ibuf)); 374 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile3a\n"); 375 ok(written == sizeof(obuf), "write file len 3a\n"); 376 ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), " WriteFile3b\n"); 377 ok(written == sizeof(obuf2), "write file len 3b\n"); 378 ok(PeekNamedPipe(hFile, ibuf, 4, &readden, &avail, &left), "Peek3\n"); 379 ok(readden == 4, "peek3 got %ld bytes\n", readden); 380 if (pipemode == PIPE_TYPE_BYTE) 381 ok(left == -4, "peek3 got %ld bytes left\n", left); 382 else 383 ok(left == sizeof(obuf)-4, "peek3 got %ld bytes left\n", left); 384 ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %ld bytes available\n", avail); 385 ok(PeekNamedPipe(hFile, ibuf, sizeof(ibuf), &readden, &avail, &left), "Peek3\n"); 386 if (pipemode == PIPE_TYPE_BYTE) { 387 ok(readden == sizeof(obuf) + sizeof(obuf2), "peek3 got %ld bytes\n", readden); 388 ok(left == (DWORD) -(sizeof(obuf) + sizeof(obuf2)), "peek3 got %ld bytes left\n", left); 389 } 390 else 391 { 392 ok(readden == sizeof(obuf), "peek3 got %ld bytes\n", readden); 393 ok(left == 0, "peek3 got %ld bytes left\n", left); 394 } 395 ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %ld bytes available\n", avail); 396 pbuf = ibuf; 397 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "pipe content 3a 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 3b check\n"); 401 } 402 ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 403 ok(readden == sizeof(obuf) + sizeof(obuf2), "read 3 got %ld bytes\n", readden); 404 pbuf = ibuf; 405 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 3a check\n"); 406 pbuf += sizeof(obuf); 407 ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "content 3b check\n"); 408 409 /* Multiple writes in the reverse direction */ 410 memset(ibuf, 0, sizeof(ibuf)); 411 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile4a\n"); 412 ok(written == sizeof(obuf), "write file len 4a\n"); 413 ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), " WriteFile4b\n"); 414 ok(written == sizeof(obuf2), "write file len 4b\n"); 415 ok(PeekNamedPipe(hnp, ibuf, 4, &readden, &avail, &left), "Peek3\n"); 416 ok(readden == 4, "peek3 got %ld bytes\n", readden); 417 if (pipemode == PIPE_TYPE_BYTE) 418 ok(left == -4, "peek3 got %ld bytes left\n", left); 419 else 420 ok(left == sizeof(obuf)-4, "peek3 got %ld bytes left\n", left); 421 ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %ld bytes available\n", avail); 422 ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, &left), "Peek4\n"); 423 if (pipemode == PIPE_TYPE_BYTE) { 424 ok(readden == sizeof(obuf) + sizeof(obuf2), "peek4 got %ld bytes\n", readden); 425 ok(left == (DWORD) -(sizeof(obuf) + sizeof(obuf2)), "peek4 got %ld bytes left\n", left); 426 } 427 else 428 { 429 ok(readden == sizeof(obuf), "peek4 got %ld bytes\n", readden); 430 ok(left == 0, "peek4 got %ld bytes left\n", left); 431 } 432 ok(avail == sizeof(obuf) + sizeof(obuf2), "peek4 got %ld bytes available\n", avail); 433 pbuf = ibuf; 434 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "pipe content 4a check\n"); 435 if (pipemode == PIPE_TYPE_BYTE && readden >= sizeof(obuf)+sizeof(obuf2)) { 436 pbuf += sizeof(obuf); 437 ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "pipe content 4b check\n"); 438 } 439 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 440 if (pipemode == PIPE_TYPE_BYTE) { 441 ok(readden == sizeof(obuf) + sizeof(obuf2), "read 4 got %ld bytes\n", readden); 442 } 443 else { 444 ok(readden == sizeof(obuf), "read 4 got %ld bytes\n", readden); 445 } 446 pbuf = ibuf; 447 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 4a check\n"); 448 if (pipemode == PIPE_TYPE_BYTE) { 449 pbuf += sizeof(obuf); 450 ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "content 4b check\n"); 451 } 452 453 /* Test reading of multiple writes after a mode change 454 (CreateFile always creates a byte mode pipe) */ 455 lpmode = PIPE_READMODE_MESSAGE; 456 if (pipemode == PIPE_TYPE_BYTE) { 457 /* trying to change the client end of a byte pipe to message mode should fail */ 458 ok(!SetNamedPipeHandleState(hFile, &lpmode, NULL, NULL), "Change mode\n"); 459 } 460 else { 461 ok(SetNamedPipeHandleState(hFile, &lpmode, NULL, NULL), "Change mode\n"); 462 463 memset(ibuf, 0, sizeof(ibuf)); 464 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile5a\n"); 465 ok(written == sizeof(obuf), "write file len 3a\n"); 466 ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), " WriteFile5b\n"); 467 ok(written == sizeof(obuf2), "write file len 3b\n"); 468 ok(PeekNamedPipe(hFile, ibuf, sizeof(ibuf), &readden, &avail, &left), "Peek5\n"); 469 ok(readden == sizeof(obuf), "peek5 got %ld bytes\n", readden); 470 ok(avail == sizeof(obuf) + sizeof(obuf2), "peek5 got %ld bytes available\n", avail); 471 ok(left == 0, "peek5 got %ld bytes left\n", left); 472 pbuf = ibuf; 473 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 5a check\n"); 474 ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 475 ok(readden == sizeof(obuf), "read 5 got %ld bytes\n", readden); 476 pbuf = ibuf; 477 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 5a check\n"); 478 if (readden <= sizeof(obuf)) 479 ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 480 481 /* Multiple writes in the reverse direction */ 482 /* the write of obuf2 from write4 should still be in the buffer */ 483 ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek6a\n"); 484 ok(readden == sizeof(obuf2), "peek6a got %ld bytes\n", readden); 485 ok(avail == sizeof(obuf2), "peek6a got %ld bytes available\n", avail); 486 if (avail > 0) { 487 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 488 ok(readden == sizeof(obuf2), "read 6a got %ld bytes\n", readden); 489 pbuf = ibuf; 490 ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "content 6a check\n"); 491 } 492 memset(ibuf, 0, sizeof(ibuf)); 493 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile6a\n"); 494 ok(written == sizeof(obuf), "write file len 6a\n"); 495 ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), " WriteFile6b\n"); 496 ok(written == sizeof(obuf2), "write file len 6b\n"); 497 ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek6\n"); 498 ok(readden == sizeof(obuf), "peek6 got %ld bytes\n", readden); 499 500 ok(avail == sizeof(obuf) + sizeof(obuf2), "peek6b got %ld bytes available\n", avail); 501 pbuf = ibuf; 502 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 6a check\n"); 503 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 504 ok(readden == sizeof(obuf), "read 6b got %ld bytes\n", readden); 505 pbuf = ibuf; 506 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 6a check\n"); 507 if (readden <= sizeof(obuf)) 508 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n"); 509 510 /* Test how ReadFile behaves when the buffer is not big enough for the whole message */ 511 memset(ibuf, 0, sizeof(ibuf)); 512 ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), "WriteFile 7\n"); 513 ok(written == sizeof(obuf2), "write file len 7\n"); 514 SetLastError(0xdeadbeef); 515 ok(!ReadFile(hFile, ibuf, 4, &readden, NULL), "ReadFile 7\n"); 516 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 7\n"); 517 ok(readden == 4, "read got %ld bytes 7\n", readden); 518 ok(ReadFile(hFile, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile 7\n"); 519 ok(readden == sizeof(obuf2) - 4, "read got %ld bytes 7\n", readden); 520 ok(memcmp(obuf2, ibuf, written) == 0, "content check 7\n"); 521 522 memset(ibuf, 0, sizeof(ibuf)); 523 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile 8\n"); 524 ok(written == sizeof(obuf), "write file len 8\n"); 525 SetLastError(0xdeadbeef); 526 ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile 8\n"); 527 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 8\n"); 528 ok(readden == 4, "read got %ld bytes 8\n", readden); 529 ok(ReadFile(hnp, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile 8\n"); 530 ok(readden == sizeof(obuf) - 4, "read got %ld bytes 8\n", readden); 531 ok(memcmp(obuf, ibuf, written) == 0, "content check 8\n"); 532 533 /* The following test shows that when doing a partial read of a message, the rest 534 * is still in the pipe, and can be received from a second thread. This shows 535 * especially that the content is _not_ stored in thread-local-storage until it is 536 * completely transmitted. The same method works even across multiple processes. */ 537 memset(ibuf, 0, sizeof(ibuf)); 538 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile 9\n"); 539 ok(written == sizeof(obuf), "write file len 9\n"); 540 ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), "WriteFile 9\n"); 541 ok(written == sizeof(obuf2), "write file len 9\n"); 542 SetLastError(0xdeadbeef); 543 ok(!ReadFile(hFile, ibuf, 4, &readden, NULL), "ReadFile 9\n"); 544 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n"); 545 ok(readden == 4, "read got %ld bytes 9\n", readden); 546 SetLastError(0xdeadbeef); 547 ret = RpcReadFile(hFile, ibuf + 4, 4, &readden, NULL); 548 ok(!ret, "RpcReadFile 9\n"); 549 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n"); 550 ok(readden == 4, "read got %ld bytes 9\n", readden); 551 ret = RpcReadFile(hFile, ibuf + 8, sizeof(ibuf), &readden, NULL); 552 ok(ret, "RpcReadFile 9\n"); 553 ok(readden == sizeof(obuf) - 8, "read got %ld bytes 9\n", readden); 554 ok(memcmp(obuf, ibuf, sizeof(obuf)) == 0, "content check 9\n"); 555 if (readden <= sizeof(obuf) - 8) /* blocks forever if second part was already received */ 556 { 557 memset(ibuf, 0, sizeof(ibuf)); 558 SetLastError(0xdeadbeef); 559 ret = RpcReadFile(hFile, ibuf, 4, &readden, NULL); 560 ok(!ret, "RpcReadFile 9\n"); 561 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n"); 562 ok(readden == 4, "read got %ld bytes 9\n", readden); 563 SetLastError(0xdeadbeef); 564 ok(!ReadFile(hFile, ibuf + 4, 4, &readden, NULL), "ReadFile 9\n"); 565 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n"); 566 ok(readden == 4, "read got %ld bytes 9\n", readden); 567 ret = RpcReadFile(hFile, ibuf + 8, sizeof(ibuf), &readden, NULL); 568 ok(ret, "RpcReadFile 9\n"); 569 ok(readden == sizeof(obuf2) - 8, "read got %ld bytes 9\n", readden); 570 ok(memcmp(obuf2, ibuf, sizeof(obuf2)) == 0, "content check 9\n"); 571 } 572 573 /* Now the reverse direction */ 574 memset(ibuf, 0, sizeof(ibuf)); 575 ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), "WriteFile 10\n"); 576 ok(written == sizeof(obuf2), "write file len 10\n"); 577 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile 10\n"); 578 ok(written == sizeof(obuf), "write file len 10\n"); 579 SetLastError(0xdeadbeef); 580 ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile 10\n"); 581 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n"); 582 ok(readden == 4, "read got %ld bytes 10\n", readden); 583 SetLastError(0xdeadbeef); 584 ret = RpcReadFile(hnp, ibuf + 4, 4, &readden, NULL); 585 ok(!ret, "RpcReadFile 10\n"); 586 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n"); 587 ok(readden == 4, "read got %ld bytes 10\n", readden); 588 ret = RpcReadFile(hnp, ibuf + 8, sizeof(ibuf), &readden, NULL); 589 ok(ret, "RpcReadFile 10\n"); 590 ok(readden == sizeof(obuf2) - 8, "read got %ld bytes 10\n", readden); 591 ok(memcmp(obuf2, ibuf, sizeof(obuf2)) == 0, "content check 10\n"); 592 if (readden <= sizeof(obuf2) - 8) /* blocks forever if second part was already received */ 593 { 594 memset(ibuf, 0, sizeof(ibuf)); 595 SetLastError(0xdeadbeef); 596 ret = RpcReadFile(hnp, ibuf, 4, &readden, NULL); 597 ok(!ret, "RpcReadFile 10\n"); 598 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n"); 599 ok(readden == 4, "read got %ld bytes 10\n", readden); 600 SetLastError(0xdeadbeef); 601 ok(!ReadFile(hnp, ibuf + 4, 4, &readden, NULL), "ReadFile 10\n"); 602 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n"); 603 ok(readden == 4, "read got %ld bytes 10\n", readden); 604 ret = RpcReadFile(hnp, ibuf + 8, sizeof(ibuf), &readden, NULL); 605 ok(ret, "RpcReadFile 10\n"); 606 ok(readden == sizeof(obuf) - 8, "read got %ld bytes 10\n", readden); 607 ok(memcmp(obuf, ibuf, sizeof(obuf)) == 0, "content check 10\n"); 608 } 609 610 } 611 612 /* Picky conformance tests */ 613 614 /* Verify that you can't connect to pipe again 615 * until server calls DisconnectNamedPipe+ConnectNamedPipe 616 * or creates a new pipe 617 * case 1: other client not yet closed 618 */ 619 hFile2 = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 620 ok(hFile2 == INVALID_HANDLE_VALUE, 621 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n"); 622 ok(GetLastError() == ERROR_PIPE_BUSY, 623 "connecting to named pipe before other client closes should fail with ERROR_PIPE_BUSY\n"); 624 625 ok(CloseHandle(hFile), "CloseHandle\n"); 626 627 /* case 2: other client already closed */ 628 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 629 ok(hFile == INVALID_HANDLE_VALUE, 630 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n"); 631 ok(GetLastError() == ERROR_PIPE_BUSY, 632 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail with ERROR_PIPE_BUSY\n"); 633 634 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n"); 635 636 /* case 3: server has called DisconnectNamedPipe but not ConnectNamed Pipe */ 637 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 638 ok(hFile == INVALID_HANDLE_VALUE, 639 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n"); 640 ok(GetLastError() == ERROR_PIPE_BUSY, 641 "connecting to named pipe after other client closes but before ConnectNamedPipe should fail with ERROR_PIPE_BUSY\n"); 642 643 /* to be complete, we'd call ConnectNamedPipe here and loop, 644 * but by default that's blocking, so we'd either have 645 * to turn on the uncommon nonblocking mode, or 646 * use another thread. 647 */ 648 } 649 650 ok(CloseHandle(hnp), "CloseHandle\n"); 651 652 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_INBOUND, pipemode | PIPE_WAIT, 653 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); 654 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 655 test_signaled(hnp); 656 657 test_file_access(hnp, SYNCHRONIZE | READ_CONTROL | FILE_READ_ATTRIBUTES | FILE_READ_PROPERTIES 658 | FILE_READ_DATA); 659 660 CloseHandle(hnp); 661 662 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_OUTBOUND, pipemode | PIPE_WAIT, 663 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); 664 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 665 test_signaled(hnp); 666 667 test_file_access(hnp, SYNCHRONIZE | READ_CONTROL | FILE_WRITE_ATTRIBUTES 668 | FILE_WRITE_PROPERTIES | FILE_APPEND_DATA | FILE_WRITE_DATA); 669 670 hFile = CreateFileA(PIPENAME, 0, 0, NULL, OPEN_EXISTING, 0, 0); 671 ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed: %lu\n", GetLastError()); 672 test_file_access(hFile, SYNCHRONIZE | FILE_READ_ATTRIBUTES); 673 CloseHandle(hFile); 674 675 CloseHandle(hnp); 676 677 hnp = CreateNamedPipeA("\\\\.\\pipe\\a<>*?|\"/b", PIPE_ACCESS_DUPLEX, 678 PIPE_TYPE_BYTE, 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); 679 ok(hnp != INVALID_HANDLE_VALUE, "failed to create pipe, error %lu\n", GetLastError()); 680 hFile = CreateFileA("\\\\.\\pipe\\a<>*?|\"/b", 0, 0, NULL, OPEN_EXISTING, 0, 0); 681 ok(hFile != INVALID_HANDLE_VALUE, "failed to open pipe, error %lu\n", GetLastError()); 682 CloseHandle(hFile); 683 CloseHandle(hnp); 684 685 hnp = CreateNamedPipeA("\\\\.\\pipe\\trailingslash\\", PIPE_ACCESS_DUPLEX, 686 PIPE_TYPE_BYTE, 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); 687 ok(hnp != INVALID_HANDLE_VALUE, "failed to create pipe, error %lu\n", GetLastError()); 688 hFile = CreateFileA("\\\\.\\pipe\\trailingslash", 0, 0, NULL, OPEN_EXISTING, 0, 0); 689 ok(hFile == INVALID_HANDLE_VALUE, "expected opening pipe to fail\n"); 690 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %lu\n", GetLastError()); 691 hFile = CreateFileA("\\\\.\\pipe\\trailingslash\\", 0, 0, NULL, OPEN_EXISTING, 0, 0); 692 ok(hFile != INVALID_HANDLE_VALUE, "failed to open pipe, error %lu\n", GetLastError()); 693 CloseHandle(hFile); 694 CloseHandle(hnp); 695 696 if (winetest_debug > 1) trace("test_CreateNamedPipe returning\n"); 697} 698 699static void test_CreateNamedPipe_instances_must_match(void) 700{ 701 HANDLE hnp, hnp2; 702 703 /* Check no mismatch */ 704 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 705 /* nMaxInstances */ 2, 706 /* nOutBufSize */ 1024, 707 /* nInBufSize */ 1024, 708 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 709 /* lpSecurityAttrib */ NULL); 710 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 711 712 hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 713 /* nMaxInstances */ 2, 714 /* nOutBufSize */ 1024, 715 /* nInBufSize */ 1024, 716 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 717 /* lpSecurityAttrib */ NULL); 718 ok(hnp2 != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 719 720 ok(CloseHandle(hnp), "CloseHandle\n"); 721 ok(CloseHandle(hnp2), "CloseHandle\n"); 722 723 /* Check nMaxInstances */ 724 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 725 /* nMaxInstances */ 1, 726 /* nOutBufSize */ 1024, 727 /* nInBufSize */ 1024, 728 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 729 /* lpSecurityAttrib */ NULL); 730 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 731 732 hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 733 /* nMaxInstances */ 1, 734 /* nOutBufSize */ 1024, 735 /* nInBufSize */ 1024, 736 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 737 /* lpSecurityAttrib */ NULL); 738 ok(hnp2 == INVALID_HANDLE_VALUE 739 && GetLastError() == ERROR_PIPE_BUSY, "nMaxInstances not obeyed\n"); 740 741 ok(CloseHandle(hnp), "CloseHandle\n"); 742 743 /* Check PIPE_ACCESS_* */ 744 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 745 /* nMaxInstances */ 2, 746 /* nOutBufSize */ 1024, 747 /* nInBufSize */ 1024, 748 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 749 /* lpSecurityAttrib */ NULL); 750 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 751 752 hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_WAIT, 753 /* nMaxInstances */ 2, 754 /* nOutBufSize */ 1024, 755 /* nInBufSize */ 1024, 756 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 757 /* lpSecurityAttrib */ NULL); 758 ok(hnp2 == INVALID_HANDLE_VALUE 759 && GetLastError() == ERROR_ACCESS_DENIED, "PIPE_ACCESS_* mismatch allowed\n"); 760 761 ok(CloseHandle(hnp), "CloseHandle\n"); 762 763 /* check everything else */ 764 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 765 /* nMaxInstances */ 4, 766 /* nOutBufSize */ 1024, 767 /* nInBufSize */ 1024, 768 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 769 /* lpSecurityAttrib */ NULL); 770 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 771 772 hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE, 773 /* nMaxInstances */ 3, 774 /* nOutBufSize */ 102, 775 /* nInBufSize */ 24, 776 /* nDefaultWait */ 1234, 777 /* lpSecurityAttrib */ NULL); 778 ok(hnp2 != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 779 780 ok(CloseHandle(hnp), "CloseHandle\n"); 781 ok(CloseHandle(hnp2), "CloseHandle\n"); 782} 783 784static void test_ReadFile(void) 785{ 786 HANDLE server, client; 787 OVERLAPPED overlapped; 788 DWORD size; 789 BOOL res; 790 791 static char buf[512]; 792 793 server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, 794 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 795 1, 1024, 1024, NMPWAIT_WAIT_FOREVER, NULL); 796 ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %lu\n", GetLastError()); 797 798 client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, 799 OPEN_EXISTING, 0, 0); 800 ok(client != INVALID_HANDLE_VALUE, "CreateFile failed with %lu\n", GetLastError()); 801 802 ok(WriteFile(client, buf, sizeof(buf), &size, NULL), "WriteFile\n"); 803 804 res = ReadFile(server, buf, 1, &size, NULL); 805 ok(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned %x(%lu)\n", res, GetLastError()); 806 ok(size == 1, "size = %lu\n", size); 807 808 /* pass both overlapped and ret read */ 809 memset(&overlapped, 0, sizeof(overlapped)); 810 res = ReadFile(server, buf, 1, &size, &overlapped); 811 ok(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned %x(%lu)\n", res, GetLastError()); 812 ok(size == 0, "size = %lu\n", size); 813 ok((NTSTATUS)overlapped.Internal == STATUS_BUFFER_OVERFLOW, "Internal = %Ix\n", overlapped.Internal); 814 ok(overlapped.InternalHigh == 1, "InternalHigh = %Ix\n", overlapped.InternalHigh); 815 816 DisconnectNamedPipe(server); 817 818 memset(&overlapped, 0, sizeof(overlapped)); 819 overlapped.InternalHigh = 0xdeadbeef; 820 res = ReadFile(server, buf, 1, &size, &overlapped); 821 ok(!res && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "ReadFile returned %x(%lu)\n", res, GetLastError()); 822 ok(size == 0, "size = %lu\n", size); 823 ok(overlapped.Internal == STATUS_PENDING, "Internal = %Ix\n", overlapped.Internal); 824 ok(overlapped.InternalHigh == 0xdeadbeef, "InternalHigh = %Ix\n", overlapped.InternalHigh); 825 826 memset(&overlapped, 0, sizeof(overlapped)); 827 overlapped.InternalHigh = 0xdeadbeef; 828 res = WriteFile(server, buf, 1, &size, &overlapped); 829 ok(!res && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "ReadFile returned %x(%lu)\n", res, GetLastError()); 830 ok(size == 0, "size = %lu\n", size); 831 ok(overlapped.Internal == STATUS_PENDING, "Internal = %Ix\n", overlapped.Internal); 832 ok(overlapped.InternalHigh == 0xdeadbeef, "InternalHigh = %Ix\n", overlapped.InternalHigh); 833 834 CloseHandle(server); 835 CloseHandle(client); 836} 837 838/** implementation of alarm() */ 839static DWORD CALLBACK alarmThreadMain(LPVOID arg) 840{ 841 DWORD_PTR timeout = (DWORD_PTR) arg; 842 if (winetest_debug > 1) trace("alarmThreadMain\n"); 843 if (WaitForSingleObject( alarm_event, timeout ) == WAIT_TIMEOUT) 844 { 845 ok(FALSE, "alarm\n"); 846 ExitProcess(1); 847 } 848 return 1; 849} 850 851static HANDLE hnp = INVALID_HANDLE_VALUE; 852 853/** Trivial byte echo server - disconnects after each session */ 854static DWORD CALLBACK serverThreadMain1(LPVOID arg) 855{ 856 int i; 857 858 if (winetest_debug > 1) trace("serverThreadMain1 start\n"); 859 /* Set up a simple echo server */ 860 hnp = CreateNamedPipeA(PIPENAME "serverThreadMain1", PIPE_ACCESS_DUPLEX, 861 PIPE_TYPE_BYTE | PIPE_WAIT, 862 /* nMaxInstances */ 1, 863 /* nOutBufSize */ 1024, 864 /* nInBufSize */ 1024, 865 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 866 /* lpSecurityAttrib */ NULL); 867 868 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 869 for (i = 0; i < NB_SERVER_LOOPS; i++) { 870 char buf[512]; 871 DWORD written; 872 DWORD readden; 873 BOOL success; 874 875 /* Wait for client to connect */ 876 if (winetest_debug > 1) trace("Server calling ConnectNamedPipe...\n"); 877 ok(ConnectNamedPipe(hnp, NULL) 878 || GetLastError() == ERROR_PIPE_CONNECTED, "ConnectNamedPipe\n"); 879 if (winetest_debug > 1) trace("ConnectNamedPipe returned.\n"); 880 881 /* Echo bytes once */ 882 memset(buf, 0, sizeof(buf)); 883 884 if (winetest_debug > 1) trace("Server reading...\n"); 885 success = ReadFile(hnp, buf, sizeof(buf), &readden, NULL); 886 if (winetest_debug > 1) trace("Server done reading.\n"); 887 ok(success, "ReadFile\n"); 888 ok(readden, "short read\n"); 889 890 if (winetest_debug > 1) trace("Server writing...\n"); 891 ok(WriteFile(hnp, buf, readden, &written, NULL), "WriteFile\n"); 892 if (winetest_debug > 1) trace("Server done writing.\n"); 893 ok(written == readden, "write file len\n"); 894 895 /* finish this connection, wait for next one */ 896 ok(FlushFileBuffers(hnp), "FlushFileBuffers\n"); 897 if (winetest_debug > 1) trace("Server done flushing.\n"); 898 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n"); 899 if (winetest_debug > 1) trace("Server done disconnecting.\n"); 900 } 901 return 0; 902} 903 904/** Trivial byte echo server - closes after each connection */ 905static DWORD CALLBACK serverThreadMain2(LPVOID arg) 906{ 907 int i; 908 HANDLE hnpNext = 0; 909 910 trace("serverThreadMain2\n"); 911 /* Set up a simple echo server */ 912 hnp = CreateNamedPipeA(PIPENAME "serverThreadMain2", PIPE_ACCESS_DUPLEX, 913 PIPE_TYPE_BYTE | PIPE_WAIT, 914 /* nMaxInstances */ 2, 915 /* nOutBufSize */ 1024, 916 /* nInBufSize */ 1024, 917 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 918 /* lpSecurityAttrib */ NULL); 919 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 920 921 for (i = 0; i < NB_SERVER_LOOPS; i++) { 922 char buf[512]; 923 DWORD written; 924 DWORD readden; 925 DWORD ret; 926 BOOL success; 927 928 929 user_apc_ran = FALSE; 930 if (i == 0) 931 { 932 if (winetest_debug > 1) trace("Queueing an user APC\n"); /* verify the pipe is non alerable */ 933 ret = QueueUserAPC(&user_apc, GetCurrentThread(), 0); 934 ok(ret, "QueueUserAPC failed: %ld\n", GetLastError()); 935 } 936 937 /* Wait for client to connect */ 938 if (winetest_debug > 1) trace("Server calling ConnectNamedPipe...\n"); 939 ok(ConnectNamedPipe(hnp, NULL) 940 || GetLastError() == ERROR_PIPE_CONNECTED, "ConnectNamedPipe\n"); 941 if (winetest_debug > 1) trace("ConnectNamedPipe returned.\n"); 942 943 /* Echo bytes once */ 944 memset(buf, 0, sizeof(buf)); 945 946 if (winetest_debug > 1) trace("Server reading...\n"); 947 success = ReadFile(hnp, buf, sizeof(buf), &readden, NULL); 948 if (winetest_debug > 1) trace("Server done reading.\n"); 949 ok(success, "ReadFile\n"); 950 951 if (winetest_debug > 1) trace("Server writing...\n"); 952 ok(WriteFile(hnp, buf, readden, &written, NULL), "WriteFile\n"); 953 if (winetest_debug > 1) trace("Server done writing.\n"); 954 ok(written == readden, "write file len\n"); 955 956 /* finish this connection, wait for next one */ 957 ok(FlushFileBuffers(hnp), "FlushFileBuffers\n"); 958 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n"); 959 960 ok(user_apc_ran == FALSE, "UserAPC ran, pipe using alertable io mode\n"); 961 962 if (i == 0) 963 SleepEx(0, TRUE); /* get rid of apc */ 964 965 /* Set up next echo server */ 966 hnpNext = 967 CreateNamedPipeA(PIPENAME "serverThreadMain2", PIPE_ACCESS_DUPLEX, 968 PIPE_TYPE_BYTE | PIPE_WAIT, 969 /* nMaxInstances */ 2, 970 /* nOutBufSize */ 1024, 971 /* nInBufSize */ 1024, 972 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 973 /* lpSecurityAttrib */ NULL); 974 975 ok(hnpNext != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 976 977 ok(CloseHandle(hnp), "CloseHandle\n"); 978 hnp = hnpNext; 979 } 980 return 0; 981} 982 983/** Trivial byte echo server - uses overlapped named pipe calls */ 984static DWORD CALLBACK serverThreadMain3(LPVOID arg) 985{ 986 int i; 987 HANDLE hEvent; 988 989 if (winetest_debug > 1) trace("serverThreadMain3\n"); 990 /* Set up a simple echo server */ 991 hnp = CreateNamedPipeA(PIPENAME "serverThreadMain3", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 992 PIPE_TYPE_BYTE | PIPE_WAIT, 993 /* nMaxInstances */ 1, 994 /* nOutBufSize */ 1024, 995 /* nInBufSize */ 1024, 996 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 997 /* lpSecurityAttrib */ NULL); 998 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 999 1000 hEvent = CreateEventW(NULL, /* security attribute */ 1001 TRUE, /* manual reset event */ 1002 FALSE, /* initial state */ 1003 NULL); /* name */ 1004 ok(hEvent != NULL, "CreateEvent\n"); 1005 1006 for (i = 0; i < NB_SERVER_LOOPS; i++) { 1007 char buf[512]; 1008 DWORD written; 1009 DWORD readden; 1010 DWORD dummy; 1011 BOOL success; 1012 OVERLAPPED oOverlap; 1013 int letWFSOEwait = (i & 2); 1014 int letGORwait = (i & 1); 1015 DWORD err; 1016 1017 memset(&oOverlap, 0, sizeof(oOverlap)); 1018 oOverlap.hEvent = hEvent; 1019 1020 /* Wait for client to connect */ 1021 if (i == 0) { 1022 if (winetest_debug > 1) trace("Server calling non-overlapped ConnectNamedPipe on overlapped pipe...\n"); 1023 success = ConnectNamedPipe(hnp, NULL); 1024 err = GetLastError(); 1025 ok(success || (err == ERROR_PIPE_CONNECTED), "ConnectNamedPipe failed: %ld\n", err); 1026 if (winetest_debug > 1) trace("ConnectNamedPipe operation complete.\n"); 1027 } else { 1028 if (winetest_debug > 1) trace("Server calling overlapped ConnectNamedPipe...\n"); 1029 success = ConnectNamedPipe(hnp, &oOverlap); 1030 err = GetLastError(); 1031 ok(!success && (err == ERROR_IO_PENDING || err == ERROR_PIPE_CONNECTED), "overlapped ConnectNamedPipe\n"); 1032 if (winetest_debug > 1) trace("overlapped ConnectNamedPipe returned.\n"); 1033 if (!success && (err == ERROR_IO_PENDING)) { 1034 if (letWFSOEwait) 1035 { 1036 DWORD ret; 1037 do { 1038 ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE); 1039 } while (ret == WAIT_IO_COMPLETION); 1040 ok(ret == 0, "wait ConnectNamedPipe returned %lx\n", ret); 1041 } 1042 success = GetOverlappedResult(hnp, &oOverlap, &dummy, letGORwait); 1043 if (!letGORwait && !letWFSOEwait && !success) { 1044 ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n"); 1045 success = GetOverlappedResult(hnp, &oOverlap, &dummy, TRUE); 1046 } 1047 } 1048 ok(success || (err == ERROR_PIPE_CONNECTED), "GetOverlappedResult ConnectNamedPipe\n"); 1049 if (winetest_debug > 1) trace("overlapped ConnectNamedPipe operation complete.\n"); 1050 } 1051 1052 /* Echo bytes once */ 1053 memset(buf, 0, sizeof(buf)); 1054 1055 if (winetest_debug > 1) trace("Server reading...\n"); 1056 success = ReadFile(hnp, buf, sizeof(buf), &readden, &oOverlap); 1057 if (winetest_debug > 1) trace("Server ReadFile returned...\n"); 1058 err = GetLastError(); 1059 ok(success || err == ERROR_IO_PENDING, "overlapped ReadFile\n"); 1060 if (winetest_debug > 1) trace("overlapped ReadFile returned.\n"); 1061 if (!success && (err == ERROR_IO_PENDING)) { 1062 if (letWFSOEwait) 1063 { 1064 DWORD ret; 1065 do { 1066 ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE); 1067 } while (ret == WAIT_IO_COMPLETION); 1068 ok(ret == 0, "wait ReadFile returned %lx\n", ret); 1069 } 1070 success = GetOverlappedResult(hnp, &oOverlap, &readden, letGORwait); 1071 if (!letGORwait && !letWFSOEwait && !success) { 1072 ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n"); 1073 success = GetOverlappedResult(hnp, &oOverlap, &readden, TRUE); 1074 } 1075 } 1076 if (winetest_debug > 1) trace("Server done reading.\n"); 1077 ok(success, "overlapped ReadFile\n"); 1078 1079 if (winetest_debug > 1) trace("Server writing...\n"); 1080 success = WriteFile(hnp, buf, readden, &written, &oOverlap); 1081 if (winetest_debug > 1) trace("Server WriteFile returned...\n"); 1082 err = GetLastError(); 1083 ok(success || err == ERROR_IO_PENDING, "overlapped WriteFile\n"); 1084 if (winetest_debug > 1) trace("overlapped WriteFile returned.\n"); 1085 if (!success && (err == ERROR_IO_PENDING)) { 1086 if (letWFSOEwait) 1087 { 1088 DWORD ret; 1089 do { 1090 ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE); 1091 } while (ret == WAIT_IO_COMPLETION); 1092 ok(ret == 0, "wait WriteFile returned %lx\n", ret); 1093 } 1094 success = GetOverlappedResult(hnp, &oOverlap, &written, letGORwait); 1095 if (!letGORwait && !letWFSOEwait && !success) { 1096 ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n"); 1097 success = GetOverlappedResult(hnp, &oOverlap, &written, TRUE); 1098 } 1099 } 1100 if (winetest_debug > 1) trace("Server done writing.\n"); 1101 ok(success, "overlapped WriteFile\n"); 1102 ok(written == readden, "write file len\n"); 1103 1104 /* finish this connection, wait for next one */ 1105 ok(FlushFileBuffers(hnp), "FlushFileBuffers\n"); 1106 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n"); 1107 } 1108 return 0; 1109} 1110 1111/** Trivial byte echo server - uses i/o completion ports */ 1112static DWORD CALLBACK serverThreadMain4(LPVOID arg) 1113{ 1114 int i; 1115 HANDLE hcompletion; 1116 BOOL ret; 1117 1118 if (winetest_debug > 1) trace("serverThreadMain4\n"); 1119 /* Set up a simple echo server */ 1120 hnp = CreateNamedPipeA(PIPENAME "serverThreadMain4", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 1121 PIPE_TYPE_BYTE | PIPE_WAIT, 1122 /* nMaxInstances */ 1, 1123 /* nOutBufSize */ 1024, 1124 /* nInBufSize */ 1024, 1125 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 1126 /* lpSecurityAttrib */ NULL); 1127 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 1128 1129 hcompletion = CreateIoCompletionPort(hnp, NULL, 12345, 1); 1130 ok(hcompletion != NULL, "CreateIoCompletionPort failed, error=%li\n", GetLastError()); 1131 1132 for (i = 0; i < NB_SERVER_LOOPS; i++) { 1133 char buf[512]; 1134 DWORD written; 1135 DWORD readden; 1136 DWORD dummy; 1137 BOOL success; 1138 OVERLAPPED oConnect; 1139 OVERLAPPED oRead; 1140 OVERLAPPED oWrite; 1141 OVERLAPPED *oResult; 1142 DWORD err; 1143 ULONG_PTR compkey; 1144 1145 memset(&oConnect, 0, sizeof(oConnect)); 1146 memset(&oRead, 0, sizeof(oRead)); 1147 memset(&oWrite, 0, sizeof(oWrite)); 1148 1149 /* Wait for client to connect */ 1150 if (winetest_debug > 1) trace("Server calling overlapped ConnectNamedPipe...\n"); 1151 success = ConnectNamedPipe(hnp, &oConnect); 1152 err = GetLastError(); 1153 ok(!success && (err == ERROR_IO_PENDING || err == ERROR_PIPE_CONNECTED), 1154 "overlapped ConnectNamedPipe got %u err %lu\n", success, err ); 1155 if (!success && err == ERROR_IO_PENDING) { 1156 if (winetest_debug > 1) trace("ConnectNamedPipe GetQueuedCompletionStatus\n"); 1157 success = GetQueuedCompletionStatus(hcompletion, &dummy, &compkey, &oResult, 0); 1158 if (!success) 1159 { 1160 ok( GetLastError() == WAIT_TIMEOUT, 1161 "ConnectNamedPipe GetQueuedCompletionStatus wrong error %lu\n", GetLastError()); 1162 success = GetQueuedCompletionStatus(hcompletion, &dummy, &compkey, &oResult, 10000); 1163 } 1164 ok(success, "ConnectNamedPipe GetQueuedCompletionStatus failed, errno=%li\n", GetLastError()); 1165 if (success) 1166 { 1167 ok(compkey == 12345, "got completion key %i instead of 12345\n", (int)compkey); 1168 ok(oResult == &oConnect, "got overlapped pointer %p instead of %p\n", oResult, &oConnect); 1169 } 1170 } 1171 if (winetest_debug > 1) trace("overlapped ConnectNamedPipe operation complete.\n"); 1172 1173 /* Echo bytes once */ 1174 memset(buf, 0, sizeof(buf)); 1175 1176 if (winetest_debug > 1) trace("Server reading...\n"); 1177 success = ReadFile(hnp, buf, sizeof(buf), &readden, &oRead); 1178 if (winetest_debug > 1) trace("Server ReadFile returned...\n"); 1179 err = GetLastError(); 1180 ok(success || err == ERROR_IO_PENDING, "overlapped ReadFile, err=%li\n", err); 1181 success = GetQueuedCompletionStatus(hcompletion, &readden, &compkey, 1182 &oResult, 10000); 1183 ok(success, "ReadFile GetQueuedCompletionStatus failed, errno=%li\n", GetLastError()); 1184 if (success) 1185 { 1186 ok(compkey == 12345, "got completion key %i instead of 12345\n", (int)compkey); 1187 ok(oResult == &oRead, "got overlapped pointer %p instead of %p\n", oResult, &oRead); 1188 } 1189 if (winetest_debug > 1) trace("Server done reading.\n"); 1190 1191 if (winetest_debug > 1) trace("Server writing...\n"); 1192 success = WriteFile(hnp, buf, readden, &written, &oWrite); 1193 if (winetest_debug > 1) trace("Server WriteFile returned...\n"); 1194 err = GetLastError(); 1195 ok(success || err == ERROR_IO_PENDING, "overlapped WriteFile failed, err=%lu\n", err); 1196 success = GetQueuedCompletionStatus(hcompletion, &written, &compkey, 1197 &oResult, 10000); 1198 ok(success, "WriteFile GetQueuedCompletionStatus failed, errno=%li\n", GetLastError()); 1199 if (success) 1200 { 1201 ok(compkey == 12345, "got completion key %i instead of 12345\n", (int)compkey); 1202 ok(oResult == &oWrite, "got overlapped pointer %p instead of %p\n", oResult, &oWrite); 1203 ok(written == readden, "write file len\n"); 1204 } 1205 if (winetest_debug > 1) trace("Server done writing.\n"); 1206 1207 /* Client will finish this connection, the following ops will trigger broken pipe errors. */ 1208 1209 /* Wait for the pipe to break. */ 1210 while (PeekNamedPipe(hnp, NULL, 0, NULL, &written, &written)); 1211 1212 if (winetest_debug > 1) trace("Server writing on disconnected pipe...\n"); 1213 SetLastError(ERROR_SUCCESS); 1214 success = WriteFile(hnp, buf, readden, &written, &oWrite); 1215 err = GetLastError(); 1216 ok(!success && err == ERROR_NO_DATA, 1217 "overlapped WriteFile on disconnected pipe returned %u, err=%li\n", success, err); 1218 1219 /* No completion status is queued on immediate error. */ 1220 SetLastError(ERROR_SUCCESS); 1221 oResult = (OVERLAPPED *)0xdeadbeef; 1222 success = GetQueuedCompletionStatus(hcompletion, &written, &compkey, 1223 &oResult, 0); 1224 err = GetLastError(); 1225 ok(!success && err == WAIT_TIMEOUT && !oResult, 1226 "WriteFile GetQueuedCompletionStatus returned %u, err=%li, oResult %p\n", 1227 success, err, oResult); 1228 1229 if (winetest_debug > 1) trace("Server reading from disconnected pipe...\n"); 1230 SetLastError(ERROR_SUCCESS); 1231 success = ReadFile(hnp, buf, sizeof(buf), &readden, &oRead); 1232 if (winetest_debug > 1) trace("Server ReadFile from disconnected pipe returned...\n"); 1233 err = GetLastError(); 1234 ok(!success && err == ERROR_BROKEN_PIPE, 1235 "overlapped ReadFile on disconnected pipe returned %u, err=%li\n", success, err); 1236 1237 SetLastError(ERROR_SUCCESS); 1238 oResult = (OVERLAPPED *)0xdeadbeef; 1239 success = GetQueuedCompletionStatus(hcompletion, &readden, &compkey, 1240 &oResult, 0); 1241 err = GetLastError(); 1242 ok(!success && err == WAIT_TIMEOUT && !oResult, 1243 "ReadFile GetQueuedCompletionStatus returned %u, err=%li, oResult %p\n", 1244 success, err, oResult); 1245 1246 /* finish this connection, wait for next one */ 1247 ok(FlushFileBuffers(hnp), "FlushFileBuffers\n"); 1248 success = DisconnectNamedPipe(hnp); 1249 ok(success, "DisconnectNamedPipe failed, err %lu\n", GetLastError()); 1250 } 1251 1252 ret = CloseHandle(hnp); 1253 ok(ret, "CloseHandle named pipe failed, err=%li\n", GetLastError()); 1254 ret = CloseHandle(hcompletion); 1255 ok(ret, "CloseHandle completion failed, err=%li\n", GetLastError()); 1256 1257 return 0; 1258} 1259 1260static int completion_called; 1261static DWORD completion_errorcode; 1262static DWORD completion_num_bytes; 1263static LPOVERLAPPED completion_lpoverlapped; 1264 1265static VOID WINAPI completion_routine(DWORD errorcode, DWORD num_bytes, LPOVERLAPPED lpoverlapped) 1266{ 1267 completion_called++; 1268 completion_errorcode = errorcode; 1269 completion_num_bytes = num_bytes; 1270 completion_lpoverlapped = lpoverlapped; 1271 SetEvent(lpoverlapped->hEvent); 1272} 1273 1274/** Trivial byte echo server - uses ReadFileEx/WriteFileEx */ 1275static DWORD CALLBACK serverThreadMain5(LPVOID arg) 1276{ 1277 int i; 1278 HANDLE hEvent; 1279 1280 if (winetest_debug > 1) trace("serverThreadMain5\n"); 1281 /* Set up a simple echo server */ 1282 hnp = CreateNamedPipeA(PIPENAME "serverThreadMain5", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 1283 PIPE_TYPE_BYTE | PIPE_WAIT, 1284 /* nMaxInstances */ 1, 1285 /* nOutBufSize */ 1024, 1286 /* nInBufSize */ 1024, 1287 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 1288 /* lpSecurityAttrib */ NULL); 1289 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 1290 1291 hEvent = CreateEventW(NULL, /* security attribute */ 1292 TRUE, /* manual reset event */ 1293 FALSE, /* initial state */ 1294 NULL); /* name */ 1295 ok(hEvent != NULL, "CreateEvent\n"); 1296 1297 for (i = 0; i < NB_SERVER_LOOPS; i++) { 1298 char buf[512]; 1299 DWORD readden; 1300 BOOL success; 1301 OVERLAPPED oOverlap; 1302 DWORD err; 1303 1304 memset(&oOverlap, 0, sizeof(oOverlap)); 1305 oOverlap.hEvent = hEvent; 1306 1307 /* Wait for client to connect */ 1308 if (winetest_debug > 1) trace("Server calling ConnectNamedPipe...\n"); 1309 success = ConnectNamedPipe(hnp, NULL); 1310 err = GetLastError(); 1311 ok(success || (err == ERROR_PIPE_CONNECTED), "ConnectNamedPipe failed: %ld\n", err); 1312 if (winetest_debug > 1) trace("ConnectNamedPipe operation complete.\n"); 1313 1314 /* Echo bytes once */ 1315 memset(buf, 0, sizeof(buf)); 1316 1317 if (winetest_debug > 1) trace("Server reading...\n"); 1318 completion_called = 0; 1319 ResetEvent(hEvent); 1320 success = ReadFileEx(hnp, buf, sizeof(buf), &oOverlap, completion_routine); 1321 if (winetest_debug > 1) trace("Server ReadFileEx returned...\n"); 1322 ok(success, "ReadFileEx failed, err=%li\n", GetLastError()); 1323 ok(completion_called == 0, "completion routine called before ReadFileEx return\n"); 1324 if (winetest_debug > 1) trace("ReadFileEx returned.\n"); 1325 if (success) { 1326 DWORD ret; 1327 do { 1328 ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE); 1329 } while (ret == WAIT_IO_COMPLETION); 1330 ok(ret == 0, "wait ReadFileEx returned %lx\n", ret); 1331 } 1332 ok(completion_called == 1, "completion routine called %i times\n", completion_called); 1333 ok(completion_errorcode == ERROR_SUCCESS, "completion routine got error %ld\n", completion_errorcode); 1334 ok(completion_num_bytes != 0, "read 0 bytes\n"); 1335 ok(completion_lpoverlapped == &oOverlap, "got wrong overlapped pointer %p\n", completion_lpoverlapped); 1336 readden = completion_num_bytes; 1337 if (winetest_debug > 1) trace("Server done reading.\n"); 1338 1339 if (winetest_debug > 1) trace("Server writing...\n"); 1340 completion_called = 0; 1341 ResetEvent(hEvent); 1342 success = WriteFileEx(hnp, buf, readden, &oOverlap, completion_routine); 1343 if (winetest_debug > 1) trace("Server WriteFileEx returned...\n"); 1344 ok(success, "WriteFileEx failed, err=%li\n", GetLastError()); 1345 ok(completion_called == 0, "completion routine called before ReadFileEx return\n"); 1346 if (winetest_debug > 1) trace("overlapped WriteFile returned.\n"); 1347 if (success) { 1348 DWORD ret; 1349 do { 1350 ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE); 1351 } while (ret == WAIT_IO_COMPLETION); 1352 ok(ret == 0, "wait WriteFileEx returned %lx\n", ret); 1353 } 1354 if (winetest_debug > 1) trace("Server done writing.\n"); 1355 ok(completion_called == 1, "completion routine called %i times\n", completion_called); 1356 ok(completion_errorcode == ERROR_SUCCESS, "completion routine got error %ld\n", completion_errorcode); 1357 ok(completion_num_bytes == readden, "read %li bytes wrote %li\n", readden, completion_num_bytes); 1358 ok(completion_lpoverlapped == &oOverlap, "got wrong overlapped pointer %p\n", completion_lpoverlapped); 1359 1360 /* finish this connection, wait for next one */ 1361 ok(FlushFileBuffers(hnp), "FlushFileBuffers\n"); 1362 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n"); 1363 } 1364 return 0; 1365} 1366 1367static void exerciseServer(const char *pipename, HANDLE serverThread) 1368{ 1369 int i; 1370 1371 if (winetest_debug > 1) trace("exerciseServer starting\n"); 1372 for (i = 0; i < NB_SERVER_LOOPS; i++) { 1373 HANDLE hFile=INVALID_HANDLE_VALUE; 1374 static const char obuf[] = "Bit Bucket"; 1375 char ibuf[32]; 1376 DWORD written; 1377 DWORD readden; 1378 int loop; 1379 1380 for (loop = 0; loop < 3; loop++) { 1381 DWORD err; 1382 if (winetest_debug > 1) trace("Client connecting...\n"); 1383 /* Connect to the server */ 1384 hFile = CreateFileA(pipename, GENERIC_READ | GENERIC_WRITE, 0, 1385 NULL, OPEN_EXISTING, 0, 0); 1386 if (hFile != INVALID_HANDLE_VALUE) 1387 break; 1388 err = GetLastError(); 1389 if (loop == 0) 1390 ok(err == ERROR_PIPE_BUSY || err == ERROR_FILE_NOT_FOUND, "connecting to pipe\n"); 1391 else 1392 ok(err == ERROR_PIPE_BUSY, "connecting to pipe\n"); 1393 if (winetest_debug > 1) trace("connect failed, retrying\n"); 1394 Sleep(200); 1395 } 1396 ok(hFile != INVALID_HANDLE_VALUE, "client opening named pipe\n"); 1397 1398 /* Make sure it can echo */ 1399 memset(ibuf, 0, sizeof(ibuf)); 1400 if (winetest_debug > 1) trace("Client writing...\n"); 1401 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile to client end of pipe\n"); 1402 ok(written == sizeof(obuf), "write file len\n"); 1403 if (winetest_debug > 1) trace("Client reading...\n"); 1404 ok(ReadFile(hFile, ibuf, sizeof(obuf), &readden, NULL), "ReadFile from client end of pipe\n"); 1405 ok(readden == sizeof(obuf), "read file len\n"); 1406 ok(memcmp(obuf, ibuf, written) == 0, "content check\n"); 1407 1408 if (winetest_debug > 1) trace("Client closing...\n"); 1409 ok(CloseHandle(hFile), "CloseHandle\n"); 1410 } 1411 1412 ok(WaitForSingleObject(serverThread,INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject\n"); 1413 CloseHandle(hnp); 1414 if (winetest_debug > 1) trace("exerciseServer returning\n"); 1415} 1416 1417static void test_NamedPipe_2(void) 1418{ 1419 HANDLE serverThread; 1420 DWORD serverThreadId; 1421 HANDLE alarmThread; 1422 DWORD alarmThreadId; 1423 1424 trace("test_NamedPipe_2 starting\n"); 1425 /* Set up a twenty second timeout */ 1426 alarm_event = CreateEventW( NULL, TRUE, FALSE, NULL ); 1427 SetLastError(0xdeadbeef); 1428 alarmThread = CreateThread(NULL, 0, alarmThreadMain, (void *) 20000, 0, &alarmThreadId); 1429 ok(alarmThread != NULL, "CreateThread failed: %ld\n", GetLastError()); 1430 1431 /* The servers we're about to exercise do try to clean up carefully, 1432 * but to reduce the chance of a test failure due to a pipe handle 1433 * leak in the test code, we'll use a different pipe name for each server. 1434 */ 1435 1436 /* Try server #1 */ 1437 SetLastError(0xdeadbeef); 1438 serverThread = CreateThread(NULL, 0, serverThreadMain1, (void *)8, 0, &serverThreadId); 1439 ok(serverThread != NULL, "CreateThread failed: %ld\n", GetLastError()); 1440 exerciseServer(PIPENAME "serverThreadMain1", serverThread); 1441 1442 /* Try server #2 */ 1443 SetLastError(0xdeadbeef); 1444 serverThread = CreateThread(NULL, 0, serverThreadMain2, 0, 0, &serverThreadId); 1445 ok(serverThread != NULL, "CreateThread failed: %ld\n", GetLastError()); 1446 exerciseServer(PIPENAME "serverThreadMain2", serverThread); 1447 1448 /* Try server #3 */ 1449 SetLastError(0xdeadbeef); 1450 serverThread = CreateThread(NULL, 0, serverThreadMain3, 0, 0, &serverThreadId); 1451 ok(serverThread != NULL, "CreateThread failed: %ld\n", GetLastError()); 1452 exerciseServer(PIPENAME "serverThreadMain3", serverThread); 1453 1454 /* Try server #4 */ 1455 SetLastError(0xdeadbeef); 1456 serverThread = CreateThread(NULL, 0, serverThreadMain4, 0, 0, &serverThreadId); 1457 ok(serverThread != NULL, "CreateThread failed: %ld\n", GetLastError()); 1458 exerciseServer(PIPENAME "serverThreadMain4", serverThread); 1459 1460 /* Try server #5 */ 1461 SetLastError(0xdeadbeef); 1462 serverThread = CreateThread(NULL, 0, serverThreadMain5, 0, 0, &serverThreadId); 1463 ok(serverThread != NULL, "CreateThread failed: %ld\n", GetLastError()); 1464 exerciseServer(PIPENAME "serverThreadMain5", serverThread); 1465 1466 ok(SetEvent( alarm_event ), "SetEvent\n"); 1467 CloseHandle( alarm_event ); 1468 if (winetest_debug > 1) trace("test_NamedPipe_2 returning\n"); 1469} 1470 1471static int test_DisconnectNamedPipe(void) 1472{ 1473 HANDLE hnp; 1474 HANDLE hFile; 1475 static const char obuf[] = "Bit Bucket"; 1476 char ibuf[32]; 1477 DWORD written; 1478 DWORD readden; 1479 DWORD ret; 1480 1481 SetLastError(0xdeadbeef); 1482 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 1483 /* nMaxInstances */ 1, 1484 /* nOutBufSize */ 1024, 1485 /* nInBufSize */ 1024, 1486 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 1487 /* lpSecurityAttrib */ NULL); 1488 if ((hnp == INVALID_HANDLE_VALUE /* Win98 */ || !hnp /* Win95 */) 1489 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { 1490 1491 win_skip("Named pipes are not implemented\n"); 1492 return 1; 1493 } 1494 1495 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL) == 0 1496 && GetLastError() == ERROR_PIPE_LISTENING, "WriteFile to not-yet-connected pipe\n"); 1497 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0 1498 && GetLastError() == ERROR_PIPE_LISTENING, "ReadFile from not-yet-connected pipe\n"); 1499 1500 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 1501 ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed\n"); 1502 1503 /* don't try to do i/o if one side couldn't be opened, as it hangs */ 1504 if (hFile != INVALID_HANDLE_VALUE) { 1505 1506 /* see what happens if server calls DisconnectNamedPipe 1507 * when there are bytes in the pipe 1508 */ 1509 1510 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile\n"); 1511 ok(written == sizeof(obuf), "write file len\n"); 1512 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe while messages waiting\n"); 1513 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL) == 0 1514 && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "WriteFile to disconnected pipe\n"); 1515 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL) == 0 1516 && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "WriteFile to disconnected pipe\n"); 1517 ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL) == 0 1518 && GetLastError() == ERROR_PIPE_NOT_CONNECTED, 1519 "ReadFile from disconnected pipe with bytes waiting\n"); 1520 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0 1521 && GetLastError() == ERROR_PIPE_NOT_CONNECTED, 1522 "ReadFile from disconnected pipe with bytes waiting\n"); 1523 1524 ok(!DisconnectNamedPipe(hnp) && GetLastError() == ERROR_PIPE_NOT_CONNECTED, 1525 "DisconnectNamedPipe worked twice\n"); 1526 ret = WaitForSingleObject(hFile, 0); 1527 ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %lX\n", ret); 1528 1529 ret = PeekNamedPipe(hFile, NULL, 0, NULL, &readden, NULL); 1530 ok(!ret && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "PeekNamedPipe returned %lx (%lu)\n", 1531 ret, GetLastError()); 1532 ret = PeekNamedPipe(hnp, NULL, 0, NULL, &readden, NULL); 1533 ok(!ret && GetLastError() == ERROR_BAD_PIPE, "PeekNamedPipe returned %lx (%lu)\n", 1534 ret, GetLastError()); 1535 ok(CloseHandle(hFile), "CloseHandle\n"); 1536 } 1537 1538 ok(CloseHandle(hnp), "CloseHandle\n"); 1539 1540 return 0; 1541} 1542static void test_CreatePipe(void) 1543{ 1544 SECURITY_ATTRIBUTES pipe_attr; 1545 HANDLE piperead, pipewrite; 1546 DWORD written; 1547 DWORD read; 1548 DWORD i, size; 1549 BYTE *buffer; 1550 char readbuf[32]; 1551 1552 user_apc_ran = FALSE; 1553 ok(QueueUserAPC(user_apc, GetCurrentThread(), 0), "couldn't create user apc\n"); 1554 1555 pipe_attr.nLength = sizeof(SECURITY_ATTRIBUTES); 1556 pipe_attr.bInheritHandle = TRUE; 1557 pipe_attr.lpSecurityDescriptor = NULL; 1558 ok(CreatePipe(&piperead, &pipewrite, &pipe_attr, 0) != 0, "CreatePipe failed\n"); 1559 test_pipe_info(piperead, FILE_PIPE_SERVER_END, 4096, 4096, 1); 1560 test_pipe_info(pipewrite, 0, 4096, 4096, 1); 1561 test_file_access(piperead, SYNCHRONIZE | READ_CONTROL | FILE_WRITE_ATTRIBUTES 1562 | FILE_READ_ATTRIBUTES | FILE_READ_PROPERTIES | FILE_READ_DATA); 1563 test_file_access(pipewrite, SYNCHRONIZE | READ_CONTROL | FILE_WRITE_ATTRIBUTES 1564 | FILE_READ_ATTRIBUTES | FILE_WRITE_PROPERTIES | FILE_APPEND_DATA 1565 | FILE_WRITE_DATA); 1566 1567 ok(WriteFile(pipewrite,PIPENAME,sizeof(PIPENAME), &written, NULL), "Write to anonymous pipe failed\n"); 1568 ok(written == sizeof(PIPENAME), "Write to anonymous pipe wrote %ld bytes\n", written); 1569 ok(ReadFile(piperead,readbuf,sizeof(readbuf),&read, NULL), "Read from non empty pipe failed\n"); 1570 ok(read == sizeof(PIPENAME), "Read from anonymous pipe got %ld bytes\n", read); 1571 ok(CloseHandle(pipewrite), "CloseHandle for the write pipe failed\n"); 1572 ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n"); 1573 1574 /* Now write another chunk*/ 1575 ok(CreatePipe(&piperead, &pipewrite, &pipe_attr, 0) != 0, "CreatePipe failed\n"); 1576 ok(WriteFile(pipewrite,PIPENAME,sizeof(PIPENAME), &written, NULL), "Write to anonymous pipe failed\n"); 1577 ok(written == sizeof(PIPENAME), "Write to anonymous pipe wrote %ld bytes\n", written); 1578 /* and close the write end, read should still succeed*/ 1579 ok(CloseHandle(pipewrite), "CloseHandle for the Write Pipe failed\n"); 1580 ok(ReadFile(piperead,readbuf,sizeof(readbuf),&read, NULL), "Read from broken pipe with pending data failed\n"); 1581 ok(read == sizeof(PIPENAME), "Read from anonymous pipe got %ld bytes\n", read); 1582 /* But now we need to get informed that the pipe is closed */ 1583 ok(ReadFile(piperead,readbuf,sizeof(readbuf),&read, NULL) == 0, "Broken pipe not detected\n"); 1584 ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n"); 1585 1586 /* Try bigger chunks */ 1587 size = 32768; 1588 buffer = HeapAlloc( GetProcessHeap(), 0, size ); 1589 for (i = 0; i < size; i++) buffer[i] = i; 1590 ok(CreatePipe(&piperead, &pipewrite, &pipe_attr, (size + 24)) != 0, "CreatePipe failed\n"); 1591 ok(WriteFile(pipewrite, buffer, size, &written, NULL), "Write to anonymous pipe failed\n"); 1592 ok(written == size, "Write to anonymous pipe wrote %ld bytes\n", written); 1593 /* and close the write end, read should still succeed*/ 1594 ok(CloseHandle(pipewrite), "CloseHandle for the Write Pipe failed\n"); 1595 memset( buffer, 0, size ); 1596 ok(ReadFile(piperead, buffer, size, &read, NULL), "Read from broken pipe with pending data failed\n"); 1597 ok(read == size, "Read from anonymous pipe got %ld bytes\n", read); 1598 for (i = 0; i < size; i++) ok( buffer[i] == (BYTE)i, "invalid data %x at %lx\n", buffer[i], i ); 1599 /* But now we need to get informed that the pipe is closed */ 1600 ok(ReadFile(piperead,readbuf,sizeof(readbuf),&read, NULL) == 0, "Broken pipe not detected\n"); 1601 ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n"); 1602 HeapFree(GetProcessHeap(), 0, buffer); 1603 1604 ok(user_apc_ran == FALSE, "user apc ran, pipe using alertable io mode\n"); 1605 SleepEx(0, TRUE); /* get rid of apc */ 1606 1607 ok(CreatePipe(&piperead, &pipewrite, &pipe_attr, 1) != 0, "CreatePipe failed\n"); 1608 test_pipe_info(piperead, FILE_PIPE_SERVER_END, 1, 1, 1); 1609 test_pipe_info(pipewrite, 0, 1, 1, 1); 1610 ok(CloseHandle(pipewrite), "CloseHandle for the Write Pipe failed\n"); 1611 ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n"); 1612} 1613 1614static void test_CloseHandle(void) 1615{ 1616 static const char testdata[] = "Hello World"; 1617 DWORD state, numbytes; 1618 HANDLE hpipe, hfile; 1619 char buffer[32]; 1620 BOOL ret; 1621 1622 hpipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, 1623 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1624 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); 1625 ok(hpipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %lu\n", GetLastError()); 1626 1627 hfile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 1628 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile failed with %lu\n", GetLastError()); 1629 1630 numbytes = 0xdeadbeef; 1631 ret = WriteFile(hpipe, testdata, sizeof(testdata), &numbytes, NULL); 1632 ok(ret, "WriteFile failed with %lu\n", GetLastError()); 1633 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %lu\n", numbytes); 1634 1635 numbytes = 0xdeadbeef; 1636 ret = PeekNamedPipe(hfile, NULL, 0, NULL, &numbytes, NULL); 1637 ok(ret, "PeekNamedPipe failed with %lu\n", GetLastError()); 1638 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %lu\n", numbytes); 1639 1640 ret = CloseHandle(hpipe); 1641 ok(ret, "CloseHandle failed with %lu\n", GetLastError()); 1642 1643 numbytes = 0xdeadbeef; 1644 memset(buffer, 0, sizeof(buffer)); 1645 ret = ReadFile(hfile, buffer, 0, &numbytes, NULL); 1646 ok(ret, "ReadFile failed with %lu\n", GetLastError()); 1647 ok(numbytes == 0, "expected 0, got %lu\n", numbytes); 1648 1649 numbytes = 0xdeadbeef; 1650 ret = PeekNamedPipe(hfile, NULL, 0, NULL, &numbytes, NULL); 1651 ok(ret, "PeekNamedPipe failed with %lu\n", GetLastError()); 1652 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %lu\n", numbytes); 1653 1654 numbytes = 0xdeadbeef; 1655 memset(buffer, 0, sizeof(buffer)); 1656 ret = ReadFile(hfile, buffer, sizeof(buffer), &numbytes, NULL); 1657 ok(ret, "ReadFile failed with %lu\n", GetLastError()); 1658 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %lu\n", numbytes); 1659 1660 ret = GetNamedPipeHandleStateA(hfile, &state, NULL, NULL, NULL, NULL, 0); 1661 ok(ret, "GetNamedPipeHandleState failed with %lu\n", GetLastError()); 1662 state = PIPE_READMODE_MESSAGE | PIPE_WAIT; 1663 ret = SetNamedPipeHandleState(hfile, &state, NULL, NULL); 1664 ok(ret, "SetNamedPipeHandleState failed with %lu\n", GetLastError()); 1665 1666 SetLastError(0xdeadbeef); 1667 ret = ReadFile(hfile, buffer, 0, &numbytes, NULL); 1668 ok(!ret, "ReadFile unexpectedly succeeded\n"); 1669 ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %lu\n", GetLastError()); 1670 1671 numbytes = 0xdeadbeef; 1672 ret = PeekNamedPipe(hfile, NULL, 0, NULL, &numbytes, NULL); 1673 ok(!ret && GetLastError() == ERROR_BROKEN_PIPE, "PeekNamedPipe returned %x (%lu)\n", 1674 ret, GetLastError()); 1675 ok(numbytes == 0xdeadbeef, "numbytes = %lu\n", numbytes); 1676 1677 SetLastError(0xdeadbeef); 1678 ret = WriteFile(hfile, testdata, sizeof(testdata), &numbytes, NULL); 1679 ok(!ret, "WriteFile unexpectedly succeeded\n"); 1680 ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %lu\n", GetLastError()); 1681 1682 CloseHandle(hfile); 1683 1684 hpipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, 1685 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1686 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); 1687 ok(hpipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %lu\n", GetLastError()); 1688 1689 hfile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 1690 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile failed with %lu\n", GetLastError()); 1691 1692 numbytes = 0xdeadbeef; 1693 ret = WriteFile(hpipe, testdata, 0, &numbytes, NULL); 1694 ok(ret, "WriteFile failed with %lu\n", GetLastError()); 1695 ok(numbytes == 0, "expected 0, got %lu\n", numbytes); 1696 1697 ret = CloseHandle(hpipe); 1698 ok(ret, "CloseHandle failed with %lu\n", GetLastError()); 1699 1700 numbytes = 0xdeadbeef; 1701 memset(buffer, 0, sizeof(buffer)); 1702 ret = ReadFile(hfile, buffer, sizeof(buffer), &numbytes, NULL); 1703 ok(ret, "ReadFile failed with %lu\n", GetLastError()); 1704 ok(numbytes == 0, "expected 0, got %lu\n", numbytes); 1705 1706 SetLastError(0xdeadbeef); 1707 ret = ReadFile(hfile, buffer, 0, &numbytes, NULL); 1708 ok(!ret, "ReadFile unexpectedly succeeded\n"); 1709 ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %lu\n", GetLastError()); 1710 1711 ret = GetNamedPipeHandleStateA(hfile, &state, NULL, NULL, NULL, NULL, 0); 1712 ok(ret, "GetNamedPipeHandleState failed with %lu\n", GetLastError()); 1713 state = PIPE_READMODE_MESSAGE | PIPE_WAIT; 1714 ret = SetNamedPipeHandleState(hfile, &state, NULL, NULL); 1715 ok(ret, "SetNamedPipeHandleState failed with %lu\n", GetLastError()); 1716 1717 SetLastError(0xdeadbeef); 1718 ret = ReadFile(hfile, buffer, 0, &numbytes, NULL); 1719 ok(!ret, "ReadFile unexpectedly succeeded\n"); 1720 ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %lu\n", GetLastError()); 1721 1722 SetLastError(0xdeadbeef); 1723 ret = WriteFile(hfile, testdata, sizeof(testdata), &numbytes, NULL); 1724 ok(!ret, "WriteFile unexpectedly succeeded\n"); 1725 ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %lu\n", GetLastError()); 1726 1727 CloseHandle(hfile); 1728 1729 /* repeat test with hpipe <-> hfile swapped */ 1730 1731 hpipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, 1732 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1733 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); 1734 ok(hpipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %lu\n", GetLastError()); 1735 1736 hfile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 1737 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile failed with %lu\n", GetLastError()); 1738 1739 numbytes = 0xdeadbeef; 1740 ret = WriteFile(hfile, testdata, sizeof(testdata), &numbytes, NULL); 1741 ok(ret, "WriteFile failed with %lu\n", GetLastError()); 1742 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %lu\n", numbytes); 1743 1744 numbytes = 0xdeadbeef; 1745 ret = PeekNamedPipe(hpipe, NULL, 0, NULL, &numbytes, NULL); 1746 ok(ret, "PeekNamedPipe failed with %lu\n", GetLastError()); 1747 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %lu\n", numbytes); 1748 1749 ret = CloseHandle(hfile); 1750 ok(ret, "CloseHandle failed with %lu\n", GetLastError()); 1751 1752 numbytes = 0xdeadbeef; 1753 memset(buffer, 0, sizeof(buffer)); 1754 ret = ReadFile(hpipe, buffer, 0, &numbytes, NULL); 1755 ok(ret || GetLastError() == ERROR_MORE_DATA /* >= Win 8 */, 1756 "ReadFile failed with %lu\n", GetLastError()); 1757 ok(numbytes == 0, "expected 0, got %lu\n", numbytes); 1758 1759 numbytes = 0xdeadbeef; 1760 ret = PeekNamedPipe(hpipe, NULL, 0, NULL, &numbytes, NULL); 1761 ok(ret, "PeekNamedPipe failed with %lu\n", GetLastError()); 1762 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %lu\n", numbytes); 1763 1764 numbytes = 0xdeadbeef; 1765 memset(buffer, 0, sizeof(buffer)); 1766 ret = ReadFile(hpipe, buffer, sizeof(buffer), &numbytes, NULL); 1767 ok(ret, "ReadFile failed with %lu\n", GetLastError()); 1768 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %lu\n", numbytes); 1769 1770 ret = GetNamedPipeHandleStateA(hpipe, &state, NULL, NULL, NULL, NULL, 0); 1771 ok(ret, "GetNamedPipeHandleState failed with %lu\n", GetLastError()); 1772 state = PIPE_READMODE_MESSAGE | PIPE_WAIT; 1773 ret = SetNamedPipeHandleState(hpipe, &state, NULL, NULL); 1774 ok(ret, "SetNamedPipeHandleState failed with %lu\n", GetLastError()); 1775 1776 SetLastError(0xdeadbeef); 1777 ret = ReadFile(hpipe, buffer, 0, &numbytes, NULL); 1778 ok(!ret, "ReadFile unexpectedly succeeded\n"); 1779 ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %lu\n", GetLastError()); 1780 1781 numbytes = 0xdeadbeef; 1782 ret = PeekNamedPipe(hpipe, NULL, 0, NULL, &numbytes, NULL); 1783 ok(!ret && GetLastError() == ERROR_BROKEN_PIPE, "PeekNamedPipe returned %x (%lu)\n", 1784 ret, GetLastError()); 1785 ok(numbytes == 0xdeadbeef, "numbytes = %lu\n", numbytes); 1786 1787 SetLastError(0xdeadbeef); 1788 ret = WriteFile(hpipe, testdata, sizeof(testdata), &numbytes, NULL); 1789 ok(!ret, "WriteFile unexpectedly succeeded\n"); 1790 ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %lu\n", GetLastError()); 1791 1792 CloseHandle(hpipe); 1793 1794 hpipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, 1795 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1796 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); 1797 ok(hpipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %lu\n", GetLastError()); 1798 1799 hfile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 1800 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile failed with %lu\n", GetLastError()); 1801 1802 numbytes = 0xdeadbeef; 1803 ret = WriteFile(hfile, testdata, 0, &numbytes, NULL); 1804 ok(ret, "WriteFile failed with %lu\n", GetLastError()); 1805 ok(numbytes == 0, "expected 0, got %lu\n", numbytes); 1806 1807 ret = CloseHandle(hfile); 1808 ok(ret, "CloseHandle failed with %lu\n", GetLastError()); 1809 1810 numbytes = 0xdeadbeef; 1811 memset(buffer, 0, sizeof(buffer)); 1812 ret = ReadFile(hpipe, buffer, sizeof(buffer), &numbytes, NULL); 1813 ok(ret, "ReadFile failed with %lu\n", GetLastError()); 1814 ok(numbytes == 0, "expected 0, got %lu\n", numbytes); 1815 1816 SetLastError(0xdeadbeef); 1817 ret = ReadFile(hpipe, buffer, 0, &numbytes, NULL); 1818 ok(!ret, "ReadFile unexpectedly succeeded\n"); 1819 ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %lu\n", GetLastError()); 1820 1821 ret = GetNamedPipeHandleStateA(hpipe, &state, NULL, NULL, NULL, NULL, 0); 1822 ok(ret, "GetNamedPipeHandleState failed with %lu\n", GetLastError()); 1823 state = PIPE_READMODE_MESSAGE | PIPE_WAIT; 1824 ret = SetNamedPipeHandleState(hpipe, &state, NULL, NULL); 1825 ok(ret, "SetNamedPipeHandleState failed with %lu\n", GetLastError()); 1826 1827 SetLastError(0xdeadbeef); 1828 ret = ReadFile(hpipe, buffer, 0, &numbytes, NULL); 1829 ok(!ret, "ReadFile unexpectedly succeeded\n"); 1830 ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %lu\n", GetLastError()); 1831 1832 SetLastError(0xdeadbeef); 1833 ret = WriteFile(hpipe, testdata, sizeof(testdata), &numbytes, NULL); 1834 ok(!ret, "WriteFile unexpectedly succeeded\n"); 1835 ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %lu\n", GetLastError()); 1836 1837 CloseHandle(hpipe); 1838} 1839 1840struct named_pipe_client_params 1841{ 1842 DWORD security_flags; 1843 HANDLE token; 1844 BOOL revert; 1845}; 1846 1847#define PIPE_NAME "\\\\.\\pipe\\named_pipe_test" 1848 1849static DWORD CALLBACK named_pipe_client_func(LPVOID p) 1850{ 1851 struct named_pipe_client_params *params = p; 1852 HANDLE pipe; 1853 BOOL ret; 1854 const char message[] = "Test"; 1855 DWORD bytes_read, bytes_written; 1856 char dummy; 1857 TOKEN_PRIVILEGES *Privileges = NULL; 1858 1859 if (params->token) 1860 { 1861 if (params->revert) 1862 { 1863 /* modify the token so we can tell if the pipe impersonation 1864 * token reverts to the process token */ 1865 ret = AdjustTokenPrivileges(params->token, TRUE, NULL, 0, NULL, NULL); 1866 ok(ret, "AdjustTokenPrivileges failed with error %ld\n", GetLastError()); 1867 } 1868 ret = SetThreadToken(NULL, params->token); 1869 ok(ret, "SetThreadToken failed with error %ld\n", GetLastError()); 1870 } 1871 else 1872 { 1873 DWORD Size = 0; 1874 HANDLE process_token; 1875 1876 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES, &process_token); 1877 ok(ret, "OpenProcessToken failed with error %ld\n", GetLastError()); 1878 1879 ret = GetTokenInformation(process_token, TokenPrivileges, NULL, 0, &Size); 1880 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenPrivileges) failed with %ld\n", GetLastError()); 1881 Privileges = HeapAlloc(GetProcessHeap(), 0, Size); 1882 ret = GetTokenInformation(process_token, TokenPrivileges, Privileges, Size, &Size); 1883 ok(ret, "GetTokenInformation(TokenPrivileges) failed with %ld\n", GetLastError()); 1884 1885 ret = AdjustTokenPrivileges(process_token, TRUE, NULL, 0, NULL, NULL); 1886 ok(ret, "AdjustTokenPrivileges failed with error %ld\n", GetLastError()); 1887 1888 CloseHandle(process_token); 1889 } 1890 1891 pipe = CreateFileA(PIPE_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, params->security_flags, NULL); 1892 ok(pipe != INVALID_HANDLE_VALUE, "CreateFile for pipe failed with error %ld\n", GetLastError()); 1893 1894 ret = WriteFile(pipe, message, sizeof(message), &bytes_written, NULL); 1895 ok(ret, "WriteFile failed with error %ld\n", GetLastError()); 1896 1897 ret = ReadFile(pipe, &dummy, sizeof(dummy), &bytes_read, NULL); 1898 ok(ret, "ReadFile failed with error %ld\n", GetLastError()); 1899 1900 if (params->token) 1901 { 1902 if (params->revert) 1903 { 1904 ret = RevertToSelf(); 1905 ok(ret, "RevertToSelf failed with error %ld\n", GetLastError()); 1906 } 1907 else 1908 { 1909 ret = AdjustTokenPrivileges(params->token, TRUE, NULL, 0, NULL, NULL); 1910 ok(ret, "AdjustTokenPrivileges failed with error %ld\n", GetLastError()); 1911 } 1912 } 1913 else 1914 { 1915 HANDLE process_token; 1916 1917 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &process_token); 1918 ok(ret, "OpenProcessToken failed with error %ld\n", GetLastError()); 1919 1920 ret = AdjustTokenPrivileges(process_token, FALSE, Privileges, 0, NULL, NULL); 1921 ok(ret, "AdjustTokenPrivileges failed with error %ld\n", GetLastError()); 1922 1923 HeapFree(GetProcessHeap(), 0, Privileges); 1924 1925 CloseHandle(process_token); 1926 } 1927 1928 ret = WriteFile(pipe, message, sizeof(message), &bytes_written, NULL); 1929 ok(ret, "WriteFile failed with error %ld\n", GetLastError()); 1930 1931 ret = ReadFile(pipe, &dummy, sizeof(dummy), &bytes_read, NULL); 1932 ok(ret, "ReadFile failed with error %ld\n", GetLastError()); 1933 1934 CloseHandle(pipe); 1935 1936 return 0; 1937} 1938 1939static HANDLE make_impersonation_token(DWORD Access, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel) 1940{ 1941 HANDLE ProcessToken; 1942 HANDLE Token = NULL; 1943 BOOL ret; 1944 1945 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &ProcessToken); 1946 ok(ret, "OpenProcessToken failed with error %ld\n", GetLastError()); 1947 1948 ret = pDuplicateTokenEx(ProcessToken, Access, NULL, ImpersonationLevel, TokenImpersonation, &Token); 1949 ok(ret, "DuplicateToken failed with error %ld\n", GetLastError()); 1950 1951 CloseHandle(ProcessToken); 1952 1953 return Token; 1954} 1955 1956static void test_ImpersonateNamedPipeClient(HANDLE hClientToken, DWORD security_flags, BOOL revert, void (*test_func)(int, HANDLE)) 1957{ 1958 HANDLE hPipeServer; 1959 BOOL ret; 1960 DWORD dwTid; 1961 HANDLE hThread; 1962 char buffer[256]; 1963 DWORD dwBytesRead; 1964 DWORD error; 1965 struct named_pipe_client_params params; 1966 char dummy = 0; 1967 DWORD dwBytesWritten; 1968 HANDLE hToken = NULL; 1969 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; 1970 DWORD size; 1971 1972 hPipeServer = CreateNamedPipeA(PIPE_NAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 100, 100, NMPWAIT_USE_DEFAULT_WAIT, NULL); 1973 ok(hPipeServer != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with error %ld\n", GetLastError()); 1974 1975 params.security_flags = security_flags; 1976 params.token = hClientToken; 1977 params.revert = revert; 1978 hThread = CreateThread(NULL, 0, named_pipe_client_func, &params, 0, &dwTid); 1979 ok(hThread != NULL, "CreateThread failed with error %ld\n", GetLastError()); 1980 1981 SetLastError(0xdeadbeef); 1982 ret = ImpersonateNamedPipeClient(hPipeServer); 1983 error = GetLastError(); 1984 ok(ret /* win2k3 */ || (error == ERROR_CANNOT_IMPERSONATE), 1985 "ImpersonateNamedPipeClient should have failed with ERROR_CANNOT_IMPERSONATE instead of %ld\n", GetLastError()); 1986 1987 ret = ConnectNamedPipe(hPipeServer, NULL); 1988 ok(ret || (GetLastError() == ERROR_PIPE_CONNECTED), "ConnectNamedPipe failed with error %ld\n", GetLastError()); 1989 1990 ret = ReadFile(hPipeServer, buffer, sizeof(buffer), &dwBytesRead, NULL); 1991 ok(ret, "ReadFile failed with error %ld\n", GetLastError()); 1992 1993 ret = ImpersonateNamedPipeClient(hPipeServer); 1994 ok(ret, "ImpersonateNamedPipeClient failed with error %ld\n", GetLastError()); 1995 1996 ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken); 1997 ok(ret, "OpenThreadToken failed with error %ld\n", GetLastError()); 1998 1999 (*test_func)(0, hToken); 2000 2001 ImpersonationLevel = 0xdeadbeef; /* to avoid false positives */ 2002 ret = GetTokenInformation(hToken, TokenImpersonationLevel, &ImpersonationLevel, sizeof(ImpersonationLevel), &size); 2003 ok(ret, "GetTokenInformation(TokenImpersonationLevel) failed with error %ld\n", GetLastError()); 2004 ok(ImpersonationLevel == SecurityImpersonation, "ImpersonationLevel should have been SecurityImpersonation(%d) instead of %d\n", SecurityImpersonation, ImpersonationLevel); 2005 2006 CloseHandle(hToken); 2007 2008 RevertToSelf(); 2009 2010 ret = WriteFile(hPipeServer, &dummy, sizeof(dummy), &dwBytesWritten, NULL); 2011 ok(ret, "WriteFile failed with error %ld\n", GetLastError()); 2012 2013 ret = ReadFile(hPipeServer, buffer, sizeof(buffer), &dwBytesRead, NULL); 2014 ok(ret, "ReadFile failed with error %ld\n", GetLastError()); 2015 2016 ret = ImpersonateNamedPipeClient(hPipeServer); 2017 ok(ret, "ImpersonateNamedPipeClient failed with error %ld\n", GetLastError()); 2018 2019 ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken); 2020 ok(ret, "OpenThreadToken failed with error %ld\n", GetLastError()); 2021 2022 (*test_func)(1, hToken); 2023 2024 CloseHandle(hToken); 2025 2026 RevertToSelf(); 2027 2028 ret = WriteFile(hPipeServer, &dummy, sizeof(dummy), &dwBytesWritten, NULL); 2029 ok(ret, "WriteFile failed with error %ld\n", GetLastError()); 2030 2031 WaitForSingleObject(hThread, INFINITE); 2032 2033 ret = ImpersonateNamedPipeClient(hPipeServer); 2034 ok(ret, "ImpersonateNamedPipeClient failed with error %ld\n", GetLastError()); 2035 2036 RevertToSelf(); 2037 2038 CloseHandle(hThread); 2039 CloseHandle(hPipeServer); 2040} 2041 2042static BOOL are_all_privileges_disabled(HANDLE hToken) 2043{ 2044 BOOL ret; 2045 TOKEN_PRIVILEGES *Privileges = NULL; 2046 DWORD Size = 0; 2047 BOOL all_privs_disabled = TRUE; 2048 DWORD i; 2049 2050 ret = GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &Size); 2051 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER) 2052 { 2053 Privileges = HeapAlloc(GetProcessHeap(), 0, Size); 2054 ret = GetTokenInformation(hToken, TokenPrivileges, Privileges, Size, &Size); 2055 if (!ret) 2056 { 2057 HeapFree(GetProcessHeap(), 0, Privileges); 2058 return FALSE; 2059 } 2060 } 2061 else 2062 return FALSE; 2063 2064 for (i = 0; i < Privileges->PrivilegeCount; i++) 2065 { 2066 if (Privileges->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) 2067 { 2068 all_privs_disabled = FALSE; 2069 break; 2070 } 2071 } 2072 2073 HeapFree(GetProcessHeap(), 0, Privileges); 2074 2075 return all_privs_disabled; 2076} 2077 2078static DWORD get_privilege_count(HANDLE hToken) 2079{ 2080 TOKEN_STATISTICS Statistics; 2081 DWORD Size = sizeof(Statistics); 2082 BOOL ret; 2083 2084 ret = GetTokenInformation(hToken, TokenStatistics, &Statistics, Size, &Size); 2085 ok(ret, "GetTokenInformation(TokenStatistics)\n"); 2086 if (!ret) return -1; 2087 2088 return Statistics.PrivilegeCount; 2089} 2090 2091static void test_no_sqos_no_token(int call_index, HANDLE hToken) 2092{ 2093 DWORD priv_count; 2094 2095 switch (call_index) 2096 { 2097 case 0: 2098 priv_count = get_privilege_count(hToken); 2099 todo_wine 2100 ok(priv_count == 0, "privilege count should have been 0 instead of %ld\n", priv_count); 2101 break; 2102 case 1: 2103 priv_count = get_privilege_count(hToken); 2104 ok(priv_count > 0, "privilege count should now be > 0 instead of 0\n"); 2105 ok(!are_all_privileges_disabled(hToken), "impersonated token should not have been modified\n"); 2106 break; 2107 default: 2108 ok(0, "shouldn't happen\n"); 2109 } 2110} 2111 2112static void test_no_sqos(int call_index, HANDLE hToken) 2113{ 2114 switch (call_index) 2115 { 2116 case 0: 2117 ok(!are_all_privileges_disabled(hToken), "token should be a copy of the process one\n"); 2118 break; 2119 case 1: 2120 todo_wine 2121 ok(are_all_privileges_disabled(hToken), "impersonated token should have been modified\n"); 2122 break; 2123 default: 2124 ok(0, "shouldn't happen\n"); 2125 } 2126} 2127 2128static void test_static_context(int call_index, HANDLE hToken) 2129{ 2130 switch (call_index) 2131 { 2132 case 0: 2133 ok(!are_all_privileges_disabled(hToken), "token should be a copy of the process one\n"); 2134 break; 2135 case 1: 2136 ok(!are_all_privileges_disabled(hToken), "impersonated token should not have been modified\n"); 2137 break; 2138 default: 2139 ok(0, "shouldn't happen\n"); 2140 } 2141} 2142 2143static void test_dynamic_context(int call_index, HANDLE hToken) 2144{ 2145 switch (call_index) 2146 { 2147 case 0: 2148 ok(!are_all_privileges_disabled(hToken), "token should be a copy of the process one\n"); 2149 break; 2150 case 1: 2151 todo_wine 2152 ok(are_all_privileges_disabled(hToken), "impersonated token should have been modified\n"); 2153 break; 2154 default: 2155 ok(0, "shouldn't happen\n"); 2156 } 2157} 2158 2159static void test_dynamic_context_no_token(int call_index, HANDLE hToken) 2160{ 2161 switch (call_index) 2162 { 2163 case 0: 2164 ok(are_all_privileges_disabled(hToken), "token should be a copy of the process one\n"); 2165 break; 2166 case 1: 2167 ok(!are_all_privileges_disabled(hToken), "process token modification should have been detected and impersonation token updated\n"); 2168 break; 2169 default: 2170 ok(0, "shouldn't happen\n"); 2171 } 2172} 2173 2174static void test_no_sqos_revert(int call_index, HANDLE hToken) 2175{ 2176 DWORD priv_count; 2177 switch (call_index) 2178 { 2179 case 0: 2180 priv_count = get_privilege_count(hToken); 2181 todo_wine 2182 ok(priv_count == 0, "privilege count should have been 0 instead of %ld\n", priv_count); 2183 break; 2184 case 1: 2185 priv_count = get_privilege_count(hToken); 2186 ok(priv_count > 0, "privilege count should now be > 0 instead of 0\n"); 2187 ok(!are_all_privileges_disabled(hToken), "impersonated token should not have been modified\n"); 2188 break; 2189 default: 2190 ok(0, "shouldn't happen\n"); 2191 } 2192} 2193 2194static void test_static_context_revert(int call_index, HANDLE hToken) 2195{ 2196 switch (call_index) 2197 { 2198 case 0: 2199 todo_wine 2200 ok(are_all_privileges_disabled(hToken), "privileges should have been disabled\n"); 2201 break; 2202 case 1: 2203 todo_wine 2204 ok(are_all_privileges_disabled(hToken), "impersonated token should not have been modified\n"); 2205 break; 2206 default: 2207 ok(0, "shouldn't happen\n"); 2208 } 2209} 2210 2211static void test_dynamic_context_revert(int call_index, HANDLE hToken) 2212{ 2213 switch (call_index) 2214 { 2215 case 0: 2216 todo_wine 2217 ok(are_all_privileges_disabled(hToken), "privileges should have been disabled\n"); 2218 break; 2219 case 1: 2220 ok(!are_all_privileges_disabled(hToken), "impersonated token should now be process token\n"); 2221 break; 2222 default: 2223 ok(0, "shouldn't happen\n"); 2224 } 2225} 2226 2227static void test_impersonation(void) 2228{ 2229 HANDLE hClientToken; 2230 HANDLE hProcessToken; 2231 BOOL ret; 2232 2233 if( !pDuplicateTokenEx ) { 2234 skip("DuplicateTokenEx not found\n"); 2235 return; 2236 } 2237 2238 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hProcessToken); 2239 if (!ret) 2240 { 2241 skip("couldn't open process token, skipping impersonation tests\n"); 2242 return; 2243 } 2244 2245 if (!get_privilege_count(hProcessToken) || are_all_privileges_disabled(hProcessToken)) 2246 { 2247 skip("token didn't have any privileges or they were all disabled. token not suitable for impersonation tests\n"); 2248 CloseHandle(hProcessToken); 2249 return; 2250 } 2251 CloseHandle(hProcessToken); 2252 2253 test_ImpersonateNamedPipeClient(NULL, 0, FALSE, test_no_sqos_no_token); 2254 hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation); 2255 test_ImpersonateNamedPipeClient(hClientToken, 0, FALSE, test_no_sqos); 2256 CloseHandle(hClientToken); 2257 hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation); 2258 test_ImpersonateNamedPipeClient(hClientToken, 2259 SECURITY_SQOS_PRESENT | SECURITY_IMPERSONATION, FALSE, 2260 test_static_context); 2261 CloseHandle(hClientToken); 2262 hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation); 2263 test_ImpersonateNamedPipeClient(hClientToken, 2264 SECURITY_SQOS_PRESENT | SECURITY_CONTEXT_TRACKING | SECURITY_IMPERSONATION, 2265 FALSE, test_dynamic_context); 2266 CloseHandle(hClientToken); 2267 test_ImpersonateNamedPipeClient(NULL, 2268 SECURITY_SQOS_PRESENT | SECURITY_CONTEXT_TRACKING | SECURITY_IMPERSONATION, 2269 FALSE, test_dynamic_context_no_token); 2270 2271 hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation); 2272 test_ImpersonateNamedPipeClient(hClientToken, 0, TRUE, test_no_sqos_revert); 2273 CloseHandle(hClientToken); 2274 hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation); 2275 test_ImpersonateNamedPipeClient(hClientToken, 2276 SECURITY_SQOS_PRESENT | SECURITY_IMPERSONATION, TRUE, 2277 test_static_context_revert); 2278 CloseHandle(hClientToken); 2279 hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation); 2280 test_ImpersonateNamedPipeClient(hClientToken, 2281 SECURITY_SQOS_PRESENT | SECURITY_CONTEXT_TRACKING | SECURITY_IMPERSONATION, 2282 TRUE, test_dynamic_context_revert); 2283 CloseHandle(hClientToken); 2284} 2285 2286struct overlapped_server_args 2287{ 2288 HANDLE pipe_created; 2289}; 2290 2291static DWORD CALLBACK overlapped_server(LPVOID arg) 2292{ 2293 OVERLAPPED ol; 2294 HANDLE pipe; 2295 int ret, err; 2296 struct overlapped_server_args *a = arg; 2297 DWORD num; 2298 char buf[100]; 2299 2300 pipe = CreateNamedPipeA("\\\\.\\pipe\\my pipe", FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 1, 0, 0, 100000, NULL); 2301 ok(pipe != NULL, "pipe NULL\n"); 2302 2303 ol.hEvent = CreateEventA(0, 1, 0, 0); 2304 ok(ol.hEvent != NULL, "event NULL\n"); 2305 ret = ConnectNamedPipe(pipe, &ol); 2306 err = GetLastError(); 2307 ok(ret == 0, "ret %d\n", ret); 2308 ok(err == ERROR_IO_PENDING, "gle %d\n", err); 2309 SetEvent(a->pipe_created); 2310 2311 ret = WaitForSingleObjectEx(ol.hEvent, INFINITE, 1); 2312 ok(ret == WAIT_OBJECT_0, "ret %x\n", ret); 2313 2314 ret = GetOverlappedResult(pipe, &ol, &num, 1); 2315 ok(ret == 1, "ret %d\n", ret); 2316 2317 /* This should block */ 2318 ret = ReadFile(pipe, buf, sizeof(buf), &num, NULL); 2319 ok(ret == 1, "ret %d\n", ret); 2320 2321 DisconnectNamedPipe(pipe); 2322 2323 ret = ConnectNamedPipe(pipe, &ol); 2324 err = GetLastError(); 2325 ok(ret == 0, "ret %d\n", ret); 2326 ok(err == ERROR_IO_PENDING, "gle %d\n", err); 2327 CancelIo(pipe); 2328 ret = WaitForSingleObjectEx(ol.hEvent, INFINITE, 1); 2329 ok(ret == WAIT_OBJECT_0, "ret %x\n", ret); 2330 2331 ret = GetOverlappedResult(pipe, &ol, &num, 1); 2332 err = GetLastError(); 2333 ok(ret == 0, "ret %d\n", ret); 2334 ok(err == ERROR_OPERATION_ABORTED, "gle %d\n", err); 2335 2336 CloseHandle(ol.hEvent); 2337 CloseHandle(pipe); 2338 return 1; 2339} 2340 2341static void test_overlapped(void) 2342{ 2343 DWORD tid, num; 2344 HANDLE thread, pipe; 2345 BOOL ret; 2346 struct overlapped_server_args args; 2347 2348 args.pipe_created = CreateEventA(0, 1, 0, 0); 2349 thread = CreateThread(NULL, 0, overlapped_server, &args, 0, &tid); 2350 2351 WaitForSingleObject(args.pipe_created, INFINITE); 2352 pipe = CreateFileA("\\\\.\\pipe\\my pipe", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); 2353 ok(pipe != INVALID_HANDLE_VALUE, "cf failed\n"); 2354 2355 /* Sleep to try to get the ReadFile in the server to occur before the following WriteFile */ 2356 Sleep(1); 2357 2358 ret = WriteFile(pipe, "x", 1, &num, NULL); 2359 ok(ret, "WriteFile failed with error %ld\n", GetLastError()); 2360 2361 WaitForSingleObject(thread, INFINITE); 2362 CloseHandle(pipe); 2363 CloseHandle(args.pipe_created); 2364 CloseHandle(thread); 2365} 2366 2367static void test_overlapped_error(void) 2368{ 2369 HANDLE pipe, file, event; 2370 DWORD err, numbytes; 2371 OVERLAPPED overlapped; 2372 BOOL ret; 2373 2374 event = CreateEventA(NULL, TRUE, FALSE, NULL); 2375 ok(event != NULL, "CreateEventA failed with %lu\n", GetLastError()); 2376 2377 pipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 2378 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 2379 1, 1024, 1024, NMPWAIT_WAIT_FOREVER, NULL); 2380 ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %lu\n", GetLastError()); 2381 2382 memset(&overlapped, 0, sizeof(overlapped)); 2383 overlapped.hEvent = event; 2384 ret = ConnectNamedPipe(pipe, &overlapped); 2385 err = GetLastError(); 2386 ok(ret == FALSE, "ConnectNamedPipe succeeded\n"); 2387 ok(err == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %lu\n", err); 2388 2389 file = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, 2390 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); 2391 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed with %lu\n", GetLastError()); 2392 2393 numbytes = 0xdeadbeef; 2394 ret = GetOverlappedResult(pipe, &overlapped, &numbytes, TRUE); 2395 ok(ret == TRUE, "GetOverlappedResult failed\n"); 2396 ok(numbytes == 0, "expected 0, got %lu\n", numbytes); 2397 ok(overlapped.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08Ix\n", overlapped.Internal); 2398 2399 CloseHandle(file); 2400 CloseHandle(pipe); 2401 2402 pipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 2403 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 2404 1, 1024, 1024, NMPWAIT_WAIT_FOREVER, NULL); 2405 ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %lu\n", GetLastError()); 2406 2407 file = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, 2408 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); 2409 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed with %lu\n", GetLastError()); 2410 2411 memset(&overlapped, 0, sizeof(overlapped)); 2412 overlapped.hEvent = event; 2413 ret = ConnectNamedPipe(pipe, &overlapped); 2414 err = GetLastError(); 2415 ok(ret == FALSE, "ConnectNamedPipe succeeded\n"); 2416 ok(err == ERROR_PIPE_CONNECTED, "expected ERROR_PIPE_CONNECTED, got %lu\n", err); 2417 ok(overlapped.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %08Ix\n", overlapped.Internal); 2418 2419 CloseHandle(file); 2420 CloseHandle(pipe); 2421 2422 CloseHandle(event); 2423} 2424 2425static void test_NamedPipeHandleState(void) 2426{ 2427 HANDLE server, client; 2428 BOOL ret; 2429 DWORD state, instances, maxCollectionCount, collectDataTimeout; 2430 char userName[MAX_PATH]; 2431 2432 server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, 2433 /* dwOpenMode */ PIPE_TYPE_BYTE | PIPE_WAIT, 2434 /* nMaxInstances */ 1, 2435 /* nOutBufSize */ 1024, 2436 /* nInBufSize */ 1024, 2437 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 2438 /* lpSecurityAttrib */ NULL); 2439 ok(server != INVALID_HANDLE_VALUE, "cf failed\n"); 2440 ret = GetNamedPipeHandleStateA(server, NULL, NULL, NULL, NULL, NULL, 0); 2441 ok(ret, "GetNamedPipeHandleState failed: %ld\n", GetLastError()); 2442 ret = GetNamedPipeHandleStateA(server, &state, &instances, NULL, NULL, NULL, 2443 0); 2444 ok(ret, "GetNamedPipeHandleState failed: %ld\n", GetLastError()); 2445 if (ret) 2446 { 2447 ok(state == 0, "unexpected state %08lx\n", state); 2448 ok(instances == 1, "expected 1 instances, got %ld\n", instances); 2449 } 2450 /* Some parameters have no meaning, and therefore can't be retrieved, 2451 * on a local pipe. 2452 */ 2453 SetLastError(0xdeadbeef); 2454 ret = GetNamedPipeHandleStateA(server, &state, &instances, &maxCollectionCount, 2455 &collectDataTimeout, userName, ARRAY_SIZE(userName)); 2456 todo_wine 2457 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 2458 "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); 2459 /* A byte-mode pipe server can't be changed to message mode. */ 2460 state = PIPE_READMODE_MESSAGE; 2461 SetLastError(0xdeadbeef); 2462 ret = SetNamedPipeHandleState(server, &state, NULL, NULL); 2463 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 2464 "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); 2465 2466 client = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, NULL, 2467 OPEN_EXISTING, 0, NULL); 2468 ok(client != INVALID_HANDLE_VALUE, "cf failed\n"); 2469 2470 state = PIPE_READMODE_BYTE; 2471 ret = SetNamedPipeHandleState(client, &state, NULL, NULL); 2472 ok(ret, "SetNamedPipeHandleState failed: %ld\n", GetLastError()); 2473 /* A byte-mode pipe client can't be changed to message mode, either. */ 2474 state = PIPE_READMODE_MESSAGE; 2475 SetLastError(0xdeadbeef); 2476 ret = SetNamedPipeHandleState(server, &state, NULL, NULL); 2477 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 2478 "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); 2479 2480 CloseHandle(client); 2481 CloseHandle(server); 2482 2483 server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, 2484 /* dwOpenMode */ PIPE_TYPE_MESSAGE | PIPE_WAIT, 2485 /* nMaxInstances */ 1, 2486 /* nOutBufSize */ 1024, 2487 /* nInBufSize */ 1024, 2488 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 2489 /* lpSecurityAttrib */ NULL); 2490 ok(server != INVALID_HANDLE_VALUE, "cf failed\n"); 2491 ret = GetNamedPipeHandleStateA(server, NULL, NULL, NULL, NULL, NULL, 0); 2492 ok(ret, "GetNamedPipeHandleState failed: %ld\n", GetLastError()); 2493 ret = GetNamedPipeHandleStateA(server, &state, &instances, NULL, NULL, NULL, 2494 0); 2495 ok(ret, "GetNamedPipeHandleState failed: %ld\n", GetLastError()); 2496 if (ret) 2497 { 2498 ok(state == 0, "unexpected state %08lx\n", state); 2499 ok(instances == 1, "expected 1 instances, got %ld\n", instances); 2500 } 2501 /* In contrast to byte-mode pipes, a message-mode pipe server can be 2502 * changed to byte mode. 2503 */ 2504 state = PIPE_READMODE_BYTE; 2505 ret = SetNamedPipeHandleState(server, &state, NULL, NULL); 2506 ok(ret, "SetNamedPipeHandleState failed: %ld\n", GetLastError()); 2507 2508 client = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, NULL, 2509 OPEN_EXISTING, 0, NULL); 2510 ok(client != INVALID_HANDLE_VALUE, "cf failed\n"); 2511 2512 state = PIPE_READMODE_MESSAGE; 2513 ret = SetNamedPipeHandleState(client, &state, NULL, NULL); 2514 ok(ret, "SetNamedPipeHandleState failed: %ld\n", GetLastError()); 2515 /* A message-mode pipe client can also be changed to byte mode. 2516 */ 2517 state = PIPE_READMODE_BYTE; 2518 ret = SetNamedPipeHandleState(client, &state, NULL, NULL); 2519 ok(ret, "SetNamedPipeHandleState failed: %ld\n", GetLastError()); 2520 2521 CloseHandle(client); 2522 CloseHandle(server); 2523} 2524 2525static void test_GetNamedPipeInfo(void) 2526{ 2527 HANDLE server; 2528 2529 server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, 2530 /* dwOpenMode */ PIPE_TYPE_BYTE | PIPE_WAIT, 2531 /* nMaxInstances */ 1, 2532 /* nOutBufSize */ 1024, 2533 /* nInBufSize */ 1024, 2534 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 2535 /* lpSecurityAttrib */ NULL); 2536 ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 2537 2538 test_pipe_info(server, PIPE_SERVER_END | PIPE_TYPE_BYTE, 1024, 1024, 1); 2539 2540 CloseHandle(server); 2541 2542 server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, 2543 /* dwOpenMode */ PIPE_TYPE_MESSAGE | PIPE_NOWAIT, 2544 /* nMaxInstances */ 3, 2545 /* nOutBufSize */ 1024, 2546 /* nInBufSize */ 1024, 2547 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 2548 /* lpSecurityAttrib */ NULL); 2549 ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 2550 2551 test_pipe_info(server, PIPE_SERVER_END | PIPE_TYPE_MESSAGE, 1024, 1024, 3); 2552 2553 CloseHandle(server); 2554 2555 server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, 2556 /* dwOpenMode */ PIPE_TYPE_MESSAGE | PIPE_WAIT, 2557 /* nMaxInstances */ 1, 2558 /* nOutBufSize */ 0, 2559 /* nInBufSize */ 0, 2560 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 2561 /* lpSecurityAttrib */ NULL); 2562 ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 2563 2564 test_pipe_info(server, PIPE_SERVER_END | PIPE_TYPE_MESSAGE, 0, 0, 1); 2565 2566 CloseHandle(server); 2567 2568 server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, 2569 /* dwOpenMode */ PIPE_TYPE_MESSAGE | PIPE_WAIT, 2570 /* nMaxInstances */ 1, 2571 /* nOutBufSize */ 0xf000, 2572 /* nInBufSize */ 0xf000, 2573 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 2574 /* lpSecurityAttrib */ NULL); 2575 ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 2576 2577 test_pipe_info(server, PIPE_SERVER_END | PIPE_TYPE_MESSAGE, 0xf000, 0xf000, 1); 2578 2579 CloseHandle(server); 2580} 2581 2582static void test_readfileex_pending(void) 2583{ 2584 HANDLE server, client, event; 2585 BOOL ret; 2586 DWORD err, wait, num_bytes; 2587 OVERLAPPED overlapped; 2588 char read_buf[1024]; 2589 char write_buf[1024]; 2590 const char test_string[] = "test"; 2591 int i; 2592 2593 server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, 2594 /* dwOpenMode */ PIPE_TYPE_BYTE | PIPE_WAIT, 2595 /* nMaxInstances */ 1, 2596 /* nOutBufSize */ 1024, 2597 /* nInBufSize */ 1024, 2598 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 2599 /* lpSecurityAttrib */ NULL); 2600 ok(server != INVALID_HANDLE_VALUE, "cf failed\n"); 2601 2602 event = CreateEventA(NULL, TRUE, FALSE, NULL); 2603 ok(event != NULL, "CreateEventA failed\n"); 2604 2605 memset(&overlapped, 0, sizeof(overlapped)); 2606 overlapped.hEvent = event; 2607 2608 ret = ConnectNamedPipe(server, &overlapped); 2609 err = GetLastError(); 2610 ok(ret == FALSE, "ConnectNamedPipe succeeded\n"); 2611 ok(err == ERROR_IO_PENDING, "ConnectNamedPipe set error %li\n", err); 2612 2613 wait = WaitForSingleObject(event, 0); 2614 ok(wait == WAIT_TIMEOUT, "WaitForSingleObject returned %lx\n", wait); 2615 2616 client = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, NULL, 2617 OPEN_EXISTING, 0, NULL); 2618 ok(client != INVALID_HANDLE_VALUE, "cf failed\n"); 2619 2620 wait = WaitForSingleObject(event, 0); 2621 ok(wait == WAIT_OBJECT_0, "WaitForSingleObject returned %lx\n", wait); 2622 2623 /* Start a read that can't complete immediately. */ 2624 completion_called = 0; 2625 ResetEvent(event); 2626 ret = ReadFileEx(server, read_buf, sizeof(read_buf), &overlapped, completion_routine); 2627 ok(ret == TRUE, "ReadFileEx failed, err=%li\n", GetLastError()); 2628 ok(completion_called == 0, "completion routine called before ReadFileEx returned\n"); 2629 2630 ret = WriteFile(client, test_string, strlen(test_string), &num_bytes, NULL); 2631 ok(ret == TRUE, "WriteFile failed\n"); 2632 ok(num_bytes == strlen(test_string), "only %li bytes written\n", num_bytes); 2633 2634 ok(completion_called == 0, "completion routine called during WriteFile\n"); 2635 2636 wait = WaitForSingleObjectEx(event, 0, TRUE); 2637 ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObjectEx returned %lx\n", wait); 2638 2639 ok(completion_called == 1, "completion not called after writing pipe\n"); 2640 ok(completion_errorcode == 0, "completion called with error %lx\n", completion_errorcode); 2641 ok(completion_num_bytes == strlen(test_string), "ReadFileEx returned only %ld bytes\n", completion_num_bytes); 2642 ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n"); 2643 ok(!memcmp(test_string, read_buf, strlen(test_string)), "ReadFileEx read wrong bytes\n"); 2644 2645 /* Make writes until the pipe is full and the write fails */ 2646 memset(write_buf, 0xaa, sizeof(write_buf)); 2647 for (i=0; i<256; i++) 2648 { 2649 completion_called = 0; 2650 ResetEvent(event); 2651 ret = WriteFileEx(server, write_buf, sizeof(write_buf), &overlapped, completion_routine); 2652 err = GetLastError(); 2653 2654 ok(completion_called == 0, "completion routine called during WriteFileEx\n"); 2655 2656 wait = WaitForSingleObjectEx(event, 0, TRUE); 2657 2658 if (wait == WAIT_TIMEOUT) 2659 /* write couldn't complete immediately, presumably the pipe is full */ 2660 break; 2661 2662 ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObject returned %lx\n", wait); 2663 2664 ok(ret == TRUE, "WriteFileEx failed, err=%li\n", err); 2665 ok(completion_errorcode == 0, "completion called with error %lx\n", completion_errorcode); 2666 ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n"); 2667 } 2668 2669 ok(ret == TRUE, "WriteFileEx failed, err=%li\n", err); 2670 ok(completion_called == 0, "completion routine called but wait timed out\n"); 2671 ok(completion_errorcode == 0, "completion called with error %lx\n", completion_errorcode); 2672 ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n"); 2673 2674 /* free up some space in the pipe */ 2675 for (i=0; i<256; i++) 2676 { 2677 ret = ReadFile(client, read_buf, sizeof(read_buf), &num_bytes, NULL); 2678 ok(ret == TRUE, "ReadFile failed\n"); 2679 2680 ok(completion_called == 0, "completion routine called during ReadFile\n"); 2681 2682 wait = WaitForSingleObjectEx(event, 0, TRUE); 2683 ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0 || wait == WAIT_TIMEOUT, 2684 "WaitForSingleObject returned %lx\n", wait); 2685 if (wait != WAIT_TIMEOUT) break; 2686 } 2687 2688 ok(completion_called == 1, "completion routine not called\n"); 2689 ok(completion_errorcode == 0, "completion called with error %lx\n", completion_errorcode); 2690 ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n"); 2691 2692 num_bytes = 0xdeadbeef; 2693 SetLastError(0xdeadbeef); 2694 ret = ReadFile(INVALID_HANDLE_VALUE, read_buf, 0, &num_bytes, NULL); 2695 ok(!ret, "ReadFile should fail\n"); 2696 ok(GetLastError() == ERROR_INVALID_HANDLE, "wrong error %lu\n", GetLastError()); 2697 ok(num_bytes == 0, "expected 0, got %lu\n", num_bytes); 2698 2699 overlapped.Offset = 0; 2700 overlapped.OffsetHigh = 0; 2701 overlapped.Internal = -1; 2702 overlapped.InternalHigh = -1; 2703 overlapped.hEvent = event; 2704 num_bytes = 0xdeadbeef; 2705 SetLastError(0xdeadbeef); 2706 ret = ReadFile(server, read_buf, 0, &num_bytes, &overlapped); 2707 ok(!ret, "ReadFile should fail\n"); 2708 ok(GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %ld\n", GetLastError()); 2709 ok(num_bytes == 0, "bytes %lu\n", num_bytes); 2710 ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %#Ix\n", overlapped.Internal); 2711 ok(overlapped.InternalHigh == -1, "expected -1, got %Iu\n", overlapped.InternalHigh); 2712 2713 wait = WaitForSingleObject(event, 100); 2714 ok(wait == WAIT_TIMEOUT, "WaitForSingleObject returned %lx\n", wait); 2715 2716 num_bytes = 0xdeadbeef; 2717 ret = WriteFile(client, test_string, 1, &num_bytes, NULL); 2718 ok(ret, "WriteFile failed\n"); 2719 ok(num_bytes == 1, "bytes %lu\n", num_bytes); 2720 2721 wait = WaitForSingleObject(event, 100); 2722 ok(wait == WAIT_OBJECT_0, "WaitForSingleObject returned %lx\n", wait); 2723 2724 ok(num_bytes == 1, "bytes %lu\n", num_bytes); 2725 ok((NTSTATUS)overlapped.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#Ix\n", overlapped.Internal); 2726 ok(overlapped.InternalHigh == 0, "expected 0, got %Iu\n", overlapped.InternalHigh); 2727 2728 /* read the pending byte and clear the pipe */ 2729 num_bytes = 0xdeadbeef; 2730 ret = ReadFile(server, read_buf, 1, &num_bytes, &overlapped); 2731 ok(ret, "ReadFile failed\n"); 2732 ok(num_bytes == 1, "bytes %lu\n", num_bytes); 2733 2734 CloseHandle(client); 2735 CloseHandle(server); 2736 CloseHandle(event); 2737} 2738 2739#define test_peek_pipe(a,b,c,d) _test_peek_pipe(__LINE__,a,b,c,d) 2740static void _test_peek_pipe(unsigned line, HANDLE pipe, DWORD expected_read, DWORD expected_avail, DWORD expected_message_length) 2741{ 2742 DWORD bytes_read = 0xdeadbeed, avail = 0xdeadbeef, left = 0xdeadbeed; 2743 char buf[12000]; 2744 FILE_PIPE_PEEK_BUFFER *peek_buf = (void*)buf; 2745 IO_STATUS_BLOCK io; 2746 NTSTATUS status; 2747 BOOL r; 2748 2749 r = PeekNamedPipe(pipe, buf, sizeof(buf), &bytes_read, &avail, &left); 2750 ok_(__FILE__,line)(r, "PeekNamedPipe failed: %lu\n", GetLastError()); 2751 ok_(__FILE__,line)(bytes_read == expected_read, "bytes_read = %lu, expected %lu\n", bytes_read, expected_read); 2752 ok_(__FILE__,line)(avail == expected_avail, "avail = %lu, expected %lu\n", avail, expected_avail); 2753 ok_(__FILE__,line)(left == expected_message_length - expected_read, "left = %ld, expected %ld\n", 2754 left, expected_message_length - expected_read); 2755 2756 status = NtFsControlFile(pipe, 0, NULL, NULL, &io, FSCTL_PIPE_PEEK, NULL, 0, buf, sizeof(buf)); 2757 ok_(__FILE__,line)(!status || status == STATUS_PENDING, "NtFsControlFile(FSCTL_PIPE_PEEK) failed: %lx\n", status); 2758 ok_(__FILE__,line)(io.Information == FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[expected_read]), 2759 "io.Information = %Iu\n", io.Information); 2760 ok_(__FILE__,line)(peek_buf->ReadDataAvailable == expected_avail, "ReadDataAvailable = %lu, expected %lu\n", 2761 peek_buf->ReadDataAvailable, expected_avail); 2762 ok_(__FILE__,line)(peek_buf->MessageLength == expected_message_length, "MessageLength = %lu, expected %lu\n", 2763 peek_buf->MessageLength, expected_message_length); 2764 2765 if (expected_read) 2766 { 2767 r = PeekNamedPipe(pipe, buf, 1, &bytes_read, &avail, &left); 2768 ok_(__FILE__,line)(r, "PeekNamedPipe failed: %lu\n", GetLastError()); 2769 ok_(__FILE__,line)(bytes_read == 1, "bytes_read = %lu, expected %lu\n", bytes_read, expected_read); 2770 ok_(__FILE__,line)(avail == expected_avail, "avail = %lu, expected %lu\n", avail, expected_avail); 2771 ok_(__FILE__,line)(left == expected_message_length-1, "left = %ld, expected %ld\n", left, expected_message_length-1); 2772 } 2773} 2774 2775#define overlapped_read_sync(a,b,c,d,e) _overlapped_read_sync(__LINE__,a,b,c,d,e) 2776static void _overlapped_read_sync(unsigned line, HANDLE reader, void *buf, DWORD buf_size, DWORD expected_result, BOOL partial_read) 2777{ 2778 DWORD read_bytes = 0xdeadbeef; 2779 OVERLAPPED overlapped; 2780 BOOL res; 2781 2782 memset(&overlapped, 0, sizeof(overlapped)); 2783 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 2784 res = ReadFile(reader, buf, buf_size, &read_bytes, &overlapped); 2785 if (partial_read) 2786 ok_(__FILE__,line)(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned: %x (%lu)\n", res, GetLastError()); 2787 else 2788 ok_(__FILE__,line)(res, "ReadFile failed: %lu\n", GetLastError()); 2789 if(partial_read) 2790 ok_(__FILE__,line)(!read_bytes, "read_bytes %lu expected 0\n", read_bytes); 2791 else 2792 ok_(__FILE__,line)(read_bytes == expected_result, "read_bytes %lu expected %lu\n", read_bytes, expected_result); 2793 2794 read_bytes = 0xdeadbeef; 2795 res = GetOverlappedResult(reader, &overlapped, &read_bytes, FALSE); 2796 if (partial_read) 2797 ok_(__FILE__,line)(!res && GetLastError() == ERROR_MORE_DATA, 2798 "GetOverlappedResult returned: %x (%lu)\n", res, GetLastError()); 2799 else 2800 ok_(__FILE__,line)(res, "GetOverlappedResult failed: %lu\n", GetLastError()); 2801 ok_(__FILE__,line)(read_bytes == expected_result, "read_bytes %lu expected %lu\n", read_bytes, expected_result); 2802 CloseHandle(overlapped.hEvent); 2803} 2804 2805#define overlapped_read_async(a,b,c,d) _overlapped_read_async(__LINE__,a,b,c,d) 2806static void _overlapped_read_async(unsigned line, HANDLE reader, void *buf, DWORD buf_size, OVERLAPPED *overlapped) 2807{ 2808 DWORD read_bytes = 0xdeadbeef; 2809 BOOL res; 2810 2811 memset(overlapped, 0, sizeof(*overlapped)); 2812 overlapped->hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 2813 res = ReadFile(reader, buf, buf_size, &read_bytes, overlapped); 2814 ok_(__FILE__,line)(!res && GetLastError() == ERROR_IO_PENDING, "ReadFile returned %x(%lu)\n", res, GetLastError()); 2815 ok_(__FILE__,line)(!read_bytes, "read_bytes %lu expected 0\n", read_bytes); 2816 2817 _test_not_signaled(line, overlapped->hEvent); 2818} 2819 2820#define overlapped_write_sync(a,b,c) _overlapped_write_sync(__LINE__,a,b,c) 2821static void _overlapped_write_sync(unsigned line, HANDLE writer, void *buf, DWORD size) 2822{ 2823 DWORD written_bytes = 0xdeadbeef; 2824 OVERLAPPED overlapped; 2825 BOOL res; 2826 2827 memset(&overlapped, 0, sizeof(overlapped)); 2828 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 2829 res = WriteFile(writer, buf, size, &written_bytes, &overlapped); 2830 ok_(__FILE__,line)(res, "WriteFile returned %x(%lu)\n", res, GetLastError()); 2831 ok_(__FILE__,line)(written_bytes == size, "WriteFile returned written_bytes = %lu\n", written_bytes); 2832 2833 written_bytes = 0xdeadbeef; 2834 res = GetOverlappedResult(writer, &overlapped, &written_bytes, FALSE); 2835 ok_(__FILE__,line)(res, "GetOverlappedResult failed: %lu\n", GetLastError()); 2836 ok_(__FILE__,line)(written_bytes == size, "GetOverlappedResult returned written_bytes %lu expected %lu\n", written_bytes, size); 2837 2838 CloseHandle(overlapped.hEvent); 2839} 2840 2841#define overlapped_write_async(a,b,c,d) _overlapped_write_async(__LINE__,a,b,c,d) 2842static void _overlapped_write_async(unsigned line, HANDLE writer, void *buf, DWORD size, OVERLAPPED *overlapped) 2843{ 2844 DWORD written_bytes = 0xdeadbeef; 2845 BOOL res; 2846 2847 memset(overlapped, 0, sizeof(*overlapped)); 2848 overlapped->hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 2849 res = WriteFile(writer, buf, size, &written_bytes, overlapped); 2850 ok_(__FILE__,line)(!res && GetLastError() == ERROR_IO_PENDING, "WriteFile returned %x(%lu)\n", res, GetLastError()); 2851 ok_(__FILE__,line)(!written_bytes, "written_bytes = %lu\n", written_bytes); 2852 2853 _test_not_signaled(line, overlapped->hEvent); 2854} 2855 2856#define test_flush_sync(a) _test_flush_sync(__LINE__,a) 2857static void _test_flush_sync(unsigned line, HANDLE pipe) 2858{ 2859 BOOL res; 2860 2861 res = FlushFileBuffers(pipe); 2862 ok_(__FILE__,line)(res, "FlushFileBuffers failed: %lu\n", GetLastError()); 2863} 2864 2865static DWORD expected_flush_error; 2866 2867static DWORD CALLBACK flush_proc(HANDLE pipe) 2868{ 2869 BOOL res; 2870 2871 res = FlushFileBuffers(pipe); 2872 if (expected_flush_error == ERROR_SUCCESS) 2873 { 2874 ok(res, "FlushFileBuffers failed: %lu\n", GetLastError()); 2875 } 2876 else 2877 { 2878 ok(!res, "FlushFileBuffers should have failed\n"); 2879 ok(GetLastError() == expected_flush_error, 2880 "FlushFileBuffers set error %lu, expected %lu\n", GetLastError(), expected_flush_error); 2881 } 2882 return 0; 2883} 2884 2885#define test_flush_async(a,b) _test_flush_async(__LINE__,a,b) 2886static HANDLE _test_flush_async(unsigned line, HANDLE pipe, DWORD error) 2887{ 2888 HANDLE thread; 2889 DWORD tid; 2890 2891 expected_flush_error = error; 2892 thread = CreateThread(NULL, 0, flush_proc, pipe, 0, &tid); 2893 ok_(__FILE__,line)(thread != NULL, "CreateThread failed: %lu\n", GetLastError()); 2894 2895 Sleep(50); 2896 _test_not_signaled(line, thread); 2897 return thread; 2898} 2899 2900#define test_flush_done(a) _test_flush_done(__LINE__,a) 2901static void _test_flush_done(unsigned line, HANDLE thread) 2902{ 2903 DWORD res = WaitForSingleObject(thread, 1000); 2904 ok_(__FILE__,line)(res == WAIT_OBJECT_0, "WaitForSingleObject returned %lu (%lu)\n", res, GetLastError()); 2905 CloseHandle(thread); 2906} 2907 2908#define test_overlapped_result(a,b,c,d) _test_overlapped_result(__LINE__,a,b,c,d) 2909static void _test_overlapped_result(unsigned line, HANDLE handle, OVERLAPPED *overlapped, DWORD expected_result, BOOL partial_read) 2910{ 2911 DWORD result = 0xdeadbeef; 2912 BOOL res; 2913 2914 _test_signaled(line, overlapped->hEvent); 2915 2916 res = GetOverlappedResult(handle, overlapped, &result, FALSE); 2917 if (partial_read) 2918 ok_(__FILE__,line)(!res && GetLastError() == ERROR_MORE_DATA, "GetOverlappedResult returned: %x (%lu)\n", res, GetLastError()); 2919 else 2920 ok_(__FILE__,line)(res, "GetOverlappedResult failed: %lu\n", GetLastError()); 2921 ok_(__FILE__,line)(result == expected_result, "read_bytes = %lu, expected %lu\n", result, expected_result); 2922 CloseHandle(overlapped->hEvent); 2923} 2924 2925#define test_overlapped_failure(a,b,c) _test_overlapped_failure(__LINE__,a,b,c) 2926static void _test_overlapped_failure(unsigned line, HANDLE handle, OVERLAPPED *overlapped, DWORD error) 2927{ 2928 DWORD result; 2929 BOOL res; 2930 2931 _test_signaled(line, overlapped->hEvent); 2932 2933 res = GetOverlappedResult(handle, overlapped, &result, FALSE); 2934 ok_(__FILE__,line)(!res && GetLastError() == error, "GetOverlappedResult returned: %x (%lu), expected error %lu\n", 2935 res, GetLastError(), error); 2936 ok_(__FILE__,line)(!result, "result = %lu\n", result); 2937 CloseHandle(overlapped->hEvent); 2938} 2939 2940#define cancel_overlapped(a,b) _cancel_overlapped(__LINE__,a,b) 2941static void _cancel_overlapped(unsigned line, HANDLE handle, OVERLAPPED *overlapped) 2942{ 2943 BOOL res; 2944 2945 res = pCancelIoEx(handle, overlapped); 2946 ok_(__FILE__,line)(res, "CancelIoEx failed: %lu\n", GetLastError()); 2947 2948 _test_overlapped_failure(line, handle, overlapped, ERROR_OPERATION_ABORTED); 2949} 2950 2951static void test_blocking_rw(HANDLE writer, HANDLE reader, DWORD buf_size, BOOL msg_mode, BOOL msg_read) 2952{ 2953 OVERLAPPED read_overlapped, read_overlapped2, write_overlapped, write_overlapped2; 2954 char buf[10000], read_buf[10000]; 2955 HANDLE flush_thread; 2956 BOOL res; 2957 2958 memset(buf, 0xaa, sizeof(buf)); 2959 2960 /* test pending read with overlapped event */ 2961 overlapped_read_async(reader, read_buf, 1000, &read_overlapped); 2962 test_flush_sync(writer); 2963 test_peek_pipe(reader, 0, 0, 0); 2964 2965 /* write more data than needed for read */ 2966 overlapped_write_sync(writer, buf, 4000); 2967 test_overlapped_result(reader, &read_overlapped, 1000, msg_read); 2968 test_peek_pipe(reader, 3000, 3000, msg_mode ? 3000 : 0); 2969 2970 /* test pending write with overlapped event */ 2971 overlapped_write_async(writer, buf, buf_size, &write_overlapped); 2972 test_peek_pipe(reader, 3000 + (msg_mode ? 0 : buf_size), 3000 + buf_size, msg_mode ? 3000 : 0); 2973 2974 /* write one more byte */ 2975 overlapped_write_async(writer, buf, 1, &write_overlapped2); 2976 flush_thread = test_flush_async(writer, ERROR_SUCCESS); 2977 test_not_signaled(write_overlapped.hEvent); 2978 test_peek_pipe(reader, 3000 + (msg_mode ? 0 : buf_size + 1), 3000 + buf_size + 1, 2979 msg_mode ? 3000 : 0); 2980 2981 /* empty write will not block */ 2982 overlapped_write_sync(writer, buf, 0); 2983 test_not_signaled(write_overlapped.hEvent); 2984 test_not_signaled(write_overlapped2.hEvent); 2985 test_peek_pipe(reader, 3000 + (msg_mode ? 0 : buf_size + 1), 3000 + buf_size + 1, 2986 msg_mode ? 3000 : 0); 2987 2988 /* read remaining data from the first write */ 2989 overlapped_read_sync(reader, read_buf, 3000, 3000, FALSE); 2990 test_overlapped_result(writer, &write_overlapped, buf_size, FALSE); 2991 test_not_signaled(write_overlapped2.hEvent); 2992 test_not_signaled(flush_thread); 2993 test_peek_pipe(reader, buf_size + (msg_mode ? 0 : 1), buf_size + 1, msg_mode ? buf_size : 0); 2994 2995 /* read one byte so that the next write fits the buffer */ 2996 overlapped_read_sync(reader, read_buf, 1, 1, msg_read); 2997 test_overlapped_result(writer, &write_overlapped2, 1, FALSE); 2998 test_peek_pipe(reader, buf_size + (msg_mode ? -1 : 0), buf_size, msg_mode ? buf_size - 1 : 0); 2999 3000 /* read the whole buffer */ 3001 overlapped_read_sync(reader, read_buf, buf_size, buf_size-msg_read, FALSE); 3002 test_peek_pipe(reader, msg_read ? 1 : 0, msg_read ? 1 : 0, msg_read ? 1 : 0); 3003 3004 if(msg_read) 3005 { 3006 overlapped_read_sync(reader, read_buf, 1000, 1, FALSE); 3007 test_peek_pipe(reader, 0, 0, 0); 3008 } 3009 3010 if(msg_mode) 3011 { 3012 /* we still have an empty message in queue */ 3013 overlapped_read_sync(reader, read_buf, 1000, 0, FALSE); 3014 test_peek_pipe(reader, 0, 0, 0); 3015 } 3016 test_flush_done(flush_thread); 3017 3018 /* pipe is empty, the next read will block */ 3019 overlapped_read_async(reader, read_buf, 0, &read_overlapped); 3020 overlapped_read_async(reader, read_buf, 1000, &read_overlapped2); 3021 3022 /* write one byte */ 3023 overlapped_write_sync(writer, buf, 1); 3024 test_overlapped_result(reader, &read_overlapped, 0, msg_read); 3025 test_overlapped_result(reader, &read_overlapped2, 1, FALSE); 3026 test_peek_pipe(reader, 0, 0, 0); 3027 3028 /* write a message larger than buffer */ 3029 overlapped_write_async(writer, buf, buf_size+2000, &write_overlapped); 3030 test_peek_pipe(reader, buf_size + 2000, buf_size + 2000, msg_mode ? buf_size + 2000 : 0); 3031 3032 /* read so that pending write is still larger than the buffer */ 3033 overlapped_read_sync(reader, read_buf, 1999, 1999, msg_read); 3034 test_not_signaled(write_overlapped.hEvent); 3035 test_peek_pipe(reader, buf_size + 1, buf_size + 1, msg_mode ? buf_size + 1 : 0); 3036 3037 /* read one more byte */ 3038 overlapped_read_sync(reader, read_buf, 1, 1, msg_read); 3039 test_overlapped_result(writer, &write_overlapped, buf_size+2000, FALSE); 3040 test_peek_pipe(reader, buf_size, buf_size, msg_mode ? buf_size : 0); 3041 3042 /* read remaining data */ 3043 overlapped_read_sync(reader, read_buf, buf_size+1, buf_size, FALSE); 3044 test_peek_pipe(reader, 0, 0, 0); 3045 3046 /* simple pass of empty message */ 3047 overlapped_write_sync(writer, buf, 0); 3048 test_peek_pipe(reader, 0, 0, 0); 3049 if(msg_mode) 3050 overlapped_read_sync(reader, read_buf, 1, 0, FALSE); 3051 3052 /* pipe is empty, the next read will block */ 3053 test_flush_sync(writer); 3054 overlapped_read_async(reader, read_buf, 0, &read_overlapped); 3055 overlapped_read_async(reader, read_buf, 1, &read_overlapped2); 3056 3057 /* 0 length write wakes one read in msg mode */ 3058 overlapped_write_sync(writer, buf, 0); 3059 if(msg_mode) 3060 test_overlapped_result(reader, &read_overlapped, 0, FALSE); 3061 else 3062 test_not_signaled(read_overlapped.hEvent); 3063 test_not_signaled(read_overlapped2.hEvent); 3064 overlapped_write_sync(writer, buf, 1); 3065 test_overlapped_result(reader, &read_overlapped2, 1, FALSE); 3066 3067 overlapped_write_sync(writer, buf, 20); 3068 test_peek_pipe(reader, 20, 20, msg_mode ? 20 : 0); 3069 overlapped_write_sync(writer, buf, 15); 3070 test_peek_pipe(reader, msg_mode ? 20 : 35, 35, msg_mode ? 20 : 0); 3071 overlapped_read_sync(reader, read_buf, 10, 10, msg_read); 3072 test_peek_pipe(reader, msg_mode ? 10 : 25, 25, msg_mode ? 10 : 0); 3073 overlapped_read_sync(reader, read_buf, 10, 10, FALSE); 3074 test_peek_pipe(reader, 15, 15, msg_mode ? 15 : 0); 3075 overlapped_read_sync(reader, read_buf, 15, 15, FALSE); 3076 3077 if(!pCancelIoEx) { 3078 win_skip("CancelIoEx not available\n"); 3079 return; 3080 } 3081 3082 /* add one more pending read, then cancel the first one */ 3083 overlapped_read_async(reader, read_buf, 1, &read_overlapped); 3084 overlapped_read_async(reader, read_buf, 1, &read_overlapped2); 3085 cancel_overlapped(reader, &read_overlapped2); 3086 test_not_signaled(read_overlapped.hEvent); 3087 overlapped_write_sync(writer, buf, 1); 3088 test_overlapped_result(reader, &read_overlapped, 1, FALSE); 3089 3090 /* Test that canceling the same operation twice gives a sensible error */ 3091 SetLastError(0xdeadbeef); 3092 overlapped_read_async(reader, read_buf, 1, &read_overlapped2); 3093 res = pCancelIoEx(reader, &read_overlapped2); 3094 ok(res, "CancelIoEx failed with error %ld\n", GetLastError()); 3095 res = pCancelIoEx(reader, &read_overlapped2); 3096 ok(!res, "CancelIOEx succeeded unexpectedly\n"); 3097 ok(GetLastError() == ERROR_NOT_FOUND, 3098 "In CancelIoEx failure, expected ERROR_NOT_FOUND, got %ld\n", GetLastError()); 3099 test_overlapped_failure(reader, &read_overlapped2, ERROR_OPERATION_ABORTED); 3100 3101 /* make two async writes, cancel the first one and make sure that we read from the second one */ 3102 overlapped_write_async(writer, buf, buf_size+2000, &write_overlapped); 3103 overlapped_write_async(writer, buf, 1, &write_overlapped2); 3104 test_peek_pipe(reader, buf_size + 2000 + (msg_mode ? 0 : 1), 3105 buf_size + 2001, msg_mode ? buf_size + 2000 : 0); 3106 cancel_overlapped(writer, &write_overlapped); 3107 test_peek_pipe(reader, 1, 1, msg_mode ? 1 : 0); 3108 overlapped_read_sync(reader, read_buf, 1000, 1, FALSE); 3109 test_overlapped_result(writer, &write_overlapped2, 1, FALSE); 3110 test_peek_pipe(reader, 0, 0, 0); 3111 3112 /* same as above, but partially read written data before canceling */ 3113 overlapped_write_async(writer, buf, buf_size+2000, &write_overlapped); 3114 overlapped_write_async(writer, buf, 1, &write_overlapped2); 3115 test_peek_pipe(reader, buf_size + 2000 + (msg_mode ? 0 : 1), 3116 buf_size + 2001, msg_mode ? buf_size + 2000 : 0); 3117 overlapped_read_sync(reader, read_buf, 10, 10, msg_read); 3118 test_not_signaled(write_overlapped.hEvent); 3119 cancel_overlapped(writer, &write_overlapped); 3120 test_peek_pipe(reader, 1, 1, msg_mode ? 1 : 0); 3121 overlapped_read_sync(reader, read_buf, 1000, 1, FALSE); 3122 test_overlapped_result(writer, &write_overlapped2, 1, FALSE); 3123 test_peek_pipe(reader, 0, 0, 0); 3124 3125 /* empty queue by canceling write and make sure that flush is signaled */ 3126 overlapped_write_async(writer, buf, buf_size+2000, &write_overlapped); 3127 flush_thread = test_flush_async(writer, ERROR_SUCCESS); 3128 test_not_signaled(flush_thread); 3129 cancel_overlapped(writer, &write_overlapped); 3130 test_peek_pipe(reader, 0, 0, 0); 3131 test_flush_done(flush_thread); 3132} 3133 3134#define overlapped_transact(a,b,c,d,e,f) _overlapped_transact(__LINE__,a,b,c,d,e,f) 3135static void _overlapped_transact(unsigned line, HANDLE caller, void *write_buf, DWORD write_size, 3136 void *read_buf, DWORD read_size, OVERLAPPED *overlapped) 3137{ 3138 BOOL res; 3139 3140 memset(overlapped, 0, sizeof(*overlapped)); 3141 overlapped->hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 3142 res = TransactNamedPipe(caller, write_buf, write_size, read_buf, read_size, NULL, overlapped); 3143 ok_(__FILE__,line)(!res && GetLastError() == ERROR_IO_PENDING, 3144 "TransactNamedPipe returned: %x(%lu)\n", res, GetLastError()); 3145} 3146 3147#define overlapped_transact_failure(a,b,c,d,e,f) _overlapped_transact_failure(__LINE__,a,b,c,d,e,f) 3148static void _overlapped_transact_failure(unsigned line, HANDLE caller, void *write_buf, DWORD write_size, 3149 void *read_buf, DWORD read_size, DWORD expected_error) 3150{ 3151 OVERLAPPED overlapped; 3152 BOOL res; 3153 3154 memset(&overlapped, 0, sizeof(overlapped)); 3155 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 3156 res = TransactNamedPipe(caller, write_buf, write_size, read_buf, read_size, NULL, &overlapped); 3157 ok_(__FILE__,line)(!res, "TransactNamedPipe succeeded\n"); 3158 3159 if (GetLastError() == ERROR_IO_PENDING) /* win8+ */ 3160 { 3161 _test_overlapped_failure(line, caller, &overlapped, expected_error); 3162 } 3163 else 3164 { 3165 ok_(__FILE__,line)(GetLastError() == expected_error, 3166 "TransactNamedPipe returned error %lu, expected %lu\n", 3167 GetLastError(), expected_error); 3168 CloseHandle(overlapped.hEvent); 3169 } 3170} 3171 3172static void child_process_write_pipe(HANDLE pipe) 3173{ 3174 OVERLAPPED overlapped; 3175 char buf[10000]; 3176 3177 memset(buf, 'x', sizeof(buf)); 3178 overlapped_write_async(pipe, buf, sizeof(buf), &overlapped); 3179 3180 /* sleep until parent process terminates this process */ 3181 Sleep(INFINITE); 3182} 3183 3184static HANDLE create_writepipe_process(HANDLE pipe) 3185{ 3186 STARTUPINFOA si = { sizeof(si) }; 3187 PROCESS_INFORMATION info; 3188 char **argv, buf[MAX_PATH]; 3189 BOOL res; 3190 3191 winetest_get_mainargs(&argv); 3192 sprintf(buf, "\"%s\" pipe writepipe %Ix", argv[0], (UINT_PTR)pipe); 3193 res = CreateProcessA(NULL, buf, NULL, NULL, TRUE, 0L, NULL, NULL, &si, &info); 3194 ok(res, "CreateProcess failed: %lu\n", GetLastError()); 3195 CloseHandle(info.hThread); 3196 3197 return info.hProcess; 3198} 3199 3200static void create_overlapped_pipe(DWORD mode, HANDLE *client, HANDLE *server) 3201{ 3202 SECURITY_ATTRIBUTES sec_attr = { sizeof(sec_attr), NULL, TRUE }; 3203 DWORD read_mode = mode & (PIPE_READMODE_BYTE | PIPE_READMODE_MESSAGE); 3204 OVERLAPPED overlapped; 3205 BOOL res; 3206 3207 *server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, 3208 PIPE_WAIT | mode, 1, 5000, 6000, NMPWAIT_USE_DEFAULT_WAIT, NULL); 3209 ok(*server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %lu\n", GetLastError()); 3210 test_signaled(*server); 3211 3212 memset(&overlapped, 0, sizeof(overlapped)); 3213 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 3214 res = ConnectNamedPipe(*server, &overlapped); 3215 ok(!res && GetLastError() == ERROR_IO_PENDING, "WriteFile returned %x(%lu)\n", res, GetLastError()); 3216 test_not_signaled(*server); 3217 test_not_signaled(overlapped.hEvent); 3218 3219 *client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, &sec_attr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); 3220 ok(*client != INVALID_HANDLE_VALUE, "CreateFile failed: %lu\n", GetLastError()); 3221 3222 res = SetNamedPipeHandleState(*client, &read_mode, NULL, NULL); 3223 ok(res, "SetNamedPipeHandleState failed: %lu\n", GetLastError()); 3224 3225 test_signaled(*client); 3226 test_not_signaled(*server); 3227 test_overlapped_result(*server, &overlapped, 0, FALSE); 3228} 3229 3230static void test_overlapped_transport(BOOL msg_mode, BOOL msg_read_mode) 3231{ 3232 OVERLAPPED overlapped, overlapped2; 3233 HANDLE server, client, flush; 3234 DWORD read_bytes; 3235 HANDLE process; 3236 char buf[60000]; 3237 BOOL res; 3238 3239 DWORD create_flags = 3240 (msg_mode ? PIPE_TYPE_MESSAGE : PIPE_TYPE_BYTE) | 3241 (msg_read_mode ? PIPE_READMODE_MESSAGE : PIPE_READMODE_BYTE); 3242 3243 create_overlapped_pipe(create_flags, &client, &server); 3244 3245 trace("testing %s, %s server->client writes...\n", 3246 msg_mode ? "message mode" : "byte mode", msg_read_mode ? "message read" : "byte read"); 3247 test_blocking_rw(server, client, 5000, msg_mode, msg_read_mode); 3248 trace("testing %s, %s client->server writes...\n", 3249 msg_mode ? "message mode" : "byte mode", msg_read_mode ? "message read" : "byte read"); 3250 test_blocking_rw(client, server, 6000, msg_mode, msg_read_mode); 3251 3252 CloseHandle(client); 3253 CloseHandle(server); 3254 3255 /* close client with pending writes */ 3256 memset(buf, 0xaa, sizeof(buf)); 3257 create_overlapped_pipe(create_flags, &client, &server); 3258 overlapped_write_async(server, buf, 7000, &overlapped); 3259 flush = test_flush_async(server, ERROR_BROKEN_PIPE); 3260 CloseHandle(client); 3261 test_overlapped_failure(server, &overlapped, ERROR_BROKEN_PIPE); 3262 test_flush_done(flush); 3263 CloseHandle(server); 3264 3265 /* close server with pending writes */ 3266 create_overlapped_pipe(create_flags, &client, &server); 3267 overlapped_write_async(client, buf, 7000, &overlapped); 3268 flush = test_flush_async(client, ERROR_BROKEN_PIPE); 3269 CloseHandle(server); 3270 test_overlapped_failure(client, &overlapped, ERROR_BROKEN_PIPE); 3271 test_flush_done(flush); 3272 CloseHandle(client); 3273 3274 /* disconnect with pending writes */ 3275 create_overlapped_pipe(create_flags, &client, &server); 3276 overlapped_write_async(client, buf, 7000, &overlapped); 3277 overlapped_write_async(server, buf, 7000, &overlapped2); 3278 flush = test_flush_async(client, ERROR_PIPE_NOT_CONNECTED); 3279 res = DisconnectNamedPipe(server); 3280 ok(res, "DisconnectNamedPipe failed: %lu\n", GetLastError()); 3281 test_overlapped_failure(client, &overlapped, ERROR_PIPE_NOT_CONNECTED); 3282 test_overlapped_failure(client, &overlapped2, ERROR_PIPE_NOT_CONNECTED); 3283 test_flush_done(flush); 3284 CloseHandle(server); 3285 CloseHandle(client); 3286 3287 /* terminate process with pending write */ 3288 create_overlapped_pipe(create_flags, &client, &server); 3289 process = create_writepipe_process(client); 3290 /* successfully read part of write that is pending in child process */ 3291 res = ReadFile(server, buf, 10, &read_bytes, NULL); 3292 if(!msg_read_mode) 3293 ok(res, "ReadFile failed: %lu\n", GetLastError()); 3294 else 3295 ok(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned: %x %lu\n", res, GetLastError()); 3296 ok(read_bytes == 10, "read_bytes = %lu\n", read_bytes); 3297 TerminateProcess(process, 0); 3298 wait_child_process(process); 3299 /* after terminating process, there is no pending write and pipe buffer is empty */ 3300 overlapped_read_async(server, buf, 10, &overlapped); 3301 overlapped_write_sync(client, buf, 1); 3302 test_overlapped_result(server, &overlapped, 1, FALSE); 3303 CloseHandle(process); 3304 CloseHandle(server); 3305 CloseHandle(client); 3306} 3307 3308static void test_transact(HANDLE caller, HANDLE callee, DWORD write_buf_size, DWORD read_buf_size) 3309{ 3310 OVERLAPPED overlapped, overlapped2, read_overlapped, write_overlapped; 3311 char buf[10000], read_buf[10000]; 3312 3313 memset(buf, 0xaa, sizeof(buf)); 3314 3315 /* simple transact call */ 3316 overlapped_transact(caller, (BYTE*)"abc", 3, read_buf, 100, &overlapped); 3317 overlapped_write_sync(callee, (BYTE*)"test", 4); 3318 test_overlapped_result(caller, &overlapped, 4, FALSE); 3319 ok(!memcmp(read_buf, "test", 4), "unexpected read_buf\n"); 3320 overlapped_read_sync(callee, read_buf, 1000, 3, FALSE); 3321 ok(!memcmp(read_buf, "abc", 3), "unexpected read_buf\n"); 3322 3323 /* transact fails if there is already data in read buffer */ 3324 overlapped_write_sync(callee, buf, 1); 3325 overlapped_transact_failure(caller, buf, 2, read_buf, 1, ERROR_PIPE_BUSY); 3326 overlapped_read_sync(caller, read_buf, 1000, 1, FALSE); 3327 3328 /* transact doesn't block on write */ 3329 overlapped_write_async(caller, buf, write_buf_size+2000, &write_overlapped); 3330 overlapped_transact(caller, buf, 2, read_buf, 1, &overlapped); 3331 test_not_signaled(overlapped.hEvent); 3332 overlapped_write_sync(callee, buf, 1); 3333 test_overlapped_result(caller, &overlapped, 1, FALSE); 3334 overlapped_read_sync(callee, read_buf, sizeof(read_buf), write_buf_size+2000, FALSE); 3335 test_overlapped_result(caller, &write_overlapped, write_buf_size+2000, FALSE); 3336 overlapped_read_sync(callee, read_buf, sizeof(read_buf), 2, FALSE); 3337 3338 /* transact with already pending read */ 3339 overlapped_read_async(callee, read_buf, 10, &read_overlapped); 3340 overlapped_transact(caller, buf, 5, read_buf, 6, &overlapped); 3341 test_overlapped_result(callee, &read_overlapped, 5, FALSE); 3342 test_not_signaled(overlapped.hEvent); 3343 overlapped_write_sync(callee, buf, 10); 3344 test_overlapped_result(caller, &overlapped, 6, TRUE); 3345 overlapped_read_sync(caller, read_buf, sizeof(read_buf), 4, FALSE); 3346 3347 /* 0-size messages */ 3348 overlapped_transact(caller, buf, 5, read_buf, 0, &overlapped); 3349 overlapped_read_sync(callee, read_buf, sizeof(read_buf), 5, FALSE); 3350 overlapped_write_sync(callee, buf, 0); 3351 test_overlapped_result(caller, &overlapped, 0, FALSE); 3352 3353 overlapped_transact(caller, buf, 0, read_buf, 0, &overlapped); 3354 overlapped_read_sync(callee, read_buf, sizeof(read_buf), 0, FALSE); 3355 test_not_signaled(overlapped.hEvent); 3356 overlapped_write_sync(callee, buf, 0); 3357 test_overlapped_result(caller, &overlapped, 0, FALSE); 3358 3359 /* reply transact with another transact */ 3360 overlapped_transact(caller, buf, 3, read_buf, 100, &overlapped); 3361 overlapped_read_sync(callee, read_buf, 1000, 3, FALSE); 3362 overlapped_transact(callee, buf, 4, read_buf, 100, &overlapped2); 3363 test_overlapped_result(caller, &overlapped, 4, FALSE); 3364 overlapped_write_sync(caller, buf, 1); 3365 test_overlapped_result(caller, &overlapped2, 1, FALSE); 3366 3367 if (!pCancelIoEx) return; 3368 3369 /* cancel keeps written data */ 3370 overlapped_write_async(caller, buf, write_buf_size+2000, &write_overlapped); 3371 overlapped_transact(caller, buf, 2, read_buf, 1, &overlapped); 3372 test_not_signaled(overlapped.hEvent); 3373 cancel_overlapped(caller, &overlapped); 3374 overlapped_read_sync(callee, read_buf, sizeof(read_buf), write_buf_size+2000, FALSE); 3375 test_overlapped_result(caller, &write_overlapped, write_buf_size+2000, FALSE); 3376 overlapped_read_sync(callee, read_buf, sizeof(read_buf), 2, FALSE); 3377} 3378 3379static void test_TransactNamedPipe(void) 3380{ 3381 HANDLE client, server; 3382 BYTE buf[10]; 3383 3384 create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server); 3385 overlapped_transact_failure(client, buf, 2, buf, 1, ERROR_BAD_PIPE); 3386 CloseHandle(client); 3387 CloseHandle(server); 3388 3389 create_overlapped_pipe(PIPE_TYPE_MESSAGE | PIPE_READMODE_BYTE, &client, &server); 3390 overlapped_transact_failure(client, buf, 2, buf, 1, ERROR_BAD_PIPE); 3391 CloseHandle(client); 3392 CloseHandle(server); 3393 3394 trace("testing server->client transaction...\n"); 3395 create_overlapped_pipe(PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, &client, &server); 3396 test_transact(server, client, 5000, 6000); 3397 CloseHandle(client); 3398 CloseHandle(server); 3399 3400 trace("testing client->server transaction...\n"); 3401 create_overlapped_pipe(PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, &client, &server); 3402 test_transact(client, server, 6000, 5000); 3403 CloseHandle(client); 3404 CloseHandle(server); 3405} 3406 3407static HANDLE create_overlapped_server( OVERLAPPED *overlapped ) 3408{ 3409 HANDLE pipe; 3410 BOOL ret; 3411 3412 pipe = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, PIPE_READMODE_BYTE | PIPE_WAIT, 3413 1, 5000, 6000, NMPWAIT_USE_DEFAULT_WAIT, NULL); 3414 ok(pipe != INVALID_HANDLE_VALUE, "got %lu\n", GetLastError()); 3415 ret = ConnectNamedPipe(pipe, overlapped); 3416 ok(!ret && GetLastError() == ERROR_IO_PENDING, "got %lu\n", GetLastError()); 3417 return pipe; 3418} 3419 3420static void child_process_check_pid(DWORD server_pid) 3421{ 3422 DWORD current = GetProcessId(GetCurrentProcess()); 3423 HANDLE pipe; 3424 ULONG pid; 3425 BOOL ret; 3426 3427 pipe = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); 3428 ok(pipe != INVALID_HANDLE_VALUE, "got %lu\n", GetLastError()); 3429 3430 pid = 0; 3431 ret = pGetNamedPipeClientProcessId(pipe, &pid); 3432 ok(ret, "got %lu\n", GetLastError()); 3433 ok(pid == current, "got %04lx\n", pid); 3434 3435 pid = 0; 3436 ret = pGetNamedPipeServerProcessId(pipe, &pid); 3437 ok(ret, "got %lu\n", GetLastError()); 3438 ok(pid == server_pid, "got %04lx expected %04lx\n", pid, server_pid); 3439 CloseHandle(pipe); 3440} 3441 3442static HANDLE create_check_id_process(const char *verb, DWORD id) 3443{ 3444 STARTUPINFOA si = {sizeof(si)}; 3445 PROCESS_INFORMATION info; 3446 char **argv, buf[MAX_PATH]; 3447 BOOL ret; 3448 3449 winetest_get_mainargs(&argv); 3450 sprintf(buf, "\"%s\" pipe %s %lx", argv[0], verb, id); 3451 ret = CreateProcessA(NULL, buf, NULL, NULL, TRUE, 0, NULL, NULL, &si, &info); 3452 ok(ret, "got %lu\n", GetLastError()); 3453 CloseHandle(info.hThread); 3454 return info.hProcess; 3455} 3456 3457static void test_namedpipe_process_id(void) 3458{ 3459 HANDLE client, server, process; 3460 DWORD current = GetProcessId(GetCurrentProcess()); 3461 OVERLAPPED overlapped; 3462 ULONG pid; 3463 BOOL ret; 3464 3465#if defined(__REACTOS__) && DLL_EXPORT_VERSION >= 0x600 3466 /* FIXME: GetNamedPipeClientProcessId is a STUB on ReactOS. */ 3467 if (is_reactos() || !pGetNamedPipeClientProcessId) 3468#else 3469 if (!pGetNamedPipeClientProcessId) 3470#endif 3471 { 3472 win_skip("GetNamedPipeClientProcessId not available\n"); 3473 return; 3474 } 3475 3476 create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server); 3477 3478 SetLastError(0xdeadbeef); 3479 ret = pGetNamedPipeClientProcessId(server, NULL); 3480 ok(!ret, "success\n"); 3481 todo_wine ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", GetLastError()); 3482 3483 pid = 0; 3484 ret = pGetNamedPipeClientProcessId(server, &pid); 3485 ok(ret, "got %lu\n", GetLastError()); 3486 ok(pid == current, "got %04lx expected %04lx\n", pid, current); 3487 3488 pid = 0; 3489 ret = pGetNamedPipeClientProcessId(client, &pid); 3490 ok(ret, "got %lu\n", GetLastError()); 3491 ok(pid == current, "got %04lx expected %04lx\n", pid, current); 3492 3493 SetLastError(0xdeadbeef); 3494 ret = pGetNamedPipeServerProcessId(server, NULL); 3495 ok(!ret, "success\n"); 3496 todo_wine ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", GetLastError()); 3497 3498 pid = 0; 3499 ret = pGetNamedPipeServerProcessId(client, &pid); 3500 ok(ret, "got %lu\n", GetLastError()); 3501 ok(pid == current, "got %04lx expected %04lx\n", pid, current); 3502 3503 pid = 0; 3504 ret = pGetNamedPipeServerProcessId(server, &pid); 3505 ok(ret, "got %lu\n", GetLastError()); 3506 ok(pid == current, "got %04lx expected %04lx\n", pid, current); 3507 3508 /* closed client handle */ 3509 CloseHandle(client); 3510 pid = 0; 3511 ret = pGetNamedPipeClientProcessId(server, &pid); 3512 ok(ret, "got %lu\n", GetLastError()); 3513 ok(pid == current, "got %04lx expected %04lx\n", pid, current); 3514 3515 pid = 0; 3516 ret = pGetNamedPipeServerProcessId(server, &pid); 3517 ok(ret, "got %lu\n", GetLastError()); 3518 ok(pid == current, "got %04lx expected %04lx\n", pid, current); 3519 CloseHandle(server); 3520 3521 /* disconnected server */ 3522 create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server); 3523 DisconnectNamedPipe(server); 3524 3525 SetLastError(0xdeadbeef); 3526 ret = pGetNamedPipeClientProcessId(server, &pid); 3527 todo_wine ok(!ret, "success\n"); 3528 todo_wine ok(GetLastError() == ERROR_NOT_FOUND, "got %lu\n", GetLastError()); 3529 3530 pid = 0; 3531 ret = pGetNamedPipeServerProcessId(server, &pid); 3532 ok(ret, "got %lu\n", GetLastError()); 3533 ok(pid == current, "got %04lx expected %04lx\n", pid, current); 3534 3535 SetLastError(0xdeadbeef); 3536 ret = pGetNamedPipeClientProcessId(client, &pid); 3537 todo_wine ok(!ret, "success\n"); 3538 todo_wine ok(GetLastError() == ERROR_PIPE_NOT_CONNECTED, "got %lu\n", GetLastError()); 3539 3540 SetLastError(0xdeadbeef); 3541 ret = pGetNamedPipeServerProcessId(client, &pid); 3542 todo_wine ok(!ret, "success\n"); 3543 todo_wine ok(GetLastError() == ERROR_PIPE_NOT_CONNECTED, "got %lu\n", GetLastError()); 3544 CloseHandle(client); 3545 CloseHandle(server); 3546 3547 /* closed server handle */ 3548 create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server); 3549 CloseHandle(server); 3550 3551 pid = 0; 3552 ret = pGetNamedPipeClientProcessId(client, &pid); 3553 ok(ret, "got %lu\n", GetLastError()); 3554 ok(pid == current, "got %04lx expected %04lx\n", pid, current); 3555 3556 pid = 0; 3557 ret = pGetNamedPipeServerProcessId(client, &pid); 3558 ok(ret, "got %lu\n", GetLastError()); 3559 ok(pid == current, "got %04lx expected %04lx\n", pid, current); 3560 CloseHandle(client); 3561 3562 /* different process */ 3563 memset(&overlapped, 0, sizeof(overlapped)); 3564 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 3565 server = create_overlapped_server( &overlapped ); 3566 ok(server != INVALID_HANDLE_VALUE, "got %lu\n", GetLastError()); 3567 3568 process = create_check_id_process("checkpid", GetProcessId(GetCurrentProcess())); 3569 wait_child_process(process); 3570 3571 CloseHandle(overlapped.hEvent); 3572 CloseHandle(process); 3573 CloseHandle(server); 3574} 3575 3576static void child_process_check_session_id(DWORD server_id) 3577{ 3578 DWORD current; 3579 HANDLE pipe; 3580 ULONG id; 3581 BOOL ret; 3582 3583 ProcessIdToSessionId(GetProcessId(GetCurrentProcess()), &current); 3584 3585 pipe = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); 3586 ok(pipe != INVALID_HANDLE_VALUE, "got %lu\n", GetLastError()); 3587 3588 id = 0; 3589 ret = pGetNamedPipeClientSessionId(pipe, &id); 3590 ok(ret, "got %lu\n", GetLastError()); 3591 ok(id == current, "got %04lx\n", id); 3592 3593 id = 0; 3594 ret = pGetNamedPipeServerSessionId(pipe, &id); 3595 ok(ret, "got %lu\n", GetLastError()); 3596 ok(id == server_id, "got %04lx expected %04lx\n", id, server_id); 3597 CloseHandle(pipe); 3598} 3599 3600static void test_namedpipe_session_id(void) 3601{ 3602 HANDLE client, server, process; 3603 OVERLAPPED overlapped; 3604 DWORD current; 3605 ULONG id; 3606 BOOL ret; 3607 3608#if defined(__REACTOS__) && DLL_EXPORT_VERSION >= 0x600 3609 /* FIXME: GetNamedPipeClientSessionId is a STUB on ReactOS. */ 3610 if (is_reactos() || !pGetNamedPipeClientSessionId) 3611#else 3612 if (!pGetNamedPipeClientSessionId) 3613#endif 3614 { 3615 win_skip("GetNamedPipeClientSessionId not available\n"); 3616 return; 3617 } 3618 3619 ProcessIdToSessionId(GetProcessId(GetCurrentProcess()), &current); 3620 3621 create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server); 3622 3623 if (0) /* crashes on recent Windows */ 3624 { 3625 SetLastError(0xdeadbeef); 3626 ret = pGetNamedPipeClientSessionId(server, NULL); 3627 ok(!ret, "success\n"); 3628 } 3629 3630 id = 0; 3631 ret = pGetNamedPipeClientSessionId(server, &id); 3632 ok(ret, "got %lu\n", GetLastError()); 3633 ok(id == current, "got %lu expected %lu\n", id, current); 3634 3635 id = 0; 3636 ret = pGetNamedPipeClientSessionId(client, &id); 3637 ok(ret, "got %lu\n", GetLastError()); 3638 ok(id == current, "got %lu expected %lu\n", id, current); 3639 3640 SetLastError(0xdeadbeef); 3641 ret = pGetNamedPipeServerSessionId(server, NULL); 3642 ok(!ret, "success\n"); 3643 todo_wine ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", GetLastError()); 3644 3645 id = 0; 3646 ret = pGetNamedPipeServerSessionId(client, &id); 3647 ok(ret, "got %lu\n", GetLastError()); 3648 ok(id == current, "got %lu expected %lu\n", id, current); 3649 3650 id = 0; 3651 ret = pGetNamedPipeServerSessionId(server, &id); 3652 ok(ret, "got %lu\n", GetLastError()); 3653 ok(id == current, "got %lu expected %lu\n", id, current); 3654 3655 /* closed client handle */ 3656 CloseHandle(client); 3657 3658 id = 0; 3659 ret = pGetNamedPipeClientSessionId(server, &id); 3660 ok(ret, "got %lu\n", GetLastError()); 3661 ok(id == current, "got %04lx expected %04lx\n", id, current); 3662 3663 id = 0; 3664 ret = pGetNamedPipeServerSessionId(server, &id); 3665 ok(ret, "got %lu\n", GetLastError()); 3666 ok(id == current, "got %04lx expected %04lx\n", id, current); 3667 CloseHandle(server); 3668 3669 /* disconnected server */ 3670 create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server); 3671 DisconnectNamedPipe(server); 3672 3673 SetLastError(0xdeadbeef); 3674 ret = pGetNamedPipeClientSessionId(server, &id); 3675 todo_wine ok(!ret, "success\n"); 3676 todo_wine ok(GetLastError() == ERROR_NOT_FOUND, "got %lu\n", GetLastError()); 3677 3678 id = 0; 3679 ret = pGetNamedPipeServerSessionId(server, &id); 3680 ok(ret, "got %lu\n", GetLastError()); 3681 ok(id == current, "got %04lx expected %04lx\n", id, current); 3682 3683 SetLastError(0xdeadbeef); 3684 ret = pGetNamedPipeClientSessionId(client, &id); 3685 todo_wine ok(!ret, "success\n"); 3686 todo_wine ok(GetLastError() == ERROR_PIPE_NOT_CONNECTED, "got %lu\n", GetLastError()); 3687 3688 SetLastError(0xdeadbeef); 3689 ret = pGetNamedPipeServerSessionId(client, &id); 3690 todo_wine ok(!ret, "success\n"); 3691 todo_wine ok(GetLastError() == ERROR_PIPE_NOT_CONNECTED, "got %lu\n", GetLastError()); 3692 CloseHandle(client); 3693 CloseHandle(server); 3694 3695 /* closed server handle */ 3696 create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server); 3697 CloseHandle(server); 3698 3699 id = 0; 3700 ret = pGetNamedPipeClientSessionId(client, &id); 3701 ok(ret, "got %lu\n", GetLastError()); 3702 ok(id == current, "got %04lx expected %04lx\n", id, current); 3703 3704 id = 0; 3705 ret = pGetNamedPipeServerSessionId(client, &id); 3706 ok(ret, "got %lu\n", GetLastError()); 3707 ok(id == current, "got %04lx expected %04lx\n", id, current); 3708 CloseHandle(client); 3709 3710 /* different process */ 3711 memset(&overlapped, 0, sizeof(overlapped)); 3712 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 3713 server = create_overlapped_server( &overlapped ); 3714 ok(server != INVALID_HANDLE_VALUE, "got %lu\n", GetLastError()); 3715 3716 process = create_check_id_process("checksessionid", current); 3717 wait_child_process(process); 3718 3719 CloseHandle(overlapped.hEvent); 3720 CloseHandle(process); 3721 CloseHandle(server); 3722} 3723 3724static void test_multiple_instances(void) 3725{ 3726 HANDLE server[4], client; 3727 int i; 3728 BOOL ret; 3729 OVERLAPPED ov; 3730 3731 if(!pCancelIoEx) 3732 { 3733 win_skip("Skipping multiple instance tests on too old Windows\n"); 3734 return; 3735 } 3736 3737 for (i = 0; i < ARRAY_SIZE(server); i++) 3738 { 3739 server[i] = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 3740 PIPE_READMODE_BYTE | PIPE_WAIT, ARRAY_SIZE(server), 1024, 1024, 3741 NMPWAIT_USE_DEFAULT_WAIT, NULL); 3742 ok(server[i] != INVALID_HANDLE_VALUE, "got invalid handle\n"); 3743 } 3744 3745 client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 3746 ok(client != INVALID_HANDLE_VALUE, "got invalid handle\n"); 3747 3748 /* Show that this has connected to server[0] not any other one */ 3749 3750 memset(&ov, 0, sizeof(ov)); 3751 ret = ConnectNamedPipe(server[2], &ov); 3752 ok(ret == FALSE, "got %d\n", ret); 3753 ok(GetLastError() == ERROR_IO_PENDING, "got %ld\n", GetLastError()); 3754 3755 memset(&ov, 0, sizeof(ov)); 3756 ret = ConnectNamedPipe(server[0], &ov); 3757 ok(ret == FALSE, "got %d\n", ret); 3758 ok(GetLastError() == ERROR_PIPE_CONNECTED, "got %ld\n", GetLastError()); 3759 3760 CloseHandle(client); 3761 3762 /* The next connected server is server[1], doesn't matter that server[2] has pending listeners */ 3763 3764 client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 3765 ok(client != INVALID_HANDLE_VALUE, "got invalid handle\n"); 3766 3767 memset(&ov, 0, sizeof(ov)); 3768 ret = ConnectNamedPipe(server[2], &ov); 3769 ok(ret == FALSE, "got %d\n", ret); 3770 ok(GetLastError() == ERROR_IO_PENDING, "got %ld\n", GetLastError()); 3771 3772 memset(&ov, 0, sizeof(ov)); 3773 ret = ConnectNamedPipe(server[1], &ov); 3774 ok(ret == FALSE, "got %d\n", ret); 3775 ok(GetLastError() == ERROR_PIPE_CONNECTED, "got %ld\n", GetLastError()); 3776 3777 CloseHandle(client); 3778 3779 /* server[2] is connected next */ 3780 3781 client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 3782 ok(client != INVALID_HANDLE_VALUE, "got invalid handle\n"); 3783 3784 memset(&ov, 0, sizeof(ov)); 3785 ret = ConnectNamedPipe(server[2], &ov); 3786 ok(ret == FALSE, "got %d\n", ret); 3787 ok(GetLastError() == ERROR_PIPE_CONNECTED, "got %ld\n", GetLastError()); 3788 3789 CloseHandle(client); 3790 3791 /* Disconnect in order server[0] and server[2] */ 3792 3793 DisconnectNamedPipe(server[0]); 3794 DisconnectNamedPipe(server[2]); 3795 3796 /* Put into listening state server[2] and server[0] */ 3797 3798 memset(&ov, 0, sizeof(ov)); 3799 ret = ConnectNamedPipe(server[2], &ov); 3800 ok(ret == FALSE, "got %d\n", ret); 3801 ok(GetLastError() == ERROR_IO_PENDING, "got %ld\n", GetLastError()); 3802 3803 memset(&ov, 0, sizeof(ov)); 3804 ret = ConnectNamedPipe(server[0], &ov); 3805 ok(ret == FALSE, "got %d\n", ret); 3806 ok(GetLastError() == ERROR_IO_PENDING, "got %ld\n", GetLastError()); 3807 3808 /* server[3] is connected next */ 3809 3810 client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 3811 ok(client != INVALID_HANDLE_VALUE, "got invalid handle\n"); 3812 3813 memset(&ov, 0, sizeof(ov)); 3814 ret = ConnectNamedPipe(server[3], &ov); 3815 ok(ret == FALSE, "got %d\n", ret); 3816 ok(GetLastError() == ERROR_PIPE_CONNECTED, "got %ld\n", GetLastError()); 3817 3818 CloseHandle(client); 3819 3820 /* server[2], which stasted listening first, will be connected next */ 3821 3822 client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 3823 ok(client != INVALID_HANDLE_VALUE, "got invalid handle\n"); 3824 3825 memset(&ov, 0, sizeof(ov)); 3826 ret = ConnectNamedPipe(server[2], &ov); 3827 ok(ret == FALSE, "got %d\n", ret); 3828 ok(GetLastError() == ERROR_PIPE_CONNECTED, "got %ld\n", GetLastError()); 3829 3830 memset(&ov, 0, sizeof(ov)); 3831 ret = ConnectNamedPipe(server[0], &ov); 3832 ok(ret == FALSE, "got %d\n", ret); 3833 ok(GetLastError() == ERROR_IO_PENDING, "got %ld\n", GetLastError()); 3834 3835 CloseHandle(client); 3836 3837 /* Finally server[0] is connected */ 3838 3839 client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 3840 ok(client != INVALID_HANDLE_VALUE, "got invalid handle\n"); 3841 3842 memset(&ov, 0, sizeof(ov)); 3843 ret = ConnectNamedPipe(server[0], &ov); 3844 ok(ret == FALSE, "got %d\n", ret); 3845 ok(GetLastError() == ERROR_PIPE_CONNECTED, "got %ld\n", GetLastError()); 3846 3847 CloseHandle(client); 3848 3849 /* No more listening pipes available */ 3850 DisconnectNamedPipe(server[0]); 3851 client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 3852 ok(client == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY, "got %p(%lu)\n", client, GetLastError()); 3853 3854 for (i = 0; i < ARRAY_SIZE(server); i++) 3855 { 3856 DisconnectNamedPipe(server[i]); 3857 CloseHandle(server[i]); 3858 } 3859} 3860 3861static DWORD WINAPI wait_pipe_proc(void *arg) 3862{ 3863 BOOL ret; 3864 ret = WaitNamedPipeA(PIPENAME, 1000); 3865 ok(ret, "WaitNamedPipe failed (%lu)\n", GetLastError()); 3866 return 0; 3867} 3868 3869static HANDLE async_wait_pipe(void) 3870{ 3871 HANDLE thread; 3872 BOOL ret; 3873 3874 thread = CreateThread(NULL, 0, wait_pipe_proc, NULL, 0, NULL); 3875 ok(thread != NULL, "CreateThread failed: %lu\n", GetLastError()); 3876 3877 ret = WaitNamedPipeA(PIPENAME, 1); 3878 ok(!ret && GetLastError() == ERROR_SEM_TIMEOUT, "WaitNamedPipe failed %x(%lu)\n", ret, GetLastError()); 3879 3880 return thread; 3881} 3882 3883static void test_wait_pipe(void) 3884{ 3885 HANDLE server[2], client, wait; 3886 OVERLAPPED ov; 3887 DWORD res; 3888 BOOL ret; 3889 3890 ret = WaitNamedPipeA(PIPENAME, 0); 3891 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, "WaitNamedPipe failed %x(%lu)\n", ret, GetLastError()); 3892 3893 server[0] = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 3894 PIPE_READMODE_BYTE | PIPE_WAIT, ARRAY_SIZE(server), 1024, 1024, 3895 NMPWAIT_USE_DEFAULT_WAIT, NULL); 3896 ok(server[0] != INVALID_HANDLE_VALUE, "got invalid handle\n"); 3897 3898 ret = WaitNamedPipeA(PIPENAME, 1); 3899 ok(ret, "WaitNamedPipe failed (%lu)\n", GetLastError()); 3900 3901 client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 3902 ok(client != INVALID_HANDLE_VALUE, "got invalid handle\n"); 3903 3904 /* Creating a new pipe server wakes waiters */ 3905 wait = async_wait_pipe(); 3906 server[1] = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 3907 PIPE_READMODE_BYTE | PIPE_WAIT, ARRAY_SIZE(server), 1024, 1024, 3908 NMPWAIT_USE_DEFAULT_WAIT, NULL); 3909 ok(server[1] != INVALID_HANDLE_VALUE, "got invalid handle\n"); 3910 3911 res = WaitForSingleObject(wait, 100); 3912 ok(res == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", res); 3913 3914 CloseHandle(wait); 3915 CloseHandle(server[1]); 3916 3917 CloseHandle(client); 3918 ret = DisconnectNamedPipe(server[0]); 3919 ok(ret, "DisconnectNamedPipe failed (%lu)\n", GetLastError()); 3920 3921 /* Putting pipe server into waiting listening state wakes waiters */ 3922 wait = async_wait_pipe(); 3923 memset(&ov, 0, sizeof(ov)); 3924 ov.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 3925 ret = ConnectNamedPipe(server[0], &ov); 3926 ok(ret == FALSE, "got %d\n", ret); 3927 ok(GetLastError() == ERROR_IO_PENDING, "got %ld\n", GetLastError()); 3928 3929 res = WaitForSingleObject(wait, 100); 3930 ok(res == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", res); 3931 CloseHandle(server[0]); 3932 3933 res = WaitForSingleObject(ov.hEvent, 0); 3934 ok(res == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", res); 3935 CloseHandle(ov.hEvent); 3936} 3937 3938static void test_nowait(DWORD pipe_type) 3939{ 3940 HANDLE piperead, pipewrite, file; 3941 OVERLAPPED ol, ol2; 3942 DWORD read, write; 3943 char readbuf[32768]; 3944 static const char teststring[] = "bits"; 3945 3946 /* CreateNamedPipe with PIPE_NOWAIT, and read from empty pipe */ 3947 piperead = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, 3948 /* dwPipeMode */ pipe_type | PIPE_NOWAIT, 3949 /* nMaxInstances */ 1, 3950 /* nOutBufSize */ 512, 3951 /* nInBufSize */ 512, 3952 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 3953 /* lpSecurityAttrib */ NULL); 3954 ok(piperead != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 3955 pipewrite = CreateFileA(PIPENAME, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 3956 ok(pipewrite != INVALID_HANDLE_VALUE, "CreateFileA failed\n"); 3957 memset(&ol, 0, sizeof(ol)); 3958 ol.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 3959 SetLastError(0xdeadbeef); 3960 ok(ReadFile(piperead, readbuf, sizeof(readbuf), &read, &ol) == FALSE, "ReadFile should fail\n"); 3961 ok(GetLastError() == ERROR_NO_DATA, "got %ld should be ERROR_NO_DATA\n", GetLastError()); 3962 if (GetLastError() == ERROR_IO_PENDING) 3963 CancelIo(piperead); 3964 3965 /* test a small write/read */ 3966 ok(WriteFile(pipewrite, teststring, sizeof(teststring), &write, NULL), "WriteFile should succeed\n"); 3967 ok(ReadFile(piperead, readbuf, sizeof(readbuf), &read, &ol), "ReadFile should succeed\n"); 3968 ok(read == write, "read/write bytes should match\n"); 3969 ok(CloseHandle(ol.hEvent), "CloseHandle for the event failed\n"); 3970 ok(CloseHandle(pipewrite), "CloseHandle for the write pipe failed\n"); 3971 ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n"); 3972 3973 3974 /* create write side with PIPE_NOWAIT, read side PIPE_WAIT, and test writes */ 3975 pipewrite = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, 3976 /* dwPipeMode */ pipe_type | PIPE_NOWAIT, 3977 /* nMaxInstances */ 1, 3978 /* nOutBufSize */ 512, 3979 /* nInBufSize */ 512, 3980 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 3981 /* lpSecurityAttrib */ NULL); 3982 ok(pipewrite != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 3983 piperead = CreateFileA(PIPENAME, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); 3984 ok(piperead != INVALID_HANDLE_VALUE, "CreateFileA failed\n"); 3985 memset(&ol, 0, sizeof(ol)); 3986 ol.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 3987 memset(&ol2, 0, sizeof(ol2)); 3988 ol2.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 3989 3990 /* write one byte larger than the buffer size, should fail */ 3991 SetLastError(0xdeadbeef); 3992 ok(WriteFile(pipewrite, readbuf, 513, &write, &ol), "WriteFile should succeed\n"); 3993 /* WriteFile only documents that 'write < sizeof(readbuf)' for this case, but Windows 3994 * doesn't seem to do partial writes ('write == 0' always) 3995 */ 3996 ok(write < sizeof(readbuf), "WriteFile should fail to write the whole buffer\n"); 3997 ok(write == 0, "WriteFile doesn't do partial writes here\n"); 3998 if (GetLastError() == ERROR_IO_PENDING) 3999 CancelIo(piperead); 4000 4001 /* overlapped read of 32768, non-blocking write of 512 */ 4002 SetLastError(0xdeadbeef); 4003 ok(ReadFile(piperead, readbuf, sizeof(readbuf), &read, &ol2) == FALSE, "ReadFile should fail\n"); 4004 ok(GetLastError() == ERROR_IO_PENDING, "got %ld should be ERROR_IO_PENDING\n", GetLastError()); 4005 ok(WriteFile(pipewrite, teststring, sizeof(teststring), &write, &ol), "WriteFile should succeed\n"); 4006 ok(write == sizeof(teststring), "got %ld\n", write); 4007 ok(GetOverlappedResult(piperead, &ol2, &read, FALSE), "GetOverlappedResult should succeed\n"); 4008 ok(read == sizeof(teststring), "got %ld\n", read); 4009 if (GetOverlappedResult(piperead, &ol2, &read, FALSE) == FALSE) 4010 CancelIo(piperead); 4011 4012 /* overlapped read of 32768, non-blocking write of 513 */ 4013 SetLastError(0xdeadbeef); 4014 ok(ReadFile(piperead, readbuf, sizeof(readbuf), &read, &ol2) == FALSE, "ReadFile should fail\n"); 4015 ok(GetLastError() == ERROR_IO_PENDING, "got %ld should be ERROR_IO_PENDING\n", GetLastError()); 4016 ok(WriteFile(pipewrite, readbuf, 513, &write, &ol), "WriteFile should succeed\n"); 4017 ok(write == 513, "got %ld, write should be %d\n", write, 513); 4018 ok(GetOverlappedResult(piperead, &ol2, &read, FALSE), "GetOverlappedResult should succeed\n"); 4019 ok(read == 513, "got %ld, read should be %d\n", read, 513); 4020 if (GetOverlappedResult(piperead, &ol2, &read, FALSE) == FALSE) 4021 CancelIo(piperead); 4022 4023 /* overlapped read of 1 byte, non-blocking write of 513 bytes */ 4024 SetLastError(0xdeadbeef); 4025 ok(ReadFile(piperead, readbuf, 1, &read, &ol2) == FALSE, "ReadFile should fail\n"); 4026 ok(GetLastError() == ERROR_IO_PENDING, "got %ld should be ERROR_IO_PENDING\n", GetLastError()); 4027 ok(WriteFile(pipewrite, readbuf, 513, &write, &ol), "WriteFile should succeed\n"); 4028 ok(write == 513, "got %ld, write should be %d\n", write, 513); 4029 ok(GetOverlappedResult(piperead, &ol2, &read, FALSE), "GetOverlappedResult should succeed\n"); 4030 ok(read == 1, "got %ld, read should be %d\n", read, 1); 4031 if (GetOverlappedResult(piperead, &ol2, &read, FALSE) == FALSE) 4032 CancelIo(piperead); 4033 /* read the remaining 512 bytes */ 4034 SetLastError(0xdeadbeef); 4035 ok(ReadFile(piperead, readbuf, sizeof(readbuf), &read, &ol2), "ReadFile should succeed\n"); 4036 ok(read == 512, "got %ld, write should be %d\n", write, 512); 4037 if (GetOverlappedResult(piperead, &ol2, &read, FALSE) == FALSE) 4038 CancelIo(piperead); 4039 4040 /* overlapped read of 1 byte, non-blocking write of 514 bytes */ 4041 SetLastError(0xdeadbeef); 4042 ok(ReadFile(piperead, readbuf, 1, &read, &ol2) == FALSE, "ReadFile should fail\n"); 4043 ok(GetLastError() == ERROR_IO_PENDING, "got %ld should be ERROR_IO_PENDING\n", GetLastError()); 4044 ok(WriteFile(pipewrite, readbuf, 514, &write, &ol), "WriteFile should succeed\n"); 4045 if (pipe_type == PIPE_TYPE_MESSAGE) 4046 { 4047 todo_wine 4048 ok(write == 0, "got %ld\n", write); 4049 todo_wine 4050 ok(!GetOverlappedResult(piperead, &ol2, &read, FALSE), "GetOverlappedResult should fail\n"); 4051 todo_wine 4052 ok(GetLastError() == ERROR_IO_INCOMPLETE, "got %ld should be ERROR_IO_PENDING\n", GetLastError()); 4053 todo_wine 4054 ok(read == 0, "got %ld, read should be %d\n", read, 1); 4055 } 4056 else 4057 { 4058 ok(write == 1, "got %ld\n", write); 4059 ok(GetOverlappedResult(piperead, &ol2, &read, FALSE), "GetOverlappedResult should fail\n"); 4060 ok(read == 1, "got %ld, read should be %d\n", read, 1); 4061 } 4062 if (GetOverlappedResult(piperead, &ol2, &read, FALSE) == FALSE) 4063 CancelIo(piperead); 4064 4065 /* write the exact buffer size, should succeed */ 4066 SetLastError(0xdeadbeef); 4067 ok(WriteFile(pipewrite, readbuf, 512, &write, &ol), "WriteFile should succeed\n"); 4068 ok(write == 512, "WriteFile should write the whole buffer\n"); 4069 if (GetLastError() == ERROR_IO_PENDING) 4070 CancelIo(piperead); 4071 4072 ok(CloseHandle(ol.hEvent), "CloseHandle for the event failed\n"); 4073 ok(CloseHandle(ol2.hEvent), "CloseHandle for the event failed\n"); 4074 ok(CloseHandle(pipewrite), "CloseHandle for the write pipe failed\n"); 4075 ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n"); 4076 4077 4078 /* CreateNamedPipe with PIPE_NOWAIT, test ConnectNamedPipe */ 4079 pipewrite = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, 4080 /* dwPipeMode */ pipe_type | PIPE_NOWAIT, 4081 /* nMaxInstances */ 1, 4082 /* nOutBufSize */ 512, 4083 /* nInBufSize */ 512, 4084 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, 4085 /* lpSecurityAttrib */ NULL); 4086 ok(pipewrite != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); 4087 memset(&ol, 0, sizeof(ol)); 4088 ol.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 4089 SetLastError(0xdeadbeef); 4090 ok(ConnectNamedPipe(pipewrite, &ol) == FALSE, "ConnectNamedPipe should fail\n"); 4091 ok(GetLastError() == ERROR_PIPE_LISTENING, "got %ld should be ERROR_PIPE_LISTENING\n", GetLastError()); 4092 if (GetLastError() == ERROR_IO_PENDING) 4093 CancelIo(pipewrite); 4094 4095 /* connect and disconnect, then test ConnectNamedPipe again */ 4096 file = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 4097 ok(file != INVALID_HANDLE_VALUE, "CreateFileA failed\n"); 4098 ok(CloseHandle(file), "CloseHandle failed\n"); 4099 SetLastError(0xdeadbeef); 4100 ok(ConnectNamedPipe(pipewrite,&ol) == FALSE, "ConnectNamedPipe should fail\n"); 4101 ok(GetLastError() == ERROR_NO_DATA, "got %ld should be ERROR_NO_DATA\n", GetLastError()); 4102 if (GetLastError() == ERROR_IO_PENDING) 4103 CancelIo(pipewrite); 4104 4105 /* call DisconnectNamedPipe and test ConnectNamedPipe again */ 4106 ok(DisconnectNamedPipe(pipewrite) == TRUE, "DisconnectNamedPipe should succeed\n"); 4107 SetLastError(0xdeadbeef); 4108 ok(ConnectNamedPipe(pipewrite,&ol) == FALSE, "ConnectNamedPipe should fail\n"); 4109 ok(GetLastError() == ERROR_PIPE_LISTENING, "got %ld should be ERROR_PIPE_LISTENING\n", GetLastError()); 4110 if (GetLastError() == ERROR_IO_PENDING) 4111 CancelIo(pipewrite); 4112 ok(CloseHandle(ol.hEvent), "CloseHandle for the event failed\n"); 4113 ok(CloseHandle(pipewrite), "CloseHandle for the write pipe failed\n"); 4114} 4115 4116static void test_GetOverlappedResultEx(void) 4117{ 4118 HANDLE client, server; 4119 OVERLAPPED ovl; 4120 char buffer[8000]; 4121 DWORD ret_size; 4122 BOOL ret; 4123 4124 if (!pGetOverlappedResultEx) 4125 { 4126 win_skip("GetOverlappedResultEx() is not available\n"); 4127 return; 4128 } 4129 4130 create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server); 4131 4132 overlapped_write_async(client, buffer, sizeof(buffer), &ovl); 4133 4134 user_apc_ran = FALSE; 4135 QueueUserAPC(user_apc, GetCurrentThread(), 0); 4136 4137 SetLastError(0xdeadbeef); 4138 ret = pGetOverlappedResultEx(client, &ovl, &ret_size, 0, FALSE); 4139 ok(!ret, "expected failure\n"); 4140 ok(GetLastError() == ERROR_IO_INCOMPLETE, "wrong error %lu\n", GetLastError()); 4141 ok(!user_apc_ran, "APC should not have run\n"); 4142 4143 SetLastError(0xdeadbeef); 4144 ret = pGetOverlappedResultEx(client, &ovl, &ret_size, 0, TRUE); 4145 ok(!ret, "expected failure\n"); 4146 ok(GetLastError() == ERROR_IO_INCOMPLETE, "wrong error %lu\n", GetLastError()); 4147 ok(!user_apc_ran, "APC should not have run\n"); 4148 4149 SetLastError(0xdeadbeef); 4150 ret = pGetOverlappedResultEx(client, &ovl, &ret_size, 10, FALSE); 4151 ok(!ret, "expected failure\n"); 4152 ok(GetLastError() == WAIT_TIMEOUT, "wrong error %lu\n", GetLastError()); 4153 ok(!user_apc_ran, "APC should not have run\n"); 4154 4155 SetLastError(0xdeadbeef); 4156 ret = pGetOverlappedResultEx(client, &ovl, &ret_size, 10, TRUE); 4157 ok(!ret, "expected failure\n"); 4158 ok(GetLastError() == WAIT_IO_COMPLETION, "wrong error %lu\n", GetLastError()); 4159 ok(user_apc_ran, "APC should have run\n"); 4160 4161 CloseHandle(ovl.hEvent); 4162 4163 CloseHandle(client); 4164 CloseHandle(server); 4165} 4166 4167static void child_process_exit_process_async(DWORD parent_pid, HANDLE parent_pipe) 4168{ 4169 OVERLAPPED overlapped = {0}; 4170 static char buffer[1]; 4171 HANDLE parent, pipe; 4172 BOOL ret; 4173 4174 parent = OpenProcess(PROCESS_DUP_HANDLE, FALSE, parent_pid); 4175 ok(!!parent, "got parent %p\n", parent); 4176 4177 ret = DuplicateHandle(parent, parent_pipe, GetCurrentProcess(), &pipe, 0, 4178 FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); 4179 ok(ret, "got error %lu\n", GetLastError()); 4180 4181 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 4182 4183 ret = ReadFile(pipe, buffer, sizeof(buffer), NULL, &overlapped); 4184 ok(!ret, "expected failure\n"); 4185 ok(GetLastError() == ERROR_IO_PENDING, "got error %lu\n", GetLastError()); 4186 4187 /* exit without closing the pipe handle */ 4188} 4189 4190static void test_exit_process_async(void) 4191{ 4192 HANDLE client, server, port; 4193 OVERLAPPED *overlapped; 4194 PROCESS_INFORMATION pi; 4195 STARTUPINFOA si = {0}; 4196 char cmdline[300]; 4197 ULONG_PTR key; 4198 char **argv; 4199 DWORD size; 4200 BOOL ret; 4201 4202 winetest_get_mainargs(&argv); 4203 4204 create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server); 4205 port = CreateIoCompletionPort(client, NULL, 123, 0); 4206 4207 sprintf(cmdline, "%s pipe exit_process_async %lx %p", argv[0], GetCurrentProcessId(), client); 4208 ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); 4209 ok(ret, "got error %lu\n", GetLastError()); 4210 ret = WaitForSingleObject(pi.hProcess, 1000); 4211 ok(!ret, "wait timed out\n"); 4212 CloseHandle(pi.hThread); 4213 CloseHandle(pi.hProcess); 4214 4215 key = 0xdeadbeef; 4216 size = 0xdeadbeef; 4217 ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped, 1000); 4218 ok(!ret, "expected failure\n"); 4219 ok(GetLastError() == ERROR_OPERATION_ABORTED, "got error %lu\n", GetLastError()); 4220 ok(!size, "got size %lu\n", size); 4221 ok(key == 123, "got key %Iu\n", key); 4222 4223 CloseHandle(port); 4224 CloseHandle(server); 4225} 4226 4227static DWORD CALLBACK synchronousIoThreadMain(void *arg) 4228{ 4229 HANDLE pipe; 4230 BOOL ret; 4231 4232 pipe = arg; 4233 SetLastError(0xdeadbeef); 4234 ret = ConnectNamedPipe(pipe, NULL); 4235 ok(!ret, "expected failure\n"); 4236 ok(GetLastError() == ERROR_OPERATION_ABORTED, "got error %lu\n", GetLastError()); 4237 return 0; 4238} 4239 4240static DWORD CALLBACK synchronousIoThreadMain2(void *arg) 4241{ 4242 OVERLAPPED ov; 4243 HANDLE pipe; 4244 BOOL ret; 4245 4246 pipe = arg; 4247 memset(&ov, 0, sizeof(ov)); 4248 ov.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 4249 SetLastError(0xdeadbeef); 4250 ret = ConnectNamedPipe(pipe, &ov); 4251 ok(!ret, "expected failure\n"); 4252 ok(GetLastError() == ERROR_IO_PENDING, "got error %lu\n", GetLastError()); 4253 ret = WaitForSingleObject(ov.hEvent, 1000); 4254 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", ret); 4255 CloseHandle(ov.hEvent); 4256 return 0; 4257} 4258 4259static void test_CancelSynchronousIo(void) 4260{ 4261 BOOL res; 4262 DWORD wait; 4263 HANDLE file; 4264 HANDLE pipe; 4265 HANDLE thread; 4266 4267 /* bogus values */ 4268 SetLastError(0xdeadbeef); 4269 res = pCancelSynchronousIo((HANDLE)0xdeadbeef); 4270 ok(!res, "CancelSynchronousIo succeeded unexpectedly\n"); 4271 ok(GetLastError() == ERROR_INVALID_HANDLE, 4272 "In CancelSynchronousIo failure, expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); 4273 4274 SetLastError(0xdeadbeef); 4275 res = pCancelSynchronousIo(GetCurrentThread()); 4276 ok(!res, "CancelSynchronousIo succeeded unexpectedly\n"); 4277 ok(GetLastError() == ERROR_NOT_FOUND, 4278 "In CancelSynchronousIo failure, expected ERROR_NOT_FOUND, got %ld\n", GetLastError()); 4279 4280 /* synchronous i/o */ 4281 pipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, 4282 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 4283 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); 4284 ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %lu\n", GetLastError()); 4285 thread = CreateThread(NULL, 0, synchronousIoThreadMain, pipe, 0, NULL); 4286 /* wait for I/O to start, which transitions the pipe handle from signaled to nonsignaled state. */ 4287 while ((wait = WaitForSingleObject(pipe, 0)) == WAIT_OBJECT_0) Sleep(1); 4288 ok(wait == WAIT_TIMEOUT, "WaitForSingleObject returned %lu (error %lu)\n", wait, GetLastError()); 4289 SetLastError(0xdeadbeef); 4290 res = pCancelSynchronousIo(thread); 4291 ok(res, "CancelSynchronousIo failed with error %ld\n", GetLastError()); 4292 ok(GetLastError() == 0xdeadbeef, 4293 "In CancelSynchronousIo failure, expected 0xdeadbeef got %ld\n", GetLastError()); 4294 wait = WaitForSingleObject(thread, 1000); 4295 ok(wait == WAIT_OBJECT_0, "WaitForSingleObject returned %lx\n", wait); 4296 CloseHandle(thread); 4297 CloseHandle(pipe); 4298 4299 /* asynchronous i/o */ 4300 pipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 4301 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 4302 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); 4303 ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %lu\n", GetLastError()); 4304 thread = CreateThread(NULL, 0, synchronousIoThreadMain2, pipe, 0, NULL); 4305 /* wait for I/O to start, which transitions the pipe handle from signaled to nonsignaled state. */ 4306 while ((wait = WaitForSingleObject(pipe, 0)) == WAIT_OBJECT_0) Sleep(1); 4307 ok(wait == WAIT_TIMEOUT, "WaitForSingleObject returned %lu (error %lu)\n", wait, GetLastError()); 4308 SetLastError(0xdeadbeef); 4309 res = pCancelSynchronousIo(thread); 4310 ok(!res, "CancelSynchronousIo succeeded unexpectedly\n"); 4311 ok(GetLastError() == ERROR_NOT_FOUND, 4312 "In CancelSynchronousIo failure, expected ERROR_NOT_FOUND, got %ld\n", GetLastError()); 4313 file = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 4314 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed (%ld)\n", GetLastError()); 4315 WaitForSingleObject(thread, INFINITE); 4316 CloseHandle(thread); 4317 CloseHandle(file); 4318 CloseHandle(pipe); 4319} 4320 4321START_TEST(pipe) 4322{ 4323 char **argv; 4324 int argc; 4325 HMODULE hmod; 4326 4327 hmod = GetModuleHandleA("advapi32.dll"); 4328 pDuplicateTokenEx = (void *) GetProcAddress(hmod, "DuplicateTokenEx"); 4329 hmod = GetModuleHandleA("kernel32.dll"); 4330 pCancelIoEx = (void *) GetProcAddress(hmod, "CancelIoEx"); 4331 pCancelSynchronousIo = (void *) GetProcAddress(hmod, "CancelSynchronousIo"); 4332 pGetNamedPipeClientProcessId = (void *) GetProcAddress(hmod, "GetNamedPipeClientProcessId"); 4333 pGetNamedPipeServerProcessId = (void *) GetProcAddress(hmod, "GetNamedPipeServerProcessId"); 4334 pGetNamedPipeClientSessionId = (void *) GetProcAddress(hmod, "GetNamedPipeClientSessionId"); 4335 pGetNamedPipeServerSessionId = (void *) GetProcAddress(hmod, "GetNamedPipeServerSessionId"); 4336 pGetOverlappedResultEx = (void *)GetProcAddress(hmod, "GetOverlappedResultEx"); 4337 4338 argc = winetest_get_mainargs(&argv); 4339 4340 if (argc > 3) 4341 { 4342 if (!strcmp(argv[2], "writepipe")) 4343 { 4344 ULONG handle; 4345 sscanf(argv[3], "%lx", &handle); 4346 child_process_write_pipe(ULongToHandle(handle)); 4347 return; 4348 } 4349 if (!strcmp(argv[2], "checkpid")) 4350 { 4351 DWORD pid = GetProcessId(GetCurrentProcess()); 4352 sscanf(argv[3], "%lx", &pid); 4353 child_process_check_pid(pid); 4354 return; 4355 } 4356 if (!strcmp(argv[2], "checksessionid")) 4357 { 4358 DWORD id; 4359 ProcessIdToSessionId(GetProcessId(GetCurrentProcess()), &id); 4360 sscanf(argv[3], "%lx", &id); 4361 child_process_check_session_id(id); 4362 return; 4363 } 4364 if (!strcmp(argv[2], "exit_process_async")) 4365 { 4366 HANDLE handle; 4367 DWORD pid; 4368 sscanf(argv[3], "%lx", &pid); 4369 sscanf(argv[4], "%p", &handle); 4370 child_process_exit_process_async(pid, handle); 4371 return; 4372 } 4373 } 4374 4375 if (test_DisconnectNamedPipe()) 4376 return; 4377 test_CreateNamedPipe_instances_must_match(); 4378 test_NamedPipe_2(); 4379 test_CreateNamedPipe(PIPE_TYPE_BYTE); 4380 test_CreateNamedPipe(PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE); 4381 test_CreatePipe(); 4382 test_ReadFile(); 4383 test_CloseHandle(); 4384 test_impersonation(); 4385 test_overlapped(); 4386 test_overlapped_error(); 4387 test_NamedPipeHandleState(); 4388 test_GetNamedPipeInfo(); 4389 test_readfileex_pending(); 4390 test_overlapped_transport(TRUE, FALSE); 4391 test_overlapped_transport(TRUE, TRUE); 4392 test_overlapped_transport(FALSE, FALSE); 4393 test_TransactNamedPipe(); 4394 test_namedpipe_process_id(); 4395 test_namedpipe_session_id(); 4396 test_multiple_instances(); 4397 test_wait_pipe(); 4398 test_nowait(PIPE_TYPE_BYTE); 4399 test_nowait(PIPE_TYPE_MESSAGE); 4400 test_GetOverlappedResultEx(); 4401#ifdef __REACTOS__ 4402 if (is_reactos() || GetNTVersion() <= _WIN32_WINNT_WS03) { 4403 skip("These next tests crash or hang on ReactOS and Windows Server 2003.\n"); 4404 return; 4405 } 4406#endif 4407 test_exit_process_async(); 4408 test_CancelSynchronousIo(); 4409}