Не работает безопасное завершение дочерних процессов на C++
Необходимо завершать процесс и все его дочерние процессы в программе на Microsoft Visual C++
Используется немного измененный код.
Функция SafeTerminateProcess для безопасного завершения процесса по этой ссылке.
http://hyacinth.byus.net/moniwiki/wi...rminateProcess
И функция KillProcessTree для рекурсивного завершения дочерних процессов по этой ссылке:
http://www.cyberforum.ru/cpp-builder/thread1202071.html
Если не удается завершить процесс с помощью функции SafeTerminateProcess, завершаю его с помощью функции TerminateProcess.
Завершение процессов работает, но для дочерних процессов отладка показывает, что в большинстве случаев не работает функция SafeTerminateProcess, и в результате вызывается функция TerminateProcess. Для основного процесса SafeTerminateProcess всегда работает.
Появляется одна из двух ошибок (если не было первой, в большинстве случаев появляется вторая).
Функция GetExitCodeProcess получает ExitCode для дочернего процесса, равный нулю.
Или бывает вторая ошибка hRT == null с ошибкой код 0x5 - Access Denied.
Если сделать следующий код, вместо нее появляется ошибка Error unknown revision 0x519
Код:
PSECURITY_DESCRIPTOR pSD;
pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR,
SECURITY_DESCRIPTOR_MIN_LENGTH);
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof (SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = TRUE;
hRT = CreateRemoteThread((bDup) ? hProcessDup : hProcess,
&sa,
0,
(LPTHREAD_START_ROUTINE)pfnExitProc,
(PVOID)uExitCode, 0, &dwTID);
Если делать несколько попыток заврешения того же процесса с помощью SafeTerminateProcess, это не помогает. Можно ли исправить эти 2 ошибки и сделать, чтобы функция SafeTerminateProcess всегда завершала дочерние процессы?
Код:
BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode)
{
DWORD dwTID, dwCode, dwErr = 0;
HANDLE hProcessDup = INVALID_HANDLE_VALUE;
HANDLE hRT = NULL;
HINSTANCE hKernel = GetModuleHandle(_T("kernel32"));
BOOL bSuccess = FALSE;
BOOL bDup = DuplicateHandle(GetCurrentProcess(),
hProcess,
GetCurrentProcess(),
&hProcessDup,
PROCESS_ALL_ACCESS,
FALSE,
0);
if (GetExitCodeProcess((bDup) ? hProcessDup : hProcess, &dwCode) &&
(dwCode == STILL_ACTIVE))
{
FARPROC pfnExitProc;
pfnExitProc = GetProcAddress(hKernel, "ExitProcess");
hRT = CreateRemoteThread((bDup) ? hProcessDup : hProcess,
NULL,
0,
(LPTHREAD_START_ROUTINE)pfnExitProc,
(PVOID)uExitCode, 0, &dwTID);
if (hRT == NULL) dwErr = GetLastError();
}
else
{
dwErr = ERROR_PROCESS_ABORTED;
}
if (hRT)
{
WaitForSingleObject((bDup) ? hProcessDup : hProcess, (DWORD)
10);
CloseHandle(hRT);
bSuccess = TRUE;
}
if (bDup)
CloseHandle(hProcessDup);
if (!bSuccess)
SetLastError(dwErr);
return bSuccess;
}
bool KillProcessTree(DWORD myprocID, DWORD dwTimeout)
{
bool bRet = true;
HANDLE hWnd;
PROCESSENTRY32 pe;
memset(&pe, 0, sizeof(PROCESSENTRY32));
pe.dwSize = sizeof(PROCESSENTRY32);
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (Process32First(hSnap, &pe))
{
BOOL bContinue = TRUE;
while (bContinue)
{
if (pe.th32ParentProcessID == myprocID)
{
KillProcessTree(pe.th32ProcessID, dwTimeout);
HANDLE hChildProc = OpenProcess
(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
if (hChildProc)
{
if (WaitForSingleObject(hChildProc,
dwTimeout) == WAIT_OBJECT_0)
bRet = true;
else
{
bRet =
SafeTerminateProcess(hChildProc, 0);
if (!bRet)
bRet =
TerminateProcess(hChildProc, 0);
}
CloseHandle(hChildProc);
}
}
bContinue = Process32Next(hSnap, &pe);
}
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE,
myprocID);
if (hProc)
{
if (!SafeTerminateProcess(hProc, 0))
TerminateProcess(hProc, 0);
CloseHandle(hProc);
}
}
return bRet;
}
|