From 0285323c9d8a6bde3617a2795c607a503791c069 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 10 May 2007 00:02:04 +0000 Subject: [PATCH] - Refactor the registry initialization code to be somewhat closer to the Cm rewrite branch. - No actual code/implementation changes per-se, simply moved code into new routines, deleted old routines, renamed some routines and added more error-checking. - Also performed registry initialization in an order more analogous to Windows. - Added cmsysini.c from the branch, but it's not used at the moment. svn path=/trunk/; revision=26669 --- reactos/ntoskrnl/cm/import.c | 72 +-- reactos/ntoskrnl/cm/registry.c | 626 +++++++++++------- reactos/ntoskrnl/config/cmsysini.c | 646 +++++++++++++++++++ reactos/ntoskrnl/include/internal/ntoskrnl.h | 4 +- reactos/ntoskrnl/ntoskrnl.rbuild | 1 + 5 files changed, 1061 insertions(+), 288 deletions(-) create mode 100644 reactos/ntoskrnl/config/cmsysini.c diff --git a/reactos/ntoskrnl/cm/import.c b/reactos/ntoskrnl/cm/import.c index 1501da83d47..48cfaacee5e 100644 --- a/reactos/ntoskrnl/cm/import.c +++ b/reactos/ntoskrnl/cm/import.c @@ -22,8 +22,6 @@ /* GLOBALS ******************************************************************/ -static BOOLEAN CmiHardwareHiveImported = FALSE; - /* FUNCTIONS ****************************************************************/ static BOOLEAN @@ -85,14 +83,13 @@ CmImportBinaryHive (PCHAR ChunkBase, } -BOOLEAN INIT_FUNCTION +BOOLEAN +INIT_FUNCTION CmImportSystemHive(PCHAR ChunkBase, - ULONG ChunkSize) + ULONG ChunkSize, + OUT PEREGISTRY_HIVE *RegistryHive) { - OBJECT_ATTRIBUTES ObjectAttributes; - PEREGISTRY_HIVE RegistryHive; - UNICODE_STRING KeyName; - NTSTATUS Status; + *RegistryHive = NULL; DPRINT ("CmImportSystemHive() called\n"); @@ -105,56 +102,38 @@ CmImportSystemHive(PCHAR ChunkBase, DPRINT ("Found '%.*s' magic\n", 4, ChunkBase); /* Import the binary system hive (non-volatile, offset-based, permanent) */ - if (!CmImportBinaryHive (ChunkBase, ChunkSize, 0, &RegistryHive)) + if (!CmImportBinaryHive (ChunkBase, ChunkSize, 0, RegistryHive)) { DPRINT1 ("CmiImportBinaryHive() failed\n"); return FALSE; } - /* Attach it to the machine key */ - RtlInitUnicodeString (&KeyName, - REG_SYSTEM_KEY_NAME); - InitializeObjectAttributes (&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - Status = CmiConnectHive (&ObjectAttributes, - RegistryHive); - if (!NT_SUCCESS(Status)) - { - DPRINT1 ("CmiConnectHive(%wZ) failed (Status %lx)\n", &KeyName, Status); - return FALSE; - } - /* Set the hive filename */ - RtlCreateUnicodeString (&RegistryHive->HiveFileName, + RtlCreateUnicodeString (&(*RegistryHive)->HiveFileName, SYSTEM_REG_FILE); /* Set the log filename */ - RtlCreateUnicodeString (&RegistryHive->LogFileName, + RtlCreateUnicodeString (&(*RegistryHive)->LogFileName, SYSTEM_LOG_FILE); return TRUE; } - -BOOLEAN INIT_FUNCTION +BOOLEAN +INIT_FUNCTION CmImportHardwareHive(PCHAR ChunkBase, - ULONG ChunkSize) + ULONG ChunkSize, + OUT PEREGISTRY_HIVE *RegistryHive) { OBJECT_ATTRIBUTES ObjectAttributes; - PEREGISTRY_HIVE RegistryHive; UNICODE_STRING KeyName; HANDLE HardwareKey; ULONG Disposition; NTSTATUS Status; + *RegistryHive = NULL; DPRINT ("CmImportHardwareHive() called\n"); - if (CmiHardwareHiveImported == TRUE) - return TRUE; - if (ChunkBase == NULL && ChunkSize == 0) { @@ -260,39 +239,20 @@ CmImportHardwareHive(PCHAR ChunkBase, DPRINT ("ChunkBase %lx ChunkSize %lu\n", ChunkBase, ChunkSize); /* Import the binary system hive (volatile, offset-based, permanent) */ - if (!CmImportBinaryHive (ChunkBase, ChunkSize, HIVE_NO_FILE, &RegistryHive)) + if (!CmImportBinaryHive (ChunkBase, ChunkSize, HIVE_NO_FILE, RegistryHive)) { DPRINT1 ("CmiImportBinaryHive() failed\n"); return FALSE; } - /* Attach it to the machine key */ - RtlInitUnicodeString (&KeyName, - REG_HARDWARE_KEY_NAME); - InitializeObjectAttributes (&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - Status = CmiConnectHive (&ObjectAttributes, - RegistryHive); - if (!NT_SUCCESS(Status)) - { - DPRINT1 ("CmiConnectHive(%wZ) failed (Status %lx)\n", &KeyName, Status); -// CmiRemoveRegistryHive(RegistryHive); - return FALSE; - } - /* Set the hive filename */ - RtlInitUnicodeString (&RegistryHive->HiveFileName, + RtlInitUnicodeString (&(*RegistryHive)->HiveFileName, NULL); /* Set the log filename */ - RtlInitUnicodeString (&RegistryHive->LogFileName, + RtlInitUnicodeString (&(*RegistryHive)->LogFileName, NULL); - CmiHardwareHiveImported = TRUE; - return TRUE; } diff --git a/reactos/ntoskrnl/cm/registry.c b/reactos/ntoskrnl/cm/registry.c index a8eb3620d24..5b8d3b14009 100644 --- a/reactos/ntoskrnl/cm/registry.c +++ b/reactos/ntoskrnl/cm/registry.c @@ -54,6 +54,18 @@ VOID CmiCheckKey(BOOLEAN Verbose, HANDLE Key); +BOOLEAN +INIT_FUNCTION +CmImportSystemHive(PCHAR ChunkBase, + ULONG ChunkSize, + OUT PEREGISTRY_HIVE *RegistryHive); + +BOOLEAN +INIT_FUNCTION +CmImportHardwareHive(PCHAR ChunkBase, + ULONG ChunkSize, + OUT PEREGISTRY_HIVE *RegistryHive); + static NTSTATUS CmiCreateCurrentControlSetLink(VOID); @@ -66,6 +78,8 @@ CmiHiveSyncDpcRoutine(PKDPC Dpc, extern LIST_ENTRY CmiCallbackHead; extern FAST_MUTEX CmiCallbackLock; +UNICODE_STRING CmpSystemStartOptions; +UNICODE_STRING CmpLoadOptions; /* FUNCTIONS ****************************************************************/ VOID STDCALL @@ -129,99 +143,13 @@ CmiWorkerThread(PVOID Param) } } -VOID INIT_FUNCTION -CmInit2(PCHAR CommandLine) +PVOID +NTAPI +CmpRosGetHardwareHive(OUT PULONG Length) { - ULONG PiceStart = 4; - BOOLEAN MiniNT = FALSE; - NTSTATUS Status; - UNICODE_STRING TempString; - - /* Create the 'CurrentControlSet' link. */ - Status = CmiCreateCurrentControlSetLink(); - if (!NT_SUCCESS(Status)) - KEBUGCHECK(CONFIG_INITIALIZATION_FAILED); - - /* - * Write the system boot device to registry. - */ - RtlCreateUnicodeStringFromAsciiz(&TempString, KeLoaderBlock->ArcBootDeviceName); - Status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE, - L"\\Registry\\Machine\\System\\CurrentControlSet\\Control", - L"SystemBootDevice", - REG_SZ, - TempString.Buffer, - TempString.MaximumLength); - RtlFreeUnicodeString(&TempString); - if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(CONFIG_INITIALIZATION_FAILED); - } - - /* - * Parse the system start options. - */ - if (strstr(KeLoaderBlock->LoadOptions, "DEBUGPORT=PICE") != NULL) - PiceStart = 1; - MiniNT = strstr(KeLoaderBlock->LoadOptions, "MININT") != NULL; - - /* - * Write the system start options to registry. - */ - RtlCreateUnicodeStringFromAsciiz(&TempString, KeLoaderBlock->LoadOptions); - Status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE, - L"\\Registry\\Machine\\System\\CurrentControlSet\\Control", - L"SystemStartOptions", - REG_SZ, - TempString.Buffer, - TempString.MaximumLength); - RtlFreeUnicodeString(&TempString); - if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(CONFIG_INITIALIZATION_FAILED); - } - - /* - * 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); - } - - /* Set PICE 'Start' value to 1, if PICE debugging is enabled */ - Status = RtlWriteRegistryValue( - RTL_REGISTRY_SERVICES, - L"\\Pice", - L"Start", - REG_DWORD, - &PiceStart, - sizeof(ULONG)); - if (!NT_SUCCESS(Status)) - KEBUGCHECK(CONFIG_INITIALIZATION_FAILED); -} - - -VOID -INIT_FUNCTION -STDCALL -CmInitHives(BOOLEAN SetupBoot) -{ - PCHAR BaseAddress; PLIST_ENTRY ListHead, NextEntry; PMEMORY_ALLOCATION_DESCRIPTOR MdBlock = NULL; - /* Load Registry Hives. This one can be missing. */ - BaseAddress = KeLoaderBlock->RegistryBase; - if (BaseAddress) - { - CmImportSystemHive(BaseAddress, - KeLoaderBlock->RegistryLength); - } - /* Loop the memory descriptors */ ListHead = &KeLoaderBlock->MemoryDescriptorListHead; NextEntry = ListHead->Flink; @@ -236,7 +164,8 @@ CmInitHives(BOOLEAN SetupBoot) if (MdBlock->MemoryType == LoaderRegistryData) { /* Check if it's not the SYSTEM hive that we already initialized */ - if ((MdBlock->BasePage) != ((ULONG_PTR)BaseAddress >> PAGE_SHIFT)) + if ((MdBlock->BasePage) != + ((ULONG_PTR)KeLoaderBlock->RegistryBase >> PAGE_SHIFT)) { /* Hardware hive break out */ break; @@ -249,16 +178,239 @@ CmInitHives(BOOLEAN SetupBoot) /* We need a hardware hive */ ASSERT(MdBlock); + *Length = MdBlock->PageCount << PAGE_SHIFT; + return (PVOID)(MdBlock->BasePage << PAGE_SHIFT); +} - BaseAddress = (PCHAR)(MdBlock->BasePage << PAGE_SHIFT); - CmImportHardwareHive(BaseAddress, - MdBlock->PageCount << PAGE_SHIFT); +NTSTATUS +NTAPI +CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName, + IN HANDLE RootDirectory, + IN PEREGISTRY_HIVE RegistryHive, + IN BOOLEAN Allocate, + IN PSECURITY_DESCRIPTOR SecurityDescriptor) +{ + OBJECT_ATTRIBUTES ObjectAttributes; - /* Create dummy keys if no hardware hive was found */ - CmImportHardwareHive (NULL, 0); + /* Don't do anything if we don't actually have a hive */ + if (Allocate) return STATUS_SUCCESS; - /* Initialize volatile registry settings */ - if (SetupBoot == FALSE) CmInit2(KeLoaderBlock->LoadOptions); + /* Setup the object attributes */ + InitializeObjectAttributes(&ObjectAttributes, + LinkName, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + RootDirectory, + SecurityDescriptor); + + /* Connect the hive */ + return CmiConnectHive(&ObjectAttributes, RegistryHive); +} + +NTSTATUS +NTAPI +CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName, ValueName; + HANDLE KeyHandle; + NTSTATUS Status; + ASSERT(LoaderBlock != NULL); + if (ExpInTextModeSetup) return STATUS_SUCCESS; + + /* Setup attributes for loader options */ + RtlInitUnicodeString(&KeyName, + L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\" + L"Control"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenKey(&KeyHandle, KEY_WRITE, &ObjectAttributes); + if (!NT_SUCCESS(Status)) goto Quickie; + + /* Key opened, now write to the key */ + RtlInitUnicodeString(&KeyName, L"SystemStartOptions"); + Status = NtSetValueKey(KeyHandle, + &KeyName, + 0, + REG_SZ, + CmpSystemStartOptions.Buffer, + CmpSystemStartOptions.Length); + if (!NT_SUCCESS(Status)) goto Quickie; + + /* Free the options now */ + ExFreePool(CmpSystemStartOptions.Buffer); + + /* Setup value name for system boot device */ + RtlInitUnicodeString(&KeyName, L"SystemBootDevice"); + RtlCreateUnicodeStringFromAsciiz(&ValueName, LoaderBlock->NtBootPathName); + Status = NtSetValueKey(KeyHandle, + &KeyName, + 0, + REG_SZ, + ValueName.Buffer, + ValueName.Length); + +Quickie: + /* Free the buffers */ + RtlFreeUnicodeString(&ValueName); + + /* Close the key and return */ + NtClose(KeyHandle); + + /* Return the status */ + return Status; +} + +BOOLEAN +NTAPI +CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + PVOID HiveBase; + ANSI_STRING LoadString; + PVOID Buffer; + ULONG Length; + NTSTATUS Status; + BOOLEAN Allocate; + UNICODE_STRING KeyName; + PEREGISTRY_HIVE SystemHive; + PAGED_CODE(); + + /* Setup the ansi string */ + RtlInitAnsiString(&LoadString, LoaderBlock->LoadOptions); + + /* Allocate the unicode buffer */ + Length = LoadString.Length * sizeof(WCHAR) + sizeof(UNICODE_NULL); + Buffer = ExAllocatePoolWithTag(PagedPool, Length, 0); + if (!Buffer) + { + /* Fail */ + KEBUGCHECKEX(BAD_SYSTEM_CONFIG_INFO, 3, 1, (ULONG_PTR)LoaderBlock, 0); + } + + /* Setup the unicode string */ + RtlInitEmptyUnicodeString(&CmpLoadOptions, Buffer, Length); + + /* Add the load options and null-terminate */ + RtlAnsiStringToUnicodeString(&CmpLoadOptions, &LoadString, FALSE); + CmpLoadOptions.Buffer[LoadString.Length] = UNICODE_NULL; + CmpLoadOptions.Length += sizeof(WCHAR); + + /* Get the System Hive base address */ + HiveBase = LoaderBlock->RegistryBase; + if (HiveBase) + { + /* Import it */ + Status = CmImportSystemHive(HiveBase, + LoaderBlock->RegistryLength, + &SystemHive); + if (!NT_SUCCESS(Status)) return FALSE; + + /* We imported, no need to create a new hive */ + Allocate = FALSE; + } + else + { + /* FIXME: Create an empty hive */ + Allocate = TRUE; + } + + /* Attach it to the system key */ + RtlInitUnicodeString(&KeyName, REG_SYSTEM_KEY_NAME); + Status = CmpLinkHiveToMaster(&KeyName, NULL, SystemHive, Allocate, NULL); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Success! */ + return TRUE; +} + +NTSTATUS +NTAPI +CmpCreateObjectTypes(VOID) +{ + OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; + UNICODE_STRING Name; + PAGED_CODE(); + + /* Initialize the Key object type */ + RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); + RtlInitUnicodeString(&Name, L"Key"); + ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); + ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(KEY_OBJECT); + ObjectTypeInitializer.GenericMapping = CmiKeyMapping; + ObjectTypeInitializer.PoolType = PagedPool; + ObjectTypeInitializer.ValidAccessMask = KEY_ALL_ACCESS; + ObjectTypeInitializer.UseDefaultObject = TRUE; + ObjectTypeInitializer.DeleteProcedure = CmiObjectDelete; + ObjectTypeInitializer.ParseProcedure = CmiObjectParse; + ObjectTypeInitializer.SecurityProcedure = CmiObjectSecurity; + ObjectTypeInitializer.QueryNameProcedure = CmiObjectQueryName; + + /* Create it */ + return ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &CmiKeyType); +} + +BOOLEAN +NTAPI +CmpCreateRegistryRoot(VOID) +{ + UNICODE_STRING KeyName; + OBJECT_ATTRIBUTES ObjectAttributes; + PKEY_OBJECT RootKey; + HANDLE RootKeyHandle; + NTSTATUS Status; + + /* Create '\Registry' key. */ + RtlInitUnicodeString(&KeyName, REG_ROOT_KEY_NAME); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = ObCreateObject(KernelMode, + CmiKeyType, + &ObjectAttributes, + KernelMode, + NULL, + sizeof(KEY_OBJECT), + 0, + 0, + (PVOID*)&RootKey); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Setup the root key */ + RootKey->RegistryHive = CmiVolatileHive; + RootKey->KeyCellOffset = CmiVolatileHive->Hive.HiveHeader->RootCell; + RootKey->KeyCell = HvGetCell(&CmiVolatileHive->Hive, RootKey->KeyCellOffset); + RootKey->ParentKey = RootKey; + RootKey->Flags = 0; + RootKey->SubKeyCounts = 0; + RootKey->SubKeys = NULL; + RootKey->SizeOfSubKeys = 0; + InsertTailList(&CmiKeyObjectListHead, &RootKey->ListEntry); + Status = RtlpCreateUnicodeString(&RootKey->Name, L"Registry", NonPagedPool); + + /* Insert the key into the namespace */ + Status = ObInsertObject(RootKey, + NULL, + KEY_ALL_ACCESS, + 0, + NULL, + &RootKeyHandle); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Reference the key again so that we never lose it */ + Status = ObReferenceObjectByHandle(RootKeyHandle, + KEY_READ, + NULL, + KernelMode, + (PVOID*)&RootKey, + NULL); + if (!NT_SUCCESS(Status)) return FALSE; + + /* Completely sucessful */ + return TRUE; } BOOLEAN @@ -266,159 +418,172 @@ INIT_FUNCTION NTAPI CmInitSystem1(VOID) { - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING KeyName; - PKEY_OBJECT RootKey; -#if 0 - PCM_KEY_SECURITY RootSecurityCell; -#endif - HANDLE RootKeyHandle; - HANDLE KeyHandle; - NTSTATUS Status; - LARGE_INTEGER DueTime; - HANDLE ThreadHandle; - CLIENT_ID ThreadId; - OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; - UNICODE_STRING Name; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName; + HANDLE KeyHandle; + NTSTATUS Status; + LARGE_INTEGER DueTime; + HANDLE ThreadHandle; + CLIENT_ID ThreadId; + PEREGISTRY_HIVE HardwareHive; + BOOLEAN Allocate = FALSE; + PVOID BaseAddress; + ULONG Length; + PAGED_CODE(); - DPRINT("Creating Registry Object Type\n"); - - /* Initialize the Key object type */ - RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); - RtlInitUnicodeString(&Name, L"Key"); - ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); - ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(KEY_OBJECT); - ObjectTypeInitializer.GenericMapping = CmiKeyMapping; - ObjectTypeInitializer.PoolType = PagedPool; - ObjectTypeInitializer.ValidAccessMask = KEY_ALL_ACCESS; - ObjectTypeInitializer.UseDefaultObject = TRUE; - ObjectTypeInitializer.DeleteProcedure = CmiObjectDelete; - ObjectTypeInitializer.ParseProcedure = CmiObjectParse; - ObjectTypeInitializer.SecurityProcedure = CmiObjectSecurity; - ObjectTypeInitializer.QueryNameProcedure = CmiObjectQueryName; + /* Initialize the hive list */ + InitializeListHead(&CmiHiveListHead); - ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &CmiKeyType); + /* Initialize registry lock */ + ExInitializeResourceLite(&CmiRegistryLock); - /* Initialize the hive list */ - InitializeListHead(&CmiHiveListHead); + /* Initialize the key object list */ + InitializeListHead(&CmiKeyObjectListHead); + InitializeListHead(&CmiConnectedHiveList); - /* Initialize registry lock */ - ExInitializeResourceLite(&CmiRegistryLock); + /* Initialize the worker timer */ + KeInitializeTimerEx(&CmiWorkerTimer, SynchronizationTimer); - /* Initialize the key object list */ - InitializeListHead(&CmiKeyObjectListHead); - InitializeListHead(&CmiConnectedHiveList); + /* Initialize the worker thread */ + Status = PsCreateSystemThread(&ThreadHandle, + THREAD_ALL_ACCESS, + NULL, + NULL, + &ThreadId, + CmiWorkerThread, + NULL); + if (!NT_SUCCESS(Status)) return FALSE; - /* Initialize the worker timer */ - KeInitializeTimerEx(&CmiWorkerTimer, SynchronizationTimer); + /* Start the timer */ + DueTime.QuadPart = -1; + KeSetTimerEx(&CmiWorkerTimer, DueTime, 5000, NULL); /* 5sec */ - /* Initialize the worker thread */ - Status = PsCreateSystemThread(&ThreadHandle, - THREAD_ALL_ACCESS, - NULL, - NULL, - &ThreadId, - CmiWorkerThread, - NULL); - if (!NT_SUCCESS(Status)) return FALSE; + InitializeListHead(&CmiCallbackHead); + ExInitializeFastMutex(&CmiCallbackLock); - /* Start the timer */ - DueTime.QuadPart = -1; - KeSetTimerEx(&CmiWorkerTimer, DueTime, 5000, NULL); /* 5sec */ + /* Create the key object types */ + Status = CmpCreateObjectTypes(); + if (!NT_SUCCESS(Status)) + { + /* Bugcheck */ + KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 1, Status, 0); + } - /* Build volatile registry store */ - Status = CmiCreateVolatileHive (&CmiVolatileHive); - ASSERT(NT_SUCCESS(Status)); + /* Build volatile registry store */ + Status = CmiCreateVolatileHive(&CmiVolatileHive); + if (!NT_SUCCESS(Status)) + { + /* Bugcheck */ + KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 2, Status, 0); + } - InitializeListHead(&CmiCallbackHead); - ExInitializeFastMutex(&CmiCallbackLock); + /* Create the \REGISTRY key node */ + if (!CmpCreateRegistryRoot()) + { + /* Bugcheck */ + KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 4, 0, 0); + } - /* Create '\Registry' key. */ - RtlInitUnicodeString(&KeyName, REG_ROOT_KEY_NAME); - InitializeObjectAttributes(&ObjectAttributes, &KeyName, 0, NULL, NULL); - Status = ObCreateObject(KernelMode, - CmiKeyType, - &ObjectAttributes, - KernelMode, - NULL, - sizeof(KEY_OBJECT), - 0, - 0, - (PVOID *) &RootKey); - ASSERT(NT_SUCCESS(Status)); - Status = ObInsertObject(RootKey, - NULL, - KEY_ALL_ACCESS, - 0, - NULL, - &RootKeyHandle); - ASSERT(NT_SUCCESS(Status)); - RootKey->RegistryHive = CmiVolatileHive; - RootKey->KeyCellOffset = CmiVolatileHive->Hive.HiveHeader->RootCell; - RootKey->KeyCell = HvGetCell (&CmiVolatileHive->Hive, RootKey->KeyCellOffset); - RootKey->ParentKey = RootKey; - RootKey->Flags = 0; - RootKey->SubKeyCounts = 0; - RootKey->SubKeys = NULL; - RootKey->SizeOfSubKeys = 0; - InsertTailList(&CmiKeyObjectListHead, &RootKey->ListEntry); - Status = RtlpCreateUnicodeString(&RootKey->Name, L"Registry", NonPagedPool); - ASSERT(NT_SUCCESS(Status)); + /* Create '\Registry\Machine' key. */ + RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\MACHINE"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtCreateKey(&KeyHandle, + KEY_READ | KEY_WRITE, + &ObjectAttributes, + 0, + NULL, + 0, + NULL); + if (!NT_SUCCESS(Status)) + { + /* Bugcheck */ + KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 5, Status, 0); + } -#if 0 - Status = CmiAllocateCell(CmiVolatileHive, - 0x10, //LONG CellSize, - (PVOID *)&RootSecurityCell, - &RootKey->KeyCell->SecurityKeyOffset); - ASSERT(NT_SUCCESS(Status)); + /* Close the handle */ + NtClose(KeyHandle); - /* Copy the security descriptor */ + /* Create '\Registry\User' key. */ + RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\USER"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtCreateKey(&KeyHandle, + KEY_READ | KEY_WRITE, + &ObjectAttributes, + 0, + NULL, + 0, + NULL); + if (!NT_SUCCESS(Status)) + { + /* Bugcheck */ + KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 6, Status, 0); + } - CmiVolatileHive->RootSecurityCell = RootSecurityCell; -#endif + /* Close the handle */ + NtClose(KeyHandle); + /* Initialize the system hive */ + if (!CmpInitializeSystemHive(KeLoaderBlock)) + { + /* Bugcheck */ + KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 7, 0, 0); + } - /* Create '\Registry\Machine' key. */ - RtlInitUnicodeString(&KeyName, - L"Machine"); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - 0, - RootKeyHandle, - NULL); - Status = ZwCreateKey(&KeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_VOLATILE, - NULL); - ASSERT(NT_SUCCESS(Status)); + /* Create the 'CurrentControlSet' link. */ + Status = CmiCreateCurrentControlSetLink(); + if (!NT_SUCCESS(Status)) + { + /* Bugcheck */ + KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 8, Status, 0); + } - /* Create '\Registry\User' key. */ - RtlInitUnicodeString(&KeyName, - L"User"); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - 0, - RootKeyHandle, - NULL); - Status = ZwCreateKey(&KeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_VOLATILE, - NULL); - ASSERT(NT_SUCCESS(Status)); + /* Initialize the hardware hive */ + BaseAddress = CmpRosGetHardwareHive(&Length); + if (!CmImportHardwareHive(BaseAddress, Length, &HardwareHive)) + { + /* Create dummy keys if no hardware hive was found */ + if (!CmImportHardwareHive (NULL, 0, &HardwareHive)) + { + /* Bugcheck */ + KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 11, Status, 0); + } - /* Import and Load Registry Hives */ - CmInitHives(ExpInTextModeSetup); - return TRUE; + /* Don't actually link anything below */ + Allocate = TRUE; + } + + /* Attach it to the machine key */ + RtlInitUnicodeString(&KeyName, REG_HARDWARE_KEY_NAME); + Status = CmpLinkHiveToMaster(&KeyName, NULL, HardwareHive, FALSE, NULL); + if (!NT_SUCCESS(Status)) + { + /* Bugcheck */ + KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 12, Status, 0); + } + + /* Initialize volatile registry settings */ + Status = CmpSetSystemValues(KeLoaderBlock); + if (!NT_SUCCESS(Status)) + { + /* Bugcheck */ + KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 15, Status, 0); + } + + /* Free the load options */ + ExFreePool(CmpLoadOptions.Buffer); + + /* If we got here, all went well */ + return TRUE; } - - static NTSTATUS CmiCreateCurrentControlSetLink(VOID) { @@ -435,6 +600,7 @@ CmiCreateCurrentControlSetLink(VOID) NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE KeyHandle; + if (ExpInTextModeSetup) return STATUS_SUCCESS; DPRINT("CmiCreateCurrentControlSetLink() called\n"); diff --git a/reactos/ntoskrnl/config/cmsysini.c b/reactos/ntoskrnl/config/cmsysini.c new file mode 100644 index 00000000000..115dcc55d41 --- /dev/null +++ b/reactos/ntoskrnl/config/cmsysini.c @@ -0,0 +1,646 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/config/cmsysini.c + * PURPOSE: Configuration Manager - System Initialization Code + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include "ntoskrnl.h" +#include "cm.h" +#define NDEBUG +#include "debug.h" + +#if 0 +/* GLOBALS *******************************************************************/ + +UNICODE_STRING CmSymbolicLinkValueName = + RTL_CONSTANT_STRING(L"SymbolicLinkValue"); + +UNICODE_STRING CmpSystemStartOptions; +UNICODE_STRING CmpLoadOptions; + +/* FUNCTIONS *****************************************************************/ + +NTSTATUS +NTAPI +CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName, ValueName; + HANDLE KeyHandle; + NTSTATUS Status; + ASSERT(LoaderBlock != NULL); + + /* Setup attributes for loader options */ + RtlInitUnicodeString(&KeyName, + L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\" + L"Control"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenKey(&KeyHandle, KEY_WRITE, &ObjectAttributes); + if (!NT_SUCCESS(Status)) goto Quickie; + + /* Key opened, now write to the key */ + RtlInitUnicodeString(&KeyName, L"SystemStartOptions"); + Status = NtSetValueKey(KeyHandle, + &KeyName, + 0, + REG_SZ, + CmpSystemStartOptions.Buffer, + CmpSystemStartOptions.Length); + if (!NT_SUCCESS(Status)) goto Quickie; + + /* Free the options now */ + ExFreePool(CmpSystemStartOptions.Buffer); + + /* Setup value name for system boot device */ + RtlInitUnicodeString(&KeyName, L"SystemBootDevice"); + RtlCreateUnicodeStringFromAsciiz(&ValueName, LoaderBlock->NtBootPathName); + Status = NtSetValueKey(KeyHandle, + &KeyName, + 0, + REG_SZ, + ValueName.Buffer, + ValueName.Length); + +Quickie: + /* Free the buffers */ + RtlFreeUnicodeString(&ValueName); + + /* Close the key and return */ + NtClose(KeyHandle); + + /* Return the status */ + return Status; +} + +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, "%04ld", 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%03ld", + 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, "%04ld",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\\%04ld", + 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; +} +#endif diff --git a/reactos/ntoskrnl/include/internal/ntoskrnl.h b/reactos/ntoskrnl/include/internal/ntoskrnl.h index 78fb018de7b..d1062a0328c 100644 --- a/reactos/ntoskrnl/include/internal/ntoskrnl.h +++ b/reactos/ntoskrnl/include/internal/ntoskrnl.h @@ -73,8 +73,8 @@ typedef struct __DESCRIPTOR BOOLEAN NTAPI ObInit(VOID); BOOLEAN NTAPI CmInitSystem1(VOID); VOID CmShutdownRegistry(VOID); -BOOLEAN CmImportSystemHive(PCHAR ChunkBase, ULONG ChunkSize); -BOOLEAN CmImportHardwareHive(PCHAR ChunkBase, ULONG ChunkSize); +//BOOLEAN CmImportSystemHive(PCHAR ChunkBase, ULONG ChunkSize); +//BOOLEAN CmImportHardwareHive(PCHAR ChunkBase, ULONG ChunkSize); BOOLEAN NTAPI KdInitSystem(ULONG Reserved, PLOADER_PARAMETER_BLOCK LoaderBlock); /* FIXME - RtlpCreateUnicodeString is obsolete and should be removed ASAP! */ diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index e081c6948bc..78c12cdd26e 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -92,6 +92,7 @@ cmname.c cmparse.c cmsecach.c + cmsysini.c cmvalue.c