Sync with trunk head.
[reactos.git] / ntoskrnl / config / cmboot.c
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/config/cmboot.c
5 * PURPOSE: Configuration Manager - Boot Initialization
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include "ntoskrnl.h"
12 #define NDEBUG
13 #include "debug.h"
14
15 /* GLOBALS *******************************************************************/
16
17 /* FUNCTIONS *****************************************************************/
18
19 HCELL_INDEX
20 NTAPI
21 CmpFindControlSet(IN PHHIVE SystemHive,
22 IN HCELL_INDEX RootCell,
23 IN PUNICODE_STRING SelectKeyName,
24 OUT PBOOLEAN AutoSelect)
25 {
26 UNICODE_STRING KeyName;
27 PCM_KEY_NODE Node;
28 HCELL_INDEX SelectCell, AutoSelectCell, SelectValueCell, ControlSetCell;
29 HCELL_INDEX CurrentValueCell;
30 PCM_KEY_VALUE KeyValue;
31 ULONG Length;
32 PULONG ControlSetId;
33 ANSI_STRING ControlSetAnsiName;
34 CHAR Buffer[128];
35 WCHAR WideBuffer[128];
36 NTSTATUS Status;
37 PULONG CurrentData;
38
39 /* Sanity check */
40 ASSERT(SystemHive->ReleaseCellRoutine == NULL);
41
42 /* Get the Select subkey */
43 RtlInitUnicodeString(&KeyName, L"select");
44 Node = (PCM_KEY_NODE)HvGetCell(SystemHive, RootCell);
45 if (!Node) return HCELL_NIL;
46 SelectCell = CmpFindSubKeyByName(SystemHive, Node, &KeyName);
47 if (SelectCell == HCELL_NIL) return SelectCell;
48
49 /* Get AutoSelect value */
50 RtlInitUnicodeString(&KeyName, L"AutoSelect");
51 Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
52 if (!Node) return HCELL_NIL;
53 AutoSelectCell = CmpFindValueByName(SystemHive, Node, &KeyName);
54 if (AutoSelectCell == HCELL_NIL)
55 {
56 /* Assume TRUE if the value is missing. */
57 *AutoSelect = TRUE;
58 }
59 else
60 {
61 /* Read the value */
62 KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, AutoSelectCell);
63 if (KeyValue == NULL) return HCELL_NIL;
64
65 /* Convert it to a boolean */
66 *AutoSelect = *(PBOOLEAN)CmpValueToData(SystemHive, KeyValue, &Length);
67 }
68
69 /* Now find the control set being looked up */
70 Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
71 if (!Node) return HCELL_NIL;
72 SelectValueCell = CmpFindValueByName(SystemHive, Node, SelectKeyName);
73 if (SelectValueCell == HCELL_NIL) return SelectValueCell;
74
75 /* Read the value (corresponding to the CCS ID) */
76 KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, SelectValueCell);
77 if (!KeyValue) return HCELL_NIL;
78 if (KeyValue->Type != REG_DWORD) return HCELL_NIL;
79 ControlSetId = (PULONG)CmpValueToData(SystemHive, KeyValue, &Length);
80
81 /* Now build an Ansi String for the CCS's Name */
82 sprintf(Buffer, "ControlSet%03lu", *ControlSetId);
83 ControlSetAnsiName.Length = (USHORT)strlen(Buffer);
84 ControlSetAnsiName.MaximumLength = (USHORT)strlen(Buffer);
85 ControlSetAnsiName.Buffer = Buffer;
86
87 /* And convert it to Unicode... */
88 KeyName.MaximumLength = 256;
89 KeyName.Buffer = WideBuffer;
90 Status = RtlAnsiStringToUnicodeString(&KeyName,
91 &ControlSetAnsiName,
92 FALSE);
93 if (!NT_SUCCESS(Status)) return HCELL_NIL;
94
95 /* Now open it */
96 Node = (PCM_KEY_NODE)HvGetCell(SystemHive, RootCell);
97 if (!Node) return HCELL_NIL;
98 ControlSetCell = CmpFindSubKeyByName(SystemHive, Node, &KeyName);
99 if (ControlSetCell == HCELL_NIL) return ControlSetCell;
100
101 /* Get the value of the "Current" CCS */
102 RtlInitUnicodeString(&KeyName, L"Current");
103 Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
104 if (!Node) return HCELL_NIL;
105 CurrentValueCell = CmpFindValueByName(SystemHive, Node, &KeyName);
106
107 /* Make sure it exists */
108 if (CurrentValueCell != HCELL_NIL)
109 {
110 /* Get the current value and make sure its a ULONG */
111 KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, CurrentValueCell);
112 if (!KeyValue) return HCELL_NIL;
113 if (KeyValue->Type == REG_DWORD)
114 {
115 /* Get the data and update it */
116 CurrentData = (PULONG)CmpValueToData(SystemHive,
117 KeyValue,
118 &Length);
119 if (!CurrentData) return HCELL_NIL;
120 *CurrentData = *ControlSetId;
121 }
122 }
123
124 /* Return the CCS Cell */
125 return ControlSetCell;
126 }