- Add the 'failure' command. The 'actions' option is not implemented yet.

svn path=/trunk/; revision=71638
This commit is contained in:
Eric Kohl 2016-06-14 20:34:21 +00:00
parent 1f533a9d6b
commit 71cb6b0b4d
6 changed files with 170 additions and 0 deletions

View file

@ -7,6 +7,7 @@ list(APPEND SOURCE
create.c
delete.c
description.c
failure.c
misc.c
print.c
qfailure.c

View file

@ -0,0 +1,70 @@
/*
* PROJECT: ReactOS Services
* LICENSE: GPL - See COPYING in the top level directory
* FILE: base/applications/sc/failure.c
* PURPOSE: Set the service failure actions
* COPYRIGHT: Copyright 2016 Eric Kohl
*/
#include "sc.h"
BOOL
SetFailure(
LPCTSTR *ServiceArgs,
INT ArgCount)
{
SC_HANDLE hManager = NULL;
SC_HANDLE hService = NULL;
BOOL bResult = TRUE;
SERVICE_FAILURE_ACTIONS FailureActions;
LPCTSTR lpServiceName = NULL;
if (!ParseFailureArguments(ServiceArgs, ArgCount, &lpServiceName, &FailureActions))
{
SetFailureUsage();
return FALSE;
}
hManager = OpenSCManager(NULL,
NULL,
SC_MANAGER_CONNECT);
if (hManager == NULL)
{
_tprintf(_T("[SC] OpenSCManager FAILED %lu:\n\n"), GetLastError());
bResult = FALSE;
goto done;
}
hService = OpenService(hManager,
lpServiceName,
SERVICE_CHANGE_CONFIG);
if (hService == NULL)
{
_tprintf(_T("[SC] OpenService FAILED %lu:\n\n"), GetLastError());
bResult = FALSE;
goto done;
}
if (!ChangeServiceConfig2(hService,
SERVICE_CONFIG_FAILURE_ACTIONS,
(LPBYTE)&FailureActions))
{
_tprintf(_T("[SC] ChangeServiceConfig2 FAILED %lu:\n\n"), GetLastError());
bResult = FALSE;
goto done;
}
_tprintf(_T("[SC] ChangeServiceConfig2 SUCCESS\n\n"));
done:
if (bResult == FALSE)
ReportLastError();
if (hService)
CloseServiceHandle(hService);
if (hManager)
CloseServiceHandle(hManager);
return bResult;
}

View file

@ -158,3 +158,70 @@ ParseCreateConfigArguments(
return (ArgCount == 0);
}
BOOL
ParseFailureArguments(
IN LPCTSTR *ServiceArgs,
IN INT ArgCount,
OUT LPCTSTR *ppServiceName,
OUT LPSERVICE_FAILURE_ACTIONS pFailureActions)
{
INT /*i,*/ ArgIndex = 1;
LPCTSTR lpActions = NULL;
LPCTSTR lpReset = NULL;
if (ArgCount < 1)
return FALSE;
ZeroMemory(pFailureActions, sizeof(SERVICE_FAILURE_ACTIONS));
*ppServiceName = ServiceArgs[0];
ArgCount--;
while (ArgCount > 1)
{
if (!lstrcmpi(ServiceArgs[ArgIndex], _T("actions=")))
{
lpActions = (LPTSTR)ServiceArgs[ArgIndex + 1];
}
else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("command=")))
{
pFailureActions->lpCommand = (LPTSTR)ServiceArgs[ArgIndex + 1];
}
else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("reboot=")))
{
pFailureActions->lpRebootMsg = (LPTSTR)ServiceArgs[ArgIndex + 1];
}
else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("reset=")))
{
lpReset = (LPTSTR)ServiceArgs[ArgIndex + 1];
}
ArgIndex += 2;
ArgCount -= 2;
}
if ((lpReset == NULL && lpActions != NULL) ||
(lpReset != NULL && lpActions == NULL))
{
_tprintf(_T("ERROR: The reset and actions options must be used simultaneously.\n\n"));
return FALSE;
}
if (lpReset != NULL)
{
if (!lstrcmpi(lpReset, _T("infinite")))
pFailureActions->dwResetPeriod = INFINITE;
else
pFailureActions->dwResetPeriod = _ttoi(lpReset);
}
if (lpActions != NULL)
{
/* FIXME */
}
return (ArgCount == 0);
}

View file

@ -268,6 +268,10 @@ ScControl(LPCTSTR Server, // remote machine name
{
SetConfig(ServiceArgs, ArgCount);
}
else if (!lstrcmpi(Command, _T("failure")))
{
SetFailure(ServiceArgs, ArgCount);
}
else
{
MainUsage();

View file

@ -44,6 +44,7 @@ BOOL SetConfig(LPCTSTR *ServiceArgs, INT ArgCount);
BOOL QueryDescription(LPCTSTR ServiceName);
BOOL SetDescription(LPCTSTR ServiceName, LPCTSTR Description);
BOOL QueryFailure(LPCTSTR ServiceName);
BOOL SetFailure(LPCTSTR *ServiceArgs, INT ArgCount);
/* print and error functions */
VOID PrintService(LPCTSTR ServiceName, LPSERVICE_STATUS_PROCESS pStatus, BOOL bExtended);
@ -57,6 +58,13 @@ ParseCreateConfigArguments(
BOOL bChangeService,
OUT LPSERVICE_CREATE_INFO lpServiceInfo);
BOOL
ParseFailureArguments(
LPCTSTR *ServiceArgs,
INT ArgCount,
OUT LPCTSTR *ppServiceName,
OUT LPSERVICE_FAILURE_ACTIONS pFailureActions);
/* usage functions */
VOID MainUsage(VOID);
VOID StartUsage(VOID);
@ -74,5 +82,6 @@ VOID QueryDescriptionUsage(VOID);
VOID QueryFailureUsage(VOID);
VOID SetDescriptionUsage(VOID);
VOID SetConfigUsage(VOID);
VOID SetFailureUsage(VOID);
#endif /* _SC_PCH_ */

View file

@ -243,3 +243,22 @@ VOID SetConfigUsage(VOID)
_T(" DisplayName= <display name>\n")
_T(" password= <password>\n"));
}
VOID SetFailureUsage(VOID)
{
_tprintf(_T("DESCRIPTION:\n")
_T(" Changes the actions upon failure.\n")
_T("USAGE:\n")
_T(" sc <server> failure [service name] <option1> <option2>...\n")
_T("\n")
_T("OPTIONS:\n")
_T(" reset= <Length of period of no failures (in seconds)\n")
_T(" after which to reset the failure count to 0 (may be INFINITE)>\n")
_T(" (Must be used in conjunction with actions= )\n")
_T(" reboot= <Message broadcast before rebooting on failure>\n")
_T(" command= <Command line to be run on failure>\n")
_T(" actions= <Failure actions and their delay time (in milliseconds),\n")
_T(" separated by / (forward slash) -- e.g., run/5000/reboot/800\n")
_T(" Valid actions are <run|restart|reboot> >\n")
_T(" (Must be used in conjunction with the reset= option)\n"));
}