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 LPWSTR 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
);
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 dwError
= RegSetValueExW(hServiceKey
,
165 dwGroupLength
* sizeof(WCHAR
));
167 if (dwError
== ERROR_SUCCESS
)
169 dwError
= RegSetValueExW(hServiceKey
,
173 (LPBYTE
)lpServiceDeps
,
174 dwServiceLength
* sizeof(WCHAR
));
177 HeapFree(GetProcessHeap(), 0, lpGroupDeps
);
185 ScmMarkServiceForDelete(PSERVICE pService
)
187 HKEY hServiceKey
= NULL
;
191 DPRINT("ScmMarkServiceForDelete() called\n");
193 dwError
= ScmOpenServiceKey(pService
->lpServiceName
,
196 if (dwError
!= ERROR_SUCCESS
)
199 dwError
= RegSetValueExW(hServiceKey
,
206 RegCloseKey(hServiceKey
);
213 ScmIsDeleteFlagSet(HKEY hServiceKey
)
218 DWORD dwSize
= sizeof(DWORD
);
220 dwError
= RegQueryValueExW(hServiceKey
,
227 return (dwError
== ERROR_SUCCESS
);
232 ScmReadString(HKEY hServiceKey
,
240 LPWSTR expanded
= NULL
;
246 dwError
= RegQueryValueExW(hServiceKey
,
252 if (dwError
!= ERROR_SUCCESS
)
255 ptr
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
257 return ERROR_NOT_ENOUGH_MEMORY
;
259 dwError
= RegQueryValueExW(hServiceKey
,
265 if (dwError
!= ERROR_SUCCESS
)
268 if (dwType
== REG_EXPAND_SZ
)
270 /* Expand the value... */
271 dwSizeNeeded
= ExpandEnvironmentStringsW((LPCWSTR
)ptr
, NULL
, 0);
272 if (dwSizeNeeded
== 0)
274 dwError
= GetLastError();
277 expanded
= HeapAlloc(GetProcessHeap(), 0, dwSizeNeeded
* sizeof(WCHAR
));
278 if (dwSizeNeeded
< ExpandEnvironmentStringsW((LPCWSTR
)ptr
, expanded
, dwSizeNeeded
))
280 dwError
= GetLastError();
284 HeapFree(GetProcessHeap(), 0, ptr
);
285 dwError
= ERROR_SUCCESS
;
293 if (dwError
!= ERROR_SUCCESS
)
295 HeapFree(GetProcessHeap(), 0, ptr
);
297 HeapFree(GetProcessHeap(), 0, expanded
);
305 ScmReadDependencies(HKEY hServiceKey
,
306 LPWSTR
*lpDependencies
,
307 DWORD
*lpdwDependenciesLength
)
309 LPWSTR lpGroups
= NULL
;
310 LPWSTR lpServices
= NULL
;
311 DWORD dwGroupsLength
= 0;
312 DWORD dwServicesLength
= 0;
318 *lpDependencies
= NULL
;
319 *lpdwDependenciesLength
= 0;
321 /* Read the dependency values */
322 ScmReadString(hServiceKey
,
326 ScmReadString(hServiceKey
,
330 /* Leave, if there are no dependencies */
331 if (lpGroups
== NULL
&& lpServices
== NULL
)
332 return ERROR_SUCCESS
;
334 /* Determine the total buffer size for the dependencies */
341 DPRINT(" %S\n", lpSrc
);
343 len
= wcslen(lpSrc
) + 1;
344 dwGroupsLength
+= len
+ 1;
352 DPRINT("Services:\n");
356 DPRINT(" %S\n", lpSrc
);
358 len
= wcslen(lpSrc
) + 1;
359 dwServicesLength
+= len
;
365 dwTotalLength
= dwGroupsLength
+ dwServicesLength
+ 1;
366 DPRINT("dwTotalLength: %lu\n", dwTotalLength
);
368 /* Allocate the common buffer for the dependencies */
369 *lpDependencies
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwTotalLength
* sizeof(WCHAR
));
370 if (*lpDependencies
== NULL
)
373 HeapFree(GetProcessHeap(), 0, lpGroups
);
376 HeapFree(GetProcessHeap(), 0, lpServices
);
378 return ERROR_NOT_ENOUGH_MEMORY
;
381 /* Return the allocated buffer length in characters */
382 *lpdwDependenciesLength
= dwTotalLength
;
384 /* Copy the service dependencies into the common buffer */
385 lpDest
= *lpDependencies
;
390 dwServicesLength
* sizeof(WCHAR
));
392 lpDest
= lpDest
+ dwServicesLength
;
395 /* Copy the group dependencies into the common buffer */
401 len
= wcslen(lpSrc
) + 1;
403 *lpDest
= SC_GROUP_IDENTIFIERW
;
406 wcscpy(lpDest
, lpSrc
);
408 lpDest
= lpDest
+ len
;
413 /* Free the temporary buffers */
415 HeapFree(GetProcessHeap(), 0, lpGroups
);
418 HeapFree(GetProcessHeap(), 0, lpServices
);
420 return ERROR_SUCCESS
;