[CMAKE]
[reactos.git] / base / applications / sc / create.c
1 /*
2 * PROJECT: ReactOS Services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/system/sc/create.c
5 * PURPOSE: Create a service
6 * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy <gedmurphy@gmail.com>
7 * Roel Messiant <roelmessiant@gmail.com>
8 *
9 */
10
11 #include "sc.h"
12
13
14 typedef struct
15 {
16 LPCTSTR lpOption;
17 DWORD dwValue;
18 } OPTION_INFO;
19
20 typedef struct
21 {
22 LPCTSTR lpServiceName;
23 LPCTSTR lpDisplayName;
24 DWORD dwServiceType;
25 DWORD dwStartType;
26 DWORD dwErrorControl;
27 LPCTSTR lpBinaryPathName;
28 LPCTSTR lpLoadOrderGroup;
29 DWORD dwTagId;
30 LPCTSTR lpDependencies;
31 LPCTSTR lpServiceStartName;
32 LPCTSTR lpPassword;
33
34 BOOL bTagId;
35 } SERVICE_CREATE_INFO, *LPSERVICE_CREATE_INFO;
36
37
38 static const OPTION_INFO TypeOpts[] =
39 {
40 { _T("own"), SERVICE_WIN32_OWN_PROCESS },
41 { _T("share"), SERVICE_WIN32_SHARE_PROCESS },
42 { _T("interact"), SERVICE_INTERACTIVE_PROCESS },
43 { _T("kernel"), SERVICE_KERNEL_DRIVER },
44 { _T("filesys"), SERVICE_FILE_SYSTEM_DRIVER },
45 { _T("rec"), SERVICE_RECOGNIZER_DRIVER }
46 };
47
48 static const OPTION_INFO StartOpts[] =
49 {
50 { _T("boot"), SERVICE_BOOT_START },
51 { _T("system"), SERVICE_SYSTEM_START },
52 { _T("auto"), SERVICE_AUTO_START },
53 { _T("demand"), SERVICE_DEMAND_START },
54 { _T("disabled"), SERVICE_DISABLED }
55 };
56
57 static const OPTION_INFO ErrorOpts[] =
58 {
59 { _T("normal"), SERVICE_ERROR_NORMAL },
60 { _T("severe"), SERVICE_ERROR_SEVERE },
61 { _T("critical"), SERVICE_ERROR_CRITICAL },
62 { _T("ignore"), SERVICE_ERROR_IGNORE }
63 };
64
65 static const OPTION_INFO TagOpts[] =
66 {
67 { _T("yes"), TRUE },
68 { _T("no"), FALSE }
69 };
70
71
72 static BOOL ParseCreateArguments(
73 LPCTSTR *ServiceArgs,
74 INT ArgCount,
75 OUT LPSERVICE_CREATE_INFO lpServiceInfo
76 )
77 {
78 INT i, ArgIndex = 1;
79
80 if (ArgCount < 1)
81 return FALSE;
82
83 ZeroMemory(lpServiceInfo, sizeof(SERVICE_CREATE_INFO));
84
85 lpServiceInfo->lpServiceName = ServiceArgs[0];
86
87 ArgCount--;
88
89 while (ArgCount > 1)
90 {
91 if (!lstrcmpi(ServiceArgs[ArgIndex], _T("type=")))
92 {
93 for (i = 0; i < sizeof(TypeOpts) / sizeof(TypeOpts[0]); i++)
94 if (!lstrcmpi(ServiceArgs[ArgIndex + 1], TypeOpts[i].lpOption))
95 {
96 lpServiceInfo->dwServiceType |= TypeOpts[i].dwValue;
97 break;
98 }
99
100 if (i == sizeof(TypeOpts) / sizeof(TypeOpts[0]))
101 break;
102 }
103 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("start=")))
104 {
105 for (i = 0; i < sizeof(StartOpts) / sizeof(StartOpts[0]); i++)
106 if (!lstrcmpi(ServiceArgs[ArgIndex + 1], StartOpts[i].lpOption))
107 {
108 lpServiceInfo->dwStartType = StartOpts[i].dwValue;
109 break;
110 }
111
112 if (i == sizeof(StartOpts) / sizeof(StartOpts[0]))
113 break;
114 }
115 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("error=")))
116 {
117 for (i = 0; i < sizeof(ErrorOpts) / sizeof(ErrorOpts[0]); i++)
118 if (!lstrcmpi(ServiceArgs[ArgIndex + 1], ErrorOpts[i].lpOption))
119 {
120 lpServiceInfo->dwErrorControl = ErrorOpts[i].dwValue;
121 break;
122 }
123
124 if (i == sizeof(ErrorOpts) / sizeof(ErrorOpts[0]))
125 break;
126 }
127 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("tag=")))
128 {
129 for (i = 0; i < sizeof(TagOpts) / sizeof(TagOpts[0]); i++)
130 if (!lstrcmpi(ServiceArgs[ArgIndex + 1], TagOpts[i].lpOption))
131 {
132 lpServiceInfo->bTagId = TagOpts[i].dwValue;
133 break;
134 }
135
136 if (i == sizeof(TagOpts) / sizeof(TagOpts[0]))
137 break;
138 }
139 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("binpath=")))
140 {
141 lpServiceInfo->lpBinaryPathName = ServiceArgs[ArgIndex + 1];
142 }
143 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("group=")))
144 {
145 lpServiceInfo->lpLoadOrderGroup = ServiceArgs[ArgIndex + 1];
146 }
147 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("depend=")))
148 {
149 lpServiceInfo->lpDependencies = ServiceArgs[ArgIndex + 1];
150 }
151 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("obj=")))
152 {
153 lpServiceInfo->lpServiceStartName = ServiceArgs[ArgIndex + 1];
154 }
155 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("displayname=")))
156 {
157 lpServiceInfo->lpDisplayName = ServiceArgs[ArgIndex + 1];
158 }
159 else if (!lstrcmpi(ServiceArgs[ArgIndex], _T("password=")))
160 {
161 lpServiceInfo->lpPassword = ServiceArgs[ArgIndex + 1];
162 }
163
164 ArgIndex += 2;
165 ArgCount -= 2;
166 }
167
168 return (ArgCount == 0);
169 }
170
171 BOOL Create(LPCTSTR *ServiceArgs, INT ArgCount)
172 {
173 SC_HANDLE hSCManager;
174 SC_HANDLE hSc;
175 BOOL bRet = FALSE;
176
177 INT i;
178 INT Length;
179 LPTSTR lpBuffer = NULL;
180 SERVICE_CREATE_INFO ServiceInfo;
181
182 if (!ParseCreateArguments(ServiceArgs, ArgCount, &ServiceInfo))
183 {
184 CreateUsage();
185 return FALSE;
186 }
187
188 if (!ServiceInfo.dwServiceType)
189 ServiceInfo.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
190
191 if (!ServiceInfo.dwStartType)
192 ServiceInfo.dwStartType = SERVICE_DEMAND_START;
193
194 if (!ServiceInfo.dwErrorControl)
195 ServiceInfo.dwErrorControl = SERVICE_ERROR_NORMAL;
196
197 if (ServiceInfo.lpDependencies)
198 {
199 Length = lstrlen(ServiceInfo.lpDependencies);
200
201 lpBuffer = HeapAlloc(GetProcessHeap(),
202 0,
203 (Length + 2) * sizeof(TCHAR));
204
205 for (i = 0; i < Length; i++)
206 if (ServiceInfo.lpDependencies[i] == _T('/'))
207 lpBuffer[i] = 0;
208 else
209 lpBuffer[i] = ServiceInfo.lpDependencies[i];
210
211 lpBuffer[Length] = 0;
212 lpBuffer[Length + 1] = 0;
213
214 ServiceInfo.lpDependencies = lpBuffer;
215 }
216
217 #ifdef SCDBG
218 _tprintf(_T("service name - %s\n"), ServiceInfo.lpServiceName);
219 _tprintf(_T("display name - %s\n"), ServiceInfo.lpDisplayName);
220 _tprintf(_T("service type - %lu\n"), ServiceInfo.dwServiceType);
221 _tprintf(_T("start type - %lu\n"), ServiceInfo.dwStartType);
222 _tprintf(_T("error control - %lu\n"), ServiceInfo.dwErrorControl);
223 _tprintf(_T("Binary path - %s\n"), ServiceInfo.lpBinaryPathName);
224 _tprintf(_T("load order group - %s\n"), ServiceInfo.lpLoadOrderGroup);
225 _tprintf(_T("tag - %lu\n"), ServiceInfo.dwTagId);
226 _tprintf(_T("dependencies - %s\n"), ServiceInfo.lpDependencies);
227 _tprintf(_T("account start name - %s\n"), ServiceInfo.lpServiceStartName);
228 _tprintf(_T("account password - %s\n"), ServiceInfo.lpPassword);
229 #endif
230
231 hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
232
233 if (hSCManager != NULL)
234 {
235 hSc = CreateService(hSCManager,
236 ServiceInfo.lpServiceName,
237 ServiceInfo.lpDisplayName,
238 SERVICE_ALL_ACCESS,
239 ServiceInfo.dwServiceType,
240 ServiceInfo.dwStartType,
241 ServiceInfo.dwErrorControl,
242 ServiceInfo.lpBinaryPathName,
243 ServiceInfo.lpLoadOrderGroup,
244 ServiceInfo.bTagId ? &ServiceInfo.dwTagId : NULL,
245 ServiceInfo.lpDependencies,
246 ServiceInfo.lpServiceStartName,
247 ServiceInfo.lpPassword);
248
249 if (hSc != NULL)
250 {
251 _tprintf(_T("[SC] CreateService SUCCESS\n"));
252
253 CloseServiceHandle(hSc);
254 bRet = TRUE;
255 }
256 else
257 ReportLastError();
258
259 CloseServiceHandle(hSCManager);
260 }
261 else
262 ReportLastError();
263
264 if (lpBuffer != NULL)
265 HeapFree(GetProcessHeap(), 0, lpBuffer);
266
267 return bRet;
268 }