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 DWORD dwGroupLength
= 0;
102 DWORD dwServiceLength
= 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 dwLength
= wcslen(lpSrc
) + 1;
129 if (*lpSrc
== SC_GROUP_IDENTIFIERW
)
132 dwGroupLength
+= dwLength
;
133 wcscpy(lpDst
, lpSrc
);
134 lpDst
= lpDst
+ dwLength
;
137 lpSrc
= lpSrc
+ dwLength
;
143 lpSrc
= lpDependencies
;
144 lpServiceDeps
= lpDst
;
147 dwLength
= wcslen(lpSrc
) + 1;
148 if (*lpSrc
!= SC_GROUP_IDENTIFIERW
)
150 dwServiceLength
+= dwLength
;
151 wcscpy(lpDst
, lpSrc
);
152 lpDst
= lpDst
+ dwLength
;
155 lpSrc
= lpSrc
+ dwLength
;
160 if (dwGroupLength
> 1)
162 dwError
= RegSetValueExW(hServiceKey
,
167 dwGroupLength
* sizeof(WCHAR
));
171 RegDeleteValueW(hServiceKey
,
175 if (dwError
== ERROR_SUCCESS
)
177 if (dwServiceLength
> 1)
179 dwError
= RegSetValueExW(hServiceKey
,
183 (LPBYTE
)lpServiceDeps
,
184 dwServiceLength
* 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
;
262 dwError
= RegQueryValueExW(hServiceKey
,
268 if (dwError
!= ERROR_SUCCESS
)
271 ptr
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
273 return ERROR_NOT_ENOUGH_MEMORY
;
275 dwError
= RegQueryValueExW(hServiceKey
,
281 if (dwError
!= ERROR_SUCCESS
)
284 if (dwType
== REG_EXPAND_SZ
)
286 /* Expand the value... */
287 dwSizeNeeded
= ExpandEnvironmentStringsW((LPCWSTR
)ptr
, NULL
, 0);
288 if (dwSizeNeeded
== 0)
290 dwError
= GetLastError();
293 expanded
= HeapAlloc(GetProcessHeap(), 0, dwSizeNeeded
* sizeof(WCHAR
));
294 if (dwSizeNeeded
< ExpandEnvironmentStringsW((LPCWSTR
)ptr
, expanded
, dwSizeNeeded
))
296 dwError
= GetLastError();
300 HeapFree(GetProcessHeap(), 0, ptr
);
301 dwError
= ERROR_SUCCESS
;
309 if (dwError
!= ERROR_SUCCESS
)
311 HeapFree(GetProcessHeap(), 0, ptr
);
313 HeapFree(GetProcessHeap(), 0, expanded
);
321 ScmReadDependencies(HKEY hServiceKey
,
322 LPWSTR
*lpDependencies
,
323 DWORD
*lpdwDependenciesLength
)
325 LPWSTR lpGroups
= NULL
;
326 LPWSTR lpServices
= NULL
;
327 DWORD dwGroupsLength
= 0;
328 DWORD dwServicesLength
= 0;
334 *lpDependencies
= NULL
;
335 *lpdwDependenciesLength
= 0;
337 /* Read the dependency values */
338 ScmReadString(hServiceKey
,
342 ScmReadString(hServiceKey
,
346 /* Leave, if there are no dependencies */
347 if (lpGroups
== NULL
&& lpServices
== NULL
)
348 return ERROR_SUCCESS
;
350 /* Determine the total buffer size for the dependencies */
357 DPRINT(" %S\n", lpSrc
);
359 len
= wcslen(lpSrc
) + 1;
360 dwGroupsLength
+= len
+ 1;
368 DPRINT("Services:\n");
372 DPRINT(" %S\n", lpSrc
);
374 len
= wcslen(lpSrc
) + 1;
375 dwServicesLength
+= len
;
381 dwTotalLength
= dwGroupsLength
+ dwServicesLength
+ 1;
382 DPRINT("dwTotalLength: %lu\n", dwTotalLength
);
384 /* Allocate the common buffer for the dependencies */
385 *lpDependencies
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwTotalLength
* sizeof(WCHAR
));
386 if (*lpDependencies
== NULL
)
389 HeapFree(GetProcessHeap(), 0, lpGroups
);
392 HeapFree(GetProcessHeap(), 0, lpServices
);
394 return ERROR_NOT_ENOUGH_MEMORY
;
397 /* Return the allocated buffer length in characters */
398 *lpdwDependenciesLength
= dwTotalLength
;
400 /* Copy the service dependencies into the common buffer */
401 lpDest
= *lpDependencies
;
406 dwServicesLength
* sizeof(WCHAR
));
408 lpDest
= lpDest
+ dwServicesLength
;
411 /* Copy the group dependencies into the common buffer */
417 len
= wcslen(lpSrc
) + 1;
419 *lpDest
= SC_GROUP_IDENTIFIERW
;
422 wcscpy(lpDest
, lpSrc
);
424 lpDest
= lpDest
+ len
;
429 /* Free the temporary buffers */
431 HeapFree(GetProcessHeap(), 0, lpGroups
);
434 HeapFree(GetProcessHeap(), 0, lpServices
);
436 return ERROR_SUCCESS
;