ReactOS  0.4.15-dev-3316-g067ca88
controlset.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Service Control Manager
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: base/system/services/controlset.c
5  * PURPOSE: Control Set Management
6  * COPYRIGHT: Copyright 2012 Eric Kohl
7  *
8  */
9 
10 /* INCLUDES *****************************************************************/
11 
12 #include "services.h"
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 
18 /* GLOBALS *******************************************************************/
19 
21 
22 
23 /* FUNCTIONS *****************************************************************/
24 
25 #if (_WIN32_WINNT < 0x0600)
26 static
27 DWORD
29  HKEY hSrcKey,
30  HKEY hDstKey)
31 {
32  DWORD dwSubKeys;
33  DWORD dwValues;
34  DWORD dwType;
35  DWORD dwMaxSubKeyNameLength;
36  DWORD dwSubKeyNameLength;
37  DWORD dwMaxValueNameLength;
38  DWORD dwValueNameLength;
39  DWORD dwMaxValueLength;
40  DWORD dwValueLength;
41  DWORD dwDisposition;
42  DWORD i;
44  LPBYTE lpDataBuffer;
45  HKEY hDstSubKey;
46  HKEY hSrcSubKey;
47  DWORD dwError;
48 
49  DPRINT("ScmCopyTree()\n");
50 
51  dwError = RegQueryInfoKey(hSrcKey,
52  NULL,
53  NULL,
54  NULL,
55  &dwSubKeys,
56  &dwMaxSubKeyNameLength,
57  NULL,
58  &dwValues,
59  &dwMaxValueNameLength,
60  &dwMaxValueLength,
61  NULL,
62  NULL);
63  if (dwError != ERROR_SUCCESS)
64  {
65  DPRINT1("RegQueryInfoKey() failed (Error %lu)\n", dwError);
66  return dwError;
67  }
68 
69  dwMaxSubKeyNameLength++;
70  dwMaxValueNameLength++;
71 
72  DPRINT("dwSubKeys %lu\n", dwSubKeys);
73  DPRINT("dwMaxSubKeyNameLength %lu\n", dwMaxSubKeyNameLength);
74  DPRINT("dwValues %lu\n", dwValues);
75  DPRINT("dwMaxValueNameLength %lu\n", dwMaxValueNameLength);
76  DPRINT("dwMaxValueLength %lu\n", dwMaxValueLength);
77 
78  /* Copy subkeys */
79  if (dwSubKeys != 0)
80  {
82  0,
83  dwMaxSubKeyNameLength * sizeof(WCHAR));
84  if (lpNameBuffer == NULL)
85  {
86  DPRINT1("Buffer allocation failed\n");
88  }
89 
90  for (i = 0; i < dwSubKeys; i++)
91  {
92  dwSubKeyNameLength = dwMaxSubKeyNameLength;
93  dwError = RegEnumKeyExW(hSrcKey,
94  i,
96  &dwSubKeyNameLength,
97  NULL,
98  NULL,
99  NULL,
100  NULL);
101  if (dwError != ERROR_SUCCESS)
102  {
103  DPRINT1("Subkey enumeration failed (Error %lu)\n", dwError);
105  0,
106  lpNameBuffer);
107  return dwError;
108  }
109 
110  dwError = RegCreateKeyExW(hDstKey,
111  lpNameBuffer,
112  0,
113  NULL,
115  KEY_WRITE,
116  NULL,
117  &hDstSubKey,
118  &dwDisposition);
119  if (dwError != ERROR_SUCCESS)
120  {
121  DPRINT1("Subkey creation failed (Error %lu)\n", dwError);
123  0,
124  lpNameBuffer);
125  return dwError;
126  }
127 
128  dwError = RegOpenKeyExW(hSrcKey,
129  lpNameBuffer,
130  0,
131  KEY_READ,
132  &hSrcSubKey);
133  if (dwError != ERROR_SUCCESS)
134  {
135  DPRINT1("Error: %lu\n", dwError);
136  RegCloseKey(hDstSubKey);
138  0,
139  lpNameBuffer);
140  return dwError;
141  }
142 
143  dwError = ScmCopyTree(hSrcSubKey,
144  hDstSubKey);
145  if (dwError != ERROR_SUCCESS)
146  {
147  DPRINT1("Error: %lu\n", dwError);
148  RegCloseKey (hSrcSubKey);
149  RegCloseKey (hDstSubKey);
151  0,
152  lpNameBuffer);
153  return dwError;
154  }
155 
156  RegCloseKey(hSrcSubKey);
157  RegCloseKey(hDstSubKey);
158  }
159 
161  0,
162  lpNameBuffer);
163  }
164 
165  /* Copy values */
166  if (dwValues != 0)
167  {
169  0,
170  dwMaxValueNameLength * sizeof(WCHAR));
171  if (lpNameBuffer == NULL)
172  {
173  DPRINT1("Buffer allocation failed\n");
175  }
176 
177  /* RegSetValueExW tries to read behind the maximum length, so give it space for that */
178  lpDataBuffer = HeapAlloc(GetProcessHeap(),
180  dwMaxValueLength + sizeof(WCHAR));
181  if (lpDataBuffer == NULL)
182  {
183  DPRINT1("Buffer allocation failed\n");
185  0,
186  lpNameBuffer);
188  }
189 
190  for (i = 0; i < dwValues; i++)
191  {
192  dwValueNameLength = dwMaxValueNameLength;
193  dwValueLength = dwMaxValueLength;
194  dwError = RegEnumValueW(hSrcKey,
195  i,
196  lpNameBuffer,
197  &dwValueNameLength,
198  NULL,
199  &dwType,
200  lpDataBuffer,
201  &dwValueLength);
202  if (dwError != ERROR_SUCCESS)
203  {
204  DPRINT1("Error: %lu\n", dwError);
206  0,
207  lpDataBuffer);
209  0,
210  lpNameBuffer);
211  return dwError;
212  }
213 
214  dwError = RegSetValueExW(hDstKey,
215  lpNameBuffer,
216  0,
217  dwType,
218  lpDataBuffer,
219  dwValueLength);
220  if (dwError != ERROR_SUCCESS)
221  {
222  DPRINT1("Error: %lu\n", dwError);
224  0,
225  lpDataBuffer);
227  0,
228  lpNameBuffer);
229  return dwError;
230  }
231  }
232 
234  0,
235  lpDataBuffer);
236 
238  0,
239  lpNameBuffer);
240  }
241 
242  DPRINT("ScmCopyTree() done\n");
243 
244  return ERROR_SUCCESS;
245 }
246 
247 
248 DWORD
250  HKEY hKey,
251  PCWSTR pszSubKey)
252 {
253  DWORD dwMaxSubkeyLength, dwMaxValueLength;
254  DWORD dwMaxLength, dwSize;
255  PWSTR pszName = NULL;
256  HKEY hSubKey = NULL;
257  DWORD dwError;
258 
259  if (pszSubKey != NULL)
260  {
261  dwError = RegOpenKeyExW(hKey, pszSubKey, 0, KEY_READ, &hSubKey);
262  if (dwError != ERROR_SUCCESS)
263  return dwError;
264  }
265  else
266  {
267  hSubKey = hKey;
268  }
269 
270  /* Get highest length for keys, values */
271  dwError = RegQueryInfoKeyW(hSubKey,
272  NULL,
273  NULL,
274  NULL,
275  NULL,
276  &dwMaxSubkeyLength,
277  NULL,
278  NULL,
279  &dwMaxValueLength,
280  NULL,
281  NULL,
282  NULL);
283  if (dwError != ERROR_SUCCESS)
284  goto done;
285 
286  dwMaxSubkeyLength++;
287  dwMaxValueLength++;
288  dwMaxLength = max(dwMaxSubkeyLength, dwMaxValueLength);
289 
290  /* Allocate a buffer for key and value names */
291  pszName = HeapAlloc(GetProcessHeap(),
292  0,
293  dwMaxLength * sizeof(WCHAR));
294  if (pszName == NULL)
295  {
296  dwError = ERROR_NOT_ENOUGH_MEMORY;
297  goto done;
298  }
299 
300  /* Recursively delete all the subkeys */
301  while (TRUE)
302  {
303  dwSize = dwMaxLength;
304  if (RegEnumKeyExW(hSubKey,
305  0,
306  pszName,
307  &dwSize,
308  NULL,
309  NULL,
310  NULL,
311  NULL))
312  break;
313 
314  dwError = ScmDeleteTree(hSubKey, pszName);
315  if (dwError != ERROR_SUCCESS)
316  goto done;
317  }
318 
319  if (pszSubKey != NULL)
320  {
321  dwError = RegDeleteKeyW(hKey, pszSubKey);
322  }
323  else
324  {
325  while (TRUE)
326  {
327  dwSize = dwMaxLength;
328  if (RegEnumValueW(hKey,
329  0,
330  pszName,
331  &dwSize,
332  NULL,
333  NULL,
334  NULL,
335  NULL))
336  break;
337 
338  dwError = RegDeleteValueW(hKey, pszName);
339  if (dwError != ERROR_SUCCESS)
340  goto done;
341  }
342  }
343 
344 done:
345  if (pszName != NULL)
346  HeapFree(GetProcessHeap(), 0, pszName);
347 
348  if (pszSubKey != NULL)
349  RegCloseKey(hSubKey);
350 
351  return dwError;
352 }
353 #endif
354 
355 
356 static
357 DWORD
359  PDWORD pdwCurrentControlSet,
360  PDWORD pdwDefaultControlSet,
361  PDWORD pdwFailedControlSet,
362  PDWORD pdwLastKnownGoodControlSet)
363 {
364  HKEY hSelectKey;
365  DWORD dwType;
366  DWORD dwSize;
367  DWORD dwError;
368 
369  DPRINT("ScmGetControlSetValues() called\n");
370 
372  L"System\\Select",
373  0,
374  KEY_READ,
375  &hSelectKey);
376  if (dwError != ERROR_SUCCESS)
377  return dwError;
378 
379  dwSize = sizeof(DWORD);
380  dwError = RegQueryValueExW(hSelectKey,
381  L"Current",
382  0,
383  &dwType,
384  (LPBYTE)pdwCurrentControlSet,
385  &dwSize);
386  if (dwError != ERROR_SUCCESS)
387  {
388  *pdwCurrentControlSet = 0;
389  }
390 
391  dwSize = sizeof(DWORD);
392  dwError = RegQueryValueExW(hSelectKey,
393  L"Default",
394  0,
395  &dwType,
396  (LPBYTE)pdwDefaultControlSet,
397  &dwSize);
398  if (dwError != ERROR_SUCCESS)
399  {
400  *pdwDefaultControlSet = 0;
401  }
402 
403  dwSize = sizeof(DWORD);
404  dwError = RegQueryValueExW(hSelectKey,
405  L"Failed",
406  0,
407  &dwType,
408  (LPBYTE)pdwFailedControlSet,
409  &dwSize);
410  if (dwError != ERROR_SUCCESS)
411  {
412  *pdwFailedControlSet = 0;
413  }
414 
415  dwSize = sizeof(DWORD);
416  dwError = RegQueryValueExW(hSelectKey,
417  L"LastKnownGood",
418  0,
419  &dwType,
420  (LPBYTE)pdwLastKnownGoodControlSet,
421  &dwSize);
422  if (dwError != ERROR_SUCCESS)
423  {
424  *pdwLastKnownGoodControlSet = 0;
425  }
426 
427  RegCloseKey(hSelectKey);
428 
429  DPRINT("ControlSets:\n");
430  DPRINT("Current: %lu\n", *pdwCurrentControlSet);
431  DPRINT("Default: %lu\n", *pdwDefaultControlSet);
432  DPRINT("Failed: %lu\n", *pdwFailedControlSet);
433  DPRINT("LastKnownGood: %lu\n", *pdwLastKnownGoodControlSet);
434 
435  return dwError;
436 }
437 
438 
439 static
440 DWORD
442  DWORD dwControlSet)
443 {
444  HKEY hSelectKey;
445  DWORD dwError;
446 
448  L"System\\Select",
449  0,
450  KEY_WRITE,
451  &hSelectKey);
452  if (dwError != ERROR_SUCCESS)
453  return dwError;
454 
455  dwError = RegSetValueExW(hSelectKey,
456  L"LastKnownGood",
457  0,
458  REG_DWORD,
459  (LPBYTE)&dwControlSet,
460  sizeof(dwControlSet));
461 
462  RegFlushKey(hSelectKey);
463  RegCloseKey(hSelectKey);
464 
465  return dwError;
466 }
467 
468 
469 static
470 DWORD
472 {
473  DWORD dwError;
474  HKEY hKey;
475  DWORD dwType;
476  DWORD dwSize;
477  DWORD dwSetupInProgress = (DWORD)-1;
478 
479  DPRINT("ScmGetSetupInProgress()\n");
480 
481  /* Open key */
483  L"SYSTEM\\Setup",
484  0,
486  &hKey);
487  if (dwError == ERROR_SUCCESS)
488  {
489  /* Read key */
490  dwSize = sizeof(DWORD);
492  L"SystemSetupInProgress",
493  NULL,
494  &dwType,
495  (LPBYTE)&dwSetupInProgress,
496  &dwSize);
497  RegCloseKey(hKey);
498  }
499 
500  DPRINT("SetupInProgress: %lu\n", dwSetupInProgress);
501  return dwSetupInProgress;
502 }
503 
504 
505 static
506 DWORD
508  DWORD dwSourceControlSet,
509  DWORD dwDestinationControlSet)
510 {
511  WCHAR szSourceControlSetName[32];
512  WCHAR szDestinationControlSetName[32];
513  HKEY hSourceControlSetKey = NULL;
514  HKEY hDestinationControlSetKey = NULL;
515  DWORD dwDisposition;
516  DWORD dwError;
517 
518  /* Create the source control set name */
519  swprintf(szSourceControlSetName, L"SYSTEM\\ControlSet%03lu", dwSourceControlSet);
520  DPRINT("Source control set: %S\n", szSourceControlSetName);
521 
522  /* Create the destination control set name */
523  swprintf(szDestinationControlSetName, L"SYSTEM\\ControlSet%03lu", dwDestinationControlSet);
524  DPRINT("Destination control set: %S\n", szDestinationControlSetName);
525 
526  /* Open the source control set key */
528  szSourceControlSetName,
529  0,
530  KEY_READ,
531  &hSourceControlSetKey);
532  if (dwError != ERROR_SUCCESS)
533  goto done;
534 
535  /* Create the destination control set key */
537  szDestinationControlSetName,
538  0,
539  NULL,
541  KEY_WRITE,
542  NULL,
543  &hDestinationControlSetKey,
544  &dwDisposition);
545  if (dwError != ERROR_SUCCESS)
546  goto done;
547 
548  /* Copy the source control set to the destination control set */
549 #if (_WIN32_WINNT >= 0x0600)
550  dwError = RegCopyTreeW(hSourceControlSetKey,
551  NULL,
552  hDestinationControlSetKey);
553 #else
554  dwError = ScmCopyTree(hSourceControlSetKey,
555  hDestinationControlSetKey);
556 #endif
557  if (dwError != ERROR_SUCCESS)
558  goto done;
559 
560  RegFlushKey(hDestinationControlSetKey);
561 
562 done:
563  if (hDestinationControlSetKey != NULL)
564  RegCloseKey(hDestinationControlSetKey);
565 
566  if (hSourceControlSetKey != NULL)
567  RegCloseKey(hSourceControlSetKey);
568 
569  return dwError;
570 }
571 
572 
573 static
574 DWORD
576  DWORD dwControlSet)
577 {
578  WCHAR szControlSetName[32];
579  HKEY hControlSetKey = NULL;
580  DWORD dwError;
581 
582  DPRINT("ScmDeleteControSet(%lu)\n", dwControlSet);
583 
584  /* Create the control set name */
585  swprintf(szControlSetName, L"SYSTEM\\ControlSet%03lu", dwControlSet);
586  DPRINT("Control set: %S\n", szControlSetName);
587 
588  /* Open the system key */
590  szControlSetName,
591  0,
593  &hControlSetKey);
594  if (dwError != ERROR_SUCCESS)
595  return dwError;
596 
597  /* Delete the control set */
598 #if (_WIN32_WINNT >= 0x0600)
599  dwError = RegDeleteTreeW(hControlSetKey,
600  NULL);
601 #else
602  dwError = ScmDeleteTree(hControlSetKey,
603  NULL);
604 #endif
605 
606  /* Open the system key */
607  RegCloseKey(hControlSetKey);
608 
609  return dwError;
610 }
611 
612 
613 DWORD
615 {
616  DWORD dwCurrentControlSet, dwDefaultControlSet;
617  DWORD dwFailedControlSet, dwLastKnownGoodControlSet;
618  DWORD dwNewControlSet;
619  DWORD dwError;
620 
621  /* Get the control set values */
622  dwError = ScmGetControlSetValues(&dwCurrentControlSet,
623  &dwDefaultControlSet,
624  &dwFailedControlSet,
625  &dwLastKnownGoodControlSet);
626  if (dwError != ERROR_SUCCESS)
627  return dwError;
628 
629  /* First boot after setup? */
630  if ((ScmGetSetupInProgress() == 0) &&
631  (dwCurrentControlSet == dwLastKnownGoodControlSet))
632  {
633  DPRINT("First boot after setup!\n");
634 
635  /* Search for a new control set number */
636  for (dwNewControlSet = 1; dwNewControlSet < 1000; dwNewControlSet++)
637  {
638  if ((dwNewControlSet != dwCurrentControlSet) &&
639  (dwNewControlSet != dwDefaultControlSet) &&
640  (dwNewControlSet != dwFailedControlSet) &&
641  (dwNewControlSet != dwLastKnownGoodControlSet))
642  break;
643  }
644 
645  /* Fail if we did not find an unused control set!*/
646  if (dwNewControlSet >= 1000)
647  {
648  DPRINT1("Too many control sets!\n");
649  return ERROR_NO_MORE_ITEMS;
650  }
651 
652  /* Copy the current control set */
653  dwError = ScmCopyControlSet(dwCurrentControlSet,
654  dwNewControlSet);
655  if (dwError != ERROR_SUCCESS)
656  return dwError;
657 
658  /* Set the new 'LastKnownGood' control set */
659  dwError = ScmSetLastKnownGoodControlSet(dwNewControlSet);
660  if (dwError == ERROR_SUCCESS)
661  {
662  /*
663  * Accept the boot here in order to prevent the creation of
664  * another control set when a user is going to get logged on
665  */
667  }
668  }
669 
670  return dwError;
671 }
672 
673 
674 DWORD
676 {
677  DWORD dwCurrentControlSet, dwDefaultControlSet;
678  DWORD dwFailedControlSet, dwLastKnownGoodControlSet;
679  DWORD dwNewControlSet;
680  DWORD dwError;
681 
682  DPRINT("ScmAcceptBoot()\n");
683 
684  if (bBootAccepted)
685  {
686  DPRINT1("Boot has alread been accepted!\n");
688  }
689 
690  /* Get the control set values */
691  dwError = ScmGetControlSetValues(&dwCurrentControlSet,
692  &dwDefaultControlSet,
693  &dwFailedControlSet,
694  &dwLastKnownGoodControlSet);
695  if (dwError != ERROR_SUCCESS)
696  return dwError;
697 
698  /* Search for a new control set number */
699  for (dwNewControlSet = 1; dwNewControlSet < 1000; dwNewControlSet++)
700  {
701  if ((dwNewControlSet != dwCurrentControlSet) &&
702  (dwNewControlSet != dwDefaultControlSet) &&
703  (dwNewControlSet != dwFailedControlSet) &&
704  (dwNewControlSet != dwLastKnownGoodControlSet))
705  break;
706  }
707 
708  /* Fail if we did not find an unused control set!*/
709  if (dwNewControlSet >= 1000)
710  {
711  DPRINT1("Too many control sets!\n");
712  return ERROR_NO_MORE_ITEMS;
713  }
714 
715  /* Copy the current control set */
716  dwError = ScmCopyControlSet(dwCurrentControlSet,
717  dwNewControlSet);
718  if (dwError != ERROR_SUCCESS)
719  return dwError;
720 
721  /* Delete the current last known good contol set, if it is not used anywhere else */
722  if ((dwLastKnownGoodControlSet != dwCurrentControlSet) &&
723  (dwLastKnownGoodControlSet != dwDefaultControlSet) &&
724  (dwLastKnownGoodControlSet != dwFailedControlSet))
725  {
726  ScmDeleteControlSet(dwLastKnownGoodControlSet);
727  }
728 
729  /* Set the new 'LastKnownGood' control set */
730  dwError = ScmSetLastKnownGoodControlSet(dwNewControlSet);
731  if (dwError != ERROR_SUCCESS)
732  return dwError;
733 
735 
736  return ERROR_SUCCESS;
737 }
738 
739 
740 DWORD
742 {
743  DPRINT("ScmRunLastKnownGood()\n");
744 
745  if (bBootAccepted)
746  {
747  DPRINT1("Boot has alread been accepted!\n");
749  }
750 
751  /* FIXME */
752 
753  return ERROR_SUCCESS;
754 }
755 
756 /* EOF */
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define max(a, b)
Definition: svc.c:63
DWORD ScmAcceptBoot(VOID)
Definition: controlset.c:675
#define RegQueryInfoKey
Definition: winreg.h:521
#define ERROR_SUCCESS
Definition: deptool.c:10
#define KEY_SET_VALUE
Definition: nt_native.h:1017
static DWORD ScmGetSetupInProgress(VOID)
Definition: controlset.c:471
static DWORD ScmCopyTree(HKEY hSrcKey, HKEY hDstKey)
Definition: controlset.c:28
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
static BOOL bBootAccepted
Definition: controlset.c:20
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
uint16_t * PWSTR
Definition: typedefs.h:56
DWORD ScmCreateLastKnownGoodControlSet(VOID)
Definition: controlset.c:614
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1237
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
static DWORD ScmCopyControlSet(DWORD dwSourceControlSet, DWORD dwDestinationControlSet)
Definition: controlset.c:507
#define swprintf
Definition: precomp.h:40
LONG WINAPI RegFlushKey(HKEY hKey)
Definition: reg.c:2974
#define DWORD
Definition: nt_native.h:44
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:1091
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:53
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
static DWORD ScmSetLastKnownGoodControlSet(DWORD dwControlSet)
Definition: controlset.c:441
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2853
static LPSTR lpNameBuffer
Definition: secur32.c:50
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WRITE
Definition: nt_native.h:1031
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:4899
#define ERROR_BOOT_ALREADY_ACCEPTED
Definition: winerror.h:627
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4120
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned long DWORD
Definition: ntddk_ex.h:95
LONG WINAPI RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3690
static const WCHAR L[]
Definition: oid.c:1250
DWORD ScmDeleteTree(HKEY hKey, PCWSTR pszSubKey)
Definition: controlset.c:249
LSTATUS WINAPI RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
Definition: reg.c:1746
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2355
FxAutoRegKey hKey
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
static DWORD ScmDeleteControlSet(DWORD dwControlSet)
Definition: controlset.c:575
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
DWORD * PDWORD
Definition: pedump.c:68
#define DPRINT1
Definition: precomp.h:8
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
LONG WINAPI RegCopyTreeW(IN HKEY hKeySrc, IN LPCWSTR lpSubKey OPTIONAL, IN HKEY hKeyDest)
Definition: reg.c:736
DWORD ScmRunLastKnownGood(VOID)
Definition: controlset.c:741
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2527
#define DPRINT
Definition: sndvol32.h:71
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define REG_DWORD
Definition: sdbapi.c:596
#define HeapFree(x, y, z)
Definition: compat.h:594
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static DWORD ScmGetControlSetValues(PDWORD pdwCurrentControlSet, PDWORD pdwDefaultControlSet, PDWORD pdwFailedControlSet, PDWORD pdwLastKnownGoodControlSet)
Definition: controlset.c:358
#define DELETE
Definition: nt_native.h:57
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019