commit 24fd85eade01d03cff3391be5a3f82bec246f97c Author: Jacek Caban Date: Thu Dec 1 11:27:10 2016 +0100 kernel32/tests: Added test of async write terminated by process exit. diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c index cb2ca30..c17d2a0 100644 --- a/dlls/kernel32/tests/pipe.c +++ b/dlls/kernel32/tests/pipe.c @@ -2801,8 +2801,37 @@ static void test_blocking_rw(HANDLE writer, HANDLE reader, DWORD buf_size, BOOL test_flush_done(flush_thread); } +static void child_process_write_pipe(HANDLE pipe) +{ + OVERLAPPED overlapped; + char buf[10000]; + + memset(buf, 'x', sizeof(buf)); + overlapped_write_async(pipe, buf, sizeof(buf), &overlapped); + + /* sleep until parent process tesrminates this process. */ + Sleep(INFINITE); +} + +static HANDLE create_writepipe_process(HANDLE pipe) +{ + STARTUPINFOA si = { sizeof(si) }; + PROCESS_INFORMATION info; + char **argv, buf[MAX_PATH]; + BOOL res; + + winetest_get_mainargs(&argv); + sprintf(buf, "\"%s\" pipe writepipe %lx", argv[0], (UINT_PTR)pipe); + res = CreateProcessA(NULL, buf, NULL, NULL, TRUE, 0L, NULL, NULL, &si, &info); + ok(res, "CreateProcess failed: %u\n", GetLastError()); + CloseHandle(info.hThread); + + return info.hProcess; +} + static void create_overlapped_pipe(DWORD read_mode, HANDLE *client, HANDLE *server) { + SECURITY_ATTRIBUTES sec_attr = { sizeof(sec_attr), NULL, TRUE }; DWORD mode = read_mode; OVERLAPPED overlapped; BOOL res; @@ -2819,7 +2848,7 @@ static void create_overlapped_pipe(DWORD read_mode, HANDLE *client, HANDLE *serv test_not_signaled(*server); test_not_signaled(overlapped.hEvent); - *client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + *client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, &sec_attr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); ok(*server != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError()); res = SetNamedPipeHandleState(*client, &mode, NULL, NULL); @@ -2834,6 +2863,8 @@ static void test_overlapped_transport(DWORD read_mode) { OVERLAPPED overlapped, overlapped2; HANDLE server, client, flush; + DWORD read_bytes; + HANDLE process; char buf[60000]; BOOL res; @@ -2877,10 +2908,32 @@ static void test_overlapped_transport(DWORD read_mode) test_flush_done(flush); CloseHandle(server); CloseHandle(client); + + /* terminate process with pending write */ + create_overlapped_pipe(read_mode, &client, &server); + process = create_writepipe_process(client); + /* succesfully read part of write that is pending in child process */ + res = ReadFile(server, buf, 10, &read_bytes, NULL); + if(read_mode == PIPE_READMODE_BYTE) + ok(res, "ReadFile failed: %u\n", GetLastError()); + else + ok(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned: %x %u\n", res, GetLastError()); + ok(read_bytes == 10, "read_bytes = %u\n", read_bytes); + TerminateProcess(process, 0); + winetest_wait_child_process(process); + /* after terminating process, there is no pending write and pipe buffer is empty */ + overlapped_read_async(server, buf, 10, &overlapped); + overlapped_write_sync(client, buf, 1); + test_overlapped_result(server, &overlapped, 1, FALSE); + CloseHandle(process); + CloseHandle(server); + CloseHandle(client); } START_TEST(pipe) { + char **argv; + int argc; HMODULE hmod; hmod = GetModuleHandleA("advapi32.dll"); @@ -2889,6 +2942,16 @@ START_TEST(pipe) pQueueUserAPC = (void *) GetProcAddress(hmod, "QueueUserAPC"); pCancelIoEx = (void *) GetProcAddress(hmod, "CancelIoEx"); + argc = winetest_get_mainargs(&argv); + + if (argc > 3 && !strcmp(argv[2], "writepipe")) + { + UINT_PTR handle; + sscanf(argv[3], "%lx", &handle); + child_process_write_pipe((HANDLE)handle); + return; + } + if (test_DisconnectNamedPipe()) return; test_CreateNamedPipe_instances_must_match();