ReactOS 0.4.15-dev-7131-ge4d03f4
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)
26static
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,
107 return dwError;
108 }
109
110 dwError = RegCreateKeyExW(hDstKey,
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,
125 return dwError;
126 }
127
128 dwError = RegOpenKeyExW(hSrcKey,
130 0,
131 KEY_READ,
132 &hSrcSubKey);
133 if (dwError != ERROR_SUCCESS)
134 {
135 DPRINT1("Error: %lu\n", dwError);
136 RegCloseKey(hDstSubKey);
138 0,
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,
153 return dwError;
154 }
155
156 RegCloseKey(hSrcSubKey);
157 RegCloseKey(hDstSubKey);
158 }
159
161 0,
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,
188 }
189
190 for (i = 0; i < dwValues; i++)
191 {
192 dwValueNameLength = dwMaxValueNameLength;
193 dwValueLength = dwMaxValueLength;
194 dwError = RegEnumValueW(hSrcKey,
195 i,
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,
211 return dwError;
212 }
213
214 dwError = RegSetValueExW(hDstKey,
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,
229 return dwError;
230 }
231 }
232
234 0,
235 lpDataBuffer);
236
238 0,
240 }
241
242 DPRINT("ScmCopyTree() done\n");
243
244 return ERROR_SUCCESS;
245}
246
247
248DWORD
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;
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
344done:
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
356static
357DWORD
359 PDWORD pdwCurrentControlSet,
360 PDWORD pdwDefaultControlSet,
361 PDWORD pdwFailedControlSet,
362 PDWORD pdwLastKnownGoodControlSet)
363{
364 HKEY hSelectKey;
365 DWORD dwType;
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
439static
440DWORD
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
469static
470DWORD
472{
473 DWORD dwError;
474 HKEY hKey;
475 DWORD dwType;
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);
498 }
499
500 DPRINT("SetupInProgress: %lu\n", dwSetupInProgress);
501 return dwSetupInProgress;
502}
503
504
505static
506DWORD
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
562done:
563 if (hDestinationControlSetKey != NULL)
564 RegCloseKey(hDestinationControlSetKey);
565
566 if (hSourceControlSetKey != NULL)
567 RegCloseKey(hSourceControlSetKey);
568
569 return dwError;
570}
571
572
573static
574DWORD
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
613DWORD
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
674DWORD
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 already 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
740DWORD
742{
743 DPRINT("ScmRunLastKnownGood()\n");
744
745 if (bBootAccepted)
746 {
747 DPRINT1("Boot has already been accepted\n");
749 }
750
751 /* FIXME */
752
753 return ERROR_SUCCESS;
754}
755
756/* EOF */
#define DPRINT1
Definition: precomp.h:8
#define RegCloseKey(hKey)
Definition: registry.h:49
DWORD ScmRunLastKnownGood(VOID)
Definition: controlset.c:741
DWORD ScmCreateLastKnownGoodControlSet(VOID)
Definition: controlset.c:614
DWORD ScmDeleteTree(HKEY hKey, PCWSTR pszSubKey)
Definition: controlset.c:249
static DWORD ScmSetLastKnownGoodControlSet(DWORD dwControlSet)
Definition: controlset.c:441
static DWORD ScmGetSetupInProgress(VOID)
Definition: controlset.c:471
static DWORD ScmDeleteControlSet(DWORD dwControlSet)
Definition: controlset.c:575
DWORD ScmAcceptBoot(VOID)
Definition: controlset.c:675
static DWORD ScmGetControlSetValues(PDWORD pdwCurrentControlSet, PDWORD pdwDefaultControlSet, PDWORD pdwFailedControlSet, PDWORD pdwLastKnownGoodControlSet)
Definition: controlset.c:358
static DWORD ScmCopyControlSet(DWORD dwSourceControlSet, DWORD dwDestinationControlSet)
Definition: controlset.c:507
static BOOL bBootAccepted
Definition: controlset.c:20
static DWORD ScmCopyTree(HKEY hSrcKey, HKEY hDstKey)
Definition: controlset.c:28
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
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 RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3353
LONG WINAPI RegCopyTreeW(IN HKEY hKeySrc, IN LPCWSTR lpSubKey OPTIONAL, IN HKEY hKeyDest)
Definition: reg.c:736
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:2524
LONG WINAPI RegFlushKey(HKEY hKey)
Definition: reg.c:2971
LSTATUS WINAPI RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
Definition: reg.c:1743
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:4902
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1234
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2352
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:2850
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:3682
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4123
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define swprintf
Definition: precomp.h:40
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
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
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define KEY_READ
Definition: nt_native.h:1023
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#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_WRITE
Definition: nt_native.h:1031
#define DWORD
Definition: nt_native.h:44
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define L(x)
Definition: ntvdm.h:50
DWORD * PDWORD
Definition: pedump.c:68
#define REG_DWORD
Definition: sdbapi.c:596
static LPSTR lpNameBuffer
Definition: secur32.c:50
#define DPRINT
Definition: sndvol32.h:71
#define max(a, b)
Definition: svc.c:63
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
unsigned char * LPBYTE
Definition: typedefs.h:53
#define ERROR_BOOT_ALREADY_ACCEPTED
Definition: winerror.h:627
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define RegQueryInfoKey
Definition: winreg.h:521
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184