mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 21:03:00 +00:00
- 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:
parent
6a2986170b
commit
aa1bc628b3
6 changed files with 64 additions and 258 deletions
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue