ReactOS 0.4.15-dev-7961-gdcf9eb0
misc.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/sc/misc.c
5 * PURPOSE: Various functions
6 * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy <gedmurphy@gmail.com>
7 * Roel Messiant <roelmessiant@gmail.com>
8 */
9
10#include "sc.h"
11
12typedef struct
13{
17
18static const OPTION_INFO TypeOpts[] =
19{
20 { _T("own"), SERVICE_WIN32_OWN_PROCESS },
21 { _T("share"), SERVICE_WIN32_SHARE_PROCESS },
22 { _T("interact"), SERVICE_INTERACTIVE_PROCESS },
23 { _T("kernel"), SERVICE_KERNEL_DRIVER },
24 { _T("filesys"), SERVICE_FILE_SYSTEM_DRIVER },
26};
27
28static const OPTION_INFO StartOpts[] =
29{
30 { _T("boot"), SERVICE_BOOT_START },
31 { _T("system"), SERVICE_SYSTEM_START },
32 { _T("auto"), SERVICE_AUTO_START },
33 { _T("demand"), SERVICE_DEMAND_START },
34 { _T("disabled"), SERVICE_DISABLED }
35};
36
37static const OPTION_INFO ErrorOpts[] =
38{
39 { _T("normal"), SERVICE_ERROR_NORMAL },
40 { _T("severe"), SERVICE_ERROR_SEVERE },
41 { _T("critical"), SERVICE_ERROR_CRITICAL },
42 { _T("ignore"), SERVICE_ERROR_IGNORE }
43};
44
45static const OPTION_INFO TagOpts[] =
46{
47 { _T("yes"), TRUE },
48 { _T("no"), FALSE }
49};
50
51
52BOOL
54 LPCTSTR *ServiceArgs,
55 INT ArgCount,
56 BOOL bChangeService,
57 OUT LPSERVICE_CREATE_INFO lpServiceInfo)
58{
59 INT i, ArgIndex = 1;
60
61 if (ArgCount < 1)
62 return FALSE;
63
64 ZeroMemory(lpServiceInfo, sizeof(SERVICE_CREATE_INFO));
65
66 if (bChangeService)
67 {
68 lpServiceInfo->dwServiceType = SERVICE_NO_CHANGE;
69 lpServiceInfo->dwStartType = SERVICE_NO_CHANGE;
70 lpServiceInfo->dwErrorControl = SERVICE_NO_CHANGE;
71 }
72
73 lpServiceInfo->lpServiceName = ServiceArgs[0];
74
75 ArgCount--;
76
77 while (ArgCount > 1)
78 {
79 if (!lstrcmpi(ServiceArgs[ArgIndex], _T("type=")))
80 {
81 for (i = 0; i < sizeof(TypeOpts) / sizeof(TypeOpts[0]); i++)
82 if (!lstrcmpi(ServiceArgs[ArgIndex + 1], TypeOpts[i].lpOption))
83 {
84 if (lpServiceInfo->dwServiceType == SERVICE_NO_CHANGE)
85 lpServiceInfo->dwServiceType = TypeOpts[i].dwValue;
86 else
87 lpServiceInfo->dwServiceType |= TypeOpts[i].dwValue;
88 break;
89 }
90
91 if (i == sizeof(TypeOpts) / sizeof(TypeOpts[0]))
92 break;
93 }
94 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("start=")))
95 {
96 for (i = 0; i < sizeof(StartOpts) / sizeof(StartOpts[0]); i++)
97 if (!lstrcmpi(ServiceArgs[ArgIndex + 1], StartOpts[i].lpOption))
98 {
99 lpServiceInfo->dwStartType = StartOpts[i].dwValue;
100 break;
101 }
102
103 if (i == sizeof(StartOpts) / sizeof(StartOpts[0]))
104 break;
105 }
106 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("error=")))
107 {
108 for (i = 0; i < sizeof(ErrorOpts) / sizeof(ErrorOpts[0]); i++)
109 if (!lstrcmpi(ServiceArgs[ArgIndex + 1], ErrorOpts[i].lpOption))
110 {
111 lpServiceInfo->dwErrorControl = ErrorOpts[i].dwValue;
112 break;
113 }
114
115 if (i == sizeof(ErrorOpts) / sizeof(ErrorOpts[0]))
116 break;
117 }
118 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("tag=")))
119 {
120 for (i = 0; i < sizeof(TagOpts) / sizeof(TagOpts[0]); i++)
121 if (!lstrcmpi(ServiceArgs[ArgIndex + 1], TagOpts[i].lpOption))
122 {
123 lpServiceInfo->bTagId = TagOpts[i].dwValue;
124 break;
125 }
126
127 if (i == sizeof(TagOpts) / sizeof(TagOpts[0]))
128 break;
129 }
130 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("binpath=")))
131 {
132 lpServiceInfo->lpBinaryPathName = ServiceArgs[ArgIndex + 1];
133 }
134 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("group=")))
135 {
136 lpServiceInfo->lpLoadOrderGroup = ServiceArgs[ArgIndex + 1];
137 }
138 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("depend=")))
139 {
140 lpServiceInfo->lpDependencies = ServiceArgs[ArgIndex + 1];
141 }
142 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("obj=")))
143 {
144 lpServiceInfo->lpServiceStartName = ServiceArgs[ArgIndex + 1];
145 }
146 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("displayname=")))
147 {
148 lpServiceInfo->lpDisplayName = ServiceArgs[ArgIndex + 1];
149 }
150 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("password=")))
151 {
152 lpServiceInfo->lpPassword = ServiceArgs[ArgIndex + 1];
153 }
154
155 ArgIndex += 2;
156 ArgCount -= 2;
157 }
158
159 return (ArgCount == 0);
160}
161
162
163BOOL
165 IN LPCTSTR lpActions,
166 OUT DWORD *pcActions,
167 OUT SC_ACTION **ppActions)
168{
169 SC_ACTION *pActions = NULL;
170 LPTSTR pStringBuffer = NULL;
171 LPTSTR p;
173 INT nCount = 0;
174
175 *pcActions = 0;
176 *ppActions = NULL;
177
178 nLength = _tcslen(lpActions);
179
180 /* Allocate the string buffer */
181 pStringBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nLength + 2) * sizeof(TCHAR));
182 if (pStringBuffer == NULL)
183 {
184 return FALSE;
185 }
186
187 /* Copy the actions string into the string buffer */
188 CopyMemory(pStringBuffer, lpActions, nLength * sizeof(TCHAR));
189
190 /* Replace all slashes by null characters */
191 p = pStringBuffer;
192 while (*p != _T('\0'))
193 {
194 if (*p == _T('/'))
195 *p = _T('\0');
196 p++;
197 }
198
199 /* Count the arguments in the buffer */
200 p = pStringBuffer;
201 while (*p != _T('\0'))
202 {
203 nCount++;
204
205 nLength = _tcslen(p);
206 p = (LPTSTR)((LONG_PTR)p + ((nLength + 1) * sizeof(TCHAR)));
207 }
208
209 /* Allocate the actions buffer */
210 pActions = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nCount / 2 * sizeof(SC_ACTION));
211 if (pActions == NULL)
212 {
213 HeapFree(GetProcessHeap(), 0, pStringBuffer);
214 return FALSE;
215 }
216
217 /* Parse the string buffer */
218 nCount = 0;
219 p = pStringBuffer;
220 while (*p != _T('\0'))
221 {
222 nLength = _tcslen(p);
223
224 if (nCount % 2 == 0)
225 {
226 /* Action */
227 if (!lstrcmpi(p, _T("reboot")))
228 pActions[nCount / 2].Type = SC_ACTION_REBOOT;
229 else if (!lstrcmpi(p, _T("restart")))
230 pActions[nCount / 2].Type = SC_ACTION_RESTART;
231 else if (!lstrcmpi(p, _T("run")))
232 pActions[nCount / 2].Type = SC_ACTION_RUN_COMMAND;
233 else
234 break;
235 }
236 else
237 {
238 /* Delay */
239 pActions[nCount / 2].Delay = _tcstoul(p, NULL, 10);
240 if (pActions[nCount / 2].Delay == 0 && errno == ERANGE)
241 break;
242 }
243
244 p = (LPTSTR)((LONG_PTR)p + ((nLength + 1) * sizeof(TCHAR)));
245 nCount++;
246 }
247
248 /* Free the string buffer */
249 HeapFree(GetProcessHeap(), 0, pStringBuffer);
250
251 *pcActions = nCount / 2;
252 *ppActions = pActions;
253
254 return TRUE;
255}
256
257
258BOOL
260 IN LPCTSTR *ServiceArgs,
261 IN INT ArgCount,
262 OUT LPCTSTR *ppServiceName,
263 OUT LPSERVICE_FAILURE_ACTIONS pFailureActions)
264{
265 INT ArgIndex = 1;
266 LPCTSTR lpActions = NULL;
267 LPCTSTR lpReset = NULL;
268
269 if (ArgCount < 1)
270 return FALSE;
271
272 ZeroMemory(pFailureActions, sizeof(SERVICE_FAILURE_ACTIONS));
273
274 *ppServiceName = ServiceArgs[0];
275
276 ArgCount--;
277
278 while (ArgCount > 1)
279 {
280 if (!lstrcmpi(ServiceArgs[ArgIndex], _T("actions=")))
281 {
282 lpActions = (LPTSTR)ServiceArgs[ArgIndex + 1];
283 }
284 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("command=")))
285 {
286 pFailureActions->lpCommand = (LPTSTR)ServiceArgs[ArgIndex + 1];
287 }
288 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("reboot=")))
289 {
290 pFailureActions->lpRebootMsg = (LPTSTR)ServiceArgs[ArgIndex + 1];
291 }
292 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("reset=")))
293 {
294 lpReset = (LPTSTR)ServiceArgs[ArgIndex + 1];
295 }
296
297 ArgIndex += 2;
298 ArgCount -= 2;
299 }
300
301 if ((lpReset == NULL && lpActions != NULL) ||
302 (lpReset != NULL && lpActions == NULL))
303 {
304 _tprintf(_T("ERROR: The reset and actions options must be used simultaneously.\n\n"));
305 return FALSE;
306 }
307
308 if (lpReset != NULL)
309 {
310 if (!lstrcmpi(lpReset, _T("infinite")))
311 pFailureActions->dwResetPeriod = INFINITE;
312 else
313 pFailureActions->dwResetPeriod = _ttoi(lpReset);
314 }
315
316 if (lpActions != NULL)
317 {
318 if (!ParseFailureActions(lpActions,
319 &pFailureActions->cActions,
320 &pFailureActions->lpsaActions))
321 {
322 return FALSE;
323 }
324 }
325
326 return (ArgCount == 0);
327}
#define ERANGE
Definition: acclib.h:92
static const OPTION_INFO TagOpts[]
Definition: misc.c:45
BOOL ParseFailureActions(IN LPCTSTR lpActions, OUT DWORD *pcActions, OUT SC_ACTION **ppActions)
Definition: misc.c:164
static const OPTION_INFO TypeOpts[]
Definition: misc.c:18
BOOL ParseCreateConfigArguments(LPCTSTR *ServiceArgs, INT ArgCount, BOOL bChangeService, OUT LPSERVICE_CREATE_INFO lpServiceInfo)
Definition: misc.c:53
static const OPTION_INFO ErrorOpts[]
Definition: misc.c:37
static const OPTION_INFO StartOpts[]
Definition: misc.c:28
BOOL ParseFailureArguments(IN LPCTSTR *ServiceArgs, IN INT ArgCount, OUT LPCTSTR *ppServiceName, OUT LPSERVICE_FAILURE_ACTIONS pFailureActions)
Definition: misc.c:259
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define _tcstoul
Definition: tchar.h:595
#define _tprintf
Definition: tchar.h:506
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define errno
Definition: errno.h:18
LPCTSTR lpOption
Definition: misc.c:14
DWORD dwValue
Definition: misc.c:15
DWORD Delay
Definition: winsvc.h:206
SC_ACTION_TYPE Type
Definition: winsvc.h:205
int32_t INT_PTR
Definition: typedefs.h:64
int32_t INT
Definition: typedefs.h:58
#define IN
Definition: typedefs.h:39
#define OUT
Definition: typedefs.h:40
#define _T(x)
Definition: vfdio.h:22
#define ZeroMemory
Definition: winbase.h:1712
#define CopyMemory
Definition: winbase.h:1710
#define lstrcmpi
Definition: winbase.h:3873
_In_ DWORD nLength
Definition: wincon.h:473
@ SC_ACTION_RUN_COMMAND
Definition: winsvc.h:202
@ SC_ACTION_REBOOT
Definition: winsvc.h:201
@ SC_ACTION_RESTART
Definition: winsvc.h:200
#define SERVICE_NO_CHANGE
Definition: winsvc.h:20
#define SERVICE_DEMAND_START
Definition: cmtypes.h:978
#define SERVICE_KERNEL_DRIVER
Definition: cmtypes.h:953
#define SERVICE_WIN32_SHARE_PROCESS
Definition: cmtypes.h:963
#define SERVICE_ERROR_SEVERE
Definition: cmtypes.h:983
#define SERVICE_RECOGNIZER_DRIVER
Definition: cmtypes.h:956
#define SERVICE_INTERACTIVE_PROCESS
Definition: cmtypes.h:967
#define SERVICE_DISABLED
Definition: cmtypes.h:979
#define SERVICE_AUTO_START
Definition: cmtypes.h:977
#define SERVICE_BOOT_START
Definition: cmtypes.h:975
#define SERVICE_ERROR_CRITICAL
Definition: cmtypes.h:984
#define SERVICE_WIN32_OWN_PROCESS
Definition: cmtypes.h:962
#define SERVICE_SYSTEM_START
Definition: cmtypes.h:976
#define SERVICE_FILE_SYSTEM_DRIVER
Definition: cmtypes.h:954
#define SERVICE_ERROR_IGNORE
Definition: cmtypes.h:981
#define SERVICE_ERROR_NORMAL
Definition: cmtypes.h:982
char TCHAR
Definition: xmlstorage.h:189
#define _ttoi
Definition: xmlstorage.h:195
const CHAR * LPCTSTR
Definition: xmlstorage.h:193
CHAR * LPTSTR
Definition: xmlstorage.h:192
#define _tcslen
Definition: xmlstorage.h:198