//
//   FUNCTION: CServiceBase::Start(DWORD, PWSTR *)
//
//   PURPOSE: The function starts the service. It calls the OnStart virtual 
//   function in which you can specify the actions to take when the service 
//   starts. If an error occurs during the startup, the error will be logged 
//   in the Application event log, and the service will be stopped.
//
//   PARAMETERS:
//   * dwArgc   - number of command line arguments
//   * lpszArgv - array of command line arguments
//
void CServiceBase::Start(DWORD dwArgc, PWSTR *pszArgv)
{
    WriteEventLogEntry(L"Service starting.", TRACE_LEVEL_ERROR);
    try
    {
        // Tell SCM that the service is starting.
        SetServiceStatus(SERVICE_START_PENDING);

        // Perform service-specific initialization.
        OnStart(dwArgc, pszArgv);

        // Tell SCM that the service is started.
        SetServiceStatus(SERVICE_RUNNING);
    }
    catch (DWORD dwError)
    {
        // Log the error.
        WriteErrorLogEntry(L"Service failed to start.", dwError);

        // Set the service status to be stopped.
        SetServiceStatus(SERVICE_STOPPED, dwError);
    }
    catch (...)
    {
        // Log the error.
        WriteEventLogEntry(L"Service failed to start.", TRACE_LEVEL_ERROR);

        // Set the service status to be stopped.
        SetServiceStatus(SERVICE_STOPPED);
    }
}
void ZeroTierOneService::threadMain()
throw()
{
    ZT_SVCDBG("ZeroTierOneService::threadMain()\r\n");

restart_node:
    try {
        {
            ZeroTier::Mutex::Lock _l(_lock);
            delete _service;
            _service = (ZeroTier::OneService *)0; // in case newInstance() fails
            _service = ZeroTier::OneService::newInstance(
                           ZeroTier::OneService::platformDefaultHomePath().c_str(),
                           ZT_DEFAULT_PORT);
        }
        switch(_service->run()) {
        case ZeroTier::OneService::ONE_UNRECOVERABLE_ERROR: {
            std::string err("ZeroTier One encountered an unrecoverable error: ");
            err.append(_service->fatalErrorMessage());
            err.append(" (restarting in 5 seconds)");
            WriteEventLogEntry(const_cast <PSTR>(err.c_str()),EVENTLOG_ERROR_TYPE);
            Sleep(5000);
        }
        goto restart_node;

        case ZeroTier::OneService::ONE_IDENTITY_COLLISION: {
            std::string homeDir(ZeroTier::OneService::platformDefaultHomePath());
            delete _service;
            _service = (ZeroTier::OneService *)0;
            std::string oldid;
            ZeroTier::OSUtils::readFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str(),oldid);
            if (oldid.length()) {
                ZeroTier::OSUtils::writeFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret.saved_after_collision").c_str(),oldid);
                ZeroTier::OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str());
                ZeroTier::OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.public").c_str());
            }
        }
        goto restart_node;

        default: // normal termination
            break;
        }
    } catch ( ... ) {
        // sanity check, shouldn't happen since Node::run() should catch all its own errors
        // could also happen if we're out of memory though!
        WriteEventLogEntry("unexpected exception (out of memory?) (trying again in 5 seconds)",EVENTLOG_ERROR_TYPE);
        Sleep(5000);
        goto restart_node;
    }

    {
        ZeroTier::Mutex::Lock _l(_lock);
        delete _service;
        _service = (ZeroTier::OneService *)0;
    }
}
Ejemplo n.º 3
0
void SessionServer::OnSessionEmpty(const XSessionConstPtr& session)
{
	// Hold the lock during callbacks from the sessions, which run in their own threads 
	ScopedLock lock(m_mutex);

	XT_UNREFERENCED_PARAM(session);

	// Log a service stop message to the Application log.
	WriteEventLogEntry(L"Sharing Service session empty", EVENTLOG_INFORMATION_TYPE);

	if (session->GetType() == SessionType::ADHOC)
	{
		// Find the session in the list
		for (size_t i = 0; i < m_sessions.size(); ++i)
		{
			if (m_sessions[i] == session)
			{
				uint32 sessionID = session->GetId();

				// Queue the sessions the be deleted on the server's thread
				m_sessionsPendingDeletion.push_back(m_sessions[i]);

				// Erase the session from the list
				m_sessionChangeListener.erase(m_sessionChangeListener.find(m_sessions[i]));
				m_sessions.erase(m_sessions.begin() + i);
				
				// Notify the clients that the session has closed
				SessionClosedMsg closedMsg(sessionID);
				SendSessionMessageToAllClients(closedMsg.ToJSONString());

				break;
			}
		}
	}
}
//
//   FUNCTION: CSampleService::OnStop(void)
//
//   PURPOSE: The function is executed when a Stop command is sent to the 
//   service by SCM. It specifies actions to take when a service stops 
//   running. In this code sample, OnStop logs a service-stop message to the 
//   Application log, and waits for the finish of the main service function.
//
//   COMMENTS:
//   Be sure to periodically call ReportServiceStatus() with 
//   SERVICE_STOP_PENDING if the procedure is going to take long time. 
//
void CSampleService::OnStop()
{
    // Log a service stop message to the Application log.
    WriteEventLogEntry(L"CppWindowsService in OnStop", 
        EVENTLOG_INFORMATION_TYPE);
	ProcessHelper::SendCtrlC();
}
//
//   FUNCTION: CSampleService::OnStart(DWORD, LPWSTR *)
//
//   PURPOSE: The function is executed when a Start command is sent to the 
//   service by the SCM or when the operating system starts (for a service 
//   that starts automatically). It specifies actions to take when the 
//   service starts. In this code sample, OnStart logs a service-start 
//   message to the Application log, and queues the main service function for 
//   execution in a thread pool worker thread.
//
//   PARAMETERS:
//   * dwArgc   - number of command line arguments
//   * lpszArgv - array of command line arguments
//
//   NOTE: A service application is designed to be long running. Therefore, 
//   it usually polls or monitors something in the system. The monitoring is 
//   set up in the OnStart method. However, OnStart does not actually do the 
//   monitoring. The OnStart method must return to the operating system after 
//   the service's operation has begun. It must not loop forever or block. To 
//   set up a simple monitoring mechanism, one general solution is to create 
//   a timer in OnStart. The timer would then raise events in your code 
//   periodically, at which time your service could do its monitoring. The 
//   other solution is to spawn a new thread to perform the main service 
//   functions, which is demonstrated in this code sample.
//
void CSampleService::OnStart(DWORD dwArgc, PWSTR *lpszArgv)
{
    // Log a service start message to the Application log.
    WriteEventLogEntry(L"CppWindowsService in OnStart", EVENTLOG_INFORMATION_TYPE);
	// Launch external process
	ProcessHelper::CreateConsoleProcess();
}
//
//   FUNCTION: CServiceBase::Continue()
//
//   PURPOSE: The function resumes normal functioning after being paused if
//   the service supports pause and continue. It calls the OnContinue virtual 
//   function in which you can specify the actions to take when the service 
//   continues. If an error occurs, the error will be logged in the 
//   Application event log, and the service will still be paused.
//
void CServiceBase::Continue()
{
    try
    {
        // Tell SCM that the service is resuming.
        SetServiceStatus(SERVICE_CONTINUE_PENDING);

        // Perform service-specific continue operations.
        OnContinue();

        // Tell SCM that the service is running.
        SetServiceStatus(SERVICE_RUNNING);
    }
    catch (DWORD dwError)
    {
        // Log the error.
        WriteErrorLogEntry(L"Service failed to resume.", dwError);

        // Tell SCM that the service is still paused.
        SetServiceStatus(SERVICE_PAUSED);
    }
    catch (...)
    {
        // Log the error.
        WriteEventLogEntry(L"Service failed to resume.", TRACE_LEVEL_ERROR);

        // Tell SCM that the service is still paused.
        SetServiceStatus(SERVICE_PAUSED);
    }
}
//
//   FUNCTION: CServiceBase::Pause()
//
//   PURPOSE: The function pauses the service if the service supports pause 
//   and continue. It calls the OnPause virtual function in which you can 
//   specify the actions to take when the service pauses. If an error occurs, 
//   the error will be logged in the Application event log, and the service 
//   will become running.
//
void CServiceBase::Pause()
{
    try
    {
        // Tell SCM that the service is pausing.
        SetServiceStatus(SERVICE_PAUSE_PENDING);

        // Perform service-specific pause operations.
        OnPause();

        // Tell SCM that the service is paused.
        SetServiceStatus(SERVICE_PAUSED);
    }
    catch (DWORD dwError)
    {
        // Log the error.
        WriteErrorLogEntry(L"Service failed to pause.", dwError);

        // Tell SCM that the service is still running.
        SetServiceStatus(SERVICE_RUNNING);
    }
    catch (...)
    {
        // Log the error.
        WriteEventLogEntry(L"Service failed to pause.", TRACE_LEVEL_ERROR);

        // Tell SCM that the service is still running.
        SetServiceStatus(SERVICE_RUNNING);
    }
}
//
//   FUNCTION: CServiceBase::Stop()
//
//   PURPOSE: The function stops the service. It calls the OnStop virtual 
//   function in which you can specify the actions to take when the service 
//   stops. If an error occurs, the error will be logged in the Application 
//   event log, and the service will be restored to the original state.
//
void CServiceBase::Stop()
{
    DWORD dwOriginalState = m_status.dwCurrentState;
    try
    {
        // Tell SCM that the service is stopping.
        SetServiceStatus(SERVICE_STOP_PENDING);

        // Perform service-specific stop operations.
        OnStop();

        // Tell SCM that the service is stopped.
        SetServiceStatus(SERVICE_STOPPED);
    }
    catch (DWORD dwError)
    {
        // Log the error.
        WriteErrorLogEntry(L"Service failed to stop.", dwError);

        // Set the orginal service status.
        SetServiceStatus(dwOriginalState);
    }
    catch (...)
    {
        // Log the error.
        WriteEventLogEntry(L"Service failed to stop.", TRACE_LEVEL_ERROR);

        // Set the orginal service status.
        SetServiceStatus(dwOriginalState);
    }
}
Ejemplo n.º 9
0
//
//   FUNCTION: ServiceBase::WriteErrorLogEntry(PWSTR, DWORD)
//
//   PURPOSE: Log an error message to the Application event log.
//
//   PARAMETERS:
//   * pszFunction - the function that gives the error
//   * dwError - the error code
//
void ServiceBase::WriteErrorLogEntry(PWSTR pszFunction, DWORD dwError)
{
    wchar_t szMessage[260];
    StringCchPrintf(szMessage, ARRAYSIZE(szMessage), 
        L"%s failed w/err 0x%08lx", pszFunction, dwError);
    WriteEventLogEntry(szMessage, EVENTLOG_ERROR_TYPE);
}
Ejemplo n.º 10
0
//
//   FUNCTION: CServiceBase::WriteErrorLogEntry(PWSTR, DWORD)
//
//   PURPOSE: Log an event.
//
//   PARAMETERS:
//   * pszFunction - the function that gives the error
//   * dwError - the error code
//
void CServiceBase::WriteErrorLogEntry(
    _In_ PWSTR pszFunction,
    _In_ DWORD dwError)
{
    wchar_t szMessage[260];
    StringCchPrintf(szMessage, ARRAYSIZE(szMessage),
        L"%s failed w/err 0x%08lx", pszFunction, dwError);
    WriteEventLogEntry(szMessage, TRACE_LEVEL_ERROR);
}
Ejemplo n.º 11
0
//
//   FUNCTION: CSampleService::OnStart(DWORD, LPWSTR *)
//
//   PURPOSE: The function is executed when a Start command is sent to the 
//   service by the SCM or when the operating system starts (for a service 
//   that starts automatically). It specifies actions to take when the 
//   service starts. In this code sample, OnStart logs a service-start 
//   message to the Application log, and queues the main service function for 
//   execution in a thread pool worker thread.
//
//   PARAMETERS:
//   * dwArgc   - number of command line arguments
//   * lpszArgv - array of command line arguments
//
//   NOTE: A service application is designed to be long running. Therefore, 
//   it usually polls or monitors something in the system. The monitoring is 
//   set up in the OnStart method. However, OnStart does not actually do the 
//   monitoring. The OnStart method must return to the operating system after 
//   the service's operation has begun. It must not loop forever or block. To 
//   set up a simple monitoring mechanism, one general solution is to create 
//   a timer in OnStart. The timer would then raise events in your code 
//   periodically, at which time your service could do its monitoring. The 
//   other solution is to spawn a new thread to perform the main service 
//   functions, which is demonstrated in this code sample.
//
void CSampleService::OnStart(DWORD dwArgc, LPWSTR *lpszArgv)
{
    // Log a service start message to the Application log.
    WriteEventLogEntry(L"CppWindowsService in OnStart", 
        EVENTLOG_INFORMATION_TYPE);

    // Queue the main service function for execution in a worker thread.
    CThreadPool::QueueUserWorkItem(&CSampleService::ServiceWorkerThread, this);
}
Ejemplo n.º 12
0
//
//   FUNCTION: CSampleService::OnStop(void)
//
//   PURPOSE: The function is executed when a Stop command is sent to the 
//   service by SCM. It specifies actions to take when a service stops 
//   running. In this code sample, OnStop logs a service-stop message to the 
//   Application log, and waits for the finish of the main service function.
//
//   COMMENTS:
//   Be sure to periodically call ReportServiceStatus() with 
//   SERVICE_STOP_PENDING if the procedure is going to take long time. 
//
void CSampleService::OnStop()
{
    // Log a service stop message to the Application log.
    WriteEventLogEntry(L"CppWindowsService in OnStop", 
        EVENTLOG_INFORMATION_TYPE);

    // Indicate that the service is stopping and wait for the finish of the 
    // main service function (ServiceWorkerThread).
    m_fStopping = TRUE;
    if (WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0)
    {
        throw GetLastError();
    }
}
Ejemplo n.º 13
0
void SessionServer::OnStop()
{
    LogInfo("**********************************");
    LogInfo("****** Sharing Service OnStop ******");
    LogInfo("**********************************");

	// Log a service stop message to the Application log.
	WriteEventLogEntry(L"Sharing Server stopping", EVENTLOG_INFORMATION_TYPE);

	// Indicate that the service is stopping and wait for the finish of the 
	// main service function (ServerThreadFunc).
	m_stopping = TRUE;
	m_serverThread->WaitForThreadExit();

    TeardownFileLogger();

}
Ejemplo n.º 14
0
//
//   FUNCTION: CServiceBase::Shutdown()
//
//   PURPOSE: The function executes when the system is shutting down. It 
//   calls the OnShutdown virtual function in which you can specify what 
//   should occur immediately prior to the system shutting down. If an error 
//   occurs, the error will be logged in the Application event log.
//
void CServiceBase::Shutdown()
{
    try
    {
        // Perform service-specific shutdown operations.
        OnShutdown();

        // Tell SCM that the service is stopped.
        SetServiceStatus(SERVICE_STOPPED);
    }
    catch (DWORD dwError)
    {
        // Log the error.
        WriteErrorLogEntry(L"Service failed to shut down.", dwError);
    }
    catch (...)
    {
        // Log the error.
        WriteEventLogEntry(L"Service failed to shut down.", TRACE_LEVEL_ERROR);
    }
}
Ejemplo n.º 15
0
void SessionServer::OnStart(DWORD dwArgc, PWSTR *pszArgv)
{
    InitializeFileLogger();

    // Log out an obvious piece of text to help distinguish between server sessions.
    LogInfo("***********************************");
    LogInfo("****** Sharing Service OnStart ******");
    LogInfo("***********************************");

	// Log a service start message to the Application log.
	WriteEventLogEntry(L"Sharing Server starting", EVENTLOG_INFORMATION_TYPE);
	LogInfo("Server Info: \n\tBuild Version: %ls \n\tSchema Version: %i", XTOOLS_VERSION_STRING, kXToolsSchemaVersion);

	// TODO: use different machines, etc, based on command line parameters
	XT_UNREFERENCED_PARAM(dwArgc);
	XT_UNREFERENCED_PARAM(pszArgv);

	// Start listening for new connections
	m_listenerReceipt = m_socketMgr->AcceptConnections(kSessionServerPort, kSessionServerMaxConnections, this);
	LogInfo("Listening for session list connections on port %i of all network devices of the local machine.", kSessionServerPort);
	LogInfo("Local IP addresses are:");

	IPAddressList addressList = m_socketMgr->GetLocalMachineAddresses();
	for (size_t i = 0; i < addressList.size(); ++i)
	{
		LogInfo("\t%s", addressList[i].ToString().c_str());
	}
	
	// Allocate a pool of ports to use for sessions
	m_portPool = new PortPool(kSessionServerPort-1, 256);

	// TODO: Read from a configuration file for persistent sessions. 
	XTVERIFY(CreateNewSession("Default", SessionType::PERSISTENT) != NULL);

	// Start a thread to run the main service logic. 
	m_serverThread = new MemberFuncThread(&SessionServer::ServerThreadFunc, this);
}
Ejemplo n.º 16
0
void ZeroTierOneService::threadMain()
	throw()
{
	ZT_SVCDBG("ZeroTierOneService::threadMain()\r\n");

restart_node:
	try {
		{
			// start or restart
			ZeroTier::Mutex::Lock _l(_lock);
			delete _node;
			_node = new ZeroTier::Node(ZeroTier::ZT_DEFAULTS.defaultHomePath.c_str(),ZT_DEFAULT_UDP_PORT,0,false);
		}
		switch(_node->run()) {
			case ZeroTier::Node::NODE_RESTART_FOR_UPGRADE: {
				// Shut down node
				ZeroTier::Node *n;
				{
				   ZeroTier::Mutex::Lock _l(_lock);
				   n = _node;
				   _node = (ZeroTier::Node *)0;
				}
				std::string msiPath;
				if (n) {
					const char *msiPathTmp = n->reasonForTermination();
					if (msiPathTmp)
						msiPath = msiPathTmp;
				}
				delete n;

				if ((!msiPath.length())||(!ZeroTier::Utils::fileExists(msiPath.c_str()))) {
					WriteEventLogEntry("auto-update failed: no msi path provided by Node",EVENTLOG_ERROR_TYPE);
					Sleep(5000);
					goto restart_node;
				}

				if (!doStartUpgrade(msiPath)) {
					WriteEventLogEntry("auto-update failed: unable to create InstallAndRestartService.bat",EVENTLOG_ERROR_TYPE);
					Sleep(5000);
					goto restart_node;
				}

				// Terminate service to allow updater to update
				Stop();
			}	return;
			case ZeroTier::Node::NODE_UNRECOVERABLE_ERROR: {
				std::string err("ZeroTier node encountered an unrecoverable error: ");
				const char *r = _node->reasonForTermination();
				if (r)
					err.append(r);
				else err.append("(unknown error)");
				err.append(" (restarting in 5 seconds)");
				WriteEventLogEntry(const_cast <PSTR>(err.c_str()),EVENTLOG_ERROR_TYPE);
				Sleep(5000);
				goto restart_node;
			}	break;
			default: // includes normal termination, which will terminate thread
				break;
		}
	} catch ( ... ) {
		// sanity check, shouldn't happen since Node::run() should catch all its own errors
		// could also happen if we're out of memory though!
		WriteEventLogEntry("unexpected exception (out of memory?) (trying again in 5 seconds)",EVENTLOG_ERROR_TYPE);
		Sleep(5000);
		goto restart_node;
	}

	_lock.lock();
	delete _node;
	_node = (ZeroTier::Node *)0;
	_lock.unlock();
}