2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/config/cmconfig.c
5 * PURPOSE: Configuration Manager - System Configuration Routines
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
15 /* FUNCTIONS *****************************************************************/
20 CmpInitializeRegistryNode(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry
,
22 OUT PHANDLE NewHandle
,
23 IN INTERFACE_TYPE InterfaceType
,
25 IN PUSHORT DeviceIndexTable
)
28 OBJECT_ATTRIBUTES ObjectAttributes
;
29 UNICODE_STRING KeyName
, ValueName
, ValueData
;
30 HANDLE KeyHandle
, ParentHandle
;
31 ANSI_STRING TempString
;
34 PCONFIGURATION_COMPONENT Component
;
35 ULONG Disposition
, Length
= 0;
37 /* Get the component */
38 Component
= &CurrentEntry
->ComponentEntry
;
40 /* Set system class components to ARC system type */
41 if (Component
->Class
== SystemClass
) Component
->Type
= ArcSystem
;
43 /* Create a key for the component */
44 InitializeObjectAttributes(&ObjectAttributes
,
45 &CmTypeName
[Component
->Type
],
49 Status
= NtCreateKey(&KeyHandle
,
56 if (!NT_SUCCESS(Status
)) return Status
;
58 /* Check if this is anything but a system class component */
59 if (Component
->Class
!= SystemClass
)
61 /* Build the sub-component string */
62 RtlIntegerToChar(DeviceIndexTable
[Component
->Type
]++,
66 RtlInitAnsiString(&TempString
, TempBuffer
);
68 /* Convert it to Unicode */
69 RtlInitEmptyUnicodeString(&KeyName
, Buffer
, sizeof(Buffer
));
70 Status
= RtlAnsiStringToUnicodeString(&KeyName
, &TempString
, FALSE
);
71 if (!NT_SUCCESS(Status
))
78 ParentHandle
= KeyHandle
;
79 InitializeObjectAttributes(&ObjectAttributes
,
84 Status
= NtCreateKey(&KeyHandle
,
91 NtClose(ParentHandle
);
93 /* Fail if the key couldn't be created, and make sure it's a new key */
94 if (!NT_SUCCESS(Status
)) return Status
;
95 ASSERT(Disposition
== REG_CREATED_NEW_KEY
);
98 /* Setup the component information key */
99 RtlInitUnicodeString(&ValueName
, L
"Component Information");
100 Status
= NtSetValueKey(KeyHandle
,
105 FIELD_OFFSET(CONFIGURATION_COMPONENT
,
106 ConfigurationDataLength
) -
107 FIELD_OFFSET(CONFIGURATION_COMPONENT
, Flags
));
108 if (!NT_SUCCESS(Status
))
115 /* Check if we have an identifier */
116 if (Component
->IdentifierLength
)
118 /* Build the string and convert it to Unicode */
119 RtlInitUnicodeString(&ValueName
, L
"Identifier");
120 RtlInitAnsiString(&TempString
, Component
->Identifier
);
121 Status
= RtlAnsiStringToUnicodeString(&ValueData
,
124 if (NT_SUCCESS(Status
))
126 /* Save the identifier in the registry */
127 Status
= NtSetValueKey(KeyHandle
,
132 ValueData
.Length
+ sizeof(UNICODE_NULL
));
133 RtlFreeUnicodeString(&ValueData
);
136 /* Check for failure during conversion or registry write */
137 if (!NT_SUCCESS(Status
))
145 /* Setup the configuration data string */
146 RtlInitUnicodeString(&ValueName
, L
"Configuration Data");
148 /* Check if we got configuration data */
149 if (CurrentEntry
->ConfigurationData
)
151 /* Calculate the total length and check if it fits into our buffer */
152 Length
= Component
->ConfigurationDataLength
+
153 FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR
, PartialResourceList
);
154 if (Length
> CmpConfigurationAreaSize
)
156 ASSERTMSG("Component too large -- need reallocation!\n", FALSE
);
161 RtlCopyMemory(&CmpConfigurationData
->PartialResourceList
.Version
,
162 CurrentEntry
->ConfigurationData
,
163 Component
->ConfigurationDataLength
);
168 /* No configuration data, setup defaults */
169 CmpConfigurationData
->PartialResourceList
.Version
= 0;
170 CmpConfigurationData
->PartialResourceList
.Revision
= 0;
171 CmpConfigurationData
->PartialResourceList
.Count
= 0;
172 Length
= FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST
, PartialDescriptors
) +
173 FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR
, PartialResourceList
);
176 /* Set the interface type and bus number */
177 CmpConfigurationData
->InterfaceType
= InterfaceType
;
178 CmpConfigurationData
->BusNumber
= BusNumber
;
180 /* Save the actual data */
181 Status
= NtSetValueKey(KeyHandle
,
184 REG_FULL_RESOURCE_DESCRIPTOR
,
185 CmpConfigurationData
,
187 if (!NT_SUCCESS(Status
))
194 /* Return the new handle */
195 *NewHandle
= KeyHandle
;
205 CmpSetupConfigurationTree(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry
,
206 IN HANDLE ParentHandle
,
207 IN INTERFACE_TYPE InterfaceType
,
210 PCONFIGURATION_COMPONENT Component
;
211 USHORT DeviceIndexTable
[MaximumType
+ 1] = {0};
212 INTERFACE_TYPE Interface
= InterfaceType
;
213 ULONG Bus
= BusNumber
, i
;
217 /* Loop each entry */
220 /* Check if this is an adapter */
221 Component
= &CurrentEntry
->ComponentEntry
;
222 if ((Component
->Class
== AdapterClass
) &&
223 (CurrentEntry
->Parent
->ComponentEntry
.Class
== SystemClass
))
225 /* Check what kind of adapter it is */
226 switch (Component
->Type
)
231 /* Fixup information */
233 Bus
= CmpTypeCount
[EisaAdapter
]++;
240 /* Fixup information */
241 Interface
= TurboChannel
;
242 Bus
= CmpTypeCount
[TurboChannel
]++;
246 /* ISA, PCI, etc busses */
247 case MultiFunctionAdapter
:
249 /* Check if we have an identifier */
250 if (Component
->Identifier
)
252 /* Loop each multi-function adapter type */
253 for (i
= 0; CmpMultifunctionTypes
[i
].Identifier
; i
++)
255 /* Check for a name match */
256 if (!_stricmp(CmpMultifunctionTypes
[i
].Identifier
,
257 Component
->Identifier
))
264 /* Fix up information */
265 Interface
= CmpMultifunctionTypes
[i
].InterfaceType
;
266 Bus
= CmpMultifunctionTypes
[i
].Count
++;
275 Interface
= Internal
;
276 Bus
= CmpTypeCount
[ScsiAdapter
]++;
283 Interface
= InterfaceTypeUndefined
;
284 Bus
= CmpUnknownBusCount
++;
290 /* Dump information on the component */
292 /* Setup the hardware node */
293 Status
= CmpInitializeRegistryNode(CurrentEntry
,
299 if (!NT_SUCCESS(Status
)) return Status
;
301 /* Check for children */
302 if (CurrentEntry
->Child
)
305 Status
= CmpSetupConfigurationTree(CurrentEntry
->Child
,
309 if (!NT_SUCCESS(Status
))
317 /* Get to the next entry */
319 CurrentEntry
= CurrentEntry
->Sibling
;
323 return STATUS_SUCCESS
;
329 CmpInitializeHardwareConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
332 OBJECT_ATTRIBUTES ObjectAttributes
;
335 UNICODE_STRING KeyName
;
337 /* Set the alternative system architecture information */
338 #if defined(SARCH_PC98)
339 SharedUserData
->AlternativeArchitecture
= NEC98x86
;
342 /* Setup the key name */
343 RtlInitUnicodeString(&KeyName
,
344 L
"\\Registry\\Machine\\Hardware\\DeviceMap");
345 InitializeObjectAttributes(&ObjectAttributes
,
347 OBJ_CASE_INSENSITIVE
,
351 /* Create the device map key */
352 Status
= NtCreateKey(&KeyHandle
,
353 KEY_READ
| KEY_WRITE
,
359 if (!NT_SUCCESS(Status
))
363 /* Nobody should've created this key yet! */
364 ASSERT(Disposition
== REG_CREATED_NEW_KEY
);
366 /* Setup the key name */
367 RtlInitUnicodeString(&KeyName
,
368 L
"\\Registry\\Machine\\Hardware\\Description");
369 InitializeObjectAttributes(&ObjectAttributes
,
371 OBJ_CASE_INSENSITIVE
,
375 /* Create the description key */
376 Status
= NtCreateKey(&KeyHandle
,
377 KEY_READ
| KEY_WRITE
,
383 if (!NT_SUCCESS(Status
))
386 /* Nobody should've created this key yet! */
387 ASSERT(Disposition
== REG_CREATED_NEW_KEY
);
389 /* Allocate the configuration data buffer */
390 CmpConfigurationData
= ExAllocatePoolWithTag(PagedPool
,
391 CmpConfigurationAreaSize
,
393 if (!CmpConfigurationData
)
396 return STATUS_INSUFFICIENT_RESOURCES
;
399 /* Check if we got anything from NTLDR */
400 if (LoaderBlock
->ConfigurationRoot
)
402 /* Setup the configuration tree */
403 Status
= CmpSetupConfigurationTree(LoaderBlock
->ConfigurationRoot
,
405 InterfaceTypeUndefined
,
410 /* Nothing else to do */
411 Status
= STATUS_SUCCESS
;
414 /* Free the buffer, close our handle and return status */
415 ExFreePoolWithTag(CmpConfigurationData
, TAG_CM
);