ReactOS 0.4.15-dev-7918-g2a2556c
controlset.c File Reference
#include "services.h"
#include <debug.h>
Include dependency graph for controlset.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

LSTATUS WINAPI RegCopyTreeW (_In_ HKEY, _In_opt_ LPCWSTR, _In_ HKEY)
 
LSTATUS WINAPI RegDeleteTreeW (_In_ HKEY, _In_opt_ LPCWSTR)
 
static DWORD ScmGetControlSetValues (PDWORD pdwCurrentControlSet, PDWORD pdwDefaultControlSet, PDWORD pdwFailedControlSet, PDWORD pdwLastKnownGoodControlSet)
 
static DWORD ScmSetLastKnownGoodControlSet (DWORD dwControlSet)
 
static DWORD ScmGetSetupInProgress (VOID)
 
static DWORD ScmCopyControlSet (DWORD dwSourceControlSet, DWORD dwDestinationControlSet)
 
static DWORD ScmDeleteControlSet (DWORD dwControlSet)
 
DWORD ScmCreateLastKnownGoodControlSet (VOID)
 
DWORD ScmAcceptBoot (VOID)
 
DWORD ScmRunLastKnownGood (VOID)
 

Variables

static BOOL bBootAccepted = FALSE
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file controlset.c.

Function Documentation

◆ RegCopyTreeW()

LSTATUS WINAPI RegCopyTreeW ( _In_  HKEY,
_In_opt_  LPCWSTR,
_In_  HKEY 
)

Referenced by ScmCopyControlSet().

◆ RegDeleteTreeW()

◆ ScmAcceptBoot()

DWORD ScmAcceptBoot ( VOID  )

Definition at line 336 of file controlset.c.

337{
338 DWORD dwCurrentControlSet, dwDefaultControlSet;
339 DWORD dwFailedControlSet, dwLastKnownGoodControlSet;
340 DWORD dwNewControlSet;
341 DWORD dwError;
342
343 DPRINT("ScmAcceptBoot()\n");
344
345 if (bBootAccepted)
346 {
347 DPRINT1("Boot has already been accepted\n");
349 }
350
351 /* Get the control set values */
352 dwError = ScmGetControlSetValues(&dwCurrentControlSet,
353 &dwDefaultControlSet,
354 &dwFailedControlSet,
355 &dwLastKnownGoodControlSet);
356 if (dwError != ERROR_SUCCESS)
357 return dwError;
358
359 /* Search for a new control set number */
360 for (dwNewControlSet = 1; dwNewControlSet < 1000; dwNewControlSet++)
361 {
362 if ((dwNewControlSet != dwCurrentControlSet) &&
363 (dwNewControlSet != dwDefaultControlSet) &&
364 (dwNewControlSet != dwFailedControlSet) &&
365 (dwNewControlSet != dwLastKnownGoodControlSet))
366 break;
367 }
368
369 /* Fail if we did not find an unused control set!*/
370 if (dwNewControlSet >= 1000)
371 {
372 DPRINT1("Too many control sets\n");
373 return ERROR_NO_MORE_ITEMS;
374 }
375
376 /* Copy the current control set */
377 dwError = ScmCopyControlSet(dwCurrentControlSet,
378 dwNewControlSet);
379 if (dwError != ERROR_SUCCESS)
380 return dwError;
381
382 /* Delete the current last known good contol set, if it is not used anywhere else */
383 if ((dwLastKnownGoodControlSet != dwCurrentControlSet) &&
384 (dwLastKnownGoodControlSet != dwDefaultControlSet) &&
385 (dwLastKnownGoodControlSet != dwFailedControlSet))
386 {
387 ScmDeleteControlSet(dwLastKnownGoodControlSet);
388 }
389
390 /* Set the new 'LastKnownGood' control set */
391 dwError = ScmSetLastKnownGoodControlSet(dwNewControlSet);
392 if (dwError != ERROR_SUCCESS)
393 return dwError;
394
396
397 return ERROR_SUCCESS;
398}
#define DPRINT1
Definition: precomp.h:8
static DWORD ScmSetLastKnownGoodControlSet(DWORD dwControlSet)
Definition: controlset.c:112
static DWORD ScmDeleteControlSet(DWORD dwControlSet)
Definition: controlset.c:241
static DWORD ScmGetControlSetValues(PDWORD pdwCurrentControlSet, PDWORD pdwDefaultControlSet, PDWORD pdwFailedControlSet, PDWORD pdwLastKnownGoodControlSet)
Definition: controlset.c:29
static DWORD ScmCopyControlSet(DWORD dwSourceControlSet, DWORD dwDestinationControlSet)
Definition: controlset.c:178
static BOOL bBootAccepted
Definition: controlset.c:22
#define ERROR_SUCCESS
Definition: deptool.c:10
#define TRUE
Definition: types.h:120
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DPRINT
Definition: sndvol32.h:71
#define ERROR_BOOT_ALREADY_ACCEPTED
Definition: winerror.h:627

Referenced by RNotifyBootConfigStatus().

◆ ScmCopyControlSet()

static DWORD ScmCopyControlSet ( DWORD  dwSourceControlSet,
DWORD  dwDestinationControlSet 
)
static

Definition at line 178 of file controlset.c.

181{
182 WCHAR szSourceControlSetName[32];
183 WCHAR szDestinationControlSetName[32];
184 HKEY hSourceControlSetKey = NULL;
185 HKEY hDestinationControlSetKey = NULL;
186 DWORD dwDisposition;
187 DWORD dwError;
188
189 /* Create the source control set name */
190 swprintf(szSourceControlSetName, L"SYSTEM\\ControlSet%03lu", dwSourceControlSet);
191 DPRINT("Source control set: %S\n", szSourceControlSetName);
192
193 /* Create the destination control set name */
194 swprintf(szDestinationControlSetName, L"SYSTEM\\ControlSet%03lu", dwDestinationControlSet);
195 DPRINT("Destination control set: %S\n", szDestinationControlSetName);
196
197 /* Open the source control set key */
199 szSourceControlSetName,
200 0,
201 KEY_READ,
202 &hSourceControlSetKey);
203 if (dwError != ERROR_SUCCESS)
204 goto done;
205
206 /* Create the destination control set key */
208 szDestinationControlSetName,
209 0,
210 NULL,
212 KEY_WRITE,
213 NULL,
214 &hDestinationControlSetKey,
215 &dwDisposition);
216 if (dwError != ERROR_SUCCESS)
217 goto done;
218
219 /* Copy the source control set to the destination control set */
220 dwError = RegCopyTreeW(hSourceControlSetKey,
221 NULL,
222 hDestinationControlSetKey);
223 if (dwError != ERROR_SUCCESS)
224 goto done;
225
226 RegFlushKey(hDestinationControlSetKey);
227
228done:
229 if (hDestinationControlSetKey != NULL)
230 RegCloseKey(hDestinationControlSetKey);
231
232 if (hSourceControlSetKey != NULL)
233 RegCloseKey(hSourceControlSetKey);
234
235 return dwError;
236}
#define RegCloseKey(hKey)
Definition: registry.h:49
LSTATUS WINAPI RegCopyTreeW(_In_ HKEY, _In_opt_ LPCWSTR, _In_ HKEY)
#define NULL
Definition: types.h:112
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegFlushKey(HKEY hKey)
Definition: reg.c:2951
#define swprintf
Definition: precomp.h:40
#define KEY_READ
Definition: nt_native.h:1023
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WRITE
Definition: nt_native.h:1031
#define L(x)
Definition: ntvdm.h:50
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by ScmAcceptBoot(), and ScmCreateLastKnownGoodControlSet().

◆ ScmCreateLastKnownGoodControlSet()

DWORD ScmCreateLastKnownGoodControlSet ( VOID  )

Definition at line 275 of file controlset.c.

276{
277 DWORD dwCurrentControlSet, dwDefaultControlSet;
278 DWORD dwFailedControlSet, dwLastKnownGoodControlSet;
279 DWORD dwNewControlSet;
280 DWORD dwError;
281
282 /* Get the control set values */
283 dwError = ScmGetControlSetValues(&dwCurrentControlSet,
284 &dwDefaultControlSet,
285 &dwFailedControlSet,
286 &dwLastKnownGoodControlSet);
287 if (dwError != ERROR_SUCCESS)
288 return dwError;
289
290 /* First boot after setup? */
291 if ((ScmGetSetupInProgress() == 0) &&
292 (dwCurrentControlSet == dwLastKnownGoodControlSet))
293 {
294 DPRINT("First boot after setup\n");
295
296 /* Search for a new control set number */
297 for (dwNewControlSet = 1; dwNewControlSet < 1000; dwNewControlSet++)
298 {
299 if ((dwNewControlSet != dwCurrentControlSet) &&
300 (dwNewControlSet != dwDefaultControlSet) &&
301 (dwNewControlSet != dwFailedControlSet) &&
302 (dwNewControlSet != dwLastKnownGoodControlSet))
303 break;
304 }
305
306 /* Fail if we did not find an unused control set!*/
307 if (dwNewControlSet >= 1000)
308 {
309 DPRINT1("Too many control sets\n");
310 return ERROR_NO_MORE_ITEMS;
311 }
312
313 /* Copy the current control set */
314 dwError = ScmCopyControlSet(dwCurrentControlSet,
315 dwNewControlSet);
316 if (dwError != ERROR_SUCCESS)
317 return dwError;
318
319 /* Set the new 'LastKnownGood' control set */
320 dwError = ScmSetLastKnownGoodControlSet(dwNewControlSet);
321 if (dwError == ERROR_SUCCESS)
322 {
323 /*
324 * Accept the boot here in order to prevent the creation of
325 * another control set when a user is going to get logged on
326 */
328 }
329 }
330
331 return dwError;
332}
static DWORD ScmGetSetupInProgress(VOID)
Definition: controlset.c:142

Referenced by wWinMain().

◆ ScmDeleteControlSet()

static DWORD ScmDeleteControlSet ( DWORD  dwControlSet)
static

Definition at line 241 of file controlset.c.

243{
244 WCHAR szControlSetName[32];
245 HKEY hControlSetKey = NULL;
246 DWORD dwError;
247
248 DPRINT("ScmDeleteControSet(%lu)\n", dwControlSet);
249
250 /* Create the control set name */
251 swprintf(szControlSetName, L"SYSTEM\\ControlSet%03lu", dwControlSet);
252 DPRINT("Control set: %S\n", szControlSetName);
253
254 /* Open the system key */
256 szControlSetName,
257 0,
259 &hControlSetKey);
260 if (dwError != ERROR_SUCCESS)
261 return dwError;
262
263 /* Delete the control set */
264 dwError = RegDeleteTreeW(hControlSetKey,
265 NULL);
266
267 /* Open the system key */
268 RegCloseKey(hControlSetKey);
269
270 return dwError;
271}
LSTATUS WINAPI RegDeleteTreeW(_In_ HKEY, _In_opt_ LPCWSTR)
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define DELETE
Definition: nt_native.h:57
#define KEY_SET_VALUE
Definition: nt_native.h:1017

Referenced by ScmAcceptBoot().

◆ ScmGetControlSetValues()

static DWORD ScmGetControlSetValues ( PDWORD  pdwCurrentControlSet,
PDWORD  pdwDefaultControlSet,
PDWORD  pdwFailedControlSet,
PDWORD  pdwLastKnownGoodControlSet 
)
static

Definition at line 29 of file controlset.c.

34{
35 HKEY hSelectKey;
36 DWORD dwType;
38 DWORD dwError;
39
40 DPRINT("ScmGetControlSetValues() called\n");
41
43 L"System\\Select",
44 0,
46 &hSelectKey);
47 if (dwError != ERROR_SUCCESS)
48 return dwError;
49
50 dwSize = sizeof(DWORD);
51 dwError = RegQueryValueExW(hSelectKey,
52 L"Current",
53 0,
54 &dwType,
55 (LPBYTE)pdwCurrentControlSet,
56 &dwSize);
57 if (dwError != ERROR_SUCCESS)
58 {
59 *pdwCurrentControlSet = 0;
60 }
61
62 dwSize = sizeof(DWORD);
63 dwError = RegQueryValueExW(hSelectKey,
64 L"Default",
65 0,
66 &dwType,
67 (LPBYTE)pdwDefaultControlSet,
68 &dwSize);
69 if (dwError != ERROR_SUCCESS)
70 {
71 *pdwDefaultControlSet = 0;
72 }
73
74 dwSize = sizeof(DWORD);
75 dwError = RegQueryValueExW(hSelectKey,
76 L"Failed",
77 0,
78 &dwType,
79 (LPBYTE)pdwFailedControlSet,
80 &dwSize);
81 if (dwError != ERROR_SUCCESS)
82 {
83 *pdwFailedControlSet = 0;
84 }
85
86 dwSize = sizeof(DWORD);
87 dwError = RegQueryValueExW(hSelectKey,
88 L"LastKnownGood",
89 0,
90 &dwType,
91 (LPBYTE)pdwLastKnownGoodControlSet,
92 &dwSize);
93 if (dwError != ERROR_SUCCESS)
94 {
95 *pdwLastKnownGoodControlSet = 0;
96 }
97
98 RegCloseKey(hSelectKey);
99
100 DPRINT("ControlSets:\n");
101 DPRINT("Current: %lu\n", *pdwCurrentControlSet);
102 DPRINT("Default: %lu\n", *pdwDefaultControlSet);
103 DPRINT("Failed: %lu\n", *pdwFailedControlSet);
104 DPRINT("LastKnownGood: %lu\n", *pdwLastKnownGoodControlSet);
105
106 return dwError;
107}
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define DWORD
Definition: nt_native.h:44
unsigned char * LPBYTE
Definition: typedefs.h:53

Referenced by ScmAcceptBoot(), and ScmCreateLastKnownGoodControlSet().

◆ ScmGetSetupInProgress()

static DWORD ScmGetSetupInProgress ( VOID  )
static

Definition at line 142 of file controlset.c.

143{
144 DWORD dwError;
145 HKEY hKey;
146 DWORD dwType;
148 DWORD dwSetupInProgress = (DWORD)-1;
149
150 DPRINT("ScmGetSetupInProgress()\n");
151
152 /* Open key */
154 L"SYSTEM\\Setup",
155 0,
157 &hKey);
158 if (dwError == ERROR_SUCCESS)
159 {
160 /* Read key */
161 dwSize = sizeof(DWORD);
163 L"SystemSetupInProgress",
164 NULL,
165 &dwType,
166 (LPBYTE)&dwSetupInProgress,
167 &dwSize);
169 }
170
171 DPRINT("SetupInProgress: %lu\n", dwSetupInProgress);
172 return dwSetupInProgress;
173}
FxAutoRegKey hKey

Referenced by ScmCreateLastKnownGoodControlSet().

◆ ScmRunLastKnownGood()

DWORD ScmRunLastKnownGood ( VOID  )

Definition at line 402 of file controlset.c.

403{
404 DPRINT("ScmRunLastKnownGood()\n");
405
406 if (bBootAccepted)
407 {
408 DPRINT1("Boot has already been accepted\n");
410 }
411
412 /* FIXME */
413
414 return ERROR_SUCCESS;
415}

Referenced by RNotifyBootConfigStatus().

◆ ScmSetLastKnownGoodControlSet()

static DWORD ScmSetLastKnownGoodControlSet ( DWORD  dwControlSet)
static

Definition at line 112 of file controlset.c.

114{
115 HKEY hSelectKey;
116 DWORD dwError;
117
119 L"System\\Select",
120 0,
121 KEY_WRITE,
122 &hSelectKey);
123 if (dwError != ERROR_SUCCESS)
124 return dwError;
125
126 dwError = RegSetValueExW(hSelectKey,
127 L"LastKnownGood",
128 0,
129 REG_DWORD,
130 (LPBYTE)&dwControlSet,
131 sizeof(dwControlSet));
132
133 RegFlushKey(hSelectKey);
134 RegCloseKey(hSelectKey);
135
136 return dwError;
137}
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
#define REG_DWORD
Definition: sdbapi.c:596

Referenced by ScmAcceptBoot(), and ScmCreateLastKnownGoodControlSet().

Variable Documentation

◆ bBootAccepted

BOOL bBootAccepted = FALSE
static