1 /* 2 * PROJECT: ReactOS Services 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: base/applications/sc/failure.c 5 * PURPOSE: Query/Set the service failure actions 6 * COPYRIGHT: Copyright 2016 Eric Kohl 7 */ 8 9 #include "sc.h" 10 11 BOOL QueryFailure(LPCTSTR ServiceName) 12 { 13 SC_HANDLE hManager = NULL; 14 SC_HANDLE hService = NULL; 15 BOOL bResult = TRUE; 16 DWORD cbBytesNeeded = 0; 17 LPSERVICE_FAILURE_ACTIONS pServiceFailure = NULL; 18 INT i; 19 20 #ifdef SCDBG 21 _tprintf(_T("service to show failure action - %s\n\n"), ServiceName); 22 #endif 23 24 hManager = OpenSCManager(NULL, 25 NULL, 26 SC_MANAGER_CONNECT); 27 if (hManager == NULL) 28 { 29 bResult = FALSE; 30 goto done; 31 } 32 33 hService = OpenService(hManager, ServiceName, SERVICE_QUERY_CONFIG); 34 if (hService == NULL) 35 { 36 bResult = FALSE; 37 goto done; 38 } 39 40 if (!QueryServiceConfig2(hService, 41 SERVICE_CONFIG_FAILURE_ACTIONS, 42 NULL, 43 0, 44 &cbBytesNeeded)) 45 { 46 if (cbBytesNeeded == 0) 47 { 48 bResult = FALSE; 49 goto done; 50 } 51 } 52 53 pServiceFailure = HeapAlloc(GetProcessHeap(), 0, cbBytesNeeded); 54 if (pServiceFailure == NULL) 55 { 56 SetLastError(ERROR_OUTOFMEMORY); 57 bResult = FALSE; 58 goto done; 59 } 60 61 if (!QueryServiceConfig2(hService, 62 SERVICE_CONFIG_FAILURE_ACTIONS, 63 (LPBYTE)pServiceFailure, 64 cbBytesNeeded, 65 &cbBytesNeeded)) 66 { 67 bResult = FALSE; 68 goto done; 69 } 70 71 _tprintf(_T("SERVICE_NAME: %s\n"), ServiceName); 72 _tprintf(_T(" RESET_PERIOD : %lu seconds\n"), pServiceFailure->dwResetPeriod); 73 _tprintf(_T(" REBOOT_MESSAGE : %s\n"), (pServiceFailure->lpRebootMsg) ? pServiceFailure->lpRebootMsg : _T("")); 74 _tprintf(_T(" COMMAND_LINE : %s\n"), (pServiceFailure->lpCommand) ? pServiceFailure->lpCommand : _T("")); 75 _tprintf(_T(" FAILURE_ACTIONS : ")); 76 for (i = 0; i < pServiceFailure->cActions; i++) 77 { 78 if (i != 0) 79 _tprintf(_T(" ")); 80 switch (pServiceFailure->lpsaActions[i].Type) 81 { 82 case SC_ACTION_NONE: 83 continue; 84 85 case SC_ACTION_RESTART: 86 _tprintf(_T("RESTART -- Delay = %lu milliseconds.\n"), pServiceFailure->lpsaActions[i].Delay); 87 break; 88 89 case SC_ACTION_REBOOT: 90 _tprintf(_T("REBOOT -- Delay = %lu milliseconds.\n"), pServiceFailure->lpsaActions[i].Delay); 91 break; 92 93 case SC_ACTION_RUN_COMMAND: 94 _tprintf(_T("RUN_COMMAND -- Delay = %lu milliseconds.\n"), pServiceFailure->lpsaActions[i].Delay); 95 break; 96 97 default: 98 _tprintf(_T("\n")); 99 break; 100 } 101 } 102 103 done: 104 if (bResult == FALSE) 105 ReportLastError(); 106 107 if (pServiceFailure != NULL) 108 HeapFree(GetProcessHeap(), 0, pServiceFailure); 109 110 if (hService) 111 CloseServiceHandle(hService); 112 113 if (hManager) 114 CloseServiceHandle(hManager); 115 116 return bResult; 117 } 118 119 BOOL 120 SetFailure( 121 LPCTSTR *ServiceArgs, 122 INT ArgCount) 123 { 124 SC_HANDLE hManager = NULL; 125 SC_HANDLE hService = NULL; 126 BOOL bResult = TRUE; 127 SERVICE_FAILURE_ACTIONS FailureActions; 128 LPCTSTR lpServiceName = NULL; 129 BOOLEAN Old = FALSE; 130 131 ZeroMemory(&FailureActions, sizeof(SERVICE_FAILURE_ACTIONS)); 132 133 if (!ParseFailureArguments(ServiceArgs, ArgCount, &lpServiceName, &FailureActions)) 134 { 135 SetFailureUsage(); 136 return FALSE; 137 } 138 139 hManager = OpenSCManager(NULL, 140 NULL, 141 SC_MANAGER_CONNECT); 142 if (hManager == NULL) 143 { 144 _tprintf(_T("[SC] OpenSCManager FAILED %lu:\n\n"), GetLastError()); 145 bResult = FALSE; 146 goto done; 147 } 148 149 hService = OpenService(hManager, 150 lpServiceName, 151 SERVICE_CHANGE_CONFIG | SERVICE_START); 152 if (hService == NULL) 153 { 154 _tprintf(_T("[SC] OpenService FAILED %lu:\n\n"), GetLastError()); 155 bResult = FALSE; 156 goto done; 157 } 158 159 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &Old); 160 161 if (!ChangeServiceConfig2(hService, 162 SERVICE_CONFIG_FAILURE_ACTIONS, 163 (LPBYTE)&FailureActions)) 164 { 165 _tprintf(_T("[SC] ChangeServiceConfig2 FAILED %lu:\n\n"), GetLastError()); 166 bResult = FALSE; 167 goto done; 168 } 169 170 _tprintf(_T("[SC] ChangeServiceConfig2 SUCCESS\n\n")); 171 172 done: 173 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, Old, FALSE, &Old); 174 175 if (bResult == FALSE) 176 ReportLastError(); 177 178 if (FailureActions.lpsaActions != NULL) 179 HeapFree(GetProcessHeap(), 0, FailureActions.lpsaActions); 180 181 if (hService) 182 CloseServiceHandle(hService); 183 184 if (hManager) 185 CloseServiceHandle(hManager); 186 187 return bResult; 188 } 189