mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 08:25:48 +00:00
Simplified key deletion.
Added workaround to prevent BSOD on missing hives. svn path=/trunk/; revision=4129
This commit is contained in:
parent
cc025a380a
commit
8ce89c167c
4 changed files with 122 additions and 57 deletions
|
@ -437,6 +437,11 @@ CmiAddSubKey(IN PREGISTRY_HIVE RegistryHive,
|
||||||
IN PUNICODE_STRING Class,
|
IN PUNICODE_STRING Class,
|
||||||
IN ULONG CreateOptions);
|
IN ULONG CreateOptions);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
CmiRemoveSubKey(IN PREGISTRY_HIVE RegistryHive,
|
||||||
|
IN PKEY_OBJECT Parent,
|
||||||
|
IN PKEY_OBJECT SubKey);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
|
CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
|
||||||
IN PKEY_CELL KeyCell,
|
IN PKEY_CELL KeyCell,
|
||||||
|
|
|
@ -976,11 +976,11 @@ NtOpenKey(OUT PHANDLE KeyHandle,
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
NtQueryKey(IN HANDLE KeyHandle,
|
NtQueryKey(IN HANDLE KeyHandle,
|
||||||
IN KEY_INFORMATION_CLASS KeyInformationClass,
|
IN KEY_INFORMATION_CLASS KeyInformationClass,
|
||||||
OUT PVOID KeyInformation,
|
OUT PVOID KeyInformation,
|
||||||
IN ULONG Length,
|
IN ULONG Length,
|
||||||
OUT PULONG ResultLength)
|
OUT PULONG ResultLength)
|
||||||
{
|
{
|
||||||
PKEY_BASIC_INFORMATION BasicInformation;
|
PKEY_BASIC_INFORMATION BasicInformation;
|
||||||
PKEY_NODE_INFORMATION NodeInformation;
|
PKEY_NODE_INFORMATION NodeInformation;
|
||||||
|
@ -1007,22 +1007,26 @@ NtQueryKey(IN HANDLE KeyHandle,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
CHECKPOINT1;
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
CHECKPOINT1;
|
||||||
|
|
||||||
/* Acquire hive lock */
|
/* Acquire hive lock */
|
||||||
ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE);
|
ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE);
|
||||||
|
CHECKPOINT1;
|
||||||
|
|
||||||
VERIFY_KEY_OBJECT(KeyObject);
|
VERIFY_KEY_OBJECT(KeyObject);
|
||||||
|
|
||||||
/* Get pointer to KeyCell */
|
/* Get pointer to KeyCell */
|
||||||
KeyCell = KeyObject->KeyCell;
|
KeyCell = KeyObject->KeyCell;
|
||||||
RegistryHive = KeyObject->RegistryHive;
|
RegistryHive = KeyObject->RegistryHive;
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
switch (KeyInformationClass)
|
switch (KeyInformationClass)
|
||||||
{
|
{
|
||||||
case KeyBasicInformation:
|
case KeyBasicInformation:
|
||||||
|
CHECKPOINT1;
|
||||||
/* Check size of buffer */
|
/* Check size of buffer */
|
||||||
if (Length < sizeof(KEY_BASIC_INFORMATION) +
|
if (Length < sizeof(KEY_BASIC_INFORMATION) +
|
||||||
KeyObject->NameSize * sizeof(WCHAR))
|
KeyObject->NameSize * sizeof(WCHAR))
|
||||||
|
@ -1043,8 +1047,9 @@ NtQueryKey(IN HANDLE KeyHandle,
|
||||||
*ResultLength = sizeof(KEY_BASIC_INFORMATION) +
|
*ResultLength = sizeof(KEY_BASIC_INFORMATION) +
|
||||||
KeyObject->NameSize * sizeof(WCHAR);
|
KeyObject->NameSize * sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
|
CHECKPOINT1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KeyNodeInformation:
|
case KeyNodeInformation:
|
||||||
/* Check size of buffer */
|
/* Check size of buffer */
|
||||||
if (Length < sizeof(KEY_NODE_INFORMATION)
|
if (Length < sizeof(KEY_NODE_INFORMATION)
|
||||||
|
@ -1124,10 +1129,13 @@ NtQueryKey(IN HANDLE KeyHandle,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CHECKPOINT1;
|
||||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
|
CHECKPOINT1;
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
|
CHECKPOINT1;
|
||||||
|
|
||||||
return Status;
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -508,10 +508,20 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note:
|
||||||
|
* This is a workaround to prevent a BSOD because of missing registry hives.
|
||||||
|
* The workaround is only useful for developers. An implementation for the
|
||||||
|
* ordinary user must bail out on missing registry hives because they are
|
||||||
|
* essential to booting and configuring the OS.
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
if (CreateNew == TRUE)
|
if (CreateNew == TRUE)
|
||||||
CreateDisposition = FILE_OPEN_IF;
|
CreateDisposition = FILE_OPEN_IF;
|
||||||
else
|
else
|
||||||
CreateDisposition = FILE_OPEN;
|
CreateDisposition = FILE_OPEN;
|
||||||
|
#endif
|
||||||
|
CreateDisposition = FILE_OPEN_IF;
|
||||||
|
|
||||||
Status = NtCreateFile(&FileHandle,
|
Status = NtCreateFile(&FileHandle,
|
||||||
FILE_ALL_ACCESS,
|
FILE_ALL_ACCESS,
|
||||||
|
@ -531,7 +541,11 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Note: Another workaround! See the note above! */
|
||||||
|
#if 0
|
||||||
if ((CreateNew) && (IoSB.Information == FILE_CREATED))
|
if ((CreateNew) && (IoSB.Information == FILE_CREATED))
|
||||||
|
#endif
|
||||||
|
if (IoSB.Information != FILE_OPENED)
|
||||||
{
|
{
|
||||||
Status = CmiCreateNewRegFile(FileHandle);
|
Status = CmiCreateNewRegFile(FileHandle);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -1219,13 +1233,13 @@ CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive,
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
|
CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
|
||||||
PKEY_OBJECT Parent,
|
PKEY_OBJECT Parent,
|
||||||
PKEY_OBJECT SubKey,
|
PKEY_OBJECT SubKey,
|
||||||
PWSTR NewSubKeyName,
|
PWSTR NewSubKeyName,
|
||||||
USHORT NewSubKeyNameSize,
|
USHORT NewSubKeyNameSize,
|
||||||
ULONG TitleIndex,
|
ULONG TitleIndex,
|
||||||
PUNICODE_STRING Class,
|
PUNICODE_STRING Class,
|
||||||
ULONG CreateOptions)
|
ULONG CreateOptions)
|
||||||
{
|
{
|
||||||
PHASH_TABLE_CELL NewHashBlock;
|
PHASH_TABLE_CELL NewHashBlock;
|
||||||
PHASH_TABLE_CELL HashBlock;
|
PHASH_TABLE_CELL HashBlock;
|
||||||
|
@ -1303,7 +1317,7 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
|
||||||
/* Don't modify hash table if key is volatile and parent is not */
|
/* Don't modify hash table if key is volatile and parent is not */
|
||||||
if (IsVolatileHive(RegistryHive) && (!IsVolatileHive(Parent->RegistryHive)))
|
if (IsVolatileHive(RegistryHive) && (!IsVolatileHive(Parent->RegistryHive)))
|
||||||
{
|
{
|
||||||
return Status;
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (KeyCell->HashTableOffset == (ULONG_PTR) -1)
|
if (KeyCell->HashTableOffset == (ULONG_PTR) -1)
|
||||||
|
@ -1313,15 +1327,15 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
|
||||||
&KeyCell->HashTableOffset,
|
&KeyCell->HashTableOffset,
|
||||||
REG_INIT_HASH_TABLE_SIZE);
|
REG_INIT_HASH_TABLE_SIZE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
return(Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HashBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL);
|
HashBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL);
|
||||||
if (((KeyCell->NumberOfSubKeys + 1) >= HashBlock->HashTableSize))
|
if (((KeyCell->NumberOfSubKeys + 1) >= HashBlock->HashTableSize))
|
||||||
{
|
{
|
||||||
BLOCK_OFFSET HTOffset;
|
BLOCK_OFFSET HTOffset;
|
||||||
|
|
||||||
/* Reallocate the hash table block */
|
/* Reallocate the hash table block */
|
||||||
|
@ -1335,24 +1349,84 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlZeroMemory(&NewHashBlock->Table[0],
|
RtlZeroMemory(&NewHashBlock->Table[0],
|
||||||
sizeof(NewHashBlock->Table[0]) * NewHashBlock->HashTableSize);
|
sizeof(NewHashBlock->Table[0]) * NewHashBlock->HashTableSize);
|
||||||
RtlCopyMemory(&NewHashBlock->Table[0],
|
RtlCopyMemory(&NewHashBlock->Table[0],
|
||||||
&HashBlock->Table[0],
|
&HashBlock->Table[0],
|
||||||
sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize);
|
sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize);
|
||||||
CmiDestroyBlock(RegistryHive, HashBlock, KeyCell->HashTableOffset);
|
CmiDestroyBlock(RegistryHive,
|
||||||
KeyCell->HashTableOffset = HTOffset;
|
HashBlock,
|
||||||
HashBlock = NewHashBlock;
|
KeyCell->HashTableOffset);
|
||||||
}
|
KeyCell->HashTableOffset = HTOffset;
|
||||||
|
HashBlock = NewHashBlock;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = CmiAddKeyToHashTable(RegistryHive, HashBlock, NewKeyCell, NKBOffset);
|
Status = CmiAddKeyToHashTable(RegistryHive,
|
||||||
|
HashBlock,
|
||||||
|
NewKeyCell,
|
||||||
|
NKBOffset);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
KeyCell->NumberOfSubKeys++;
|
KeyCell->NumberOfSubKeys++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive,
|
||||||
|
PKEY_OBJECT ParentKey,
|
||||||
|
PKEY_OBJECT SubKey)
|
||||||
|
{
|
||||||
|
PHASH_TABLE_CELL HashBlock;
|
||||||
|
|
||||||
|
DPRINT1("CmiRemoveSubKey() called\n");
|
||||||
|
|
||||||
|
/* Remove the key from the parent key's hash block */
|
||||||
|
HashBlock = CmiGetBlock(RegistryHive,
|
||||||
|
ParentKey->KeyCell->HashTableOffset,
|
||||||
|
NULL);
|
||||||
|
if (HashBlock != NULL)
|
||||||
|
{
|
||||||
|
CmiRemoveKeyFromHashTable(RegistryHive,
|
||||||
|
HashBlock,
|
||||||
|
SubKey->BlockOffset);
|
||||||
|
CmiMarkBlockDirty(RegistryHive,
|
||||||
|
ParentKey->KeyCell->HashTableOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the key's hash block */
|
||||||
|
DPRINT1("HashTableOffset %lx\n", SubKey->KeyCell->HashTableOffset)
|
||||||
|
if (SubKey->KeyCell->HashTableOffset != 0)
|
||||||
|
{
|
||||||
|
HashBlock = CmiGetBlock(RegistryHive,
|
||||||
|
SubKey->KeyCell->HashTableOffset,
|
||||||
|
NULL);
|
||||||
|
DPRINT1("HashBlock %p\n", HashBlock)
|
||||||
|
if (HashBlock != NULL)
|
||||||
|
{
|
||||||
|
CmiDestroyBlock(RegistryHive,
|
||||||
|
HashBlock,
|
||||||
|
SubKey->KeyCell->HashTableOffset);
|
||||||
|
}
|
||||||
|
SubKey->KeyCell->HashTableOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECKPOINT1;
|
||||||
|
/* Remove the key from the parent key's hash block */
|
||||||
|
ParentKey->KeyCell->NumberOfSubKeys--;
|
||||||
|
CmiMarkBlockDirty(RegistryHive,
|
||||||
|
ParentKey->BlockOffset);
|
||||||
|
|
||||||
|
CHECKPOINT1;
|
||||||
|
/* Destroy key cell */
|
||||||
|
CmiDestroyBlock(RegistryHive,
|
||||||
|
SubKey->KeyCell,
|
||||||
|
SubKey->BlockOffset);
|
||||||
|
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -277,34 +277,12 @@ CmiObjectDelete(PVOID DeletedObject)
|
||||||
|
|
||||||
if (KeyObject->Flags & KO_MARKED_FOR_DELETE)
|
if (KeyObject->Flags & KO_MARKED_FOR_DELETE)
|
||||||
{
|
{
|
||||||
PHASH_TABLE_CELL HashBlock;
|
|
||||||
|
|
||||||
DPRINT("delete really key\n");
|
DPRINT("delete really key\n");
|
||||||
|
|
||||||
/* FIXME: Destroy the key's hash block */
|
CmiRemoveSubKey(KeyObject->RegistryHive,
|
||||||
|
KeyObject->ParentKey,
|
||||||
|
KeyObject);
|
||||||
|
|
||||||
/* Remove the key from the parent key's hash block */
|
|
||||||
HashBlock = CmiGetBlock(KeyObject->RegistryHive,
|
|
||||||
KeyObject->ParentKey->KeyCell->HashTableOffset, NULL);
|
|
||||||
DPRINT1("HashBlock %p\n", HashBlock);
|
|
||||||
if (HashBlock != NULL)
|
|
||||||
{
|
|
||||||
CmiRemoveKeyFromHashTable(KeyObject->RegistryHive,
|
|
||||||
HashBlock,
|
|
||||||
KeyObject->BlockOffset);
|
|
||||||
CmiMarkBlockDirty(KeyObject->RegistryHive,
|
|
||||||
KeyObject->ParentKey->KeyCell->HashTableOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove the key from the parent key's hash block */
|
|
||||||
KeyObject->ParentKey->KeyCell->NumberOfSubKeys--;
|
|
||||||
CmiMarkBlockDirty(KeyObject->RegistryHive,
|
|
||||||
KeyObject->ParentKey->BlockOffset);
|
|
||||||
|
|
||||||
/* Destroy key cell */
|
|
||||||
CmiDestroyBlock(KeyObject->RegistryHive,
|
|
||||||
KeyObject->KeyCell,
|
|
||||||
KeyObject->BlockOffset);
|
|
||||||
if (IsPermanentHive(KeyObject->RegistryHive))
|
if (IsPermanentHive(KeyObject->RegistryHive))
|
||||||
CmiSyncHives();
|
CmiSyncHives();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue