[PATCH] kernel32/tests: Add a couple of process helper functions.

Francois Gouget fgouget at codeweavers.com
Mon Mar 23 19:56:11 CDT 2020


wait_and_close_child_process() simplifies waiting for the child process
and closing its handles. And because it uses wait_child_process() this
ensures that any error happening in the child process is detected.
reload_child_dump() wraps a cryptic WritePrivateProfileStringA() call
and avoids having to add a comment every time.

Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---
 dlls/kernel32/tests/process.c | 279 +++++++++++-----------------------
 1 file changed, 92 insertions(+), 187 deletions(-)

diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index 0f0889073b0..9a2b05914a6 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -203,6 +203,21 @@ static WCHAR*   decodeW(const char* str)
     return ptr;
 }
 
+static void wait_and_close_child_process(PROCESS_INFORMATION *pi)
+{
+    wait_child_process(pi->hProcess);
+    CloseHandle(pi->hThread);
+    CloseHandle(pi->hProcess);
+}
+
+static void reload_child_info(const char* resfile)
+{
+    /* This forces the profile functions to reload the resource file
+     * after the child process has modified it.
+     */
+    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+}
+
 /******************************************************************
  *		init
  *
@@ -615,13 +630,9 @@ static void test_Startup(void)
     get_file_name(resfile);
     sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
     ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
-    CloseHandle(info.hThread);
-    CloseHandle(info.hProcess);
+    wait_and_close_child_process(&info);
 
+    reload_child_info(resfile);
     GetStartupInfoA(&si);
     okChildInt("StartupInfoA", "cb", startup.cb);
     okChildString("StartupInfoA", "lpDesktop", si.lpDesktop);
@@ -655,13 +666,9 @@ static void test_Startup(void)
     get_file_name(resfile);
     sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
     ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
-    CloseHandle(info.hThread);
-    CloseHandle(info.hProcess);
+    wait_and_close_child_process(&info);
 
+    reload_child_info(resfile);
     okChildInt("StartupInfoA", "cb", startup.cb);
     okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
     okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
@@ -695,13 +702,9 @@ static void test_Startup(void)
     get_file_name(resfile);
     sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
     ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
-    CloseHandle(info.hThread);
-    CloseHandle(info.hProcess);
+    wait_and_close_child_process(&info);
 
+    reload_child_info(resfile);
     okChildInt("StartupInfoA", "cb", startup.cb);
     okChildString("StartupInfoA", "lpDesktop", si.lpDesktop);
     okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
@@ -735,13 +738,9 @@ static void test_Startup(void)
     get_file_name(resfile);
     sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
     ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
-    CloseHandle(info.hThread);
-    CloseHandle(info.hProcess);
+    wait_and_close_child_process(&info);
 
+    reload_child_info(resfile);
     okChildInt("StartupInfoA", "cb", startup.cb);
     okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
     okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
@@ -775,13 +774,9 @@ static void test_Startup(void)
     get_file_name(resfile);
     sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
     ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
-    CloseHandle(info.hThread);
-    CloseHandle(info.hProcess);
+    wait_and_close_child_process(&info);
 
+    reload_child_info(resfile);
     okChildInt("StartupInfoA", "cb", startup.cb);
     okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
     result = getChildString( "StartupInfoA", "lpTitle" );
@@ -817,13 +812,9 @@ static void test_Startup(void)
     get_file_name(resfile);
     sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
     ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
-    CloseHandle(info.hThread);
-    CloseHandle(info.hProcess);
+    wait_and_close_child_process(&info);
 
+    reload_child_info(resfile);
     okChildInt("StartupInfoA", "cb", startup.cb);
     okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
     okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
@@ -857,13 +848,9 @@ static void test_Startup(void)
     get_file_name(resfile);
     sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
     ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
-    CloseHandle(info.hThread);
-    CloseHandle(info.hProcess);
+    wait_and_close_child_process(&info);
 
+    reload_child_info(resfile);
     okChildInt("StartupInfoA", "cb", startup.cb);
     okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
     okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
@@ -920,13 +907,9 @@ static void test_CommandLine(void)
     ok(startup.lpTitle == NULL, "lpTitle is not NULL\n");
     ok(startup.dwFlags == STARTF_USESHOWWINDOW, "unexpected dwFlags %04x\n", startup.dwFlags);
     ok(startup.wShowWindow == SW_SHOWNORMAL, "unexpected wShowWindow %d\n", startup.wShowWindow);
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
-    CloseHandle(info.hThread);
-    CloseHandle(info.hProcess);
+    wait_and_close_child_process(&info);
 
+    reload_child_info(resfile);
     okChildInt("Arguments", "argcA", 5);
     okChildString("Arguments", "argvA4", "C:\\Program Files\\my nice app.exe");
     okChildString("Arguments", "argvA5", NULL);
@@ -938,13 +921,9 @@ static void test_CommandLine(void)
     get_file_name(resfile);
     sprintf(buffer, "\"%s\" process dump \"%s\" \"a\\\"b\\\\\" c\\\" d", selfname, resfile);
     ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
-    CloseHandle(info.hThread);
-    CloseHandle(info.hProcess);
+    wait_and_close_child_process(&info);
 
+    reload_child_info(resfile);
     okChildInt("Arguments", "argcA", 7);
     okChildString("Arguments", "argvA4", "a\"b\\");
     okChildString("Arguments", "argvA5", "c\"");
@@ -963,12 +942,9 @@ static void test_CommandLine(void)
     SetLastError(0xdeadbeef);
     ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
     ok(ret, "CreateProcess (%s) failed : %d\n", buffer, GetLastError());
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
-    CloseHandle(info.hThread);
-    CloseHandle(info.hProcess);
+    wait_and_close_child_process(&info);
+
+    reload_child_info(resfile);
     sprintf(buffer, "./%s", exename);
     okChildInt("Arguments", "argcA", 5);
     okChildString("Arguments", "argvA0", buffer);
@@ -983,12 +959,9 @@ static void test_CommandLine(void)
     SetLastError(0xdeadbeef);
     ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
     ok(ret, "CreateProcess (%s) failed : %d\n", buffer, GetLastError());
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
-    CloseHandle(info.hThread);
-    CloseHandle(info.hProcess);
+    wait_and_close_child_process(&info);
+
+    reload_child_info(resfile);
     sprintf(buffer, ".\\%s", exename);
     okChildString("Arguments", "argvA0", buffer);
     release_memory();
@@ -1005,12 +978,9 @@ static void test_CommandLine(void)
     SetLastError(0xdeadbeef);
     ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
     ok(ret, "CreateProcess (%s) failed : %d\n", buffer, GetLastError());
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
-    CloseHandle(info.hThread);
-    CloseHandle(info.hProcess);
+    wait_and_close_child_process(&info);
+
+    reload_child_info(resfile);
     if (p) sprintf(buffer, "..%s/%s", p, exename);
     else sprintf(buffer, "./%s", exename);
     okChildString("Arguments", "argvA0", buffer);
@@ -1030,12 +1000,9 @@ static void test_CommandLine(void)
     SetLastError(0xdeadbeef);
     ret = CreateProcessA(buffer, buffer2, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
     ok(ret, "CreateProcess (%s) failed : %d\n", buffer, GetLastError());
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
-    CloseHandle(info.hThread);
-    CloseHandle(info.hProcess);
+    wait_and_close_child_process(&info);
+
+    reload_child_info(resfile);
     okChildString("Arguments", "argvA0", "dummy");
     okChildString("Arguments", "CommandLineA", buffer2);
     okChildStringWA("Arguments", "CommandLineW", buffer2);
@@ -1128,13 +1095,9 @@ static void test_Directory(void)
     sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
     GetWindowsDirectoryA( windir, sizeof(windir) );
     ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, windir, &startup, &info), "CreateProcess\n");
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
-    CloseHandle(info.hThread);
-    CloseHandle(info.hProcess);
+    wait_and_close_child_process(&info);
 
+    reload_child_info(resfile);
     okChildIString("Misc", "CurrDirA", windir);
     release_memory();
     DeleteFileA(resfile);
@@ -1174,11 +1137,9 @@ static void test_Toolhelp(void)
     get_file_name(resfile);
     sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
     ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess failed\n");
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    CloseHandle(info.hProcess);
-    CloseHandle(info.hThread);
+    wait_and_close_child_process(&info);
 
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+    reload_child_info(resfile);
     okChildInt("Toolhelp", "cntUsage", 0);
     okChildInt("Toolhelp", "th32DefaultHeapID", 0);
     okChildInt("Toolhelp", "th32ModuleID", 0);
@@ -1192,7 +1153,7 @@ static void test_Toolhelp(void)
     get_file_name(resfile);
     sprintf(buffer, "\"%s\" process nested \"%s\"", selfname, resfile);
     ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess failed\n");
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
+    wait_child_process(info.hProcess);
 
     process = OpenProcess(PROCESS_ALL_ACCESS_NT4, FALSE, info.dwProcessId);
     ok(process != NULL, "OpenProcess failed %u\n", GetLastError());
@@ -1214,7 +1175,7 @@ static void test_Toolhelp(void)
     ok(i < 20 || broken(i == 20), "process object not released\n");
 
     /* Look for the nested process by pid */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+    reload_child_info(resfile);
     nested_pid = GetPrivateProfileIntA("Nested", "Pid", 0, resfile);
     DeleteFileA(resfile);
 
@@ -1253,11 +1214,10 @@ static void test_Toolhelp(void)
     ok(ret == 1, "expected 1, got %u\n", ret);
     CloseHandle(thread);
 
-    ret = WaitForSingleObject(process, 30000);
-    ok(ret == WAIT_OBJECT_0, "Child process termination got %u le=%u\n", ret, GetLastError());
+    wait_child_process(process);
     CloseHandle(process);
 
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+    reload_child_info(resfile);
     okChildInt("Toolhelp", "cntUsage", 0);
     okChildInt("Toolhelp", "th32DefaultHeapID", 0);
     okChildInt("Toolhelp", "th32ModuleID", 0);
@@ -1353,11 +1313,9 @@ static void test_Environment(void)
     get_file_name(resfile);
     sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
     ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+    wait_and_close_child_process(&info);
 
+    reload_child_info(resfile);
     env = GetEnvironmentStringsA();
     cmpEnvironment(env);
     release_memory();
@@ -1410,11 +1368,9 @@ static void test_Environment(void)
     }
     *ptr = '\0';
     ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, child_env, NULL, &startup, &info), "CreateProcess\n");
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+    wait_and_close_child_process(&info);
 
+    reload_child_info(resfile);
     cmpEnvironment(child_env);
 
     HeapFree(GetProcessHeap(), 0, child_env);
@@ -1446,13 +1402,11 @@ static  void    test_SuspendFlag(void)
     ok(GetExitCodeThread(info.hThread, &exit_status) && exit_status == STILL_ACTIVE, "thread still running\n");
     ok(ResumeThread(info.hThread) == 1, "Resuming thread\n");
 
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+    wait_and_close_child_process(&info);
 
     GetStartupInfoA(&us);
 
+    reload_child_info(resfile);
     okChildInt("StartupInfoA", "cb", startup.cb);
     okChildString("StartupInfoA", "lpDesktop", us.lpDesktop);
     result = getChildString( "StartupInfoA", "lpTitle" );
@@ -1508,13 +1462,11 @@ static  void    test_DebuggingFlag(void)
     } while (de.dwDebugEventCode != EXIT_PROCESS_DEBUG_EVENT);
 
     ok(dbg, "I have seen a debug event\n");
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+    wait_and_close_child_process(&info);
 
     GetStartupInfoA(&us);
 
+    reload_child_info(resfile);
     okChildInt("StartupInfoA", "cb", startup.cb);
     okChildString("StartupInfoA", "lpDesktop", us.lpDesktop);
     result = getChildString( "StartupInfoA", "lpTitle" );
@@ -1588,12 +1540,9 @@ static void test_Console(void)
     get_file_name(resfile);
     sprintf(buffer, "\"%s\" process dump \"%s\" console", selfname, resfile);
     ok(CreateProcessA(NULL, buffer, NULL, NULL, TRUE, 0, NULL, NULL, &startup, &info), "CreateProcess\n");
+    wait_and_close_child_process(&info);
 
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
-
+    reload_child_info(resfile);
     /* now get the modification the child has made, and resets parents expected values */
     ok(GetConsoleScreenBufferInfo(startup.hStdOutput, &sbiC), "Getting sb info\n");
     ok(GetConsoleMode(startup.hStdInput, &modeInC), "Getting console in mode\n");
@@ -1715,11 +1664,9 @@ static void test_Console(void)
     /* the child may also send the final "n tests executed" string, so read it to avoid a deadlock */
     ReadFile(hParentIn, buffer, sizeof(buffer), &w, NULL);
 
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+    wait_and_close_child_process(&info);
 
+    reload_child_info(resfile);
     okChildString("StdHandle", "msg", msg);
 
     release_memory();
@@ -1743,11 +1690,10 @@ static  void    test_ExitCode(void)
     sprintf(buffer, "\"%s\" process dump \"%s\" exit_code", selfname, resfile);
     ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info), "CreateProcess\n");
 
-    /* wait for child to terminate */
+    /* not wait_child_process() because of the exit code */
     ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    /* child process has changed result file, so let profile functions know about it */
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
 
+    reload_child_info(resfile);
     ok(GetExitCodeProcess(info.hProcess, &code), "Getting exit code\n");
     okChildInt("ExitCode", "value", code);
 
@@ -2458,7 +2404,6 @@ static void test_IsProcessInJob(void)
     HANDLE job, job2;
     PROCESS_INFORMATION pi;
     BOOL ret, out;
-    DWORD dwret;
 
     if (!pIsProcessInJob)
     {
@@ -2503,9 +2448,7 @@ static void test_IsProcessInJob(void)
     ok(out, "IsProcessInJob returned out=%u\n", out);
 
     TerminateProcess(pi.hProcess, 0);
-
-    dwret = WaitForSingleObject(pi.hProcess, 1000);
-    ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
+    wait_child_process(pi.hProcess);
 
     out = FALSE;
     ret = pIsProcessInJob(pi.hProcess, job, &out);
@@ -2536,6 +2479,7 @@ static void test_TerminateJobObject(void)
     ret = pTerminateJobObject(job, 123);
     ok(ret, "TerminateJobObject error %u\n", GetLastError());
 
+    /* not wait_child_process() because of the exit code */
     dwret = WaitForSingleObject(pi.hProcess, 1000);
     ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
     if (dwret == WAIT_TIMEOUT) TerminateProcess(pi.hProcess, 0);
@@ -2550,9 +2494,7 @@ static void test_TerminateJobObject(void)
 
     /* Test adding an already terminated process to a job object */
     create_process("exit", &pi);
-
-    dwret = WaitForSingleObject(pi.hProcess, 1000);
-    ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
+    wait_child_process(pi.hProcess);
 
     SetLastError(0xdeadbeef);
     ret = pAssignProcessToJobObject(job, pi.hProcess);
@@ -2590,9 +2532,7 @@ static void test_QueryInformationJobObject(void)
     ok(ret, "AssignProcessToJobObject error %u\n", GetLastError());
 
     ReleaseSemaphore(sem, 1, NULL);
-    wait_child_process(pi[0].hProcess);
-    CloseHandle(pi[0].hProcess);
-    CloseHandle(pi[0].hThread);
+    wait_and_close_child_process(&pi[0]);
 
     create_process("wait", &pi[0]);
     ret = pAssignProcessToJobObject(job, pi[0].hProcess);
@@ -2696,7 +2636,6 @@ static void test_CompletionPort(void)
     JOBOBJECT_ASSOCIATE_COMPLETION_PORT port_info;
     PROCESS_INFORMATION pi;
     HANDLE job, port;
-    DWORD dwret;
     BOOL ret;
 
     job = pCreateJobObjectW(NULL, NULL);
@@ -2718,8 +2657,7 @@ static void test_CompletionPort(void)
     test_completion(port, JOB_OBJECT_MSG_NEW_PROCESS, (DWORD_PTR)job, pi.dwProcessId, 0);
 
     TerminateProcess(pi.hProcess, 0);
-    dwret = WaitForSingleObject(pi.hProcess, 1000);
-    ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
+    wait_child_process(pi.hProcess);
 
     test_completion(port, JOB_OBJECT_MSG_EXIT_PROCESS, (DWORD_PTR)job, pi.dwProcessId, 0);
     test_completion(port, JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO, (DWORD_PTR)job, 0, 100);
@@ -2757,6 +2695,7 @@ static void test_KillOnJobClose(void)
 
     CloseHandle(job);
 
+    /* not wait_child_process() for the kill */
     dwret = WaitForSingleObject(pi.hProcess, 1000);
     ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
     if (dwret == WAIT_TIMEOUT) TerminateProcess(pi.hProcess, 0);
@@ -2847,9 +2786,7 @@ static void test_WaitForJobObject(void)
     dwret = WaitForSingleObject(job, 100);
     ok(dwret == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", dwret);
 
-    wait_child_process(pi.hProcess);
-    CloseHandle(pi.hProcess);
-    CloseHandle(pi.hThread);
+    wait_and_close_child_process(&pi);
     CloseHandle(job);
     CloseHandle(sem);
 }
@@ -2871,7 +2808,6 @@ static HANDLE test_AddSelfToJob(void)
 static void test_jobInheritance(HANDLE job)
 {
     PROCESS_INFORMATION pi;
-    DWORD dwret;
     BOOL ret, out;
 
     if (!pIsProcessInJob)
@@ -2887,11 +2823,7 @@ static void test_jobInheritance(HANDLE job)
     ok(ret, "IsProcessInJob error %u\n", GetLastError());
     ok(out, "IsProcessInJob returned out=%u\n", out);
 
-    dwret = WaitForSingleObject(pi.hProcess, 1000);
-    ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
-
-    CloseHandle(pi.hProcess);
-    CloseHandle(pi.hThread);
+    wait_and_close_child_process(&pi);
 }
 
 static void test_BreakawayOk(HANDLE job)
@@ -2901,7 +2833,6 @@ static void test_BreakawayOk(HANDLE job)
     STARTUPINFOA si = {0};
     char buffer[MAX_PATH + 23];
     BOOL ret, out;
-    DWORD dwret;
 
     if (!pIsProcessInJob)
     {
@@ -2917,12 +2848,7 @@ static void test_BreakawayOk(HANDLE job)
     if (ret)
     {
         TerminateProcess(pi.hProcess, 0);
-
-        dwret = WaitForSingleObject(pi.hProcess, 1000);
-        ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
-
-        CloseHandle(pi.hProcess);
-        CloseHandle(pi.hThread);
+        wait_and_close_child_process(&pi);
     }
 
     limit_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_BREAKAWAY_OK;
@@ -2936,11 +2862,7 @@ static void test_BreakawayOk(HANDLE job)
     ok(ret, "IsProcessInJob error %u\n", GetLastError());
     ok(!out, "IsProcessInJob returned out=%u\n", out);
 
-    dwret = WaitForSingleObject(pi.hProcess, 1000);
-    ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
-
-    CloseHandle(pi.hProcess);
-    CloseHandle(pi.hThread);
+    wait_and_close_child_process(&pi);
 
     limit_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK;
     ret = pSetInformationJobObject(job, JobObjectExtendedLimitInformation, &limit_info, sizeof(limit_info));
@@ -2953,11 +2875,7 @@ static void test_BreakawayOk(HANDLE job)
     ok(ret, "IsProcessInJob error %u\n", GetLastError());
     ok(!out, "IsProcessInJob returned out=%u\n", out);
 
-    dwret = WaitForSingleObject(pi.hProcess, 1000);
-    ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
-
-    CloseHandle(pi.hProcess);
-    CloseHandle(pi.hThread);
+    wait_and_close_child_process(&pi);
 
     /* unset breakaway ok */
     limit_info.BasicLimitInformation.LimitFlags = 0;
@@ -2980,8 +2898,9 @@ static void test_StartupNoConsole(void)
     sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
     ok(CreateProcessA(NULL, buffer, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &startup,
                       &info), "CreateProcess\n");
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+    wait_and_close_child_process(&info);
+
+    reload_child_info(resfile);
     okChildInt("StartupInfoA", "hStdInput", (UINT)INVALID_HANDLE_VALUE);
     okChildInt("StartupInfoA", "hStdOutput", (UINT)INVALID_HANDLE_VALUE);
     okChildInt("StartupInfoA", "hStdError", (UINT)INVALID_HANDLE_VALUE);
@@ -3012,9 +2931,9 @@ static void test_DetachConsoleHandles(void)
     sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
     ok(CreateProcessA(NULL, buffer, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &startup,
                       &info), "CreateProcess\n");
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+    wait_and_close_child_process(&info);
 
+    reload_child_info(resfile);
     result = GetPrivateProfileIntA("StartupInfoA", "hStdInput", 0, resfile);
     ok(result != 0 && result != (UINT)INVALID_HANDLE_VALUE, "bad handle %x\n", result);
     result = GetPrivateProfileIntA("StartupInfoA", "hStdOutput", 0, resfile);
@@ -3204,9 +3123,7 @@ static void test_SuspendProcessNewThread(void)
         CloseHandle(thread_handle);
 
     TerminateProcess(pi.hProcess, 0);
-    WaitForSingleObject(pi.hProcess, 10000);
-    CloseHandle(pi.hProcess);
-    CloseHandle(pi.hThread);
+    wait_and_close_child_process(&pi);
 }
 
 static void test_SuspendProcessState(void)
@@ -3403,9 +3320,7 @@ static void test_SuspendProcessState(void)
 
     CloseHandle(server_pipe_handle);
     TerminateProcess(pi.hProcess, 0);
-    WaitForSingleObject(pi.hProcess, 10000);
-    CloseHandle(pi.hProcess);
-    CloseHandle(pi.hThread);
+    wait_and_close_child_process(&pi);
 }
 #else
 static void test_SuspendProcessNewThread(void)
@@ -3452,8 +3367,9 @@ static void test_DetachStdHandles(void)
     SetStdHandle(STD_ERROR_HANDLE, hstderr);
 
     ok(res, "CreateProcess failed\n");
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+    wait_and_close_child_process(&info);
+
+    reload_child_info(resfile);
     okChildInt("StartupInfoA", "hStdInput", (UINT)INVALID_HANDLE_VALUE);
     okChildInt("StartupInfoA", "hStdOutput", (UINT)INVALID_HANDLE_VALUE);
     okChildInt("StartupInfoA", "hStdError", (UINT)INVALID_HANDLE_VALUE);
@@ -3930,9 +3846,7 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
         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);
+        wait_and_close_child_process(&info);
 #endif
         si.lpAttributeList = heap_alloc(size);
         ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
@@ -3944,9 +3858,7 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
         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);
+        wait_and_close_child_process(&info);
         CloseHandle(handle);
         pDeleteProcThreadAttributeList(si.lpAttributeList);
         heap_free(si.lpAttributeList);
@@ -3992,11 +3904,7 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
         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);
-        }
+            wait_and_close_child_process(&info);
         pDeleteProcThreadAttributeList(si.lpAttributeList);
         heap_free(si.lpAttributeList);
 
@@ -4027,10 +3935,7 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
         ret = WriteFile(write_pipe, &parent_data, sizeof(parent_data), &size, NULL);
     }
 
-    /* wait for child to terminate */
-    ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
-    CloseHandle(info.hThread);
-    CloseHandle(info.hProcess);
+    wait_and_close_child_process(&info);
 
     if (!level)
     {
-- 
2.20.1



More information about the wine-devel mailing list