Author: ion Date: Fri Oct 6 18:47:19 2006 New Revision: 24423
URL: http://svn.reactos.org/svn/reactos?rev=24423&view=rev Log: - Implement CmpHwProfileDefaultSelect, CmpAddDockingInfo, CmpAddAliasEntry, CmpCreateCurrentControlSetLink. - Stub CmpCloneHwProfile, CmpSetAcpiHwProfile since there are more complex to handle and shouldn't occur while testing.
Modified: branches/alex-cm-branch/reactos/ntoskrnl/cm/cminit.c
Modified: branches/alex-cm-branch/reactos/ntoskrnl/cm/cminit.c URL: http://svn.reactos.org/svn/reactos/branches/alex-cm-branch/reactos/ntoskrnl/... ============================================================================== --- branches/alex-cm-branch/reactos/ntoskrnl/cm/cminit.c (original) +++ branches/alex-cm-branch/reactos/ntoskrnl/cm/cminit.c Fri Oct 6 18:47:19 2006 @@ -16,6 +16,8 @@ RTL_CONSTANT_STRING(L"\REGISTRY\MACHINE\SYSTEM"); UNICODE_STRING CmpSystemFileName = RTL_CONSTANT_STRING(L"SYSTEM"); +UNICODE_STRING CmSymbolicLinkValueName = + RTL_CONSTANT_STRING(L"SymbolicLinkValue");
BOOLEAN CmpMiniNTBoot; BOOLEAN CmpShareSystemHives; @@ -354,6 +356,570 @@ return TRUE; }
+NTSTATUS +NTAPI +CmpHwProfileDefaultSelect(IN PVOID ProfileList, + OUT PULONG ProfileIndexToUse, + IN PVOID Context) +{ + /* Clear the index and return success */ + *ProfileIndexToUse = 0; + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CmpAddDockingInfo(IN HANDLE Key, + IN PPROFILE_PARAMETER_BLOCK ProfileBlock) +{ + NTSTATUS Status = STATUS_SUCCESS; + UNICODE_STRING KeyName; + ULONG Value; + PAGED_CODE (); + + /* Get the Value from the profile block, create a Name for it and set it */ + Value = ProfileBlock->DockingState; + RtlInitUnicodeString(&KeyName, L"DockingState"); + Status = NtSetValueKey(Key, + &KeyName, + 0, + REG_DWORD, + &Value, + sizeof(Value)); + if (!NT_SUCCESS(Status)) return Status; + + /* Get the Value from the profile block, create a Name for it and set it */ + Value = ProfileBlock->Capabilities; + RtlInitUnicodeString(&KeyName, L"Capabilities"); + Status = NtSetValueKey(Key, + &KeyName, + 0, + REG_DWORD, + &Value, + sizeof(Value)); + if (!NT_SUCCESS(Status)) return Status; + + /* Get the Value from the profile block, create a Name for it and set it */ + Value = ProfileBlock->DockID; + RtlInitUnicodeString(&KeyName, L"DockID"); + Status = NtSetValueKey(Key, + &KeyName, + 0, + REG_DWORD, + &Value, + sizeof(Value)); + if (!NT_SUCCESS(Status)) return Status; + + /* Get the Value from the profile block, create a Name for it and set it */ + Value = ProfileBlock->SerialNumber; + RtlInitUnicodeString(&KeyName, L"SerialNumber"); + Status = NtSetValueKey(Key, + &KeyName, + 0, + REG_DWORD, + &Value, + sizeof(Value)); + + /* Return Status */ + return Status; +} + +NTSTATUS +NTAPI +CmpAddAliasEntry(IN HANDLE IDConfigDB, + IN PPROFILE_PARAMETER_BLOCK ProfileBlock, + IN ULONG ProfileNumber) +{ + UNICODE_STRING KeyName; + OBJECT_ATTRIBUTES ObjectAttributes; + NTSTATUS Status = STATUS_SUCCESS; + CHAR Buffer[128]; + WCHAR UnicodeBuffer[128]; + ANSI_STRING TempString; + HANDLE AliasHandle = NULL, AliasIdHandle = NULL; + ULONG Value; + ULONG Disposition; + ULONG AliasId = 0; + PAGED_CODE (); + + /* Open the alias key */ + RtlInitUnicodeString(&KeyName, L"Alias"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + IDConfigDB, + NULL); + Status = NtOpenKey(&AliasHandle, KEY_READ | KEY_WRITE, &ObjectAttributes); + + /* Check if we failed to open it */ + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + { + /* Create it instead */ + Status = NtCreateKey(&AliasHandle, + KEY_READ | KEY_WRITE, + &ObjectAttributes, + 0, + NULL, + 0, + &Disposition); + } + + /* Check if we failed */ + if (!NT_SUCCESS (Status)) + { + /* Cleanup and exit */ + AliasHandle = NULL; + goto Exit; + } + + /* Loop every alias ID */ + while (AliasId++ < 200) + { + /* Build the KeyName */ + sprintf(Buffer, "%04d", AliasId); + RtlInitAnsiString(&TempString, Buffer); + + /* Convert it to Unicode */ + KeyName.MaximumLength = sizeof(UnicodeBuffer); + KeyName.Buffer = UnicodeBuffer; + Status = RtlAnsiStringToUnicodeString(&KeyName, + &TempString, + FALSE); + ASSERT (STATUS_SUCCESS == Status); + + /* Open the key */ + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + AliasHandle, + NULL); + Status = NtOpenKey(&AliasIdHandle, + KEY_READ | KEY_WRITE, + &ObjectAttributes); + if (NT_SUCCESS (Status)) + { + /* We opened it, close and keep looping */ + NtClose(AliasIdHandle); + } + else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + { + /* We couldn't find it, change Status and break out */ + Status = STATUS_SUCCESS; + break; + } + else + { + /* Any other error, break out */ + break; + } + } + + /* Check if we failed in the alias loop */ + if (!NT_SUCCESS(Status)) + { + /* Cleanup and exit */ + AliasIdHandle = 0; + goto Exit; + } + + /* Otherwise, create the alias key */ + Status = NtCreateKey(&AliasIdHandle, + KEY_READ | KEY_WRITE, + &ObjectAttributes, + 0, + NULL, + 0, + &Disposition); + if (!NT_SUCCESS(Status)) + { + /* Cleanup and exit */ + AliasIdHandle = 0; + goto Exit; + } + + /* Add docking information */ + CmpAddDockingInfo(AliasIdHandle, ProfileBlock); + + /* Set the profile number */ + Value = ProfileNumber; + RtlInitUnicodeString(&KeyName, L"ProfileNumber"); + Status = NtSetValueKey(AliasIdHandle, + &KeyName, + 0, + REG_DWORD, + &Value, + sizeof(Value)); + +Exit: + /* Close every opened key */ + if (AliasHandle) NtClose(AliasHandle); + if (AliasIdHandle) NtClose(AliasIdHandle); + + /* Return Status */ + return Status; +} + +NTSTATUS +NTAPI +CmSetAcpiHwProfile(IN PPROFILE_ACPI_DOCKING_STATE NewDockState, + IN PVOID Select, + IN PVOID Context, + OUT PHANDLE NewProfile, + OUT PBOOLEAN ProfileChanged) +{ + /* FIXME: TODO */ + *ProfileChanged = FALSE; + *NewProfile = NULL; + ASSERT(FALSE); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CmpCloneHwProfile(IN HANDLE ConfigHandle, + IN HANDLE Parent, + IN HANDLE OldProfile, + IN ULONG OldProfileNumber, + IN USHORT DockingState, + OUT PHANDLE NewProfile, + OUT PULONG NewProfileNumber) +{ + /* FIXME: TODO */ + *NewProfileNumber = FALSE; + *NewProfile = NULL; + ASSERT(FALSE); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +CmpCreateCurrentControlSetLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + UNICODE_STRING ConfigName = RTL_CONSTANT_STRING(L"Control\ConfigHandle"); + UNICODE_STRING SelectName = + RTL_CONSTANT_STRING(L"\Registry\Machine\System\Select"); + UNICODE_STRING KeyName; + OBJECT_ATTRIBUTES ObjectAttributes; + CHAR ValueInfoBuffer[128]; + PKEY_VALUE_FULL_INFORMATION ValueInfo; + CHAR Buffer[128]; + WCHAR UnicodeBuffer[128]; + HANDLE SelectHandle, KeyHandle, ConfigHandle = NULL, ProfileHandle = NULL; + HANDLE ParentHandle = NULL, AcpiHandle; + ULONG ControlSet, HwProfile; + ANSI_STRING TempString; + NTSTATUS Status; + ULONG ResultLength, Disposition; + BOOLEAN AcpiProfile = FALSE; + PLOADER_PARAMETER_EXTENSION LoaderExtension; + PROFILE_ACPI_DOCKING_STATE AcpiDockState; + BOOLEAN Active; + PAGED_CODE(); + + /* Open the select key */ + InitializeObjectAttributes(&ObjectAttributes, + &SelectName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenKey(&SelectHandle, KEY_READ, &ObjectAttributes); + if (!NT_SUCCESS(Status))return(Status); + + /* Open the current value */ + RtlInitUnicodeString(&KeyName, L"Current"); + Status = NtQueryValueKey(SelectHandle, + &KeyName, + KeyValueFullInformation, + ValueInfoBuffer, + sizeof(ValueInfoBuffer), + &ResultLength); + NtClose(SelectHandle); + if (!NT_SUCCESS(Status)) return Status; + + /* Get the actual value pointer, and get the control set ID */ + ValueInfo = (PKEY_VALUE_FULL_INFORMATION)ValueInfoBuffer; + ControlSet = *(PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset); + + /* Create the current control set key */ + RtlInitUnicodeString(&KeyName, + L"\Registry\Machine\System\CurrentControlSet"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtCreateKey(&KeyHandle, + KEY_CREATE_LINK, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK, + &Disposition); + if (!NT_SUCCESS(Status)) return Status; + + /* Sanity check */ + ASSERT(Disposition == REG_CREATED_NEW_KEY); + + /* Initialize the symbolic link name */ + sprintf(Buffer, + "\Registry\Machine\System\ControlSet%03d", + ControlSet); + RtlInitAnsiString(&TempString, Buffer); + + /* Create a Unicode string out of it */ + KeyName.MaximumLength = sizeof(UnicodeBuffer); + KeyName.Buffer = UnicodeBuffer; + Status = RtlAnsiStringToUnicodeString(&KeyName, &TempString, FALSE); + + /* Set the value */ + Status = NtSetValueKey(KeyHandle, + &CmSymbolicLinkValueName, + 0, + REG_LINK, + KeyName.Buffer, + KeyName.Length); + if (!NT_SUCCESS(Status)) return Status; + + /* Get the configuration database key */ + InitializeObjectAttributes(&ObjectAttributes, + &ConfigName, + OBJ_CASE_INSENSITIVE, + KeyHandle, + NULL); + Status = NtOpenKey(&ConfigHandle, KEY_READ, &ObjectAttributes); + NtClose(KeyHandle); + + /* Check if we don't have one */ + if (!NT_SUCCESS(Status)) + { + /* Cleanup and exit */ + ConfigHandle = 0; + goto Cleanup; + } + + /* Now get the current config */ + RtlInitUnicodeString(&KeyName, L"CurrentConfig"); + Status = NtQueryValueKey(ConfigHandle, + &KeyName, + KeyValueFullInformation, + ValueInfoBuffer, + sizeof(ValueInfoBuffer), + &ResultLength); + + /* Set pointer to buffer */ + ValueInfo = (PKEY_VALUE_FULL_INFORMATION)ValueInfoBuffer; + + /* Check if we failed or got a non DWORD-value */ + if (!(NT_SUCCESS(Status)) || (ValueInfo->Type != REG_DWORD)) goto Cleanup; + + /* Get the hadware profile */ + HwProfile = *(PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset); + + /* Open the hardware profile key */ + RtlInitUnicodeString(&KeyName, + L"\Registry\Machine\System\CurrentControlSet" + L"\Hardware Profiles"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenKey(&ParentHandle, KEY_READ, &ObjectAttributes); + + /* Check if there is no hardware profile key */ + if (!NT_SUCCESS (Status)) + { + /* Exit and clean up */ + ParentHandle = 0; + goto Cleanup; + } + + /* Build the profile name */ + sprintf(Buffer, "%04d",HwProfile); + RtlInitAnsiString(&TempString, Buffer); + + /* Convert it to Unicode */ + KeyName.MaximumLength = sizeof(UnicodeBuffer); + KeyName.Buffer = UnicodeBuffer; + Status = RtlAnsiStringToUnicodeString(&KeyName, + &TempString, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + + /* Open the associated key */ + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + ParentHandle, + NULL); + Status = NtOpenKey(&ProfileHandle, + KEY_READ | KEY_WRITE, + &ObjectAttributes); + + /* Check if there's no such key */ + if (!NT_SUCCESS (Status)) + { + /* Cleanup and exit */ + ProfileHandle = 0; + goto Cleanup; + } + + /* Check if we have a loader block extension */ + LoaderExtension = LoaderBlock->Extension; + if (LoaderExtension) + { + /* Check the hardware profile status */ + switch (LoaderExtension->Profile.Status) + { + /* Cloned status */ + case 3: + + /* Clone it */ + Status = CmpCloneHwProfile(ConfigHandle, + ParentHandle, + ProfileHandle, + HwProfile, + LoaderExtension-> + Profile.DockingState, + &ProfileHandle, + &HwProfile); + if (!NT_SUCCESS(Status)) + { + /* Cloning failed, cleanup and exit */ + ProfileHandle = 0; + goto Cleanup; + } + + /* Set the current config key */ + RtlInitUnicodeString(&KeyName, L"CurrentConfig"); + Status = NtSetValueKey(ConfigHandle, + &KeyName, + 0, + REG_DWORD, + &HwProfile, + sizeof (HwProfile)); + if (!NT_SUCCESS (Status)) goto Cleanup; + + /* Alias status */ + case 1: + + /* Create an alias entry */ + Status = CmpAddAliasEntry(ConfigHandle, + &LoaderExtension->Profile, + HwProfile); + + /* Docking status */ + case 2: + + /* Create the current dock info key */ + RtlInitUnicodeString(&KeyName, + L"CurrentDockInfo"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + ConfigHandle, + NULL); + Status = NtCreateKey(&KeyHandle, + KEY_READ | KEY_WRITE, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + &Disposition); + ASSERT (STATUS_SUCCESS == Status); + + /* Add the docking information */ + Status = CmpAddDockingInfo(KeyHandle, + &LoaderExtension->Profile); + break; + + /* Other cases */ + case 0: + case 0xC001: + break; + + /* Unknown status */ + default: + ASSERT(FALSE); + } + } + + /* Create the current hardware profile key */ + RtlInitUnicodeString(&KeyName, + L"\Registry\Machine\System\CurrentControlSet\" + L"Hardware Profiles\Current"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtCreateKey(&KeyHandle, + KEY_CREATE_LINK, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK, + &Disposition); + if (NT_SUCCESS(Status)) + { + /* Sanity check */ + ASSERT(Disposition == REG_CREATED_NEW_KEY); + + /* Create the profile name */ + sprintf(Buffer, + "\Registry\Machine\System\CurrentControlSet\" + "Hardware Profiles\%04d", + HwProfile); + RtlInitAnsiString(&TempString, Buffer); + + /* Convert it to Unicode */ + KeyName.MaximumLength = sizeof(UnicodeBuffer); + KeyName.Buffer = UnicodeBuffer; + Status = RtlAnsiStringToUnicodeString(&KeyName, + &TempString, + FALSE); + ASSERT (STATUS_SUCCESS == Status); + + /* Set it */ + Status = NtSetValueKey(KeyHandle, + &CmSymbolicLinkValueName, + 0, + REG_LINK, + KeyName.Buffer, + KeyName.Length); + NtClose(KeyHandle); + } + + /* Check if we have to set the ACPI Profile */ + if (AcpiProfile) + { + /* Setup the docking state to undocked */ + AcpiDockState.DockingState = 1; + AcpiDockState.SerialLength = 2; + AcpiDockState.SerialNumber[0] = L'\0'; + + /* Set the ACPI profile */ + Status = CmSetAcpiHwProfile(&AcpiDockState, + CmpHwProfileDefaultSelect, + NULL, + &AcpiHandle, + &Active); + ASSERT(NT_SUCCESS(Status)); + + /* Close the key */ + NtClose(AcpiHandle); + } + + /* Close every opened handle */ +Cleanup: + if (ConfigHandle) NtClose(ConfigHandle); + if (ProfileHandle) NtClose(ProfileHandle); + if (ParentHandle) NtClose(ParentHandle); + + /* Return success */ + return STATUS_SUCCESS; +} + VOID NTAPI CmInitSystem1(IN PLOADER_PARAMETER_BLOCK LoaderBlock) @@ -487,41 +1053,3 @@ CmpSetSystemBootValues(LoaderBlock); }
-#if 0 -VOID -INIT_FUNCTION -STDCALL -CmInitHives(BOOLEAN SetupBoot) -{ - PCHAR BaseAddress; - - /* Load Registry Hives. This one can be missing. */ - if (CachedModules[SystemRegistry]) { - BaseAddress = (PCHAR)CachedModules[SystemRegistry]->ModStart; - CmImportSystemHive(BaseAddress, - CachedModules[SystemRegistry]->ModEnd - (ULONG_PTR)BaseAddress); - } - - BaseAddress = (PCHAR)CachedModules[HardwareRegistry]->ModStart; - CmImportHardwareHive(BaseAddress, - CachedModules[HardwareRegistry]->ModEnd - (ULONG_PTR)BaseAddress); - - - /* Create dummy keys if no hardware hive was found */ - CmImportHardwareHive (NULL, 0); - - /* Initialize volatile registry settings */ - if (SetupBoot == FALSE) CmInit2((PCHAR)KeLoaderBlock.CommandLine); -} - - /* - * Create a CurrentControlSet\Control\MiniNT key that is used - * to detect WinPE/MiniNT systems. - */ - if (MiniNT) - { - Status = RtlCreateRegistryKey(RTL_REGISTRY_CONTROL, L"MiniNT"); - if (!NT_SUCCESS(Status)) - KEBUGCHECK(CONFIG_INITIALIZATION_FAILED); - } -#endif