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/CMake…
==============================================================================
--- 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/failu…
==============================================================================
--- 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.…
==============================================================================
--- 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?…
==============================================================================
--- 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