diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h
index ec6ed2f5ebf..2492aa13dd0 100644
--- a/reactos/include/ddk/winddk.h
+++ b/reactos/include/ddk/winddk.h
@@ -4592,6 +4592,7 @@ typedef enum _CONFIGURATION_TYPE {
SystemMemory,
DockingInformation,
RealModeIrqRoutingTable,
+ RealModePCIEnumeration,
MaximumType
} CONFIGURATION_TYPE, *PCONFIGURATION_TYPE;
diff --git a/reactos/ntoskrnl/config/cm.h b/reactos/ntoskrnl/config/cm.h
index e1de9db4daf..f01d55acdfb 100644
--- a/reactos/ntoskrnl/config/cm.h
+++ b/reactos/ntoskrnl/config/cm.h
@@ -939,6 +939,20 @@ CmpFindControlSet(
OUT PBOOLEAN AutoSelect
);
+//
+// Hardware Configuration Routines
+//
+NTSTATUS
+NTAPI
+CmpInitializeRegistryNode(
+ IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
+ IN HANDLE NodeHandle,
+ OUT PHANDLE NewHandle,
+ IN INTERFACE_TYPE InterfaceType,
+ IN ULONG BusNumber,
+ IN PUSHORT DeviceIndexTable
+);
+
//
// Global variables accessible from all of Cm
//
@@ -961,6 +975,10 @@ extern ULONG CmInstallUILanguageIdType;
extern LANGID PsInstallUILanguageId;
extern LANGID PsDefaultUILanguageId;
extern CM_SYSTEM_CONTROL_VECTOR CmControlVector[];
+extern ULONG CmpConfigurationAreaSize;
+extern PCM_FULL_RESOURCE_DESCRIPTOR CmpConfigurationData;
+extern UNICODE_STRING CmTypeName[];
+extern BOOLEAN ExpInTextModeSetup;
//
// Inlined functions
diff --git a/reactos/ntoskrnl/config/cmconfig.c b/reactos/ntoskrnl/config/cmconfig.c
new file mode 100644
index 00000000000..272074be1c0
--- /dev/null
+++ b/reactos/ntoskrnl/config/cmconfig.c
@@ -0,0 +1,198 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/config/cmconfig.c
+ * PURPOSE: Configuration Manager - System Configuration Routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "ntoskrnl.h"
+#include "cm.h"
+#define NDEBUG
+#include "debug.h"
+
+/* FUNCTIONS *****************************************************************/
+
+NTSTATUS
+NTAPI
+CmpInitializeRegistryNode(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
+ IN HANDLE NodeHandle,
+ OUT PHANDLE NewHandle,
+ IN INTERFACE_TYPE InterfaceType,
+ IN ULONG BusNumber,
+ IN PUSHORT DeviceIndexTable)
+{
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING KeyName, ValueName, ValueData;
+ HANDLE KeyHandle, ParentHandle;
+ ANSI_STRING TempString;
+ CHAR TempBuffer[12];
+ WCHAR Buffer[12];
+ PCONFIGURATION_COMPONENT Component;
+ ULONG Disposition, Length = 0;
+
+ /* Get the component */
+ Component = &CurrentEntry->ComponentEntry;
+
+ /* Set system class components to ARC system type */
+ if (Component->Class == SystemClass) Component->Type = ArcSystem;
+
+ /* Create a key for the component */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &CmTypeName[Component->Type],
+ OBJ_CASE_INSENSITIVE,
+ NodeHandle,
+ NULL);
+ Status = NtCreateKey(&KeyHandle,
+ KEY_READ | KEY_WRITE,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ 0,
+ &Disposition);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Check if this is anything but a system class component */
+ if (Component->Class != SystemClass)
+ {
+ /* Build the sub-component string */
+ RtlIntegerToChar(DeviceIndexTable[Component->Type]++,
+ 10,
+ 12,
+ TempBuffer);
+ RtlInitAnsiString(&TempString, TempBuffer);
+
+ /* Convert it to Unicode */
+ RtlInitEmptyUnicodeString(&KeyName, Buffer, sizeof(Buffer));
+ RtlAnsiStringToUnicodeString(&KeyName, &TempString, FALSE);
+
+ /* Create the key */
+ ParentHandle = KeyHandle;
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ ParentHandle,
+ NULL);
+ Status = NtCreateKey(&KeyHandle,
+ KEY_READ | KEY_WRITE,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ 0,
+ &Disposition);
+ NtClose(ParentHandle);
+
+ /* Fail if the key couldn't be created, and make sure it's a new key */
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* These keys should -not- exist, but FreeLDR creates them :( */
+ //ASSERT(Disposition == REG_CREATED_NEW_KEY);
+ }
+
+ /* Sstup the compnent information key */
+ RtlInitUnicodeString(&ValueName, L"Component Information");
+ Status = NtSetValueKey(KeyHandle,
+ &ValueName,
+ 0,
+ REG_BINARY,
+ &Component->Flags,
+ FIELD_OFFSET(CONFIGURATION_COMPONENT,
+ ConfigurationDataLength) -
+ FIELD_OFFSET(CONFIGURATION_COMPONENT, Flags));
+ if (!NT_SUCCESS(Status))
+ {
+ /* Fail */
+ NtClose(KeyHandle);
+ return Status;
+ }
+
+ /* Check if we have an identifier */
+ if (Component->IdentifierLength)
+ {
+ /* Build the string and convert it to Unicode */
+ RtlInitUnicodeString(&ValueName, L"Identifier");
+ RtlInitAnsiString(&TempString, Component->Identifier);
+ Status = RtlAnsiStringToUnicodeString(&ValueData,
+ &TempString,
+ TRUE);
+ if (NT_SUCCESS(Status))
+ {
+ /* Save the identifier in the registry */
+ Status = NtSetValueKey(KeyHandle,
+ &ValueName,
+ 0,
+ REG_SZ,
+ ValueData.Buffer,
+ ValueData.Length + sizeof(UNICODE_NULL));
+ RtlFreeUnicodeString(&ValueData);
+ }
+
+ /* Check for failure during conversion or registry write */
+ if (!NT_SUCCESS(Status))
+ {
+ /* Fail */
+ NtClose(KeyHandle);
+ return Status;
+ }
+ }
+
+ /* Setup the configuration data string */
+ RtlInitUnicodeString(&ValueName, L"Configuration Data");
+
+ /* Check if we got configuration data */
+ if (CurrentEntry->ConfigurationData)
+ {
+ /* Calculate the total length and check if it fits into our buffer */
+ Length = Component->ConfigurationDataLength +
+ FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList);
+ if (Length > CmpConfigurationAreaSize)
+ {
+ ASSERTMSG("Component too large -- need reallocation!", FALSE);
+ }
+ else
+ {
+ /* Copy the data */
+ RtlCopyMemory(&CmpConfigurationData->PartialResourceList.Version,
+ CurrentEntry->ConfigurationData,
+ Component->ConfigurationDataLength);
+ }
+ }
+ else
+ {
+ /* No configuration data, setup defaults */
+ CmpConfigurationData->PartialResourceList.Version = 0;
+ CmpConfigurationData->PartialResourceList.Revision = 0;
+ CmpConfigurationData->PartialResourceList.Count = 0;
+ Length = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors) +
+ FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList);
+ }
+
+ /* Set the interface type and bus number */
+ CmpConfigurationData->InterfaceType = InterfaceType;
+ CmpConfigurationData->BusNumber = BusNumber;
+
+ /* Save the actual data */
+ Status = NtSetValueKey(KeyHandle,
+ &ValueName,
+ 0,
+ REG_FULL_RESOURCE_DESCRIPTOR,
+ CmpConfigurationData,
+ Length);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Fail */
+ NtClose(KeyHandle);
+ }
+ else
+ {
+ /* Return the new handle */
+ *NewHandle = KeyHandle;
+ }
+
+ /* Return status */
+ return Status;
+}
+
diff --git a/reactos/ntoskrnl/config/cmdata.c b/reactos/ntoskrnl/config/cmdata.c
index 2335f68142c..4eaf5544ab0 100644
--- a/reactos/ntoskrnl/config/cmdata.c
+++ b/reactos/ntoskrnl/config/cmdata.c
@@ -33,6 +33,55 @@ ULONG CmSuiteBufferType;
CMHIVE CmControlHive;
+ULONG CmpConfigurationAreaSize = PAGE_SIZE * 4;
+PCM_FULL_RESOURCE_DESCRIPTOR CmpConfigurationData;
+
+UNICODE_STRING CmTypeName[MaximumType + 1] =
+{
+ RTL_CONSTANT_STRING(L"System"),
+ RTL_CONSTANT_STRING(L"CentralProcessor"),
+ RTL_CONSTANT_STRING(L"FloatingPointProcessor"),
+ RTL_CONSTANT_STRING(L"PrimaryICache"),
+ RTL_CONSTANT_STRING(L"PrimaryDCache"),
+ RTL_CONSTANT_STRING(L"SecondaryICache"),
+ RTL_CONSTANT_STRING(L"SecondaryDCache"),
+ RTL_CONSTANT_STRING(L"SecondaryCache"),
+ RTL_CONSTANT_STRING(L"EisaAdapter"),
+ RTL_CONSTANT_STRING(L"TcAdapter"),
+ RTL_CONSTANT_STRING(L"ScsiAdapter"),
+ RTL_CONSTANT_STRING(L"DtiAdapter"),
+ RTL_CONSTANT_STRING(L"MultifunctionAdapter"),
+ RTL_CONSTANT_STRING(L"DiskController"),
+ RTL_CONSTANT_STRING(L"TapeController"),
+ RTL_CONSTANT_STRING(L"CdRomController"),
+ RTL_CONSTANT_STRING(L"WormController"),
+ RTL_CONSTANT_STRING(L"SerialController"),
+ RTL_CONSTANT_STRING(L"NetworkController"),
+ RTL_CONSTANT_STRING(L"DisplayController"),
+ RTL_CONSTANT_STRING(L"ParallelController"),
+ RTL_CONSTANT_STRING(L"PointerController"),
+ RTL_CONSTANT_STRING(L"KeyboardController"),
+ RTL_CONSTANT_STRING(L"AudioController"),
+ RTL_CONSTANT_STRING(L"OtherController"),
+ RTL_CONSTANT_STRING(L"DiskPeripheral"),
+ RTL_CONSTANT_STRING(L"FloppyDiskPeripheral"),
+ RTL_CONSTANT_STRING(L"TapePeripheral"),
+ RTL_CONSTANT_STRING(L"ModemPeripheral"),
+ RTL_CONSTANT_STRING(L"MonitorPeripheral"),
+ RTL_CONSTANT_STRING(L"PrinterPeripheral"),
+ RTL_CONSTANT_STRING(L"PointerPeripheral"),
+ RTL_CONSTANT_STRING(L"KeyboardPeripheral"),
+ RTL_CONSTANT_STRING(L"TerminalPeripheral"),
+ RTL_CONSTANT_STRING(L"OtherPeripheral"),
+ RTL_CONSTANT_STRING(L"LinePeripheral"),
+ RTL_CONSTANT_STRING(L"NetworkPeripheral"),
+ RTL_CONSTANT_STRING(L"SystemMemory"),
+ RTL_CONSTANT_STRING(L"DockingInformation"),
+ RTL_CONSTANT_STRING(L"RealModeIrqRoutingTable"),
+ RTL_CONSTANT_STRING(L"RealModePCIEnumeration"),
+ RTL_CONSTANT_STRING(L"Undefined")
+};
+
CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
{
{
diff --git a/reactos/ntoskrnl/config/i386/cmhardwr.c b/reactos/ntoskrnl/config/i386/cmhardwr.c
index c7db38ea319..13a84991079 100644
--- a/reactos/ntoskrnl/config/i386/cmhardwr.c
+++ b/reactos/ntoskrnl/config/i386/cmhardwr.c
@@ -13,6 +13,11 @@
#define NDEBUG
#include "debug.h"
+/* GLOBALS *******************************************************************/
+
+PCHAR CmpID1 = "80%u86-%c%x";
+PCHAR CmpID2 = "x86 Family %u Model %u Stepping %u";
+
/* FUNCTIONS *****************************************************************/
NTSTATUS
@@ -23,8 +28,15 @@ CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBloc
OBJECT_ATTRIBUTES ObjectAttributes;
ULONG HavePae;
NTSTATUS Status;
- HANDLE KeyHandle;
+ HANDLE KeyHandle, BiosHandle, SystemHandle;
+ ULONG Disposition;
+ CONFIGURATION_COMPONENT_DATA ConfigData;
+ CHAR Buffer[128];
+ ULONG i;
+ PKPRCB Prcb;
+ USHORT IndexTable[MaximumType + 1] = {0};
+ /* Open the SMSS Memory Management key */
RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\"
L"Control\\Session Manager\\Memory Management");
@@ -52,6 +64,111 @@ CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBloc
NtClose(KeyHandle);
}
+ /* Open the hardware description key */
+ RtlInitUnicodeString(&KeyName,
+ L"\\Registry\\Machine\\Hardware\\Description\\System");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = NtOpenKey(&SystemHandle, KEY_READ | KEY_WRITE, &ObjectAttributes);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Create the BIOS Information key */
+ RtlInitUnicodeString(&KeyName,
+ L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\"
+ L"Control\\BIOSINFO");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = NtCreateKey(&BiosHandle,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ &Disposition);
+ if (!NT_SUCCESS(Status) && !ExpInTextModeSetup) return Status;
+
+ /* Create the CPU Key, and check if it already existed */
+ RtlInitUnicodeString(&KeyName, L"CentralProcessor");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ SystemHandle,
+ NULL);
+ Status = NtCreateKey(&KeyHandle,
+ KEY_READ | KEY_WRITE,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ 0,
+ &Disposition);
+ NtClose(KeyHandle);
+
+ /* This key -never- exists on x86 machines, except in ReactOS! */
+ //if (Disposition == REG_CREATED_NEW_KEY)
+ {
+ /* Allocate the configuration data for cmconfig.c */
+ CmpConfigurationData = ExAllocatePoolWithTag(PagedPool,
+ CmpConfigurationAreaSize,
+ TAG_CM);
+ if (!CmpConfigurationData) return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* Loop all CPUs */
+ for (i = 0; i < KeNumberProcessors; i++)
+ {
+ /* Get the PRCB */
+ Prcb = KiProcessorBlock[i];
+
+ /* Setup the Configuration Entry for the Processor */
+ RtlZeroMemory(&ConfigData, sizeof (ConfigData));
+ ConfigData.ComponentEntry.Class = ProcessorClass;
+ ConfigData.ComponentEntry.Type = CentralProcessor;
+ ConfigData.ComponentEntry.Key = i;
+ ConfigData.ComponentEntry.AffinityMask = 1 << i;
+ ConfigData.ComponentEntry.Identifier = Buffer;
+
+ /* Check if the CPU doesn't support CPUID */
+ if (!Prcb->CpuID)
+ {
+ /* Build ID1-style string for older CPUs */
+ sprintf(Buffer,
+ CmpID1,
+ Prcb->CpuType,
+ (Prcb->CpuStep >> 8) + 'A',
+ Prcb->CpuStep & 0xff);
+ }
+ else
+ {
+ /* Build ID2-style string for newer CPUs */
+ sprintf(Buffer,
+ CmpID2,
+ Prcb->CpuType,
+ (Prcb->CpuStep >> 8),
+ Prcb->CpuStep & 0xff);
+ }
+
+ /* Save the ID string length now that we've created it */
+ ConfigData.ComponentEntry.IdentifierLength = strlen(Buffer) + 1;
+
+ /* Initialize the registry configuration node for it */
+ Status = CmpInitializeRegistryNode(&ConfigData,
+ SystemHandle,
+ &KeyHandle,
+ InterfaceTypeUndefined,
+ 0xFFFFFFFF,
+ IndexTable);
+ if (!NT_SUCCESS(Status)) return(Status);
+ }
+
+ /* Free the configuration data */
+ ExFreePool(CmpConfigurationData);
+ }
+
/* All done*/
return STATUS_SUCCESS;
}
diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild
index 59642596f19..4a1c09cc41c 100644
--- a/reactos/ntoskrnl/ntoskrnl.rbuild
+++ b/reactos/ntoskrnl/ntoskrnl.rbuild
@@ -91,6 +91,7 @@
cmboot.c
cmcontrl.c
+ cmconfig.c
cmdata.c
cmindex.c
cmhook.c