- Implement NtCreateKey using the new parse routine.

- NtOpenKey should only return the key handle if the operation was successful.
- Point to new parse routine, and rename it to CmParseKey instead of CmParseKey2 which was used during the test phase.
- Delete all of the "cm" directory, this code is now fully gone; the new Configuration Manager is in place.
- Move cm.h and cm_x.h to include/internal where they belong to and fix all their includers.

svn path=/trunk/; revision=31252
This commit is contained in:
Aleksey Bragin
2007-12-15 18:14:41 +00:00
parent ffa5f05eca
commit 0b6a2fda00
34 changed files with 11540 additions and 12666 deletions
-18
View File
@@ -1,18 +0,0 @@
#ifndef __INCLUDE_CM_H
#define __INCLUDE_CM_H
#include "ntoskrnl/config/cm.h"
extern POBJECT_TYPE CmpKeyObjectType;
extern ERESOURCE CmpRegistryLock;
extern EX_PUSH_LOCK CmpHiveListHeadLock;
#define VERIFY_BIN_HEADER(x) ASSERT(x->HeaderId == REG_BIN_ID)
#define VERIFY_KEY_CELL(x) ASSERT(x->Signature == CM_KEY_NODE_SIGNATURE)
#define VERIFY_ROOT_KEY_CELL(x) ASSERT(x->Signature == CM_KEY_NODE_SIGNATURE)
#define VERIFY_VALUE_CELL(x) ASSERT(x->Signature == CM_KEY_VALUE_SIGNATURE)
#define VERIFY_VALUE_LIST_CELL(x)
#define VERIFY_KEY_OBJECT(x)
#define VERIFY_REGISTRY_HIVE(x)
#endif /*__INCLUDE_CM_H*/
File diff suppressed because it is too large Load Diff
-1
View File
@@ -11,7 +11,6 @@
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
#include "cm.h"
/* GLOBALS *******************************************************************/
-1
View File
@@ -9,7 +9,6 @@
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#include "cm.h"
#define NDEBUG
#include "debug.h"
+126 -127
View File
@@ -1,127 +1,126 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmboot.c
* PURPOSE: Configuration Manager - Boot Initialization
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#include "cm.h"
#define NDEBUG
#include "debug.h"
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
HCELL_INDEX
NTAPI
CmpFindControlSet(IN PHHIVE SystemHive,
IN HCELL_INDEX RootCell,
IN PUNICODE_STRING SelectKeyName,
OUT PBOOLEAN AutoSelect)
{
UNICODE_STRING KeyName;
PCM_KEY_NODE Node;
HCELL_INDEX SelectCell, AutoSelectCell, SelectValueCell, ControlSetCell;
HCELL_INDEX CurrentValueCell;
PCM_KEY_VALUE KeyValue;
ULONG Length;
PULONG ControlSetId;
ANSI_STRING ControlSetAnsiName;
CHAR Buffer[128];
WCHAR WideBuffer[128];
NTSTATUS Status;
PULONG CurrentData;
/* Sanity check */
ASSERT(SystemHive->ReleaseCellRoutine == NULL);
/* Get the Select subkey */
RtlInitUnicodeString(&KeyName, L"select");
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, RootCell);
if (!Node) return HCELL_NIL;
SelectCell = CmpFindSubKeyByName(SystemHive, Node, &KeyName);
if (SelectCell == HCELL_NIL) return SelectCell;
/* Get AutoSelect value */
RtlInitUnicodeString(&KeyName, L"AutoSelect");
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
if (!Node) return HCELL_NIL;
AutoSelectCell = CmpFindValueByName(SystemHive, Node, &KeyName);
if (AutoSelectCell == HCELL_NIL)
{
/* Assume TRUE if the value is missing. */
*AutoSelect = TRUE;
}
else
{
/* Read the value */
KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, AutoSelectCell);
if (KeyValue == NULL) return HCELL_NIL;
/* Convert it to a boolean */
*AutoSelect = *(PBOOLEAN)CmpValueToData(SystemHive, KeyValue, &Length);
}
/* Now find the control set being looked up */
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
if (!Node) return HCELL_NIL;
SelectValueCell = CmpFindValueByName(SystemHive, Node, SelectKeyName);
if (SelectValueCell == HCELL_NIL) return SelectValueCell;
/* Read the value (corresponding to the CCS ID) */
KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, SelectValueCell);
if (!KeyValue) return HCELL_NIL;
if (KeyValue->Type != REG_DWORD) return HCELL_NIL;
ControlSetId = (PULONG)CmpValueToData(SystemHive, KeyValue, &Length);
/* Now build an Ansi String for the CCS's Name */
sprintf(Buffer, "ControlSet%03lu", *ControlSetId);
ControlSetAnsiName.Length = (USHORT)strlen(Buffer);
ControlSetAnsiName.MaximumLength = (USHORT)strlen(Buffer);
ControlSetAnsiName.Buffer = Buffer;
/* And convert it to Unicode... */
KeyName.MaximumLength = 256;
KeyName.Buffer = WideBuffer;
Status = RtlAnsiStringToUnicodeString(&KeyName,
&ControlSetAnsiName,
FALSE);
if (!NT_SUCCESS(Status)) return HCELL_NIL;
/* Now open it */
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, RootCell);
if (!Node) return HCELL_NIL;
ControlSetCell = CmpFindSubKeyByName(SystemHive, Node, &KeyName);
if (ControlSetCell == HCELL_NIL) return ControlSetCell;
/* Get the value of the "Current" CCS */
RtlInitUnicodeString(&KeyName, L"Current");
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
if (!Node) return HCELL_NIL;
CurrentValueCell = CmpFindValueByName(SystemHive, Node, &KeyName);
/* Make sure it exists */
if (CurrentValueCell != HCELL_NIL)
{
/* Get the current value and make sure its a ULONG */
KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, CurrentValueCell);
if (!KeyValue) return HCELL_NIL;
if (KeyValue->Type == REG_DWORD)
{
/* Get the data and update it */
CurrentData = (PULONG)CmpValueToData(SystemHive,
KeyValue,
&Length);
if (!CurrentData) return HCELL_NIL;
*CurrentData = *ControlSetId;
}
}
/* Return the CCS Cell */
return ControlSetCell;
}
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmboot.c
* PURPOSE: Configuration Manager - Boot Initialization
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#define NDEBUG
#include "debug.h"
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
HCELL_INDEX
NTAPI
CmpFindControlSet(IN PHHIVE SystemHive,
IN HCELL_INDEX RootCell,
IN PUNICODE_STRING SelectKeyName,
OUT PBOOLEAN AutoSelect)
{
UNICODE_STRING KeyName;
PCM_KEY_NODE Node;
HCELL_INDEX SelectCell, AutoSelectCell, SelectValueCell, ControlSetCell;
HCELL_INDEX CurrentValueCell;
PCM_KEY_VALUE KeyValue;
ULONG Length;
PULONG ControlSetId;
ANSI_STRING ControlSetAnsiName;
CHAR Buffer[128];
WCHAR WideBuffer[128];
NTSTATUS Status;
PULONG CurrentData;
/* Sanity check */
ASSERT(SystemHive->ReleaseCellRoutine == NULL);
/* Get the Select subkey */
RtlInitUnicodeString(&KeyName, L"select");
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, RootCell);
if (!Node) return HCELL_NIL;
SelectCell = CmpFindSubKeyByName(SystemHive, Node, &KeyName);
if (SelectCell == HCELL_NIL) return SelectCell;
/* Get AutoSelect value */
RtlInitUnicodeString(&KeyName, L"AutoSelect");
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
if (!Node) return HCELL_NIL;
AutoSelectCell = CmpFindValueByName(SystemHive, Node, &KeyName);
if (AutoSelectCell == HCELL_NIL)
{
/* Assume TRUE if the value is missing. */
*AutoSelect = TRUE;
}
else
{
/* Read the value */
KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, AutoSelectCell);
if (KeyValue == NULL) return HCELL_NIL;
/* Convert it to a boolean */
*AutoSelect = *(PBOOLEAN)CmpValueToData(SystemHive, KeyValue, &Length);
}
/* Now find the control set being looked up */
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
if (!Node) return HCELL_NIL;
SelectValueCell = CmpFindValueByName(SystemHive, Node, SelectKeyName);
if (SelectValueCell == HCELL_NIL) return SelectValueCell;
/* Read the value (corresponding to the CCS ID) */
KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, SelectValueCell);
if (!KeyValue) return HCELL_NIL;
if (KeyValue->Type != REG_DWORD) return HCELL_NIL;
ControlSetId = (PULONG)CmpValueToData(SystemHive, KeyValue, &Length);
/* Now build an Ansi String for the CCS's Name */
sprintf(Buffer, "ControlSet%03lu", *ControlSetId);
ControlSetAnsiName.Length = (USHORT)strlen(Buffer);
ControlSetAnsiName.MaximumLength = (USHORT)strlen(Buffer);
ControlSetAnsiName.Buffer = Buffer;
/* And convert it to Unicode... */
KeyName.MaximumLength = 256;
KeyName.Buffer = WideBuffer;
Status = RtlAnsiStringToUnicodeString(&KeyName,
&ControlSetAnsiName,
FALSE);
if (!NT_SUCCESS(Status)) return HCELL_NIL;
/* Now open it */
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, RootCell);
if (!Node) return HCELL_NIL;
ControlSetCell = CmpFindSubKeyByName(SystemHive, Node, &KeyName);
if (ControlSetCell == HCELL_NIL) return ControlSetCell;
/* Get the value of the "Current" CCS */
RtlInitUnicodeString(&KeyName, L"Current");
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
if (!Node) return HCELL_NIL;
CurrentValueCell = CmpFindValueByName(SystemHive, Node, &KeyName);
/* Make sure it exists */
if (CurrentValueCell != HCELL_NIL)
{
/* Get the current value and make sure its a ULONG */
KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, CurrentValueCell);
if (!KeyValue) return HCELL_NIL;
if (KeyValue->Type == REG_DWORD)
{
/* Get the data and update it */
CurrentData = (PULONG)CmpValueToData(SystemHive,
KeyValue,
&Length);
if (!CurrentData) return HCELL_NIL;
*CurrentData = *ControlSetId;
}
}
/* Return the CCS Cell */
return ControlSetCell;
}
+26 -27
View File
@@ -1,27 +1,26 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmcheck.c
* PURPOSE: Configuration Manager - Hive and Key Validation
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#include "cm.h"
#define NDEBUG
#include "debug.h"
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
ULONG
NTAPI
CmCheckRegistry(IN PCMHIVE RegistryHive,
IN ULONG Flags)
{
/* FIXME: HACK! */
return 0;
}
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmcheck.c
* PURPOSE: Configuration Manager - Hive and Key Validation
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#define NDEBUG
#include "debug.h"
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
ULONG
NTAPI
CmCheckRegistry(IN PCMHIVE RegistryHive,
IN ULONG Flags)
{
/* FIXME: HACK! */
return 0;
}
+398 -399
View File
@@ -1,399 +1,398 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmconfig.c
* PURPOSE: Configuration Manager - System Configuration Routines
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#include "cm.h"
#define NDEBUG
#include "debug.h"
/* FUNCTIONS *****************************************************************/
NTSTATUS
NTAPI
CmpInitializeRegistryNode(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
IN HANDLE NodeHandle,
OUT PHANDLE NewHandle,
IN INTERFACE_TYPE InterfaceType,
IN ULONG BusNumber,
IN PUSHORT DeviceIndexTable)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName, ValueName, ValueData;
HANDLE KeyHandle, ParentHandle;
ANSI_STRING TempString;
CHAR TempBuffer[12];
WCHAR Buffer[12];
PCONFIGURATION_COMPONENT Component;
ULONG Disposition, Length = 0;
/* Get the component */
Component = &CurrentEntry->ComponentEntry;
/* Set system class components to ARC system type */
if (Component->Class == SystemClass) Component->Type = ArcSystem;
/* Create a key for the component */
InitializeObjectAttributes(&ObjectAttributes,
&CmTypeName[Component->Type],
OBJ_CASE_INSENSITIVE,
NodeHandle,
NULL);
Status = NtCreateKey(&KeyHandle,
KEY_READ | KEY_WRITE,
&ObjectAttributes,
0,
NULL,
0,
&Disposition);
if (!NT_SUCCESS(Status)) return Status;
/* Check if this is anything but a system class component */
if (Component->Class != SystemClass)
{
/* Build the sub-component string */
RtlIntegerToChar(DeviceIndexTable[Component->Type]++,
10,
12,
TempBuffer);
RtlInitAnsiString(&TempString, TempBuffer);
/* Convert it to Unicode */
RtlInitEmptyUnicodeString(&KeyName, Buffer, sizeof(Buffer));
RtlAnsiStringToUnicodeString(&KeyName, &TempString, FALSE);
/* Create the key */
ParentHandle = KeyHandle;
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
ParentHandle,
NULL);
Status = NtCreateKey(&KeyHandle,
KEY_READ | KEY_WRITE,
&ObjectAttributes,
0,
NULL,
0,
&Disposition);
NtClose(ParentHandle);
/* Fail if the key couldn't be created, and make sure it's a new key */
if (!NT_SUCCESS(Status)) return Status;
ASSERT(Disposition == REG_CREATED_NEW_KEY);
}
/* Setup the component information key */
RtlInitUnicodeString(&ValueName, L"Component Information");
Status = NtSetValueKey(KeyHandle,
&ValueName,
0,
REG_BINARY,
&Component->Flags,
FIELD_OFFSET(CONFIGURATION_COMPONENT,
ConfigurationDataLength) -
FIELD_OFFSET(CONFIGURATION_COMPONENT, Flags));
if (!NT_SUCCESS(Status))
{
/* Fail */
NtClose(KeyHandle);
return Status;
}
/* Check if we have an identifier */
if (Component->IdentifierLength)
{
/* Build the string and convert it to Unicode */
RtlInitUnicodeString(&ValueName, L"Identifier");
RtlInitAnsiString(&TempString, Component->Identifier);
Status = RtlAnsiStringToUnicodeString(&ValueData,
&TempString,
TRUE);
RtlCreateUnicodeString(&ValueData, (PWCHAR)Component->Identifier);
if (NT_SUCCESS(Status))
{
/* Save the identifier in the registry */
Status = NtSetValueKey(KeyHandle,
&ValueName,
0,
REG_SZ,
ValueData.Buffer,
ValueData.Length + sizeof(UNICODE_NULL));
RtlFreeUnicodeString(&ValueData);
}
/* Check for failure during conversion or registry write */
if (!NT_SUCCESS(Status))
{
/* Fail */
NtClose(KeyHandle);
return Status;
}
}
/* Setup the configuration data string */
RtlInitUnicodeString(&ValueName, L"Configuration Data");
/* Check if we got configuration data */
if (CurrentEntry->ConfigurationData)
{
/* Calculate the total length and check if it fits into our buffer */
Length = Component->ConfigurationDataLength +
FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList);
if (Length > CmpConfigurationAreaSize)
{
ASSERTMSG("Component too large -- need reallocation!", FALSE);
}
else
{
/* Copy the data */
RtlCopyMemory(&CmpConfigurationData->PartialResourceList.Version,
CurrentEntry->ConfigurationData,
Component->ConfigurationDataLength);
}
}
else
{
/* No configuration data, setup defaults */
CmpConfigurationData->PartialResourceList.Version = 0;
CmpConfigurationData->PartialResourceList.Revision = 0;
CmpConfigurationData->PartialResourceList.Count = 0;
Length = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors) +
FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList);
}
/* Set the interface type and bus number */
CmpConfigurationData->InterfaceType = InterfaceType;
CmpConfigurationData->BusNumber = BusNumber;
/* Save the actual data */
Status = NtSetValueKey(KeyHandle,
&ValueName,
0,
REG_FULL_RESOURCE_DESCRIPTOR,
CmpConfigurationData,
Length);
if (!NT_SUCCESS(Status))
{
/* Fail */
NtClose(KeyHandle);
}
else
{
/* Return the new handle */
*NewHandle = KeyHandle;
}
/* Return status */
return Status;
}
NTSTATUS
NTAPI
CmpSetupConfigurationTree(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
IN HANDLE ParentHandle,
IN INTERFACE_TYPE InterfaceType,
IN ULONG BusNumber)
{
PCONFIGURATION_COMPONENT Component;
USHORT DeviceIndexTable[MaximumType + 1] = {0};
ULONG Interface = InterfaceType, Bus = BusNumber, i;
NTSTATUS Status;
HANDLE NewHandle;
/* Loop each entry */
while (CurrentEntry)
{
/* Check if this is an adapter */
Component = &CurrentEntry->ComponentEntry;
if ((Component->Class == AdapterClass) &&
(CurrentEntry->Parent->ComponentEntry.Class == SystemClass))
{
/* Check what kind of adapter it is */
switch (Component->Type)
{
/* EISA */
case EisaAdapter:
/* Fixup information */
Interface = Eisa;
Bus = CmpTypeCount[EisaAdapter]++;
break;
/* Turbo-channel */
case TcAdapter:
/* Fixup information */
Interface = TurboChannel;
Bus = CmpTypeCount[TurboChannel]++;
break;
/* ISA, PCI, etc busses */
case MultiFunctionAdapter:
/* Check if we have an identifier */
if (Component->Identifier)
{
/* Loop each multi-function adapter type */
for (i = 0; CmpMultifunctionTypes[i].Identifier; i++)
{
/* Check for a name match */
if (!_wcsicmp(CmpMultifunctionTypes[i].Identifier,
(PWCHAR)Component->Identifier))
{
/* Match found */
break;
}
}
/* Fix up information */
Interface = CmpMultifunctionTypes[i].InterfaceType;
Bus = CmpMultifunctionTypes[i].Count++;
}
break;
/* SCSI Bus */
case ScsiAdapter:
/* Fix up */
Interface = Internal;
Bus = CmpTypeCount[ScsiAdapter]++;
break;
/* Unknown */
default:
Interface = -1;
Bus = CmpUnknownBusCount++;
break;
}
}
/* Dump information on the component */
/* Setup the hardware node */
Status = CmpInitializeRegistryNode(CurrentEntry,
ParentHandle,
&NewHandle,
Interface,
Bus,
DeviceIndexTable);
if (!NT_SUCCESS(Status)) return Status;
/* Check for children */
if (CurrentEntry->Child)
{
/* Recurse child */
Status = CmpSetupConfigurationTree(CurrentEntry->Child,
NewHandle,
Interface,
Bus);
if (!NT_SUCCESS(Status))
{
/* Fail */
NtClose(NewHandle);
return Status;
}
}
/* Get to the next entry */
NtClose(NewHandle);
CurrentEntry = CurrentEntry->Sibling;
}
/* We're done */
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
CmpInitializeHardwareConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE KeyHandle;
ULONG Disposition;
UNICODE_STRING KeyName;
/* Setup the key name */
RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\Hardware\\DeviceMap");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
/* Create the device map key */
Status = NtCreateKey(&KeyHandle,
KEY_READ | KEY_WRITE,
&ObjectAttributes,
0,
NULL,
0,
&Disposition);
if (!NT_SUCCESS(Status)) return Status;
NtClose(KeyHandle);
/* Nobody should've created this key yet! */
ASSERT(Disposition == REG_CREATED_NEW_KEY);
/* Setup the key name */
RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\Hardware\\Description");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
/* Create the description key */
Status = NtCreateKey(&KeyHandle,
KEY_READ | KEY_WRITE,
&ObjectAttributes,
0,
NULL,
0,
&Disposition);
if (!NT_SUCCESS(Status)) return Status;
/* Nobody should've created this key yet! */
ASSERT(Disposition == REG_CREATED_NEW_KEY);
/* Allocate the configuration data buffer */
CmpConfigurationData = ExAllocatePoolWithTag(PagedPool,
CmpConfigurationAreaSize,
TAG_CM);
if (!CmpConfigurationData) return STATUS_INSUFFICIENT_RESOURCES;
/* Check if we got anything from NTLDR */
if (LoaderBlock->ConfigurationRoot)
{
/* Setup the configuration tree */
Status = CmpSetupConfigurationTree(LoaderBlock->ConfigurationRoot,
KeyHandle,
-1,
-1);
}
else
{
/* Nothing else to do */
Status = STATUS_SUCCESS;
}
/* Close our handle, free the buffer and return status */
ExFreePool(CmpConfigurationData);
NtClose(KeyHandle);
return Status;
}
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmconfig.c
* PURPOSE: Configuration Manager - System Configuration Routines
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#define NDEBUG
#include "debug.h"
/* FUNCTIONS *****************************************************************/
NTSTATUS
NTAPI
CmpInitializeRegistryNode(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
IN HANDLE NodeHandle,
OUT PHANDLE NewHandle,
IN INTERFACE_TYPE InterfaceType,
IN ULONG BusNumber,
IN PUSHORT DeviceIndexTable)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName, ValueName, ValueData;
HANDLE KeyHandle, ParentHandle;
ANSI_STRING TempString;
CHAR TempBuffer[12];
WCHAR Buffer[12];
PCONFIGURATION_COMPONENT Component;
ULONG Disposition, Length = 0;
/* Get the component */
Component = &CurrentEntry->ComponentEntry;
/* Set system class components to ARC system type */
if (Component->Class == SystemClass) Component->Type = ArcSystem;
/* Create a key for the component */
InitializeObjectAttributes(&ObjectAttributes,
&CmTypeName[Component->Type],
OBJ_CASE_INSENSITIVE,
NodeHandle,
NULL);
Status = NtCreateKey(&KeyHandle,
KEY_READ | KEY_WRITE,
&ObjectAttributes,
0,
NULL,
0,
&Disposition);
if (!NT_SUCCESS(Status)) return Status;
/* Check if this is anything but a system class component */
if (Component->Class != SystemClass)
{
/* Build the sub-component string */
RtlIntegerToChar(DeviceIndexTable[Component->Type]++,
10,
12,
TempBuffer);
RtlInitAnsiString(&TempString, TempBuffer);
/* Convert it to Unicode */
RtlInitEmptyUnicodeString(&KeyName, Buffer, sizeof(Buffer));
RtlAnsiStringToUnicodeString(&KeyName, &TempString, FALSE);
/* Create the key */
ParentHandle = KeyHandle;
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
ParentHandle,
NULL);
Status = NtCreateKey(&KeyHandle,
KEY_READ | KEY_WRITE,
&ObjectAttributes,
0,
NULL,
0,
&Disposition);
NtClose(ParentHandle);
/* Fail if the key couldn't be created, and make sure it's a new key */
if (!NT_SUCCESS(Status)) return Status;
ASSERT(Disposition == REG_CREATED_NEW_KEY);
}
/* Setup the component information key */
RtlInitUnicodeString(&ValueName, L"Component Information");
Status = NtSetValueKey(KeyHandle,
&ValueName,
0,
REG_BINARY,
&Component->Flags,
FIELD_OFFSET(CONFIGURATION_COMPONENT,
ConfigurationDataLength) -
FIELD_OFFSET(CONFIGURATION_COMPONENT, Flags));
if (!NT_SUCCESS(Status))
{
/* Fail */
NtClose(KeyHandle);
return Status;
}
/* Check if we have an identifier */
if (Component->IdentifierLength)
{
/* Build the string and convert it to Unicode */
RtlInitUnicodeString(&ValueName, L"Identifier");
RtlInitAnsiString(&TempString, Component->Identifier);
Status = RtlAnsiStringToUnicodeString(&ValueData,
&TempString,
TRUE);
RtlCreateUnicodeString(&ValueData, (PWCHAR)Component->Identifier);
if (NT_SUCCESS(Status))
{
/* Save the identifier in the registry */
Status = NtSetValueKey(KeyHandle,
&ValueName,
0,
REG_SZ,
ValueData.Buffer,
ValueData.Length + sizeof(UNICODE_NULL));
RtlFreeUnicodeString(&ValueData);
}
/* Check for failure during conversion or registry write */
if (!NT_SUCCESS(Status))
{
/* Fail */
NtClose(KeyHandle);
return Status;
}
}
/* Setup the configuration data string */
RtlInitUnicodeString(&ValueName, L"Configuration Data");
/* Check if we got configuration data */
if (CurrentEntry->ConfigurationData)
{
/* Calculate the total length and check if it fits into our buffer */
Length = Component->ConfigurationDataLength +
FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList);
if (Length > CmpConfigurationAreaSize)
{
ASSERTMSG("Component too large -- need reallocation!", FALSE);
}
else
{
/* Copy the data */
RtlCopyMemory(&CmpConfigurationData->PartialResourceList.Version,
CurrentEntry->ConfigurationData,
Component->ConfigurationDataLength);
}
}
else
{
/* No configuration data, setup defaults */
CmpConfigurationData->PartialResourceList.Version = 0;
CmpConfigurationData->PartialResourceList.Revision = 0;
CmpConfigurationData->PartialResourceList.Count = 0;
Length = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors) +
FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList);
}
/* Set the interface type and bus number */
CmpConfigurationData->InterfaceType = InterfaceType;
CmpConfigurationData->BusNumber = BusNumber;
/* Save the actual data */
Status = NtSetValueKey(KeyHandle,
&ValueName,
0,
REG_FULL_RESOURCE_DESCRIPTOR,
CmpConfigurationData,
Length);
if (!NT_SUCCESS(Status))
{
/* Fail */
NtClose(KeyHandle);
}
else
{
/* Return the new handle */
*NewHandle = KeyHandle;
}
/* Return status */
return Status;
}
NTSTATUS
NTAPI
CmpSetupConfigurationTree(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
IN HANDLE ParentHandle,
IN INTERFACE_TYPE InterfaceType,
IN ULONG BusNumber)
{
PCONFIGURATION_COMPONENT Component;
USHORT DeviceIndexTable[MaximumType + 1] = {0};
ULONG Interface = InterfaceType, Bus = BusNumber, i;
NTSTATUS Status;
HANDLE NewHandle;
/* Loop each entry */
while (CurrentEntry)
{
/* Check if this is an adapter */
Component = &CurrentEntry->ComponentEntry;
if ((Component->Class == AdapterClass) &&
(CurrentEntry->Parent->ComponentEntry.Class == SystemClass))
{
/* Check what kind of adapter it is */
switch (Component->Type)
{
/* EISA */
case EisaAdapter:
/* Fixup information */
Interface = Eisa;
Bus = CmpTypeCount[EisaAdapter]++;
break;
/* Turbo-channel */
case TcAdapter:
/* Fixup information */
Interface = TurboChannel;
Bus = CmpTypeCount[TurboChannel]++;
break;
/* ISA, PCI, etc busses */
case MultiFunctionAdapter:
/* Check if we have an identifier */
if (Component->Identifier)
{
/* Loop each multi-function adapter type */
for (i = 0; CmpMultifunctionTypes[i].Identifier; i++)
{
/* Check for a name match */
if (!_wcsicmp(CmpMultifunctionTypes[i].Identifier,
(PWCHAR)Component->Identifier))
{
/* Match found */
break;
}
}
/* Fix up information */
Interface = CmpMultifunctionTypes[i].InterfaceType;
Bus = CmpMultifunctionTypes[i].Count++;
}
break;
/* SCSI Bus */
case ScsiAdapter:
/* Fix up */
Interface = Internal;
Bus = CmpTypeCount[ScsiAdapter]++;
break;
/* Unknown */
default:
Interface = -1;
Bus = CmpUnknownBusCount++;
break;
}
}
/* Dump information on the component */
/* Setup the hardware node */
Status = CmpInitializeRegistryNode(CurrentEntry,
ParentHandle,
&NewHandle,
Interface,
Bus,
DeviceIndexTable);
if (!NT_SUCCESS(Status)) return Status;
/* Check for children */
if (CurrentEntry->Child)
{
/* Recurse child */
Status = CmpSetupConfigurationTree(CurrentEntry->Child,
NewHandle,
Interface,
Bus);
if (!NT_SUCCESS(Status))
{
/* Fail */
NtClose(NewHandle);
return Status;
}
}
/* Get to the next entry */
NtClose(NewHandle);
CurrentEntry = CurrentEntry->Sibling;
}
/* We're done */
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
CmpInitializeHardwareConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE KeyHandle;
ULONG Disposition;
UNICODE_STRING KeyName;
/* Setup the key name */
RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\Hardware\\DeviceMap");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
/* Create the device map key */
Status = NtCreateKey(&KeyHandle,
KEY_READ | KEY_WRITE,
&ObjectAttributes,
0,
NULL,
0,
&Disposition);
if (!NT_SUCCESS(Status)) return Status;
NtClose(KeyHandle);
/* Nobody should've created this key yet! */
ASSERT(Disposition == REG_CREATED_NEW_KEY);
/* Setup the key name */
RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\Hardware\\Description");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
/* Create the description key */
Status = NtCreateKey(&KeyHandle,
KEY_READ | KEY_WRITE,
&ObjectAttributes,
0,
NULL,
0,
&Disposition);
if (!NT_SUCCESS(Status)) return Status;
/* Nobody should've created this key yet! */
ASSERT(Disposition == REG_CREATED_NEW_KEY);
/* Allocate the configuration data buffer */
CmpConfigurationData = ExAllocatePoolWithTag(PagedPool,
CmpConfigurationAreaSize,
TAG_CM);
if (!CmpConfigurationData) return STATUS_INSUFFICIENT_RESOURCES;
/* Check if we got anything from NTLDR */
if (LoaderBlock->ConfigurationRoot)
{
/* Setup the configuration tree */
Status = CmpSetupConfigurationTree(LoaderBlock->ConfigurationRoot,
KeyHandle,
-1,
-1);
}
else
{
/* Nothing else to do */
Status = STATUS_SUCCESS;
}
/* Close our handle, free the buffer and return status */
ExFreePool(CmpConfigurationData);
NtClose(KeyHandle);
return Status;
}
+264 -265
View File
@@ -1,265 +1,264 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmcontrl.c
* PURPOSE: Configuration Manager - Control Set Management
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#include "cm.h"
#define NDEBUG
#include "debug.h"
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
LANGID
NTAPI
CmpConvertLangId(IN LPWSTR Name,
IN ULONG NameLength)
{
ULONG i;
WCHAR p;
LANGID LangId = 0;
ULONG IdCode;
/* Convert the length in chars and loop */
NameLength = NameLength / sizeof(WCHAR);
for (i = 0; i < NameLength; i++)
{
/* Get the character */
p = Name[i];
/* Handle each case */
if ((p >= L'0') && (p <= L'9'))
{
/* Handle digits*/
IdCode = p - L'0';
}
else if ((p >= L'A') && (p <= L'F'))
{
/* Handle upper-case letters */
IdCode = p - L'A' + 10;
}
else if ((p >= L'a') && (p <= L'f'))
{
/* Handle lower-case letters */
IdCode = p - L'a' + 10;
}
else
{
/* Unhandled case, return what we have till now */
break;
}
/* If the ID Code is >= 16, then we're done */
if (IdCode >= 16) break;
/* Build the Language ID */
LangId = (LangId << 4) | (LANGID)IdCode;
}
/* Return the Language ID */
return LangId;
}
HCELL_INDEX
NTAPI
CmpWalkPath(IN PHHIVE SystemHive,
IN HCELL_INDEX ParentCell,
IN LPWSTR Path)
{
UNICODE_STRING UnicodePath, NextName;
BOOLEAN LastName;
HCELL_INDEX CurrentCell = ParentCell;
PCM_KEY_NODE Node;
/* We shouldn't have a release routine at this point */
ASSERT(SystemHive->ReleaseCellRoutine == NULL);
/* Initialize the Unicode path and start looping */
RtlInitUnicodeString(&UnicodePath, Path);
while (TRUE)
{
/* Get the next name */
CmpGetNextName(&UnicodePath, &NextName, &LastName);
if (!NextName.Length) return CurrentCell;
/* Get the subkey */
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, CurrentCell);
if (!Node) return HCELL_NIL;
CurrentCell = CmpFindSubKeyByName(SystemHive, Node, &NextName);
if (CurrentCell == HCELL_NIL) return CurrentCell;
}
}
VOID
NTAPI
CmGetSystemControlValues(IN PVOID SystemHiveData,
IN PCM_SYSTEM_CONTROL_VECTOR ControlVector)
{
PHHIVE SystemHive = (PHHIVE)&CmControlHive;
NTSTATUS Status;
HCELL_INDEX RootCell, BaseCell, KeyCell, ValueCell;
ULONG Length, DataSize;
PCM_KEY_NODE Node;
PCM_KEY_VALUE ValueData;
UNICODE_STRING KeyName;
BOOLEAN Auto, IsSmallKey;
PVOID Buffer;
/* LUDDDIIIICRROOOUUSSSS KI^H^H HACKKKK */
if (!SystemHiveData) return;
/* Initialize the Hive View List and the security cache */
RtlZeroMemory(SystemHive, sizeof(SystemHive));
CmpInitHiveViewList((PCMHIVE)SystemHive);
CmpInitSecurityCache((PCMHIVE)SystemHive);
/* Initialize the Hive */
Status = HvInitialize(SystemHive,
HINIT_FLAT,
HIVE_VOLATILE,
HFILE_TYPE_PRIMARY,
SystemHiveData,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
1,
NULL);
if (!NT_SUCCESS(Status)) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 1, 1, 0, 0);
/* Sanity check, flat hives don't have release routines */
ASSERT(SystemHive->ReleaseCellRoutine == NULL);
/* FIXME: Prepare it */
CmPrepareHive(SystemHive);
/* Set the Root Cell */
RootCell = ((PHBASE_BLOCK)SystemHiveData)->RootCell;
/* Find the current control set */
RtlInitUnicodeString(&KeyName, L"current");
BaseCell = CmpFindControlSet(SystemHive, RootCell, &KeyName, &Auto);
if (BaseCell == HCELL_NIL) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 1, 2, 0, 0);
/* Find the control subkey */
RtlInitUnicodeString(&KeyName, L"control");
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, BaseCell);
BaseCell = CmpFindSubKeyByName(SystemHive, Node, &KeyName);
if (BaseCell == HCELL_NIL) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO,1 , 3, 0, 0);
/* Loop each key */
while (ControlVector->KeyPath)
{
/* Assume failure */
Length = -1;
/* Get the cell for this key */
KeyCell = CmpWalkPath(SystemHive, BaseCell, ControlVector->KeyPath);
if (KeyCell != HCELL_NIL)
{
/* Now get the cell for the value */
RtlInitUnicodeString(&KeyName, ControlVector->ValueName);
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, KeyCell);
ValueCell = CmpFindValueByName(SystemHive, Node, &KeyName);
if (ValueCell != HCELL_NIL)
{
/* Check if there's any data */
if (!ControlVector->BufferLength)
{
/* No, the buffer will only be large enough for a ULONG */
DataSize = sizeof(ULONG);
}
else
{
/* Yes, save the data size */
DataSize = *ControlVector->BufferLength;
}
/* Get the actual data */
ValueData = (PCM_KEY_VALUE)HvGetCell(SystemHive, ValueCell);
/* Check if this is a small key */
IsSmallKey = CmpIsKeyValueSmall(&Length, ValueData->DataLength);
/* If the length is bigger then our buffer, normalize it */
if (DataSize < Length) Length = DataSize;
/* Make sure we have some data */
if (Length > 0)
{
/* Check if this was a small key */
if (IsSmallKey)
{
/* The buffer is directly safe to read */
Buffer = (PVOID)(&(ValueData->Data));
}
else
{
/* Use the longer path */
Buffer = (PVOID)HvGetCell(SystemHive, ValueData->Data);
}
/* Sanity check if this is a small key */
ASSERT((IsSmallKey ?
(Length <= CM_KEY_VALUE_SMALL) : TRUE));
/* Copy the data in the buffer */
RtlCopyMemory(ControlVector->Buffer, Buffer, Length);
}
/* Check if we should return the data type */
if (ControlVector->Type)
{
/* Return the type that we read */
*ControlVector->Type = ValueData->Type;
}
}
}
/* Return the size that we read */
if (ControlVector->BufferLength) *ControlVector->BufferLength = Length;
/* Go to the next entry */
ControlVector++;
}
/* Check if the ID is in the registry */
if (CmDefaultLanguageIdType == REG_SZ)
{
/* Read it */
PsDefaultSystemLocaleId =
(LCID)CmpConvertLangId(CmDefaultLanguageId,
CmDefaultLanguageIdLength);
}
else
{
/* Use EN_US by default */
PsDefaultSystemLocaleId = 0x409;
}
/* Check if the ID Is in the registry */
if (CmInstallUILanguageIdType == REG_SZ)
{
/* Read it */
PsInstallUILanguageId = CmpConvertLangId(CmInstallUILanguageId,
CmInstallUILanguageIdLength);
}
else
{
/* Otherwise, use the default */
PsInstallUILanguageId = LANGIDFROMLCID(PsDefaultSystemLocaleId);
}
/* Set the defaults for the Thread UI */
PsDefaultThreadLocaleId = PsDefaultSystemLocaleId;
PsDefaultUILanguageId = PsInstallUILanguageId;
}
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmcontrl.c
* PURPOSE: Configuration Manager - Control Set Management
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#define NDEBUG
#include "debug.h"
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
LANGID
NTAPI
CmpConvertLangId(IN LPWSTR Name,
IN ULONG NameLength)
{
ULONG i;
WCHAR p;
LANGID LangId = 0;
ULONG IdCode;
/* Convert the length in chars and loop */
NameLength = NameLength / sizeof(WCHAR);
for (i = 0; i < NameLength; i++)
{
/* Get the character */
p = Name[i];
/* Handle each case */
if ((p >= L'0') && (p <= L'9'))
{
/* Handle digits*/
IdCode = p - L'0';
}
else if ((p >= L'A') && (p <= L'F'))
{
/* Handle upper-case letters */
IdCode = p - L'A' + 10;
}
else if ((p >= L'a') && (p <= L'f'))
{
/* Handle lower-case letters */
IdCode = p - L'a' + 10;
}
else
{
/* Unhandled case, return what we have till now */
break;
}
/* If the ID Code is >= 16, then we're done */
if (IdCode >= 16) break;
/* Build the Language ID */
LangId = (LangId << 4) | (LANGID)IdCode;
}
/* Return the Language ID */
return LangId;
}
HCELL_INDEX
NTAPI
CmpWalkPath(IN PHHIVE SystemHive,
IN HCELL_INDEX ParentCell,
IN LPWSTR Path)
{
UNICODE_STRING UnicodePath, NextName;
BOOLEAN LastName;
HCELL_INDEX CurrentCell = ParentCell;
PCM_KEY_NODE Node;
/* We shouldn't have a release routine at this point */
ASSERT(SystemHive->ReleaseCellRoutine == NULL);
/* Initialize the Unicode path and start looping */
RtlInitUnicodeString(&UnicodePath, Path);
while (TRUE)
{
/* Get the next name */
CmpGetNextName(&UnicodePath, &NextName, &LastName);
if (!NextName.Length) return CurrentCell;
/* Get the subkey */
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, CurrentCell);
if (!Node) return HCELL_NIL;
CurrentCell = CmpFindSubKeyByName(SystemHive, Node, &NextName);
if (CurrentCell == HCELL_NIL) return CurrentCell;
}
}
VOID
NTAPI
CmGetSystemControlValues(IN PVOID SystemHiveData,
IN PCM_SYSTEM_CONTROL_VECTOR ControlVector)
{
PHHIVE SystemHive = (PHHIVE)&CmControlHive;
NTSTATUS Status;
HCELL_INDEX RootCell, BaseCell, KeyCell, ValueCell;
ULONG Length, DataSize;
PCM_KEY_NODE Node;
PCM_KEY_VALUE ValueData;
UNICODE_STRING KeyName;
BOOLEAN Auto, IsSmallKey;
PVOID Buffer;
/* LUDDDIIIICRROOOUUSSSS KI^H^H HACKKKK */
if (!SystemHiveData) return;
/* Initialize the Hive View List and the security cache */
RtlZeroMemory(SystemHive, sizeof(SystemHive));
CmpInitHiveViewList((PCMHIVE)SystemHive);
CmpInitSecurityCache((PCMHIVE)SystemHive);
/* Initialize the Hive */
Status = HvInitialize(SystemHive,
HINIT_FLAT,
HIVE_VOLATILE,
HFILE_TYPE_PRIMARY,
SystemHiveData,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
1,
NULL);
if (!NT_SUCCESS(Status)) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 1, 1, 0, 0);
/* Sanity check, flat hives don't have release routines */
ASSERT(SystemHive->ReleaseCellRoutine == NULL);
/* FIXME: Prepare it */
CmPrepareHive(SystemHive);
/* Set the Root Cell */
RootCell = ((PHBASE_BLOCK)SystemHiveData)->RootCell;
/* Find the current control set */
RtlInitUnicodeString(&KeyName, L"current");
BaseCell = CmpFindControlSet(SystemHive, RootCell, &KeyName, &Auto);
if (BaseCell == HCELL_NIL) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 1, 2, 0, 0);
/* Find the control subkey */
RtlInitUnicodeString(&KeyName, L"control");
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, BaseCell);
BaseCell = CmpFindSubKeyByName(SystemHive, Node, &KeyName);
if (BaseCell == HCELL_NIL) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO,1 , 3, 0, 0);
/* Loop each key */
while (ControlVector->KeyPath)
{
/* Assume failure */
Length = -1;
/* Get the cell for this key */
KeyCell = CmpWalkPath(SystemHive, BaseCell, ControlVector->KeyPath);
if (KeyCell != HCELL_NIL)
{
/* Now get the cell for the value */
RtlInitUnicodeString(&KeyName, ControlVector->ValueName);
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, KeyCell);
ValueCell = CmpFindValueByName(SystemHive, Node, &KeyName);
if (ValueCell != HCELL_NIL)
{
/* Check if there's any data */
if (!ControlVector->BufferLength)
{
/* No, the buffer will only be large enough for a ULONG */
DataSize = sizeof(ULONG);
}
else
{
/* Yes, save the data size */
DataSize = *ControlVector->BufferLength;
}
/* Get the actual data */
ValueData = (PCM_KEY_VALUE)HvGetCell(SystemHive, ValueCell);
/* Check if this is a small key */
IsSmallKey = CmpIsKeyValueSmall(&Length, ValueData->DataLength);
/* If the length is bigger then our buffer, normalize it */
if (DataSize < Length) Length = DataSize;
/* Make sure we have some data */
if (Length > 0)
{
/* Check if this was a small key */
if (IsSmallKey)
{
/* The buffer is directly safe to read */
Buffer = (PVOID)(&(ValueData->Data));
}
else
{
/* Use the longer path */
Buffer = (PVOID)HvGetCell(SystemHive, ValueData->Data);
}
/* Sanity check if this is a small key */
ASSERT((IsSmallKey ?
(Length <= CM_KEY_VALUE_SMALL) : TRUE));
/* Copy the data in the buffer */
RtlCopyMemory(ControlVector->Buffer, Buffer, Length);
}
/* Check if we should return the data type */
if (ControlVector->Type)
{
/* Return the type that we read */
*ControlVector->Type = ValueData->Type;
}
}
}
/* Return the size that we read */
if (ControlVector->BufferLength) *ControlVector->BufferLength = Length;
/* Go to the next entry */
ControlVector++;
}
/* Check if the ID is in the registry */
if (CmDefaultLanguageIdType == REG_SZ)
{
/* Read it */
PsDefaultSystemLocaleId =
(LCID)CmpConvertLangId(CmDefaultLanguageId,
CmDefaultLanguageIdLength);
}
else
{
/* Use EN_US by default */
PsDefaultSystemLocaleId = 0x409;
}
/* Check if the ID Is in the registry */
if (CmInstallUILanguageIdType == REG_SZ)
{
/* Read it */
PsInstallUILanguageId = CmpConvertLangId(CmInstallUILanguageId,
CmInstallUILanguageIdLength);
}
else
{
/* Otherwise, use the default */
PsInstallUILanguageId = LANGIDFROMLCID(PsDefaultSystemLocaleId);
}
/* Set the defaults for the Thread UI */
PsDefaultThreadLocaleId = PsDefaultSystemLocaleId;
PsDefaultUILanguageId = PsInstallUILanguageId;
}
File diff suppressed because it is too large Load Diff
-1
View File
@@ -11,7 +11,6 @@
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
#include "cm.h"
/* GLOBALS *******************************************************************/
+197 -198
View File
@@ -1,198 +1,197 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmhook.c
* PURPOSE: Configuration Manager - Registry Notifications/Callbacks
* PROGRAMMERS: Thomas Weidenmueller ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#include "cm.h"
#define NDEBUG
#include "debug.h"
/* GLOBALS *******************************************************************/
ULONG CmpCallBackCount = 0;
EX_CALLBACK CmpCallBackVector[100];
LIST_ENTRY CmiCallbackHead;
FAST_MUTEX CmiCallbackLock;
typedef struct _REGISTRY_CALLBACK
{
LIST_ENTRY ListEntry;
EX_RUNDOWN_REF RundownRef;
PEX_CALLBACK_FUNCTION Function;
PVOID Context;
LARGE_INTEGER Cookie;
BOOLEAN PendingDelete;
} REGISTRY_CALLBACK, *PREGISTRY_CALLBACK;
/* PRIVATE FUNCTIONS *********************************************************/
VOID
NTAPI
CmpInitCallback(VOID)
{
ULONG i;
PAGED_CODE();
/* Reset counter */
CmpCallBackCount = 0;
/* Loop all the callbacks */
for (i = 0; i < CMP_MAX_CALLBACKS; i++)
{
/* Initialize this one */
ExInitializeCallBack(&CmpCallBackVector[i]);
}
/* ROS: Initialize old-style callbacks for now */
InitializeListHead(&CmiCallbackHead);
ExInitializeFastMutex(&CmiCallbackLock);
}
NTSTATUS
CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1,
IN PVOID Argument2)
{
PLIST_ENTRY CurrentEntry;
NTSTATUS Status = STATUS_SUCCESS;
PREGISTRY_CALLBACK CurrentCallback;
PAGED_CODE();
ExAcquireFastMutex(&CmiCallbackLock);
for (CurrentEntry = CmiCallbackHead.Flink;
CurrentEntry != &CmiCallbackHead;
CurrentEntry = CurrentEntry->Flink)
{
CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry);
if (!CurrentCallback->PendingDelete &&
ExAcquireRundownProtection(&CurrentCallback->RundownRef))
{
/* don't hold locks during the callbacks! */
ExReleaseFastMutex(&CmiCallbackLock);
Status = CurrentCallback->Function(CurrentCallback->Context,
(PVOID)Argument1,
Argument2);
ExAcquireFastMutex(&CmiCallbackLock);
/* don't release the rundown protection before holding the callback lock
so the pointer to the next callback isn't cleared in case this callback
get's deleted */
ExReleaseRundownProtection(&CurrentCallback->RundownRef);
if(!NT_SUCCESS(Status))
{
/* one callback returned failure, don't call any more callbacks */
break;
}
}
}
ExReleaseFastMutex(&CmiCallbackLock);
return Status;
}
/* PUBLIC FUNCTIONS **********************************************************/
/*
* @implemented
*/
NTSTATUS
NTAPI
CmRegisterCallback(IN PEX_CALLBACK_FUNCTION Function,
IN PVOID Context,
IN OUT PLARGE_INTEGER Cookie)
{
PREGISTRY_CALLBACK Callback;
PAGED_CODE();
ASSERT(Function && Cookie);
Callback = ExAllocatePoolWithTag(PagedPool,
sizeof(REGISTRY_CALLBACK),
TAG('C', 'M', 'c', 'b'));
if (Callback != NULL)
{
/* initialize the callback */
ExInitializeRundownProtection(&Callback->RundownRef);
Callback->Function = Function;
Callback->Context = Context;
Callback->PendingDelete = FALSE;
/* add it to the callback list and receive a cookie for the callback */
ExAcquireFastMutex(&CmiCallbackLock);
/* FIXME - to receive a unique cookie we'll just return the pointer to the
callback object */
Callback->Cookie.QuadPart = (ULONG_PTR)Callback;
InsertTailList(&CmiCallbackHead, &Callback->ListEntry);
ExReleaseFastMutex(&CmiCallbackLock);
*Cookie = Callback->Cookie;
return STATUS_SUCCESS;
}
return STATUS_INSUFFICIENT_RESOURCES;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
CmUnRegisterCallback(IN LARGE_INTEGER Cookie)
{
PLIST_ENTRY CurrentEntry;
PREGISTRY_CALLBACK CurrentCallback;
PAGED_CODE();
ExAcquireFastMutex(&CmiCallbackLock);
for (CurrentEntry = CmiCallbackHead.Flink;
CurrentEntry != &CmiCallbackHead;
CurrentEntry = CurrentEntry->Flink)
{
CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry);
if (CurrentCallback->Cookie.QuadPart == Cookie.QuadPart)
{
if (!CurrentCallback->PendingDelete)
{
/* found the callback, don't unlink it from the list yet so we don't screw
the calling loop */
CurrentCallback->PendingDelete = TRUE;
ExReleaseFastMutex(&CmiCallbackLock);
/* if the callback is currently executing, wait until it finished */
ExWaitForRundownProtectionRelease(&CurrentCallback->RundownRef);
/* time to unlink it. It's now safe because every attempt to acquire a
runtime protection on this callback will fail */
ExAcquireFastMutex(&CmiCallbackLock);
RemoveEntryList(&CurrentCallback->ListEntry);
ExReleaseFastMutex(&CmiCallbackLock);
/* free the callback */
ExFreePool(CurrentCallback);
return STATUS_SUCCESS;
}
else
{
/* pending delete, pretend like it already is deleted */
ExReleaseFastMutex(&CmiCallbackLock);
return STATUS_UNSUCCESSFUL;
}
}
}
ExReleaseFastMutex(&CmiCallbackLock);
return STATUS_UNSUCCESSFUL;
}
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmhook.c
* PURPOSE: Configuration Manager - Registry Notifications/Callbacks
* PROGRAMMERS: Thomas Weidenmueller ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#define NDEBUG
#include "debug.h"
/* GLOBALS *******************************************************************/
ULONG CmpCallBackCount = 0;
EX_CALLBACK CmpCallBackVector[100];
LIST_ENTRY CmiCallbackHead;
FAST_MUTEX CmiCallbackLock;
typedef struct _REGISTRY_CALLBACK
{
LIST_ENTRY ListEntry;
EX_RUNDOWN_REF RundownRef;
PEX_CALLBACK_FUNCTION Function;
PVOID Context;
LARGE_INTEGER Cookie;
BOOLEAN PendingDelete;
} REGISTRY_CALLBACK, *PREGISTRY_CALLBACK;
/* PRIVATE FUNCTIONS *********************************************************/
VOID
NTAPI
CmpInitCallback(VOID)
{
ULONG i;
PAGED_CODE();
/* Reset counter */
CmpCallBackCount = 0;
/* Loop all the callbacks */
for (i = 0; i < CMP_MAX_CALLBACKS; i++)
{
/* Initialize this one */
ExInitializeCallBack(&CmpCallBackVector[i]);
}
/* ROS: Initialize old-style callbacks for now */
InitializeListHead(&CmiCallbackHead);
ExInitializeFastMutex(&CmiCallbackLock);
}
NTSTATUS
CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1,
IN PVOID Argument2)
{
PLIST_ENTRY CurrentEntry;
NTSTATUS Status = STATUS_SUCCESS;
PREGISTRY_CALLBACK CurrentCallback;
PAGED_CODE();
ExAcquireFastMutex(&CmiCallbackLock);
for (CurrentEntry = CmiCallbackHead.Flink;
CurrentEntry != &CmiCallbackHead;
CurrentEntry = CurrentEntry->Flink)
{
CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry);
if (!CurrentCallback->PendingDelete &&
ExAcquireRundownProtection(&CurrentCallback->RundownRef))
{
/* don't hold locks during the callbacks! */
ExReleaseFastMutex(&CmiCallbackLock);
Status = CurrentCallback->Function(CurrentCallback->Context,
(PVOID)Argument1,
Argument2);
ExAcquireFastMutex(&CmiCallbackLock);
/* don't release the rundown protection before holding the callback lock
so the pointer to the next callback isn't cleared in case this callback
get's deleted */
ExReleaseRundownProtection(&CurrentCallback->RundownRef);
if(!NT_SUCCESS(Status))
{
/* one callback returned failure, don't call any more callbacks */
break;
}
}
}
ExReleaseFastMutex(&CmiCallbackLock);
return Status;
}
/* PUBLIC FUNCTIONS **********************************************************/
/*
* @implemented
*/
NTSTATUS
NTAPI
CmRegisterCallback(IN PEX_CALLBACK_FUNCTION Function,
IN PVOID Context,
IN OUT PLARGE_INTEGER Cookie)
{
PREGISTRY_CALLBACK Callback;
PAGED_CODE();
ASSERT(Function && Cookie);
Callback = ExAllocatePoolWithTag(PagedPool,
sizeof(REGISTRY_CALLBACK),
TAG('C', 'M', 'c', 'b'));
if (Callback != NULL)
{
/* initialize the callback */
ExInitializeRundownProtection(&Callback->RundownRef);
Callback->Function = Function;
Callback->Context = Context;
Callback->PendingDelete = FALSE;
/* add it to the callback list and receive a cookie for the callback */
ExAcquireFastMutex(&CmiCallbackLock);
/* FIXME - to receive a unique cookie we'll just return the pointer to the
callback object */
Callback->Cookie.QuadPart = (ULONG_PTR)Callback;
InsertTailList(&CmiCallbackHead, &Callback->ListEntry);
ExReleaseFastMutex(&CmiCallbackLock);
*Cookie = Callback->Cookie;
return STATUS_SUCCESS;
}
return STATUS_INSUFFICIENT_RESOURCES;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
CmUnRegisterCallback(IN LARGE_INTEGER Cookie)
{
PLIST_ENTRY CurrentEntry;
PREGISTRY_CALLBACK CurrentCallback;
PAGED_CODE();
ExAcquireFastMutex(&CmiCallbackLock);
for (CurrentEntry = CmiCallbackHead.Flink;
CurrentEntry != &CmiCallbackHead;
CurrentEntry = CurrentEntry->Flink)
{
CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry);
if (CurrentCallback->Cookie.QuadPart == Cookie.QuadPart)
{
if (!CurrentCallback->PendingDelete)
{
/* found the callback, don't unlink it from the list yet so we don't screw
the calling loop */
CurrentCallback->PendingDelete = TRUE;
ExReleaseFastMutex(&CmiCallbackLock);
/* if the callback is currently executing, wait until it finished */
ExWaitForRundownProtectionRelease(&CurrentCallback->RundownRef);
/* time to unlink it. It's now safe because every attempt to acquire a
runtime protection on this callback will fail */
ExAcquireFastMutex(&CmiCallbackLock);
RemoveEntryList(&CurrentCallback->ListEntry);
ExReleaseFastMutex(&CmiCallbackLock);
/* free the callback */
ExFreePool(CurrentCallback);
return STATUS_SUCCESS;
}
else
{
/* pending delete, pretend like it already is deleted */
ExReleaseFastMutex(&CmiCallbackLock);
return STATUS_UNSUCCESSFUL;
}
}
}
ExReleaseFastMutex(&CmiCallbackLock);
return STATUS_UNSUCCESSFUL;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+220 -221
View File
@@ -1,221 +1,220 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmkeydel.c
* PURPOSE: Configuration Manager - Key Body Deletion
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#include "cm.h"
#define NDEBUG
#include "debug.h"
/* FUNCTIONS *****************************************************************/
BOOLEAN
NTAPI
CmpMarkKeyDirty(IN PHHIVE Hive,
IN HCELL_INDEX Cell,
IN BOOLEAN CheckNoSubkeys)
{
PCELL_DATA CellData, ListData, SecurityData, ValueData;
ULONG i;
/* Get the cell data for our target */
CellData = HvGetCell(Hive, Cell);
if (!CellData) return FALSE;
/* Check if sanity checks requested */
if (CheckNoSubkeys)
{
/* Do them */
ASSERT(CellData->u.KeyNode.SubKeyCounts[Stable] == 0);
ASSERT(CellData->u.KeyNode.SubKeyCounts[Volatile] == 0);
}
/* If this is an exit hive, there's nothing to do */
if (CellData->u.KeyNode.Flags & KEY_HIVE_EXIT)
{
/* Release the cell and get out */
HvReleaseCell(Hive, Cell);
return TRUE;
}
/* Otherwise, mark it dirty and release it */
HvMarkCellDirty(Hive, Cell, FALSE);
HvReleaseCell(Hive, Cell);
/* Check if we have a class */
if (CellData->u.KeyNode.Class != HCELL_NIL)
{
/* Mark it dirty */
HvMarkCellDirty(Hive, CellData->u.KeyNode.Class, FALSE);
}
/* Check if we have security */
if (CellData->u.KeyNode.Security != HCELL_NIL)
{
/* Mark it dirty */
HvMarkCellDirty(Hive, CellData->u.KeyNode.Security, FALSE);
/* Get the security data and release it */
SecurityData = HvGetCell(Hive, CellData->u.KeyNode.Security);
if (!SecurityData) ASSERT(FALSE);
HvReleaseCell(Hive, CellData->u.KeyNode.Security);
/* Mark the security links dirty too */
HvMarkCellDirty(Hive, SecurityData->u.KeySecurity.Flink, FALSE);
HvMarkCellDirty(Hive, SecurityData->u.KeySecurity.Blink, FALSE);
}
/* Check if we have any values */
if (CellData->u.KeyNode.ValueList.Count > 0)
{
/* Dirty the value list */
HvMarkCellDirty(Hive, CellData->u.KeyNode.ValueList.List, FALSE);
/* Get the list data itself, and release it */
ListData = HvGetCell(Hive, CellData->u.KeyNode.ValueList.List);
if (!ListData) ASSERT(FALSE);
HvReleaseCell(Hive, CellData->u.KeyNode.ValueList.List);
/* Loop all values */
for (i = 0; i < CellData->u.KeyNode.ValueList.Count; i++)
{
/* Dirty each value */
HvMarkCellDirty(Hive, ListData->u.KeyList[i], FALSE);
/* Get the value data and release it */
ValueData = HvGetCell(Hive, ListData->u.KeyList[i]);
ASSERT(ValueData);
HvReleaseCell(Hive,ListData->u.KeyList[i]);
/* Mark the value data dirty too */
if (!CmpMarkValueDataDirty(Hive, &ValueData->u.KeyValue))
{
/* Failure */
return FALSE;
}
}
}
/* If this is an entry hive, we're done */
if (CellData->u.KeyNode.Flags & KEY_HIVE_ENTRY) return TRUE;
/* Otherwise mark the index dirty too */
if (!CmpMarkIndexDirty(Hive, CellData->u.KeyNode.Parent, Cell))
{
/* Failure */
return FALSE;
}
/* Finally, mark the parent dirty */
HvMarkCellDirty(Hive, CellData->u.KeyNode.Parent, FALSE);
return TRUE;
}
BOOLEAN
NTAPI
CmpFreeKeyBody(IN PHHIVE Hive,
IN HCELL_INDEX Cell)
{
PCELL_DATA CellData;
/* Get the key node */
CellData = HvGetCell(Hive, Cell);
if (!CellData) ASSERT(FALSE);
/* Check if we can delete the child cells */
if (!(CellData->u.KeyNode.Flags & KEY_HIVE_EXIT))
{
/* Check if we have a security cell */
if (CellData->u.KeyNode.Security != HCELL_NIL)
{
/* Free the security cell */
HvFreeCell(Hive, CellData->u.KeyNode.Security);
}
/* Check if we have a class */
if (CellData->u.KeyNode.ClassLength > 0)
{
/* Free it */
HvFreeCell(Hive, CellData->u.KeyNode.Class);
}
}
/* Release and free the cell */
HvReleaseCell(Hive, Cell);
HvFreeCell(Hive, Cell);
return TRUE;
}
NTSTATUS
NTAPI
CmpFreeKeyByCell(IN PHHIVE Hive,
IN HCELL_INDEX Cell,
IN BOOLEAN Unlink)
{
PCELL_DATA CellData, ParentData, ListData;
ULONG i;
BOOLEAN Result;
/* Mark the entire key dirty */
CmpMarkKeyDirty(Hive, Cell ,TRUE);
/* Get the target node and release it */
CellData = HvGetCell(Hive, Cell);
if (!CellData) ASSERT(FALSE);
HvReleaseCell(Hive, Cell);
/* Make sure we don't have subkeys */
ASSERT((CellData->u.KeyNode.SubKeyCounts[Stable] +
CellData->u.KeyNode.SubKeyCounts[Volatile]) == 0);
/* Check if we have to unlink */
if (Unlink)
{
/* Remove the subkey */
Result = CmpRemoveSubKey(Hive, CellData->u.KeyNode.Parent, Cell);
if (!Result) return STATUS_INSUFFICIENT_RESOURCES;
/* Get the parent node and release it */
ParentData = HvGetCell(Hive, CellData->u.KeyNode.Parent);
if (!ParentData) ASSERT(FALSE);
HvReleaseCell(Hive, CellData->u.KeyNode.Parent);
/* Check if the parent node has no more subkeys */
if (!(ParentData->u.KeyNode.SubKeyCounts[Stable] +
ParentData->u.KeyNode.SubKeyCounts[Volatile]))
{
/* Then free the cached name/class lengths */
ParentData->u.KeyNode.MaxNameLen = 0;
ParentData->u.KeyNode.MaxClassLen = 0;
}
}
/* Check if we have any values */
if (CellData->u.KeyNode.ValueList.Count > 0)
{
/* Get the value list and release it */
ListData = HvGetCell(Hive, CellData->u.KeyNode.ValueList.List);
if (!ListData) ASSERT(FALSE);
HvReleaseCell(Hive, CellData->u.KeyNode.ValueList.List);
/* Loop every value */
for (i = 0; i < CellData->u.KeyNode.ValueList.Count; i++)
{
/* Free it */
if (!CmpFreeValue(Hive, ListData->u.KeyList[i])) ASSERT(FALSE);
}
/* Free the value list */
HvFreeCell(Hive, CellData->u.KeyNode.ValueList.List);
}
/* Free the key body itself, and then return our status */
if (!CmpFreeKeyBody(Hive, Cell)) return STATUS_INSUFFICIENT_RESOURCES;
return STATUS_SUCCESS;
}
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmkeydel.c
* PURPOSE: Configuration Manager - Key Body Deletion
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#define NDEBUG
#include "debug.h"
/* FUNCTIONS *****************************************************************/
BOOLEAN
NTAPI
CmpMarkKeyDirty(IN PHHIVE Hive,
IN HCELL_INDEX Cell,
IN BOOLEAN CheckNoSubkeys)
{
PCELL_DATA CellData, ListData, SecurityData, ValueData;
ULONG i;
/* Get the cell data for our target */
CellData = HvGetCell(Hive, Cell);
if (!CellData) return FALSE;
/* Check if sanity checks requested */
if (CheckNoSubkeys)
{
/* Do them */
ASSERT(CellData->u.KeyNode.SubKeyCounts[Stable] == 0);
ASSERT(CellData->u.KeyNode.SubKeyCounts[Volatile] == 0);
}
/* If this is an exit hive, there's nothing to do */
if (CellData->u.KeyNode.Flags & KEY_HIVE_EXIT)
{
/* Release the cell and get out */
HvReleaseCell(Hive, Cell);
return TRUE;
}
/* Otherwise, mark it dirty and release it */
HvMarkCellDirty(Hive, Cell, FALSE);
HvReleaseCell(Hive, Cell);
/* Check if we have a class */
if (CellData->u.KeyNode.Class != HCELL_NIL)
{
/* Mark it dirty */
HvMarkCellDirty(Hive, CellData->u.KeyNode.Class, FALSE);
}
/* Check if we have security */
if (CellData->u.KeyNode.Security != HCELL_NIL)
{
/* Mark it dirty */
HvMarkCellDirty(Hive, CellData->u.KeyNode.Security, FALSE);
/* Get the security data and release it */
SecurityData = HvGetCell(Hive, CellData->u.KeyNode.Security);
if (!SecurityData) ASSERT(FALSE);
HvReleaseCell(Hive, CellData->u.KeyNode.Security);
/* Mark the security links dirty too */
HvMarkCellDirty(Hive, SecurityData->u.KeySecurity.Flink, FALSE);
HvMarkCellDirty(Hive, SecurityData->u.KeySecurity.Blink, FALSE);
}
/* Check if we have any values */
if (CellData->u.KeyNode.ValueList.Count > 0)
{
/* Dirty the value list */
HvMarkCellDirty(Hive, CellData->u.KeyNode.ValueList.List, FALSE);
/* Get the list data itself, and release it */
ListData = HvGetCell(Hive, CellData->u.KeyNode.ValueList.List);
if (!ListData) ASSERT(FALSE);
HvReleaseCell(Hive, CellData->u.KeyNode.ValueList.List);
/* Loop all values */
for (i = 0; i < CellData->u.KeyNode.ValueList.Count; i++)
{
/* Dirty each value */
HvMarkCellDirty(Hive, ListData->u.KeyList[i], FALSE);
/* Get the value data and release it */
ValueData = HvGetCell(Hive, ListData->u.KeyList[i]);
ASSERT(ValueData);
HvReleaseCell(Hive,ListData->u.KeyList[i]);
/* Mark the value data dirty too */
if (!CmpMarkValueDataDirty(Hive, &ValueData->u.KeyValue))
{
/* Failure */
return FALSE;
}
}
}
/* If this is an entry hive, we're done */
if (CellData->u.KeyNode.Flags & KEY_HIVE_ENTRY) return TRUE;
/* Otherwise mark the index dirty too */
if (!CmpMarkIndexDirty(Hive, CellData->u.KeyNode.Parent, Cell))
{
/* Failure */
return FALSE;
}
/* Finally, mark the parent dirty */
HvMarkCellDirty(Hive, CellData->u.KeyNode.Parent, FALSE);
return TRUE;
}
BOOLEAN
NTAPI
CmpFreeKeyBody(IN PHHIVE Hive,
IN HCELL_INDEX Cell)
{
PCELL_DATA CellData;
/* Get the key node */
CellData = HvGetCell(Hive, Cell);
if (!CellData) ASSERT(FALSE);
/* Check if we can delete the child cells */
if (!(CellData->u.KeyNode.Flags & KEY_HIVE_EXIT))
{
/* Check if we have a security cell */
if (CellData->u.KeyNode.Security != HCELL_NIL)
{
/* Free the security cell */
HvFreeCell(Hive, CellData->u.KeyNode.Security);
}
/* Check if we have a class */
if (CellData->u.KeyNode.ClassLength > 0)
{
/* Free it */
HvFreeCell(Hive, CellData->u.KeyNode.Class);
}
}
/* Release and free the cell */
HvReleaseCell(Hive, Cell);
HvFreeCell(Hive, Cell);
return TRUE;
}
NTSTATUS
NTAPI
CmpFreeKeyByCell(IN PHHIVE Hive,
IN HCELL_INDEX Cell,
IN BOOLEAN Unlink)
{
PCELL_DATA CellData, ParentData, ListData;
ULONG i;
BOOLEAN Result;
/* Mark the entire key dirty */
CmpMarkKeyDirty(Hive, Cell ,TRUE);
/* Get the target node and release it */
CellData = HvGetCell(Hive, Cell);
if (!CellData) ASSERT(FALSE);
HvReleaseCell(Hive, Cell);
/* Make sure we don't have subkeys */
ASSERT((CellData->u.KeyNode.SubKeyCounts[Stable] +
CellData->u.KeyNode.SubKeyCounts[Volatile]) == 0);
/* Check if we have to unlink */
if (Unlink)
{
/* Remove the subkey */
Result = CmpRemoveSubKey(Hive, CellData->u.KeyNode.Parent, Cell);
if (!Result) return STATUS_INSUFFICIENT_RESOURCES;
/* Get the parent node and release it */
ParentData = HvGetCell(Hive, CellData->u.KeyNode.Parent);
if (!ParentData) ASSERT(FALSE);
HvReleaseCell(Hive, CellData->u.KeyNode.Parent);
/* Check if the parent node has no more subkeys */
if (!(ParentData->u.KeyNode.SubKeyCounts[Stable] +
ParentData->u.KeyNode.SubKeyCounts[Volatile]))
{
/* Then free the cached name/class lengths */
ParentData->u.KeyNode.MaxNameLen = 0;
ParentData->u.KeyNode.MaxClassLen = 0;
}
}
/* Check if we have any values */
if (CellData->u.KeyNode.ValueList.Count > 0)
{
/* Get the value list and release it */
ListData = HvGetCell(Hive, CellData->u.KeyNode.ValueList.List);
if (!ListData) ASSERT(FALSE);
HvReleaseCell(Hive, CellData->u.KeyNode.ValueList.List);
/* Loop every value */
for (i = 0; i < CellData->u.KeyNode.ValueList.Count; i++)
{
/* Free it */
if (!CmpFreeValue(Hive, ListData->u.KeyList[i])) ASSERT(FALSE);
}
/* Free the value list */
HvFreeCell(Hive, CellData->u.KeyNode.ValueList.List);
}
/* Free the key body itself, and then return our status */
if (!CmpFreeKeyBody(Hive, Cell)) return STATUS_INSUFFICIENT_RESOURCES;
return STATUS_SUCCESS;
}
-1
View File
@@ -9,7 +9,6 @@
/* INCLUDES *******************************************************************/
#include "ntoskrnl.h"
#include "cm.h"
#define NDEBUG
#include "debug.h"
+32 -33
View File
@@ -1,33 +1,32 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmmapvw.c
* PURPOSE: Configuration Manager - Map-Viewed Hive Support
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#include "cm.h"
#define NDEBUG
#include "debug.h"
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
VOID
NTAPI
CmpInitHiveViewList(IN PCMHIVE Hive)
{
/* Initialize the list heads */
InitializeListHead(&Hive->LRUViewListHead);
InitializeListHead(&Hive->PinViewListHead);
/* Reset data */
Hive->MappedViews = 0;
Hive->PinnedViews = 0;
Hive->UseCount = 0;
}
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmmapvw.c
* PURPOSE: Configuration Manager - Map-Viewed Hive Support
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#define NDEBUG
#include "debug.h"
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
VOID
NTAPI
CmpInitHiveViewList(IN PCMHIVE Hive)
{
/* Initialize the list heads */
InitializeListHead(&Hive->LRUViewListHead);
InitializeListHead(&Hive->PinViewListHead);
/* Reset data */
Hive->MappedViews = 0;
Hive->PinnedViews = 0;
Hive->UseCount = 0;
}
+253 -254
View File
@@ -1,254 +1,253 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmname.c
* PURPOSE: Configuration Manager - Name Management
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#include "cm.h"
#define NDEBUG
#include "debug.h"
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
USHORT
NTAPI
CmpCopyName(IN PHHIVE Hive,
IN PWCHAR Destination,
IN PUNICODE_STRING Source)
{
ULONG i;
/* Check for old hives */
if (Hive->Version == 1)
{
/* Just copy the source directly */
RtlCopyMemory(Destination, Source->Buffer, Source->Length);
return Source->Length;
}
/* For new versions, check for compressed name */
for (i = 0; i < (Source->Length / sizeof(WCHAR)); i++)
{
/* Check if the name is non compressed */
if (Source->Buffer[i] > (UCHAR)-1)
{
/* Do the copy */
RtlCopyMemory(Destination, Source->Buffer, Source->Length);
return Source->Length;
}
/* Copy this character */
((PCHAR)Destination)[i] = (CHAR)(Source->Buffer[i]);
}
/* Compressed name, return length */
return Source->Length / sizeof(WCHAR);
}
VOID
NTAPI
CmpCopyCompressedName(IN PWCHAR Destination,
IN ULONG DestinationLength,
IN PWCHAR Source,
IN ULONG SourceLength)
{
ULONG i, Length;
/* Get the actual length to copy */
Length = min(DestinationLength / sizeof(WCHAR), SourceLength);
for (i = 0; i < Length; i++)
{
/* Copy each character */
Destination[i] = (WCHAR)((PCHAR)Source)[i];
}
}
USHORT
NTAPI
CmpNameSize(IN PHHIVE Hive,
IN PUNICODE_STRING Name)
{
ULONG i;
/* For old hives, just retun the length */
if (Hive->Version == 1) return Name->Length;
/* For new versions, check for compressed name */
for (i = 0; i < (Name->Length / sizeof(WCHAR)); i++)
{
/* Check if the name is non compressed */
if (Name->Buffer[i] > (UCHAR)-1) return Name->Length;
}
/* Compressed name, return length */
return Name->Length / sizeof(WCHAR);
}
USHORT
NTAPI
CmpCompressedNameSize(IN PWCHAR Name,
IN ULONG Length)
{
/*
* Don't remove this: compressed names are "opaque" and just because
* the current implementation turns them into ansi-names doesn't mean
* that it will remain that way forever, so -never- assume this code
* below internally!
*/
return (USHORT)Length * sizeof(WCHAR);
}
LONG
NTAPI
CmpCompareCompressedName(IN PCUNICODE_STRING SearchName,
IN PWCHAR CompressedName,
IN ULONG NameLength)
{
WCHAR *p;
CHAR *pp;
WCHAR p1, p2;
USHORT SearchLength;
LONG Result;
/* Set the pointers and length and then loop */
p = SearchName->Buffer;
pp = (PCHAR)CompressedName;
SearchLength = (SearchName->Length / sizeof(WCHAR));
while ((SearchLength) && (NameLength))
{
/* Get the characters */
p1 = *p++;
p2 = (WCHAR)(*pp++);
/* Check if we have a direct match */
if (p1 != p2)
{
/* See if they match and return result if they don't */
Result = (LONG)RtlUpcaseUnicodeChar(p1) -
(LONG)RtlUpcaseUnicodeChar(p2);
if (Result) return Result;
}
/* Next chars */
SearchLength--;
NameLength--;
}
/* Return the difference directly */
return SearchLength - NameLength;
}
BOOLEAN
NTAPI
CmpFindNameInList(IN PHHIVE Hive,
IN PCHILD_LIST ChildList,
IN PUNICODE_STRING Name,
IN PULONG ChildIndex,
IN PHCELL_INDEX CellIndex)
{
PCELL_DATA CellData;
HCELL_INDEX CellToRelease = HCELL_NIL;
ULONG i;
PCM_KEY_VALUE KeyValue;
LONG Result;
UNICODE_STRING SearchName;
BOOLEAN Success;
/* Make sure there's actually something on the list */
if (ChildList->Count != 0)
{
/* Get the cell data */
CellData = (PCELL_DATA)HvGetCell(Hive, ChildList->List);
if (!CellData)
{
/* Couldn't get the cell... tell the caller */
*CellIndex = HCELL_NIL;
return FALSE;
}
/* Now loop every entry */
for (i = 0; i < ChildList->Count; i++)
{
/* Check if we have a cell to release */
if (CellToRelease != HCELL_NIL)
{
/* Release it */
HvReleaseCell(Hive, CellToRelease);
CellToRelease = HCELL_NIL;
}
/* Get this value */
KeyValue = (PCM_KEY_VALUE)HvGetCell(Hive, CellData->u.KeyList[i]);
if (!KeyValue)
{
/* Return with no data found */
*CellIndex = HCELL_NIL;
Success = FALSE;
goto Return;
}
/* Save the cell to release */
CellToRelease = CellData->u.KeyList[i];
/* Check if it's a compressed value name */
if (KeyValue->Flags & VALUE_COMP_NAME)
{
/* Use the compressed name check */
Result = CmpCompareCompressedName(Name,
KeyValue->Name,
KeyValue->NameLength);
}
else
{
/* Setup the Unicode string */
SearchName.Length = KeyValue->NameLength;
SearchName.MaximumLength = SearchName.Length;
SearchName.Buffer = KeyValue->Name;
Result = RtlCompareUnicodeString(Name, &SearchName, TRUE);
}
/* Check if we found it */
if (!Result)
{
/* We did...return info to caller */
if (ChildIndex) *ChildIndex = i;
*CellIndex = CellData->u.KeyList[i];
/* Set success state */
Success = TRUE;
goto Return;
}
}
/* Got to the end of the list */
if (ChildIndex) *ChildIndex = i;
*CellIndex = HCELL_NIL;
/* Nothing found if we got here */
Success = TRUE;
goto Return;
}
/* Nothing found...check if the caller wanted more info */
ASSERT(ChildList->Count == 0);
if (ChildIndex) *ChildIndex = 0;
*CellIndex = HCELL_NIL;
/* Nothing found if we got here */
return TRUE;
Return:
/* Release the first cell we got */
if (CellData) HvReleaseCell(Hive, ChildList->List);
/* Release the secondary one, if we have one */
if (CellToRelease) HvReleaseCell(Hive, CellToRelease);
return Success;
}
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmname.c
* PURPOSE: Configuration Manager - Name Management
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#define NDEBUG
#include "debug.h"
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
USHORT
NTAPI
CmpCopyName(IN PHHIVE Hive,
IN PWCHAR Destination,
IN PUNICODE_STRING Source)
{
ULONG i;
/* Check for old hives */
if (Hive->Version == 1)
{
/* Just copy the source directly */
RtlCopyMemory(Destination, Source->Buffer, Source->Length);
return Source->Length;
}
/* For new versions, check for compressed name */
for (i = 0; i < (Source->Length / sizeof(WCHAR)); i++)
{
/* Check if the name is non compressed */
if (Source->Buffer[i] > (UCHAR)-1)
{
/* Do the copy */
RtlCopyMemory(Destination, Source->Buffer, Source->Length);
return Source->Length;
}
/* Copy this character */
((PCHAR)Destination)[i] = (CHAR)(Source->Buffer[i]);
}
/* Compressed name, return length */
return Source->Length / sizeof(WCHAR);
}
VOID
NTAPI
CmpCopyCompressedName(IN PWCHAR Destination,
IN ULONG DestinationLength,
IN PWCHAR Source,
IN ULONG SourceLength)
{
ULONG i, Length;
/* Get the actual length to copy */
Length = min(DestinationLength / sizeof(WCHAR), SourceLength);
for (i = 0; i < Length; i++)
{
/* Copy each character */
Destination[i] = (WCHAR)((PCHAR)Source)[i];
}
}
USHORT
NTAPI
CmpNameSize(IN PHHIVE Hive,
IN PUNICODE_STRING Name)
{
ULONG i;
/* For old hives, just retun the length */
if (Hive->Version == 1) return Name->Length;
/* For new versions, check for compressed name */
for (i = 0; i < (Name->Length / sizeof(WCHAR)); i++)
{
/* Check if the name is non compressed */
if (Name->Buffer[i] > (UCHAR)-1) return Name->Length;
}
/* Compressed name, return length */
return Name->Length / sizeof(WCHAR);
}
USHORT
NTAPI
CmpCompressedNameSize(IN PWCHAR Name,
IN ULONG Length)
{
/*
* Don't remove this: compressed names are "opaque" and just because
* the current implementation turns them into ansi-names doesn't mean
* that it will remain that way forever, so -never- assume this code
* below internally!
*/
return (USHORT)Length * sizeof(WCHAR);
}
LONG
NTAPI
CmpCompareCompressedName(IN PCUNICODE_STRING SearchName,
IN PWCHAR CompressedName,
IN ULONG NameLength)
{
WCHAR *p;
CHAR *pp;
WCHAR p1, p2;
USHORT SearchLength;
LONG Result;
/* Set the pointers and length and then loop */
p = SearchName->Buffer;
pp = (PCHAR)CompressedName;
SearchLength = (SearchName->Length / sizeof(WCHAR));
while ((SearchLength) && (NameLength))
{
/* Get the characters */
p1 = *p++;
p2 = (WCHAR)(*pp++);
/* Check if we have a direct match */
if (p1 != p2)
{
/* See if they match and return result if they don't */
Result = (LONG)RtlUpcaseUnicodeChar(p1) -
(LONG)RtlUpcaseUnicodeChar(p2);
if (Result) return Result;
}
/* Next chars */
SearchLength--;
NameLength--;
}
/* Return the difference directly */
return SearchLength - NameLength;
}
BOOLEAN
NTAPI
CmpFindNameInList(IN PHHIVE Hive,
IN PCHILD_LIST ChildList,
IN PUNICODE_STRING Name,
IN PULONG ChildIndex,
IN PHCELL_INDEX CellIndex)
{
PCELL_DATA CellData;
HCELL_INDEX CellToRelease = HCELL_NIL;
ULONG i;
PCM_KEY_VALUE KeyValue;
LONG Result;
UNICODE_STRING SearchName;
BOOLEAN Success;
/* Make sure there's actually something on the list */
if (ChildList->Count != 0)
{
/* Get the cell data */
CellData = (PCELL_DATA)HvGetCell(Hive, ChildList->List);
if (!CellData)
{
/* Couldn't get the cell... tell the caller */
*CellIndex = HCELL_NIL;
return FALSE;
}
/* Now loop every entry */
for (i = 0; i < ChildList->Count; i++)
{
/* Check if we have a cell to release */
if (CellToRelease != HCELL_NIL)
{
/* Release it */
HvReleaseCell(Hive, CellToRelease);
CellToRelease = HCELL_NIL;
}
/* Get this value */
KeyValue = (PCM_KEY_VALUE)HvGetCell(Hive, CellData->u.KeyList[i]);
if (!KeyValue)
{
/* Return with no data found */
*CellIndex = HCELL_NIL;
Success = FALSE;
goto Return;
}
/* Save the cell to release */
CellToRelease = CellData->u.KeyList[i];
/* Check if it's a compressed value name */
if (KeyValue->Flags & VALUE_COMP_NAME)
{
/* Use the compressed name check */
Result = CmpCompareCompressedName(Name,
KeyValue->Name,
KeyValue->NameLength);
}
else
{
/* Setup the Unicode string */
SearchName.Length = KeyValue->NameLength;
SearchName.MaximumLength = SearchName.Length;
SearchName.Buffer = KeyValue->Name;
Result = RtlCompareUnicodeString(Name, &SearchName, TRUE);
}
/* Check if we found it */
if (!Result)
{
/* We did...return info to caller */
if (ChildIndex) *ChildIndex = i;
*CellIndex = CellData->u.KeyList[i];
/* Set success state */
Success = TRUE;
goto Return;
}
}
/* Got to the end of the list */
if (ChildIndex) *ChildIndex = i;
*CellIndex = HCELL_NIL;
/* Nothing found if we got here */
Success = TRUE;
goto Return;
}
/* Nothing found...check if the caller wanted more info */
ASSERT(ChildList->Count == 0);
if (ChildIndex) *ChildIndex = 0;
*CellIndex = HCELL_NIL;
/* Nothing found if we got here */
return TRUE;
Return:
/* Release the first cell we got */
if (CellData) HvReleaseCell(Hive, ChildList->List);
/* Release the secondary one, if we have one */
if (CellToRelease) HvReleaseCell(Hive, CellToRelease);
return Success;
}
File diff suppressed because it is too large Load Diff
+152 -153
View File
@@ -1,153 +1,152 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmse.c
* PURPOSE: Configuration Manager - Security Subsystem Interface
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#include "cm.h"
#define NDEBUG
#include "debug.h"
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
PSECURITY_DESCRIPTOR
NTAPI
CmpHiveRootSecurityDescriptor(VOID)
{
NTSTATUS Status;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PACL Acl, AclCopy;
PSID Sid[4];
SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
ULONG AceLength, AclLength, SidLength;
PACE_HEADER AceHeader;
ULONG i;
PAGED_CODE();
/* Phase 1: Allocate SIDs */
SidLength = RtlLengthRequiredSid(1);
Sid[0] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
Sid[1] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
Sid[2] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
SidLength = RtlLengthRequiredSid(2);
Sid[3] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
/* Make sure all SIDs were allocated */
if (!(Sid[0]) || !(Sid[1]) || !(Sid[2]) || !(Sid[3]))
{
/* Bugcheck */
KEBUGCHECKEX(REGISTRY_ERROR, 11, 1, 0, 0);
}
/* Phase 2: Initialize all SIDs */
Status = RtlInitializeSid(Sid[0], &WorldAuthority, 1);
Status |= RtlInitializeSid(Sid[1], &NtAuthority, 1);
Status |= RtlInitializeSid(Sid[2], &NtAuthority, 1);
Status |= RtlInitializeSid(Sid[3], &NtAuthority, 2);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 2, 0, 0);
/* Phase 2: Setup SID Sub Authorities */
*RtlSubAuthoritySid(Sid[0], 0) = SECURITY_WORLD_RID;
*RtlSubAuthoritySid(Sid[1], 0) = SECURITY_RESTRICTED_CODE_RID;
*RtlSubAuthoritySid(Sid[2], 0) = SECURITY_LOCAL_SYSTEM_RID;
*RtlSubAuthoritySid(Sid[3], 0) = SECURITY_BUILTIN_DOMAIN_RID;
*RtlSubAuthoritySid(Sid[3], 1) = DOMAIN_ALIAS_RID_ADMINS;
/* Make sure all SIDs are valid */
ASSERT(RtlValidSid(Sid[0]));
ASSERT(RtlValidSid(Sid[1]));
ASSERT(RtlValidSid(Sid[2]));
ASSERT(RtlValidSid(Sid[3]));
/* Phase 3: Calculate ACL Length */
AclLength = sizeof(ACL);
for (i = 0; i < 4; i++)
{
/* This is what MSDN says to do */
AceLength = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart);
AceLength += SeLengthSid(Sid[i]);
AclLength += AceLength;
}
/* Phase 3: Allocate the ACL */
Acl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_CM);
if (!Acl) KEBUGCHECKEX(REGISTRY_ERROR, 11, 3, 0, 0);
/* Phase 4: Create the ACL */
Status = RtlCreateAcl(Acl, AclLength, ACL_REVISION);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 4, Status, 0);
/* Phase 5: Build the ACL */
Status = RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[0]);
Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[1]);
Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[2]);
Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[3]);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 5, Status, 0);
/* Phase 5: Make the ACEs inheritable */
Status = RtlGetAce(Acl, 0,( PVOID*)&AceHeader);
ASSERT(NT_SUCCESS(Status));
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
Status = RtlGetAce(Acl, 1, (PVOID*)&AceHeader);
ASSERT(NT_SUCCESS(Status));
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
Status = RtlGetAce(Acl, 2, (PVOID*)&AceHeader);
ASSERT(NT_SUCCESS(Status));
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
Status = RtlGetAce(Acl, 3, (PVOID*)&AceHeader);
ASSERT(NT_SUCCESS(Status));
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
/* Phase 6: Allocate the security descriptor and make space for the ACL */
SecurityDescriptor = ExAllocatePoolWithTag(PagedPool,
sizeof(SECURITY_DESCRIPTOR) +
AclLength,
TAG_CM);
if (!SecurityDescriptor) KEBUGCHECKEX(REGISTRY_ERROR, 11, 6, 0, 0);
/* Phase 6: Make a copy of the ACL */
AclCopy = (PACL)((PISECURITY_DESCRIPTOR)SecurityDescriptor + 1);
RtlCopyMemory(AclCopy, Acl, AclLength);
/* Phase 7: Create the security descriptor */
Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 7, Status, 0);
/* Phase 8: Set the ACL as a DACL */
Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
TRUE,
AclCopy,
FALSE);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 8, Status, 0);
/* Free the SIDs and original ACL */
for (i = 0; i < 4; i++) ExFreePool(Sid[i]);
ExFreePool(Acl);
/* Return the security descriptor */
return SecurityDescriptor;
}
NTSTATUS
NTAPI
CmpSecurityMethod(IN PVOID ObjectBody,
IN SECURITY_OPERATION_CODE OperationCode,
IN PSECURITY_INFORMATION SecurityInformation,
IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
IN OUT PULONG BufferLength,
IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
IN POOL_TYPE PoolType,
IN PGENERIC_MAPPING GenericMapping)
{
/* HACK */
return STATUS_SUCCESS;
}
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmse.c
* PURPOSE: Configuration Manager - Security Subsystem Interface
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#define NDEBUG
#include "debug.h"
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
PSECURITY_DESCRIPTOR
NTAPI
CmpHiveRootSecurityDescriptor(VOID)
{
NTSTATUS Status;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PACL Acl, AclCopy;
PSID Sid[4];
SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
ULONG AceLength, AclLength, SidLength;
PACE_HEADER AceHeader;
ULONG i;
PAGED_CODE();
/* Phase 1: Allocate SIDs */
SidLength = RtlLengthRequiredSid(1);
Sid[0] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
Sid[1] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
Sid[2] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
SidLength = RtlLengthRequiredSid(2);
Sid[3] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
/* Make sure all SIDs were allocated */
if (!(Sid[0]) || !(Sid[1]) || !(Sid[2]) || !(Sid[3]))
{
/* Bugcheck */
KEBUGCHECKEX(REGISTRY_ERROR, 11, 1, 0, 0);
}
/* Phase 2: Initialize all SIDs */
Status = RtlInitializeSid(Sid[0], &WorldAuthority, 1);
Status |= RtlInitializeSid(Sid[1], &NtAuthority, 1);
Status |= RtlInitializeSid(Sid[2], &NtAuthority, 1);
Status |= RtlInitializeSid(Sid[3], &NtAuthority, 2);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 2, 0, 0);
/* Phase 2: Setup SID Sub Authorities */
*RtlSubAuthoritySid(Sid[0], 0) = SECURITY_WORLD_RID;
*RtlSubAuthoritySid(Sid[1], 0) = SECURITY_RESTRICTED_CODE_RID;
*RtlSubAuthoritySid(Sid[2], 0) = SECURITY_LOCAL_SYSTEM_RID;
*RtlSubAuthoritySid(Sid[3], 0) = SECURITY_BUILTIN_DOMAIN_RID;
*RtlSubAuthoritySid(Sid[3], 1) = DOMAIN_ALIAS_RID_ADMINS;
/* Make sure all SIDs are valid */
ASSERT(RtlValidSid(Sid[0]));
ASSERT(RtlValidSid(Sid[1]));
ASSERT(RtlValidSid(Sid[2]));
ASSERT(RtlValidSid(Sid[3]));
/* Phase 3: Calculate ACL Length */
AclLength = sizeof(ACL);
for (i = 0; i < 4; i++)
{
/* This is what MSDN says to do */
AceLength = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart);
AceLength += SeLengthSid(Sid[i]);
AclLength += AceLength;
}
/* Phase 3: Allocate the ACL */
Acl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_CM);
if (!Acl) KEBUGCHECKEX(REGISTRY_ERROR, 11, 3, 0, 0);
/* Phase 4: Create the ACL */
Status = RtlCreateAcl(Acl, AclLength, ACL_REVISION);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 4, Status, 0);
/* Phase 5: Build the ACL */
Status = RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[0]);
Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[1]);
Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[2]);
Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[3]);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 5, Status, 0);
/* Phase 5: Make the ACEs inheritable */
Status = RtlGetAce(Acl, 0,( PVOID*)&AceHeader);
ASSERT(NT_SUCCESS(Status));
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
Status = RtlGetAce(Acl, 1, (PVOID*)&AceHeader);
ASSERT(NT_SUCCESS(Status));
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
Status = RtlGetAce(Acl, 2, (PVOID*)&AceHeader);
ASSERT(NT_SUCCESS(Status));
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
Status = RtlGetAce(Acl, 3, (PVOID*)&AceHeader);
ASSERT(NT_SUCCESS(Status));
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
/* Phase 6: Allocate the security descriptor and make space for the ACL */
SecurityDescriptor = ExAllocatePoolWithTag(PagedPool,
sizeof(SECURITY_DESCRIPTOR) +
AclLength,
TAG_CM);
if (!SecurityDescriptor) KEBUGCHECKEX(REGISTRY_ERROR, 11, 6, 0, 0);
/* Phase 6: Make a copy of the ACL */
AclCopy = (PACL)((PISECURITY_DESCRIPTOR)SecurityDescriptor + 1);
RtlCopyMemory(AclCopy, Acl, AclLength);
/* Phase 7: Create the security descriptor */
Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 7, Status, 0);
/* Phase 8: Set the ACL as a DACL */
Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
TRUE,
AclCopy,
FALSE);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 8, Status, 0);
/* Free the SIDs and original ACL */
for (i = 0; i < 4; i++) ExFreePool(Sid[i]);
ExFreePool(Acl);
/* Return the security descriptor */
return SecurityDescriptor;
}
NTSTATUS
NTAPI
CmpSecurityMethod(IN PVOID ObjectBody,
IN SECURITY_OPERATION_CODE OperationCode,
IN PSECURITY_INFORMATION SecurityInformation,
IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
IN OUT PULONG BufferLength,
IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
IN POOL_TYPE PoolType,
IN PGENERIC_MAPPING GenericMapping)
{
/* HACK */
return STATUS_SUCCESS;
}
+37 -38
View File
@@ -1,38 +1,37 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmsecach.c
* PURPOSE: Configuration Manager - Security Cache
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#include "cm.h"
#define NDEBUG
#include "debug.h"
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
VOID
NTAPI
CmpInitSecurityCache(IN PCMHIVE Hive)
{
ULONG i;
/* Reset data */
Hive->SecurityCount = 0;
Hive->SecurityCacheSize = 0;
Hive->SecurityHitHint = -1;
Hive->SecurityCache = NULL;
/* Loop every security hash */
for (i = 0; i < 64; i++)
{
/* Initialize it */
InitializeListHead(&Hive->SecurityHash[i]);
}
}
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmsecach.c
* PURPOSE: Configuration Manager - Security Cache
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#define NDEBUG
#include "debug.h"
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
VOID
NTAPI
CmpInitSecurityCache(IN PCMHIVE Hive)
{
ULONG i;
/* Reset data */
Hive->SecurityCount = 0;
Hive->SecurityCacheSize = 0;
Hive->SecurityHitHint = -1;
Hive->SecurityCache = NULL;
/* Loop every security hash */
for (i = 0; i < 64; i++)
{
/* Initialize it */
InitializeListHead(&Hive->SecurityHash[i]);
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+363 -364
View File
@@ -1,364 +1,363 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmvalue.c
* PURPOSE: Configuration Manager - Cell Values
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#include "cm.h"
#define NDEBUG
#include "debug.h"
/* FUNCTIONS *****************************************************************/
BOOLEAN
NTAPI
CmpMarkValueDataDirty(IN PHHIVE Hive,
IN PCM_KEY_VALUE Value)
{
ULONG KeySize;
PAGED_CODE();
/* Make sure there's actually any data */
if (Value->Data != HCELL_NIL)
{
/* If this is a small key, there's no need to have it dirty */
if (CmpIsKeyValueSmall(&KeySize, Value->DataLength)) return TRUE;
/* Check if this is a big key */
ASSERT_VALUE_BIG(Hive, KeySize);
/* Normal value, just mark it dirty */
HvMarkCellDirty(Hive, Value->Data, FALSE);
}
/* Operation complete */
return TRUE;
}
BOOLEAN
NTAPI
CmpFreeValueData(IN PHHIVE Hive,
IN HCELL_INDEX DataCell,
IN ULONG DataLength)
{
ULONG KeySize;
PAGED_CODE();
/* If this is a small key, the data is built-in */
if (!CmpIsKeyValueSmall(&KeySize, DataLength))
{
/* If there's no data cell, there's nothing to do */
if (DataCell == HCELL_NIL) return TRUE;
/* Make sure the data cell is allocated */
//ASSERT(HvIsCellAllocated(Hive, DataCell));
/* Unsupported value type */
ASSERT_VALUE_BIG(Hive, KeySize);
/* Normal value, just free the data cell */
HvFreeCell(Hive, DataCell);
}
/* Operation complete */
return TRUE;
}
BOOLEAN
NTAPI
CmpFreeValue(IN PHHIVE Hive,
IN HCELL_INDEX Cell)
{
PCM_KEY_VALUE Value;
PAGED_CODE();
/* Get the cell data */
Value = (PCM_KEY_VALUE)HvGetCell(Hive, Cell);
if (!Value) ASSERT(FALSE);
/* Free it */
if (!CmpFreeValueData(Hive, Value->Data, Value->DataLength))
{
/* We failed to free the data, return failure */
HvReleaseCell(Hive, Cell);
return FALSE;
}
/* Release the cell and free it */
HvReleaseCell(Hive, Cell);
HvFreeCell(Hive, Cell);
return TRUE;
}
HCELL_INDEX
NTAPI
CmpFindValueByName(IN PHHIVE Hive,
IN PCM_KEY_NODE KeyNode,
IN PUNICODE_STRING Name)
{
HCELL_INDEX CellIndex;
/* Call the main function */
if (!CmpFindNameInList(Hive,
&KeyNode->ValueList,
Name,
NULL,
&CellIndex))
{
/* Santy check */
ASSERT(CellIndex == HCELL_NIL);
}
/* Return the index */
return CellIndex;
}
BOOLEAN
NTAPI
CmpGetValueData(IN PHHIVE Hive,
IN PCM_KEY_VALUE Value,
IN PULONG Length,
OUT PVOID *Buffer,
OUT PBOOLEAN BufferAllocated,
OUT PHCELL_INDEX CellToRelease)
{
PAGED_CODE();
/* Sanity check */
ASSERT(Value->Signature == CM_KEY_VALUE_SIGNATURE);
/* Set failure defaults */
*BufferAllocated = FALSE;
*Buffer = NULL;
*CellToRelease = HCELL_NIL;
/* Check if this is a small key */
if (CmpIsKeyValueSmall(Length, Value->DataLength))
{
/* Return the data immediately */
*Buffer = &Value->Data;
return TRUE;
}
/* Unsupported */
ASSERT_VALUE_BIG(Hive, *Length);
/* Get the data from the cell */
*Buffer = HvGetCell(Hive, Value->Data);
if (!(*Buffer)) return FALSE;
/* Return success and the cell to be released */
*CellToRelease = Value->Data;
return TRUE;
}
PCELL_DATA
NTAPI
CmpValueToData(IN PHHIVE Hive,
IN PCM_KEY_VALUE Value,
OUT PULONG Length)
{
PCELL_DATA Buffer;
BOOLEAN BufferAllocated;
HCELL_INDEX CellToRelease;
PAGED_CODE();
/* Sanity check */
ASSERT(Hive->ReleaseCellRoutine == NULL);
/* Get the actual data */
if (!CmpGetValueData(Hive,
Value,
Length,
(PVOID)&Buffer,
&BufferAllocated,
&CellToRelease))
{
/* We failed */
ASSERT(BufferAllocated == FALSE);
ASSERT(Buffer == NULL);
return NULL;
}
/* This should never happen!*/
if (BufferAllocated)
{
/* Free the buffer and bugcheck */
ExFreePool(Buffer);
KEBUGCHECKEX(REGISTRY_ERROR, 8, 0, (ULONG_PTR)Hive, (ULONG_PTR)Value);
}
/* Otherwise, return the cell data */
return Buffer;
}
NTSTATUS
NTAPI
CmpAddValueToList(IN PHHIVE Hive,
IN HCELL_INDEX ValueCell,
IN ULONG Index,
IN ULONG Type,
IN OUT PCHILD_LIST ChildList)
{
HCELL_INDEX ListCell;
ULONG ChildCount, Length, i;
PCELL_DATA CellData;
PAGED_CODE();
/* Sanity check */
ASSERT((((LONG)Index) >= 0) && (Index <= ChildList->Count));
/* Get the number of entries in the child list */
ChildCount = ChildList->Count;
ChildCount++;
if (ChildCount > 1)
{
/* The cell should be dirty at this point */
ASSERT(HvIsCellDirty(Hive, ChildList->List));
/* Check if we have less then 100 children */
if (ChildCount < 100)
{
/* Allocate just enough as requested */
Length = ChildCount * sizeof(HCELL_INDEX);
}
else
{
/* Otherwise, we have quite a few, so allocate a batch */
Length = ROUND_UP(ChildCount, 100) * sizeof(HCELL_INDEX);
if (Length > HBLOCK_SIZE)
{
/* But make sure we don't allocate beyond our block size */
Length = ROUND_UP(Length, HBLOCK_SIZE);
}
}
/* Perform the allocation */
ListCell = HvReallocateCell(Hive, ChildList->List, Length);
}
else
{
/* This is our first child, so allocate a single cell */
ListCell = HvAllocateCell(Hive, sizeof(HCELL_INDEX), Type, HCELL_NIL);
}
/* Fail if we couldn't get a cell */
if (ListCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
/* Set this cell as the child list's list cell */
ChildList->List = ListCell;
/* Get the actual key list memory */
CellData = HvGetCell(Hive, ListCell);
ASSERT(CellData != NULL);
/* Loop all the children */
for (i = ChildCount - 1; i > Index; i--)
{
/* Move them all down */
CellData->u.KeyList[i] = CellData->u.KeyList[i - 1];
}
/* Insert us on top now */
CellData->u.KeyList[Index] = ValueCell;
ChildList->Count = ChildCount;
/* Release the list cell and make sure the value cell is dirty */
HvReleaseCell(Hive, ListCell);
ASSERT(HvIsCellDirty(Hive, ValueCell));
/* We're done here */
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
CmpSetValueDataNew(IN PHHIVE Hive,
IN PVOID Data,
IN ULONG DataSize,
IN ULONG StorageType,
IN HCELL_INDEX ValueCell,
OUT PHCELL_INDEX DataCell)
{
PCELL_DATA CellData;
PAGED_CODE();
ASSERT(DataSize > CM_KEY_VALUE_SMALL);
/* Check if this is a big key */
ASSERT_VALUE_BIG(Hive, DataSize);
/* Allocate a data cell */
*DataCell = HvAllocateCell(Hive, DataSize, StorageType, HCELL_NIL);
if (*DataCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
/* Get the actual data */
CellData = HvGetCell(Hive, *DataCell);
if (!CellData) ASSERT(FALSE);
/* Copy our buffer into it */
RtlCopyMemory(CellData, Data, DataSize);
/* All done */
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
CmpRemoveValueFromList(IN PHHIVE Hive,
IN ULONG Index,
IN OUT PCHILD_LIST ChildList)
{
ULONG Count;
PCELL_DATA CellData;
HCELL_INDEX NewCell;
PAGED_CODE();
/* Sanity check */
ASSERT((((LONG)Index) >= 0) && (Index <= ChildList->Count));
/* Get the new count after removal */
Count = ChildList->Count - 1;
if (Count > 0)
{
/* Get the actual list array */
CellData = HvGetCell(Hive, ChildList->List);
if (!CellData) return STATUS_INSUFFICIENT_RESOURCES;
/* Make sure cells data have been made dirty */
ASSERT(HvIsCellDirty(Hive, ChildList->List));
ASSERT(HvIsCellDirty(Hive, CellData->u.KeyList[Index]));
/* Loop the list */
while (Index < Count)
{
/* Move everything up */
CellData->u.KeyList[Index] = CellData->u.KeyList[Index + 1];
Index++;
}
/* Re-allocate the cell for the list by decreasing the count */
NewCell = HvReallocateCell(Hive,
ChildList->List,
Count * sizeof(HCELL_INDEX));
ASSERT(NewCell != HCELL_NIL);
HvReleaseCell(Hive,ChildList->List);
/* Update the list cell */
ChildList->List = NewCell;
}
else
{
/* Otherwise, we were the last entry, so free the list entirely */
HvFreeCell(Hive, ChildList->List);
ChildList->List = HCELL_NIL;
}
/* Update the child list with the new count */
ChildList->Count = Count;
return STATUS_SUCCESS;
}
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmvalue.c
* PURPOSE: Configuration Manager - Cell Values
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#define NDEBUG
#include "debug.h"
/* FUNCTIONS *****************************************************************/
BOOLEAN
NTAPI
CmpMarkValueDataDirty(IN PHHIVE Hive,
IN PCM_KEY_VALUE Value)
{
ULONG KeySize;
PAGED_CODE();
/* Make sure there's actually any data */
if (Value->Data != HCELL_NIL)
{
/* If this is a small key, there's no need to have it dirty */
if (CmpIsKeyValueSmall(&KeySize, Value->DataLength)) return TRUE;
/* Check if this is a big key */
ASSERT_VALUE_BIG(Hive, KeySize);
/* Normal value, just mark it dirty */
HvMarkCellDirty(Hive, Value->Data, FALSE);
}
/* Operation complete */
return TRUE;
}
BOOLEAN
NTAPI
CmpFreeValueData(IN PHHIVE Hive,
IN HCELL_INDEX DataCell,
IN ULONG DataLength)
{
ULONG KeySize;
PAGED_CODE();
/* If this is a small key, the data is built-in */
if (!CmpIsKeyValueSmall(&KeySize, DataLength))
{
/* If there's no data cell, there's nothing to do */
if (DataCell == HCELL_NIL) return TRUE;
/* Make sure the data cell is allocated */
//ASSERT(HvIsCellAllocated(Hive, DataCell));
/* Unsupported value type */
ASSERT_VALUE_BIG(Hive, KeySize);
/* Normal value, just free the data cell */
HvFreeCell(Hive, DataCell);
}
/* Operation complete */
return TRUE;
}
BOOLEAN
NTAPI
CmpFreeValue(IN PHHIVE Hive,
IN HCELL_INDEX Cell)
{
PCM_KEY_VALUE Value;
PAGED_CODE();
/* Get the cell data */
Value = (PCM_KEY_VALUE)HvGetCell(Hive, Cell);
if (!Value) ASSERT(FALSE);
/* Free it */
if (!CmpFreeValueData(Hive, Value->Data, Value->DataLength))
{
/* We failed to free the data, return failure */
HvReleaseCell(Hive, Cell);
return FALSE;
}
/* Release the cell and free it */
HvReleaseCell(Hive, Cell);
HvFreeCell(Hive, Cell);
return TRUE;
}
HCELL_INDEX
NTAPI
CmpFindValueByName(IN PHHIVE Hive,
IN PCM_KEY_NODE KeyNode,
IN PUNICODE_STRING Name)
{
HCELL_INDEX CellIndex;
/* Call the main function */
if (!CmpFindNameInList(Hive,
&KeyNode->ValueList,
Name,
NULL,
&CellIndex))
{
/* Santy check */
ASSERT(CellIndex == HCELL_NIL);
}
/* Return the index */
return CellIndex;
}
BOOLEAN
NTAPI
CmpGetValueData(IN PHHIVE Hive,
IN PCM_KEY_VALUE Value,
IN PULONG Length,
OUT PVOID *Buffer,
OUT PBOOLEAN BufferAllocated,
OUT PHCELL_INDEX CellToRelease)
{
PAGED_CODE();
/* Sanity check */
ASSERT(Value->Signature == CM_KEY_VALUE_SIGNATURE);
/* Set failure defaults */
*BufferAllocated = FALSE;
*Buffer = NULL;
*CellToRelease = HCELL_NIL;
/* Check if this is a small key */
if (CmpIsKeyValueSmall(Length, Value->DataLength))
{
/* Return the data immediately */
*Buffer = &Value->Data;
return TRUE;
}
/* Unsupported */
ASSERT_VALUE_BIG(Hive, *Length);
/* Get the data from the cell */
*Buffer = HvGetCell(Hive, Value->Data);
if (!(*Buffer)) return FALSE;
/* Return success and the cell to be released */
*CellToRelease = Value->Data;
return TRUE;
}
PCELL_DATA
NTAPI
CmpValueToData(IN PHHIVE Hive,
IN PCM_KEY_VALUE Value,
OUT PULONG Length)
{
PCELL_DATA Buffer;
BOOLEAN BufferAllocated;
HCELL_INDEX CellToRelease;
PAGED_CODE();
/* Sanity check */
ASSERT(Hive->ReleaseCellRoutine == NULL);
/* Get the actual data */
if (!CmpGetValueData(Hive,
Value,
Length,
(PVOID)&Buffer,
&BufferAllocated,
&CellToRelease))
{
/* We failed */
ASSERT(BufferAllocated == FALSE);
ASSERT(Buffer == NULL);
return NULL;
}
/* This should never happen!*/
if (BufferAllocated)
{
/* Free the buffer and bugcheck */
ExFreePool(Buffer);
KEBUGCHECKEX(REGISTRY_ERROR, 8, 0, (ULONG_PTR)Hive, (ULONG_PTR)Value);
}
/* Otherwise, return the cell data */
return Buffer;
}
NTSTATUS
NTAPI
CmpAddValueToList(IN PHHIVE Hive,
IN HCELL_INDEX ValueCell,
IN ULONG Index,
IN ULONG Type,
IN OUT PCHILD_LIST ChildList)
{
HCELL_INDEX ListCell;
ULONG ChildCount, Length, i;
PCELL_DATA CellData;
PAGED_CODE();
/* Sanity check */
ASSERT((((LONG)Index) >= 0) && (Index <= ChildList->Count));
/* Get the number of entries in the child list */
ChildCount = ChildList->Count;
ChildCount++;
if (ChildCount > 1)
{
/* The cell should be dirty at this point */
ASSERT(HvIsCellDirty(Hive, ChildList->List));
/* Check if we have less then 100 children */
if (ChildCount < 100)
{
/* Allocate just enough as requested */
Length = ChildCount * sizeof(HCELL_INDEX);
}
else
{
/* Otherwise, we have quite a few, so allocate a batch */
Length = ROUND_UP(ChildCount, 100) * sizeof(HCELL_INDEX);
if (Length > HBLOCK_SIZE)
{
/* But make sure we don't allocate beyond our block size */
Length = ROUND_UP(Length, HBLOCK_SIZE);
}
}
/* Perform the allocation */
ListCell = HvReallocateCell(Hive, ChildList->List, Length);
}
else
{
/* This is our first child, so allocate a single cell */
ListCell = HvAllocateCell(Hive, sizeof(HCELL_INDEX), Type, HCELL_NIL);
}
/* Fail if we couldn't get a cell */
if (ListCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
/* Set this cell as the child list's list cell */
ChildList->List = ListCell;
/* Get the actual key list memory */
CellData = HvGetCell(Hive, ListCell);
ASSERT(CellData != NULL);
/* Loop all the children */
for (i = ChildCount - 1; i > Index; i--)
{
/* Move them all down */
CellData->u.KeyList[i] = CellData->u.KeyList[i - 1];
}
/* Insert us on top now */
CellData->u.KeyList[Index] = ValueCell;
ChildList->Count = ChildCount;
/* Release the list cell and make sure the value cell is dirty */
HvReleaseCell(Hive, ListCell);
ASSERT(HvIsCellDirty(Hive, ValueCell));
/* We're done here */
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
CmpSetValueDataNew(IN PHHIVE Hive,
IN PVOID Data,
IN ULONG DataSize,
IN ULONG StorageType,
IN HCELL_INDEX ValueCell,
OUT PHCELL_INDEX DataCell)
{
PCELL_DATA CellData;
PAGED_CODE();
ASSERT(DataSize > CM_KEY_VALUE_SMALL);
/* Check if this is a big key */
ASSERT_VALUE_BIG(Hive, DataSize);
/* Allocate a data cell */
*DataCell = HvAllocateCell(Hive, DataSize, StorageType, HCELL_NIL);
if (*DataCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
/* Get the actual data */
CellData = HvGetCell(Hive, *DataCell);
if (!CellData) ASSERT(FALSE);
/* Copy our buffer into it */
RtlCopyMemory(CellData, Data, DataSize);
/* All done */
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
CmpRemoveValueFromList(IN PHHIVE Hive,
IN ULONG Index,
IN OUT PCHILD_LIST ChildList)
{
ULONG Count;
PCELL_DATA CellData;
HCELL_INDEX NewCell;
PAGED_CODE();
/* Sanity check */
ASSERT((((LONG)Index) >= 0) && (Index <= ChildList->Count));
/* Get the new count after removal */
Count = ChildList->Count - 1;
if (Count > 0)
{
/* Get the actual list array */
CellData = HvGetCell(Hive, ChildList->List);
if (!CellData) return STATUS_INSUFFICIENT_RESOURCES;
/* Make sure cells data have been made dirty */
ASSERT(HvIsCellDirty(Hive, ChildList->List));
ASSERT(HvIsCellDirty(Hive, CellData->u.KeyList[Index]));
/* Loop the list */
while (Index < Count)
{
/* Move everything up */
CellData->u.KeyList[Index] = CellData->u.KeyList[Index + 1];
Index++;
}
/* Re-allocate the cell for the list by decreasing the count */
NewCell = HvReallocateCell(Hive,
ChildList->List,
Count * sizeof(HCELL_INDEX));
ASSERT(NewCell != HCELL_NIL);
HvReleaseCell(Hive,ChildList->List);
/* Update the list cell */
ChildList->List = NewCell;
}
else
{
/* Otherwise, we were the last entry, so free the list entirely */
HvFreeCell(Hive, ChildList->List);
ChildList->List = HCELL_NIL;
}
/* Update the child list with the new count */
ChildList->Count = Count;
return STATUS_SUCCESS;
}
+158 -159
View File
@@ -1,159 +1,158 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmwraprs.c
* PURPOSE: Configuration Manager - Wrappers for Hive Operations
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#include "cm.h"
#define NDEBUG
#include "debug.h"
/* FUNCTIONS *****************************************************************/
NTSTATUS
NTAPI
CmpCreateEvent(IN EVENT_TYPE EventType,
OUT PHANDLE EventHandle,
OUT PKEVENT *Event)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
/* Create the event */
InitializeObjectAttributes(&ObjectAttributes,
NULL,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL);
Status = ZwCreateEvent(EventHandle,
EVENT_ALL_ACCESS,
&ObjectAttributes,
EventType,
FALSE);
if (!NT_SUCCESS(Status)) return Status;
/* Get a pointer to the object itself */
Status = ObReferenceObjectByHandle(*EventHandle,
EVENT_ALL_ACCESS,
NULL,
KernelMode,
(PVOID*)Event,
NULL);
if (!NT_SUCCESS(Status)) ZwClose(*EventHandle);
/* Return status */
return Status;
}
PVOID
NTAPI
CmpAllocate(IN ULONG Size,
IN BOOLEAN Paged,
IN ULONG Tag)
{
return ExAllocatePoolWithTag(Paged ? PagedPool : NonPagedPool,
Size,
Tag);
}
VOID
NTAPI
CmpFree(IN PVOID Ptr,
IN ULONG Quota)
{
ExFreePool(Ptr);
}
BOOLEAN
NTAPI
CmpFileRead(IN PHHIVE RegistryHive,
IN ULONG FileType,
IN PULONG FileOffset,
OUT PVOID Buffer,
IN SIZE_T BufferLength)
{
PCMHIVE CmHive = (PCMHIVE)RegistryHive;
HANDLE HiveHandle = CmHive->FileHandles[FileType];
LARGE_INTEGER _FileOffset;
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
_FileOffset.QuadPart = *FileOffset;
Status = ZwReadFile(HiveHandle, 0, 0, 0, &IoStatusBlock,
Buffer, BufferLength, &_FileOffset, 0);
return NT_SUCCESS(Status) ? TRUE : FALSE;
}
BOOLEAN
NTAPI
CmpFileWrite(IN PHHIVE RegistryHive,
IN ULONG FileType,
IN PULONG FileOffset,
IN PVOID Buffer,
IN SIZE_T BufferLength)
{
PCMHIVE CmHive = (PCMHIVE)RegistryHive;
HANDLE HiveHandle = CmHive->FileHandles[FileType];
LARGE_INTEGER _FileOffset;
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
_FileOffset.QuadPart = *FileOffset;
Status = ZwWriteFile(HiveHandle, 0, 0, 0, &IoStatusBlock,
Buffer, BufferLength, &_FileOffset, 0);
return NT_SUCCESS(Status) ? TRUE : FALSE;
}
BOOLEAN
NTAPI
CmpFileSetSize(IN PHHIVE RegistryHive,
IN ULONG FileType,
IN ULONG FileSize,
IN ULONG OldFileSize)
{
PCMHIVE CmHive = (PCMHIVE)RegistryHive;
HANDLE HiveHandle = CmHive->FileHandles[FileType];
FILE_END_OF_FILE_INFORMATION EndOfFileInfo;
FILE_ALLOCATION_INFORMATION FileAllocationInfo;
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
EndOfFileInfo.EndOfFile.QuadPart = FileSize;
Status = ZwSetInformationFile(HiveHandle,
&IoStatusBlock,
&EndOfFileInfo,
sizeof(FILE_END_OF_FILE_INFORMATION),
FileEndOfFileInformation);
if (!NT_SUCCESS(Status)) return FALSE;
FileAllocationInfo.AllocationSize.QuadPart = FileSize;
Status = ZwSetInformationFile(HiveHandle,
&IoStatusBlock,
&FileAllocationInfo,
sizeof(FILE_ALLOCATION_INFORMATION),
FileAllocationInformation);
if (!NT_SUCCESS(Status)) return FALSE;
return TRUE;
}
BOOLEAN
NTAPI
CmpFileFlush(IN PHHIVE RegistryHive,
IN ULONG FileType,
IN OUT PLARGE_INTEGER FileOffset,
IN ULONG Length)
{
PCMHIVE CmHive = (PCMHIVE)RegistryHive;
HANDLE HiveHandle = CmHive->FileHandles[FileType];
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
Status = ZwFlushBuffersFile(HiveHandle, &IoStatusBlock);
return NT_SUCCESS(Status) ? TRUE : FALSE;
}
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmwraprs.c
* PURPOSE: Configuration Manager - Wrappers for Hive Operations
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#define NDEBUG
#include "debug.h"
/* FUNCTIONS *****************************************************************/
NTSTATUS
NTAPI
CmpCreateEvent(IN EVENT_TYPE EventType,
OUT PHANDLE EventHandle,
OUT PKEVENT *Event)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
/* Create the event */
InitializeObjectAttributes(&ObjectAttributes,
NULL,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL);
Status = ZwCreateEvent(EventHandle,
EVENT_ALL_ACCESS,
&ObjectAttributes,
EventType,
FALSE);
if (!NT_SUCCESS(Status)) return Status;
/* Get a pointer to the object itself */
Status = ObReferenceObjectByHandle(*EventHandle,
EVENT_ALL_ACCESS,
NULL,
KernelMode,
(PVOID*)Event,
NULL);
if (!NT_SUCCESS(Status)) ZwClose(*EventHandle);
/* Return status */
return Status;
}
PVOID
NTAPI
CmpAllocate(IN ULONG Size,
IN BOOLEAN Paged,
IN ULONG Tag)
{
return ExAllocatePoolWithTag(Paged ? PagedPool : NonPagedPool,
Size,
Tag);
}
VOID
NTAPI
CmpFree(IN PVOID Ptr,
IN ULONG Quota)
{
ExFreePool(Ptr);
}
BOOLEAN
NTAPI
CmpFileRead(IN PHHIVE RegistryHive,
IN ULONG FileType,
IN PULONG FileOffset,
OUT PVOID Buffer,
IN SIZE_T BufferLength)
{
PCMHIVE CmHive = (PCMHIVE)RegistryHive;
HANDLE HiveHandle = CmHive->FileHandles[FileType];
LARGE_INTEGER _FileOffset;
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
_FileOffset.QuadPart = *FileOffset;
Status = ZwReadFile(HiveHandle, 0, 0, 0, &IoStatusBlock,
Buffer, BufferLength, &_FileOffset, 0);
return NT_SUCCESS(Status) ? TRUE : FALSE;
}
BOOLEAN
NTAPI
CmpFileWrite(IN PHHIVE RegistryHive,
IN ULONG FileType,
IN PULONG FileOffset,
IN PVOID Buffer,
IN SIZE_T BufferLength)
{
PCMHIVE CmHive = (PCMHIVE)RegistryHive;
HANDLE HiveHandle = CmHive->FileHandles[FileType];
LARGE_INTEGER _FileOffset;
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
_FileOffset.QuadPart = *FileOffset;
Status = ZwWriteFile(HiveHandle, 0, 0, 0, &IoStatusBlock,
Buffer, BufferLength, &_FileOffset, 0);
return NT_SUCCESS(Status) ? TRUE : FALSE;
}
BOOLEAN
NTAPI
CmpFileSetSize(IN PHHIVE RegistryHive,
IN ULONG FileType,
IN ULONG FileSize,
IN ULONG OldFileSize)
{
PCMHIVE CmHive = (PCMHIVE)RegistryHive;
HANDLE HiveHandle = CmHive->FileHandles[FileType];
FILE_END_OF_FILE_INFORMATION EndOfFileInfo;
FILE_ALLOCATION_INFORMATION FileAllocationInfo;
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
EndOfFileInfo.EndOfFile.QuadPart = FileSize;
Status = ZwSetInformationFile(HiveHandle,
&IoStatusBlock,
&EndOfFileInfo,
sizeof(FILE_END_OF_FILE_INFORMATION),
FileEndOfFileInformation);
if (!NT_SUCCESS(Status)) return FALSE;
FileAllocationInfo.AllocationSize.QuadPart = FileSize;
Status = ZwSetInformationFile(HiveHandle,
&IoStatusBlock,
&FileAllocationInfo,
sizeof(FILE_ALLOCATION_INFORMATION),
FileAllocationInformation);
if (!NT_SUCCESS(Status)) return FALSE;
return TRUE;
}
BOOLEAN
NTAPI
CmpFileFlush(IN PHHIVE RegistryHive,
IN ULONG FileType,
IN OUT PLARGE_INTEGER FileOffset,
IN ULONG Length)
{
PCMHIVE CmHive = (PCMHIVE)RegistryHive;
HANDLE HiveHandle = CmHive->FileHandles[FileType];
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
Status = ZwFlushBuffersFile(HiveHandle, &IoStatusBlock);
return NT_SUCCESS(Status) ? TRUE : FALSE;
}
File diff suppressed because it is too large Load Diff
+20 -12
View File
@@ -9,7 +9,6 @@
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#include "cm.h"
#define NDEBUG
#include "debug.h"
@@ -18,7 +17,6 @@ BOOLEAN CmFirstTime = TRUE;
/* FUNCTIONS *****************************************************************/
#if 0
NTSTATUS
NTAPI
NtCreateKey(OUT PHANDLE KeyHandle,
@@ -32,7 +30,9 @@ NtCreateKey(OUT PHANDLE KeyHandle,
NTSTATUS Status;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
CM_PARSE_CONTEXT ParseContext = {0};
HANDLE Handle;
PAGED_CODE();
DPRINT("NtCreateKey(OB 0x%wZ)\n", ObjectAttributes->ObjectName);
/* Setup the parse context */
ParseContext.CreateOperation = TRUE;
@@ -46,13 +46,13 @@ NtCreateKey(OUT PHANDLE KeyHandle,
NULL,
DesiredAccess,
&ParseContext,
KeyHandle);
&Handle);
if (NT_SUCCESS(Status)) *KeyHandle = Handle;
/* Return data to user */
if (Disposition) *Disposition = ParseContext.Disposition;
return Status;
}
#endif
NTSTATUS
NTAPI
@@ -61,18 +61,26 @@ NtOpenKey(OUT PHANDLE KeyHandle,
IN POBJECT_ATTRIBUTES ObjectAttributes)
{
CM_PARSE_CONTEXT ParseContext = {0};
HANDLE Handle;
NTSTATUS Status;
PAGED_CODE();
DPRINT("NtOpenKey(OB 0x%wZ)\n", ObjectAttributes->ObjectName);
/* Just let the object manager handle this */
return ObOpenObjectByName(ObjectAttributes,
CmpKeyObjectType,
ExGetPreviousMode(),
NULL,
DesiredAccess,
&ParseContext,
KeyHandle);
Status = ObOpenObjectByName(ObjectAttributes,
CmpKeyObjectType,
ExGetPreviousMode(),
NULL,
DesiredAccess,
&ParseContext,
&Handle);
if (NT_SUCCESS(Status)) *KeyHandle = Handle;
/* Return status */
return Status;
}
NTSTATUS
NTAPI
NtDeleteKey(IN HANDLE KeyHandle)
File diff suppressed because it is too large Load Diff
-1
View File
@@ -12,7 +12,6 @@
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
#include "ntoskrnl/cm/cm.h"
#include "ntstrsafe.h"
typedef struct _INIT_BUFFER
@@ -1,248 +1,248 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/cm/cm_x.h
* PURPOSE: Inlined Functions for the Configuration Manager
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
//
// Returns whether or not this is a small valued key
//
BOOLEAN
FORCEINLINE
CmpIsKeyValueSmall(OUT PULONG RealLength,
IN ULONG Length)
{
/* Check if the length has the special size value */
if (Length >= CM_KEY_VALUE_SPECIAL_SIZE)
{
/* It does, so this is a small key: return the real length */
*RealLength = Length - CM_KEY_VALUE_SPECIAL_SIZE;
return TRUE;
}
/* This is not a small key, return the length we read */
*RealLength = Length;
return FALSE;
}
//
// Returns whether or not this is a big valued key
//
BOOLEAN
FORCEINLINE
CmpIsKeyValueBig(IN PHHIVE Hive,
IN ULONG Length)
{
/* Check if the hive is XP Beta 1 or newer */
if (Hive->Version >= HSYS_WHISTLER_BETA1)
{
/* Check if the key length is valid for a big value key */
if ((Length < CM_KEY_VALUE_SPECIAL_SIZE) && (Length > CM_KEY_VALUE_BIG))
{
/* Yes, this value is big */
return TRUE;
}
}
/* Not a big value key */
return FALSE;
}
//
// Returns the hashkey corresponding to a convkey
//
#define GET_HASH_KEY(ConvKey) \
((CMP_HASH_IRRATIONAL * (ConvKey)) % CMP_HASH_PRIME)
//
// Returns the index into the hash table, or the entry itself
//
#define GET_HASH_INDEX(ConvKey) \
GET_HASH_KEY(ConvKey) % CmpHashTableSize
#define GET_HASH_ENTRY(Table, ConvKey) \
(Table[GET_HASH_INDEX(ConvKey)])
//
// Returns whether or not the cell is cached
//
#define CMP_IS_CELL_CACHED(c) \
(((c) & HCELL_CACHED) && ((c) != HCELL_NIL))
//
// Return data from a cached cell
//
#define CMP_GET_CACHED_CELL(c) \
(ULONG_PTR)((c) & ~HCELL_CACHED)
#define CMP_GET_CACHED_DATA(c) \
(&(((PCM_CACHED_VALUE_INDEX)(CMP_GET_CACHED_CELL(c)))->Data.CellData))
#define CMP_GET_CACHED_INDEX(c) \
(&(((PCM_CACHED_ENTRY)(CMP_GET_CACHED_CELL(c)))->CellIndex))
#define CMP_GET_CACHED_VALUE(c) \
(&(((PCM_CACHED_VALUE)(CMP_GET_CACHED_CELL(c)))->KeyValue))
//
// Makes sure that the registry is locked
//
#define CMP_ASSERT_REGISTRY_LOCK() \
ASSERT((CmpSpecialBootCondition == TRUE) || \
(CmpTestRegistryLock() == TRUE))
//
// Makes sure that the registry is exclusively locked
//
#define CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK() \
ASSERT((CmpSpecialBootCondition == TRUE) || \
(CmpTestRegistryLockExclusive() == TRUE))
//
// Checks if a KCB is exclusively locked
//
#define CmpIsKcbLockedExclusive(k) \
(GET_HASH_ENTRY(CmpCacheTable, \
(k)->ConvKey).Owner == KeGetCurrentThread())
//
// Exclusively acquires a KCB
//
#define CmpAcquireKcbLockExclusive(k) \
{ \
ExAcquirePushLockExclusive(&GET_HASH_ENTRY(CmpCacheTable, \
(k)->ConvKey).Lock); \
GET_HASH_ENTRY(CmpCacheTable, \
(k)->ConvKey).Owner = KeGetCurrentThread(); \
}
//
// Exclusively acquires a KCB by index
//
#define CmpAcquireKcbLockExclusiveByIndex(i) \
{ \
ExAcquirePushLockExclusive(&CmpCacheTable[(i)].Lock); \
CmpCacheTable[(i)].Owner = KeGetCurrentThread(); \
}
//
// Exclusively acquires a KCB by key
//
#define CmpAcquireKcbLockExclusiveByKey(k) \
{ \
ExAcquirePushLockExclusive(&GET_HASH_ENTRY(CmpCacheTable, \
(k)).Lock); \
GET_HASH_ENTRY(CmpCacheTable, \
(k)).Owner = KeGetCurrentThread(); \
}
//
// Shared acquires a KCB
//
#define CmpAcquireKcbLockShared(k) \
{ \
ExAcquirePushLockShared(&GET_HASH_ENTRY(CmpCacheTable, \
(k)->ConvKey).Lock); \
}
//
// Shared acquires a KCB by index
//
#define CmpAcquireKcbLockSharedByIndex(i) \
{ \
ExAcquirePushLockShared(&CmpCacheTable[(i)].Lock); \
}
//
// Tries to convert a KCB lock
//
FORCEINLINE
BOOLEAN
CmpTryToConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
{
ASSERT(CmpIsKcbLockedExclusive(k) == FALSE);
if (ExConvertPushLockSharedToExclusive(
&GET_HASH_ENTRY(CmpCacheTable, k->ConvKey).Lock))
{
GET_HASH_ENTRY(CmpCacheTable,
k->ConvKey).Owner = KeGetCurrentThread();
return TRUE;
}
return FALSE;
}
//
// Releases an exlusively or shared acquired KCB
//
#define CmpReleaseKcbLock(k) \
{ \
GET_HASH_ENTRY(CmpCacheTable, (k)->ConvKey).Owner = NULL; \
ExReleasePushLock(&GET_HASH_ENTRY(CmpCacheTable, \
(k)->ConvKey).Lock); \
}
//
// Releases an exlusively or shared acquired KCB by index
//
#define CmpReleaseKcbLockByIndex(i) \
{ \
CmpCacheTable[(i)].Owner = NULL; \
ExReleasePushLock(&CmpCacheTable[(i)].Lock); \
}
//
// Releases an exlusively or shared acquired KCB by key
//
#define CmpReleaseKcbLockByKey(k) \
{ \
GET_HASH_ENTRY(CmpCacheTable, (k)).Owner = NULL; \
ExReleasePushLock(&GET_HASH_ENTRY(CmpCacheTable, \
(k)).Lock); \
}
//
// Converts a KCB lock
//
FORCEINLINE
VOID
CmpConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
{
ASSERT(CmpIsKcbLockedExclusive(k) == FALSE);
CmpReleaseKcbLock(k);
CmpAcquireKcbLockExclusive(k);
}
//
// Exclusively acquires an NCB
//
#define CmpAcquireNcbLockExclusive(n) \
{ \
ExAcquirePushLockExclusive(&GET_HASH_ENTRY(CmpNameCacheTable, \
(n)->ConvKey).Lock); \
}
//
// Exclusively acquires an NCB by key
//
#define CmpAcquireNcbLockExclusiveByKey(k) \
{ \
ExAcquirePushLockExclusive(&GET_HASH_ENTRY(CmpNameCacheTable, \
(k)).Lock); \
}
//
// Releases an exlusively or shared acquired NCB
//
#define CmpReleaseNcbLock(k) \
{ \
ExReleasePushLock(&GET_HASH_ENTRY(CmpNameCacheTable, \
(k)->ConvKey).Lock); \
}
//
// Releases an exlusively or shared acquired NCB by key
//
#define CmpReleaseNcbLockByKey(k) \
{ \
ExReleasePushLock(&GET_HASH_ENTRY(CmpNameCacheTable, \
(k)).Lock); \
}
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/cm/cm_x.h
* PURPOSE: Inlined Functions for the Configuration Manager
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
//
// Returns whether or not this is a small valued key
//
BOOLEAN
FORCEINLINE
CmpIsKeyValueSmall(OUT PULONG RealLength,
IN ULONG Length)
{
/* Check if the length has the special size value */
if (Length >= CM_KEY_VALUE_SPECIAL_SIZE)
{
/* It does, so this is a small key: return the real length */
*RealLength = Length - CM_KEY_VALUE_SPECIAL_SIZE;
return TRUE;
}
/* This is not a small key, return the length we read */
*RealLength = Length;
return FALSE;
}
//
// Returns whether or not this is a big valued key
//
BOOLEAN
FORCEINLINE
CmpIsKeyValueBig(IN PHHIVE Hive,
IN ULONG Length)
{
/* Check if the hive is XP Beta 1 or newer */
if (Hive->Version >= HSYS_WHISTLER_BETA1)
{
/* Check if the key length is valid for a big value key */
if ((Length < CM_KEY_VALUE_SPECIAL_SIZE) && (Length > CM_KEY_VALUE_BIG))
{
/* Yes, this value is big */
return TRUE;
}
}
/* Not a big value key */
return FALSE;
}
//
// Returns the hashkey corresponding to a convkey
//
#define GET_HASH_KEY(ConvKey) \
((CMP_HASH_IRRATIONAL * (ConvKey)) % CMP_HASH_PRIME)
//
// Returns the index into the hash table, or the entry itself
//
#define GET_HASH_INDEX(ConvKey) \
GET_HASH_KEY(ConvKey) % CmpHashTableSize
#define GET_HASH_ENTRY(Table, ConvKey) \
(Table[GET_HASH_INDEX(ConvKey)])
//
// Returns whether or not the cell is cached
//
#define CMP_IS_CELL_CACHED(c) \
(((c) & HCELL_CACHED) && ((c) != HCELL_NIL))
//
// Return data from a cached cell
//
#define CMP_GET_CACHED_CELL(c) \
(ULONG_PTR)((c) & ~HCELL_CACHED)
#define CMP_GET_CACHED_DATA(c) \
(&(((PCM_CACHED_VALUE_INDEX)(CMP_GET_CACHED_CELL(c)))->Data.CellData))
#define CMP_GET_CACHED_INDEX(c) \
(&(((PCM_CACHED_ENTRY)(CMP_GET_CACHED_CELL(c)))->CellIndex))
#define CMP_GET_CACHED_VALUE(c) \
(&(((PCM_CACHED_VALUE)(CMP_GET_CACHED_CELL(c)))->KeyValue))
//
// Makes sure that the registry is locked
//
#define CMP_ASSERT_REGISTRY_LOCK() \
ASSERT((CmpSpecialBootCondition == TRUE) || \
(CmpTestRegistryLock() == TRUE))
//
// Makes sure that the registry is exclusively locked
//
#define CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK() \
ASSERT((CmpSpecialBootCondition == TRUE) || \
(CmpTestRegistryLockExclusive() == TRUE))
//
// Checks if a KCB is exclusively locked
//
#define CmpIsKcbLockedExclusive(k) \
(GET_HASH_ENTRY(CmpCacheTable, \
(k)->ConvKey).Owner == KeGetCurrentThread())
//
// Exclusively acquires a KCB
//
#define CmpAcquireKcbLockExclusive(k) \
{ \
ExAcquirePushLockExclusive(&GET_HASH_ENTRY(CmpCacheTable, \
(k)->ConvKey).Lock); \
GET_HASH_ENTRY(CmpCacheTable, \
(k)->ConvKey).Owner = KeGetCurrentThread(); \
}
//
// Exclusively acquires a KCB by index
//
#define CmpAcquireKcbLockExclusiveByIndex(i) \
{ \
ExAcquirePushLockExclusive(&CmpCacheTable[(i)].Lock); \
CmpCacheTable[(i)].Owner = KeGetCurrentThread(); \
}
//
// Exclusively acquires a KCB by key
//
#define CmpAcquireKcbLockExclusiveByKey(k) \
{ \
ExAcquirePushLockExclusive(&GET_HASH_ENTRY(CmpCacheTable, \
(k)).Lock); \
GET_HASH_ENTRY(CmpCacheTable, \
(k)).Owner = KeGetCurrentThread(); \
}
//
// Shared acquires a KCB
//
#define CmpAcquireKcbLockShared(k) \
{ \
ExAcquirePushLockShared(&GET_HASH_ENTRY(CmpCacheTable, \
(k)->ConvKey).Lock); \
}
//
// Shared acquires a KCB by index
//
#define CmpAcquireKcbLockSharedByIndex(i) \
{ \
ExAcquirePushLockShared(&CmpCacheTable[(i)].Lock); \
}
//
// Tries to convert a KCB lock
//
FORCEINLINE
BOOLEAN
CmpTryToConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
{
ASSERT(CmpIsKcbLockedExclusive(k) == FALSE);
if (ExConvertPushLockSharedToExclusive(
&GET_HASH_ENTRY(CmpCacheTable, k->ConvKey).Lock))
{
GET_HASH_ENTRY(CmpCacheTable,
k->ConvKey).Owner = KeGetCurrentThread();
return TRUE;
}
return FALSE;
}
//
// Releases an exlusively or shared acquired KCB
//
#define CmpReleaseKcbLock(k) \
{ \
GET_HASH_ENTRY(CmpCacheTable, (k)->ConvKey).Owner = NULL; \
ExReleasePushLock(&GET_HASH_ENTRY(CmpCacheTable, \
(k)->ConvKey).Lock); \
}
//
// Releases an exlusively or shared acquired KCB by index
//
#define CmpReleaseKcbLockByIndex(i) \
{ \
CmpCacheTable[(i)].Owner = NULL; \
ExReleasePushLock(&CmpCacheTable[(i)].Lock); \
}
//
// Releases an exlusively or shared acquired KCB by key
//
#define CmpReleaseKcbLockByKey(k) \
{ \
GET_HASH_ENTRY(CmpCacheTable, (k)).Owner = NULL; \
ExReleasePushLock(&GET_HASH_ENTRY(CmpCacheTable, \
(k)).Lock); \
}
//
// Converts a KCB lock
//
FORCEINLINE
VOID
CmpConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
{
ASSERT(CmpIsKcbLockedExclusive(k) == FALSE);
CmpReleaseKcbLock(k);
CmpAcquireKcbLockExclusive(k);
}
//
// Exclusively acquires an NCB
//
#define CmpAcquireNcbLockExclusive(n) \
{ \
ExAcquirePushLockExclusive(&GET_HASH_ENTRY(CmpNameCacheTable, \
(n)->ConvKey).Lock); \
}
//
// Exclusively acquires an NCB by key
//
#define CmpAcquireNcbLockExclusiveByKey(k) \
{ \
ExAcquirePushLockExclusive(&GET_HASH_ENTRY(CmpNameCacheTable, \
(k)).Lock); \
}
//
// Releases an exlusively or shared acquired NCB
//
#define CmpReleaseNcbLock(k) \
{ \
ExReleasePushLock(&GET_HASH_ENTRY(CmpNameCacheTable, \
(k)->ConvKey).Lock); \
}
//
// Releases an exlusively or shared acquired NCB by key
//
#define CmpReleaseNcbLockByKey(k) \
{ \
ExReleasePushLock(&GET_HASH_ENTRY(CmpNameCacheTable, \
(k)).Lock); \
}
@@ -30,6 +30,7 @@
#include "ob.h"
#include "mm.h"
#include "ex.h"
#include "cm.h"
#include "ps.h"
#include "cc.h"
#include "io.h"
-6
View File
@@ -142,12 +142,6 @@
<file>cmwraprs.c</file>
<file>ntapi.c</file>
</directory>
<directory name="cm">
<file>ntfunc.c</file>
<file>regfile.c</file>
<file>registry.c</file>
<file>regobj.c</file>
</directory>
<directory name="dbgk">
<file>dbgkutil.c</file>
<file>dbgkobj.c</file>
-3
View File
@@ -138,9 +138,6 @@
<file>cmwraprs.c</file>
<file>ntapi.c</file>
</directory>
<directory name="cm">
<file>regobj.c</file>
</directory>
<directory name="dbgk">
<file>dbgkutil.c</file>
<file>dbgkobj.c</file>