2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/config/cmcontrl.c
5 * PURPOSE: Configuration Manager - Control Set Management
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
15 /* GLOBALS *******************************************************************/
17 /* FUNCTIONS *****************************************************************/
21 CmpConvertLangId(IN LPWSTR Name
,
29 /* Convert the length in chars and loop */
30 NameLength
= NameLength
/ sizeof(WCHAR
);
31 for (i
= 0; i
< NameLength
; i
++)
33 /* Get the character */
36 /* Handle each case */
37 if ((p
>= L
'0') && (p
<= L
'9'))
42 else if ((p
>= L
'A') && (p
<= L
'F'))
44 /* Handle upper-case letters */
45 IdCode
= p
- L
'A' + 10;
47 else if ((p
>= L
'a') && (p
<= L
'f'))
49 /* Handle lower-case letters */
50 IdCode
= p
- L
'a' + 10;
54 /* Unhandled case, return what we have till now */
58 /* If the ID Code is >= 16, then we're done */
59 if (IdCode
>= 16) break;
61 /* Build the Language ID */
62 LangId
= (LangId
<< 4) | (LANGID
)IdCode
;
65 /* Return the Language ID */
71 CmpWalkPath(IN PHHIVE SystemHive
,
72 IN HCELL_INDEX ParentCell
,
75 UNICODE_STRING UnicodePath
, NextName
;
77 HCELL_INDEX CurrentCell
= ParentCell
;
80 /* We shouldn't have a release routine at this point */
81 ASSERT(SystemHive
->ReleaseCellRoutine
== NULL
);
83 /* Initialize the Unicode path and start looping */
84 RtlInitUnicodeString(&UnicodePath
, Path
);
87 /* Get the next name */
88 CmpGetNextName(&UnicodePath
, &NextName
, &LastName
);
89 if (!NextName
.Length
) return CurrentCell
;
92 Node
= (PCM_KEY_NODE
)HvGetCell(SystemHive
, CurrentCell
);
93 if (!Node
) return HCELL_NIL
;
94 CurrentCell
= CmpFindSubKeyByName(SystemHive
, Node
, &NextName
);
95 if (CurrentCell
== HCELL_NIL
) return CurrentCell
;
101 CmGetSystemControlValues(IN PVOID SystemHiveData
,
102 IN PCM_SYSTEM_CONTROL_VECTOR ControlVector
)
104 PHHIVE SystemHive
= (PHHIVE
)&CmControlHive
;
106 HCELL_INDEX RootCell
, BaseCell
, KeyCell
, ValueCell
;
107 ULONG Length
, DataSize
;
109 PCM_KEY_VALUE ValueData
;
110 UNICODE_STRING KeyName
;
111 BOOLEAN Auto
, IsSmallKey
;
114 /* LUDDDIIIICRROOOUUSSSS KI^H^H HACKKKK */
115 if (!SystemHiveData
) return;
117 /* Initialize the Hive View List and the security cache */
118 RtlZeroMemory(SystemHive
, sizeof(SystemHive
));
119 CmpInitHiveViewList((PCMHIVE
)SystemHive
);
120 CmpInitSecurityCache((PCMHIVE
)SystemHive
);
122 /* Initialize the Hive */
123 Status
= HvInitialize(SystemHive
,
136 if (!NT_SUCCESS(Status
)) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO
, 1, 1, 0, 0);
138 /* Sanity check, flat hives don't have release routines */
139 ASSERT(SystemHive
->ReleaseCellRoutine
== NULL
);
141 /* Set the Root Cell */
142 RootCell
= ((PHBASE_BLOCK
)SystemHiveData
)->RootCell
;
144 /* Find the current control set */
145 RtlInitUnicodeString(&KeyName
, L
"current");
146 BaseCell
= CmpFindControlSet(SystemHive
, RootCell
, &KeyName
, &Auto
);
147 if (BaseCell
== HCELL_NIL
) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO
, 1, 2, 0, 0);
149 /* Find the control subkey */
150 RtlInitUnicodeString(&KeyName
, L
"control");
151 Node
= (PCM_KEY_NODE
)HvGetCell(SystemHive
, BaseCell
);
152 BaseCell
= CmpFindSubKeyByName(SystemHive
, Node
, &KeyName
);
153 if (BaseCell
== HCELL_NIL
) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO
,1 , 3, 0, 0);
156 while (ControlVector
->KeyPath
)
161 /* Get the cell for this key */
162 KeyCell
= CmpWalkPath(SystemHive
, BaseCell
, ControlVector
->KeyPath
);
163 if (KeyCell
!= HCELL_NIL
)
165 /* Now get the cell for the value */
166 RtlInitUnicodeString(&KeyName
, ControlVector
->ValueName
);
167 Node
= (PCM_KEY_NODE
)HvGetCell(SystemHive
, KeyCell
);
168 ValueCell
= CmpFindValueByName(SystemHive
, Node
, &KeyName
);
169 if (ValueCell
!= HCELL_NIL
)
171 /* Check if there's any data */
172 if (!ControlVector
->BufferLength
)
174 /* No, the buffer will only be large enough for a ULONG */
175 DataSize
= sizeof(ULONG
);
179 /* Yes, save the data size */
180 DataSize
= *ControlVector
->BufferLength
;
183 /* Get the actual data */
184 ValueData
= (PCM_KEY_VALUE
)HvGetCell(SystemHive
, ValueCell
);
186 /* Check if this is a small key */
187 IsSmallKey
= CmpIsKeyValueSmall(&Length
, ValueData
->DataLength
);
189 /* If the length is bigger then our buffer, normalize it */
190 if (DataSize
< Length
) Length
= DataSize
;
192 /* Make sure we have some data */
195 /* Check if this was a small key */
198 /* The buffer is directly safe to read */
199 Buffer
= (PVOID
)(&(ValueData
->Data
));
203 /* Use the longer path */
204 Buffer
= (PVOID
)HvGetCell(SystemHive
, ValueData
->Data
);
207 /* Sanity check if this is a small key */
209 (Length
<= CM_KEY_VALUE_SMALL
) : TRUE
));
211 /* Copy the data in the buffer */
212 RtlCopyMemory(ControlVector
->Buffer
, Buffer
, Length
);
215 /* Check if we should return the data type */
216 if (ControlVector
->Type
)
218 /* Return the type that we read */
219 *ControlVector
->Type
= ValueData
->Type
;
224 /* Return the size that we read */
225 if (ControlVector
->BufferLength
) *ControlVector
->BufferLength
= Length
;
227 /* Go to the next entry */
231 /* Check if the ID is in the registry */
232 if (CmDefaultLanguageIdType
== REG_SZ
)
235 PsDefaultSystemLocaleId
=
236 (LCID
)CmpConvertLangId(CmDefaultLanguageId
,
237 CmDefaultLanguageIdLength
);
241 /* Use EN_US by default */
242 PsDefaultSystemLocaleId
= 0x409;
245 /* Check if the ID Is in the registry */
246 if (CmInstallUILanguageIdType
== REG_SZ
)
249 PsInstallUILanguageId
= CmpConvertLangId(CmInstallUILanguageId
,
250 CmInstallUILanguageIdLength
);
254 /* Otherwise, use the default */
255 PsInstallUILanguageId
= LANGIDFROMLCID(PsDefaultSystemLocaleId
);
258 /* Set the defaults for the Thread UI */
259 PsDefaultThreadLocaleId
= PsDefaultSystemLocaleId
;
260 PsDefaultUILanguageId
= PsInstallUILanguageId
;