2 * PROJECT: ReactOS Service Control Manager
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/system/services/config.c
5 * PURPOSE: Service configuration interface
6 * COPYRIGHT: Copyright 2005 Eric Kohl
10 /* INCLUDES *****************************************************************/
17 /* FUNCTIONS *****************************************************************/
21 ScmOpenServiceKey(LPWSTR lpServiceName
,
25 HKEY hServicesKey
= NULL
;
30 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
31 L
"System\\CurrentControlSet\\Services",
35 if (dwError
!= ERROR_SUCCESS
)
38 dwError
= RegOpenKeyExW(hServicesKey
,
44 RegCloseKey(hServicesKey
);
51 ScmCreateServiceKey(LPCWSTR lpServiceName
,
55 HKEY hServicesKey
= NULL
;
61 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
62 L
"System\\CurrentControlSet\\Services",
64 KEY_READ
| KEY_CREATE_SUB_KEY
,
66 if (dwError
!= ERROR_SUCCESS
)
69 dwError
= RegCreateKeyExW(hServicesKey
,
73 REG_OPTION_NON_VOLATILE
,
79 if ((dwError
== ERROR_SUCCESS
) &&
80 (dwDisposition
== REG_OPENED_EXISTING_KEY
))
84 dwError
= ERROR_SERVICE_EXISTS
;
88 RegCloseKey(hServicesKey
);
96 ScmWriteDependencies(HKEY hServiceKey
,
97 LPCWSTR lpDependencies
,
98 DWORD dwDependenciesLength
)
100 DWORD dwError
= ERROR_SUCCESS
;
101 SIZE_T cchGroupLength
= 0;
102 SIZE_T cchServiceLength
= 0;
105 LPWSTR lpServiceDeps
;
109 if (*lpDependencies
== 0)
111 RegDeleteValueW(hServiceKey
,
113 RegDeleteValueW(hServiceKey
,
118 lpGroupDeps
= HeapAlloc(GetProcessHeap(),
120 (dwDependenciesLength
+ 2) * sizeof(WCHAR
));
121 if (lpGroupDeps
== NULL
)
122 return ERROR_NOT_ENOUGH_MEMORY
;
124 lpSrc
= lpDependencies
;
128 cchLength
= wcslen(lpSrc
) + 1;
129 if (*lpSrc
== SC_GROUP_IDENTIFIERW
)
132 cchGroupLength
+= cchLength
;
133 wcscpy(lpDst
, lpSrc
);
134 lpDst
= lpDst
+ cchLength
;
137 lpSrc
= lpSrc
+ cchLength
;
143 lpSrc
= lpDependencies
;
144 lpServiceDeps
= lpDst
;
147 cchLength
= wcslen(lpSrc
) + 1;
148 if (*lpSrc
!= SC_GROUP_IDENTIFIERW
)
150 cchServiceLength
+= cchLength
;
151 wcscpy(lpDst
, lpSrc
);
152 lpDst
= lpDst
+ cchLength
;
155 lpSrc
= lpSrc
+ cchLength
;
160 if (cchGroupLength
> 1)
162 dwError
= RegSetValueExW(hServiceKey
,
167 (DWORD
)(cchGroupLength
* sizeof(WCHAR
)));
171 RegDeleteValueW(hServiceKey
,
175 if (dwError
== ERROR_SUCCESS
)
177 if (cchServiceLength
> 1)
179 dwError
= RegSetValueExW(hServiceKey
,
183 (LPBYTE
)lpServiceDeps
,
184 (DWORD
)(cchServiceLength
* sizeof(WCHAR
)));
188 RegDeleteValueW(hServiceKey
,
193 HeapFree(GetProcessHeap(), 0, lpGroupDeps
);
201 ScmMarkServiceForDelete(PSERVICE pService
)
203 HKEY hServiceKey
= NULL
;
207 DPRINT("ScmMarkServiceForDelete() called\n");
209 dwError
= ScmOpenServiceKey(pService
->lpServiceName
,
212 if (dwError
!= ERROR_SUCCESS
)
215 dwError
= RegSetValueExW(hServiceKey
,
222 RegCloseKey(hServiceKey
);
229 ScmIsDeleteFlagSet(HKEY hServiceKey
)
234 DWORD dwSize
= sizeof(DWORD
);
236 dwError
= RegQueryValueExW(hServiceKey
,
243 return (dwError
== ERROR_SUCCESS
);
248 ScmReadString(HKEY hServiceKey
,
256 LPWSTR expanded
= NULL
;
260 dwError
= RegQueryValueExW(hServiceKey
,
266 if (dwError
!= ERROR_SUCCESS
)
269 ptr
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwSize
);
271 return ERROR_NOT_ENOUGH_MEMORY
;
273 dwError
= RegQueryValueExW(hServiceKey
,
279 if (dwError
!= ERROR_SUCCESS
)
281 HeapFree(GetProcessHeap(), 0, ptr
);
285 if (dwType
== REG_EXPAND_SZ
)
287 /* Expand the value... */
288 dwSize
= ExpandEnvironmentStringsW(ptr
, NULL
, 0);
291 expanded
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwSize
* sizeof(WCHAR
));
294 if (dwSize
== ExpandEnvironmentStringsW(ptr
, expanded
, dwSize
))
297 dwError
= ERROR_SUCCESS
;
301 dwError
= GetLastError();
302 HeapFree(GetProcessHeap(), 0, expanded
);
307 dwError
= ERROR_NOT_ENOUGH_MEMORY
;
312 dwError
= GetLastError();
315 HeapFree(GetProcessHeap(), 0, ptr
);
327 ScmReadDependencies(HKEY hServiceKey
,
328 LPWSTR
*lpDependencies
,
329 DWORD
*lpdwDependenciesLength
)
331 LPWSTR lpGroups
= NULL
;
332 LPWSTR lpServices
= NULL
;
333 SIZE_T cchGroupsLength
= 0;
334 SIZE_T cchServicesLength
= 0;
338 SIZE_T cchTotalLength
;
340 *lpDependencies
= NULL
;
341 *lpdwDependenciesLength
= 0;
343 /* Read the dependency values */
344 ScmReadString(hServiceKey
,
348 ScmReadString(hServiceKey
,
352 /* Leave, if there are no dependencies */
353 if (lpGroups
== NULL
&& lpServices
== NULL
)
354 return ERROR_SUCCESS
;
356 /* Determine the total buffer size for the dependencies */
363 DPRINT(" %S\n", lpSrc
);
365 cchLength
= wcslen(lpSrc
) + 1;
366 cchGroupsLength
+= cchLength
+ 1;
368 lpSrc
= lpSrc
+ cchLength
;
374 DPRINT("Services:\n");
378 DPRINT(" %S\n", lpSrc
);
380 cchLength
= wcslen(lpSrc
) + 1;
381 cchServicesLength
+= cchLength
;
383 lpSrc
= lpSrc
+ cchLength
;
387 cchTotalLength
= cchGroupsLength
+ cchServicesLength
+ 1;
388 DPRINT("cchTotalLength: %lu\n", cchTotalLength
);
390 /* Allocate the common buffer for the dependencies */
391 *lpDependencies
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, cchTotalLength
* sizeof(WCHAR
));
392 if (*lpDependencies
== NULL
)
395 HeapFree(GetProcessHeap(), 0, lpGroups
);
398 HeapFree(GetProcessHeap(), 0, lpServices
);
400 return ERROR_NOT_ENOUGH_MEMORY
;
403 /* Return the allocated buffer length in characters */
404 *lpdwDependenciesLength
= (DWORD
)cchTotalLength
;
406 /* Copy the service dependencies into the common buffer */
407 lpDest
= *lpDependencies
;
412 cchServicesLength
* sizeof(WCHAR
));
414 lpDest
= lpDest
+ cchServicesLength
;
417 /* Copy the group dependencies into the common buffer */
423 cchLength
= wcslen(lpSrc
) + 1;
425 *lpDest
= SC_GROUP_IDENTIFIERW
;
428 wcscpy(lpDest
, lpSrc
);
430 lpDest
= lpDest
+ cchLength
;
431 lpSrc
= lpSrc
+ cchLength
;
435 /* Free the temporary buffers */
437 HeapFree(GetProcessHeap(), 0, lpGroups
);
440 HeapFree(GetProcessHeap(), 0, lpServices
);
442 return ERROR_SUCCESS
;