static BOOL __apxProcessClose()

in src/native/windows/src/rprocess.c [422:502]


static BOOL __apxProcessClose(APXHANDLE hProcess)
{
    LPAPXPROCESS lpProc;
    DYNLOAD_FPTR_DECLARE(CreateRemoteThread);
    DYNLOAD_FPTR_DECLARE(ExitProcess);

    UINT    uExitCode = CHILD_TERMINATE_CODE; /* Could be any value like my birthday ;-)*/
    HANDLE  hDup, hRemote;

    lpProc = APXHANDLE_DATA(hProcess);
    CHECK_IF_ACTIVE(lpProc);

    /* dry run to get debug information */
    apxProcessTerminateChild(lpProc->stProcInfo.dwProcessId, TRUE);
    /* Try to close the child's stdin first */
    SAFE_CLOSE_HANDLE(lpProc->hChildInpWr);
    /* Wait 1 sec for child process to
     * recognize that the stdin has been closed.
     */
    if (WaitForSingleObject(lpProc->stProcInfo.hProcess, 1000) == WAIT_OBJECT_0) {
        apxLogWrite(APXLOG_MARK_DEBUG "__apxProcessClose Gone(input)");
        goto cleanup;
    }

    CHECK_IF_ACTIVE(lpProc);

    /* Try to create the remote thread in the child address space */
    DYNLOAD_FPTR_ADDRESS(CreateRemoteThread, KERNEL32);
    if (DuplicateHandle(lpProc->hCurrentProcess,
                        lpProc->stProcInfo.hProcess,
                        lpProc->hCurrentProcess,
                        &hDup,
                        PROCESS_ALL_ACCESS,
                        FALSE, 0)) {
        DYNLOAD_FPTR_ADDRESS(ExitProcess, KERNEL32);
        /* Now call the ExitProcess from inside the client
         * This will safely unload all the dll's.
         */
        hRemote = DYNLOAD_CALL(CreateRemoteThread)(hDup,
                                NULL, 0,
                                (LPTHREAD_START_ROUTINE)DYNLOAD_FPTR(ExitProcess),
                                (PVOID)&uExitCode, 0, NULL);
        if (!IS_INVALID_HANDLE(hRemote)) {
            if (WaitForSingleObject(lpProc->stProcInfo.hProcess,
                    2000) == WAIT_OBJECT_0) {
                DWORD status;
                if (!GetExitCodeProcess(lpProc->stProcInfo.hProcess, &status) ||
                                (status != STILL_ACTIVE)) {
                     apxLogWrite(APXLOG_MARK_DEBUG "__apxProcessClose Gone(thread exit)");
                     /* We are here when the service starts something like wildfly via standalone.sh and wildfly doesn't terminate cleanly, 
                      * dry run is FALSE: we kill all the process of the process tree
                      */
                     apxProcessTerminateChild(lpProc->stProcInfo.dwProcessId, FALSE);
                }


            }
            else {
		apxLogWrite(APXLOG_MARK_DEBUG "__apxProcessClose thread exit failed, terminate!");
                TerminateProcess(lpProc->stProcInfo.hProcess, CHILD_TERMINATE_CODE);
                // __apxProcessTerminateChild ?
            }
            CloseHandle(hRemote);
        } else {
            apxLogWrite(APXLOG_MARK_DEBUG "__apxProcessClose thread exit not usuable...");
	}
        CloseHandle(hDup);
        apxLogWrite(APXLOG_MARK_DEBUG "__apxProcessClose Done?");
        goto cleanup;
    }

    apxLogWrite(APXLOG_MARK_DEBUG "__apxProcessClose terminate!");
    TerminateProcess(lpProc->stProcInfo.hProcess, CHILD_TERMINATE_CODE);
    // __apxProcessTerminateChild ?

cleanup:
     /* Close the process handle */
    SAFE_CLOSE_HANDLE(lpProc->stProcInfo.hProcess);
    lpProc->dwChildStatus &= ~CHILD_RUNNING;
    return TRUE;
}