Author: ekohl Date: Sun Jul 3 08:56:43 2016 New Revision: 71772
URL: http://svn.reactos.org/svn/reactos?rev=71772&view=rev Log: [SC] Failure command: - Parse the actions parameter. - Adjust the shutdown privilege in order to set the failure actions.
Modified: trunk/reactos/base/applications/sc/CMakeLists.txt trunk/reactos/base/applications/sc/failure.c trunk/reactos/base/applications/sc/misc.c trunk/reactos/base/applications/sc/sc.h
Modified: trunk/reactos/base/applications/sc/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/CMakeL... ============================================================================== --- trunk/reactos/base/applications/sc/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/base/applications/sc/CMakeLists.txt [iso-8859-1] Sun Jul 3 08:56:43 2016 @@ -22,6 +22,6 @@
add_executable(sc ${SOURCE} sc.rc) set_module_type(sc win32cui UNICODE) -add_importlibs(sc advapi32 msvcrt kernel32) +add_importlibs(sc advapi32 msvcrt kernel32 ntdll) add_pch(sc sc.h SOURCE) add_cd_file(TARGET sc DESTINATION reactos/system32 FOR all)
Modified: trunk/reactos/base/applications/sc/failure.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/failur... ============================================================================== --- trunk/reactos/base/applications/sc/failure.c [iso-8859-1] (original) +++ trunk/reactos/base/applications/sc/failure.c [iso-8859-1] Sun Jul 3 08:56:43 2016 @@ -126,6 +126,9 @@ BOOL bResult = TRUE; SERVICE_FAILURE_ACTIONS FailureActions; LPCTSTR lpServiceName = NULL; + BOOLEAN Old = FALSE; + + ZeroMemory(&FailureActions, sizeof(SERVICE_FAILURE_ACTIONS));
if (!ParseFailureArguments(ServiceArgs, ArgCount, &lpServiceName, &FailureActions)) { @@ -145,13 +148,15 @@
hService = OpenService(hManager, lpServiceName, - SERVICE_CHANGE_CONFIG); + SERVICE_CHANGE_CONFIG | SERVICE_START); if (hService == NULL) { _tprintf(_T("[SC] OpenService FAILED %lu:\n\n"), GetLastError()); bResult = FALSE; goto done; } + + RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &Old);
if (!ChangeServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS, @@ -165,8 +170,13 @@ _tprintf(_T("[SC] ChangeServiceConfig2 SUCCESS\n\n"));
done: + RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, Old, FALSE, &Old); + if (bResult == FALSE) ReportLastError(); + + if (FailureActions.lpsaActions != NULL) + HeapFree(GetProcessHeap(), 0, FailureActions.lpsaActions);
if (hService) CloseServiceHandle(hService);
Modified: trunk/reactos/base/applications/sc/misc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/misc.c... ============================================================================== --- trunk/reactos/base/applications/sc/misc.c [iso-8859-1] (original) +++ trunk/reactos/base/applications/sc/misc.c [iso-8859-1] Sun Jul 3 08:56:43 2016 @@ -161,6 +161,101 @@
BOOL +ParseFailureActions( + IN LPCTSTR lpActions, + OUT DWORD *pcActions, + OUT SC_ACTION **ppActions) +{ + SC_ACTION *pActions = NULL; + LPTSTR pStringBuffer = NULL; + LPTSTR p; + INT nLength; + INT nCount = 0; + + *pcActions = 0; + *ppActions = NULL; + + nLength = _tcslen(lpActions); + + /* Allocate the string buffer */ + pStringBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nLength + 2) * sizeof(TCHAR)); + if (pStringBuffer == NULL) + { + return FALSE; + } + + /* Copy the actions string into the string buffer */ + CopyMemory(pStringBuffer, lpActions, nLength * sizeof(TCHAR)); + + /* Replace all slashes by null characters */ + p = pStringBuffer; + while (*p != 0 /*_T('\0')*/) + { + if (*p == _T('/')) + *p = 0; //_T('\0'); + p++; + } + + /* Count the arguments in the buffer */ + p = pStringBuffer; + while (*p != 0 /*_T('\0')*/) + { + nCount++; + + nLength = _tcslen(p); + p = (LPTSTR)((LONG_PTR)p + ((nLength + 1) * sizeof(TCHAR))); + } + + /* Allocate the actions buffer */ + pActions = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nCount / 2 * sizeof(SC_ACTION)); + if (pActions == NULL) + { + HeapFree(GetProcessHeap(), 0, pStringBuffer); + return FALSE; + } + + /* Parse the string buffer */ + nCount = 0; + p = pStringBuffer; + while (*p != _T('\0')) + { + nLength = _tcslen(p); + + if (nCount % 2 == 0) + { + /* Action */ + if (_tcsicmp(p, _T("reboot"))) + pActions[nCount / 2].Type = SC_ACTION_REBOOT; + else if (_tcsicmp(p, _T("restart"))) + pActions[nCount / 2].Type = SC_ACTION_RESTART; + else if (_tcsicmp(p, _T("run"))) + pActions[nCount / 2].Type = SC_ACTION_RUN_COMMAND; + else + break; + } + else + { + /* Delay */ + pActions[nCount / 2].Delay = _tcstoul(p, NULL, 10); + if (pActions[nCount / 2].Delay == 0 && errno == ERANGE) + break; + } + + p = (LPTSTR)((LONG_PTR)p + ((nLength + 1) * sizeof(TCHAR))); + nCount++; + } + + /* Free the string buffer */ + HeapFree(GetProcessHeap(), 0, pStringBuffer); + + *pcActions = nCount / 2; + *ppActions = pActions; + + return TRUE; +} + + +BOOL ParseFailureArguments( IN LPCTSTR *ServiceArgs, IN INT ArgCount, @@ -220,7 +315,12 @@
if (lpActions != NULL) { - /* FIXME */ + if (!ParseFailureActions(lpActions, + &pFailureActions->cActions, + &pFailureActions->lpsaActions)) + { + return FALSE; + } }
return (ArgCount == 0);
Modified: trunk/reactos/base/applications/sc/sc.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/sc/sc.h?r... ============================================================================== --- trunk/reactos/base/applications/sc/sc.h [iso-8859-1] (original) +++ trunk/reactos/base/applications/sc/sc.h [iso-8859-1] Sun Jul 3 08:56:43 2016 @@ -3,11 +3,16 @@
#include <stdarg.h>
+#define WIN32_NO_STATUS #include <windef.h> #include <winbase.h> #include <winsvc.h> #include <sddl.h> #include <tchar.h> + +#include <ndk/rtlfuncs.h> +#include <ndk/setypes.h> +
#define SCDBG