Added Method to Query the Failure Actions for the Service

This commit is contained in:
Jan Kevin Dick 2019-11-18 10:29:17 +01:00
parent 34ad48d16c
commit 9762ed37e9
4 changed files with 78 additions and 0 deletions

View File

@ -20,12 +20,15 @@
#include "Poco/Util/Util.h"
#include "Poco/UnWindows.h"
#include <vector>
#if defined(POCO_WIN32_UTF8)
#define POCO_LPQUERY_SERVICE_CONFIG LPQUERY_SERVICE_CONFIGW
#define POCO_LPSERVICE_FAILURE_ACTION LPSERVICE_FAILURE_ACTIONSW
#else
#define POCO_LPQUERY_SERVICE_CONFIG LPQUERY_SERVICE_CONFIGA
#define POCO_LPSERVICE_FAILURE_ACTION LPSERVICE_FAILURE_ACTIONSA
#endif
@ -49,6 +52,15 @@ public:
SVC_DISABLED
};
enum FailureAction
{
SVC_NONE,
SVC_REBOOT,
SVC_RESTART,
SVC_RUN_COMMAND
};
typedef std::vector<FailureAction> FailureActionVector;
WinService(const std::string& name);
/// Creates the WinService, using the given service name.
@ -116,6 +128,9 @@ public:
Startup getStartup() const;
/// Returns the startup mode for the service.
FailureActionVector getFailureAction() const;
/// Returns the Failure Actions for the service.
void setDescription(const std::string& description);
/// Sets the service description in the registry.

View File

@ -255,6 +255,58 @@ WinService::Startup WinService::getStartup() const
return result;
}
WinService::FailureActionVector WinService::getFailureAction() const {
open();
int size = 4096;
DWORD_PTR bytesNeeded;
POCO_LPSERVICE_FAILURE_ACTION pSvcFailureAction = (POCO_LPSERVICE_FAILURE_ACTION)LocalAlloc(LPTR, size);
if (!pSvcFailureAction) throw OutOfMemoryException("cannot allocate service failure action buffer");
try {
#if defined(POCO_WIN32_UTF8)
while (!QueryServiceConfig2W(_svcHandle, SERVICE_CONFIG_FAILURE_ACTIONS, (LPBYTE)pSvcFailureAction, size, &bytesNeeded))
#else
while (!QueryServiceConfig2A(_svcHandle, SERVICE_CONFIG_FAILURE_ACTIONS, (LPBYTE)pSvcFailureAction, size, &bytesNeeded))
#endif
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
LocalFree(pSvcFailureAction);
size = bytesNeeded;
pSvcFailureAction = (POCO_LPSERVICE_FAILURE_ACTION)LocalAlloc(LPTR, size);
} else throw SystemException("cannot query service configuration", _name);
}
}
catch (...)
{
LocalFree(pSvcFailureAction);
throw;
}
FailureActionVector result(3, SVC_NONE);
for (auto i = 0; i < pSvcFailureAction->cActions; i++)
{
switch (pSvcFailureAction->lpsaActions->Type)
{
case SC_ACTION_NONE:
result[i] = SVC_NONE;
break;
case SC_ACTION_RESTART:
result[i] = SVC_RESTART;
break;
case SC_ACTION_REBOOT:
result[i] = SVC_REBOOT;
break;
case SC_ACTION_RUN_COMMAND:
result[i] = SVC_RUN_COMMAND;
break;
default:
result[i] = SVC_NONE;
}
++pSvcFailureAction->lpsaActions;
}
LocalFree(pSvcFailureAction);
return result;
}
void WinService::setDescription(const std::string& description)
{

View File

@ -29,6 +29,15 @@ void WinServiceTest::testServiceReturnsTrueIfStopped() {
assertTrue(spoolerService_.isStopped());
}
void WinServiceTest::testServiceReturnsFailureActionConfigured() {
auto failureActions = spoolerService_.getFailureAction();
assertEqual(3, failureActions.size());
assertEqual(WinService::SVC_RESTART, failureActions[0]);
assertEqual(WinService::SVC_RESTART, failureActions[1]);
assertEqual(WinService::SVC_NONE, failureActions[2]);
}
void WinServiceTest::setUp() {
}
@ -47,6 +56,7 @@ CppUnit::Test* WinServiceTest::suite() {
CppUnit_addTest(pSuite, WinServiceTest, testServiceCouldCreatedWithExistingConnection);
CppUnit_addTest(pSuite, WinServiceTest, testServiceReturnsTrueIfStopped);
CppUnit_addTest(pSuite, WinServiceTest, testServiceReturnsFailureActionConfigured);
return pSuite;
}

View File

@ -14,6 +14,7 @@ public:
void testServiceCouldCreatedWithExistingConnection();
void testServiceReturnsTrueIfStopped();
void testServiceReturnsFailureActionConfigured();
void setUp();
void tearDown();