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
)
133 cchGroupLength
+= cchLength
;
134 wcscpy(lpDst
, lpSrc
);
135 lpDst
= lpDst
+ cchLength
;
138 lpSrc
= lpSrc
+ cchLength
;
144 lpSrc
= lpDependencies
;
145 lpServiceDeps
= lpDst
;
148 cchLength
= wcslen(lpSrc
) + 1;
149 if (*lpSrc
!= SC_GROUP_IDENTIFIERW
)
151 cchServiceLength
+= cchLength
;
152 wcscpy(lpDst
, lpSrc
);
153 lpDst
= lpDst
+ cchLength
;
156 lpSrc
= lpSrc
+ cchLength
;
161 if (cchGroupLength
> 1)
163 dwError
= RegSetValueExW(hServiceKey
,
168 (DWORD
)(cchGroupLength
* sizeof(WCHAR
)));
172 RegDeleteValueW(hServiceKey
,
176 if (dwError
== ERROR_SUCCESS
)
178 if (cchServiceLength
> 1)
180 dwError
= RegSetValueExW(hServiceKey
,
184 (LPBYTE
)lpServiceDeps
,
185 (DWORD
)(cchServiceLength
* sizeof(WCHAR
)));
189 RegDeleteValueW(hServiceKey
,
194 HeapFree(GetProcessHeap(), 0, lpGroupDeps
);
202 ScmMarkServiceForDelete(PSERVICE pService
)
204 HKEY hServiceKey
= NULL
;
208 DPRINT("ScmMarkServiceForDelete() called\n");
210 dwError
= ScmOpenServiceKey(pService
->lpServiceName
,
213 if (dwError
!= ERROR_SUCCESS
)
216 dwError
= RegSetValueExW(hServiceKey
,
223 RegCloseKey(hServiceKey
);
230 ScmIsDeleteFlagSet(HKEY hServiceKey
)
235 DWORD dwSize
= sizeof(DWORD
);
237 dwError
= RegQueryValueExW(hServiceKey
,
244 return (dwError
== ERROR_SUCCESS
);
249 ScmReadString(HKEY hServiceKey
,
257 LPWSTR expanded
= NULL
;
261 dwError
= RegQueryValueExW(hServiceKey
,
267 if (dwError
!= ERROR_SUCCESS
)
270 ptr
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwSize
);
272 return ERROR_NOT_ENOUGH_MEMORY
;
274 dwError
= RegQueryValueExW(hServiceKey
,
280 if (dwError
!= ERROR_SUCCESS
)
282 HeapFree(GetProcessHeap(), 0, ptr
);
286 if (dwType
== REG_EXPAND_SZ
)
288 /* Expand the value... */
289 dwSize
= ExpandEnvironmentStringsW(ptr
, NULL
, 0);
292 expanded
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwSize
* sizeof(WCHAR
));
295 if (dwSize
== ExpandEnvironmentStringsW(ptr
, expanded
, dwSize
))
298 dwError
= ERROR_SUCCESS
;
302 dwError
= GetLastError();
303 HeapFree(GetProcessHeap(), 0, expanded
);
308 dwError
= ERROR_NOT_ENOUGH_MEMORY
;
313 dwError
= GetLastError();
316 HeapFree(GetProcessHeap(), 0, ptr
);
328 ScmReadDependencies(HKEY hServiceKey
,
329 LPWSTR
*lpDependencies
,
330 DWORD
*lpdwDependenciesLength
)
332 LPWSTR lpGroups
= NULL
;
333 LPWSTR lpServices
= NULL
;
334 SIZE_T cchGroupsLength
= 0;
335 SIZE_T cchServicesLength
= 0;
339 SIZE_T cchTotalLength
;
341 *lpDependencies
= NULL
;
342 *lpdwDependenciesLength
= 0;
344 /* Read the dependency values */
345 ScmReadString(hServiceKey
,
349 ScmReadString(hServiceKey
,
353 /* Leave, if there are no dependencies */
354 if (lpGroups
== NULL
&& lpServices
== NULL
)
355 return ERROR_SUCCESS
;
357 /* Determine the total buffer size for the dependencies */
364 DPRINT(" %S\n", lpSrc
);
366 cchLength
= wcslen(lpSrc
) + 1;
367 cchGroupsLength
+= cchLength
+ 1;
369 lpSrc
= lpSrc
+ cchLength
;
375 DPRINT("Services:\n");
379 DPRINT(" %S\n", lpSrc
);
381 cchLength
= wcslen(lpSrc
) + 1;
382 cchServicesLength
+= cchLength
;
384 lpSrc
= lpSrc
+ cchLength
;
388 cchTotalLength
= cchGroupsLength
+ cchServicesLength
+ 1;
389 DPRINT("cchTotalLength: %lu\n", cchTotalLength
);
391 /* Allocate the common buffer for the dependencies */
392 *lpDependencies
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, cchTotalLength
* sizeof(WCHAR
));
393 if (*lpDependencies
== NULL
)
396 HeapFree(GetProcessHeap(), 0, lpGroups
);
399 HeapFree(GetProcessHeap(), 0, lpServices
);
401 return ERROR_NOT_ENOUGH_MEMORY
;
404 /* Return the allocated buffer length in characters */
405 *lpdwDependenciesLength
= (DWORD
)cchTotalLength
;
407 /* Copy the service dependencies into the common buffer */
408 lpDest
= *lpDependencies
;
413 cchServicesLength
* sizeof(WCHAR
));
415 lpDest
= lpDest
+ cchServicesLength
;
418 /* Copy the group dependencies into the common buffer */
424 cchLength
= wcslen(lpSrc
) + 1;
426 *lpDest
= SC_GROUP_IDENTIFIERW
;
429 wcscpy(lpDest
, lpSrc
);
431 lpDest
= lpDest
+ cchLength
;
432 lpSrc
= lpSrc
+ cchLength
;
436 /* Free the temporary buffers */
438 HeapFree(GetProcessHeap(), 0, lpGroups
);
441 HeapFree(GetProcessHeap(), 0, lpServices
);
443 return ERROR_SUCCESS
;