bool ActivePet::ownsProcess(HANDLE process) {
	BOOL result;
	if (!IsProcessInJob(process, m_job.get(), &result)) {
        printf("IsProcessInJob() failed: %d", GetLastError());
	}
    return result ? true : false;
}
Example #2
0
/* FIXME */
g_val_t
proc_run_func( void )
{
   DWORD aProcesses[MAXPROCESSES], cbNeeded, cProcesses;
   unsigned int i, running = 0;
   HANDLE hProcess;
   BOOL bResult;
   g_val_t val;

   if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) {
      cProcesses = 0;
   } else {
      cProcesses = cbNeeded / sizeof(DWORD);
   }
#if (_WIN32_WINNT >= 0x0501)
   /* Only for XP or newer */
   for (i = 0; i < cProcesses; i++)
      if (aProcesses[i] != 0) {
         hProcess = OpenProcess (PROCESS_QUERY_INFORMATION, 
            FALSE, aProcesses[i]);
         if (hProcess != NULL) {
            if (IsProcessInJob(hProcess, NULL, &bResult)) {
               if (bResult)
                  running++;
            }
            CloseHandle(hProcess);
         }
      }
#endif

   val.uint32 = running;

   return val;
}
void
CPCD::Process::stop() {

  char filename[PATH_MAX*2+1];
  BaseString::snprintf(filename, sizeof(filename), "%d", m_id);
  unlink(filename);

  if (is_bad_pid(m_pid))
  {
    logger.critical("Stopping process with bogus pid: %d id: %d", 
                   m_pid, m_id);
    return;
  }

  m_status = STOPPING;

#ifndef _WIN32
  errno = 0;
  int signo= SIGTERM;
  if(m_shutdown_options == "SIGKILL")
    signo= SIGKILL;

  int ret = kill(-m_pid, signo);
  switch(ret) {
  case 0:
    logger.debug("Sent SIGTERM to pid %d", (int)-m_pid);
    break;
  default:
    logger.debug("kill pid: %d : %s", (int)-m_pid, strerror(errno));
    break;
  }
  
  if(isRunning()){
    errno = 0;
    ret = kill(-m_pid, SIGKILL);
    switch(ret) {
    case 0:
      logger.debug("Sent SIGKILL to pid %d", (int)-m_pid);
      break;
    default:
      logger.debug("kill pid: %d : %s\n", (int)-m_pid, strerror(errno));
      break;
    }
  } 
#else
  if(isRunning())
  {
    BOOL truth;
    HANDLE proc;
    require(proc = OpenProcess(PROCESS_QUERY_INFORMATION, 0, m_pid));
    require(IsProcessInJob(proc, m_job,  &truth));
    require(truth == TRUE);
    require(CloseHandle(proc));
    // Terminate process with exit code 37
    require(TerminateJobObject(m_job, 37));
    require(CloseHandle(m_job));
  }
#endif

  m_pid = bad_pid;
  m_status = STOPPED;
}
Example #4
0
int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) 
{
   /* Check if we are not already associated with a job.
    * If this is the case, there is no way to switch to
    * another job.
	*/
   BOOL bInJob = FALSE;
   IsProcessInJob(GetCurrentProcess(), NULL, &bInJob);
   if (bInJob) 
   {
      MessageBox(
		  NULL, 
		  TEXT("Process already in a job"), 
          TEXT(""), 
		  MB_ICONINFORMATION | MB_OK);

      return(-1);
   }

   /* Create the completion port that receives job notifications 
    * Creates an input/output (I/O) completion port 
	* and associates it with a specified file handle, 
	* or creates an I/O completion port that is not 
	* yet associated with a file handle, allowing association at a later time.
    * 
	*  Associating an instance of an opened file handle with an I/O completion 
	*  port allows a process to receive notification of the completion 
	*  of asynchronous I/O operations involving that file handle.
	*
    * FileHandle [in] 
    *   An open file handle or INVALID_HANDLE_VALUE.
    *   The handle must be to an object that supports overlapped I/O.
    *   If a handle is provided, it has to have been opened 
	*   for overlapped I/O completion. 
	*   For example, you must specify the FILE_FLAG_OVERLAPPED flag
	*   when using the CreateFile function to obtain the handle.
	*
    *   If INVALID_HANDLE_VALUE is specified, 
	*   the function creates an I/O completion port without associating it 
	*   with a file handle. In this case, the ExistingCompletionPort parameter 
	*   must be NULL and the CompletionKey parameter is ignored.
    * 
	* ExistingCompletionPort [in, optional] 
    *   A handle to an existing I/O completion port or NULL.
    *   If this parameter is NULL, the function creates a new I/O completion port and, 
	*   if the FileHandle parameter is valid, associates it with the new I/O completion port. 
	*   Otherwise no file handle association occurs. 
	*   The function returns the handle to the new I/O completion port if successful.
	*  
	*  
    */
   g_hIOCP = CreateIoCompletionPort(
	   INVALID_HANDLE_VALUE, 
	   NULL, 
	   0, 
	   0);

   /* Create a thread that waits on the completion port */
   g_hThreadIOCP = chBEGINTHREADEX(
	   NULL, 
	   0, 
	   JobNotify, 
	   NULL, 
	   0, 
	   NULL);

   /* Create the job object */
   g_job.Create(NULL, TEXT("JobLab"));
   g_job.SetEndOfJobInfo(JOB_OBJECT_POST_AT_END_OF_JOB);
   g_job.AssociateCompletionPort(g_hIOCP, COMPKEY_JOBOBJECT);

   DialogBox(hinstExe, MAKEINTRESOURCE(IDD_JOBLAB), NULL, Dlg_Proc);

   /* Post a special key that tells the completion port thread to terminate 
    * Posts an I/O completion packet to an I/O completion port.
	*
	* CompletionPort [in] 
    *   A handle to an I/O completion port to which 
	*   the I/O completion packet is to be posted.
    * 
	* dwNumberOfBytesTransferred [in] 
    *   The value to be returned through the lpNumberOfBytesTransferred 
	*   parameter of the GetQueuedCompletionStatus function.
    *
	* dwCompletionKey [in] 
    *   The value to be returned through the lpCompletionKey parameter 
	*   of the GetQueuedCompletionStatus function.
    * 
	* lpOverlapped [in, optional] 
    *   The value to be returned through the lpOverlapped parameter 
	*   of the GetQueuedCompletionStatus function.
    *
    */
   PostQueuedCompletionStatus(g_hIOCP, 0, COMPKEY_TERMINATE, NULL);

   /* Wait for the completion port thread to terminate */
   WaitForSingleObject(g_hThreadIOCP, INFINITE);
   
   // Clean up everything properly
   CloseHandle(g_hIOCP);
   CloseHandle(g_hThreadIOCP);

   // NOTE: The job is closed when the g_job's destructor is called.
   return(0);
}
HRESULT CNodeApplicationManager::Initialize(IHttpContext* context)
{
	HRESULT hr;
	BOOL isInJob, createJob;
	JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo;

	if (this->initialized)
	{
		return S_OK;
	}

	ErrorIf(NULL == (this->eventProvider = new CNodeEventProvider()), ERROR_NOT_ENOUGH_MEMORY);
	CheckError(this->eventProvider->Initialize());
	ErrorIf(NULL != this->asyncManager, ERROR_INVALID_OPERATION);
	ErrorIf(NULL == (this->asyncManager = new CAsyncManager()), ERROR_NOT_ENOUGH_MEMORY);
	CheckError(this->asyncManager->Initialize(context));
	ErrorIf(NULL == (this->fileWatcher = new CFileWatcher()), ERROR_NOT_ENOUGH_MEMORY);
	CheckError(this->fileWatcher->Initialize(context));

	// determine whether node processes should be created in a new job object
	// or whether current job object is adequate; the goal is to kill node processes when
	// the IIS worker process is killed while preserving current job limits, if any
	
	ErrorIf(!IsProcessInJob(GetCurrentProcess(), NULL, &isInJob), HRESULT_FROM_WIN32(GetLastError()));
	if (!isInJob)
	{
		createJob = TRUE;
	}
	else
	{
		ErrorIf(!QueryInformationJobObject(NULL, JobObjectExtendedLimitInformation, &jobInfo, sizeof jobInfo, NULL), 
			HRESULT_FROM_WIN32(GetLastError()));

        if (jobInfo.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK )
        {
            createJob = TRUE;
        }
        else if(jobInfo.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE )
        {
            createJob = FALSE;
        }
        else if(jobInfo.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_BREAKAWAY_OK )
        {
            createJob = TRUE;
			this->breakAwayFromJobObject = TRUE;
        }
        else
        {
            createJob = TRUE;
        }
	}

	if (createJob)
	{
		ErrorIf(NULL == (this->jobObject = CreateJobObject(NULL, NULL)), HRESULT_FROM_WIN32(GetLastError()));
		RtlZeroMemory(&jobInfo, sizeof jobInfo);
		jobInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
		ErrorIf(!SetInformationJobObject(this->jobObject, JobObjectExtendedLimitInformation, &jobInfo, sizeof jobInfo), 
			HRESULT_FROM_WIN32(GetLastError()));
	}

	this->initialized = TRUE;

	this->GetEventProvider()->Log(L"iisnode initialized the application manager", WINEVENT_LEVEL_INFO);

	return S_OK;
Error:

	this->GetEventProvider()->Log(L"iisnode failed to initialize the application manager", WINEVENT_LEVEL_ERROR);

	if (NULL != this->asyncManager)
	{
		delete this->asyncManager;
		this->asyncManager = NULL;
	}

	if (NULL != this->jobObject)
	{
		CloseHandle(this->jobObject);
		this->jobObject = NULL;
	}

	if (NULL != this->fileWatcher)
	{
		delete this->fileWatcher;
		this->fileWatcher = NULL;
	}

	return hr;
}