Debugging helper functions added, to verify hive list integrity. Grab hive lock for insertion in EnlistKeyBodyWithKCB. Some comments added.

svn path=/trunk/; revision=29619
This commit is contained in:
Mike Nordell 2007-10-16 05:08:45 +00:00
parent 48b968be9f
commit 4475d4786b

View file

@ -38,7 +38,7 @@ ERESOURCE CmpRegistryLock;
KTIMER CmiWorkerTimer;
LIST_ENTRY CmiKeyObjectListHead;
LIST_ENTRY CmiConnectedHiveList;
ULONG CmiTimer = 0;
ULONG CmiTimer = 0; /* gets incremented every 5 seconds (CmiWorkerTimer) */
volatile BOOLEAN CmiHiveSyncEnabled = FALSE;
volatile BOOLEAN CmiHiveSyncPending = FALSE;
@ -57,6 +57,60 @@ 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)
@ -64,7 +118,9 @@ CmiWorkerThread(PVOID Param)
NTSTATUS Status;
PLIST_ENTRY CurrentEntry;
PKEY_OBJECT CurrentKey;
ULONG Count;
ULONG Count; /* how many objects have been dereferenced each pass */
/* Loop forever, getting woken up every 5 seconds by CmiWorkerTimer */
while (1)
{
@ -96,6 +152,7 @@ CmiWorkerThread(PVOID Param)
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)
{
@ -107,6 +164,7 @@ CmiWorkerThread(PVOID Param)
}
else
{
/* PointerCount was not 1, or it was marked for delete */
if (CurrentEntry == CurrentEntry->Blink)
{
DPRINT("Registry loop detected! Crashing\n");
@ -166,13 +224,21 @@ CmpRosGetHardwareHive(OUT PULONG Length)
return (PVOID)((MdBlock->BasePage << PAGE_SHIFT) | KSEG0_BASE);
}
/* Precondition: Must not hold the hive lock CmpRegistryLock */
VOID
NTAPI
EnlistKeyBodyWithKCB(IN PKEY_OBJECT KeyObject,
IN ULONG Flags)
{
/* Acquire hive lock */
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
/* Insert it into the global list (we don't have KCBs here) */
InsertTailList(&CmiKeyObjectListHead, &KeyObject->ListEntry);
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
}
NTSTATUS