diff options
author | Adam Ierymenko <adam.ierymenko@zerotier.com> | 2014-02-06 22:06:27 -0800 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@zerotier.com> | 2014-02-06 22:06:27 -0800 |
commit | 8a7486577afb259c19b82e4e73cb8b508cd2f162 (patch) | |
tree | dc36ac222fecb598972ad4a1e47454fa9099fb3a /windows/ZeroTierOne | |
parent | 6d17993eb69455a8a47013e9c6f110863f7dbb35 (diff) | |
download | infinitytier-8a7486577afb259c19b82e4e73cb8b508cd2f162.tar.gz infinitytier-8a7486577afb259c19b82e4e73cb8b508cd2f162.zip |
Windows service work, remove old installer... not sure exactly what we're going to use.
Diffstat (limited to 'windows/ZeroTierOne')
-rw-r--r-- | windows/ZeroTierOne/ServiceInstaller.cpp | 43 | ||||
-rw-r--r-- | windows/ZeroTierOne/ServiceInstaller.h | 7 | ||||
-rw-r--r-- | windows/ZeroTierOne/ZeroTierOneService.cpp | 62 | ||||
-rw-r--r-- | windows/ZeroTierOne/ZeroTierOneService.h | 18 |
4 files changed, 95 insertions, 35 deletions
diff --git a/windows/ZeroTierOne/ServiceInstaller.cpp b/windows/ZeroTierOne/ServiceInstaller.cpp index 9d7b22c7..5945ecdf 100644 --- a/windows/ZeroTierOne/ServiceInstaller.cpp +++ b/windows/ZeroTierOne/ServiceInstaller.cpp @@ -42,20 +42,21 @@ // NOTE: If the function fails to install the service, it prints the error // in the standard output stream for users to diagnose the problem. // -void InstallService(PSTR pszServiceName, +std::string InstallService(PSTR pszServiceName, PSTR pszDisplayName, DWORD dwStartType, PSTR pszDependencies, PSTR pszAccount, PSTR pszPassword) { + std::string ret; char szPath[MAX_PATH]; SC_HANDLE schSCManager = NULL; SC_HANDLE schService = NULL; if (GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath)) == 0) { - wprintf(L"GetModuleFileName failed w/err 0x%08lx\n", GetLastError()); + ret = "GetModuleFileName failed, unable to get path to self"; goto Cleanup; } @@ -64,7 +65,7 @@ void InstallService(PSTR pszServiceName, SC_MANAGER_CREATE_SERVICE); if (schSCManager == NULL) { - wprintf(L"OpenSCManager failed w/err 0x%08lx\n", GetLastError()); + ret = "OpenSCManager failed"; goto Cleanup; } @@ -86,12 +87,10 @@ void InstallService(PSTR pszServiceName, ); if (schService == NULL) { - wprintf(L"CreateService failed w/err 0x%08lx\n", GetLastError()); + ret = "CreateService failed"; goto Cleanup; } - wprintf(L"%s is installed.\n", pszServiceName); - Cleanup: // Centralized cleanup for all allocated resources. if (schSCManager) @@ -104,6 +103,8 @@ Cleanup: CloseServiceHandle(schService); schService = NULL; } + + return ret; } @@ -119,8 +120,9 @@ Cleanup: // NOTE: If the function fails to uninstall the service, it prints the // error in the standard output stream for users to diagnose the problem. // -void UninstallService(PSTR pszServiceName) +std::string UninstallService(PSTR pszServiceName) { + std::string ret; SC_HANDLE schSCManager = NULL; SC_HANDLE schService = NULL; SERVICE_STATUS ssSvcStatus = {}; @@ -129,7 +131,7 @@ void UninstallService(PSTR pszServiceName) schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (schSCManager == NULL) { - wprintf(L"OpenSCManager failed w/err 0x%08lx\n", GetLastError()); + ret = "OpenSCManager failed"; goto Cleanup; } @@ -138,45 +140,32 @@ void UninstallService(PSTR pszServiceName) SERVICE_QUERY_STATUS | DELETE); if (schService == NULL) { - wprintf(L"OpenService failed w/err 0x%08lx\n", GetLastError()); + ret = "OpenService failed (is service installed?)"; goto Cleanup; } // Try to stop the service if (ControlService(schService, SERVICE_CONTROL_STOP, &ssSvcStatus)) { - wprintf(L"Stopping %s.", pszServiceName); - Sleep(1000); + Sleep(500); while (QueryServiceStatus(schService, &ssSvcStatus)) { if (ssSvcStatus.dwCurrentState == SERVICE_STOP_PENDING) { - wprintf(L"."); - Sleep(1000); + Sleep(500); } else break; } - - if (ssSvcStatus.dwCurrentState == SERVICE_STOPPED) - { - wprintf(L"\n%s is stopped.\n", pszServiceName); - } - else - { - wprintf(L"\n%s failed to stop.\n", pszServiceName); - } } // Now remove the service by calling DeleteService. if (!DeleteService(schService)) { - wprintf(L"DeleteService failed w/err 0x%08lx\n", GetLastError()); + ret = "DeleteService failed (is service running?)"; goto Cleanup; } - wprintf(L"%s is removed.\n", pszServiceName); - Cleanup: // Centralized cleanup for all allocated resources. if (schSCManager) @@ -189,4 +178,6 @@ Cleanup: CloseServiceHandle(schService); schService = NULL; } -}
\ No newline at end of file + + return ret; +} diff --git a/windows/ZeroTierOne/ServiceInstaller.h b/windows/ZeroTierOne/ServiceInstaller.h index 1f007c05..ee9856df 100644 --- a/windows/ZeroTierOne/ServiceInstaller.h +++ b/windows/ZeroTierOne/ServiceInstaller.h @@ -16,6 +16,7 @@ #pragma once +#include <string> // // FUNCTION: InstallService @@ -38,7 +39,8 @@ // NOTE: If the function fails to install the service, it prints the error // in the standard output stream for users to diagnose the problem. // -void InstallService(PSTR pszServiceName, +// modified for ZT1 to return an error or empty string on success +std::string InstallService(PSTR pszServiceName, PSTR pszDisplayName, DWORD dwStartType, PSTR pszDependencies, @@ -58,4 +60,5 @@ void InstallService(PSTR pszServiceName, // NOTE: If the function fails to uninstall the service, it prints the // error in the standard output stream for users to diagnose the problem. // -void UninstallService(PSTR pszServiceName);
\ No newline at end of file +// Also modified to return rather than print errors +std::string UninstallService(PSTR pszServiceName); diff --git a/windows/ZeroTierOne/ZeroTierOneService.cpp b/windows/ZeroTierOne/ZeroTierOneService.cpp index 0a89e80a..b8277436 100644 --- a/windows/ZeroTierOne/ZeroTierOneService.cpp +++ b/windows/ZeroTierOne/ZeroTierOneService.cpp @@ -27,29 +27,81 @@ #pragma region Includes #include "ZeroTierOneService.h" +#include "../../node/Node.hpp" +#include "../../node/Defaults.hpp" +#include "../../node/Thread.hpp" #pragma endregion +using namespace ZeroTier; + ZeroTierOneService::ZeroTierOneService() : - CServiceBase(ZT_SERVICE_NAME,TRUE,TRUE,TRUE) + CServiceBase(ZT_SERVICE_NAME,TRUE,TRUE,FALSE), + _thread(new Thread()), + _node((Node *)0) { } ZeroTierOneService::~ZeroTierOneService(void) { + delete _thread; + delete _node; } -void ZeroTierOneService::OnStart(DWORD dwArgc, LPSTR *lpszArgv) +void ZeroTierOneService::threadMain() + throw() { + try { + // Since Windows doesn't auto-restart services, we'll restart the node + // on normal termination. + for(;;) { + switch(_node->run()) { + case Node::NODE_NORMAL_TERMINATION: + delete _node; + _node = new Node(ZT_DEFAULTS.defaultHomePath.c_str(),0,0); + break; // restart + case Node::NODE_RESTART_FOR_UPGRADE: { + } return; // terminate thread + case Node::NODE_UNRECOVERABLE_ERROR: { + std::string err("unrecoverable error: "); + const char *r = _node->reasonForTermination; + if (r) + err.append(r); + else err.append("(unknown error)"); + WriteEventLogEntry(const_cast <PSTR>(err.c_str()),EVENTLOG_ERROR_TYPE); + } return; // terminate thread + default: + break; + } + } + } catch ( ... ) { + WriteEventLogEntry("unexpected exception in Node::run() or during restart",EVENTLOG_ERROR_TYPE); + } } -void ZeroTierOneService::OnStop() +void ZeroTierOneService::OnStart(DWORD dwArgc, LPSTR *lpszArgv) { + try { + _node = new Node(ZT_DEFAULTS.defaultHomePath.c_str(),0,0); + *_thread = Thread::start(this); + } catch ( ... ) { + // shouldn't happen unless something weird occurs like out of memory... + throw (DWORD)ERROR_EXCEPTION_IN_SERVICE; + } } -void ZeroTierOneService::OnPause() +void ZeroTierOneService::OnStop() { + Node *n = _node; + _node = (Node *)0; + if (n) { + n->terminate(Node::NODE_NORMAL_TERMINATION,"Service Shutdown"); + Thread::join(*_thread); + delete n; + } } -void ZeroTierOneService::OnContinue() +void ZeroTierOneService::OnShutdown() { + // make sure it's stopped + OnStop(); } diff --git a/windows/ZeroTierOne/ZeroTierOneService.h b/windows/ZeroTierOne/ZeroTierOneService.h index 4bfc60b2..776446b0 100644 --- a/windows/ZeroTierOne/ZeroTierOneService.h +++ b/windows/ZeroTierOne/ZeroTierOneService.h @@ -36,15 +36,29 @@ #define ZT_SERVICE_ACCOUNT "NT AUTHORITY\\LocalService" #define ZT_SERVICE_PASSWORD NULL +namespace ZeroTier { +class Node; +class Thread; +} // namespace ZeroTier + class ZeroTierOneService : public CServiceBase { public: ZeroTierOneService(); virtual ~ZeroTierOneService(void); + /** + * Thread main method; do not call elsewhere + */ + void threadMain() + throw(); + protected: virtual void OnStart(DWORD dwArgc, PSTR *pszArgv); virtual void OnStop(); - virtual void OnPause(); - virtual void OnContinue(); + virtual void OnShutdown(); + +private: + ZeroTier::Node *volatile _node; + ZeroTier::Thread *volatile _thread; }; |