[ros-diffs] [ion] 24423: - Implement CmpHwProfileDefaultSelect, CmpAddDockingInfo, CmpAddAliasEntry, CmpCreateCurrentControlSetLink. - Stub CmpCloneHwProfile, CmpSetAcpiHwProfile since there are more complex to handle and shouldn't occur while testing.

ion at svn.reactos.org ion at svn.reactos.org
Sat Oct 7 18:36:52 CEST 2006


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/cm/cminit.c?rev=24423&r1=24422&r2=24423&view=diff
==============================================================================
--- 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




More information about the Ros-diffs mailing list