- 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

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

View file

@ -11,7 +11,6 @@
#include <ntoskrnl.h> #include <ntoskrnl.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#include "cm.h"
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/

View file

@ -9,7 +9,6 @@
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
#include "ntoskrnl.h" #include "ntoskrnl.h"
#include "cm.h"
#define NDEBUG #define NDEBUG
#include "debug.h" #include "debug.h"

View file

@ -1,127 +1,126 @@
/* /*
* PROJECT: ReactOS Kernel * PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmboot.c * FILE: ntoskrnl/config/cmboot.c
* PURPOSE: Configuration Manager - Boot Initialization * PURPOSE: Configuration Manager - Boot Initialization
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
#include "ntoskrnl.h" #include "ntoskrnl.h"
#include "cm.h" #define NDEBUG
#define NDEBUG #include "debug.h"
#include "debug.h"
/* GLOBALS *******************************************************************/
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
/* FUNCTIONS *****************************************************************/
HCELL_INDEX
HCELL_INDEX NTAPI
NTAPI CmpFindControlSet(IN PHHIVE SystemHive,
CmpFindControlSet(IN PHHIVE SystemHive, IN HCELL_INDEX RootCell,
IN HCELL_INDEX RootCell, IN PUNICODE_STRING SelectKeyName,
IN PUNICODE_STRING SelectKeyName, OUT PBOOLEAN AutoSelect)
OUT PBOOLEAN AutoSelect) {
{ UNICODE_STRING KeyName;
UNICODE_STRING KeyName; PCM_KEY_NODE Node;
PCM_KEY_NODE Node; HCELL_INDEX SelectCell, AutoSelectCell, SelectValueCell, ControlSetCell;
HCELL_INDEX SelectCell, AutoSelectCell, SelectValueCell, ControlSetCell; HCELL_INDEX CurrentValueCell;
HCELL_INDEX CurrentValueCell; PCM_KEY_VALUE KeyValue;
PCM_KEY_VALUE KeyValue; ULONG Length;
ULONG Length; PULONG ControlSetId;
PULONG ControlSetId; ANSI_STRING ControlSetAnsiName;
ANSI_STRING ControlSetAnsiName; CHAR Buffer[128];
CHAR Buffer[128]; WCHAR WideBuffer[128];
WCHAR WideBuffer[128]; NTSTATUS Status;
NTSTATUS Status; PULONG CurrentData;
PULONG CurrentData;
/* Sanity check */
/* Sanity check */ ASSERT(SystemHive->ReleaseCellRoutine == NULL);
ASSERT(SystemHive->ReleaseCellRoutine == NULL);
/* Get the Select subkey */
/* Get the Select subkey */ RtlInitUnicodeString(&KeyName, L"select");
RtlInitUnicodeString(&KeyName, L"select"); Node = (PCM_KEY_NODE)HvGetCell(SystemHive, RootCell);
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, RootCell); if (!Node) return HCELL_NIL;
if (!Node) return HCELL_NIL; SelectCell = CmpFindSubKeyByName(SystemHive, Node, &KeyName);
SelectCell = CmpFindSubKeyByName(SystemHive, Node, &KeyName); if (SelectCell == HCELL_NIL) return SelectCell;
if (SelectCell == HCELL_NIL) return SelectCell;
/* Get AutoSelect value */
/* Get AutoSelect value */ RtlInitUnicodeString(&KeyName, L"AutoSelect");
RtlInitUnicodeString(&KeyName, L"AutoSelect"); Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell); if (!Node) return HCELL_NIL;
if (!Node) return HCELL_NIL; AutoSelectCell = CmpFindValueByName(SystemHive, Node, &KeyName);
AutoSelectCell = CmpFindValueByName(SystemHive, Node, &KeyName); if (AutoSelectCell == HCELL_NIL)
if (AutoSelectCell == HCELL_NIL) {
{ /* Assume TRUE if the value is missing. */
/* Assume TRUE if the value is missing. */ *AutoSelect = TRUE;
*AutoSelect = TRUE; }
} else
else {
{ /* Read the value */
/* Read the value */ KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, AutoSelectCell);
KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, AutoSelectCell); if (KeyValue == NULL) return HCELL_NIL;
if (KeyValue == NULL) return HCELL_NIL;
/* Convert it to a boolean */
/* Convert it to a boolean */ *AutoSelect = *(PBOOLEAN)CmpValueToData(SystemHive, KeyValue, &Length);
*AutoSelect = *(PBOOLEAN)CmpValueToData(SystemHive, KeyValue, &Length); }
}
/* Now find the control set being looked up */
/* Now find the control set being looked up */ Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell); if (!Node) return HCELL_NIL;
if (!Node) return HCELL_NIL; SelectValueCell = CmpFindValueByName(SystemHive, Node, SelectKeyName);
SelectValueCell = CmpFindValueByName(SystemHive, Node, SelectKeyName); if (SelectValueCell == HCELL_NIL) return SelectValueCell;
if (SelectValueCell == HCELL_NIL) return SelectValueCell;
/* Read the value (corresponding to the CCS ID) */
/* Read the value (corresponding to the CCS ID) */ KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, SelectValueCell);
KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, SelectValueCell); if (!KeyValue) return HCELL_NIL;
if (!KeyValue) return HCELL_NIL; if (KeyValue->Type != REG_DWORD) return HCELL_NIL;
if (KeyValue->Type != REG_DWORD) return HCELL_NIL; ControlSetId = (PULONG)CmpValueToData(SystemHive, KeyValue, &Length);
ControlSetId = (PULONG)CmpValueToData(SystemHive, KeyValue, &Length);
/* Now build an Ansi String for the CCS's Name */
/* Now build an Ansi String for the CCS's Name */ sprintf(Buffer, "ControlSet%03lu", *ControlSetId);
sprintf(Buffer, "ControlSet%03lu", *ControlSetId); ControlSetAnsiName.Length = (USHORT)strlen(Buffer);
ControlSetAnsiName.Length = (USHORT)strlen(Buffer); ControlSetAnsiName.MaximumLength = (USHORT)strlen(Buffer);
ControlSetAnsiName.MaximumLength = (USHORT)strlen(Buffer); ControlSetAnsiName.Buffer = Buffer;
ControlSetAnsiName.Buffer = Buffer;
/* And convert it to Unicode... */
/* And convert it to Unicode... */ KeyName.MaximumLength = 256;
KeyName.MaximumLength = 256; KeyName.Buffer = WideBuffer;
KeyName.Buffer = WideBuffer; Status = RtlAnsiStringToUnicodeString(&KeyName,
Status = RtlAnsiStringToUnicodeString(&KeyName, &ControlSetAnsiName,
&ControlSetAnsiName, FALSE);
FALSE); if (!NT_SUCCESS(Status)) return HCELL_NIL;
if (!NT_SUCCESS(Status)) return HCELL_NIL;
/* Now open it */
/* Now open it */ Node = (PCM_KEY_NODE)HvGetCell(SystemHive, RootCell);
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, RootCell); if (!Node) return HCELL_NIL;
if (!Node) return HCELL_NIL; ControlSetCell = CmpFindSubKeyByName(SystemHive, Node, &KeyName);
ControlSetCell = CmpFindSubKeyByName(SystemHive, Node, &KeyName); if (ControlSetCell == HCELL_NIL) return ControlSetCell;
if (ControlSetCell == HCELL_NIL) return ControlSetCell;
/* Get the value of the "Current" CCS */
/* Get the value of the "Current" CCS */ RtlInitUnicodeString(&KeyName, L"Current");
RtlInitUnicodeString(&KeyName, L"Current"); Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell); if (!Node) return HCELL_NIL;
if (!Node) return HCELL_NIL; CurrentValueCell = CmpFindValueByName(SystemHive, Node, &KeyName);
CurrentValueCell = CmpFindValueByName(SystemHive, Node, &KeyName);
/* Make sure it exists */
/* Make sure it exists */ if (CurrentValueCell != HCELL_NIL)
if (CurrentValueCell != HCELL_NIL) {
{ /* Get the current value and make sure its a ULONG */
/* Get the current value and make sure its a ULONG */ KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, CurrentValueCell);
KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, CurrentValueCell); if (!KeyValue) return HCELL_NIL;
if (!KeyValue) return HCELL_NIL; if (KeyValue->Type == REG_DWORD)
if (KeyValue->Type == REG_DWORD) {
{ /* Get the data and update it */
/* Get the data and update it */ CurrentData = (PULONG)CmpValueToData(SystemHive,
CurrentData = (PULONG)CmpValueToData(SystemHive, KeyValue,
KeyValue, &Length);
&Length); if (!CurrentData) return HCELL_NIL;
if (!CurrentData) return HCELL_NIL; *CurrentData = *ControlSetId;
*CurrentData = *ControlSetId; }
} }
}
/* Return the CCS Cell */
/* Return the CCS Cell */ return ControlSetCell;
return ControlSetCell; }
}

View file

@ -1,27 +1,26 @@
/* /*
* PROJECT: ReactOS Kernel * PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmcheck.c * FILE: ntoskrnl/config/cmcheck.c
* PURPOSE: Configuration Manager - Hive and Key Validation * PURPOSE: Configuration Manager - Hive and Key Validation
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
#include "ntoskrnl.h" #include "ntoskrnl.h"
#include "cm.h" #define NDEBUG
#define NDEBUG #include "debug.h"
#include "debug.h"
/* GLOBALS *******************************************************************/
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
/* FUNCTIONS *****************************************************************/
ULONG
ULONG NTAPI
NTAPI CmCheckRegistry(IN PCMHIVE RegistryHive,
CmCheckRegistry(IN PCMHIVE RegistryHive, IN ULONG Flags)
IN ULONG Flags) {
{ /* FIXME: HACK! */
/* FIXME: HACK! */ return 0;
return 0; }
}

View file

@ -1,399 +1,398 @@
/* /*
* PROJECT: ReactOS Kernel * PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmconfig.c * FILE: ntoskrnl/config/cmconfig.c
* PURPOSE: Configuration Manager - System Configuration Routines * PURPOSE: Configuration Manager - System Configuration Routines
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
#include "ntoskrnl.h" #include "ntoskrnl.h"
#include "cm.h" #define NDEBUG
#define NDEBUG #include "debug.h"
#include "debug.h"
/* FUNCTIONS *****************************************************************/
/* FUNCTIONS *****************************************************************/
NTSTATUS
NTSTATUS NTAPI
NTAPI CmpInitializeRegistryNode(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
CmpInitializeRegistryNode(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry, IN HANDLE NodeHandle,
IN HANDLE NodeHandle, OUT PHANDLE NewHandle,
OUT PHANDLE NewHandle, IN INTERFACE_TYPE InterfaceType,
IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber,
IN ULONG BusNumber, IN PUSHORT DeviceIndexTable)
IN PUSHORT DeviceIndexTable) {
{ NTSTATUS Status;
NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes;
OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName, ValueName, ValueData;
UNICODE_STRING KeyName, ValueName, ValueData; HANDLE KeyHandle, ParentHandle;
HANDLE KeyHandle, ParentHandle; ANSI_STRING TempString;
ANSI_STRING TempString; CHAR TempBuffer[12];
CHAR TempBuffer[12]; WCHAR Buffer[12];
WCHAR Buffer[12]; PCONFIGURATION_COMPONENT Component;
PCONFIGURATION_COMPONENT Component; ULONG Disposition, Length = 0;
ULONG Disposition, Length = 0;
/* Get the component */
/* Get the component */ Component = &CurrentEntry->ComponentEntry;
Component = &CurrentEntry->ComponentEntry;
/* Set system class components to ARC system type */
/* Set system class components to ARC system type */ if (Component->Class == SystemClass) Component->Type = ArcSystem;
if (Component->Class == SystemClass) Component->Type = ArcSystem;
/* Create a key for the component */
/* Create a key for the component */ InitializeObjectAttributes(&ObjectAttributes,
InitializeObjectAttributes(&ObjectAttributes, &CmTypeName[Component->Type],
&CmTypeName[Component->Type], OBJ_CASE_INSENSITIVE,
OBJ_CASE_INSENSITIVE, NodeHandle,
NodeHandle, NULL);
NULL); Status = NtCreateKey(&KeyHandle,
Status = NtCreateKey(&KeyHandle, KEY_READ | KEY_WRITE,
KEY_READ | KEY_WRITE, &ObjectAttributes,
&ObjectAttributes, 0,
0, NULL,
NULL, 0,
0, &Disposition);
&Disposition); if (!NT_SUCCESS(Status)) return Status;
if (!NT_SUCCESS(Status)) return Status;
/* Check if this is anything but a system class component */
/* Check if this is anything but a system class component */ if (Component->Class != SystemClass)
if (Component->Class != SystemClass) {
{ /* Build the sub-component string */
/* Build the sub-component string */ RtlIntegerToChar(DeviceIndexTable[Component->Type]++,
RtlIntegerToChar(DeviceIndexTable[Component->Type]++, 10,
10, 12,
12, TempBuffer);
TempBuffer); RtlInitAnsiString(&TempString, TempBuffer);
RtlInitAnsiString(&TempString, TempBuffer);
/* Convert it to Unicode */
/* Convert it to Unicode */ RtlInitEmptyUnicodeString(&KeyName, Buffer, sizeof(Buffer));
RtlInitEmptyUnicodeString(&KeyName, Buffer, sizeof(Buffer)); RtlAnsiStringToUnicodeString(&KeyName, &TempString, FALSE);
RtlAnsiStringToUnicodeString(&KeyName, &TempString, FALSE);
/* Create the key */
/* Create the key */ ParentHandle = KeyHandle;
ParentHandle = KeyHandle; InitializeObjectAttributes(&ObjectAttributes,
InitializeObjectAttributes(&ObjectAttributes, &KeyName,
&KeyName, OBJ_CASE_INSENSITIVE,
OBJ_CASE_INSENSITIVE, ParentHandle,
ParentHandle, NULL);
NULL); Status = NtCreateKey(&KeyHandle,
Status = NtCreateKey(&KeyHandle, KEY_READ | KEY_WRITE,
KEY_READ | KEY_WRITE, &ObjectAttributes,
&ObjectAttributes, 0,
0, NULL,
NULL, 0,
0, &Disposition);
&Disposition); NtClose(ParentHandle);
NtClose(ParentHandle);
/* Fail if the key couldn't be created, and make sure it's a new key */
/* Fail if the key couldn't be created, and make sure it's a new key */ if (!NT_SUCCESS(Status)) return Status;
if (!NT_SUCCESS(Status)) return Status; ASSERT(Disposition == REG_CREATED_NEW_KEY);
ASSERT(Disposition == REG_CREATED_NEW_KEY); }
}
/* Setup the component information key */
/* Setup the component information key */ RtlInitUnicodeString(&ValueName, L"Component Information");
RtlInitUnicodeString(&ValueName, L"Component Information"); Status = NtSetValueKey(KeyHandle,
Status = NtSetValueKey(KeyHandle, &ValueName,
&ValueName, 0,
0, REG_BINARY,
REG_BINARY, &Component->Flags,
&Component->Flags, FIELD_OFFSET(CONFIGURATION_COMPONENT,
FIELD_OFFSET(CONFIGURATION_COMPONENT, ConfigurationDataLength) -
ConfigurationDataLength) - FIELD_OFFSET(CONFIGURATION_COMPONENT, Flags));
FIELD_OFFSET(CONFIGURATION_COMPONENT, Flags)); if (!NT_SUCCESS(Status))
if (!NT_SUCCESS(Status)) {
{ /* Fail */
/* Fail */ NtClose(KeyHandle);
NtClose(KeyHandle); return Status;
return Status; }
}
/* Check if we have an identifier */
/* Check if we have an identifier */ if (Component->IdentifierLength)
if (Component->IdentifierLength) {
{ /* Build the string and convert it to Unicode */
/* Build the string and convert it to Unicode */ RtlInitUnicodeString(&ValueName, L"Identifier");
RtlInitUnicodeString(&ValueName, L"Identifier"); RtlInitAnsiString(&TempString, Component->Identifier);
RtlInitAnsiString(&TempString, Component->Identifier); Status = RtlAnsiStringToUnicodeString(&ValueData,
Status = RtlAnsiStringToUnicodeString(&ValueData, &TempString,
&TempString, TRUE);
TRUE); RtlCreateUnicodeString(&ValueData, (PWCHAR)Component->Identifier);
RtlCreateUnicodeString(&ValueData, (PWCHAR)Component->Identifier); if (NT_SUCCESS(Status))
if (NT_SUCCESS(Status)) {
{ /* Save the identifier in the registry */
/* Save the identifier in the registry */ Status = NtSetValueKey(KeyHandle,
Status = NtSetValueKey(KeyHandle, &ValueName,
&ValueName, 0,
0, REG_SZ,
REG_SZ, ValueData.Buffer,
ValueData.Buffer, ValueData.Length + sizeof(UNICODE_NULL));
ValueData.Length + sizeof(UNICODE_NULL)); RtlFreeUnicodeString(&ValueData);
RtlFreeUnicodeString(&ValueData); }
}
/* Check for failure during conversion or registry write */
/* Check for failure during conversion or registry write */ if (!NT_SUCCESS(Status))
if (!NT_SUCCESS(Status)) {
{ /* Fail */
/* Fail */ NtClose(KeyHandle);
NtClose(KeyHandle); return Status;
return Status; }
} }
}
/* Setup the configuration data string */
/* Setup the configuration data string */ RtlInitUnicodeString(&ValueName, L"Configuration Data");
RtlInitUnicodeString(&ValueName, L"Configuration Data");
/* Check if we got configuration data */
/* Check if we got configuration data */ if (CurrentEntry->ConfigurationData)
if (CurrentEntry->ConfigurationData) {
{ /* Calculate the total length and check if it fits into our buffer */
/* Calculate the total length and check if it fits into our buffer */ Length = Component->ConfigurationDataLength +
Length = Component->ConfigurationDataLength + FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList);
FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList); if (Length > CmpConfigurationAreaSize)
if (Length > CmpConfigurationAreaSize) {
{ ASSERTMSG("Component too large -- need reallocation!", FALSE);
ASSERTMSG("Component too large -- need reallocation!", FALSE); }
} else
else {
{ /* Copy the data */
/* Copy the data */ RtlCopyMemory(&CmpConfigurationData->PartialResourceList.Version,
RtlCopyMemory(&CmpConfigurationData->PartialResourceList.Version, CurrentEntry->ConfigurationData,
CurrentEntry->ConfigurationData, Component->ConfigurationDataLength);
Component->ConfigurationDataLength); }
} }
} else
else {
{ /* No configuration data, setup defaults */
/* No configuration data, setup defaults */ CmpConfigurationData->PartialResourceList.Version = 0;
CmpConfigurationData->PartialResourceList.Version = 0; CmpConfigurationData->PartialResourceList.Revision = 0;
CmpConfigurationData->PartialResourceList.Revision = 0; CmpConfigurationData->PartialResourceList.Count = 0;
CmpConfigurationData->PartialResourceList.Count = 0; Length = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors) +
Length = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors) + FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList);
FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList); }
}
/* Set the interface type and bus number */
/* Set the interface type and bus number */ CmpConfigurationData->InterfaceType = InterfaceType;
CmpConfigurationData->InterfaceType = InterfaceType; CmpConfigurationData->BusNumber = BusNumber;
CmpConfigurationData->BusNumber = BusNumber;
/* Save the actual data */
/* Save the actual data */ Status = NtSetValueKey(KeyHandle,
Status = NtSetValueKey(KeyHandle, &ValueName,
&ValueName, 0,
0, REG_FULL_RESOURCE_DESCRIPTOR,
REG_FULL_RESOURCE_DESCRIPTOR, CmpConfigurationData,
CmpConfigurationData, Length);
Length); if (!NT_SUCCESS(Status))
if (!NT_SUCCESS(Status)) {
{ /* Fail */
/* Fail */ NtClose(KeyHandle);
NtClose(KeyHandle); }
} else
else {
{ /* Return the new handle */
/* Return the new handle */ *NewHandle = KeyHandle;
*NewHandle = KeyHandle; }
}
/* Return status */
/* Return status */ return Status;
return Status; }
}
NTSTATUS
NTSTATUS NTAPI
NTAPI CmpSetupConfigurationTree(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
CmpSetupConfigurationTree(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry, IN HANDLE ParentHandle,
IN HANDLE ParentHandle, IN INTERFACE_TYPE InterfaceType,
IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber)
IN ULONG BusNumber) {
{ PCONFIGURATION_COMPONENT Component;
PCONFIGURATION_COMPONENT Component; USHORT DeviceIndexTable[MaximumType + 1] = {0};
USHORT DeviceIndexTable[MaximumType + 1] = {0}; ULONG Interface = InterfaceType, Bus = BusNumber, i;
ULONG Interface = InterfaceType, Bus = BusNumber, i; NTSTATUS Status;
NTSTATUS Status; HANDLE NewHandle;
HANDLE NewHandle;
/* Loop each entry */
/* Loop each entry */ while (CurrentEntry)
while (CurrentEntry) {
{ /* Check if this is an adapter */
/* Check if this is an adapter */ Component = &CurrentEntry->ComponentEntry;
Component = &CurrentEntry->ComponentEntry; if ((Component->Class == AdapterClass) &&
if ((Component->Class == AdapterClass) && (CurrentEntry->Parent->ComponentEntry.Class == SystemClass))
(CurrentEntry->Parent->ComponentEntry.Class == SystemClass)) {
{ /* Check what kind of adapter it is */
/* Check what kind of adapter it is */ switch (Component->Type)
switch (Component->Type) {
{ /* EISA */
/* EISA */ case EisaAdapter:
case EisaAdapter:
/* Fixup information */
/* Fixup information */ Interface = Eisa;
Interface = Eisa; Bus = CmpTypeCount[EisaAdapter]++;
Bus = CmpTypeCount[EisaAdapter]++; break;
break;
/* Turbo-channel */
/* Turbo-channel */ case TcAdapter:
case TcAdapter:
/* Fixup information */
/* Fixup information */ Interface = TurboChannel;
Interface = TurboChannel; Bus = CmpTypeCount[TurboChannel]++;
Bus = CmpTypeCount[TurboChannel]++; break;
break;
/* ISA, PCI, etc busses */
/* ISA, PCI, etc busses */ case MultiFunctionAdapter:
case MultiFunctionAdapter:
/* Check if we have an identifier */
/* Check if we have an identifier */ if (Component->Identifier)
if (Component->Identifier) {
{ /* Loop each multi-function adapter type */
/* Loop each multi-function adapter type */ for (i = 0; CmpMultifunctionTypes[i].Identifier; i++)
for (i = 0; CmpMultifunctionTypes[i].Identifier; i++) {
{ /* Check for a name match */
/* Check for a name match */ if (!_wcsicmp(CmpMultifunctionTypes[i].Identifier,
if (!_wcsicmp(CmpMultifunctionTypes[i].Identifier, (PWCHAR)Component->Identifier))
(PWCHAR)Component->Identifier)) {
{ /* Match found */
/* Match found */ break;
break; }
} }
}
/* Fix up information */
/* Fix up information */ Interface = CmpMultifunctionTypes[i].InterfaceType;
Interface = CmpMultifunctionTypes[i].InterfaceType; Bus = CmpMultifunctionTypes[i].Count++;
Bus = CmpMultifunctionTypes[i].Count++; }
} break;
break;
/* SCSI Bus */
/* SCSI Bus */ case ScsiAdapter:
case ScsiAdapter:
/* Fix up */
/* Fix up */ Interface = Internal;
Interface = Internal; Bus = CmpTypeCount[ScsiAdapter]++;
Bus = CmpTypeCount[ScsiAdapter]++; break;
break;
/* Unknown */
/* Unknown */ default:
default: Interface = -1;
Interface = -1; Bus = CmpUnknownBusCount++;
Bus = CmpUnknownBusCount++; break;
break; }
} }
}
/* Dump information on the component */
/* Dump information on the component */
/* Setup the hardware node */
/* Setup the hardware node */ Status = CmpInitializeRegistryNode(CurrentEntry,
Status = CmpInitializeRegistryNode(CurrentEntry, ParentHandle,
ParentHandle, &NewHandle,
&NewHandle, Interface,
Interface, Bus,
Bus, DeviceIndexTable);
DeviceIndexTable); if (!NT_SUCCESS(Status)) return Status;
if (!NT_SUCCESS(Status)) return Status;
/* Check for children */
/* Check for children */ if (CurrentEntry->Child)
if (CurrentEntry->Child) {
{ /* Recurse child */
/* Recurse child */ Status = CmpSetupConfigurationTree(CurrentEntry->Child,
Status = CmpSetupConfigurationTree(CurrentEntry->Child, NewHandle,
NewHandle, Interface,
Interface, Bus);
Bus); if (!NT_SUCCESS(Status))
if (!NT_SUCCESS(Status)) {
{ /* Fail */
/* Fail */ NtClose(NewHandle);
NtClose(NewHandle); return Status;
return Status; }
} }
}
/* Get to the next entry */
/* Get to the next entry */ NtClose(NewHandle);
NtClose(NewHandle); CurrentEntry = CurrentEntry->Sibling;
CurrentEntry = CurrentEntry->Sibling; }
}
/* We're done */
/* We're done */ return STATUS_SUCCESS;
return STATUS_SUCCESS; }
}
NTSTATUS
NTSTATUS NTAPI
NTAPI CmpInitializeHardwareConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
CmpInitializeHardwareConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock) {
{ NTSTATUS Status;
NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes;
OBJECT_ATTRIBUTES ObjectAttributes; HANDLE KeyHandle;
HANDLE KeyHandle; ULONG Disposition;
ULONG Disposition; UNICODE_STRING KeyName;
UNICODE_STRING KeyName;
/* Setup the key name */
/* Setup the key name */ RtlInitUnicodeString(&KeyName,
RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\Hardware\\DeviceMap");
L"\\Registry\\Machine\\Hardware\\DeviceMap"); InitializeObjectAttributes(&ObjectAttributes,
InitializeObjectAttributes(&ObjectAttributes, &KeyName,
&KeyName, OBJ_CASE_INSENSITIVE,
OBJ_CASE_INSENSITIVE, NULL,
NULL, NULL);
NULL);
/* Create the device map key */
/* Create the device map key */ Status = NtCreateKey(&KeyHandle,
Status = NtCreateKey(&KeyHandle, KEY_READ | KEY_WRITE,
KEY_READ | KEY_WRITE, &ObjectAttributes,
&ObjectAttributes, 0,
0, NULL,
NULL, 0,
0, &Disposition);
&Disposition); if (!NT_SUCCESS(Status)) return Status;
if (!NT_SUCCESS(Status)) return Status; NtClose(KeyHandle);
NtClose(KeyHandle);
/* Nobody should've created this key yet! */
/* Nobody should've created this key yet! */ ASSERT(Disposition == REG_CREATED_NEW_KEY);
ASSERT(Disposition == REG_CREATED_NEW_KEY);
/* Setup the key name */
/* Setup the key name */ RtlInitUnicodeString(&KeyName,
RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\Hardware\\Description");
L"\\Registry\\Machine\\Hardware\\Description"); InitializeObjectAttributes(&ObjectAttributes,
InitializeObjectAttributes(&ObjectAttributes, &KeyName,
&KeyName, OBJ_CASE_INSENSITIVE,
OBJ_CASE_INSENSITIVE, NULL,
NULL, NULL);
NULL);
/* Create the description key */
/* Create the description key */ Status = NtCreateKey(&KeyHandle,
Status = NtCreateKey(&KeyHandle, KEY_READ | KEY_WRITE,
KEY_READ | KEY_WRITE, &ObjectAttributes,
&ObjectAttributes, 0,
0, NULL,
NULL, 0,
0, &Disposition);
&Disposition); if (!NT_SUCCESS(Status)) return Status;
if (!NT_SUCCESS(Status)) return Status;
/* Nobody should've created this key yet! */
/* Nobody should've created this key yet! */ ASSERT(Disposition == REG_CREATED_NEW_KEY);
ASSERT(Disposition == REG_CREATED_NEW_KEY);
/* Allocate the configuration data buffer */
/* Allocate the configuration data buffer */ CmpConfigurationData = ExAllocatePoolWithTag(PagedPool,
CmpConfigurationData = ExAllocatePoolWithTag(PagedPool, CmpConfigurationAreaSize,
CmpConfigurationAreaSize, TAG_CM);
TAG_CM); if (!CmpConfigurationData) return STATUS_INSUFFICIENT_RESOURCES;
if (!CmpConfigurationData) return STATUS_INSUFFICIENT_RESOURCES;
/* Check if we got anything from NTLDR */
/* Check if we got anything from NTLDR */ if (LoaderBlock->ConfigurationRoot)
if (LoaderBlock->ConfigurationRoot) {
{ /* Setup the configuration tree */
/* Setup the configuration tree */ Status = CmpSetupConfigurationTree(LoaderBlock->ConfigurationRoot,
Status = CmpSetupConfigurationTree(LoaderBlock->ConfigurationRoot, KeyHandle,
KeyHandle, -1,
-1, -1);
-1); }
} else
else {
{ /* Nothing else to do */
/* Nothing else to do */ Status = STATUS_SUCCESS;
Status = STATUS_SUCCESS; }
}
/* Close our handle, free the buffer and return status */
/* Close our handle, free the buffer and return status */ ExFreePool(CmpConfigurationData);
ExFreePool(CmpConfigurationData); NtClose(KeyHandle);
NtClose(KeyHandle); return Status;
return Status; }
}

View file

@ -1,265 +1,264 @@
/* /*
* PROJECT: ReactOS Kernel * PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmcontrl.c * FILE: ntoskrnl/config/cmcontrl.c
* PURPOSE: Configuration Manager - Control Set Management * PURPOSE: Configuration Manager - Control Set Management
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
#include "ntoskrnl.h" #include "ntoskrnl.h"
#include "cm.h" #define NDEBUG
#define NDEBUG #include "debug.h"
#include "debug.h"
/* GLOBALS *******************************************************************/
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
/* FUNCTIONS *****************************************************************/
LANGID
LANGID NTAPI
NTAPI CmpConvertLangId(IN LPWSTR Name,
CmpConvertLangId(IN LPWSTR Name, IN ULONG NameLength)
IN ULONG NameLength) {
{ ULONG i;
ULONG i; WCHAR p;
WCHAR p; LANGID LangId = 0;
LANGID LangId = 0; ULONG IdCode;
ULONG IdCode;
/* Convert the length in chars and loop */
/* Convert the length in chars and loop */ NameLength = NameLength / sizeof(WCHAR);
NameLength = NameLength / sizeof(WCHAR); for (i = 0; i < NameLength; i++)
for (i = 0; i < NameLength; i++) {
{ /* Get the character */
/* Get the character */ p = Name[i];
p = Name[i];
/* Handle each case */
/* Handle each case */ if ((p >= L'0') && (p <= L'9'))
if ((p >= L'0') && (p <= L'9')) {
{ /* Handle digits*/
/* Handle digits*/ IdCode = p - L'0';
IdCode = p - L'0'; }
} else if ((p >= L'A') && (p <= L'F'))
else if ((p >= L'A') && (p <= L'F')) {
{ /* Handle upper-case letters */
/* Handle upper-case letters */ IdCode = p - L'A' + 10;
IdCode = p - L'A' + 10; }
} else if ((p >= L'a') && (p <= L'f'))
else if ((p >= L'a') && (p <= L'f')) {
{ /* Handle lower-case letters */
/* Handle lower-case letters */ IdCode = p - L'a' + 10;
IdCode = p - L'a' + 10; }
} else
else {
{ /* Unhandled case, return what we have till now */
/* Unhandled case, return what we have till now */ break;
break; }
}
/* If the ID Code is >= 16, then we're done */
/* If the ID Code is >= 16, then we're done */ if (IdCode >= 16) break;
if (IdCode >= 16) break;
/* Build the Language ID */
/* Build the Language ID */ LangId = (LangId << 4) | (LANGID)IdCode;
LangId = (LangId << 4) | (LANGID)IdCode; }
}
/* Return the Language ID */
/* Return the Language ID */ return LangId;
return LangId; }
}
HCELL_INDEX
HCELL_INDEX NTAPI
NTAPI CmpWalkPath(IN PHHIVE SystemHive,
CmpWalkPath(IN PHHIVE SystemHive, IN HCELL_INDEX ParentCell,
IN HCELL_INDEX ParentCell, IN LPWSTR Path)
IN LPWSTR Path) {
{ UNICODE_STRING UnicodePath, NextName;
UNICODE_STRING UnicodePath, NextName; BOOLEAN LastName;
BOOLEAN LastName; HCELL_INDEX CurrentCell = ParentCell;
HCELL_INDEX CurrentCell = ParentCell; PCM_KEY_NODE Node;
PCM_KEY_NODE Node;
/* We shouldn't have a release routine at this point */
/* We shouldn't have a release routine at this point */ ASSERT(SystemHive->ReleaseCellRoutine == NULL);
ASSERT(SystemHive->ReleaseCellRoutine == NULL);
/* Initialize the Unicode path and start looping */
/* Initialize the Unicode path and start looping */ RtlInitUnicodeString(&UnicodePath, Path);
RtlInitUnicodeString(&UnicodePath, Path); while (TRUE)
while (TRUE) {
{ /* Get the next name */
/* Get the next name */ CmpGetNextName(&UnicodePath, &NextName, &LastName);
CmpGetNextName(&UnicodePath, &NextName, &LastName); if (!NextName.Length) return CurrentCell;
if (!NextName.Length) return CurrentCell;
/* Get the subkey */
/* Get the subkey */ Node = (PCM_KEY_NODE)HvGetCell(SystemHive, CurrentCell);
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, CurrentCell); if (!Node) return HCELL_NIL;
if (!Node) return HCELL_NIL; CurrentCell = CmpFindSubKeyByName(SystemHive, Node, &NextName);
CurrentCell = CmpFindSubKeyByName(SystemHive, Node, &NextName); if (CurrentCell == HCELL_NIL) return CurrentCell;
if (CurrentCell == HCELL_NIL) return CurrentCell; }
} }
}
VOID
VOID NTAPI
NTAPI CmGetSystemControlValues(IN PVOID SystemHiveData,
CmGetSystemControlValues(IN PVOID SystemHiveData, IN PCM_SYSTEM_CONTROL_VECTOR ControlVector)
IN PCM_SYSTEM_CONTROL_VECTOR ControlVector) {
{ PHHIVE SystemHive = (PHHIVE)&CmControlHive;
PHHIVE SystemHive = (PHHIVE)&CmControlHive; NTSTATUS Status;
NTSTATUS Status; HCELL_INDEX RootCell, BaseCell, KeyCell, ValueCell;
HCELL_INDEX RootCell, BaseCell, KeyCell, ValueCell; ULONG Length, DataSize;
ULONG Length, DataSize; PCM_KEY_NODE Node;
PCM_KEY_NODE Node; PCM_KEY_VALUE ValueData;
PCM_KEY_VALUE ValueData; UNICODE_STRING KeyName;
UNICODE_STRING KeyName; BOOLEAN Auto, IsSmallKey;
BOOLEAN Auto, IsSmallKey; PVOID Buffer;
PVOID Buffer;
/* LUDDDIIIICRROOOUUSSSS KI^H^H HACKKKK */
/* LUDDDIIIICRROOOUUSSSS KI^H^H HACKKKK */ if (!SystemHiveData) return;
if (!SystemHiveData) return;
/* Initialize the Hive View List and the security cache */
/* Initialize the Hive View List and the security cache */ RtlZeroMemory(SystemHive, sizeof(SystemHive));
RtlZeroMemory(SystemHive, sizeof(SystemHive)); CmpInitHiveViewList((PCMHIVE)SystemHive);
CmpInitHiveViewList((PCMHIVE)SystemHive); CmpInitSecurityCache((PCMHIVE)SystemHive);
CmpInitSecurityCache((PCMHIVE)SystemHive);
/* Initialize the Hive */
/* Initialize the Hive */ Status = HvInitialize(SystemHive,
Status = HvInitialize(SystemHive, HINIT_FLAT,
HINIT_FLAT, HIVE_VOLATILE,
HIVE_VOLATILE, HFILE_TYPE_PRIMARY,
HFILE_TYPE_PRIMARY, SystemHiveData,
SystemHiveData, NULL,
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL, 1,
1, NULL);
NULL); if (!NT_SUCCESS(Status)) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 1, 1, 0, 0);
if (!NT_SUCCESS(Status)) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 1, 1, 0, 0);
/* Sanity check, flat hives don't have release routines */
/* Sanity check, flat hives don't have release routines */ ASSERT(SystemHive->ReleaseCellRoutine == NULL);
ASSERT(SystemHive->ReleaseCellRoutine == NULL);
/* FIXME: Prepare it */
/* FIXME: Prepare it */ CmPrepareHive(SystemHive);
CmPrepareHive(SystemHive);
/* Set the Root Cell */
/* Set the Root Cell */ RootCell = ((PHBASE_BLOCK)SystemHiveData)->RootCell;
RootCell = ((PHBASE_BLOCK)SystemHiveData)->RootCell;
/* Find the current control set */
/* Find the current control set */ RtlInitUnicodeString(&KeyName, L"current");
RtlInitUnicodeString(&KeyName, L"current"); BaseCell = CmpFindControlSet(SystemHive, RootCell, &KeyName, &Auto);
BaseCell = CmpFindControlSet(SystemHive, RootCell, &KeyName, &Auto); if (BaseCell == HCELL_NIL) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 1, 2, 0, 0);
if (BaseCell == HCELL_NIL) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 1, 2, 0, 0);
/* Find the control subkey */
/* Find the control subkey */ RtlInitUnicodeString(&KeyName, L"control");
RtlInitUnicodeString(&KeyName, L"control"); Node = (PCM_KEY_NODE)HvGetCell(SystemHive, BaseCell);
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, BaseCell); BaseCell = CmpFindSubKeyByName(SystemHive, Node, &KeyName);
BaseCell = CmpFindSubKeyByName(SystemHive, Node, &KeyName); if (BaseCell == HCELL_NIL) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO,1 , 3, 0, 0);
if (BaseCell == HCELL_NIL) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO,1 , 3, 0, 0);
/* Loop each key */
/* Loop each key */ while (ControlVector->KeyPath)
while (ControlVector->KeyPath) {
{ /* Assume failure */
/* Assume failure */ Length = -1;
Length = -1;
/* Get the cell for this key */
/* Get the cell for this key */ KeyCell = CmpWalkPath(SystemHive, BaseCell, ControlVector->KeyPath);
KeyCell = CmpWalkPath(SystemHive, BaseCell, ControlVector->KeyPath); if (KeyCell != HCELL_NIL)
if (KeyCell != HCELL_NIL) {
{ /* Now get the cell for the value */
/* Now get the cell for the value */ RtlInitUnicodeString(&KeyName, ControlVector->ValueName);
RtlInitUnicodeString(&KeyName, ControlVector->ValueName); Node = (PCM_KEY_NODE)HvGetCell(SystemHive, KeyCell);
Node = (PCM_KEY_NODE)HvGetCell(SystemHive, KeyCell); ValueCell = CmpFindValueByName(SystemHive, Node, &KeyName);
ValueCell = CmpFindValueByName(SystemHive, Node, &KeyName); if (ValueCell != HCELL_NIL)
if (ValueCell != HCELL_NIL) {
{ /* Check if there's any data */
/* Check if there's any data */ if (!ControlVector->BufferLength)
if (!ControlVector->BufferLength) {
{ /* No, the buffer will only be large enough for a ULONG */
/* No, the buffer will only be large enough for a ULONG */ DataSize = sizeof(ULONG);
DataSize = sizeof(ULONG); }
} else
else {
{ /* Yes, save the data size */
/* Yes, save the data size */ DataSize = *ControlVector->BufferLength;
DataSize = *ControlVector->BufferLength; }
}
/* Get the actual data */
/* Get the actual data */ ValueData = (PCM_KEY_VALUE)HvGetCell(SystemHive, ValueCell);
ValueData = (PCM_KEY_VALUE)HvGetCell(SystemHive, ValueCell);
/* Check if this is a small key */
/* Check if this is a small key */ IsSmallKey = CmpIsKeyValueSmall(&Length, ValueData->DataLength);
IsSmallKey = CmpIsKeyValueSmall(&Length, ValueData->DataLength);
/* If the length is bigger then our buffer, normalize it */
/* If the length is bigger then our buffer, normalize it */ if (DataSize < Length) Length = DataSize;
if (DataSize < Length) Length = DataSize;
/* Make sure we have some data */
/* Make sure we have some data */ if (Length > 0)
if (Length > 0) {
{ /* Check if this was a small key */
/* Check if this was a small key */ if (IsSmallKey)
if (IsSmallKey) {
{ /* The buffer is directly safe to read */
/* The buffer is directly safe to read */ Buffer = (PVOID)(&(ValueData->Data));
Buffer = (PVOID)(&(ValueData->Data)); }
} else
else {
{ /* Use the longer path */
/* Use the longer path */ Buffer = (PVOID)HvGetCell(SystemHive, ValueData->Data);
Buffer = (PVOID)HvGetCell(SystemHive, ValueData->Data); }
}
/* Sanity check if this is a small key */
/* Sanity check if this is a small key */ ASSERT((IsSmallKey ?
ASSERT((IsSmallKey ? (Length <= CM_KEY_VALUE_SMALL) : TRUE));
(Length <= CM_KEY_VALUE_SMALL) : TRUE));
/* Copy the data in the buffer */
/* Copy the data in the buffer */ RtlCopyMemory(ControlVector->Buffer, Buffer, Length);
RtlCopyMemory(ControlVector->Buffer, Buffer, Length); }
}
/* Check if we should return the data type */
/* Check if we should return the data type */ if (ControlVector->Type)
if (ControlVector->Type) {
{ /* Return the type that we read */
/* Return the type that we read */ *ControlVector->Type = ValueData->Type;
*ControlVector->Type = ValueData->Type; }
} }
} }
}
/* Return the size that we read */
/* Return the size that we read */ if (ControlVector->BufferLength) *ControlVector->BufferLength = Length;
if (ControlVector->BufferLength) *ControlVector->BufferLength = Length;
/* Go to the next entry */
/* Go to the next entry */ ControlVector++;
ControlVector++; }
}
/* Check if the ID is in the registry */
/* Check if the ID is in the registry */ if (CmDefaultLanguageIdType == REG_SZ)
if (CmDefaultLanguageIdType == REG_SZ) {
{ /* Read it */
/* Read it */ PsDefaultSystemLocaleId =
PsDefaultSystemLocaleId = (LCID)CmpConvertLangId(CmDefaultLanguageId,
(LCID)CmpConvertLangId(CmDefaultLanguageId, CmDefaultLanguageIdLength);
CmDefaultLanguageIdLength); }
} else
else {
{ /* Use EN_US by default */
/* Use EN_US by default */ PsDefaultSystemLocaleId = 0x409;
PsDefaultSystemLocaleId = 0x409; }
}
/* Check if the ID Is in the registry */
/* Check if the ID Is in the registry */ if (CmInstallUILanguageIdType == REG_SZ)
if (CmInstallUILanguageIdType == REG_SZ) {
{ /* Read it */
/* Read it */ PsInstallUILanguageId = CmpConvertLangId(CmInstallUILanguageId,
PsInstallUILanguageId = CmpConvertLangId(CmInstallUILanguageId, CmInstallUILanguageIdLength);
CmInstallUILanguageIdLength); }
} else
else {
{ /* Otherwise, use the default */
/* Otherwise, use the default */ PsInstallUILanguageId = LANGIDFROMLCID(PsDefaultSystemLocaleId);
PsInstallUILanguageId = LANGIDFROMLCID(PsDefaultSystemLocaleId); }
}
/* Set the defaults for the Thread UI */
/* Set the defaults for the Thread UI */ PsDefaultThreadLocaleId = PsDefaultSystemLocaleId;
PsDefaultThreadLocaleId = PsDefaultSystemLocaleId; PsDefaultUILanguageId = PsInstallUILanguageId;
PsDefaultUILanguageId = PsInstallUILanguageId; }
}

File diff suppressed because it is too large Load diff

View file

@ -11,7 +11,6 @@
#include <ntoskrnl.h> #include <ntoskrnl.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#include "cm.h"
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/

View file

@ -1,198 +1,197 @@
/* /*
* PROJECT: ReactOS Kernel * PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmhook.c * FILE: ntoskrnl/config/cmhook.c
* PURPOSE: Configuration Manager - Registry Notifications/Callbacks * PURPOSE: Configuration Manager - Registry Notifications/Callbacks
* PROGRAMMERS: Thomas Weidenmueller (w3seek@reactos.org) * PROGRAMMERS: Thomas Weidenmueller (w3seek@reactos.org)
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
#include "ntoskrnl.h" #include "ntoskrnl.h"
#include "cm.h" #define NDEBUG
#define NDEBUG #include "debug.h"
#include "debug.h"
/* GLOBALS *******************************************************************/
/* GLOBALS *******************************************************************/
ULONG CmpCallBackCount = 0;
ULONG CmpCallBackCount = 0; EX_CALLBACK CmpCallBackVector[100];
EX_CALLBACK CmpCallBackVector[100];
LIST_ENTRY CmiCallbackHead;
LIST_ENTRY CmiCallbackHead; FAST_MUTEX CmiCallbackLock;
FAST_MUTEX CmiCallbackLock;
typedef struct _REGISTRY_CALLBACK
typedef struct _REGISTRY_CALLBACK {
{ LIST_ENTRY ListEntry;
LIST_ENTRY ListEntry; EX_RUNDOWN_REF RundownRef;
EX_RUNDOWN_REF RundownRef; PEX_CALLBACK_FUNCTION Function;
PEX_CALLBACK_FUNCTION Function; PVOID Context;
PVOID Context; LARGE_INTEGER Cookie;
LARGE_INTEGER Cookie; BOOLEAN PendingDelete;
BOOLEAN PendingDelete; } REGISTRY_CALLBACK, *PREGISTRY_CALLBACK;
} REGISTRY_CALLBACK, *PREGISTRY_CALLBACK;
/* PRIVATE FUNCTIONS *********************************************************/
/* PRIVATE FUNCTIONS *********************************************************/
VOID
VOID NTAPI
NTAPI CmpInitCallback(VOID)
CmpInitCallback(VOID) {
{ ULONG i;
ULONG i; PAGED_CODE();
PAGED_CODE();
/* Reset counter */
/* Reset counter */ CmpCallBackCount = 0;
CmpCallBackCount = 0;
/* Loop all the callbacks */
/* Loop all the callbacks */ for (i = 0; i < CMP_MAX_CALLBACKS; i++)
for (i = 0; i < CMP_MAX_CALLBACKS; i++) {
{ /* Initialize this one */
/* Initialize this one */ ExInitializeCallBack(&CmpCallBackVector[i]);
ExInitializeCallBack(&CmpCallBackVector[i]); }
}
/* ROS: Initialize old-style callbacks for now */
/* ROS: Initialize old-style callbacks for now */ InitializeListHead(&CmiCallbackHead);
InitializeListHead(&CmiCallbackHead); ExInitializeFastMutex(&CmiCallbackLock);
ExInitializeFastMutex(&CmiCallbackLock); }
}
NTSTATUS
NTSTATUS CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1,
CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1, IN PVOID Argument2)
IN PVOID Argument2) {
{ PLIST_ENTRY CurrentEntry;
PLIST_ENTRY CurrentEntry; NTSTATUS Status = STATUS_SUCCESS;
NTSTATUS Status = STATUS_SUCCESS; PREGISTRY_CALLBACK CurrentCallback;
PREGISTRY_CALLBACK CurrentCallback; PAGED_CODE();
PAGED_CODE();
ExAcquireFastMutex(&CmiCallbackLock);
ExAcquireFastMutex(&CmiCallbackLock);
for (CurrentEntry = CmiCallbackHead.Flink;
for (CurrentEntry = CmiCallbackHead.Flink; CurrentEntry != &CmiCallbackHead;
CurrentEntry != &CmiCallbackHead; CurrentEntry = CurrentEntry->Flink)
CurrentEntry = CurrentEntry->Flink) {
{ CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry);
CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry); if (!CurrentCallback->PendingDelete &&
if (!CurrentCallback->PendingDelete && ExAcquireRundownProtection(&CurrentCallback->RundownRef))
ExAcquireRundownProtection(&CurrentCallback->RundownRef)) {
{ /* don't hold locks during the callbacks! */
/* don't hold locks during the callbacks! */ ExReleaseFastMutex(&CmiCallbackLock);
ExReleaseFastMutex(&CmiCallbackLock);
Status = CurrentCallback->Function(CurrentCallback->Context,
Status = CurrentCallback->Function(CurrentCallback->Context, (PVOID)Argument1,
(PVOID)Argument1, Argument2);
Argument2);
ExAcquireFastMutex(&CmiCallbackLock);
ExAcquireFastMutex(&CmiCallbackLock);
/* don't release the rundown protection before holding the callback lock
/* 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
so the pointer to the next callback isn't cleared in case this callback get's deleted */
get's deleted */ ExReleaseRundownProtection(&CurrentCallback->RundownRef);
ExReleaseRundownProtection(&CurrentCallback->RundownRef); if(!NT_SUCCESS(Status))
if(!NT_SUCCESS(Status)) {
{ /* one callback returned failure, don't call any more callbacks */
/* one callback returned failure, don't call any more callbacks */ break;
break; }
} }
} }
}
ExReleaseFastMutex(&CmiCallbackLock);
ExReleaseFastMutex(&CmiCallbackLock);
return Status;
return Status; }
}
/* PUBLIC FUNCTIONS **********************************************************/
/* PUBLIC FUNCTIONS **********************************************************/
/*
/* * @implemented
* @implemented */
*/ NTSTATUS
NTSTATUS NTAPI
NTAPI CmRegisterCallback(IN PEX_CALLBACK_FUNCTION Function,
CmRegisterCallback(IN PEX_CALLBACK_FUNCTION Function, IN PVOID Context,
IN PVOID Context, IN OUT PLARGE_INTEGER Cookie)
IN OUT PLARGE_INTEGER Cookie) {
{ PREGISTRY_CALLBACK Callback;
PREGISTRY_CALLBACK Callback; PAGED_CODE();
PAGED_CODE(); ASSERT(Function && Cookie);
ASSERT(Function && Cookie);
Callback = ExAllocatePoolWithTag(PagedPool,
Callback = ExAllocatePoolWithTag(PagedPool, sizeof(REGISTRY_CALLBACK),
sizeof(REGISTRY_CALLBACK), TAG('C', 'M', 'c', 'b'));
TAG('C', 'M', 'c', 'b')); if (Callback != NULL)
if (Callback != NULL) {
{ /* initialize the callback */
/* initialize the callback */ ExInitializeRundownProtection(&Callback->RundownRef);
ExInitializeRundownProtection(&Callback->RundownRef); Callback->Function = Function;
Callback->Function = Function; Callback->Context = Context;
Callback->Context = Context; Callback->PendingDelete = FALSE;
Callback->PendingDelete = FALSE;
/* add it to the callback list and receive a cookie for the callback */
/* add it to the callback list and receive a cookie for the callback */ ExAcquireFastMutex(&CmiCallbackLock);
ExAcquireFastMutex(&CmiCallbackLock);
/* FIXME - to receive a unique cookie we'll just return the pointer to the
/* FIXME - to receive a unique cookie we'll just return the pointer to the callback object */
callback object */ Callback->Cookie.QuadPart = (ULONG_PTR)Callback;
Callback->Cookie.QuadPart = (ULONG_PTR)Callback; InsertTailList(&CmiCallbackHead, &Callback->ListEntry);
InsertTailList(&CmiCallbackHead, &Callback->ListEntry);
ExReleaseFastMutex(&CmiCallbackLock);
ExReleaseFastMutex(&CmiCallbackLock);
*Cookie = Callback->Cookie;
*Cookie = Callback->Cookie; return STATUS_SUCCESS;
return STATUS_SUCCESS; }
}
return STATUS_INSUFFICIENT_RESOURCES;
return STATUS_INSUFFICIENT_RESOURCES; }
}
/*
/* * @implemented
* @implemented */
*/ NTSTATUS
NTSTATUS NTAPI
NTAPI CmUnRegisterCallback(IN LARGE_INTEGER Cookie)
CmUnRegisterCallback(IN LARGE_INTEGER Cookie) {
{ PLIST_ENTRY CurrentEntry;
PLIST_ENTRY CurrentEntry; PREGISTRY_CALLBACK CurrentCallback;
PREGISTRY_CALLBACK CurrentCallback; PAGED_CODE();
PAGED_CODE();
ExAcquireFastMutex(&CmiCallbackLock);
ExAcquireFastMutex(&CmiCallbackLock);
for (CurrentEntry = CmiCallbackHead.Flink;
for (CurrentEntry = CmiCallbackHead.Flink; CurrentEntry != &CmiCallbackHead;
CurrentEntry != &CmiCallbackHead; CurrentEntry = CurrentEntry->Flink)
CurrentEntry = CurrentEntry->Flink) {
{ CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry);
CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry); if (CurrentCallback->Cookie.QuadPart == Cookie.QuadPart)
if (CurrentCallback->Cookie.QuadPart == Cookie.QuadPart) {
{ if (!CurrentCallback->PendingDelete)
if (!CurrentCallback->PendingDelete) {
{ /* found the callback, don't unlink it from the list yet so we don't screw
/* found the callback, don't unlink it from the list yet so we don't screw the calling loop */
the calling loop */ CurrentCallback->PendingDelete = TRUE;
CurrentCallback->PendingDelete = TRUE; ExReleaseFastMutex(&CmiCallbackLock);
ExReleaseFastMutex(&CmiCallbackLock);
/* if the callback is currently executing, wait until it finished */
/* if the callback is currently executing, wait until it finished */ ExWaitForRundownProtectionRelease(&CurrentCallback->RundownRef);
ExWaitForRundownProtectionRelease(&CurrentCallback->RundownRef);
/* time to unlink it. It's now safe because every attempt to acquire a
/* time to unlink it. It's now safe because every attempt to acquire a runtime protection on this callback will fail */
runtime protection on this callback will fail */ ExAcquireFastMutex(&CmiCallbackLock);
ExAcquireFastMutex(&CmiCallbackLock); RemoveEntryList(&CurrentCallback->ListEntry);
RemoveEntryList(&CurrentCallback->ListEntry); ExReleaseFastMutex(&CmiCallbackLock);
ExReleaseFastMutex(&CmiCallbackLock);
/* free the callback */
/* free the callback */ ExFreePool(CurrentCallback);
ExFreePool(CurrentCallback); return STATUS_SUCCESS;
return STATUS_SUCCESS; }
} else
else {
{ /* pending delete, pretend like it already is deleted */
/* pending delete, pretend like it already is deleted */ ExReleaseFastMutex(&CmiCallbackLock);
ExReleaseFastMutex(&CmiCallbackLock); return STATUS_UNSUCCESSFUL;
return STATUS_UNSUCCESSFUL; }
} }
} }
}
ExReleaseFastMutex(&CmiCallbackLock);
ExReleaseFastMutex(&CmiCallbackLock);
return STATUS_UNSUCCESSFUL;
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

View file

@ -1,221 +1,220 @@
/* /*
* PROJECT: ReactOS Kernel * PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmkeydel.c * FILE: ntoskrnl/config/cmkeydel.c
* PURPOSE: Configuration Manager - Key Body Deletion * PURPOSE: Configuration Manager - Key Body Deletion
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
#include "ntoskrnl.h" #include "ntoskrnl.h"
#include "cm.h" #define NDEBUG
#define NDEBUG #include "debug.h"
#include "debug.h"
/* FUNCTIONS *****************************************************************/
/* FUNCTIONS *****************************************************************/
BOOLEAN
BOOLEAN NTAPI
NTAPI CmpMarkKeyDirty(IN PHHIVE Hive,
CmpMarkKeyDirty(IN PHHIVE Hive, IN HCELL_INDEX Cell,
IN HCELL_INDEX Cell, IN BOOLEAN CheckNoSubkeys)
IN BOOLEAN CheckNoSubkeys) {
{ PCELL_DATA CellData, ListData, SecurityData, ValueData;
PCELL_DATA CellData, ListData, SecurityData, ValueData; ULONG i;
ULONG i;
/* Get the cell data for our target */
/* Get the cell data for our target */ CellData = HvGetCell(Hive, Cell);
CellData = HvGetCell(Hive, Cell); if (!CellData) return FALSE;
if (!CellData) return FALSE;
/* Check if sanity checks requested */
/* Check if sanity checks requested */ if (CheckNoSubkeys)
if (CheckNoSubkeys) {
{ /* Do them */
/* Do them */ ASSERT(CellData->u.KeyNode.SubKeyCounts[Stable] == 0);
ASSERT(CellData->u.KeyNode.SubKeyCounts[Stable] == 0); ASSERT(CellData->u.KeyNode.SubKeyCounts[Volatile] == 0);
ASSERT(CellData->u.KeyNode.SubKeyCounts[Volatile] == 0); }
}
/* If this is an exit hive, there's nothing to do */
/* If this is an exit hive, there's nothing to do */ if (CellData->u.KeyNode.Flags & KEY_HIVE_EXIT)
if (CellData->u.KeyNode.Flags & KEY_HIVE_EXIT) {
{ /* Release the cell and get out */
/* Release the cell and get out */ HvReleaseCell(Hive, Cell);
HvReleaseCell(Hive, Cell); return TRUE;
return TRUE; }
}
/* Otherwise, mark it dirty and release it */
/* Otherwise, mark it dirty and release it */ HvMarkCellDirty(Hive, Cell, FALSE);
HvMarkCellDirty(Hive, Cell, FALSE); HvReleaseCell(Hive, Cell);
HvReleaseCell(Hive, Cell);
/* Check if we have a class */
/* Check if we have a class */ if (CellData->u.KeyNode.Class != HCELL_NIL)
if (CellData->u.KeyNode.Class != HCELL_NIL) {
{ /* Mark it dirty */
/* Mark it dirty */ HvMarkCellDirty(Hive, CellData->u.KeyNode.Class, FALSE);
HvMarkCellDirty(Hive, CellData->u.KeyNode.Class, FALSE); }
}
/* Check if we have security */
/* Check if we have security */ if (CellData->u.KeyNode.Security != HCELL_NIL)
if (CellData->u.KeyNode.Security != HCELL_NIL) {
{ /* Mark it dirty */
/* Mark it dirty */ HvMarkCellDirty(Hive, CellData->u.KeyNode.Security, FALSE);
HvMarkCellDirty(Hive, CellData->u.KeyNode.Security, FALSE);
/* Get the security data and release it */
/* Get the security data and release it */ SecurityData = HvGetCell(Hive, CellData->u.KeyNode.Security);
SecurityData = HvGetCell(Hive, CellData->u.KeyNode.Security); if (!SecurityData) ASSERT(FALSE);
if (!SecurityData) ASSERT(FALSE); HvReleaseCell(Hive, CellData->u.KeyNode.Security);
HvReleaseCell(Hive, CellData->u.KeyNode.Security);
/* Mark the security links dirty too */
/* Mark the security links dirty too */ HvMarkCellDirty(Hive, SecurityData->u.KeySecurity.Flink, FALSE);
HvMarkCellDirty(Hive, SecurityData->u.KeySecurity.Flink, FALSE); HvMarkCellDirty(Hive, SecurityData->u.KeySecurity.Blink, FALSE);
HvMarkCellDirty(Hive, SecurityData->u.KeySecurity.Blink, FALSE); }
}
/* Check if we have any values */
/* Check if we have any values */ if (CellData->u.KeyNode.ValueList.Count > 0)
if (CellData->u.KeyNode.ValueList.Count > 0) {
{ /* Dirty the value list */
/* Dirty the value list */ HvMarkCellDirty(Hive, CellData->u.KeyNode.ValueList.List, FALSE);
HvMarkCellDirty(Hive, CellData->u.KeyNode.ValueList.List, FALSE);
/* Get the list data itself, and release it */
/* Get the list data itself, and release it */ ListData = HvGetCell(Hive, CellData->u.KeyNode.ValueList.List);
ListData = HvGetCell(Hive, CellData->u.KeyNode.ValueList.List); if (!ListData) ASSERT(FALSE);
if (!ListData) ASSERT(FALSE); HvReleaseCell(Hive, CellData->u.KeyNode.ValueList.List);
HvReleaseCell(Hive, CellData->u.KeyNode.ValueList.List);
/* Loop all values */
/* Loop all values */ for (i = 0; i < CellData->u.KeyNode.ValueList.Count; i++)
for (i = 0; i < CellData->u.KeyNode.ValueList.Count; i++) {
{ /* Dirty each value */
/* Dirty each value */ HvMarkCellDirty(Hive, ListData->u.KeyList[i], FALSE);
HvMarkCellDirty(Hive, ListData->u.KeyList[i], FALSE);
/* Get the value data and release it */
/* Get the value data and release it */ ValueData = HvGetCell(Hive, ListData->u.KeyList[i]);
ValueData = HvGetCell(Hive, ListData->u.KeyList[i]); ASSERT(ValueData);
ASSERT(ValueData); HvReleaseCell(Hive,ListData->u.KeyList[i]);
HvReleaseCell(Hive,ListData->u.KeyList[i]);
/* Mark the value data dirty too */
/* Mark the value data dirty too */ if (!CmpMarkValueDataDirty(Hive, &ValueData->u.KeyValue))
if (!CmpMarkValueDataDirty(Hive, &ValueData->u.KeyValue)) {
{ /* Failure */
/* Failure */ return FALSE;
return FALSE; }
} }
} }
}
/* If this is an entry hive, we're done */
/* If this is an entry hive, we're done */ if (CellData->u.KeyNode.Flags & KEY_HIVE_ENTRY) return TRUE;
if (CellData->u.KeyNode.Flags & KEY_HIVE_ENTRY) return TRUE;
/* Otherwise mark the index dirty too */
/* Otherwise mark the index dirty too */ if (!CmpMarkIndexDirty(Hive, CellData->u.KeyNode.Parent, Cell))
if (!CmpMarkIndexDirty(Hive, CellData->u.KeyNode.Parent, Cell)) {
{ /* Failure */
/* Failure */ return FALSE;
return FALSE; }
}
/* Finally, mark the parent dirty */
/* Finally, mark the parent dirty */ HvMarkCellDirty(Hive, CellData->u.KeyNode.Parent, FALSE);
HvMarkCellDirty(Hive, CellData->u.KeyNode.Parent, FALSE); return TRUE;
return TRUE; }
}
BOOLEAN
BOOLEAN NTAPI
NTAPI CmpFreeKeyBody(IN PHHIVE Hive,
CmpFreeKeyBody(IN PHHIVE Hive, IN HCELL_INDEX Cell)
IN HCELL_INDEX Cell) {
{ PCELL_DATA CellData;
PCELL_DATA CellData;
/* Get the key node */
/* Get the key node */ CellData = HvGetCell(Hive, Cell);
CellData = HvGetCell(Hive, Cell); if (!CellData) ASSERT(FALSE);
if (!CellData) ASSERT(FALSE);
/* Check if we can delete the child cells */
/* Check if we can delete the child cells */ if (!(CellData->u.KeyNode.Flags & KEY_HIVE_EXIT))
if (!(CellData->u.KeyNode.Flags & KEY_HIVE_EXIT)) {
{ /* Check if we have a security cell */
/* Check if we have a security cell */ if (CellData->u.KeyNode.Security != HCELL_NIL)
if (CellData->u.KeyNode.Security != HCELL_NIL) {
{ /* Free the security cell */
/* Free the security cell */ HvFreeCell(Hive, CellData->u.KeyNode.Security);
HvFreeCell(Hive, CellData->u.KeyNode.Security); }
}
/* Check if we have a class */
/* Check if we have a class */ if (CellData->u.KeyNode.ClassLength > 0)
if (CellData->u.KeyNode.ClassLength > 0) {
{ /* Free it */
/* Free it */ HvFreeCell(Hive, CellData->u.KeyNode.Class);
HvFreeCell(Hive, CellData->u.KeyNode.Class); }
} }
}
/* Release and free the cell */
/* Release and free the cell */ HvReleaseCell(Hive, Cell);
HvReleaseCell(Hive, Cell); HvFreeCell(Hive, Cell);
HvFreeCell(Hive, Cell); return TRUE;
return TRUE; }
}
NTSTATUS
NTSTATUS NTAPI
NTAPI CmpFreeKeyByCell(IN PHHIVE Hive,
CmpFreeKeyByCell(IN PHHIVE Hive, IN HCELL_INDEX Cell,
IN HCELL_INDEX Cell, IN BOOLEAN Unlink)
IN BOOLEAN Unlink) {
{ PCELL_DATA CellData, ParentData, ListData;
PCELL_DATA CellData, ParentData, ListData; ULONG i;
ULONG i; BOOLEAN Result;
BOOLEAN Result;
/* Mark the entire key dirty */
/* Mark the entire key dirty */ CmpMarkKeyDirty(Hive, Cell ,TRUE);
CmpMarkKeyDirty(Hive, Cell ,TRUE);
/* Get the target node and release it */
/* Get the target node and release it */ CellData = HvGetCell(Hive, Cell);
CellData = HvGetCell(Hive, Cell); if (!CellData) ASSERT(FALSE);
if (!CellData) ASSERT(FALSE); HvReleaseCell(Hive, Cell);
HvReleaseCell(Hive, Cell);
/* Make sure we don't have subkeys */
/* Make sure we don't have subkeys */ ASSERT((CellData->u.KeyNode.SubKeyCounts[Stable] +
ASSERT((CellData->u.KeyNode.SubKeyCounts[Stable] + CellData->u.KeyNode.SubKeyCounts[Volatile]) == 0);
CellData->u.KeyNode.SubKeyCounts[Volatile]) == 0);
/* Check if we have to unlink */
/* Check if we have to unlink */ if (Unlink)
if (Unlink) {
{ /* Remove the subkey */
/* Remove the subkey */ Result = CmpRemoveSubKey(Hive, CellData->u.KeyNode.Parent, Cell);
Result = CmpRemoveSubKey(Hive, CellData->u.KeyNode.Parent, Cell); if (!Result) return STATUS_INSUFFICIENT_RESOURCES;
if (!Result) return STATUS_INSUFFICIENT_RESOURCES;
/* Get the parent node and release it */
/* Get the parent node and release it */ ParentData = HvGetCell(Hive, CellData->u.KeyNode.Parent);
ParentData = HvGetCell(Hive, CellData->u.KeyNode.Parent); if (!ParentData) ASSERT(FALSE);
if (!ParentData) ASSERT(FALSE); HvReleaseCell(Hive, CellData->u.KeyNode.Parent);
HvReleaseCell(Hive, CellData->u.KeyNode.Parent);
/* Check if the parent node has no more subkeys */
/* Check if the parent node has no more subkeys */ if (!(ParentData->u.KeyNode.SubKeyCounts[Stable] +
if (!(ParentData->u.KeyNode.SubKeyCounts[Stable] + ParentData->u.KeyNode.SubKeyCounts[Volatile]))
ParentData->u.KeyNode.SubKeyCounts[Volatile])) {
{ /* Then free the cached name/class lengths */
/* Then free the cached name/class lengths */ ParentData->u.KeyNode.MaxNameLen = 0;
ParentData->u.KeyNode.MaxNameLen = 0; ParentData->u.KeyNode.MaxClassLen = 0;
ParentData->u.KeyNode.MaxClassLen = 0; }
} }
}
/* Check if we have any values */
/* Check if we have any values */ if (CellData->u.KeyNode.ValueList.Count > 0)
if (CellData->u.KeyNode.ValueList.Count > 0) {
{ /* Get the value list and release it */
/* Get the value list and release it */ ListData = HvGetCell(Hive, CellData->u.KeyNode.ValueList.List);
ListData = HvGetCell(Hive, CellData->u.KeyNode.ValueList.List); if (!ListData) ASSERT(FALSE);
if (!ListData) ASSERT(FALSE); HvReleaseCell(Hive, CellData->u.KeyNode.ValueList.List);
HvReleaseCell(Hive, CellData->u.KeyNode.ValueList.List);
/* Loop every value */
/* Loop every value */ for (i = 0; i < CellData->u.KeyNode.ValueList.Count; i++)
for (i = 0; i < CellData->u.KeyNode.ValueList.Count; i++) {
{ /* Free it */
/* Free it */ if (!CmpFreeValue(Hive, ListData->u.KeyList[i])) ASSERT(FALSE);
if (!CmpFreeValue(Hive, ListData->u.KeyList[i])) ASSERT(FALSE); }
}
/* Free the value list */
/* Free the value list */ HvFreeCell(Hive, CellData->u.KeyNode.ValueList.List);
HvFreeCell(Hive, CellData->u.KeyNode.ValueList.List); }
}
/* Free the key body itself, and then return our status */
/* Free the key body itself, and then return our status */ if (!CmpFreeKeyBody(Hive, Cell)) return STATUS_INSUFFICIENT_RESOURCES;
if (!CmpFreeKeyBody(Hive, Cell)) return STATUS_INSUFFICIENT_RESOURCES; return STATUS_SUCCESS;
return STATUS_SUCCESS; }
}

View file

@ -9,7 +9,6 @@
/* INCLUDES *******************************************************************/ /* INCLUDES *******************************************************************/
#include "ntoskrnl.h" #include "ntoskrnl.h"
#include "cm.h"
#define NDEBUG #define NDEBUG
#include "debug.h" #include "debug.h"

View file

@ -1,33 +1,32 @@
/* /*
* PROJECT: ReactOS Kernel * PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmmapvw.c * FILE: ntoskrnl/config/cmmapvw.c
* PURPOSE: Configuration Manager - Map-Viewed Hive Support * PURPOSE: Configuration Manager - Map-Viewed Hive Support
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
#include "ntoskrnl.h" #include "ntoskrnl.h"
#include "cm.h" #define NDEBUG
#define NDEBUG #include "debug.h"
#include "debug.h"
/* GLOBALS *******************************************************************/
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
/* FUNCTIONS *****************************************************************/
VOID
VOID NTAPI
NTAPI CmpInitHiveViewList(IN PCMHIVE Hive)
CmpInitHiveViewList(IN PCMHIVE Hive) {
{ /* Initialize the list heads */
/* Initialize the list heads */ InitializeListHead(&Hive->LRUViewListHead);
InitializeListHead(&Hive->LRUViewListHead); InitializeListHead(&Hive->PinViewListHead);
InitializeListHead(&Hive->PinViewListHead);
/* Reset data */
/* Reset data */ Hive->MappedViews = 0;
Hive->MappedViews = 0; Hive->PinnedViews = 0;
Hive->PinnedViews = 0; Hive->UseCount = 0;
Hive->UseCount = 0; }
}

View file

@ -1,254 +1,253 @@
/* /*
* PROJECT: ReactOS Kernel * PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmname.c * FILE: ntoskrnl/config/cmname.c
* PURPOSE: Configuration Manager - Name Management * PURPOSE: Configuration Manager - Name Management
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
#include "ntoskrnl.h" #include "ntoskrnl.h"
#include "cm.h" #define NDEBUG
#define NDEBUG #include "debug.h"
#include "debug.h"
/* GLOBALS *******************************************************************/
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
/* FUNCTIONS *****************************************************************/
USHORT
USHORT NTAPI
NTAPI CmpCopyName(IN PHHIVE Hive,
CmpCopyName(IN PHHIVE Hive, IN PWCHAR Destination,
IN PWCHAR Destination, IN PUNICODE_STRING Source)
IN PUNICODE_STRING Source) {
{ ULONG i;
ULONG i;
/* Check for old hives */
/* Check for old hives */ if (Hive->Version == 1)
if (Hive->Version == 1) {
{ /* Just copy the source directly */
/* Just copy the source directly */ RtlCopyMemory(Destination, Source->Buffer, Source->Length);
RtlCopyMemory(Destination, Source->Buffer, Source->Length); return Source->Length;
return Source->Length; }
}
/* For new versions, check for compressed name */
/* For new versions, check for compressed name */ for (i = 0; i < (Source->Length / sizeof(WCHAR)); i++)
for (i = 0; i < (Source->Length / sizeof(WCHAR)); i++) {
{ /* Check if the name is non compressed */
/* Check if the name is non compressed */ if (Source->Buffer[i] > (UCHAR)-1)
if (Source->Buffer[i] > (UCHAR)-1) {
{ /* Do the copy */
/* Do the copy */ RtlCopyMemory(Destination, Source->Buffer, Source->Length);
RtlCopyMemory(Destination, Source->Buffer, Source->Length); return Source->Length;
return Source->Length; }
}
/* Copy this character */
/* Copy this character */ ((PCHAR)Destination)[i] = (CHAR)(Source->Buffer[i]);
((PCHAR)Destination)[i] = (CHAR)(Source->Buffer[i]); }
}
/* Compressed name, return length */
/* Compressed name, return length */ return Source->Length / sizeof(WCHAR);
return Source->Length / sizeof(WCHAR); }
}
VOID
VOID NTAPI
NTAPI CmpCopyCompressedName(IN PWCHAR Destination,
CmpCopyCompressedName(IN PWCHAR Destination, IN ULONG DestinationLength,
IN ULONG DestinationLength, IN PWCHAR Source,
IN PWCHAR Source, IN ULONG SourceLength)
IN ULONG SourceLength) {
{ ULONG i, Length;
ULONG i, Length;
/* Get the actual length to copy */
/* Get the actual length to copy */ Length = min(DestinationLength / sizeof(WCHAR), SourceLength);
Length = min(DestinationLength / sizeof(WCHAR), SourceLength); for (i = 0; i < Length; i++)
for (i = 0; i < Length; i++) {
{ /* Copy each character */
/* Copy each character */ Destination[i] = (WCHAR)((PCHAR)Source)[i];
Destination[i] = (WCHAR)((PCHAR)Source)[i]; }
} }
}
USHORT
USHORT NTAPI
NTAPI CmpNameSize(IN PHHIVE Hive,
CmpNameSize(IN PHHIVE Hive, IN PUNICODE_STRING Name)
IN PUNICODE_STRING Name) {
{ ULONG i;
ULONG i;
/* For old hives, just retun the length */
/* For old hives, just retun the length */ if (Hive->Version == 1) return Name->Length;
if (Hive->Version == 1) return Name->Length;
/* For new versions, check for compressed name */
/* For new versions, check for compressed name */ for (i = 0; i < (Name->Length / sizeof(WCHAR)); i++)
for (i = 0; i < (Name->Length / sizeof(WCHAR)); i++) {
{ /* Check if the name is non compressed */
/* Check if the name is non compressed */ if (Name->Buffer[i] > (UCHAR)-1) return Name->Length;
if (Name->Buffer[i] > (UCHAR)-1) return Name->Length; }
}
/* Compressed name, return length */
/* Compressed name, return length */ return Name->Length / sizeof(WCHAR);
return Name->Length / sizeof(WCHAR); }
}
USHORT
USHORT NTAPI
NTAPI CmpCompressedNameSize(IN PWCHAR Name,
CmpCompressedNameSize(IN PWCHAR Name, IN ULONG Length)
IN ULONG Length) {
{ /*
/* * Don't remove this: compressed names are "opaque" and just because
* Don't remove this: compressed names are "opaque" and just because * the current implementation turns them into ansi-names doesn't mean
* the current implementation turns them into ansi-names doesn't mean * that it will remain that way forever, so -never- assume this code
* that it will remain that way forever, so -never- assume this code * below internally!
* below internally! */
*/ return (USHORT)Length * sizeof(WCHAR);
return (USHORT)Length * sizeof(WCHAR); }
}
LONG
LONG NTAPI
NTAPI CmpCompareCompressedName(IN PCUNICODE_STRING SearchName,
CmpCompareCompressedName(IN PCUNICODE_STRING SearchName, IN PWCHAR CompressedName,
IN PWCHAR CompressedName, IN ULONG NameLength)
IN ULONG NameLength) {
{ WCHAR *p;
WCHAR *p; CHAR *pp;
CHAR *pp; WCHAR p1, p2;
WCHAR p1, p2; USHORT SearchLength;
USHORT SearchLength; LONG Result;
LONG Result;
/* Set the pointers and length and then loop */
/* Set the pointers and length and then loop */ p = SearchName->Buffer;
p = SearchName->Buffer; pp = (PCHAR)CompressedName;
pp = (PCHAR)CompressedName; SearchLength = (SearchName->Length / sizeof(WCHAR));
SearchLength = (SearchName->Length / sizeof(WCHAR)); while ((SearchLength) && (NameLength))
while ((SearchLength) && (NameLength)) {
{ /* Get the characters */
/* Get the characters */ p1 = *p++;
p1 = *p++; p2 = (WCHAR)(*pp++);
p2 = (WCHAR)(*pp++);
/* Check if we have a direct match */
/* Check if we have a direct match */ if (p1 != p2)
if (p1 != p2) {
{ /* See if they match and return result if they don't */
/* See if they match and return result if they don't */ Result = (LONG)RtlUpcaseUnicodeChar(p1) -
Result = (LONG)RtlUpcaseUnicodeChar(p1) - (LONG)RtlUpcaseUnicodeChar(p2);
(LONG)RtlUpcaseUnicodeChar(p2); if (Result) return Result;
if (Result) return Result; }
}
/* Next chars */
/* Next chars */ SearchLength--;
SearchLength--; NameLength--;
NameLength--; }
}
/* Return the difference directly */
/* Return the difference directly */ return SearchLength - NameLength;
return SearchLength - NameLength; }
}
BOOLEAN
BOOLEAN NTAPI
NTAPI CmpFindNameInList(IN PHHIVE Hive,
CmpFindNameInList(IN PHHIVE Hive, IN PCHILD_LIST ChildList,
IN PCHILD_LIST ChildList, IN PUNICODE_STRING Name,
IN PUNICODE_STRING Name, IN PULONG ChildIndex,
IN PULONG ChildIndex, IN PHCELL_INDEX CellIndex)
IN PHCELL_INDEX CellIndex) {
{ PCELL_DATA CellData;
PCELL_DATA CellData; HCELL_INDEX CellToRelease = HCELL_NIL;
HCELL_INDEX CellToRelease = HCELL_NIL; ULONG i;
ULONG i; PCM_KEY_VALUE KeyValue;
PCM_KEY_VALUE KeyValue; LONG Result;
LONG Result; UNICODE_STRING SearchName;
UNICODE_STRING SearchName; BOOLEAN Success;
BOOLEAN Success;
/* Make sure there's actually something on the list */
/* Make sure there's actually something on the list */ if (ChildList->Count != 0)
if (ChildList->Count != 0) {
{ /* Get the cell data */
/* Get the cell data */ CellData = (PCELL_DATA)HvGetCell(Hive, ChildList->List);
CellData = (PCELL_DATA)HvGetCell(Hive, ChildList->List); if (!CellData)
if (!CellData) {
{ /* Couldn't get the cell... tell the caller */
/* Couldn't get the cell... tell the caller */ *CellIndex = HCELL_NIL;
*CellIndex = HCELL_NIL; return FALSE;
return FALSE; }
}
/* Now loop every entry */
/* Now loop every entry */ for (i = 0; i < ChildList->Count; i++)
for (i = 0; i < ChildList->Count; i++) {
{ /* Check if we have a cell to release */
/* Check if we have a cell to release */ if (CellToRelease != HCELL_NIL)
if (CellToRelease != HCELL_NIL) {
{ /* Release it */
/* Release it */ HvReleaseCell(Hive, CellToRelease);
HvReleaseCell(Hive, CellToRelease); CellToRelease = HCELL_NIL;
CellToRelease = HCELL_NIL; }
}
/* Get this value */
/* Get this value */ KeyValue = (PCM_KEY_VALUE)HvGetCell(Hive, CellData->u.KeyList[i]);
KeyValue = (PCM_KEY_VALUE)HvGetCell(Hive, CellData->u.KeyList[i]); if (!KeyValue)
if (!KeyValue) {
{ /* Return with no data found */
/* Return with no data found */ *CellIndex = HCELL_NIL;
*CellIndex = HCELL_NIL; Success = FALSE;
Success = FALSE; goto Return;
goto Return; }
}
/* Save the cell to release */
/* Save the cell to release */ CellToRelease = CellData->u.KeyList[i];
CellToRelease = CellData->u.KeyList[i];
/* Check if it's a compressed value name */
/* Check if it's a compressed value name */ if (KeyValue->Flags & VALUE_COMP_NAME)
if (KeyValue->Flags & VALUE_COMP_NAME) {
{ /* Use the compressed name check */
/* Use the compressed name check */ Result = CmpCompareCompressedName(Name,
Result = CmpCompareCompressedName(Name, KeyValue->Name,
KeyValue->Name, KeyValue->NameLength);
KeyValue->NameLength); }
} else
else {
{ /* Setup the Unicode string */
/* Setup the Unicode string */ SearchName.Length = KeyValue->NameLength;
SearchName.Length = KeyValue->NameLength; SearchName.MaximumLength = SearchName.Length;
SearchName.MaximumLength = SearchName.Length; SearchName.Buffer = KeyValue->Name;
SearchName.Buffer = KeyValue->Name; Result = RtlCompareUnicodeString(Name, &SearchName, TRUE);
Result = RtlCompareUnicodeString(Name, &SearchName, TRUE); }
}
/* Check if we found it */
/* Check if we found it */ if (!Result)
if (!Result) {
{ /* We did...return info to caller */
/* We did...return info to caller */ if (ChildIndex) *ChildIndex = i;
if (ChildIndex) *ChildIndex = i; *CellIndex = CellData->u.KeyList[i];
*CellIndex = CellData->u.KeyList[i];
/* Set success state */
/* Set success state */ Success = TRUE;
Success = TRUE; goto Return;
goto Return; }
} }
}
/* Got to the end of the list */
/* Got to the end of the list */ if (ChildIndex) *ChildIndex = i;
if (ChildIndex) *ChildIndex = i; *CellIndex = HCELL_NIL;
*CellIndex = HCELL_NIL;
/* Nothing found if we got here */
/* Nothing found if we got here */ Success = TRUE;
Success = TRUE; goto Return;
goto Return; }
}
/* Nothing found...check if the caller wanted more info */
/* Nothing found...check if the caller wanted more info */ ASSERT(ChildList->Count == 0);
ASSERT(ChildList->Count == 0); if (ChildIndex) *ChildIndex = 0;
if (ChildIndex) *ChildIndex = 0; *CellIndex = HCELL_NIL;
*CellIndex = HCELL_NIL;
/* Nothing found if we got here */
/* Nothing found if we got here */ return TRUE;
return TRUE;
Return:
Return: /* Release the first cell we got */
/* Release the first cell we got */ if (CellData) HvReleaseCell(Hive, ChildList->List);
if (CellData) HvReleaseCell(Hive, ChildList->List);
/* Release the secondary one, if we have one */
/* Release the secondary one, if we have one */ if (CellToRelease) HvReleaseCell(Hive, CellToRelease);
if (CellToRelease) HvReleaseCell(Hive, CellToRelease); return Success;
return Success; }
}

File diff suppressed because it is too large Load diff

View file

@ -1,153 +1,152 @@
/* /*
* PROJECT: ReactOS Kernel * PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmse.c * FILE: ntoskrnl/config/cmse.c
* PURPOSE: Configuration Manager - Security Subsystem Interface * PURPOSE: Configuration Manager - Security Subsystem Interface
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
#include "ntoskrnl.h" #include "ntoskrnl.h"
#include "cm.h" #define NDEBUG
#define NDEBUG #include "debug.h"
#include "debug.h"
/* GLOBALS *******************************************************************/
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
/* FUNCTIONS *****************************************************************/
PSECURITY_DESCRIPTOR
PSECURITY_DESCRIPTOR NTAPI
NTAPI CmpHiveRootSecurityDescriptor(VOID)
CmpHiveRootSecurityDescriptor(VOID) {
{ NTSTATUS Status;
NTSTATUS Status; PSECURITY_DESCRIPTOR SecurityDescriptor;
PSECURITY_DESCRIPTOR SecurityDescriptor; PACL Acl, AclCopy;
PACL Acl, AclCopy; PSID Sid[4];
PSID Sid[4]; SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY}; SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; ULONG AceLength, AclLength, SidLength;
ULONG AceLength, AclLength, SidLength; PACE_HEADER AceHeader;
PACE_HEADER AceHeader; ULONG i;
ULONG i; PAGED_CODE();
PAGED_CODE();
/* Phase 1: Allocate SIDs */
/* Phase 1: Allocate SIDs */ SidLength = RtlLengthRequiredSid(1);
SidLength = RtlLengthRequiredSid(1); Sid[0] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
Sid[0] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM); Sid[1] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
Sid[1] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM); Sid[2] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
Sid[2] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM); SidLength = RtlLengthRequiredSid(2);
SidLength = RtlLengthRequiredSid(2); Sid[3] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
Sid[3] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
/* Make sure all SIDs were allocated */
/* Make sure all SIDs were allocated */ if (!(Sid[0]) || !(Sid[1]) || !(Sid[2]) || !(Sid[3]))
if (!(Sid[0]) || !(Sid[1]) || !(Sid[2]) || !(Sid[3])) {
{ /* Bugcheck */
/* Bugcheck */ KEBUGCHECKEX(REGISTRY_ERROR, 11, 1, 0, 0);
KEBUGCHECKEX(REGISTRY_ERROR, 11, 1, 0, 0); }
}
/* Phase 2: Initialize all SIDs */
/* Phase 2: Initialize all SIDs */ Status = RtlInitializeSid(Sid[0], &WorldAuthority, 1);
Status = RtlInitializeSid(Sid[0], &WorldAuthority, 1); Status |= RtlInitializeSid(Sid[1], &NtAuthority, 1);
Status |= RtlInitializeSid(Sid[1], &NtAuthority, 1); Status |= RtlInitializeSid(Sid[2], &NtAuthority, 1);
Status |= RtlInitializeSid(Sid[2], &NtAuthority, 1); Status |= RtlInitializeSid(Sid[3], &NtAuthority, 2);
Status |= RtlInitializeSid(Sid[3], &NtAuthority, 2); if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 2, 0, 0);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 2, 0, 0);
/* Phase 2: Setup SID Sub Authorities */
/* Phase 2: Setup SID Sub Authorities */ *RtlSubAuthoritySid(Sid[0], 0) = SECURITY_WORLD_RID;
*RtlSubAuthoritySid(Sid[0], 0) = SECURITY_WORLD_RID; *RtlSubAuthoritySid(Sid[1], 0) = SECURITY_RESTRICTED_CODE_RID;
*RtlSubAuthoritySid(Sid[1], 0) = SECURITY_RESTRICTED_CODE_RID; *RtlSubAuthoritySid(Sid[2], 0) = SECURITY_LOCAL_SYSTEM_RID;
*RtlSubAuthoritySid(Sid[2], 0) = SECURITY_LOCAL_SYSTEM_RID; *RtlSubAuthoritySid(Sid[3], 0) = SECURITY_BUILTIN_DOMAIN_RID;
*RtlSubAuthoritySid(Sid[3], 0) = SECURITY_BUILTIN_DOMAIN_RID; *RtlSubAuthoritySid(Sid[3], 1) = DOMAIN_ALIAS_RID_ADMINS;
*RtlSubAuthoritySid(Sid[3], 1) = DOMAIN_ALIAS_RID_ADMINS;
/* Make sure all SIDs are valid */
/* Make sure all SIDs are valid */ ASSERT(RtlValidSid(Sid[0]));
ASSERT(RtlValidSid(Sid[0])); ASSERT(RtlValidSid(Sid[1]));
ASSERT(RtlValidSid(Sid[1])); ASSERT(RtlValidSid(Sid[2]));
ASSERT(RtlValidSid(Sid[2])); ASSERT(RtlValidSid(Sid[3]));
ASSERT(RtlValidSid(Sid[3]));
/* Phase 3: Calculate ACL Length */
/* Phase 3: Calculate ACL Length */ AclLength = sizeof(ACL);
AclLength = sizeof(ACL); for (i = 0; i < 4; i++)
for (i = 0; i < 4; i++) {
{ /* This is what MSDN says to do */
/* This is what MSDN says to do */ AceLength = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart);
AceLength = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart); AceLength += SeLengthSid(Sid[i]);
AceLength += SeLengthSid(Sid[i]); AclLength += AceLength;
AclLength += AceLength; }
}
/* Phase 3: Allocate the ACL */
/* Phase 3: Allocate the ACL */ Acl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_CM);
Acl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_CM); if (!Acl) KEBUGCHECKEX(REGISTRY_ERROR, 11, 3, 0, 0);
if (!Acl) KEBUGCHECKEX(REGISTRY_ERROR, 11, 3, 0, 0);
/* Phase 4: Create the ACL */
/* Phase 4: Create the ACL */ Status = RtlCreateAcl(Acl, AclLength, ACL_REVISION);
Status = RtlCreateAcl(Acl, AclLength, ACL_REVISION); if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 4, Status, 0);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 4, Status, 0);
/* Phase 5: Build the ACL */
/* Phase 5: Build the ACL */ Status = RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[0]);
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_ALL_ACCESS, Sid[1]); Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[2]);
Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[2]); Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[3]);
Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[3]); if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 5, Status, 0);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 5, Status, 0);
/* Phase 5: Make the ACEs inheritable */
/* Phase 5: Make the ACEs inheritable */ Status = RtlGetAce(Acl, 0,( PVOID*)&AceHeader);
Status = RtlGetAce(Acl, 0,( PVOID*)&AceHeader); ASSERT(NT_SUCCESS(Status));
ASSERT(NT_SUCCESS(Status)); AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE; Status = RtlGetAce(Acl, 1, (PVOID*)&AceHeader);
Status = RtlGetAce(Acl, 1, (PVOID*)&AceHeader); ASSERT(NT_SUCCESS(Status));
ASSERT(NT_SUCCESS(Status)); AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE; Status = RtlGetAce(Acl, 2, (PVOID*)&AceHeader);
Status = RtlGetAce(Acl, 2, (PVOID*)&AceHeader); ASSERT(NT_SUCCESS(Status));
ASSERT(NT_SUCCESS(Status)); AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE; Status = RtlGetAce(Acl, 3, (PVOID*)&AceHeader);
Status = RtlGetAce(Acl, 3, (PVOID*)&AceHeader); ASSERT(NT_SUCCESS(Status));
ASSERT(NT_SUCCESS(Status)); AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
/* Phase 6: Allocate the security descriptor and make space for the ACL */
/* Phase 6: Allocate the security descriptor and make space for the ACL */ SecurityDescriptor = ExAllocatePoolWithTag(PagedPool,
SecurityDescriptor = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_DESCRIPTOR) +
sizeof(SECURITY_DESCRIPTOR) + AclLength,
AclLength, TAG_CM);
TAG_CM); if (!SecurityDescriptor) KEBUGCHECKEX(REGISTRY_ERROR, 11, 6, 0, 0);
if (!SecurityDescriptor) KEBUGCHECKEX(REGISTRY_ERROR, 11, 6, 0, 0);
/* Phase 6: Make a copy of the ACL */
/* Phase 6: Make a copy of the ACL */ AclCopy = (PACL)((PISECURITY_DESCRIPTOR)SecurityDescriptor + 1);
AclCopy = (PACL)((PISECURITY_DESCRIPTOR)SecurityDescriptor + 1); RtlCopyMemory(AclCopy, Acl, AclLength);
RtlCopyMemory(AclCopy, Acl, AclLength);
/* Phase 7: Create the security descriptor */
/* Phase 7: Create the security descriptor */ Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
Status = RtlCreateSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
SECURITY_DESCRIPTOR_REVISION); if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 7, Status, 0);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 7, Status, 0);
/* Phase 8: Set the ACL as a DACL */
/* Phase 8: Set the ACL as a DACL */ Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor, TRUE,
TRUE, AclCopy,
AclCopy, FALSE);
FALSE); if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 8, Status, 0);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 8, Status, 0);
/* Free the SIDs and original ACL */
/* Free the SIDs and original ACL */ for (i = 0; i < 4; i++) ExFreePool(Sid[i]);
for (i = 0; i < 4; i++) ExFreePool(Sid[i]); ExFreePool(Acl);
ExFreePool(Acl);
/* Return the security descriptor */
/* Return the security descriptor */ return SecurityDescriptor;
return SecurityDescriptor; }
}
NTSTATUS
NTSTATUS NTAPI
NTAPI CmpSecurityMethod(IN PVOID ObjectBody,
CmpSecurityMethod(IN PVOID ObjectBody, IN SECURITY_OPERATION_CODE OperationCode,
IN SECURITY_OPERATION_CODE OperationCode, IN PSECURITY_INFORMATION SecurityInformation,
IN PSECURITY_INFORMATION SecurityInformation, IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN OUT PULONG BufferLength,
IN OUT PULONG BufferLength, IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor, IN POOL_TYPE PoolType,
IN POOL_TYPE PoolType, IN PGENERIC_MAPPING GenericMapping)
IN PGENERIC_MAPPING GenericMapping) {
{ /* HACK */
/* HACK */ return STATUS_SUCCESS;
return STATUS_SUCCESS; }
}

View file

@ -1,38 +1,37 @@
/* /*
* PROJECT: ReactOS Kernel * PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmsecach.c * FILE: ntoskrnl/config/cmsecach.c
* PURPOSE: Configuration Manager - Security Cache * PURPOSE: Configuration Manager - Security Cache
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
#include "ntoskrnl.h" #include "ntoskrnl.h"
#include "cm.h" #define NDEBUG
#define NDEBUG #include "debug.h"
#include "debug.h"
/* GLOBALS *******************************************************************/
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
/* FUNCTIONS *****************************************************************/
VOID
VOID NTAPI
NTAPI CmpInitSecurityCache(IN PCMHIVE Hive)
CmpInitSecurityCache(IN PCMHIVE Hive) {
{ ULONG i;
ULONG i;
/* Reset data */
/* Reset data */ Hive->SecurityCount = 0;
Hive->SecurityCount = 0; Hive->SecurityCacheSize = 0;
Hive->SecurityCacheSize = 0; Hive->SecurityHitHint = -1;
Hive->SecurityHitHint = -1; Hive->SecurityCache = NULL;
Hive->SecurityCache = NULL;
/* Loop every security hash */
/* Loop every security hash */ for (i = 0; i < 64; i++)
for (i = 0; i < 64; i++) {
{ /* Initialize it */
/* Initialize it */ InitializeListHead(&Hive->SecurityHash[i]);
InitializeListHead(&Hive->SecurityHash[i]); }
} }
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,364 +1,363 @@
/* /*
* PROJECT: ReactOS Kernel * PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmvalue.c * FILE: ntoskrnl/config/cmvalue.c
* PURPOSE: Configuration Manager - Cell Values * PURPOSE: Configuration Manager - Cell Values
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
#include "ntoskrnl.h" #include "ntoskrnl.h"
#include "cm.h" #define NDEBUG
#define NDEBUG #include "debug.h"
#include "debug.h"
/* FUNCTIONS *****************************************************************/
/* FUNCTIONS *****************************************************************/
BOOLEAN
BOOLEAN NTAPI
NTAPI CmpMarkValueDataDirty(IN PHHIVE Hive,
CmpMarkValueDataDirty(IN PHHIVE Hive, IN PCM_KEY_VALUE Value)
IN PCM_KEY_VALUE Value) {
{ ULONG KeySize;
ULONG KeySize; PAGED_CODE();
PAGED_CODE();
/* Make sure there's actually any data */
/* Make sure there's actually any data */ if (Value->Data != HCELL_NIL)
if (Value->Data != HCELL_NIL) {
{ /* If this is a small key, there's no need to have it dirty */
/* If this is a small key, there's no need to have it dirty */ if (CmpIsKeyValueSmall(&KeySize, Value->DataLength)) return TRUE;
if (CmpIsKeyValueSmall(&KeySize, Value->DataLength)) return TRUE;
/* Check if this is a big key */
/* Check if this is a big key */ ASSERT_VALUE_BIG(Hive, KeySize);
ASSERT_VALUE_BIG(Hive, KeySize);
/* Normal value, just mark it dirty */
/* Normal value, just mark it dirty */ HvMarkCellDirty(Hive, Value->Data, FALSE);
HvMarkCellDirty(Hive, Value->Data, FALSE); }
}
/* Operation complete */
/* Operation complete */ return TRUE;
return TRUE; }
}
BOOLEAN
BOOLEAN NTAPI
NTAPI CmpFreeValueData(IN PHHIVE Hive,
CmpFreeValueData(IN PHHIVE Hive, IN HCELL_INDEX DataCell,
IN HCELL_INDEX DataCell, IN ULONG DataLength)
IN ULONG DataLength) {
{ ULONG KeySize;
ULONG KeySize; PAGED_CODE();
PAGED_CODE();
/* If this is a small key, the data is built-in */
/* If this is a small key, the data is built-in */ if (!CmpIsKeyValueSmall(&KeySize, DataLength))
if (!CmpIsKeyValueSmall(&KeySize, DataLength)) {
{ /* If there's no data cell, there's nothing to do */
/* If there's no data cell, there's nothing to do */ if (DataCell == HCELL_NIL) return TRUE;
if (DataCell == HCELL_NIL) return TRUE;
/* Make sure the data cell is allocated */
/* Make sure the data cell is allocated */ //ASSERT(HvIsCellAllocated(Hive, DataCell));
//ASSERT(HvIsCellAllocated(Hive, DataCell));
/* Unsupported value type */
/* Unsupported value type */ ASSERT_VALUE_BIG(Hive, KeySize);
ASSERT_VALUE_BIG(Hive, KeySize);
/* Normal value, just free the data cell */
/* Normal value, just free the data cell */ HvFreeCell(Hive, DataCell);
HvFreeCell(Hive, DataCell); }
}
/* Operation complete */
/* Operation complete */ return TRUE;
return TRUE; }
}
BOOLEAN
BOOLEAN NTAPI
NTAPI CmpFreeValue(IN PHHIVE Hive,
CmpFreeValue(IN PHHIVE Hive, IN HCELL_INDEX Cell)
IN HCELL_INDEX Cell) {
{ PCM_KEY_VALUE Value;
PCM_KEY_VALUE Value; PAGED_CODE();
PAGED_CODE();
/* Get the cell data */
/* Get the cell data */ Value = (PCM_KEY_VALUE)HvGetCell(Hive, Cell);
Value = (PCM_KEY_VALUE)HvGetCell(Hive, Cell); if (!Value) ASSERT(FALSE);
if (!Value) ASSERT(FALSE);
/* Free it */
/* Free it */ if (!CmpFreeValueData(Hive, Value->Data, Value->DataLength))
if (!CmpFreeValueData(Hive, Value->Data, Value->DataLength)) {
{ /* We failed to free the data, return failure */
/* We failed to free the data, return failure */ HvReleaseCell(Hive, Cell);
HvReleaseCell(Hive, Cell); return FALSE;
return FALSE; }
}
/* Release the cell and free it */
/* Release the cell and free it */ HvReleaseCell(Hive, Cell);
HvReleaseCell(Hive, Cell); HvFreeCell(Hive, Cell);
HvFreeCell(Hive, Cell); return TRUE;
return TRUE; }
}
HCELL_INDEX
HCELL_INDEX NTAPI
NTAPI CmpFindValueByName(IN PHHIVE Hive,
CmpFindValueByName(IN PHHIVE Hive, IN PCM_KEY_NODE KeyNode,
IN PCM_KEY_NODE KeyNode, IN PUNICODE_STRING Name)
IN PUNICODE_STRING Name) {
{ HCELL_INDEX CellIndex;
HCELL_INDEX CellIndex;
/* Call the main function */
/* Call the main function */ if (!CmpFindNameInList(Hive,
if (!CmpFindNameInList(Hive, &KeyNode->ValueList,
&KeyNode->ValueList, Name,
Name, NULL,
NULL, &CellIndex))
&CellIndex)) {
{ /* Santy check */
/* Santy check */ ASSERT(CellIndex == HCELL_NIL);
ASSERT(CellIndex == HCELL_NIL); }
}
/* Return the index */
/* Return the index */ return CellIndex;
return CellIndex; }
}
BOOLEAN
BOOLEAN NTAPI
NTAPI CmpGetValueData(IN PHHIVE Hive,
CmpGetValueData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value,
IN PCM_KEY_VALUE Value, IN PULONG Length,
IN PULONG Length, OUT PVOID *Buffer,
OUT PVOID *Buffer, OUT PBOOLEAN BufferAllocated,
OUT PBOOLEAN BufferAllocated, OUT PHCELL_INDEX CellToRelease)
OUT PHCELL_INDEX CellToRelease) {
{ PAGED_CODE();
PAGED_CODE();
/* Sanity check */
/* Sanity check */ ASSERT(Value->Signature == CM_KEY_VALUE_SIGNATURE);
ASSERT(Value->Signature == CM_KEY_VALUE_SIGNATURE);
/* Set failure defaults */
/* Set failure defaults */ *BufferAllocated = FALSE;
*BufferAllocated = FALSE; *Buffer = NULL;
*Buffer = NULL; *CellToRelease = HCELL_NIL;
*CellToRelease = HCELL_NIL;
/* Check if this is a small key */
/* Check if this is a small key */ if (CmpIsKeyValueSmall(Length, Value->DataLength))
if (CmpIsKeyValueSmall(Length, Value->DataLength)) {
{ /* Return the data immediately */
/* Return the data immediately */ *Buffer = &Value->Data;
*Buffer = &Value->Data; return TRUE;
return TRUE; }
}
/* Unsupported */
/* Unsupported */ ASSERT_VALUE_BIG(Hive, *Length);
ASSERT_VALUE_BIG(Hive, *Length);
/* Get the data from the cell */
/* Get the data from the cell */ *Buffer = HvGetCell(Hive, Value->Data);
*Buffer = HvGetCell(Hive, Value->Data); if (!(*Buffer)) return FALSE;
if (!(*Buffer)) return FALSE;
/* Return success and the cell to be released */
/* Return success and the cell to be released */ *CellToRelease = Value->Data;
*CellToRelease = Value->Data; return TRUE;
return TRUE; }
}
PCELL_DATA
PCELL_DATA NTAPI
NTAPI CmpValueToData(IN PHHIVE Hive,
CmpValueToData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value,
IN PCM_KEY_VALUE Value, OUT PULONG Length)
OUT PULONG Length) {
{ PCELL_DATA Buffer;
PCELL_DATA Buffer; BOOLEAN BufferAllocated;
BOOLEAN BufferAllocated; HCELL_INDEX CellToRelease;
HCELL_INDEX CellToRelease; PAGED_CODE();
PAGED_CODE();
/* Sanity check */
/* Sanity check */ ASSERT(Hive->ReleaseCellRoutine == NULL);
ASSERT(Hive->ReleaseCellRoutine == NULL);
/* Get the actual data */
/* Get the actual data */ if (!CmpGetValueData(Hive,
if (!CmpGetValueData(Hive, Value,
Value, Length,
Length, (PVOID)&Buffer,
(PVOID)&Buffer, &BufferAllocated,
&BufferAllocated, &CellToRelease))
&CellToRelease)) {
{ /* We failed */
/* We failed */ ASSERT(BufferAllocated == FALSE);
ASSERT(BufferAllocated == FALSE); ASSERT(Buffer == NULL);
ASSERT(Buffer == NULL); return NULL;
return NULL; }
}
/* This should never happen!*/
/* This should never happen!*/ if (BufferAllocated)
if (BufferAllocated) {
{ /* Free the buffer and bugcheck */
/* Free the buffer and bugcheck */ ExFreePool(Buffer);
ExFreePool(Buffer); KEBUGCHECKEX(REGISTRY_ERROR, 8, 0, (ULONG_PTR)Hive, (ULONG_PTR)Value);
KEBUGCHECKEX(REGISTRY_ERROR, 8, 0, (ULONG_PTR)Hive, (ULONG_PTR)Value); }
}
/* Otherwise, return the cell data */
/* Otherwise, return the cell data */ return Buffer;
return Buffer; }
}
NTSTATUS
NTSTATUS NTAPI
NTAPI CmpAddValueToList(IN PHHIVE Hive,
CmpAddValueToList(IN PHHIVE Hive, IN HCELL_INDEX ValueCell,
IN HCELL_INDEX ValueCell, IN ULONG Index,
IN ULONG Index, IN ULONG Type,
IN ULONG Type, IN OUT PCHILD_LIST ChildList)
IN OUT PCHILD_LIST ChildList) {
{ HCELL_INDEX ListCell;
HCELL_INDEX ListCell; ULONG ChildCount, Length, i;
ULONG ChildCount, Length, i; PCELL_DATA CellData;
PCELL_DATA CellData; PAGED_CODE();
PAGED_CODE();
/* Sanity check */
/* Sanity check */ ASSERT((((LONG)Index) >= 0) && (Index <= ChildList->Count));
ASSERT((((LONG)Index) >= 0) && (Index <= ChildList->Count));
/* Get the number of entries in the child list */
/* Get the number of entries in the child list */ ChildCount = ChildList->Count;
ChildCount = ChildList->Count; ChildCount++;
ChildCount++; if (ChildCount > 1)
if (ChildCount > 1) {
{ /* The cell should be dirty at this point */
/* The cell should be dirty at this point */ ASSERT(HvIsCellDirty(Hive, ChildList->List));
ASSERT(HvIsCellDirty(Hive, ChildList->List));
/* Check if we have less then 100 children */
/* Check if we have less then 100 children */ if (ChildCount < 100)
if (ChildCount < 100) {
{ /* Allocate just enough as requested */
/* Allocate just enough as requested */ Length = ChildCount * sizeof(HCELL_INDEX);
Length = ChildCount * sizeof(HCELL_INDEX); }
} else
else {
{ /* Otherwise, we have quite a few, so allocate a batch */
/* Otherwise, we have quite a few, so allocate a batch */ Length = ROUND_UP(ChildCount, 100) * sizeof(HCELL_INDEX);
Length = ROUND_UP(ChildCount, 100) * sizeof(HCELL_INDEX); if (Length > HBLOCK_SIZE)
if (Length > HBLOCK_SIZE) {
{ /* But make sure we don't allocate beyond our block size */
/* But make sure we don't allocate beyond our block size */ Length = ROUND_UP(Length, HBLOCK_SIZE);
Length = ROUND_UP(Length, HBLOCK_SIZE); }
} }
}
/* Perform the allocation */
/* Perform the allocation */ ListCell = HvReallocateCell(Hive, ChildList->List, Length);
ListCell = HvReallocateCell(Hive, ChildList->List, Length); }
} else
else {
{ /* This is our first child, so allocate a single cell */
/* This is our first child, so allocate a single cell */ ListCell = HvAllocateCell(Hive, sizeof(HCELL_INDEX), Type, HCELL_NIL);
ListCell = HvAllocateCell(Hive, sizeof(HCELL_INDEX), Type, HCELL_NIL); }
}
/* Fail if we couldn't get a cell */
/* Fail if we couldn't get a cell */ if (ListCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
if (ListCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
/* Set this cell as the child list's list cell */
/* Set this cell as the child list's list cell */ ChildList->List = ListCell;
ChildList->List = ListCell;
/* Get the actual key list memory */
/* Get the actual key list memory */ CellData = HvGetCell(Hive, ListCell);
CellData = HvGetCell(Hive, ListCell); ASSERT(CellData != NULL);
ASSERT(CellData != NULL);
/* Loop all the children */
/* Loop all the children */ for (i = ChildCount - 1; i > Index; i--)
for (i = ChildCount - 1; i > Index; i--) {
{ /* Move them all down */
/* Move them all down */ CellData->u.KeyList[i] = CellData->u.KeyList[i - 1];
CellData->u.KeyList[i] = CellData->u.KeyList[i - 1]; }
}
/* Insert us on top now */
/* Insert us on top now */ CellData->u.KeyList[Index] = ValueCell;
CellData->u.KeyList[Index] = ValueCell; ChildList->Count = ChildCount;
ChildList->Count = ChildCount;
/* Release the list cell and make sure the value cell is dirty */
/* Release the list cell and make sure the value cell is dirty */ HvReleaseCell(Hive, ListCell);
HvReleaseCell(Hive, ListCell); ASSERT(HvIsCellDirty(Hive, ValueCell));
ASSERT(HvIsCellDirty(Hive, ValueCell));
/* We're done here */
/* We're done here */ return STATUS_SUCCESS;
return STATUS_SUCCESS; }
}
NTSTATUS
NTSTATUS NTAPI
NTAPI CmpSetValueDataNew(IN PHHIVE Hive,
CmpSetValueDataNew(IN PHHIVE Hive, IN PVOID Data,
IN PVOID Data, IN ULONG DataSize,
IN ULONG DataSize, IN ULONG StorageType,
IN ULONG StorageType, IN HCELL_INDEX ValueCell,
IN HCELL_INDEX ValueCell, OUT PHCELL_INDEX DataCell)
OUT PHCELL_INDEX DataCell) {
{ PCELL_DATA CellData;
PCELL_DATA CellData; PAGED_CODE();
PAGED_CODE(); ASSERT(DataSize > CM_KEY_VALUE_SMALL);
ASSERT(DataSize > CM_KEY_VALUE_SMALL);
/* Check if this is a big key */
/* Check if this is a big key */ ASSERT_VALUE_BIG(Hive, DataSize);
ASSERT_VALUE_BIG(Hive, DataSize);
/* Allocate a data cell */
/* Allocate a data cell */ *DataCell = HvAllocateCell(Hive, DataSize, StorageType, HCELL_NIL);
*DataCell = HvAllocateCell(Hive, DataSize, StorageType, HCELL_NIL); if (*DataCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
if (*DataCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
/* Get the actual data */
/* Get the actual data */ CellData = HvGetCell(Hive, *DataCell);
CellData = HvGetCell(Hive, *DataCell); if (!CellData) ASSERT(FALSE);
if (!CellData) ASSERT(FALSE);
/* Copy our buffer into it */
/* Copy our buffer into it */ RtlCopyMemory(CellData, Data, DataSize);
RtlCopyMemory(CellData, Data, DataSize);
/* All done */
/* All done */ return STATUS_SUCCESS;
return STATUS_SUCCESS; }
}
NTSTATUS
NTSTATUS NTAPI
NTAPI CmpRemoveValueFromList(IN PHHIVE Hive,
CmpRemoveValueFromList(IN PHHIVE Hive, IN ULONG Index,
IN ULONG Index, IN OUT PCHILD_LIST ChildList)
IN OUT PCHILD_LIST ChildList) {
{ ULONG Count;
ULONG Count; PCELL_DATA CellData;
PCELL_DATA CellData; HCELL_INDEX NewCell;
HCELL_INDEX NewCell; PAGED_CODE();
PAGED_CODE();
/* Sanity check */
/* Sanity check */ ASSERT((((LONG)Index) >= 0) && (Index <= ChildList->Count));
ASSERT((((LONG)Index) >= 0) && (Index <= ChildList->Count));
/* Get the new count after removal */
/* Get the new count after removal */ Count = ChildList->Count - 1;
Count = ChildList->Count - 1; if (Count > 0)
if (Count > 0) {
{ /* Get the actual list array */
/* Get the actual list array */ CellData = HvGetCell(Hive, ChildList->List);
CellData = HvGetCell(Hive, ChildList->List); if (!CellData) return STATUS_INSUFFICIENT_RESOURCES;
if (!CellData) return STATUS_INSUFFICIENT_RESOURCES;
/* Make sure cells data have been made dirty */
/* Make sure cells data have been made dirty */ ASSERT(HvIsCellDirty(Hive, ChildList->List));
ASSERT(HvIsCellDirty(Hive, ChildList->List)); ASSERT(HvIsCellDirty(Hive, CellData->u.KeyList[Index]));
ASSERT(HvIsCellDirty(Hive, CellData->u.KeyList[Index]));
/* Loop the list */
/* Loop the list */ while (Index < Count)
while (Index < Count) {
{ /* Move everything up */
/* Move everything up */ CellData->u.KeyList[Index] = CellData->u.KeyList[Index + 1];
CellData->u.KeyList[Index] = CellData->u.KeyList[Index + 1]; Index++;
Index++; }
}
/* Re-allocate the cell for the list by decreasing the count */
/* Re-allocate the cell for the list by decreasing the count */ NewCell = HvReallocateCell(Hive,
NewCell = HvReallocateCell(Hive, ChildList->List,
ChildList->List, Count * sizeof(HCELL_INDEX));
Count * sizeof(HCELL_INDEX)); ASSERT(NewCell != HCELL_NIL);
ASSERT(NewCell != HCELL_NIL); HvReleaseCell(Hive,ChildList->List);
HvReleaseCell(Hive,ChildList->List);
/* Update the list cell */
/* Update the list cell */ ChildList->List = NewCell;
ChildList->List = NewCell; }
} else
else {
{ /* Otherwise, we were the last entry, so free the list entirely */
/* Otherwise, we were the last entry, so free the list entirely */ HvFreeCell(Hive, ChildList->List);
HvFreeCell(Hive, ChildList->List); ChildList->List = HCELL_NIL;
ChildList->List = HCELL_NIL; }
}
/* Update the child list with the new count */
/* Update the child list with the new count */ ChildList->Count = Count;
ChildList->Count = Count; return STATUS_SUCCESS;
return STATUS_SUCCESS; }
}

View file

@ -1,159 +1,158 @@
/* /*
* PROJECT: ReactOS Kernel * PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmwraprs.c * FILE: ntoskrnl/config/cmwraprs.c
* PURPOSE: Configuration Manager - Wrappers for Hive Operations * PURPOSE: Configuration Manager - Wrappers for Hive Operations
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
#include "ntoskrnl.h" #include "ntoskrnl.h"
#include "cm.h" #define NDEBUG
#define NDEBUG #include "debug.h"
#include "debug.h"
/* FUNCTIONS *****************************************************************/
/* FUNCTIONS *****************************************************************/
NTSTATUS
NTSTATUS NTAPI
NTAPI CmpCreateEvent(IN EVENT_TYPE EventType,
CmpCreateEvent(IN EVENT_TYPE EventType, OUT PHANDLE EventHandle,
OUT PHANDLE EventHandle, OUT PKEVENT *Event)
OUT PKEVENT *Event) {
{ NTSTATUS Status;
NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes;
OBJECT_ATTRIBUTES ObjectAttributes;
/* Create the event */
/* Create the event */ InitializeObjectAttributes(&ObjectAttributes,
InitializeObjectAttributes(&ObjectAttributes, NULL,
NULL, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL,
NULL, NULL);
NULL); Status = ZwCreateEvent(EventHandle,
Status = ZwCreateEvent(EventHandle, EVENT_ALL_ACCESS,
EVENT_ALL_ACCESS, &ObjectAttributes,
&ObjectAttributes, EventType,
EventType, FALSE);
FALSE); if (!NT_SUCCESS(Status)) return Status;
if (!NT_SUCCESS(Status)) return Status;
/* Get a pointer to the object itself */
/* Get a pointer to the object itself */ Status = ObReferenceObjectByHandle(*EventHandle,
Status = ObReferenceObjectByHandle(*EventHandle, EVENT_ALL_ACCESS,
EVENT_ALL_ACCESS, NULL,
NULL, KernelMode,
KernelMode, (PVOID*)Event,
(PVOID*)Event, NULL);
NULL); if (!NT_SUCCESS(Status)) ZwClose(*EventHandle);
if (!NT_SUCCESS(Status)) ZwClose(*EventHandle);
/* Return status */
/* Return status */ return Status;
return Status; }
}
PVOID
PVOID NTAPI
NTAPI CmpAllocate(IN ULONG Size,
CmpAllocate(IN ULONG Size, IN BOOLEAN Paged,
IN BOOLEAN Paged, IN ULONG Tag)
IN ULONG Tag) {
{ return ExAllocatePoolWithTag(Paged ? PagedPool : NonPagedPool,
return ExAllocatePoolWithTag(Paged ? PagedPool : NonPagedPool, Size,
Size, Tag);
Tag); }
}
VOID
VOID NTAPI
NTAPI CmpFree(IN PVOID Ptr,
CmpFree(IN PVOID Ptr, IN ULONG Quota)
IN ULONG Quota) {
{ ExFreePool(Ptr);
ExFreePool(Ptr); }
}
BOOLEAN
BOOLEAN NTAPI
NTAPI CmpFileRead(IN PHHIVE RegistryHive,
CmpFileRead(IN PHHIVE RegistryHive, IN ULONG FileType,
IN ULONG FileType, IN PULONG FileOffset,
IN PULONG FileOffset, OUT PVOID Buffer,
OUT PVOID Buffer, IN SIZE_T BufferLength)
IN SIZE_T BufferLength) {
{ PCMHIVE CmHive = (PCMHIVE)RegistryHive;
PCMHIVE CmHive = (PCMHIVE)RegistryHive; HANDLE HiveHandle = CmHive->FileHandles[FileType];
HANDLE HiveHandle = CmHive->FileHandles[FileType]; LARGE_INTEGER _FileOffset;
LARGE_INTEGER _FileOffset; IO_STATUS_BLOCK IoStatusBlock;
IO_STATUS_BLOCK IoStatusBlock; NTSTATUS Status;
NTSTATUS Status;
_FileOffset.QuadPart = *FileOffset;
_FileOffset.QuadPart = *FileOffset; Status = ZwReadFile(HiveHandle, 0, 0, 0, &IoStatusBlock,
Status = ZwReadFile(HiveHandle, 0, 0, 0, &IoStatusBlock, Buffer, BufferLength, &_FileOffset, 0);
Buffer, BufferLength, &_FileOffset, 0); return NT_SUCCESS(Status) ? TRUE : FALSE;
return NT_SUCCESS(Status) ? TRUE : FALSE; }
}
BOOLEAN
BOOLEAN NTAPI
NTAPI CmpFileWrite(IN PHHIVE RegistryHive,
CmpFileWrite(IN PHHIVE RegistryHive, IN ULONG FileType,
IN ULONG FileType, IN PULONG FileOffset,
IN PULONG FileOffset, IN PVOID Buffer,
IN PVOID Buffer, IN SIZE_T BufferLength)
IN SIZE_T BufferLength) {
{ PCMHIVE CmHive = (PCMHIVE)RegistryHive;
PCMHIVE CmHive = (PCMHIVE)RegistryHive; HANDLE HiveHandle = CmHive->FileHandles[FileType];
HANDLE HiveHandle = CmHive->FileHandles[FileType]; LARGE_INTEGER _FileOffset;
LARGE_INTEGER _FileOffset; IO_STATUS_BLOCK IoStatusBlock;
IO_STATUS_BLOCK IoStatusBlock; NTSTATUS Status;
NTSTATUS Status;
_FileOffset.QuadPart = *FileOffset;
_FileOffset.QuadPart = *FileOffset; Status = ZwWriteFile(HiveHandle, 0, 0, 0, &IoStatusBlock,
Status = ZwWriteFile(HiveHandle, 0, 0, 0, &IoStatusBlock, Buffer, BufferLength, &_FileOffset, 0);
Buffer, BufferLength, &_FileOffset, 0); return NT_SUCCESS(Status) ? TRUE : FALSE;
return NT_SUCCESS(Status) ? TRUE : FALSE; }
}
BOOLEAN
BOOLEAN NTAPI
NTAPI CmpFileSetSize(IN PHHIVE RegistryHive,
CmpFileSetSize(IN PHHIVE RegistryHive, IN ULONG FileType,
IN ULONG FileType, IN ULONG FileSize,
IN ULONG FileSize, IN ULONG OldFileSize)
IN ULONG OldFileSize) {
{ PCMHIVE CmHive = (PCMHIVE)RegistryHive;
PCMHIVE CmHive = (PCMHIVE)RegistryHive; HANDLE HiveHandle = CmHive->FileHandles[FileType];
HANDLE HiveHandle = CmHive->FileHandles[FileType]; FILE_END_OF_FILE_INFORMATION EndOfFileInfo;
FILE_END_OF_FILE_INFORMATION EndOfFileInfo; FILE_ALLOCATION_INFORMATION FileAllocationInfo;
FILE_ALLOCATION_INFORMATION FileAllocationInfo; IO_STATUS_BLOCK IoStatusBlock;
IO_STATUS_BLOCK IoStatusBlock; NTSTATUS Status;
NTSTATUS Status;
EndOfFileInfo.EndOfFile.QuadPart = FileSize;
EndOfFileInfo.EndOfFile.QuadPart = FileSize; Status = ZwSetInformationFile(HiveHandle,
Status = ZwSetInformationFile(HiveHandle, &IoStatusBlock,
&IoStatusBlock, &EndOfFileInfo,
&EndOfFileInfo, sizeof(FILE_END_OF_FILE_INFORMATION),
sizeof(FILE_END_OF_FILE_INFORMATION), FileEndOfFileInformation);
FileEndOfFileInformation); if (!NT_SUCCESS(Status)) return FALSE;
if (!NT_SUCCESS(Status)) return FALSE;
FileAllocationInfo.AllocationSize.QuadPart = FileSize;
FileAllocationInfo.AllocationSize.QuadPart = FileSize; Status = ZwSetInformationFile(HiveHandle,
Status = ZwSetInformationFile(HiveHandle, &IoStatusBlock,
&IoStatusBlock, &FileAllocationInfo,
&FileAllocationInfo, sizeof(FILE_ALLOCATION_INFORMATION),
sizeof(FILE_ALLOCATION_INFORMATION), FileAllocationInformation);
FileAllocationInformation); if (!NT_SUCCESS(Status)) return FALSE;
if (!NT_SUCCESS(Status)) return FALSE;
return TRUE;
return TRUE; }
}
BOOLEAN
BOOLEAN NTAPI
NTAPI CmpFileFlush(IN PHHIVE RegistryHive,
CmpFileFlush(IN PHHIVE RegistryHive, IN ULONG FileType,
IN ULONG FileType, IN OUT PLARGE_INTEGER FileOffset,
IN OUT PLARGE_INTEGER FileOffset, IN ULONG Length)
IN ULONG Length) {
{ PCMHIVE CmHive = (PCMHIVE)RegistryHive;
PCMHIVE CmHive = (PCMHIVE)RegistryHive; HANDLE HiveHandle = CmHive->FileHandles[FileType];
HANDLE HiveHandle = CmHive->FileHandles[FileType]; IO_STATUS_BLOCK IoStatusBlock;
IO_STATUS_BLOCK IoStatusBlock; NTSTATUS Status;
NTSTATUS Status;
Status = ZwFlushBuffersFile(HiveHandle, &IoStatusBlock);
Status = ZwFlushBuffersFile(HiveHandle, &IoStatusBlock); return NT_SUCCESS(Status) ? TRUE : FALSE;
return NT_SUCCESS(Status) ? TRUE : FALSE; }
}

File diff suppressed because it is too large Load diff

View file

@ -9,7 +9,6 @@
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
#include "ntoskrnl.h" #include "ntoskrnl.h"
#include "cm.h"
#define NDEBUG #define NDEBUG
#include "debug.h" #include "debug.h"
@ -18,7 +17,6 @@ BOOLEAN CmFirstTime = TRUE;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
#if 0
NTSTATUS NTSTATUS
NTAPI NTAPI
NtCreateKey(OUT PHANDLE KeyHandle, NtCreateKey(OUT PHANDLE KeyHandle,
@ -32,7 +30,9 @@ NtCreateKey(OUT PHANDLE KeyHandle,
NTSTATUS Status; NTSTATUS Status;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
CM_PARSE_CONTEXT ParseContext = {0}; CM_PARSE_CONTEXT ParseContext = {0};
HANDLE Handle;
PAGED_CODE(); PAGED_CODE();
DPRINT("NtCreateKey(OB 0x%wZ)\n", ObjectAttributes->ObjectName);
/* Setup the parse context */ /* Setup the parse context */
ParseContext.CreateOperation = TRUE; ParseContext.CreateOperation = TRUE;
@ -46,13 +46,13 @@ NtCreateKey(OUT PHANDLE KeyHandle,
NULL, NULL,
DesiredAccess, DesiredAccess,
&ParseContext, &ParseContext,
KeyHandle); &Handle);
if (NT_SUCCESS(Status)) *KeyHandle = Handle;
/* Return data to user */ /* Return data to user */
if (Disposition) *Disposition = ParseContext.Disposition; if (Disposition) *Disposition = ParseContext.Disposition;
return Status; return Status;
} }
#endif
NTSTATUS NTSTATUS
NTAPI NTAPI
@ -61,18 +61,26 @@ NtOpenKey(OUT PHANDLE KeyHandle,
IN POBJECT_ATTRIBUTES ObjectAttributes) IN POBJECT_ATTRIBUTES ObjectAttributes)
{ {
CM_PARSE_CONTEXT ParseContext = {0}; CM_PARSE_CONTEXT ParseContext = {0};
HANDLE Handle;
NTSTATUS Status;
PAGED_CODE(); PAGED_CODE();
DPRINT("NtOpenKey(OB 0x%wZ)\n", ObjectAttributes->ObjectName);
/* Just let the object manager handle this */ /* Just let the object manager handle this */
return ObOpenObjectByName(ObjectAttributes, Status = ObOpenObjectByName(ObjectAttributes,
CmpKeyObjectType, CmpKeyObjectType,
ExGetPreviousMode(), ExGetPreviousMode(),
NULL, NULL,
DesiredAccess, DesiredAccess,
&ParseContext, &ParseContext,
KeyHandle); &Handle);
if (NT_SUCCESS(Status)) *KeyHandle = Handle;
/* Return status */
return Status;
} }
NTSTATUS NTSTATUS
NTAPI NTAPI
NtDeleteKey(IN HANDLE KeyHandle) NtDeleteKey(IN HANDLE KeyHandle)

File diff suppressed because it is too large Load diff

View file

@ -12,7 +12,6 @@
#include <ntoskrnl.h> #include <ntoskrnl.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#include "ntoskrnl/cm/cm.h"
#include "ntstrsafe.h" #include "ntstrsafe.h"
typedef struct _INIT_BUFFER typedef struct _INIT_BUFFER

View file

@ -1,248 +1,248 @@
/* /*
* PROJECT: ReactOS Kernel * PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/cm/cm_x.h * FILE: ntoskrnl/cm/cm_x.h
* PURPOSE: Inlined Functions for the Configuration Manager * PURPOSE: Inlined Functions for the Configuration Manager
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/ */
// //
// Returns whether or not this is a small valued key // Returns whether or not this is a small valued key
// //
BOOLEAN BOOLEAN
FORCEINLINE FORCEINLINE
CmpIsKeyValueSmall(OUT PULONG RealLength, CmpIsKeyValueSmall(OUT PULONG RealLength,
IN ULONG Length) IN ULONG Length)
{ {
/* Check if the length has the special size value */ /* Check if the length has the special size value */
if (Length >= CM_KEY_VALUE_SPECIAL_SIZE) if (Length >= CM_KEY_VALUE_SPECIAL_SIZE)
{ {
/* It does, so this is a small key: return the real length */ /* It does, so this is a small key: return the real length */
*RealLength = Length - CM_KEY_VALUE_SPECIAL_SIZE; *RealLength = Length - CM_KEY_VALUE_SPECIAL_SIZE;
return TRUE; return TRUE;
} }
/* This is not a small key, return the length we read */ /* This is not a small key, return the length we read */
*RealLength = Length; *RealLength = Length;
return FALSE; return FALSE;
} }
// //
// Returns whether or not this is a big valued key // Returns whether or not this is a big valued key
// //
BOOLEAN BOOLEAN
FORCEINLINE FORCEINLINE
CmpIsKeyValueBig(IN PHHIVE Hive, CmpIsKeyValueBig(IN PHHIVE Hive,
IN ULONG Length) IN ULONG Length)
{ {
/* Check if the hive is XP Beta 1 or newer */ /* Check if the hive is XP Beta 1 or newer */
if (Hive->Version >= HSYS_WHISTLER_BETA1) if (Hive->Version >= HSYS_WHISTLER_BETA1)
{ {
/* Check if the key length is valid for a big value key */ /* Check if the key length is valid for a big value key */
if ((Length < CM_KEY_VALUE_SPECIAL_SIZE) && (Length > CM_KEY_VALUE_BIG)) if ((Length < CM_KEY_VALUE_SPECIAL_SIZE) && (Length > CM_KEY_VALUE_BIG))
{ {
/* Yes, this value is big */ /* Yes, this value is big */
return TRUE; return TRUE;
} }
} }
/* Not a big value key */ /* Not a big value key */
return FALSE; return FALSE;
} }
// //
// Returns the hashkey corresponding to a convkey // Returns the hashkey corresponding to a convkey
// //
#define GET_HASH_KEY(ConvKey) \ #define GET_HASH_KEY(ConvKey) \
((CMP_HASH_IRRATIONAL * (ConvKey)) % CMP_HASH_PRIME) ((CMP_HASH_IRRATIONAL * (ConvKey)) % CMP_HASH_PRIME)
// //
// Returns the index into the hash table, or the entry itself // Returns the index into the hash table, or the entry itself
// //
#define GET_HASH_INDEX(ConvKey) \ #define GET_HASH_INDEX(ConvKey) \
GET_HASH_KEY(ConvKey) % CmpHashTableSize GET_HASH_KEY(ConvKey) % CmpHashTableSize
#define GET_HASH_ENTRY(Table, ConvKey) \ #define GET_HASH_ENTRY(Table, ConvKey) \
(Table[GET_HASH_INDEX(ConvKey)]) (Table[GET_HASH_INDEX(ConvKey)])
// //
// Returns whether or not the cell is cached // Returns whether or not the cell is cached
// //
#define CMP_IS_CELL_CACHED(c) \ #define CMP_IS_CELL_CACHED(c) \
(((c) & HCELL_CACHED) && ((c) != HCELL_NIL)) (((c) & HCELL_CACHED) && ((c) != HCELL_NIL))
// //
// Return data from a cached cell // Return data from a cached cell
// //
#define CMP_GET_CACHED_CELL(c) \ #define CMP_GET_CACHED_CELL(c) \
(ULONG_PTR)((c) & ~HCELL_CACHED) (ULONG_PTR)((c) & ~HCELL_CACHED)
#define CMP_GET_CACHED_DATA(c) \ #define CMP_GET_CACHED_DATA(c) \
(&(((PCM_CACHED_VALUE_INDEX)(CMP_GET_CACHED_CELL(c)))->Data.CellData)) (&(((PCM_CACHED_VALUE_INDEX)(CMP_GET_CACHED_CELL(c)))->Data.CellData))
#define CMP_GET_CACHED_INDEX(c) \ #define CMP_GET_CACHED_INDEX(c) \
(&(((PCM_CACHED_ENTRY)(CMP_GET_CACHED_CELL(c)))->CellIndex)) (&(((PCM_CACHED_ENTRY)(CMP_GET_CACHED_CELL(c)))->CellIndex))
#define CMP_GET_CACHED_VALUE(c) \ #define CMP_GET_CACHED_VALUE(c) \
(&(((PCM_CACHED_VALUE)(CMP_GET_CACHED_CELL(c)))->KeyValue)) (&(((PCM_CACHED_VALUE)(CMP_GET_CACHED_CELL(c)))->KeyValue))
// //
// Makes sure that the registry is locked // Makes sure that the registry is locked
// //
#define CMP_ASSERT_REGISTRY_LOCK() \ #define CMP_ASSERT_REGISTRY_LOCK() \
ASSERT((CmpSpecialBootCondition == TRUE) || \ ASSERT((CmpSpecialBootCondition == TRUE) || \
(CmpTestRegistryLock() == TRUE)) (CmpTestRegistryLock() == TRUE))
// //
// Makes sure that the registry is exclusively locked // Makes sure that the registry is exclusively locked
// //
#define CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK() \ #define CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK() \
ASSERT((CmpSpecialBootCondition == TRUE) || \ ASSERT((CmpSpecialBootCondition == TRUE) || \
(CmpTestRegistryLockExclusive() == TRUE)) (CmpTestRegistryLockExclusive() == TRUE))
// //
// Checks if a KCB is exclusively locked // Checks if a KCB is exclusively locked
// //
#define CmpIsKcbLockedExclusive(k) \ #define CmpIsKcbLockedExclusive(k) \
(GET_HASH_ENTRY(CmpCacheTable, \ (GET_HASH_ENTRY(CmpCacheTable, \
(k)->ConvKey).Owner == KeGetCurrentThread()) (k)->ConvKey).Owner == KeGetCurrentThread())
// //
// Exclusively acquires a KCB // Exclusively acquires a KCB
// //
#define CmpAcquireKcbLockExclusive(k) \ #define CmpAcquireKcbLockExclusive(k) \
{ \ { \
ExAcquirePushLockExclusive(&GET_HASH_ENTRY(CmpCacheTable, \ ExAcquirePushLockExclusive(&GET_HASH_ENTRY(CmpCacheTable, \
(k)->ConvKey).Lock); \ (k)->ConvKey).Lock); \
GET_HASH_ENTRY(CmpCacheTable, \ GET_HASH_ENTRY(CmpCacheTable, \
(k)->ConvKey).Owner = KeGetCurrentThread(); \ (k)->ConvKey).Owner = KeGetCurrentThread(); \
} }
// //
// Exclusively acquires a KCB by index // Exclusively acquires a KCB by index
// //
#define CmpAcquireKcbLockExclusiveByIndex(i) \ #define CmpAcquireKcbLockExclusiveByIndex(i) \
{ \ { \
ExAcquirePushLockExclusive(&CmpCacheTable[(i)].Lock); \ ExAcquirePushLockExclusive(&CmpCacheTable[(i)].Lock); \
CmpCacheTable[(i)].Owner = KeGetCurrentThread(); \ CmpCacheTable[(i)].Owner = KeGetCurrentThread(); \
} }
// //
// Exclusively acquires a KCB by key // Exclusively acquires a KCB by key
// //
#define CmpAcquireKcbLockExclusiveByKey(k) \ #define CmpAcquireKcbLockExclusiveByKey(k) \
{ \ { \
ExAcquirePushLockExclusive(&GET_HASH_ENTRY(CmpCacheTable, \ ExAcquirePushLockExclusive(&GET_HASH_ENTRY(CmpCacheTable, \
(k)).Lock); \ (k)).Lock); \
GET_HASH_ENTRY(CmpCacheTable, \ GET_HASH_ENTRY(CmpCacheTable, \
(k)).Owner = KeGetCurrentThread(); \ (k)).Owner = KeGetCurrentThread(); \
} }
// //
// Shared acquires a KCB // Shared acquires a KCB
// //
#define CmpAcquireKcbLockShared(k) \ #define CmpAcquireKcbLockShared(k) \
{ \ { \
ExAcquirePushLockShared(&GET_HASH_ENTRY(CmpCacheTable, \ ExAcquirePushLockShared(&GET_HASH_ENTRY(CmpCacheTable, \
(k)->ConvKey).Lock); \ (k)->ConvKey).Lock); \
} }
// //
// Shared acquires a KCB by index // Shared acquires a KCB by index
// //
#define CmpAcquireKcbLockSharedByIndex(i) \ #define CmpAcquireKcbLockSharedByIndex(i) \
{ \ { \
ExAcquirePushLockShared(&CmpCacheTable[(i)].Lock); \ ExAcquirePushLockShared(&CmpCacheTable[(i)].Lock); \
} }
// //
// Tries to convert a KCB lock // Tries to convert a KCB lock
// //
FORCEINLINE FORCEINLINE
BOOLEAN BOOLEAN
CmpTryToConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k) CmpTryToConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
{ {
ASSERT(CmpIsKcbLockedExclusive(k) == FALSE); ASSERT(CmpIsKcbLockedExclusive(k) == FALSE);
if (ExConvertPushLockSharedToExclusive( if (ExConvertPushLockSharedToExclusive(
&GET_HASH_ENTRY(CmpCacheTable, k->ConvKey).Lock)) &GET_HASH_ENTRY(CmpCacheTable, k->ConvKey).Lock))
{ {
GET_HASH_ENTRY(CmpCacheTable, GET_HASH_ENTRY(CmpCacheTable,
k->ConvKey).Owner = KeGetCurrentThread(); k->ConvKey).Owner = KeGetCurrentThread();
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
} }
// //
// Releases an exlusively or shared acquired KCB // Releases an exlusively or shared acquired KCB
// //
#define CmpReleaseKcbLock(k) \ #define CmpReleaseKcbLock(k) \
{ \ { \
GET_HASH_ENTRY(CmpCacheTable, (k)->ConvKey).Owner = NULL; \ GET_HASH_ENTRY(CmpCacheTable, (k)->ConvKey).Owner = NULL; \
ExReleasePushLock(&GET_HASH_ENTRY(CmpCacheTable, \ ExReleasePushLock(&GET_HASH_ENTRY(CmpCacheTable, \
(k)->ConvKey).Lock); \ (k)->ConvKey).Lock); \
} }
// //
// Releases an exlusively or shared acquired KCB by index // Releases an exlusively or shared acquired KCB by index
// //
#define CmpReleaseKcbLockByIndex(i) \ #define CmpReleaseKcbLockByIndex(i) \
{ \ { \
CmpCacheTable[(i)].Owner = NULL; \ CmpCacheTable[(i)].Owner = NULL; \
ExReleasePushLock(&CmpCacheTable[(i)].Lock); \ ExReleasePushLock(&CmpCacheTable[(i)].Lock); \
} }
// //
// Releases an exlusively or shared acquired KCB by key // Releases an exlusively or shared acquired KCB by key
// //
#define CmpReleaseKcbLockByKey(k) \ #define CmpReleaseKcbLockByKey(k) \
{ \ { \
GET_HASH_ENTRY(CmpCacheTable, (k)).Owner = NULL; \ GET_HASH_ENTRY(CmpCacheTable, (k)).Owner = NULL; \
ExReleasePushLock(&GET_HASH_ENTRY(CmpCacheTable, \ ExReleasePushLock(&GET_HASH_ENTRY(CmpCacheTable, \
(k)).Lock); \ (k)).Lock); \
} }
// //
// Converts a KCB lock // Converts a KCB lock
// //
FORCEINLINE FORCEINLINE
VOID VOID
CmpConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k) CmpConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
{ {
ASSERT(CmpIsKcbLockedExclusive(k) == FALSE); ASSERT(CmpIsKcbLockedExclusive(k) == FALSE);
CmpReleaseKcbLock(k); CmpReleaseKcbLock(k);
CmpAcquireKcbLockExclusive(k); CmpAcquireKcbLockExclusive(k);
} }
// //
// Exclusively acquires an NCB // Exclusively acquires an NCB
// //
#define CmpAcquireNcbLockExclusive(n) \ #define CmpAcquireNcbLockExclusive(n) \
{ \ { \
ExAcquirePushLockExclusive(&GET_HASH_ENTRY(CmpNameCacheTable, \ ExAcquirePushLockExclusive(&GET_HASH_ENTRY(CmpNameCacheTable, \
(n)->ConvKey).Lock); \ (n)->ConvKey).Lock); \
} }
// //
// Exclusively acquires an NCB by key // Exclusively acquires an NCB by key
// //
#define CmpAcquireNcbLockExclusiveByKey(k) \ #define CmpAcquireNcbLockExclusiveByKey(k) \
{ \ { \
ExAcquirePushLockExclusive(&GET_HASH_ENTRY(CmpNameCacheTable, \ ExAcquirePushLockExclusive(&GET_HASH_ENTRY(CmpNameCacheTable, \
(k)).Lock); \ (k)).Lock); \
} }
// //
// Releases an exlusively or shared acquired NCB // Releases an exlusively or shared acquired NCB
// //
#define CmpReleaseNcbLock(k) \ #define CmpReleaseNcbLock(k) \
{ \ { \
ExReleasePushLock(&GET_HASH_ENTRY(CmpNameCacheTable, \ ExReleasePushLock(&GET_HASH_ENTRY(CmpNameCacheTable, \
(k)->ConvKey).Lock); \ (k)->ConvKey).Lock); \
} }
// //
// Releases an exlusively or shared acquired NCB by key // Releases an exlusively or shared acquired NCB by key
// //
#define CmpReleaseNcbLockByKey(k) \ #define CmpReleaseNcbLockByKey(k) \
{ \ { \
ExReleasePushLock(&GET_HASH_ENTRY(CmpNameCacheTable, \ ExReleasePushLock(&GET_HASH_ENTRY(CmpNameCacheTable, \
(k)).Lock); \ (k)).Lock); \
} }

View file

@ -30,6 +30,7 @@
#include "ob.h" #include "ob.h"
#include "mm.h" #include "mm.h"
#include "ex.h" #include "ex.h"
#include "cm.h"
#include "ps.h" #include "ps.h"
#include "cc.h" #include "cc.h"
#include "io.h" #include "io.h"

View file

@ -142,12 +142,6 @@
<file>cmwraprs.c</file> <file>cmwraprs.c</file>
<file>ntapi.c</file> <file>ntapi.c</file>
</directory> </directory>
<directory name="cm">
<file>ntfunc.c</file>
<file>regfile.c</file>
<file>registry.c</file>
<file>regobj.c</file>
</directory>
<directory name="dbgk"> <directory name="dbgk">
<file>dbgkutil.c</file> <file>dbgkutil.c</file>
<file>dbgkobj.c</file> <file>dbgkobj.c</file>

View file

@ -138,9 +138,6 @@
<file>cmwraprs.c</file> <file>cmwraprs.c</file>
<file>ntapi.c</file> <file>ntapi.c</file>
</directory> </directory>
<directory name="cm">
<file>regobj.c</file>
</directory>
<directory name="dbgk"> <directory name="dbgk">
<file>dbgkutil.c</file> <file>dbgkutil.c</file>
<file>dbgkobj.c</file> <file>dbgkobj.c</file>