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