From: Paul Gofman Subject: [PATCH v3 3/4] kernel32/tests: Test invalid parent handle in test_parent_process_attribute(). Message-Id: <20191212111833.672808-3-gofmanp@gmail.com> Date: Thu, 12 Dec 2019 14:18:32 +0300 In-Reply-To: <20191212111833.672808-1-gofmanp@gmail.com> References: <20191212111833.672808-1-gofmanp@gmail.com> Signed-off-by: Paul Gofman --- v2: - no changes; v3: - mark failed child process creation for GetCurrentProcess() parent handle as broken instead of successful creation; - replace test with INVALID_HANDLE_VALUE parent (which is the same as GetCurrentProcess()) with OpenProcess(..., GetCurrentProcessId()) handle. dlls/kernel32/tests/process.c | 85 ++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c index 6d7a9a74c3..1194c54202 100644 --- a/dlls/kernel32/tests/process.c +++ b/dlls/kernel32/tests/process.c @@ -3825,7 +3825,8 @@ static void test_ProcThreadAttributeList(void) /* level 0: Main test process * level 1: Process created by level 0 process without handle inheritance * level 2: Process created by level 1 process with handle inheritance and level 0 - * process parent substitute. */ + * process parent substitute. + * level 255: Process created by level 1 process during invalid parent handles testing. */ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe) { PROCESS_BASIC_INFORMATION pbi; @@ -3848,6 +3849,9 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe) } parent_data; + if (level == 255) + return; + if (!pInitializeProcThreadAttributeList) { win_skip("No support for ProcThreadAttributeList.\n"); @@ -3891,11 +3895,90 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe) if (level) { + HANDLE handle; SIZE_T size; ret = pInitializeProcThreadAttributeList(NULL, 1, 0, &size); ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError()); + + sprintf(buffer, "\"%s\" tests/process.c parent %u %p", selfname, 255, read_pipe); + +#if 0 + /* Crashes on some Windows installations, otherwise successfully creates process. */ + ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT, + NULL, NULL, (STARTUPINFOA *)&si, &info); + ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError()); + ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); + CloseHandle(info.hThread); + CloseHandle(info.hProcess); +#endif + si.lpAttributeList = heap_alloc(size); + ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size); + ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError()); + handle = OpenProcess(PROCESS_CREATE_PROCESS, TRUE, GetCurrentProcessId()); + ret = pUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, + &handle, sizeof(handle), NULL, NULL); + ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError()); + ret = CreateProcessA(NULL, buffer, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT, + NULL, NULL, (STARTUPINFOA *)&si, &info); + ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError()); + ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); + CloseHandle(info.hThread); + CloseHandle(info.hProcess); + CloseHandle(handle); + pDeleteProcThreadAttributeList(si.lpAttributeList); + heap_free(si.lpAttributeList); + + si.lpAttributeList = heap_alloc(size); + ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size); + ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError()); + handle = (HANDLE)0xdeadbeef; + ret = pUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, + &handle, sizeof(handle), NULL, NULL); + ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError()); + ret = CreateProcessA(NULL, buffer, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT, + NULL, NULL, (STARTUPINFOA *)&si, &info); + ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected ret %#x, GetLastError() %u.\n", + ret, GetLastError()); + pDeleteProcThreadAttributeList(si.lpAttributeList); + heap_free(si.lpAttributeList); + + si.lpAttributeList = heap_alloc(size); + ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size); + ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError()); + handle = NULL; + ret = pUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, + &handle, sizeof(handle), NULL, NULL); + ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError()); + ret = CreateProcessA(NULL, buffer, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT, + NULL, NULL, (STARTUPINFOA *)&si, &info); + ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected ret %#x, GetLastError() %u.\n", + ret, GetLastError()); + pDeleteProcThreadAttributeList(si.lpAttributeList); + heap_free(si.lpAttributeList); + + si.lpAttributeList = heap_alloc(size); + ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size); + ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError()); + handle = GetCurrentProcess(); + ret = pUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, + &handle, sizeof(handle), NULL, NULL); + ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError()); + ret = CreateProcessA(NULL, buffer, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT, + NULL, NULL, (STARTUPINFOA *)&si, &info); + /* Broken on Vista / w7 / w10. */ + ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_HANDLE), + "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError()); + if (ret) + { + ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); + CloseHandle(info.hThread); + CloseHandle(info.hProcess); + } + pDeleteProcThreadAttributeList(si.lpAttributeList); + heap_free(si.lpAttributeList); + si.lpAttributeList = heap_alloc(size); ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size); ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError()); -- 2.23.0