void\r
EnumNICs3_free (struct EnumNICs3_results *r)\r
{\r
- GNUNET_free (r);\r
+ GNUNET_free_non_null (r);\r
}\r
\r
\r
return ret;\r
}\r
\r
+/**
+ * Terminate a process by creating a remote thread within it,
+ * which proceeds to call ExitProcess() inside that process.
+ * Safer than TerminateProcess ().
+ *
+ * Code is from From http://private-storm.de/2009/08/11/case-terminateprocess/
+ *
+ * @param hProcess handle of a process to terminate
+ * @param uExitCode exit code to use for ExitProcess()
+ * @param dwTimeout number of ms to wait for the process to terminate
+ * @return TRUE on success, FALSE on failure (check last error for the code)
+ */
+BOOL\r
+SafeTerminateProcess (HANDLE hProcess, UINT uExitCode, DWORD dwTimeout)\r
+{\r
+ DWORD dwTID, dwCode, dwErr = 0;\r
+ HANDLE hProcessDup = INVALID_HANDLE_VALUE;\r
+ HANDLE hRT = NULL;\r
+ HINSTANCE hKernel = GetModuleHandle ("Kernel32");\r
+ BOOL bSuccess = FALSE;\r
+\r
+ BOOL bDup = DuplicateHandle (GetCurrentProcess (), hProcess,\r
+ GetCurrentProcess (), &hProcessDup, PROCESS_ALL_ACCESS,\r
+ FALSE, 0);\r
+\r
+ /* Detect the special case where the process is\r
+ * already dead...\r
+ */\r
+ if (GetExitCodeProcess (bDup ? hProcessDup : hProcess, &dwCode) &&\r
+ (STILL_ACTIVE == dwCode))\r
+ {\r
+ FARPROC pfnExitProc;\r
+\r
+ pfnExitProc = GetProcAddress (hKernel, "ExitProcess");\r
+\r
+ hRT = CreateRemoteThread ((bDup) ? hProcessDup : hProcess, NULL, 0,\r
+ (LPTHREAD_START_ROUTINE) pfnExitProc, (PVOID) uExitCode, 0, &dwTID);\r
+\r
+ dwErr = GetLastError ();\r
+ }\r
+ else\r
+ {\r
+ dwErr = ERROR_PROCESS_ABORTED;\r
+ }\r
+\r
+ if (hRT)\r
+ {\r
+ /* Must wait process to terminate to\r
+ * guarantee that it has exited...\r
+ */\r
+ DWORD dwWaitResult = WaitForSingleObject ((bDup) ? hProcessDup : hProcess,\r
+ dwTimeout);\r
+ if (dwWaitResult == WAIT_TIMEOUT)\r
+ dwErr = WAIT_TIMEOUT;\r
+ else\r
+ dwErr = GetLastError ();\r
+\r
+ CloseHandle (hRT);\r
+ bSuccess = dwErr == NO_ERROR;\r
+ }\r
+\r
+ if (bDup)\r
+ CloseHandle (hProcessDup);\r
+\r
+ SetLastError (dwErr);\r
+\r
+ return bSuccess;\r
+}
+\r
} /* extern "C" */\r
\r
#endif\r