24e4595a42a5ef05c7bf62012e0a077137544965
[reactos.git] / reactos / base / applications / sc / misc.c
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 {
14 LPCTSTR lpOption;
15 DWORD dwValue;
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
53 ParseCreateConfigArguments(
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
164 ParseFailureArguments(
165 IN LPCTSTR *ServiceArgs,
166 IN INT ArgCount,
167 OUT LPCTSTR *ppServiceName,
168 OUT LPSERVICE_FAILURE_ACTIONS pFailureActions)
169 {
170 INT /*i,*/ ArgIndex = 1;
171 LPCTSTR lpActions = NULL;
172 LPCTSTR lpReset = NULL;
173
174 if (ArgCount < 1)
175 return FALSE;
176
177 ZeroMemory(pFailureActions, sizeof(SERVICE_FAILURE_ACTIONS));
178
179 *ppServiceName = ServiceArgs[0];
180
181 ArgCount--;
182
183 while (ArgCount > 1)
184 {
185 if (!lstrcmpi(ServiceArgs[ArgIndex], _T("actions=")))
186 {
187 lpActions = (LPTSTR)ServiceArgs[ArgIndex + 1];
188 }
189 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("command=")))
190 {
191 pFailureActions->lpCommand = (LPTSTR)ServiceArgs[ArgIndex + 1];
192 }
193 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("reboot=")))
194 {
195 pFailureActions->lpRebootMsg = (LPTSTR)ServiceArgs[ArgIndex + 1];
196 }
197 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("reset=")))
198 {
199 lpReset = (LPTSTR)ServiceArgs[ArgIndex + 1];
200 }
201
202 ArgIndex += 2;
203 ArgCount -= 2;
204 }
205
206 if ((lpReset == NULL && lpActions != NULL) ||
207 (lpReset != NULL && lpActions == NULL))
208 {
209 _tprintf(_T("ERROR: The reset and actions options must be used simultaneously.\n\n"));
210 return FALSE;
211 }
212
213 if (lpReset != NULL)
214 {
215 if (!lstrcmpi(lpReset, _T("infinite")))
216 pFailureActions->dwResetPeriod = INFINITE;
217 else
218 pFailureActions->dwResetPeriod = _ttoi(lpReset);
219 }
220
221 if (lpActions != NULL)
222 {
223 /* FIXME */
224 }
225
226 return (ArgCount == 0);
227 }