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 *****************************************************************/
22 CmpConvertLangId(IN LPWSTR Name
,
30 /* Convert the length in chars and loop */
31 NameLength
= NameLength
/ sizeof(WCHAR
);
32 for (i
= 0; i
< NameLength
; i
++)
34 /* Get the character */
37 /* Handle each case */
38 if ((p
>= L
'0') && (p
<= L
'9'))
43 else if ((p
>= L
'A') && (p
<= L
'F'))
45 /* Handle upper-case letters */
46 IdCode
= p
- L
'A' + 10;
48 else if ((p
>= L
'a') && (p
<= L
'f'))
50 /* Handle lower-case letters */
51 IdCode
= p
- L
'a' + 10;
55 /* Unhandled case, return what we have till now */
59 /* If the ID Code is >= 16, then we're done */
60 if (IdCode
>= 16) break;
62 /* Build the Language ID */
63 LangId
= (LangId
<< 4) | (LANGID
)IdCode
;
66 /* Return the Language ID */
73 CmpWalkPath(IN PHHIVE SystemHive
,
74 IN HCELL_INDEX ParentCell
,
77 UNICODE_STRING UnicodePath
, NextName
;
79 HCELL_INDEX CurrentCell
= ParentCell
;
82 /* We shouldn't have a release routine at this point */
83 ASSERT(SystemHive
->ReleaseCellRoutine
== NULL
);
85 /* Initialize the Unicode path and start looping */
86 RtlInitUnicodeString(&UnicodePath
, Path
);
89 /* Get the next name */
90 CmpGetNextName(&UnicodePath
, &NextName
, &LastName
);
91 if (!NextName
.Length
) return CurrentCell
;
94 Node
= (PCM_KEY_NODE
)HvGetCell(SystemHive
, CurrentCell
);
95 if (!Node
) return HCELL_NIL
;
96 CurrentCell
= CmpFindSubKeyByName(SystemHive
, Node
, &NextName
);
97 if (CurrentCell
== HCELL_NIL
) return CurrentCell
;
104 CmGetSystemControlValues(IN PVOID SystemHiveData
,
105 IN PCM_SYSTEM_CONTROL_VECTOR ControlVector
)
107 PHHIVE SystemHive
= (PHHIVE
)&CmControlHive
;
109 HCELL_INDEX RootCell
, BaseCell
, KeyCell
, ValueCell
;
110 ULONG Length
, DataSize
;
112 PCM_KEY_VALUE ValueData
;
113 UNICODE_STRING KeyName
;
114 BOOLEAN Auto
, IsSmallKey
;
117 /* LUDDDIIIICRROOOUUSSSS KI^H^H HACKKKK */
118 if (!SystemHiveData
) return;
120 /* Initialize the Hive View List and the security cache */
121 RtlZeroMemory(SystemHive
, sizeof(*SystemHive
));
122 CmpInitHiveViewList((PCMHIVE
)SystemHive
);
123 CmpInitSecurityCache((PCMHIVE
)SystemHive
);
125 /* Initialize the Hive */
126 Status
= HvInitialize(SystemHive
,
139 if (!NT_SUCCESS(Status
)) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO
, 1, 1, 0, 0);
141 /* Sanity check, flat hives don't have release routines */
142 ASSERT(SystemHive
->ReleaseCellRoutine
== NULL
);
144 /* Set the Root Cell */
145 RootCell
= ((PHBASE_BLOCK
)SystemHiveData
)->RootCell
;
147 /* Find the current control set */
148 RtlInitUnicodeString(&KeyName
, L
"current");
149 BaseCell
= CmpFindControlSet(SystemHive
, RootCell
, &KeyName
, &Auto
);
150 if (BaseCell
== HCELL_NIL
) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO
, 1, 2, 0, 0);
152 /* Find the control subkey */
153 RtlInitUnicodeString(&KeyName
, L
"control");
154 Node
= (PCM_KEY_NODE
)HvGetCell(SystemHive
, BaseCell
);
155 BaseCell
= CmpFindSubKeyByName(SystemHive
, Node
, &KeyName
);
156 if (BaseCell
== HCELL_NIL
) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO
,1 , 3, 0, 0);
159 while (ControlVector
->KeyPath
)
164 /* Get the cell for this key */
165 KeyCell
= CmpWalkPath(SystemHive
, BaseCell
, ControlVector
->KeyPath
);
166 if (KeyCell
!= HCELL_NIL
)
168 /* Now get the cell for the value */
169 RtlInitUnicodeString(&KeyName
, ControlVector
->ValueName
);
170 Node
= (PCM_KEY_NODE
)HvGetCell(SystemHive
, KeyCell
);
171 ValueCell
= CmpFindValueByName(SystemHive
, Node
, &KeyName
);
172 if (ValueCell
!= HCELL_NIL
)
174 /* Check if there's any data */
175 if (!ControlVector
->BufferLength
)
177 /* No, the buffer will only be large enough for a ULONG */
178 DataSize
= sizeof(ULONG
);
182 /* Yes, save the data size */
183 DataSize
= *ControlVector
->BufferLength
;
186 /* Get the actual data */
187 ValueData
= (PCM_KEY_VALUE
)HvGetCell(SystemHive
, ValueCell
);
189 /* Check if this is a small key */
190 IsSmallKey
= CmpIsKeyValueSmall(&Length
, ValueData
->DataLength
);
192 /* If the length is bigger then our buffer, normalize it */
193 if (DataSize
< Length
) Length
= DataSize
;
195 /* Make sure we have some data */
198 /* Check if this was a small key */
201 /* The buffer is directly safe to read */
202 Buffer
= (PVOID
)(&(ValueData
->Data
));
206 /* Use the longer path */
207 Buffer
= (PVOID
)HvGetCell(SystemHive
, ValueData
->Data
);
210 /* Sanity check if this is a small key */
212 (Length
<= CM_KEY_VALUE_SMALL
) : TRUE
));
214 /* Copy the data in the buffer */
215 RtlCopyMemory(ControlVector
->Buffer
, Buffer
, Length
);
218 /* Check if we should return the data type */
219 if (ControlVector
->Type
)
221 /* Return the type that we read */
222 *ControlVector
->Type
= ValueData
->Type
;
227 /* Return the size that we read */
228 if (ControlVector
->BufferLength
) *ControlVector
->BufferLength
= Length
;
230 /* Go to the next entry */
234 /* Check if the ID is in the registry */
235 if (CmDefaultLanguageIdType
== REG_SZ
)
238 PsDefaultSystemLocaleId
=
239 (LCID
)CmpConvertLangId(CmDefaultLanguageId
,
240 CmDefaultLanguageIdLength
);
244 /* Use EN_US by default */
245 PsDefaultSystemLocaleId
= 0x409;
248 /* Check if the ID Is in the registry */
249 if (CmInstallUILanguageIdType
== REG_SZ
)
252 PsInstallUILanguageId
= CmpConvertLangId(CmInstallUILanguageId
,
253 CmInstallUILanguageIdLength
);
257 /* Otherwise, use the default */
258 PsInstallUILanguageId
= LANGIDFROMLCID(PsDefaultSystemLocaleId
);
261 /* Set the defaults for the Thread UI */
262 PsDefaultThreadLocaleId
= PsDefaultSystemLocaleId
;
263 PsDefaultUILanguageId
= PsInstallUILanguageId
;