- Start using members inside the KCB instead of the PKEY_OBJECT.

- Remove DummyKcb hacks since we now have a real, valid KCB.
- Get rid of the cm worker thread and related code, this should fix a couple of random registry bugchecks and corruption.
- This is a slow transition to using CM_KEY_BODY and KCB.

svn path=/trunk/; revision=29986
This commit is contained in:
Aleksey Bragin 2007-10-30 20:50:18 +00:00
parent 6a2986170b
commit aa1bc628b3
6 changed files with 64 additions and 258 deletions

View file

@ -149,6 +149,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
KPROCESSOR_MODE PreviousMode; KPROCESSOR_MODE PreviousMode;
UNICODE_STRING CapturedClass = {0}; UNICODE_STRING CapturedClass = {0};
HANDLE hKey; HANDLE hKey;
PCM_KEY_NODE Node, ParentNode;
PAGED_CODE(); PAGED_CODE();
@ -237,7 +238,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
if (RemainingPath.Length == 0) if (RemainingPath.Length == 0)
{ {
/* Fail if the key has been deleted */ /* Fail if the key has been deleted */
if (((PKEY_OBJECT) Object)->Flags & KO_MARKED_FOR_DELETE) if (((PKEY_OBJECT) Object)->KeyControlBlock->Delete)
{ {
PostCreateKeyInfo.Object = NULL; PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL; PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL;
@ -305,8 +306,8 @@ NtCreateKey(OUT PHANDLE KeyHandle,
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE); ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
/* Create the key */ /* Create the key */
Status = CmpDoCreate(&((PKEY_OBJECT)Object)->RegistryHive->Hive, Status = CmpDoCreate(((PKEY_OBJECT)Object)->KeyControlBlock->KeyHive,
((PKEY_OBJECT)Object)->KeyCellOffset, ((PKEY_OBJECT)Object)->KeyControlBlock->KeyCell,
NULL, NULL,
&RemainingPath, &RemainingPath,
KernelMode, KernelMode,
@ -332,10 +333,17 @@ NtCreateKey(OUT PHANDLE KeyHandle,
RtlCreateUnicodeString(&KeyObject->Name, Start); RtlCreateUnicodeString(&KeyObject->Name, Start);
KeyObject->KeyCell->Parent = KeyObject->ParentKey->KeyCellOffset; ParentNode = (PCM_KEY_NODE)HvGetCell(KeyObject->ParentKey->KeyControlBlock->KeyHive,
KeyObject->KeyCell->Security = KeyObject->ParentKey->KeyCell->Security; KeyObject->ParentKey->KeyControlBlock->KeyCell);
KeyObject->ValueCache.ValueList = KeyObject->KeyCell->ValueList.List;
KeyObject->ValueCache.Count = KeyObject->KeyCell->ValueList.Count; Node = (PCM_KEY_NODE)HvGetCell(KeyObject->KeyControlBlock->KeyHive,
KeyObject->KeyControlBlock->KeyCell);
Node->Parent = KeyObject->ParentKey->KeyControlBlock->KeyCell;
Node->Security = ParentNode->Security;
KeyObject->KeyControlBlock->ValueCache.ValueList = Node->ValueList.List;
KeyObject->KeyControlBlock->ValueCache.Count = Node->ValueList.Count;
DPRINT("RemainingPath: %wZ\n", &RemainingPath); DPRINT("RemainingPath: %wZ\n", &RemainingPath);
@ -435,7 +443,7 @@ NtFlushKey(IN HANDLE KeyHandle)
VERIFY_KEY_OBJECT(KeyObject); VERIFY_KEY_OBJECT(KeyObject);
RegistryHive = KeyObject->RegistryHive; RegistryHive = (PCMHIVE)KeyObject->KeyControlBlock->KeyHive;
/* Acquire hive lock */ /* Acquire hive lock */
KeEnterCriticalRegion(); KeEnterCriticalRegion();
@ -576,7 +584,7 @@ NtOpenKey(OUT PHANDLE KeyHandle,
RtlFreeUnicodeString(&RemainingPath); RtlFreeUnicodeString(&RemainingPath);
/* Fail if the key has been deleted */ /* Fail if the key has been deleted */
if (((PKEY_OBJECT)Object)->Flags & KO_MARKED_FOR_DELETE) if (((PKEY_OBJECT)Object)->KeyControlBlock->Delete)
{ {
Status = STATUS_UNSUCCESSFUL; Status = STATUS_UNSUCCESSFUL;
goto openkey_cleanup; goto openkey_cleanup;
@ -708,17 +716,13 @@ NtDeleteKey(IN HANDLE KeyHandle)
Status = CmiCallRegisteredCallbacks(RegNtPreDeleteKey, &DeleteKeyInfo); Status = CmiCallRegisteredCallbacks(RegNtPreDeleteKey, &DeleteKeyInfo);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
/* HACK: Setup the Dummy KCB */
CM_KEY_CONTROL_BLOCK DummyKcb = {0};
DummyKcb.KeyHive = &KeyObject->RegistryHive->Hive;
DummyKcb.KeyCell = KeyObject->KeyCellOffset;
/* Call the internal API */ /* Call the internal API */
Status = CmDeleteKey(&DummyKcb); Status = CmDeleteKey(KeyObject->KeyControlBlock);
/* Remove the keep-alive reference */ /* Remove the keep-alive reference */
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
if (KeyObject->RegistryHive != KeyObject->ParentKey->RegistryHive) if (KeyObject->KeyControlBlock->KeyHive !=
KeyObject->ParentKey->KeyControlBlock->KeyHive)
{ {
/* Dereference again */ /* Dereference again */
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
@ -777,13 +781,8 @@ NtEnumerateKey(IN HANDLE KeyHandle,
Status = CmiCallRegisteredCallbacks(RegNtPreEnumerateKey, &EnumerateKeyInfo); Status = CmiCallRegisteredCallbacks(RegNtPreEnumerateKey, &EnumerateKeyInfo);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
/* HACK: Setup the Dummy KCB */
CM_KEY_CONTROL_BLOCK DummyKcb = {0};
DummyKcb.KeyHive = &KeyObject->RegistryHive->Hive;
DummyKcb.KeyCell = KeyObject->KeyCellOffset;
/* Call the internal API */ /* Call the internal API */
Status = CmEnumerateKey(&DummyKcb, Status = CmEnumerateKey(KeyObject->KeyControlBlock,
Index, Index,
KeyInformationClass, KeyInformationClass,
KeyInformation, KeyInformation,
@ -845,13 +844,8 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
&EnumerateValueKeyInfo); &EnumerateValueKeyInfo);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
/* HACK: Setup the Dummy KCB */
CM_KEY_CONTROL_BLOCK DummyKcb = {0};
DummyKcb.KeyHive = &KeyObject->RegistryHive->Hive;
DummyKcb.KeyCell = KeyObject->KeyCellOffset;
/* Call the internal API */ /* Call the internal API */
Status = CmEnumerateValueKey(&DummyKcb, Status = CmEnumerateValueKey(KeyObject->KeyControlBlock,
Index, Index,
KeyValueInformationClass, KeyValueInformationClass,
KeyValueInformation, KeyValueInformation,
@ -911,13 +905,8 @@ NtQueryKey(IN HANDLE KeyHandle,
Status = CmiCallRegisteredCallbacks(RegNtPreQueryKey, &QueryKeyInfo); Status = CmiCallRegisteredCallbacks(RegNtPreQueryKey, &QueryKeyInfo);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
/* HACK: Setup the Dummy KCB */
CM_KEY_CONTROL_BLOCK DummyKcb = {0};
DummyKcb.KeyHive = &KeyObject->RegistryHive->Hive;
DummyKcb.KeyCell = KeyObject->KeyCellOffset;
/* Call the internal API */ /* Call the internal API */
Status = CmQueryKey(&DummyKcb, Status = CmQueryKey(KeyObject->KeyControlBlock,
KeyInformationClass, KeyInformationClass,
KeyInformation, KeyInformation,
Length, Length,
@ -976,13 +965,8 @@ NtQueryValueKey(IN HANDLE KeyHandle,
Status = CmiCallRegisteredCallbacks(RegNtPreQueryValueKey, &QueryValueKeyInfo); Status = CmiCallRegisteredCallbacks(RegNtPreQueryValueKey, &QueryValueKeyInfo);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
/* HACK: Setup the Dummy KCB */
CM_KEY_CONTROL_BLOCK DummyKcb = {0};
DummyKcb.KeyHive = &KeyObject->RegistryHive->Hive;
DummyKcb.KeyCell = KeyObject->KeyCellOffset;
/* Call the internal API */ /* Call the internal API */
Status = CmQueryValueKey(&DummyKcb, Status = CmQueryValueKey(KeyObject->KeyControlBlock,
*ValueName, *ValueName,
KeyValueInformationClass, KeyValueInformationClass,
KeyValueInformation, KeyValueInformation,
@ -1044,14 +1028,9 @@ NtSetValueKey(IN HANDLE KeyHandle,
/* Do the callback */ /* Do the callback */
Status = CmiCallRegisteredCallbacks(RegNtPreSetValueKey, &SetValueKeyInfo); Status = CmiCallRegisteredCallbacks(RegNtPreSetValueKey, &SetValueKeyInfo);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
/* HACK: Setup the Dummy KCB */
CM_KEY_CONTROL_BLOCK DummyKcb = {0};
DummyKcb.KeyHive = &KeyObject->RegistryHive->Hive;
DummyKcb.KeyCell = KeyObject->KeyCellOffset;
/* Call the internal API */ /* Call the internal API */
Status = CmSetValueKey(&DummyKcb, Status = CmSetValueKey(KeyObject->KeyControlBlock,
ValueName, ValueName,
Type, Type,
Data, Data,
@ -1100,13 +1079,8 @@ NtDeleteValueKey(IN HANDLE KeyHandle,
&DeleteValueKeyInfo); &DeleteValueKeyInfo);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
/* HACK: Setup the Dummy KCB */
CM_KEY_CONTROL_BLOCK DummyKcb = {0};
DummyKcb.KeyHive = &KeyObject->RegistryHive->Hive;
DummyKcb.KeyCell = KeyObject->KeyCellOffset;
/* Call the internal API */ /* Call the internal API */
Status = CmDeleteValueKey(&DummyKcb, *ValueName); Status = CmDeleteValueKey(KeyObject->KeyControlBlock, *ValueName);
/* Do the post callback */ /* Do the post callback */
PostOperationInfo.Object = (PVOID)KeyObject; PostOperationInfo.Object = (PVOID)KeyObject;

View file

@ -34,10 +34,8 @@ LIST_ENTRY CmpHiveListHead;
ERESOURCE CmpRegistryLock; ERESOURCE CmpRegistryLock;
KTIMER CmiWorkerTimer;
LIST_ENTRY CmiKeyObjectListHead; LIST_ENTRY CmiKeyObjectListHead;
LIST_ENTRY CmiConnectedHiveList; LIST_ENTRY CmiConnectedHiveList;
ULONG CmiTimer = 0; /* gets incremented every 5 seconds (CmiWorkerTimer) */
volatile BOOLEAN CmiHiveSyncEnabled = FALSE; volatile BOOLEAN CmiHiveSyncEnabled = FALSE;
volatile BOOLEAN CmiHiveSyncPending = FALSE; volatile BOOLEAN CmiHiveSyncPending = FALSE;
@ -54,136 +52,6 @@ CmiHiveSyncDpcRoutine(PKDPC Dpc,
extern LIST_ENTRY CmiCallbackHead; extern LIST_ENTRY CmiCallbackHead;
extern FAST_MUTEX CmiCallbackLock; extern FAST_MUTEX CmiCallbackLock;
/* FUNCTIONS ****************************************************************/
/* Debugging helper functions: */
/* CmiVerifyHiveListIntegrity */
/* CmiVerifyHiveListIntegrityWhileLocked */
/* These functions are normally unused. However, should any of the asserts */
/* checking for registry loops in CmiWorkerThread start to trigger, it is */
/* recommended to add liberal amounts of calls to this function throughout */
/* suspect code. This function is due to its iterative nature not intended */
/* to be called during normal circumstances, but as a debugging aid. */
static
VOID
NTAPI
CmipVerifyHiveListIntegrity(BOOLEAN IsLocked)
{
PLIST_ENTRY CurrentEntry;
if (!IsLocked)
{
/* Acquire hive lock */
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
}
if (IsListEmpty(&CmiKeyObjectListHead))
{
ASSERT(CmiKeyObjectListHead.Blink == CmiKeyObjectListHead.Flink);
}
/* walk the list both forwards and backwards */
CurrentEntry = CmiKeyObjectListHead.Flink;
while (CurrentEntry != &CmiKeyObjectListHead)
{
ASSERT(CurrentEntry->Blink != CurrentEntry);
ASSERT(CurrentEntry->Flink != CurrentEntry);
CurrentEntry = CurrentEntry->Flink;
}
CurrentEntry = CmiKeyObjectListHead.Blink;
while (CurrentEntry != &CmiKeyObjectListHead)
{
ASSERT(CurrentEntry->Blink != CurrentEntry);
ASSERT(CurrentEntry->Flink != CurrentEntry);
CurrentEntry = CurrentEntry->Blink;
}
if (!IsLocked)
{
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
}
}
VOID NTAPI CmiVerifyHiveListIntegrity() { CmipVerifyHiveListIntegrity(FALSE); }
VOID NTAPI CmiVerifyHiveListIntegrityWhileLocked() { CmipVerifyHiveListIntegrity(TRUE); }
VOID
NTAPI
CmiWorkerThread(PVOID Param)
{
NTSTATUS Status;
PLIST_ENTRY CurrentEntry;
PKEY_OBJECT CurrentKey;
ULONG Count; /* how many objects have been dereferenced each pass */
/* Loop forever, getting woken up every 5 seconds by CmiWorkerTimer */
while (1)
{
Status = KeWaitForSingleObject(&CmiWorkerTimer,
Executive,
KernelMode,
FALSE,
NULL);
if (Status == STATUS_SUCCESS)
{
DPRINT("CmiWorkerThread\n");
/* Acquire hive lock */
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
CmiTimer++;
Count = 0;
CurrentEntry = CmiKeyObjectListHead.Blink;
while (CurrentEntry != &CmiKeyObjectListHead)
{
CurrentKey = CONTAINING_RECORD(CurrentEntry, KEY_OBJECT, ListEntry);
if (CurrentKey->TimeStamp + 120 > CmiTimer)
{
/* The object was accessed in the last 10min */
break;
}
if (1 == ObGetObjectPointerCount(CurrentKey) &&
!(CurrentKey->Flags & KO_MARKED_FOR_DELETE))
{
/* PointerCount is 1, and it's not marked for delete */
ObDereferenceObject(CurrentKey);
if (CurrentEntry == CmiKeyObjectListHead.Blink)
{
DPRINT("Registry loop detected! Crashing\n");
KEBUGCHECK(0);
}
CurrentEntry = CmiKeyObjectListHead.Blink;
Count++;
}
else
{
/* PointerCount was not 1, or it was marked for delete */
if (CurrentEntry == CurrentEntry->Blink)
{
DPRINT("Registry loop detected! Crashing\n");
KEBUGCHECK(0);
}
CurrentEntry = CurrentEntry->Blink;
}
}
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
DPRINT("Removed %d key objects\n", Count);
}
else
{
KEBUGCHECK(0);
}
}
}
PVOID PVOID
NTAPI NTAPI
CmpRosGetHardwareHive(OUT PULONG Length) CmpRosGetHardwareHive(OUT PULONG Length)
@ -234,7 +102,7 @@ EnlistKeyBodyWithKeyObject(IN PKEY_OBJECT KeyObject,
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE); ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
/* Insert it into the global list (we don't have KCBs here) */ /* Insert it into the global list (we don't have KCBs here) */
InsertTailList(&CmiKeyObjectListHead, &KeyObject->ListEntry); InsertTailList(&CmiKeyObjectListHead, &KeyObject->KeyBodyList);
ExReleaseResourceLite(&CmpRegistryLock); ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
@ -338,8 +206,8 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
DPRINT ("SubName %S\n", SubName); DPRINT ("SubName %S\n", SubName);
/* Create the key */ /* Create the key */
Status = CmpDoCreate(&ParentKey->RegistryHive->Hive, Status = CmpDoCreate(ParentKey->KeyControlBlock->KeyHive,
ParentKey->KeyCellOffset, ParentKey->KeyControlBlock->KeyCell,
NULL, NULL,
&RemainingPath, &RemainingPath,
KernelMode, KernelMode,
@ -356,9 +224,8 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
NewKey->KeyCellOffset = RegistryHive->Hive.BaseBlock->RootCell; NewKey->KeyControlBlock->KeyCell = RegistryHive->Hive.BaseBlock->RootCell;
NewKey->KeyCell = (PVOID)HvGetCell(&RegistryHive->Hive, NewKey->KeyCellOffset); NewKey->KeyControlBlock->KeyHive = &RegistryHive->Hive;
NewKey->RegistryHive = RegistryHive;
Status = RtlpCreateUnicodeString(&NewKey->Name, Status = RtlpCreateUnicodeString(&NewKey->Name,
SubName, NonPagedPool); SubName, NonPagedPool);

View file

@ -366,7 +366,8 @@ CmpParseKey(IN PVOID ParsedObject,
UNICODE_STRING KeyName; UNICODE_STRING KeyName;
PWSTR *Path = &RemainingName->Buffer; PWSTR *Path = &RemainingName->Buffer;
PCM_KEY_CONTROL_BLOCK ParentKcb = NULL, Kcb; PCM_KEY_CONTROL_BLOCK ParentKcb = NULL, Kcb;
PCM_KEY_NODE Node;
ParsedKey = ParsedObject; ParsedKey = ParsedObject;
VERIFY_KEY_OBJECT(ParsedKey); VERIFY_KEY_OBJECT(ParsedKey);
@ -422,8 +423,11 @@ CmpParseKey(IN PVOID ParsedObject,
if (FoundObject == NULL) if (FoundObject == NULL)
{ {
/* Search for the subkey */ /* Search for the subkey */
BlockOffset = CmpFindSubKeyByName(&ParsedKey->RegistryHive->Hive, Node = (PCM_KEY_NODE)HvGetCell(ParsedKey->KeyControlBlock->KeyHive,
ParsedKey->KeyCell, ParsedKey->KeyControlBlock->KeyCell);
BlockOffset = CmpFindSubKeyByName(ParsedKey->KeyControlBlock->KeyHive,
Node,
&KeyName); &KeyName);
if (BlockOffset == HCELL_NIL) if (BlockOffset == HCELL_NIL)
{ {
@ -434,13 +438,13 @@ CmpParseKey(IN PVOID ParsedObject,
} }
/* Get the node */ /* Get the node */
SubKeyCell = (PCM_KEY_NODE)HvGetCell(&ParsedKey->RegistryHive->Hive, BlockOffset); SubKeyCell = (PCM_KEY_NODE)HvGetCell(ParsedKey->KeyControlBlock->KeyHive, BlockOffset);
if ((SubKeyCell->Flags & KEY_SYM_LINK) && if ((SubKeyCell->Flags & KEY_SYM_LINK) &&
!((Attributes & OBJ_OPENLINK) && (EndPtr == NULL))) !((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)))
{ {
RtlInitUnicodeString(&LinkPath, NULL); RtlInitUnicodeString(&LinkPath, NULL);
Status = CmiGetLinkTarget(ParsedKey->RegistryHive, Status = CmiGetLinkTarget((PCMHIVE)ParsedKey->KeyControlBlock->KeyHive,
SubKeyCell, SubKeyCell,
&LinkPath); &LinkPath);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
@ -520,7 +524,7 @@ CmpParseKey(IN PVOID ParsedObject,
ObReferenceObject(FoundObject); ObReferenceObject(FoundObject);
/* Create the KCB */ /* Create the KCB */
Kcb = CmpCreateKeyControlBlock(&ParsedKey->RegistryHive->Hive, Kcb = CmpCreateKeyControlBlock(ParsedKey->KeyControlBlock->KeyHive,
BlockOffset, BlockOffset,
SubKeyCell, SubKeyCell,
ParentKcb, ParentKcb,
@ -535,25 +539,25 @@ CmpParseKey(IN PVOID ParsedObject,
} }
FoundObject->KeyControlBlock = Kcb; FoundObject->KeyControlBlock = Kcb;
FoundObject->Flags = 0; ASSERT(FoundObject->KeyControlBlock->KeyHive == ParsedKey->KeyControlBlock->KeyHive);
FoundObject->KeyCell = SubKeyCell; InsertTailList(&CmiKeyObjectListHead, &FoundObject->KeyBodyList);
FoundObject->KeyCellOffset = BlockOffset;
FoundObject->RegistryHive = ParsedKey->RegistryHive;
InsertTailList(&CmiKeyObjectListHead, &FoundObject->ListEntry);
RtlpCreateUnicodeString(&FoundObject->Name, KeyName.Buffer, NonPagedPool); RtlpCreateUnicodeString(&FoundObject->Name, KeyName.Buffer, NonPagedPool);
CmiAddKeyToList(ParsedKey, FoundObject); CmiAddKeyToList(ParsedKey, FoundObject);
DPRINT("Created object 0x%p\n", FoundObject); DPRINT("Created object 0x%p\n", FoundObject);
} }
else else
{ {
if ((FoundObject->KeyCell->Flags & KEY_SYM_LINK) && Node = (PCM_KEY_NODE)HvGetCell(FoundObject->KeyControlBlock->KeyHive,
FoundObject->KeyControlBlock->KeyCell);
if ((Node->Flags & KEY_SYM_LINK) &&
!((Attributes & OBJ_OPENLINK) && (EndPtr == NULL))) !((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)))
{ {
DPRINT("Found link\n"); DPRINT("Found link\n");
RtlInitUnicodeString(&LinkPath, NULL); RtlInitUnicodeString(&LinkPath, NULL);
Status = CmiGetLinkTarget(FoundObject->RegistryHive, Status = CmiGetLinkTarget((PCMHIVE)FoundObject->KeyControlBlock->KeyHive,
FoundObject->KeyCell, Node,
&LinkPath); &LinkPath);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
@ -598,9 +602,8 @@ CmpParseKey(IN PVOID ParsedObject,
} }
} }
RemoveEntryList(&FoundObject->ListEntry); RemoveEntryList(&FoundObject->KeyBodyList);
InsertHeadList(&CmiKeyObjectListHead, &FoundObject->ListEntry); InsertHeadList(&CmiKeyObjectListHead, &FoundObject->KeyBodyList);
FoundObject->TimeStamp = CmiTimer;
ExReleaseResourceLite(&CmpRegistryLock); ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
@ -650,10 +653,10 @@ CmpDeleteKeyObject(PVOID DeletedObject)
KeEnterCriticalRegion(); KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE); ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
RemoveEntryList(&KeyObject->ListEntry); RemoveEntryList(&KeyObject->KeyBodyList);
RtlFreeUnicodeString(&KeyObject->Name); RtlFreeUnicodeString(&KeyObject->Name);
ASSERT((KeyObject->Flags & KO_MARKED_FOR_DELETE) == FALSE); ASSERT((KeyObject->KeyControlBlock->Delete) == FALSE);
ObDereferenceObject (ParentKeyObject); ObDereferenceObject (ParentKeyObject);
@ -812,7 +815,7 @@ CmiScanKeyList(PKEY_OBJECT Parent,
if (Index < Parent->SubKeyCounts) if (Index < Parent->SubKeyCounts)
{ {
if (CurKey->Flags & KO_MARKED_FOR_DELETE) if (CurKey->KeyControlBlock->Delete)
{ {
CHECKPOINT; CHECKPOINT;
*ReturnedObject = NULL; *ReturnedObject = NULL;

View file

@ -505,21 +505,13 @@ typedef struct _KEY_INFORMATION
#define IsNoFileHive(Hive) ((Hive)->Flags & HIVE_NO_FILE) #define IsNoFileHive(Hive) ((Hive)->Flags & HIVE_NO_FILE)
typedef struct _KEY_OBJECT typedef struct _KEY_OBJECT
{ {
CSHORT Type; ULONG Type;
CSHORT Size;
ULONG Flags;
UNICODE_STRING Name; UNICODE_STRING Name;
PCMHIVE RegistryHive;
HCELL_INDEX KeyCellOffset;
PCM_KEY_NODE KeyCell;
struct _KEY_OBJECT *ParentKey; struct _KEY_OBJECT *ParentKey;
LIST_ENTRY ListEntry; LIST_ENTRY KeyBodyList;
ULONG SubKeyCounts; ULONG SubKeyCounts;
ULONG SizeOfSubKeys; ULONG SizeOfSubKeys;
struct _KEY_OBJECT **SubKeys; struct _KEY_OBJECT **SubKeys;
ULONG TimeStamp;
LIST_ENTRY HiveList;
CACHED_CHILD_LIST ValueCache;
PCM_KEY_CONTROL_BLOCK KeyControlBlock; PCM_KEY_CONTROL_BLOCK KeyControlBlock;
} KEY_OBJECT, *PKEY_OBJECT; } KEY_OBJECT, *PKEY_OBJECT;
extern PCMHIVE CmiVolatileHive; extern PCMHIVE CmiVolatileHive;

View file

@ -230,15 +230,11 @@ CmpDoCreateChild(IN PHHIVE Hive,
/* Now fill out the Cm object */ /* Now fill out the Cm object */
KeyBody->KeyControlBlock = Kcb; KeyBody->KeyControlBlock = Kcb;
KeyBody->KeyCell = KeyNode;
KeyBody->KeyCellOffset = *KeyCell;
KeyBody->Flags = 0;
KeyBody->SubKeyCounts = 0; KeyBody->SubKeyCounts = 0;
KeyBody->SubKeys = NULL; KeyBody->SubKeys = NULL;
KeyBody->SizeOfSubKeys = 0; KeyBody->SizeOfSubKeys = 0;
KeyBody->ParentKey = Parent; KeyBody->ParentKey = Parent;
KeyBody->RegistryHive = KeyBody->ParentKey->RegistryHive; InsertTailList(&CmiKeyObjectListHead, &KeyBody->KeyBodyList);
InsertTailList(&CmiKeyObjectListHead, &KeyBody->ListEntry);
Quickie: Quickie:
/* Check if we got here because of failure */ /* Check if we got here because of failure */
@ -290,8 +286,7 @@ CmpDoCreate(IN PHHIVE Hive,
ExAcquirePushLockShared((PVOID)&((PCMHIVE)Hive)->FlusherLock); ExAcquirePushLockShared((PVOID)&((PCMHIVE)Hive)->FlusherLock);
/* Check if the parent is being deleted */ /* Check if the parent is being deleted */
#define KO_MARKED_FOR_DELETE 0x00000001 if (Parent->KeyControlBlock->Delete)
if (Parent->Flags & KO_MARKED_FOR_DELETE)
{ {
/* It has, quit */ /* It has, quit */
ASSERT(FALSE); ASSERT(FALSE);
@ -319,7 +314,7 @@ CmpDoCreate(IN PHHIVE Hive,
} }
/* Sanity check */ /* Sanity check */
ASSERT(Cell == Parent->KeyCellOffset); ASSERT(Cell == Parent->KeyControlBlock->KeyCell);
/* Get the parent type */ /* Get the parent type */
ParentType = HvGetCellType(Cell); ParentType = HvGetCellType(Cell);
@ -332,7 +327,7 @@ CmpDoCreate(IN PHHIVE Hive,
} }
/* Don't allow children under symlinks */ /* Don't allow children under symlinks */
if (Parent->Flags & KEY_SYM_LINK) if (Parent->KeyControlBlock->Flags & KEY_SYM_LINK)
{ {
/* Fail */ /* Fail */
ASSERT(FALSE); ASSERT(FALSE);
@ -376,8 +371,8 @@ CmpDoCreate(IN PHHIVE Hive,
} }
/* Sanity checks */ /* Sanity checks */
ASSERT(KeyBody->ParentKey->KeyCellOffset == Cell); ASSERT(KeyBody->ParentKey->KeyControlBlock->KeyCell == Cell);
ASSERT(&KeyBody->ParentKey->RegistryHive->Hive == Hive); ASSERT(KeyBody->ParentKey->KeyControlBlock->KeyHive == Hive);
ASSERT(KeyBody->ParentKey == Parent); ASSERT(KeyBody->ParentKey == Parent);
/* Update the timestamp */ /* Update the timestamp */

View file

@ -708,19 +708,14 @@ CmpCreateRegistryRoot(VOID)
if (!Kcb) return FALSE; if (!Kcb) return FALSE;
/* Initialize the object */ /* Initialize the object */
#if 0
RootKey->Type = TAG('k', 'v', '0', '2'); RootKey->Type = TAG('k', 'v', '0', '2');
RootKey->KeyControlBlock = Kcb; RootKey->KeyControlBlock = Kcb;
#if 0
RootKey->NotifyBlock = NULL; RootKey->NotifyBlock = NULL;
RootKey->ProcessID = PsGetCurrentProcessId(); RootKey->ProcessID = PsGetCurrentProcessId();
#else #else
RtlpCreateUnicodeString(&RootKey->Name, L"Registry", NonPagedPool); RtlpCreateUnicodeString(&RootKey->Name, L"Registry", NonPagedPool);
RootKey->KeyControlBlock = Kcb;
RootKey->RegistryHive = CmiVolatileHive;
RootKey->KeyCellOffset = RootIndex;
RootKey->KeyCell = KeyCell;
RootKey->ParentKey = RootKey; RootKey->ParentKey = RootKey;
RootKey->Flags = 0;
RootKey->SubKeyCounts = 0; RootKey->SubKeyCounts = 0;
RootKey->SubKeys = NULL; RootKey->SubKeys = NULL;
RootKey->SizeOfSubKeys = 0; RootKey->SizeOfSubKeys = 0;
@ -759,9 +754,6 @@ CmInitSystem1(VOID)
UNICODE_STRING KeyName; UNICODE_STRING KeyName;
HANDLE KeyHandle; HANDLE KeyHandle;
NTSTATUS Status; NTSTATUS Status;
LARGE_INTEGER DueTime;
HANDLE ThreadHandle;
CLIENT_ID ThreadId;
PCMHIVE HardwareHive; PCMHIVE HardwareHive;
PVOID BaseAddress; PVOID BaseAddress;
ULONG Length; ULONG Length;
@ -806,23 +798,6 @@ CmInitSystem1(VOID)
/* OLD CM: Initialize the key object list */ /* OLD CM: Initialize the key object list */
InitializeListHead(&CmiKeyObjectListHead); InitializeListHead(&CmiKeyObjectListHead);
InitializeListHead(&CmiConnectedHiveList); InitializeListHead(&CmiConnectedHiveList);
/* OLD CM: Initialize the worker timer */
KeInitializeTimerEx(&CmiWorkerTimer, SynchronizationTimer);
/* OLD CM: Initialize the worker thread */
Status = PsCreateSystemThread(&ThreadHandle,
THREAD_ALL_ACCESS,
NULL,
NULL,
&ThreadId,
CmiWorkerThread,
NULL);
if (!NT_SUCCESS(Status)) return FALSE;
/* OLD CM: Start the timer */
DueTime.QuadPart = -1;
KeSetTimerEx(&CmiWorkerTimer, DueTime, 5000, NULL); /* 5sec */
#endif #endif
/* Create the key object types */ /* Create the key object types */