mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 01:15:09 +00:00
Reverted most of the changes from 2004-01-08.
Fixed buggy key enumeration for volatile and 'foreign' keys. svn path=/trunk/; revision=7580
This commit is contained in:
parent
314759a953
commit
1631cca917
5 changed files with 167 additions and 317 deletions
|
@ -52,11 +52,9 @@
|
|||
// BLOCK_OFFSET = offset in file after header block
|
||||
typedef ULONG BLOCK_OFFSET, *PBLOCK_OFFSET;
|
||||
|
||||
|
||||
#include <pshpack1.h>
|
||||
|
||||
/* header for registry hive file : */
|
||||
|
||||
typedef struct _HIVE_HEADER
|
||||
{
|
||||
/* Hive identifier "regf" (0x66676572) */
|
||||
|
@ -103,7 +101,6 @@ typedef struct _HIVE_HEADER
|
|||
ULONG Checksum;
|
||||
} HIVE_HEADER, *PHIVE_HEADER;
|
||||
|
||||
|
||||
typedef struct _HBIN
|
||||
{
|
||||
/* Bin identifier "hbin" (0x6E696268) */
|
||||
|
@ -125,14 +122,12 @@ typedef struct _HBIN
|
|||
ULONG Unused2;
|
||||
} HBIN, *PHBIN;
|
||||
|
||||
|
||||
typedef struct _CELL_HEADER
|
||||
{
|
||||
/* <0 if used, >0 if free */
|
||||
LONG CellSize;
|
||||
} CELL_HEADER, *PCELL_HEADER;
|
||||
|
||||
|
||||
typedef struct _KEY_CELL
|
||||
{
|
||||
/* Size of this cell */
|
||||
|
@ -187,10 +182,9 @@ typedef struct _KEY_CELL
|
|||
USHORT ClassSize;
|
||||
|
||||
/* Name of key (not zero terminated) */
|
||||
UCHAR Name[1];
|
||||
UCHAR Name[0];
|
||||
} KEY_CELL, *PKEY_CELL;
|
||||
|
||||
|
||||
/* KEY_CELL.Flags constants */
|
||||
#define REG_KEY_ROOT_CELL 0x0C
|
||||
#define REG_KEY_LINK_CELL 0x10
|
||||
|
@ -199,12 +193,6 @@ typedef struct _KEY_CELL
|
|||
/*
|
||||
* Hash record
|
||||
*
|
||||
* KeyOffset:
|
||||
* The least significant bit is used to distinguish
|
||||
* between real key offsets and pointers to registry hives:
|
||||
* 0 : offset
|
||||
* 1 : pointer to registry hive
|
||||
*
|
||||
* HashValue:
|
||||
* packed name: four letters of value's name
|
||||
* otherwise: Zero!
|
||||
|
@ -303,18 +291,6 @@ typedef struct _REGISTRY_HIVE
|
|||
#define IsUsedCell(Cell)(Cell->CellSize < 0)
|
||||
|
||||
|
||||
typedef struct _HIVE_LINK
|
||||
{
|
||||
LIST_ENTRY Entry;
|
||||
|
||||
PREGISTRY_HIVE ParentKeyRegistryHive;
|
||||
BLOCK_OFFSET ParentKeyCellOffset;
|
||||
|
||||
PREGISTRY_HIVE SubKeyRegistryHive;
|
||||
BLOCK_OFFSET SubKeyCellOffset;
|
||||
} HIVE_LINK, *PHIVE_LINK;
|
||||
|
||||
|
||||
/* KEY_OBJECT.Flags */
|
||||
|
||||
/* When set, the key is scheduled for deletion, and all
|
||||
|
@ -370,7 +346,6 @@ extern PREGISTRY_HIVE CmiVolatileHive;
|
|||
extern POBJECT_TYPE CmiKeyType;
|
||||
extern KSPIN_LOCK CmiKeyListLock;
|
||||
|
||||
extern LIST_ENTRY CmiHiveLinkListHead;
|
||||
extern LIST_ENTRY CmiHiveListHead;
|
||||
extern ERESOURCE CmiHiveListLock;
|
||||
|
||||
|
@ -491,13 +466,12 @@ CmiGetMaxValueDataLength(IN PREGISTRY_HIVE RegistryHive,
|
|||
IN PKEY_CELL KeyCell);
|
||||
|
||||
NTSTATUS
|
||||
CmiScanForSubKey(IN PREGISTRY_HIVE ParentKeyRegistryHive,
|
||||
IN PKEY_CELL ParentKeyCell,
|
||||
OUT PREGISTRY_HIVE *SubKeyRegistryHive,
|
||||
OUT PKEY_CELL *SubKeyCell,
|
||||
OUT BLOCK_OFFSET *SubKeyCellOffset,
|
||||
CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive,
|
||||
IN PKEY_CELL KeyCell,
|
||||
OUT PKEY_CELL *SubKeyCell,
|
||||
OUT BLOCK_OFFSET *BlockOffset,
|
||||
IN PUNICODE_STRING KeyName,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN ULONG Attributes);
|
||||
|
||||
NTSTATUS
|
||||
|
@ -541,23 +515,22 @@ CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
|
|||
IN PUNICODE_STRING ValueName);
|
||||
|
||||
NTSTATUS
|
||||
CmiAllocateHashTableCell(IN PREGISTRY_HIVE RegistryHive,
|
||||
OUT PHASH_TABLE_CELL *HashCell,
|
||||
OUT BLOCK_OFFSET *HBOffset,
|
||||
IN ULONG HashTableSize);
|
||||
CmiAllocateHashTableCell(IN PREGISTRY_HIVE RegistryHive,
|
||||
OUT PHASH_TABLE_CELL *HashBlock,
|
||||
OUT BLOCK_OFFSET *HBOffset,
|
||||
IN ULONG HashTableSize);
|
||||
|
||||
PKEY_CELL
|
||||
CmiGetKeyFromHashByIndex(PREGISTRY_HIVE RegistryHive,
|
||||
PHASH_TABLE_CELL HashCell,
|
||||
ULONG Index);
|
||||
PHASH_TABLE_CELL HashBlock,
|
||||
ULONG Index);
|
||||
|
||||
NTSTATUS
|
||||
CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive,
|
||||
PKEY_CELL ParentKeyCell,
|
||||
BLOCK_OFFSET ParentKeyCellOffset,
|
||||
PREGISTRY_HIVE NewKeyRegistryHive,
|
||||
PKEY_CELL NewKeyCell,
|
||||
BLOCK_OFFSET NewKeyCellOffset);
|
||||
PHASH_TABLE_CELL HashCell,
|
||||
BLOCK_OFFSET HashCellOffset,
|
||||
PKEY_CELL NewKeyCell,
|
||||
BLOCK_OFFSET NKBOffset);
|
||||
|
||||
NTSTATUS
|
||||
CmiRemoveKeyFromHashTable(PREGISTRY_HIVE RegistryHive,
|
||||
|
|
|
@ -275,7 +275,7 @@ NtEnumerateKey(IN HANDLE KeyHandle,
|
|||
PKEY_OBJECT KeyObject;
|
||||
PREGISTRY_HIVE RegistryHive;
|
||||
PKEY_CELL KeyCell, SubKeyCell;
|
||||
PHASH_TABLE_CELL HashTableCell;
|
||||
PHASH_TABLE_CELL HashTableBlock;
|
||||
PKEY_BASIC_INFORMATION BasicInformation;
|
||||
PKEY_NODE_INFORMATION NodeInformation;
|
||||
PKEY_FULL_INFORMATION FullInformation;
|
||||
|
@ -314,21 +314,47 @@ NtEnumerateKey(IN HANDLE KeyHandle,
|
|||
KeyCell = KeyObject->KeyCell;
|
||||
RegistryHive = KeyObject->RegistryHive;
|
||||
|
||||
/* Check for hightest possible sub key index */
|
||||
if (Index >= KeyCell->NumberOfSubKeys + KeyObject->NumberOfSubKeys)
|
||||
{
|
||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||
KeLeaveCriticalRegion();
|
||||
ObDereferenceObject(KeyObject);
|
||||
DPRINT("No more volatile entries\n");
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
|
||||
/* Get pointer to SubKey */
|
||||
if (Index >= KeyCell->NumberOfSubKeys)
|
||||
{
|
||||
if (Index >= KeyObject->NumberOfSubKeys)
|
||||
PKEY_OBJECT CurKey = NULL;
|
||||
ULONG i;
|
||||
ULONG j;
|
||||
|
||||
/* Search for volatile or 'foreign' keys */
|
||||
j = KeyCell->NumberOfSubKeys;
|
||||
for (i = 0; i < KeyObject->NumberOfSubKeys; i++)
|
||||
{
|
||||
CurKey = KeyObject->SubKeys[i];
|
||||
if (CurKey->RegistryHive == CmiVolatileHive ||
|
||||
CurKey->RegistryHive != RegistryHive)
|
||||
{
|
||||
if (j == Index)
|
||||
break;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= KeyObject->NumberOfSubKeys)
|
||||
{
|
||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||
KeLeaveCriticalRegion();
|
||||
ObDereferenceObject(KeyObject);
|
||||
DPRINT("No more volatile entries\n");
|
||||
return(STATUS_NO_MORE_ENTRIES);
|
||||
}
|
||||
else
|
||||
{
|
||||
SubKeyCell = KeyObject->SubKeys[Index]->KeyCell;
|
||||
DPRINT("No more non-volatile entries\n");
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
|
||||
SubKeyCell = CurKey->KeyCell;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -337,11 +363,11 @@ NtEnumerateKey(IN HANDLE KeyHandle,
|
|||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||
KeLeaveCriticalRegion();
|
||||
ObDereferenceObject(KeyObject);
|
||||
return(STATUS_NO_MORE_ENTRIES);
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
|
||||
HashTableCell = CmiGetCell (RegistryHive, KeyCell->HashTableOffset, NULL);
|
||||
if (HashTableCell == NULL)
|
||||
HashTableBlock = CmiGetCell (RegistryHive, KeyCell->HashTableOffset, NULL);
|
||||
if (HashTableBlock == NULL)
|
||||
{
|
||||
DPRINT("CmiGetBlock() failed\n");
|
||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||
|
@ -349,13 +375,12 @@ NtEnumerateKey(IN HANDLE KeyHandle,
|
|||
ObDereferenceObject(KeyObject);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
SubKeyCell = CmiGetKeyFromHashByIndex(RegistryHive,
|
||||
HashTableCell,
|
||||
HashTableBlock,
|
||||
Index);
|
||||
}
|
||||
|
||||
DPRINT("SubKeyCell %p\n", SubKeyCell);
|
||||
|
||||
if (SubKeyCell == NULL)
|
||||
{
|
||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||
|
|
|
@ -2262,139 +2262,87 @@ CmiGetMaxValueDataLength(PREGISTRY_HIVE RegistryHive,
|
|||
|
||||
|
||||
NTSTATUS
|
||||
CmiScanForSubKey(IN PREGISTRY_HIVE ParentKeyRegistryHive,
|
||||
IN PKEY_CELL ParentKeyCell,
|
||||
OUT PREGISTRY_HIVE *SubKeyRegistryHive,
|
||||
CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive,
|
||||
IN PKEY_CELL KeyCell,
|
||||
OUT PKEY_CELL *SubKeyCell,
|
||||
OUT BLOCK_OFFSET *SubKeyCellOffset,
|
||||
OUT BLOCK_OFFSET *BlockOffset,
|
||||
IN PUNICODE_STRING KeyName,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN ULONG Attributes)
|
||||
{
|
||||
PHASH_TABLE_CELL HashCell;
|
||||
PHASH_TABLE_CELL HashBlock;
|
||||
PKEY_CELL CurSubKeyCell;
|
||||
PHIVE_LINK HiveLink;
|
||||
ULONG i;
|
||||
|
||||
VERIFY_KEY_CELL(ParentKeyCell);
|
||||
VERIFY_KEY_CELL(KeyCell);
|
||||
|
||||
DPRINT("Scanning for sub key %wZ\n", KeyName);
|
||||
|
||||
assert(ParentKeyRegistryHive);
|
||||
assert(RegistryHive);
|
||||
|
||||
*SubKeyCell = NULL;
|
||||
|
||||
/* The key does not have any subkeys */
|
||||
if (ParentKeyCell->HashTableOffset == (BLOCK_OFFSET)-1)
|
||||
if (KeyCell->HashTableOffset == (BLOCK_OFFSET)-1)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Get hash table */
|
||||
HashCell = CmiGetCell (ParentKeyRegistryHive, ParentKeyCell->HashTableOffset, NULL);
|
||||
if (HashCell == NULL)
|
||||
HashBlock = CmiGetCell (RegistryHive, KeyCell->HashTableOffset, NULL);
|
||||
if (HashBlock == NULL)
|
||||
{
|
||||
DPRINT("CmiGetBlock() failed\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
for (i = 0; (i < ParentKeyCell->NumberOfSubKeys) && (i < HashCell->HashTableSize); i++)
|
||||
for (i = 0; (i < KeyCell->NumberOfSubKeys) && (i < HashBlock->HashTableSize); i++)
|
||||
{
|
||||
if (Attributes & OBJ_CASE_INSENSITIVE)
|
||||
{
|
||||
if (HashCell->Table[i].KeyOffset != 0 &&
|
||||
HashCell->Table[i].KeyOffset != (ULONG_PTR)-1 &&
|
||||
(HashCell->Table[i].HashValue == 0 ||
|
||||
CmiCompareHashI(KeyName, (PCHAR)&HashCell->Table[i].HashValue)))
|
||||
if (HashBlock->Table[i].KeyOffset != 0 &&
|
||||
HashBlock->Table[i].KeyOffset != (ULONG_PTR)-1 &&
|
||||
(HashBlock->Table[i].HashValue == 0 ||
|
||||
CmiCompareHashI(KeyName, (PCHAR)&HashBlock->Table[i].HashValue)))
|
||||
{
|
||||
if (HashCell->Table[i].KeyOffset & 1)
|
||||
CurSubKeyCell = CmiGetCell (RegistryHive,
|
||||
HashBlock->Table[i].KeyOffset,
|
||||
NULL);
|
||||
if (CurSubKeyCell == NULL)
|
||||
{
|
||||
HiveLink = (PHIVE_LINK)(HashCell->Table[i].KeyOffset & ~1);
|
||||
|
||||
CurSubKeyCell = CmiGetCell (HiveLink->SubKeyRegistryHive,
|
||||
HiveLink->SubKeyCellOffset,
|
||||
NULL);
|
||||
if (CurSubKeyCell == NULL)
|
||||
{
|
||||
DPRINT("CmiGetBlock() failed\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (CmiCompareKeyNamesI(KeyName, CurSubKeyCell))
|
||||
{
|
||||
*SubKeyRegistryHive = HiveLink->SubKeyRegistryHive;
|
||||
*SubKeyCell = CurSubKeyCell;
|
||||
*SubKeyCellOffset = HiveLink->SubKeyCellOffset;
|
||||
break;
|
||||
}
|
||||
DPRINT("CmiGetBlock() failed\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurSubKeyCell = CmiGetCell (ParentKeyRegistryHive,
|
||||
HashCell->Table[i].KeyOffset,
|
||||
NULL);
|
||||
if (CurSubKeyCell == NULL)
|
||||
{
|
||||
DPRINT("CmiGetBlock() failed\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (CmiCompareKeyNamesI(KeyName, CurSubKeyCell))
|
||||
{
|
||||
*SubKeyRegistryHive = ParentKeyRegistryHive;
|
||||
*SubKeyCell = CurSubKeyCell;
|
||||
*SubKeyCellOffset = HashCell->Table[i].KeyOffset;
|
||||
break;
|
||||
}
|
||||
if (CmiCompareKeyNamesI(KeyName, CurSubKeyCell))
|
||||
{
|
||||
*SubKeyCell = CurSubKeyCell;
|
||||
*BlockOffset = HashBlock->Table[i].KeyOffset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (HashCell->Table[i].KeyOffset != 0 &&
|
||||
HashCell->Table[i].KeyOffset != (ULONG_PTR) -1 &&
|
||||
(HashCell->Table[i].HashValue == 0 ||
|
||||
CmiCompareHash(KeyName, (PCHAR)&HashCell->Table[i].HashValue)))
|
||||
if (HashBlock->Table[i].KeyOffset != 0 &&
|
||||
HashBlock->Table[i].KeyOffset != (ULONG_PTR) -1 &&
|
||||
(HashBlock->Table[i].HashValue == 0 ||
|
||||
CmiCompareHash(KeyName, (PCHAR)&HashBlock->Table[i].HashValue)))
|
||||
{
|
||||
if (HashCell->Table[i].KeyOffset & 1)
|
||||
CurSubKeyCell = CmiGetCell (RegistryHive,
|
||||
HashBlock->Table[i].KeyOffset,
|
||||
NULL);
|
||||
if (CurSubKeyCell == NULL)
|
||||
{
|
||||
HiveLink = (PHIVE_LINK)(HashCell->Table[i].KeyOffset & ~1);
|
||||
|
||||
CurSubKeyCell = CmiGetCell (HiveLink->SubKeyRegistryHive,
|
||||
HiveLink->SubKeyCellOffset,
|
||||
NULL);
|
||||
if (CurSubKeyCell == NULL)
|
||||
{
|
||||
DPRINT("CmiGetBlock() failed\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (CmiCompareKeyNames(KeyName, CurSubKeyCell))
|
||||
{
|
||||
*SubKeyRegistryHive = HiveLink->SubKeyRegistryHive;
|
||||
*SubKeyCell = CurSubKeyCell;
|
||||
*SubKeyCellOffset = HiveLink->SubKeyCellOffset;
|
||||
break;
|
||||
}
|
||||
DPRINT("CmiGetBlock() failed\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurSubKeyCell = CmiGetCell (ParentKeyRegistryHive,
|
||||
HashCell->Table[i].KeyOffset,
|
||||
NULL);
|
||||
if (CurSubKeyCell == NULL)
|
||||
{
|
||||
DPRINT("CmiGetBlock() failed\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (CmiCompareKeyNames(KeyName, CurSubKeyCell))
|
||||
{
|
||||
*SubKeyRegistryHive = ParentKeyRegistryHive;
|
||||
*SubKeyCell = CurSubKeyCell;
|
||||
*SubKeyCellOffset = HashCell->Table[i].KeyOffset;
|
||||
break;
|
||||
}
|
||||
if (CmiCompareKeyNames(KeyName, CurSubKeyCell))
|
||||
{
|
||||
*SubKeyCell = CurSubKeyCell;
|
||||
*BlockOffset = HashBlock->Table[i].KeyOffset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2413,6 +2361,7 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
|
|||
PUNICODE_STRING Class,
|
||||
ULONG CreateOptions)
|
||||
{
|
||||
PHASH_TABLE_CELL HashBlock;
|
||||
BLOCK_OFFSET NKBOffset;
|
||||
PKEY_CELL NewKeyCell;
|
||||
ULONG NewBlockSize;
|
||||
|
@ -2529,19 +2478,69 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
|
|||
return(Status);
|
||||
}
|
||||
|
||||
Status = CmiAddKeyToHashTable(ParentKey->RegistryHive,
|
||||
ParentKeyCell,
|
||||
ParentKey->KeyCellOffset,
|
||||
NULL,
|
||||
if (ParentKeyCell->HashTableOffset == (ULONG_PTR) -1)
|
||||
{
|
||||
Status = CmiAllocateHashTableCell (RegistryHive,
|
||||
&HashBlock,
|
||||
&ParentKeyCell->HashTableOffset,
|
||||
REG_INIT_HASH_TABLE_SIZE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HashBlock = CmiGetCell (RegistryHive,
|
||||
ParentKeyCell->HashTableOffset,
|
||||
NULL);
|
||||
if (HashBlock == NULL)
|
||||
{
|
||||
DPRINT("CmiGetCell() failed\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (((ParentKeyCell->NumberOfSubKeys + 1) >= HashBlock->HashTableSize))
|
||||
{
|
||||
PHASH_TABLE_CELL NewHashBlock;
|
||||
BLOCK_OFFSET HTOffset;
|
||||
|
||||
/* Reallocate the hash table cell */
|
||||
Status = CmiAllocateHashTableCell (RegistryHive,
|
||||
&NewHashBlock,
|
||||
&HTOffset,
|
||||
HashBlock->HashTableSize +
|
||||
REG_EXTEND_HASH_TABLE_SIZE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
RtlZeroMemory(&NewHashBlock->Table[0],
|
||||
sizeof(NewHashBlock->Table[0]) * NewHashBlock->HashTableSize);
|
||||
RtlCopyMemory(&NewHashBlock->Table[0],
|
||||
&HashBlock->Table[0],
|
||||
sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize);
|
||||
CmiDestroyCell (RegistryHive,
|
||||
HashBlock,
|
||||
ParentKeyCell->HashTableOffset);
|
||||
ParentKeyCell->HashTableOffset = HTOffset;
|
||||
HashBlock = NewHashBlock;
|
||||
}
|
||||
}
|
||||
|
||||
Status = CmiAddKeyToHashTable(RegistryHive,
|
||||
HashBlock,
|
||||
ParentKeyCell->HashTableOffset,
|
||||
NewKeyCell,
|
||||
NKBOffset);
|
||||
if (!NT_SUCCESS(Status))
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
ParentKeyCell->NumberOfSubKeys++;
|
||||
}
|
||||
|
||||
NtQuerySystemTime (&ParentKeyCell->LastWriteTime);
|
||||
CmiMarkBlockDirty (ParentKey->RegistryHive, ParentKey->KeyCellOffset);
|
||||
CmiMarkBlockDirty (RegistryHive, ParentKey->KeyCellOffset);
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
@ -3006,30 +3005,22 @@ CmiAllocateHashTableCell (IN PREGISTRY_HIVE RegistryHive,
|
|||
|
||||
PKEY_CELL
|
||||
CmiGetKeyFromHashByIndex(PREGISTRY_HIVE RegistryHive,
|
||||
PHASH_TABLE_CELL HashCell,
|
||||
PHASH_TABLE_CELL HashBlock,
|
||||
ULONG Index)
|
||||
{
|
||||
BLOCK_OFFSET KeyOffset;
|
||||
PHIVE_LINK HiveLink;
|
||||
PKEY_CELL KeyCell;
|
||||
|
||||
if (HashCell == NULL)
|
||||
if (HashBlock == NULL)
|
||||
return NULL;
|
||||
|
||||
if (HashCell->Table[Index].KeyOffset & 1)
|
||||
if (IsPointerHive(RegistryHive))
|
||||
{
|
||||
HiveLink = (PHIVE_LINK)(HashCell->Table[Index].KeyOffset & ~1);
|
||||
KeyCell = CmiGetCell (HiveLink->SubKeyRegistryHive,
|
||||
HiveLink->SubKeyCellOffset,
|
||||
NULL);
|
||||
}
|
||||
else if (IsPointerHive(RegistryHive))
|
||||
{
|
||||
KeyCell = (PKEY_CELL) HashCell->Table[Index].KeyOffset;
|
||||
KeyCell = (PKEY_CELL) HashBlock->Table[Index].KeyOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyOffset = HashCell->Table[Index].KeyOffset;
|
||||
KeyOffset = HashBlock->Table[Index].KeyOffset;
|
||||
KeyCell = CmiGetCell (RegistryHive, KeyOffset, NULL);
|
||||
}
|
||||
|
||||
|
@ -3039,93 +3030,18 @@ CmiGetKeyFromHashByIndex(PREGISTRY_HIVE RegistryHive,
|
|||
|
||||
NTSTATUS
|
||||
CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive,
|
||||
PKEY_CELL ParentKeyCell,
|
||||
BLOCK_OFFSET ParentKeyCellOffset,
|
||||
PREGISTRY_HIVE NewKeyRegistryHive,
|
||||
PHASH_TABLE_CELL HashCell,
|
||||
BLOCK_OFFSET HashCellOffset,
|
||||
PKEY_CELL NewKeyCell,
|
||||
BLOCK_OFFSET NewKeyCellOffset)
|
||||
BLOCK_OFFSET NKBOffset)
|
||||
{
|
||||
PHASH_TABLE_CELL HashCell;
|
||||
ULONG i;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (ParentKeyCell->HashTableOffset == (ULONG_PTR) -1)
|
||||
{
|
||||
Status = CmiAllocateHashTableCell (RegistryHive,
|
||||
&HashCell,
|
||||
&ParentKeyCell->HashTableOffset,
|
||||
REG_INIT_HASH_TABLE_SIZE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
CmiMarkBlockDirty(RegistryHive, ParentKeyCellOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
HashCell = CmiGetCell (RegistryHive,
|
||||
ParentKeyCell->HashTableOffset,
|
||||
NULL);
|
||||
if (HashCell == NULL)
|
||||
{
|
||||
DPRINT("CmiGetCell() failed\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (((ParentKeyCell->NumberOfSubKeys + 1) >= HashCell->HashTableSize))
|
||||
{
|
||||
PHASH_TABLE_CELL NewHashCell;
|
||||
BLOCK_OFFSET NewHashCellOffset;
|
||||
|
||||
/* Reallocate the hash table cell */
|
||||
Status = CmiAllocateHashTableCell (RegistryHive,
|
||||
&NewHashCell,
|
||||
&NewHashCellOffset,
|
||||
HashCell->HashTableSize +
|
||||
REG_EXTEND_HASH_TABLE_SIZE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
RtlZeroMemory(&NewHashCell->Table[0],
|
||||
sizeof(NewHashCell->Table[0]) * NewHashCell->HashTableSize);
|
||||
RtlCopyMemory(&NewHashCell->Table[0],
|
||||
&HashCell->Table[0],
|
||||
sizeof(NewHashCell->Table[0]) * HashCell->HashTableSize);
|
||||
CmiDestroyCell (RegistryHive,
|
||||
HashCell,
|
||||
ParentKeyCell->HashTableOffset);
|
||||
ParentKeyCell->HashTableOffset = NewHashCellOffset;
|
||||
HashCell = NewHashCell;
|
||||
CmiMarkBlockDirty(RegistryHive, ParentKeyCellOffset);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < HashCell->HashTableSize; i++)
|
||||
{
|
||||
if (HashCell->Table[i].KeyOffset == 0)
|
||||
{
|
||||
if (NewKeyRegistryHive != NULL && NewKeyRegistryHive != RegistryHive)
|
||||
{
|
||||
PHIVE_LINK HiveLink;
|
||||
|
||||
HiveLink = ExAllocatePool (NonPagedPool, sizeof(HIVE_LINK));
|
||||
if (HiveLink == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
InsertTailList (&CmiHiveLinkListHead, &HiveLink->Entry);
|
||||
HiveLink->ParentKeyRegistryHive = RegistryHive;
|
||||
HiveLink->ParentKeyCellOffset = ParentKeyCellOffset;
|
||||
HiveLink->SubKeyRegistryHive = NewKeyRegistryHive;
|
||||
HiveLink->SubKeyCellOffset = NewKeyCellOffset;
|
||||
|
||||
HashCell->Table[i].KeyOffset = (BLOCK_OFFSET)((ULONG)HiveLink | 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
HashCell->Table[i].KeyOffset = NewKeyCellOffset;
|
||||
}
|
||||
HashCell->Table[i].KeyOffset = NKBOffset;
|
||||
HashCell->Table[i].HashValue = 0;
|
||||
if (NewKeyCell->Flags & REG_KEY_NAME_PACKED)
|
||||
{
|
||||
|
@ -3133,9 +3049,7 @@ CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive,
|
|||
NewKeyCell->Name,
|
||||
min(NewKeyCell->NameSize, sizeof(ULONG)));
|
||||
}
|
||||
CmiMarkBlockDirty(RegistryHive, NewKeyCellOffset);
|
||||
ParentKeyCell->NumberOfSubKeys++;
|
||||
CmiMarkBlockDirty(RegistryHive, ParentKeyCellOffset);
|
||||
CmiMarkBlockDirty(RegistryHive, HashCellOffset);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: registry.c,v 1.118 2004/01/09 19:42:40 ekohl Exp $
|
||||
/* $Id: registry.c,v 1.119 2004/01/12 12:52:27 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -31,7 +31,6 @@ POBJECT_TYPE CmiKeyType = NULL;
|
|||
PREGISTRY_HIVE CmiVolatileHive = NULL;
|
||||
KSPIN_LOCK CmiKeyListLock;
|
||||
|
||||
LIST_ENTRY CmiHiveLinkListHead;
|
||||
LIST_ENTRY CmiHiveListHead;
|
||||
ERESOURCE CmiHiveListLock;
|
||||
|
||||
|
@ -282,9 +281,6 @@ CmInitializeRegistry(VOID)
|
|||
|
||||
ObpCreateTypeObject (CmiKeyType);
|
||||
|
||||
/* Initialize the hive link list */
|
||||
InitializeListHead(&CmiHiveLinkListHead);
|
||||
|
||||
/* Initialize the hive list */
|
||||
InitializeListHead(&CmiHiveListHead);
|
||||
ExInitializeResourceLite(&CmiHiveListLock);
|
||||
|
@ -600,30 +596,12 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
|
|||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Status = CmiAddKeyToHashTable(ParentKey->RegistryHive,
|
||||
ParentKey->KeyCell,
|
||||
ParentKey->KeyCellOffset,
|
||||
NewKey->RegistryHive,
|
||||
NewKey->KeyCell,
|
||||
NewKey->KeyCellOffset);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("CmiAddKeyToHashTable() failed (Status %lx)\n", Status);
|
||||
if (NewKey->SubKeys != NULL)
|
||||
{
|
||||
ExFreePool (NewKey->SubKeys);
|
||||
}
|
||||
ObDereferenceObject (NewKey);
|
||||
ObDereferenceObject (ParentKey);
|
||||
return Status;
|
||||
}
|
||||
|
||||
CmiAddKeyToList (ParentKey, NewKey);
|
||||
ObDereferenceObject (ParentKey);
|
||||
|
||||
VERIFY_KEY_OBJECT(NewKey);
|
||||
|
||||
/* Note: Do not dereference NewKey here! */
|
||||
ObDereferenceObject (ParentKey);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -636,10 +614,6 @@ CmiDisconnectHive (IN POBJECT_ATTRIBUTES KeyObjectAttributes,
|
|||
PKEY_OBJECT KeyObject;
|
||||
PREGISTRY_HIVE Hive;
|
||||
HANDLE KeyHandle;
|
||||
PLIST_ENTRY Entry;
|
||||
PHIVE_LINK HiveLink;
|
||||
PKEY_CELL ParentKeyCell;
|
||||
PHASH_TABLE_CELL HashCell;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("CmiDisconnectHive() called\n");
|
||||
|
@ -689,43 +663,9 @@ CmiDisconnectHive (IN POBJECT_ATTRIBUTES KeyObjectAttributes,
|
|||
}
|
||||
|
||||
Hive = KeyObject->RegistryHive;
|
||||
|
||||
CmiRemoveKeyFromList (KeyObject);
|
||||
|
||||
/* Remove hive link and hash table entry */
|
||||
Entry = CmiHiveLinkListHead.Flink;
|
||||
while (Entry != &CmiHiveLinkListHead)
|
||||
{
|
||||
HiveLink = CONTAINING_RECORD(Entry, HIVE_LINK, Entry);
|
||||
if (HiveLink->SubKeyRegistryHive == Hive &&
|
||||
HiveLink->SubKeyCellOffset == KeyObject->KeyCellOffset)
|
||||
{
|
||||
ParentKeyCell = CmiGetCell (HiveLink->ParentKeyRegistryHive,
|
||||
HiveLink->ParentKeyCellOffset,
|
||||
NULL);
|
||||
if (ParentKeyCell != NULL)
|
||||
{
|
||||
HashCell = CmiGetCell (HiveLink->ParentKeyRegistryHive,
|
||||
ParentKeyCell->HashTableOffset,
|
||||
NULL);
|
||||
if (HashCell != NULL)
|
||||
{
|
||||
CmiRemoveKeyFromHashTable(HiveLink->ParentKeyRegistryHive,
|
||||
HashCell,
|
||||
(BLOCK_OFFSET)((ULONG)HiveLink | 1));
|
||||
ParentKeyCell->NumberOfSubKeys--;
|
||||
}
|
||||
}
|
||||
|
||||
RemoveEntryList (Entry);
|
||||
ExFreePool (Entry);
|
||||
break;
|
||||
}
|
||||
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
/* Note: Dereference the key object twice in order to delete it */
|
||||
/* Dereference KeyObject twice to delete it */
|
||||
ObDereferenceObject (KeyObject);
|
||||
ObDereferenceObject (KeyObject);
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@ CmiObjectParse(PVOID ParsedObject,
|
|||
UNICODE_STRING LinkPath;
|
||||
UNICODE_STRING TargetPath;
|
||||
UNICODE_STRING KeyName;
|
||||
PREGISTRY_HIVE RegistryHive;
|
||||
|
||||
ParsedKey = ParsedObject;
|
||||
|
||||
|
@ -91,7 +90,6 @@ CmiObjectParse(PVOID ParsedObject,
|
|||
{
|
||||
Status = CmiScanForSubKey(ParsedKey->RegistryHive,
|
||||
ParsedKey->KeyCell,
|
||||
&RegistryHive,
|
||||
&SubKeyCell,
|
||||
&BlockOffset,
|
||||
&KeyName,
|
||||
|
@ -167,7 +165,7 @@ CmiObjectParse(PVOID ParsedObject,
|
|||
FoundObject->Flags = 0;
|
||||
FoundObject->KeyCell = SubKeyCell;
|
||||
FoundObject->KeyCellOffset = BlockOffset;
|
||||
FoundObject->RegistryHive = RegistryHive;
|
||||
FoundObject->RegistryHive = ParsedKey->RegistryHive;
|
||||
RtlCreateUnicodeString(&FoundObject->Name,
|
||||
KeyName.Buffer);
|
||||
CmiAddKeyToList(ParsedKey, FoundObject);
|
||||
|
|
Loading…
Reference in a new issue