4c1143fa3f9cb38e878656e6a01b59600c4699b3
[reactos.git] / reactos / subsys / system / services / config.c
1 /*
2 * config.c
3 */
4
5 /* INCLUDES *****************************************************************/
6
7 #include "services.h"
8
9 #define NDEBUG
10 #include <debug.h>
11
12 /* FUNCTIONS *****************************************************************/
13
14
15 DWORD
16 ScmOpenServiceKey(LPWSTR lpServiceName,
17 REGSAM samDesired,
18 PHKEY phKey)
19 {
20 HKEY hServicesKey = NULL;
21 DWORD dwError;
22
23 *phKey = NULL;
24
25 dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
26 L"System\\CurrentControlSet\\Services",
27 0,
28 KEY_READ,
29 &hServicesKey);
30 if (dwError != ERROR_SUCCESS)
31 return dwError;
32
33 dwError = RegOpenKeyExW(hServicesKey,
34 lpServiceName,
35 0,
36 samDesired,
37 phKey);
38
39 RegCloseKey(hServicesKey);
40
41 return dwError;
42 }
43
44
45 DWORD
46 ScmCreateServiceKey(LPWSTR lpServiceName,
47 REGSAM samDesired,
48 PHKEY phKey)
49 {
50 HKEY hServicesKey = NULL;
51 DWORD dwDisposition;
52 DWORD dwError;
53
54 *phKey = NULL;
55
56 dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
57 L"System\\CurrentControlSet\\Services",
58 0,
59 KEY_READ | KEY_CREATE_SUB_KEY,
60 &hServicesKey);
61 if (dwError != ERROR_SUCCESS)
62 return dwError;
63
64 dwError = RegCreateKeyExW(hServicesKey,
65 lpServiceName,
66 0,
67 NULL,
68 REG_OPTION_NON_VOLATILE,
69 samDesired,
70 NULL,
71 phKey,
72 &dwDisposition);
73 #if 0
74 if ((dwError == ERROR_SUCCESS) &&
75 (dwDisposition == REG_OPENED_EXISTING_KEY))
76 {
77 RegCloseKey(*phKey);
78 *phKey = NULL;
79 dwError = ERROR_SERVICE_EXISTS;
80 }
81 #endif
82
83 RegCloseKey(hServicesKey);
84
85 return dwError;
86 }
87
88
89
90 DWORD
91 ScmWriteDependencies(HKEY hServiceKey,
92 LPWSTR lpDependencies,
93 DWORD dwDependenciesLength)
94 {
95 DWORD dwError = ERROR_SUCCESS;
96 DWORD dwGroupLength = 0;
97 DWORD dwServiceLength = 0;
98 DWORD dwLength;
99 LPWSTR lpGroupDeps;
100 LPWSTR lpServiceDeps;
101 LPWSTR lpSrc;
102 LPWSTR lpDst;
103
104 if (*lpDependencies == 0)
105 {
106 RegDeleteValue(hServiceKey,
107 L"DependOnService");
108 RegDeleteValue(hServiceKey,
109 L"DependOnGroup");
110 }
111 else
112 {
113 lpGroupDeps = HeapAlloc(GetProcessHeap(),
114 HEAP_ZERO_MEMORY,
115 (dwDependenciesLength + 2) * sizeof(WCHAR));
116 if (lpGroupDeps == NULL)
117 return ERROR_NOT_ENOUGH_MEMORY;
118
119 lpSrc = lpDependencies;
120 lpDst = lpGroupDeps;
121 while (*lpSrc != 0)
122 {
123 dwLength = wcslen(lpSrc);
124 if (*lpSrc == SC_GROUP_IDENTIFIERW)
125 {
126 lpSrc++;
127 dwGroupLength += dwLength;
128 wcscpy(lpDst, lpSrc);
129 lpDst = lpDst + dwLength;
130 }
131
132 lpSrc = lpSrc + dwLength;
133 }
134 *lpDst = 0;
135 lpDst++;
136 dwGroupLength++;
137
138 lpSrc = lpDependencies;
139 lpServiceDeps = lpDst;
140 while (*lpSrc != 0)
141 {
142 dwLength = wcslen(lpSrc) + 1;
143 if (*lpSrc != SC_GROUP_IDENTIFIERW)
144 {
145 dwServiceLength += dwLength;
146 wcscpy(lpDst, lpSrc);
147 lpDst = lpDst + dwLength;
148 }
149
150 lpSrc = lpSrc + dwLength;
151 }
152 *lpDst = 0;
153 dwServiceLength++;
154
155 dwError = RegSetValueExW(hServiceKey,
156 L"DependOnGroup",
157 0,
158 REG_MULTI_SZ,
159 (LPBYTE)lpGroupDeps,
160 dwGroupLength * sizeof(WCHAR));
161
162 if (dwError == ERROR_SUCCESS)
163 {
164 dwError = RegSetValueExW(hServiceKey,
165 L"DependOnService",
166 0,
167 REG_MULTI_SZ,
168 (LPBYTE)lpServiceDeps,
169 dwServiceLength * sizeof(WCHAR));
170 }
171
172 HeapFree(GetProcessHeap(), 0, lpGroupDeps);
173 }
174
175 return dwError;
176 }
177
178
179 DWORD
180 ScmMarkServiceForDelete(PSERVICE pService)
181 {
182 HKEY hServiceKey = NULL;
183 DWORD dwValue = 1;
184 DWORD dwError;
185
186 DPRINT("ScmMarkServiceForDelete() called\n");
187
188 dwError = ScmOpenServiceKey(pService->lpServiceName,
189 KEY_WRITE,
190 &hServiceKey);
191 if (dwError != ERROR_SUCCESS)
192 return dwError;
193
194 dwError = RegSetValueExW(hServiceKey,
195 L"DeleteFlag",
196 0,
197 REG_DWORD,
198 (LPBYTE)&dwValue,
199 sizeof(DWORD));
200
201 RegCloseKey(hServiceKey);
202
203 return dwError;
204 }
205
206
207 BOOL
208 ScmIsDeleteFlagSet(HKEY hServiceKey)
209 {
210 DWORD dwError;
211 DWORD dwType;
212 DWORD dwFlag;
213 DWORD dwSize = sizeof(DWORD);
214
215 dwError = RegQueryValueExW(hServiceKey,
216 L"DeleteFlag",
217 0,
218 &dwType,
219 (LPBYTE)&dwFlag,
220 &dwSize);
221
222 return (dwError == ERROR_SUCCESS);
223 }
224
225
226 DWORD
227 ScmReadString(HKEY hServiceKey,
228 LPWSTR lpValueName,
229 LPWSTR *lpValue)
230 {
231 DWORD dwError;
232 DWORD dwSize;
233 DWORD dwType;
234 DWORD dwSizeNeeded;
235 LPWSTR expanded = NULL;
236 LPWSTR ptr = NULL;
237
238 *lpValue = NULL;
239
240 dwSize = 0;
241 dwError = RegQueryValueExW(hServiceKey,
242 lpValueName,
243 0,
244 &dwType,
245 NULL,
246 &dwSize);
247 if (dwError != ERROR_SUCCESS)
248 return dwError;
249
250 ptr = HeapAlloc(GetProcessHeap(), 0, dwSize);
251 if (ptr == NULL)
252 return ERROR_NOT_ENOUGH_MEMORY;
253
254 dwError = RegQueryValueExW(hServiceKey,
255 lpValueName,
256 0,
257 &dwType,
258 (LPBYTE)ptr,
259 &dwSize);
260 if (dwError != ERROR_SUCCESS)
261 goto done;
262
263 if (dwType == REG_EXPAND_SZ)
264 {
265 /* Expand the value... */
266 dwSizeNeeded = ExpandEnvironmentStringsW((LPCWSTR)ptr, NULL, 0);
267 if (dwSizeNeeded == 0)
268 {
269 dwError = GetLastError();
270 goto done;
271 }
272 expanded = HeapAlloc(GetProcessHeap(), 0, dwSizeNeeded * sizeof(WCHAR));
273 if (dwSizeNeeded < ExpandEnvironmentStringsW((LPCWSTR)ptr, expanded, dwSizeNeeded))
274 {
275 dwError = GetLastError();
276 goto done;
277 }
278 *lpValue = expanded;
279 HeapFree(GetProcessHeap(), 0, ptr);
280 dwError = ERROR_SUCCESS;
281 }
282 else
283 {
284 *lpValue = ptr;
285 }
286
287 done:;
288 if (dwError != ERROR_SUCCESS)
289 {
290 HeapFree(GetProcessHeap(), 0, ptr);
291 HeapFree(GetProcessHeap(), 0, expanded);
292 }
293
294 return dwError;
295 }
296
297 /* EOF */
298