From 0d78fd8f3d87daf2d57ecd4216d5d49f88e9ec81 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 10 May 2007 17:52:09 +0000 Subject: [PATCH] - Add more code to CmpInitializeMachineDependentConfiguration to create the BIOSINFO key and to start working on the CentralProcessor key (which, in ReactOS, FreeLDR creates when it shouldn't). Creates the basic CentralProcessor nodes for now. - Add cmconfig.c and implement a helper routine that converts from ARC CONFIGURATION_COMPONENT_DATA to a Hardware Description entry and resource descriptor. - Fix outdated _CONFIGURATION_TYPE definition in our DDK. svn path=/trunk/; revision=26677 --- reactos/include/ddk/winddk.h | 1 + reactos/ntoskrnl/config/cm.h | 18 +++ reactos/ntoskrnl/config/cmconfig.c | 198 ++++++++++++++++++++++++ reactos/ntoskrnl/config/cmdata.c | 49 ++++++ reactos/ntoskrnl/config/i386/cmhardwr.c | 119 +++++++++++++- reactos/ntoskrnl/ntoskrnl.rbuild | 1 + 6 files changed, 385 insertions(+), 1 deletion(-) create mode 100644 reactos/ntoskrnl/config/cmconfig.c 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