mirror of
https://github.com/reactos/reactos.git
synced 2024-07-21 11:48:04 +00:00
- 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
This commit is contained in:
parent
83bd3b5fc0
commit
0285323c9d
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
646
reactos/ntoskrnl/config/cmsysini.c
Normal file
646
reactos/ntoskrnl/config/cmsysini.c
Normal file
|
@ -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
|
|
@ -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! */
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
<file>cmname.c</file>
|
||||
<file>cmparse.c</file>
|
||||
<file>cmsecach.c</file>
|
||||
<file>cmsysini.c</file>
|
||||
<file>cmvalue.c</file>
|
||||
</directory>
|
||||
<directory name="cm">
|
||||
|
|
Loading…
Reference in a new issue