Windows service work, remove old installer... not sure exactly what we're going to use.

This commit is contained in:
Adam Ierymenko 2014-02-06 22:06:27 -08:00
commit 8a7486577a
7 changed files with 255 additions and 6109 deletions

View file

@ -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;
}
}
return ret;
}

View file

@ -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);
// Also modified to return rather than print errors
std::string UninstallService(PSTR pszServiceName);

View file

@ -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::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::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::OnStop()
{
Node *n = _node;
_node = (Node *)0;
if (n) {
n->terminate(Node::NODE_NORMAL_TERMINATION,"Service Shutdown");
Thread::join(*_thread);
delete n;
}
}
void ZeroTierOneService::OnPause()
{
}
void ZeroTierOneService::OnContinue()
void ZeroTierOneService::OnShutdown()
{
// make sure it's stopped
OnStop();
}

View file

@ -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;
};

File diff suppressed because it is too large Load diff

View file

@ -1,37 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!-- Select a Product Configuration -->
<InstallShieldProductConfiguration>Express</InstallShieldProductConfiguration>
<!-- Select a Visual Studio Configuration / InstallShield Release -->
<Configuration>Debug</Configuration>
<InstallShieldRelease>$(Configuration)</InstallShieldRelease>
</PropertyGroup>
<ItemGroup>
<!-- The InstallShieldProject item selects the project to build -->
<InstallShieldProject Include="$(MSBuildProjectDirectory)\$(MSBuildProjectName).isl"/>
<!-- The InstallShieldReleaseFlags sets Release Flags -->
<!--<InstallShieldReleaseFlags Include=""/>-->
<!-- The InstallShieldMergeModulePath specifies what directories are
searched for Merge Modules -->
<!--<InstallShieldMergeModulePath Include=""/>-->
</ItemGroup>
<ItemGroup>
<!-- The ProjectReference items refer to any Visual Studio solutions you want to automatically probe for Project Output Groups. -->
</ItemGroup>
<ItemGroup>
<!-- The TaggedOutputs items allow you to explicitly add extra files to output groups. Each item must include both Name and OutputGroup, as well as TargetPath metadata values. -->
<!--<TaggedOutputs Include="C:\My Test Exe.exe">
<Name>My Test Project</Name>
<OutputGroup>Primary output</OutputGroup>
<TargetPath>My Test Exe.exe</TargetPath>
</TaggedOutputs> -->
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\InstallShield\2013Limited\InstallShield.targets"/>
<ItemGroup>
<ProjectReference Include="..\ZeroTierOneService\ZeroTierOneService.csproj">
<Name>ZeroTierOneService</Name>
<Project>{63D28112-9A56-42FA-9C3E-EF6C58AF09B3}</Project>
</ProjectReference>
</ItemGroup>
</Project>