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;
}