Exemplo n.º 1
0
void
MSWindowsWatchdog::startProcess()
{
	if (m_command.empty()) {
		throw XMSWindowsWatchdogError("cannot start process, command is empty");
	}

	m_commandChanged = false;

	if (m_processRunning) {
		LOG((CLOG_DEBUG "closing existing process to make way for new one"));
		shutdownProcess(m_processInfo.hProcess, m_processInfo.dwProcessId, 20);
		m_processRunning = false;
	}

	m_session.updateActiveSession();

	SECURITY_ATTRIBUTES sa;
	ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));

	getActiveDesktop(&sa);

	ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
	HANDLE userToken = getUserToken(&sa);
	m_autoElevated = false;

	// patch by Jack Zhou and Henry Tung
	// set UIAccess to fix Windows 8 GUI interaction
	// http://synergy-project.org/spit/issues/details/3338/#c70
	DWORD uiAccess = 1;
	SetTokenInformation(userToken, TokenUIAccess, &uiAccess, sizeof(DWORD));

	BOOL createRet = doStartProcess(m_command, userToken, &sa);

	if (!createRet) {
		LOG((CLOG_ERR "could not launch"));
		DWORD exitCode = 0;
		GetExitCodeProcess(m_processInfo.hProcess, &exitCode);
		LOG((CLOG_ERR "exit code: %d", exitCode));
		throw XArch(new XArchEvalWindows);
	}
	else {
		// wait for program to fail.
		ARCH->sleep(1);
		if (!isProcessActive()) {
			throw XMSWindowsWatchdogError("process immediately stopped");
		}

		m_processRunning = true;
		m_processFailures = 0;

		LOG((CLOG_DEBUG "started process, session=%i, command=%s",
			m_session.getActiveSessionId(), m_command.c_str()));
	}
}
Exemplo n.º 2
0
bool ZoneAdminRpcMethod::duplicateProcess(const char*     command,
                                        XmlRpcResponse& response,
                                        ExecutionStatus& status
                                       )
{
   bool result = false;

   if (isProcessActive(command))
   {
      // process already found running.  set found to true.
      UtlString faultMsg;

      faultMsg.append("Duplicate process '");
      faultMsg.append(command);
      faultMsg.append("' found");
      response.setFault(ZoneAdminRpcMethod::DuplicateInstance, faultMsg.data());
      status = XmlRpcMethod::FAILED;
      result = true;
   }

   return result;
}
Exemplo n.º 3
0
void
MSWindowsWatchdog::mainLoop(void*)
{
	shutdownExistingProcesses();

	SendSas sendSasFunc = NULL;
	HINSTANCE sasLib = LoadLibrary("sas.dll");
	if (sasLib) {
		LOG((CLOG_DEBUG "found sas.dll"));
		sendSasFunc = (SendSas)GetProcAddress(sasLib, "SendSAS");
	}

	SECURITY_ATTRIBUTES saAttr; 
	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
	saAttr.bInheritHandle = TRUE; 
	saAttr.lpSecurityDescriptor = NULL; 

	if (!CreatePipe(&m_stdOutRead, &m_stdOutWrite, &saAttr, 0)) {
		throw XArch(new XArchEvalWindows());
	}

	ZeroMemory(&m_processInfo, sizeof(PROCESS_INFORMATION));

	while (m_monitoring) {
		try {

			if (m_processRunning && getCommand().empty()) {
				LOG((CLOG_INFO "process started but command is empty, shutting down"));
				shutdownExistingProcesses();
				m_processRunning = false;
				continue;
			}

			if (m_processFailures != 0) {
				// increasing backoff period, maximum of 10 seconds.
				int timeout = (m_processFailures * 2) < 10 ? (m_processFailures * 2) : 10;
				LOG((CLOG_INFO "backing off, wait=%ds, failures=%d", timeout, m_processFailures));
				ARCH->sleep(timeout);
			}
		
			if (!getCommand().empty() && ((m_processFailures != 0) || m_session.hasChanged() || m_commandChanged)) {
				startProcess();
			}

			if (m_processRunning && !isProcessActive()) {

				m_processFailures++;
				m_processRunning = false;
			
				LOG((CLOG_WARN "detected application not running, pid=%d",
					m_processInfo.dwProcessId));
			}

			if (sendSasFunc != NULL) {

				HANDLE sendSasEvent = CreateEvent(NULL, FALSE, FALSE, "Global\\SendSAS");
				if (sendSasEvent != NULL) {

					// use SendSAS event to wait for next session (timeout 1 second).
					if (WaitForSingleObject(sendSasEvent, 1000) == WAIT_OBJECT_0) {
						LOG((CLOG_DEBUG "calling SendSAS"));
						sendSasFunc(FALSE);
					}

					CloseHandle(sendSasEvent);
					continue;
				}
			}

			// if the sas event failed, wait by sleeping.
			ARCH->sleep(1);
		
		}
		catch (std::exception& e) {
			LOG((CLOG_ERR "failed to launch, error: %s", e.what()));
			m_processFailures++;
			m_processRunning = false;
			continue;
		}
		catch (...) {
			LOG((CLOG_ERR "failed to launch, unknown error."));
			m_processFailures++;
			m_processRunning = false;
			continue;
		}
	}

	if (m_processRunning) {
		LOG((CLOG_DEBUG "terminated running process on exit"));
		shutdownProcess(m_processInfo.hProcess, m_processInfo.dwProcessId, 20);
	}
	
	LOG((CLOG_DEBUG "watchdog main thread finished"));
}
Exemplo n.º 4
0
bool SwAdminRpcExecStatus::execute(const HttpRequestContext& requestContext,
                                 UtlSList&                 params,
                                 void*                     userData,
                                 XmlRpcResponse&           response,
                                 ExecutionStatus&          status)
{

   bool result = false;
   status = XmlRpcMethod::FAILED;

   if (2 != params.entries())
   {
      handleExtraExecuteParam(name(), response, status);
   }
   else
   {
      if (!params.at(0) || !params.at(0)->isInstanceOf(UtlString::TYPE))
      {
         handleMissingExecuteParam(name(), PARAM_NAME_CALLING_HOST, response, status);
      }
      else
      {
         UtlString* pCallingHostname = dynamic_cast<UtlString*>(params.at(0));
         SipxRpc* pSipxRpcImpl = ((SipxRpc *)userData);

         if (!params.at(1) || !params.at(1)->isInstanceOf(UtlString::TYPE))
         {
            handleMissingExecuteParam(name(), PARAM_NAME_COMMAND, response, status);
         }
         else
         {
            if (validCaller(requestContext, *pCallingHostname, response, *pSipxRpcImpl, name()))
            {
               UtlString* query = dynamic_cast<UtlString*>(params.at(1));
               UtlString processName;

               // Make sure that the query is valid
               if (isQueryValid(*query, processName))
               {
                  UtlString stat;

                  if (isProcessActive(processName))
                  {
                     stat = PROCESS_RUNNING;
                  }
                  else
                  {
                     stat = PROCESS_NOT_RUNNING;
                  }

                  response.setResponse(&stat);
                  status = XmlRpcMethod::OK;
                  result = true;

               } // wrong Query String
               else
               {
                  // Failed to launch the command, send a fault.
                  response.setFault(SwAdminRpcMethod::FailureToLaunch, "Invalid query");
                  status = XmlRpcMethod::FAILED;
               }
            }  // validcaller
            else
            {
               status = XmlRpcMethod::FAILED;
            }
         }  // param 1 okay
      }  // param 0 okay
   } //number of parms check

   return result;
}