ReactOS  0.4.14-dev-115-g4576127
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 
12 typedef struct
13 {
16 } OPTION_INFO;
17 
18 static 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 },
25  { _T("rec"), SERVICE_RECOGNIZER_DRIVER }
26 };
27 
28 static 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 
37 static 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 
45 static const OPTION_INFO TagOpts[] =
46 {
47  { _T("yes"), TRUE },
48  { _T("no"), FALSE }
49 };
50 
51 
52 BOOL
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 
163 BOOL
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 
258 BOOL
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 IN
Definition: typedefs.h:38
#define SERVICE_ERROR_IGNORE
Definition: cmtypes.h:979
#define _tprintf
Definition: tchar.h:506
#define SERVICE_SYSTEM_START
Definition: cmtypes.h:974
#define SERVICE_ERROR_NORMAL
Definition: cmtypes.h:980
#define TRUE
Definition: types.h:120
const CHAR * LPCTSTR
Definition: xmlstorage.h:193
#define lstrcmpi
Definition: winbase.h:3697
SC_ACTION_TYPE Type
Definition: winsvc.h:205
#define SERVICE_INTERACTIVE_PROCESS
Definition: cmtypes.h:965
_In_ DWORD nLength
Definition: wincon.h:461
static const OPTION_INFO TypeOpts[]
Definition: misc.c:18
static const OPTION_INFO TagOpts[]
Definition: misc.c:45
#define ZeroMemory
Definition: winbase.h:1642
int errno
int32_t INT_PTR
Definition: typedefs.h:62
#define SERVICE_RECOGNIZER_DRIVER
Definition: cmtypes.h:954
int32_t INT
Definition: typedefs.h:56
CHAR * LPTSTR
Definition: xmlstorage.h:192
DWORD Delay
Definition: winsvc.h:206
#define SERVICE_NO_CHANGE
Definition: winsvc.h:20
#define SERVICE_DISABLED
Definition: cmtypes.h:977
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
unsigned int BOOL
Definition: ntddk_ex.h:94
static const OPTION_INFO ErrorOpts[]
Definition: misc.c:37
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
smooth NULL
Definition: ftsmooth.c:416
#define SERVICE_BOOT_START
Definition: cmtypes.h:973
#define SERVICE_FILE_SYSTEM_DRIVER
Definition: cmtypes.h:952
#define SERVICE_WIN32_OWN_PROCESS
Definition: cmtypes.h:960
BOOL ParseFailureArguments(IN LPCTSTR *ServiceArgs, IN INT ArgCount, OUT LPCTSTR *ppServiceName, OUT LPSERVICE_FAILURE_ACTIONS pFailureActions)
Definition: misc.c:259
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define CopyMemory
Definition: winbase.h:1640
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SERVICE_WIN32_SHARE_PROCESS
Definition: cmtypes.h:961
#define ERANGE
Definition: acclib.h:92
#define _tcstoul
Definition: tchar.h:595
int CDECL _ttoi(const _TCHAR *str)
Definition: atoi.c:10
#define SERVICE_ERROR_SEVERE
Definition: cmtypes.h:981
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
DWORD dwValue
Definition: misc.c:15
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define SERVICE_AUTO_START
Definition: cmtypes.h:975
static const OPTION_INFO StartOpts[]
Definition: misc.c:28
#define OUT
Definition: typedefs.h:39
BOOL ParseFailureActions(IN LPCTSTR lpActions, OUT DWORD *pcActions, OUT SC_ACTION **ppActions)
Definition: misc.c:164
#define SERVICE_ERROR_CRITICAL
Definition: cmtypes.h:982
LPCTSTR lpOption
Definition: misc.c:14
GLfloat GLfloat p
Definition: glext.h:8902
#define SERVICE_DEMAND_START
Definition: cmtypes.h:976
#define INFINITE
Definition: serial.h:102
#define HeapFree(x, y, z)
Definition: compat.h:394
BOOL ParseCreateConfigArguments(LPCTSTR *ServiceArgs, INT ArgCount, BOOL bChangeService, OUT LPSERVICE_CREATE_INFO lpServiceInfo)
Definition: misc.c:53
#define SERVICE_KERNEL_DRIVER
Definition: cmtypes.h:951