[FORMATTING]

Fix formatting, to have an indentation of 4 spaces
No code change

svn path=/trunk/; revision=27553
This commit is contained in:
Hervé Poussineau 2007-07-09 23:22:43 +00:00
parent 4216adf631
commit 8b12884393
4 changed files with 1560 additions and 1567 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,4 @@
/* $Id$
*
/*
* PROJECT: ReactOS Kernel
* COPYRIGHT: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/cm/regfile.c
@ -62,195 +61,195 @@ CmiLoadHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
VOID
CmCloseHiveFiles(PEREGISTRY_HIVE RegistryHive)
{
ZwClose(RegistryHive->HiveHandle);
ZwClose(RegistryHive->LogHandle);
ZwClose(RegistryHive->HiveHandle);
ZwClose(RegistryHive->LogHandle);
}
NTSTATUS
CmiFlushRegistryHive(PEREGISTRY_HIVE RegistryHive)
{
BOOLEAN Success;
NTSTATUS Status;
ULONG Disposition;
BOOLEAN Success;
NTSTATUS Status;
ULONG Disposition;
ASSERT(!IsNoFileHive(RegistryHive));
ASSERT(!IsNoFileHive(RegistryHive));
if (RtlFindSetBits(&RegistryHive->Hive.DirtyVector, 1, 0) == ~0)
if (RtlFindSetBits(&RegistryHive->Hive.DirtyVector, 1, 0) == ~0)
{
return(STATUS_SUCCESS);
return(STATUS_SUCCESS);
}
Status = CmpOpenHiveFiles(&RegistryHive->HiveFileName,
L".LOG",
&RegistryHive->HiveHandle,
&RegistryHive->LogHandle,
&Disposition,
&Disposition,
FALSE,
FALSE,
TRUE,
NULL);
if (!NT_SUCCESS(Status))
Status = CmpOpenHiveFiles(&RegistryHive->HiveFileName,
L".LOG",
&RegistryHive->HiveHandle,
&RegistryHive->LogHandle,
&Disposition,
&Disposition,
FALSE,
FALSE,
TRUE,
NULL);
if (!NT_SUCCESS(Status))
{
return Status;
return Status;
}
Success = HvSyncHive(&RegistryHive->Hive);
Success = HvSyncHive(&RegistryHive->Hive);
CmCloseHiveFiles(RegistryHive);
CmCloseHiveFiles(RegistryHive);
return Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
return Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
}
ULONG
CmiGetMaxNameLength(PHHIVE Hive,
PCM_KEY_NODE KeyCell)
{
PHASH_TABLE_CELL HashBlock;
PCM_KEY_NODE CurSubKeyCell;
ULONG MaxName;
ULONG NameSize;
ULONG i;
ULONG Storage;
PHASH_TABLE_CELL HashBlock;
PCM_KEY_NODE CurSubKeyCell;
ULONG MaxName;
ULONG NameSize;
ULONG i;
ULONG Storage;
MaxName = 0;
for (Storage = HvStable; Storage < HvMaxStorageType; Storage++)
MaxName = 0;
for (Storage = HvStable; Storage < HvMaxStorageType; Storage++)
{
if (KeyCell->SubKeyLists[Storage] != HCELL_NULL)
if (KeyCell->SubKeyLists[Storage] != HCELL_NULL)
{
HashBlock = HvGetCell (Hive, KeyCell->SubKeyLists[Storage]);
ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID);
HashBlock = HvGetCell (Hive, KeyCell->SubKeyLists[Storage]);
ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID);
for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
{
CurSubKeyCell = HvGetCell (Hive,
HashBlock->Table[i].KeyOffset);
NameSize = CurSubKeyCell->NameSize;
if (CurSubKeyCell->Flags & REG_KEY_NAME_PACKED)
NameSize *= sizeof(WCHAR);
if (NameSize > MaxName)
MaxName = NameSize;
CurSubKeyCell = HvGetCell (Hive,
HashBlock->Table[i].KeyOffset);
NameSize = CurSubKeyCell->NameSize;
if (CurSubKeyCell->Flags & REG_KEY_NAME_PACKED)
NameSize *= sizeof(WCHAR);
if (NameSize > MaxName)
MaxName = NameSize;
}
}
}
DPRINT ("MaxName %lu\n", MaxName);
DPRINT ("MaxName %lu\n", MaxName);
return MaxName;
return MaxName;
}
ULONG
CmiGetMaxClassLength(PHHIVE Hive,
PCM_KEY_NODE KeyCell)
{
PHASH_TABLE_CELL HashBlock;
PCM_KEY_NODE CurSubKeyCell;
ULONG MaxClass;
ULONG i;
ULONG Storage;
PHASH_TABLE_CELL HashBlock;
PCM_KEY_NODE CurSubKeyCell;
ULONG MaxClass;
ULONG i;
ULONG Storage;
MaxClass = 0;
for (Storage = HvStable; Storage < HvMaxStorageType; Storage++)
MaxClass = 0;
for (Storage = HvStable; Storage < HvMaxStorageType; Storage++)
{
if (KeyCell->SubKeyLists[Storage] != HCELL_NULL)
if (KeyCell->SubKeyLists[Storage] != HCELL_NULL)
{
HashBlock = HvGetCell (Hive,
KeyCell->SubKeyLists[Storage]);
ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID);
HashBlock = HvGetCell (Hive,
KeyCell->SubKeyLists[Storage]);
ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID);
for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
for (i = 0; i < KeyCell->SubKeyCounts[Storage]; i++)
{
CurSubKeyCell = HvGetCell (Hive,
HashBlock->Table[i].KeyOffset);
CurSubKeyCell = HvGetCell (Hive,
HashBlock->Table[i].KeyOffset);
if (MaxClass < CurSubKeyCell->ClassSize)
if (MaxClass < CurSubKeyCell->ClassSize)
{
MaxClass = CurSubKeyCell->ClassSize;
MaxClass = CurSubKeyCell->ClassSize;
}
}
}
}
return MaxClass;
return MaxClass;
}
ULONG
CmiGetMaxValueNameLength(PHHIVE Hive,
PCM_KEY_NODE KeyCell)
PCM_KEY_NODE KeyCell)
{
PVALUE_LIST_CELL ValueListCell;
PCM_KEY_VALUE CurValueCell;
ULONG MaxValueName;
ULONG Size;
ULONG i;
PVALUE_LIST_CELL ValueListCell;
PCM_KEY_VALUE CurValueCell;
ULONG MaxValueName;
ULONG Size;
ULONG i;
VERIFY_KEY_CELL(KeyCell);
VERIFY_KEY_CELL(KeyCell);
if (KeyCell->ValueList.List == HCELL_NULL)
if (KeyCell->ValueList.List == HCELL_NULL)
{
return 0;
return 0;
}
MaxValueName = 0;
ValueListCell = HvGetCell (Hive,
KeyCell->ValueList.List);
MaxValueName = 0;
ValueListCell = HvGetCell (Hive,
KeyCell->ValueList.List);
for (i = 0; i < KeyCell->ValueList.Count; i++)
for (i = 0; i < KeyCell->ValueList.Count; i++)
{
CurValueCell = HvGetCell (Hive,
ValueListCell->ValueOffset[i]);
if (CurValueCell == NULL)
{
DPRINT("CmiGetBlock() failed\n");
}
CurValueCell = HvGetCell (Hive,
ValueListCell->ValueOffset[i]);
if (CurValueCell == NULL)
{
DPRINT("CmiGetBlock() failed\n");
}
if (CurValueCell != NULL)
{
Size = CurValueCell->NameSize;
if (CurValueCell->Flags & REG_VALUE_NAME_PACKED)
{
Size *= sizeof(WCHAR);
}
if (MaxValueName < Size)
{
MaxValueName = Size;
}
if (CurValueCell != NULL)
{
Size = CurValueCell->NameSize;
if (CurValueCell->Flags & REG_VALUE_NAME_PACKED)
{
Size *= sizeof(WCHAR);
}
if (MaxValueName < Size)
{
MaxValueName = Size;
}
}
}
return MaxValueName;
return MaxValueName;
}
ULONG
CmiGetMaxValueDataLength(PHHIVE Hive,
PCM_KEY_NODE KeyCell)
PCM_KEY_NODE KeyCell)
{
PVALUE_LIST_CELL ValueListCell;
PCM_KEY_VALUE CurValueCell;
LONG MaxValueData;
ULONG i;
PVALUE_LIST_CELL ValueListCell;
PCM_KEY_VALUE CurValueCell;
LONG MaxValueData;
ULONG i;
VERIFY_KEY_CELL(KeyCell);
VERIFY_KEY_CELL(KeyCell);
if (KeyCell->ValueList.List == HCELL_NULL)
if (KeyCell->ValueList.List == HCELL_NULL)
{
return 0;
return 0;
}
MaxValueData = 0;
ValueListCell = HvGetCell (Hive, KeyCell->ValueList.List);
MaxValueData = 0;
ValueListCell = HvGetCell (Hive, KeyCell->ValueList.List);
for (i = 0; i < KeyCell->ValueList.Count; i++)
for (i = 0; i < KeyCell->ValueList.Count; i++)
{
CurValueCell = HvGetCell (Hive,
ValueListCell->ValueOffset[i]);
if ((MaxValueData < (LONG)(CurValueCell->DataSize & REG_DATA_SIZE_MASK)))
CurValueCell = HvGetCell (Hive,
ValueListCell->ValueOffset[i]);
if ((MaxValueData < (LONG)(CurValueCell->DataSize & REG_DATA_SIZE_MASK)))
{
MaxValueData = CurValueCell->DataSize & REG_DATA_SIZE_MASK;
MaxValueData = CurValueCell->DataSize & REG_DATA_SIZE_MASK;
}
}
return MaxValueData;
return MaxValueData;
}
NTSTATUS
@ -302,250 +301,250 @@ CmiScanForSubKey(IN PEREGISTRY_HIVE RegistryHive,
NTSTATUS
CmiAddSubKey(PEREGISTRY_HIVE RegistryHive,
PKEY_OBJECT ParentKey,
PKEY_OBJECT SubKey,
PUNICODE_STRING SubKeyName,
ULONG TitleIndex,
PUNICODE_STRING Class,
ULONG CreateOptions)
PKEY_OBJECT ParentKey,
PKEY_OBJECT SubKey,
PUNICODE_STRING SubKeyName,
ULONG TitleIndex,
PUNICODE_STRING Class,
ULONG CreateOptions)
{
PHASH_TABLE_CELL HashBlock;
HCELL_INDEX NKBOffset;
PCM_KEY_NODE NewKeyCell;
ULONG NewBlockSize;
PCM_KEY_NODE ParentKeyCell;
PVOID ClassCell;
NTSTATUS Status;
USHORT NameSize;
PWSTR NamePtr;
BOOLEAN Packable;
HV_STORAGE_TYPE Storage;
ULONG i;
PHASH_TABLE_CELL HashBlock;
HCELL_INDEX NKBOffset;
PCM_KEY_NODE NewKeyCell;
ULONG NewBlockSize;
PCM_KEY_NODE ParentKeyCell;
PVOID ClassCell;
NTSTATUS Status;
USHORT NameSize;
PWSTR NamePtr;
BOOLEAN Packable;
HV_STORAGE_TYPE Storage;
ULONG i;
ParentKeyCell = ParentKey->KeyCell;
ParentKeyCell = ParentKey->KeyCell;
VERIFY_KEY_CELL(ParentKeyCell);
VERIFY_KEY_CELL(ParentKeyCell);
/* Skip leading backslash */
if (SubKeyName->Buffer[0] == L'\\')
/* Skip leading backslash */
if (SubKeyName->Buffer[0] == L'\\')
{
NamePtr = &SubKeyName->Buffer[1];
NameSize = SubKeyName->Length - sizeof(WCHAR);
NamePtr = &SubKeyName->Buffer[1];
NameSize = SubKeyName->Length - sizeof(WCHAR);
}
else
else
{
NamePtr = SubKeyName->Buffer;
NameSize = SubKeyName->Length;
NamePtr = SubKeyName->Buffer;
NameSize = SubKeyName->Length;
}
/* Check whether key name can be packed */
Packable = TRUE;
for (i = 0; i < NameSize / sizeof(WCHAR); i++)
/* Check whether key name can be packed */
Packable = TRUE;
for (i = 0; i < NameSize / sizeof(WCHAR); i++)
{
if (NamePtr[i] & 0xFF00)
{
Packable = FALSE;
break;
}
}
/* Adjust name size */
if (Packable)
{
NameSize = NameSize / sizeof(WCHAR);
}
DPRINT("Key %S Length %lu %s\n", NamePtr, NameSize, (Packable)?"True":"False");
Status = STATUS_SUCCESS;
Storage = (CreateOptions & REG_OPTION_VOLATILE) ? HvVolatile : HvStable;
NewBlockSize = sizeof(CM_KEY_NODE) + NameSize;
NKBOffset = HvAllocateCell (&RegistryHive->Hive, NewBlockSize, Storage);
if (NKBOffset == HCELL_NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
else
{
NewKeyCell = HvGetCell (&RegistryHive->Hive, NKBOffset);
NewKeyCell->Id = REG_KEY_CELL_ID;
if (CreateOptions & REG_OPTION_VOLATILE)
if (NamePtr[i] & 0xFF00)
{
NewKeyCell->Flags = REG_KEY_VOLATILE_CELL;
Packable = FALSE;
break;
}
else
{
NewKeyCell->Flags = 0;
}
KeQuerySystemTime(&NewKeyCell->LastWriteTime);
NewKeyCell->Parent = HCELL_NULL;
NewKeyCell->SubKeyCounts[HvStable] = 0;
NewKeyCell->SubKeyCounts[HvVolatile] = 0;
NewKeyCell->SubKeyLists[HvStable] = HCELL_NULL;
NewKeyCell->SubKeyLists[HvVolatile] = HCELL_NULL;
NewKeyCell->ValueList.Count = 0;
NewKeyCell->ValueList.List = HCELL_NULL;
NewKeyCell->SecurityKeyOffset = HCELL_NULL;
NewKeyCell->ClassNameOffset = HCELL_NULL;
/* Pack the key name */
NewKeyCell->NameSize = NameSize;
if (Packable)
{
NewKeyCell->Flags |= REG_KEY_NAME_PACKED;
for (i = 0; i < NameSize; i++)
{
NewKeyCell->Name[i] = (CHAR)(NamePtr[i] & 0x00FF);
}
}
else
{
RtlCopyMemory(NewKeyCell->Name,
NamePtr,
NameSize);
}
VERIFY_KEY_CELL(NewKeyCell);
if (Class != NULL && Class->Length)
{
NewKeyCell->ClassSize = Class->Length;
NewKeyCell->ClassNameOffset = HvAllocateCell(
&RegistryHive->Hive, NewKeyCell->ClassSize, HvStable);
ASSERT(NewKeyCell->ClassNameOffset != HCELL_NULL); /* FIXME */
ClassCell = HvGetCell(&RegistryHive->Hive, NewKeyCell->ClassNameOffset);
RtlCopyMemory (ClassCell,
Class->Buffer,
Class->Length);
}
}
if (!NT_SUCCESS(Status))
/* Adjust name size */
if (Packable)
{
NameSize = NameSize / sizeof(WCHAR);
}
DPRINT("Key %S Length %lu %s\n", NamePtr, NameSize, (Packable)?"True":"False");
Status = STATUS_SUCCESS;
Storage = (CreateOptions & REG_OPTION_VOLATILE) ? HvVolatile : HvStable;
NewBlockSize = sizeof(CM_KEY_NODE) + NameSize;
NKBOffset = HvAllocateCell (&RegistryHive->Hive, NewBlockSize, Storage);
if (NKBOffset == HCELL_NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
else
{
NewKeyCell = HvGetCell (&RegistryHive->Hive, NKBOffset);
NewKeyCell->Id = REG_KEY_CELL_ID;
if (CreateOptions & REG_OPTION_VOLATILE)
{
NewKeyCell->Flags = REG_KEY_VOLATILE_CELL;
}
else
{
NewKeyCell->Flags = 0;
}
KeQuerySystemTime(&NewKeyCell->LastWriteTime);
NewKeyCell->Parent = HCELL_NULL;
NewKeyCell->SubKeyCounts[HvStable] = 0;
NewKeyCell->SubKeyCounts[HvVolatile] = 0;
NewKeyCell->SubKeyLists[HvStable] = HCELL_NULL;
NewKeyCell->SubKeyLists[HvVolatile] = HCELL_NULL;
NewKeyCell->ValueList.Count = 0;
NewKeyCell->ValueList.List = HCELL_NULL;
NewKeyCell->SecurityKeyOffset = HCELL_NULL;
NewKeyCell->ClassNameOffset = HCELL_NULL;
/* Pack the key name */
NewKeyCell->NameSize = NameSize;
if (Packable)
{
NewKeyCell->Flags |= REG_KEY_NAME_PACKED;
for (i = 0; i < NameSize; i++)
{
NewKeyCell->Name[i] = (CHAR)(NamePtr[i] & 0x00FF);
}
}
else
{
RtlCopyMemory(NewKeyCell->Name,
NamePtr,
NameSize);
}
VERIFY_KEY_CELL(NewKeyCell);
if (Class != NULL && Class->Length)
{
NewKeyCell->ClassSize = Class->Length;
NewKeyCell->ClassNameOffset = HvAllocateCell(
&RegistryHive->Hive, NewKeyCell->ClassSize, HvStable);
ASSERT(NewKeyCell->ClassNameOffset != HCELL_NULL); /* FIXME */
ClassCell = HvGetCell(&RegistryHive->Hive, NewKeyCell->ClassNameOffset);
RtlCopyMemory (ClassCell,
Class->Buffer,
Class->Length);
}
}
if (!NT_SUCCESS(Status))
{
return Status;
}
SubKey->KeyCell = NewKeyCell;
SubKey->KeyCellOffset = NKBOffset;
SubKey->KeyCell = NewKeyCell;
SubKey->KeyCellOffset = NKBOffset;
if (ParentKeyCell->SubKeyLists[Storage] == HCELL_NULL)
if (ParentKeyCell->SubKeyLists[Storage] == HCELL_NULL)
{
Status = CmiAllocateHashTableCell (RegistryHive,
&HashBlock,
&ParentKeyCell->SubKeyLists[Storage],
REG_INIT_HASH_TABLE_SIZE,
Storage);
if (!NT_SUCCESS(Status))
{
return(Status);
}
Status = CmiAllocateHashTableCell (RegistryHive,
&HashBlock,
&ParentKeyCell->SubKeyLists[Storage],
REG_INIT_HASH_TABLE_SIZE,
Storage);
if (!NT_SUCCESS(Status))
{
return(Status);
}
}
else
else
{
HashBlock = HvGetCell (&RegistryHive->Hive,
ParentKeyCell->SubKeyLists[Storage]);
ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID);
HashBlock = HvGetCell (&RegistryHive->Hive,
ParentKeyCell->SubKeyLists[Storage]);
ASSERT(HashBlock->Id == REG_HASH_TABLE_CELL_ID);
if (((ParentKeyCell->SubKeyCounts[Storage] + 1) >= HashBlock->HashTableSize))
{
PHASH_TABLE_CELL NewHashBlock;
HCELL_INDEX HTOffset;
if (((ParentKeyCell->SubKeyCounts[Storage] + 1) >= HashBlock->HashTableSize))
{
PHASH_TABLE_CELL NewHashBlock;
HCELL_INDEX HTOffset;
/* Reallocate the hash table cell */
Status = CmiAllocateHashTableCell (RegistryHive,
&NewHashBlock,
&HTOffset,
HashBlock->HashTableSize +
REG_EXTEND_HASH_TABLE_SIZE,
Storage);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Reallocate the hash table cell */
Status = CmiAllocateHashTableCell (RegistryHive,
&NewHashBlock,
&HTOffset,
HashBlock->HashTableSize +
REG_EXTEND_HASH_TABLE_SIZE,
Storage);
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);
HvFreeCell (&RegistryHive->Hive, ParentKeyCell->SubKeyLists[Storage]);
ParentKeyCell->SubKeyLists[Storage] = HTOffset;
HashBlock = NewHashBlock;
}
RtlZeroMemory(&NewHashBlock->Table[0],
sizeof(NewHashBlock->Table[0]) * NewHashBlock->HashTableSize);
RtlCopyMemory(&NewHashBlock->Table[0],
&HashBlock->Table[0],
sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize);
HvFreeCell (&RegistryHive->Hive, ParentKeyCell->SubKeyLists[Storage]);
ParentKeyCell->SubKeyLists[Storage] = HTOffset;
HashBlock = NewHashBlock;
}
}
Status = CmiAddKeyToHashTable(RegistryHive,
HashBlock,
ParentKeyCell,
Storage,
NewKeyCell,
NKBOffset);
if (NT_SUCCESS(Status))
Status = CmiAddKeyToHashTable(RegistryHive,
HashBlock,
ParentKeyCell,
Storage,
NewKeyCell,
NKBOffset);
if (NT_SUCCESS(Status))
{
ParentKeyCell->SubKeyCounts[Storage]++;
ParentKeyCell->SubKeyCounts[Storage]++;
}
KeQuerySystemTime (&ParentKeyCell->LastWriteTime);
HvMarkCellDirty (&RegistryHive->Hive, ParentKey->KeyCellOffset);
KeQuerySystemTime (&ParentKeyCell->LastWriteTime);
HvMarkCellDirty (&RegistryHive->Hive, ParentKey->KeyCellOffset);
return(Status);
return(Status);
}
NTSTATUS
CmiAllocateHashTableCell (IN PEREGISTRY_HIVE RegistryHive,
OUT PHASH_TABLE_CELL *HashBlock,
OUT HCELL_INDEX *HBOffset,
IN ULONG SubKeyCount,
IN HV_STORAGE_TYPE Storage)
OUT PHASH_TABLE_CELL *HashBlock,
OUT HCELL_INDEX *HBOffset,
IN ULONG SubKeyCount,
IN HV_STORAGE_TYPE Storage)
{
PHASH_TABLE_CELL NewHashBlock;
ULONG NewHashSize;
NTSTATUS Status;
PHASH_TABLE_CELL NewHashBlock;
ULONG NewHashSize;
NTSTATUS Status;
Status = STATUS_SUCCESS;
*HashBlock = NULL;
NewHashSize = sizeof(HASH_TABLE_CELL) +
(SubKeyCount * sizeof(HASH_RECORD));
*HBOffset = HvAllocateCell (&RegistryHive->Hive, NewHashSize, Storage);
Status = STATUS_SUCCESS;
*HashBlock = NULL;
NewHashSize = sizeof(HASH_TABLE_CELL) +
(SubKeyCount * sizeof(HASH_RECORD));
*HBOffset = HvAllocateCell (&RegistryHive->Hive, NewHashSize, Storage);
if (*HBOffset == HCELL_NULL)
if (*HBOffset == HCELL_NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
Status = STATUS_INSUFFICIENT_RESOURCES;
}
else
else
{
ASSERT(SubKeyCount <= 0xffff); /* should really be USHORT_MAX or similar */
NewHashBlock = HvGetCell (&RegistryHive->Hive, *HBOffset);
NewHashBlock->Id = REG_HASH_TABLE_CELL_ID;
NewHashBlock->HashTableSize = (USHORT)SubKeyCount;
*HashBlock = NewHashBlock;
ASSERT(SubKeyCount <= 0xffff); /* should really be USHORT_MAX or similar */
NewHashBlock = HvGetCell (&RegistryHive->Hive, *HBOffset);
NewHashBlock->Id = REG_HASH_TABLE_CELL_ID;
NewHashBlock->HashTableSize = (USHORT)SubKeyCount;
*HashBlock = NewHashBlock;
}
return Status;
return Status;
}
NTSTATUS
CmiAddKeyToHashTable(PEREGISTRY_HIVE RegistryHive,
PHASH_TABLE_CELL HashCell,
PCM_KEY_NODE KeyCell,
HV_STORAGE_TYPE StorageType,
PCM_KEY_NODE NewKeyCell,
HCELL_INDEX NKBOffset)
PHASH_TABLE_CELL HashCell,
PCM_KEY_NODE KeyCell,
HV_STORAGE_TYPE StorageType,
PCM_KEY_NODE NewKeyCell,
HCELL_INDEX NKBOffset)
{
ULONG i = KeyCell->SubKeyCounts[StorageType];
ULONG i = KeyCell->SubKeyCounts[StorageType];
HashCell->Table[i].KeyOffset = NKBOffset;
HashCell->Table[i].HashValue = 0;
if (NewKeyCell->Flags & REG_KEY_NAME_PACKED)
HashCell->Table[i].KeyOffset = NKBOffset;
HashCell->Table[i].HashValue = 0;
if (NewKeyCell->Flags & REG_KEY_NAME_PACKED)
{
RtlCopyMemory(&HashCell->Table[i].HashValue,
NewKeyCell->Name,
min(NewKeyCell->NameSize, sizeof(ULONG)));
RtlCopyMemory(&HashCell->Table[i].HashValue,
NewKeyCell->Name,
min(NewKeyCell->NameSize, sizeof(ULONG)));
}
HvMarkCellDirty(&RegistryHive->Hive, KeyCell->SubKeyLists[StorageType]);
return STATUS_SUCCESS;
HvMarkCellDirty(&RegistryHive->Hive, KeyCell->SubKeyLists[StorageType]);
return STATUS_SUCCESS;
}
/* EOF */

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,4 @@
/* $Id$
*
/*
* PROJECT: ReactOS Kernel
* COPYRIGHT: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/cm/regobj.c
@ -23,8 +22,8 @@ extern ULONG CmiTimer;
static NTSTATUS
CmiGetLinkTarget(PEREGISTRY_HIVE RegistryHive,
PCM_KEY_NODE KeyCell,
PUNICODE_STRING TargetPath);
PCM_KEY_NODE KeyCell,
PUNICODE_STRING TargetPath);
/* FUNCTONS *****************************************************************/
@ -341,7 +340,8 @@ Next:
return STATUS_SUCCESS;
}
NTSTATUS STDCALL
NTSTATUS
NTAPI
CmpParseKey(IN PVOID ParsedObject,
IN PVOID ObjectType,
IN OUT PACCESS_STATE AccessState,
@ -353,524 +353,519 @@ CmpParseKey(IN PVOID ParsedObject,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
OUT PVOID *NextObject)
{
HCELL_INDEX BlockOffset;
PKEY_OBJECT FoundObject;
PKEY_OBJECT ParsedKey;
PCM_KEY_NODE SubKeyCell;
NTSTATUS Status;
PWSTR StartPtr;
PWSTR EndPtr;
ULONG Length;
UNICODE_STRING LinkPath;
UNICODE_STRING TargetPath;
UNICODE_STRING KeyName;
PWSTR *Path = &RemainingName->Buffer;
HCELL_INDEX BlockOffset;
PKEY_OBJECT FoundObject;
PKEY_OBJECT ParsedKey;
PCM_KEY_NODE SubKeyCell;
NTSTATUS Status;
PWSTR StartPtr;
PWSTR EndPtr;
ULONG Length;
UNICODE_STRING LinkPath;
UNICODE_STRING TargetPath;
UNICODE_STRING KeyName;
PWSTR *Path = &RemainingName->Buffer;
ParsedKey = ParsedObject;
ParsedKey = ParsedObject;
VERIFY_KEY_OBJECT(ParsedKey);
VERIFY_KEY_OBJECT(ParsedKey);
*NextObject = NULL;
*NextObject = NULL;
if ((*Path) == NULL)
if ((*Path) == NULL)
{
DPRINT("*Path is NULL\n");
return STATUS_UNSUCCESSFUL;
DPRINT("*Path is NULL\n");
return STATUS_UNSUCCESSFUL;
}
DPRINT("Path '%S'\n", *Path);
DPRINT("Path '%S'\n", *Path);
/* Extract relevant path name */
StartPtr = *Path;
if (*StartPtr == L'\\')
StartPtr++;
/* Extract relevant path name */
StartPtr = *Path;
if (*StartPtr == L'\\')
StartPtr++;
EndPtr = wcschr(StartPtr, L'\\');
if (EndPtr != NULL)
Length = ((PCHAR)EndPtr - (PCHAR)StartPtr) / sizeof(WCHAR);
else
Length = wcslen(StartPtr);
EndPtr = wcschr(StartPtr, L'\\');
if (EndPtr != NULL)
Length = ((PCHAR)EndPtr - (PCHAR)StartPtr) / sizeof(WCHAR);
else
Length = wcslen(StartPtr);
KeyName.Length = (USHORT)Length * sizeof(WCHAR);
KeyName.MaximumLength = (USHORT)KeyName.Length + sizeof(WCHAR);
KeyName.Buffer = ExAllocatePool(NonPagedPool,
KeyName.MaximumLength);
RtlCopyMemory(KeyName.Buffer,
StartPtr,
KeyName.Length);
KeyName.Buffer[KeyName.Length / sizeof(WCHAR)] = 0;
KeyName.Length = (USHORT)Length * sizeof(WCHAR);
KeyName.MaximumLength = (USHORT)KeyName.Length + sizeof(WCHAR);
KeyName.Buffer = ExAllocatePool(NonPagedPool,
KeyName.MaximumLength);
RtlCopyMemory(KeyName.Buffer,
StartPtr,
KeyName.Length);
KeyName.Buffer[KeyName.Length / sizeof(WCHAR)] = 0;
/* Acquire hive lock */
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
/* Acquire hive lock */
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
Status = CmiScanKeyList(ParsedKey,
&KeyName,
Attributes,
&FoundObject);
if (!NT_SUCCESS(Status))
{
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
RtlFreeUnicodeString(&KeyName);
return Status;
}
if (FoundObject == NULL)
Status = CmiScanKeyList(ParsedKey,
&KeyName,
Attributes,
&FoundObject);
if (!NT_SUCCESS(Status))
{
Status = CmiScanForSubKey(ParsedKey->RegistryHive,
ParsedKey->KeyCell,
&SubKeyCell,
&BlockOffset,
&KeyName,
0,
Attributes);
if (!NT_SUCCESS(Status))
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
RtlFreeUnicodeString(&KeyName);
return Status;
}
if (FoundObject == NULL)
{
Status = CmiScanForSubKey(ParsedKey->RegistryHive,
ParsedKey->KeyCell,
&SubKeyCell,
&BlockOffset,
&KeyName,
0,
Attributes);
if (!NT_SUCCESS(Status))
{
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
RtlFreeUnicodeString(&KeyName);
return(STATUS_UNSUCCESSFUL);
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
RtlFreeUnicodeString(&KeyName);
return(STATUS_UNSUCCESSFUL);
}
if ((SubKeyCell->Flags & REG_KEY_LINK_CELL) &&
!((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)))
if ((SubKeyCell->Flags & REG_KEY_LINK_CELL) &&
!((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)))
{
RtlInitUnicodeString(&LinkPath, NULL);
Status = CmiGetLinkTarget(ParsedKey->RegistryHive,
SubKeyCell,
&LinkPath);
if (NT_SUCCESS(Status))
RtlInitUnicodeString(&LinkPath, NULL);
Status = CmiGetLinkTarget(ParsedKey->RegistryHive,
SubKeyCell,
&LinkPath);
if (NT_SUCCESS(Status))
{
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
DPRINT("LinkPath '%wZ'\n", &LinkPath);
DPRINT("LinkPath '%wZ'\n", &LinkPath);
/* build new FullPath for reparsing */
TargetPath.MaximumLength = LinkPath.MaximumLength;
if (EndPtr != NULL)
/* build new FullPath for reparsing */
TargetPath.MaximumLength = LinkPath.MaximumLength;
if (EndPtr != NULL)
{
TargetPath.MaximumLength += (wcslen(EndPtr) * sizeof(WCHAR));
TargetPath.MaximumLength += (wcslen(EndPtr) * sizeof(WCHAR));
}
TargetPath.Length = TargetPath.MaximumLength - sizeof(WCHAR);
TargetPath.Buffer = ExAllocatePool(NonPagedPool,
TargetPath.MaximumLength);
wcscpy(TargetPath.Buffer, LinkPath.Buffer);
if (EndPtr != NULL)
TargetPath.Length = TargetPath.MaximumLength - sizeof(WCHAR);
TargetPath.Buffer = ExAllocatePool(NonPagedPool,
TargetPath.MaximumLength);
wcscpy(TargetPath.Buffer, LinkPath.Buffer);
if (EndPtr != NULL)
{
wcscat(TargetPath.Buffer, EndPtr);
wcscat(TargetPath.Buffer, EndPtr);
}
RtlFreeUnicodeString(FullPath);
RtlFreeUnicodeString(&LinkPath);
FullPath->Length = TargetPath.Length;
FullPath->MaximumLength = TargetPath.MaximumLength;
FullPath->Buffer = TargetPath.Buffer;
RtlFreeUnicodeString(FullPath);
RtlFreeUnicodeString(&LinkPath);
FullPath->Length = TargetPath.Length;
FullPath->MaximumLength = TargetPath.MaximumLength;
FullPath->Buffer = TargetPath.Buffer;
DPRINT("FullPath '%wZ'\n", FullPath);
DPRINT("FullPath '%wZ'\n", FullPath);
/* reinitialize Path for reparsing */
*Path = FullPath->Buffer;
/* reinitialize Path for reparsing */
*Path = FullPath->Buffer;
*NextObject = NULL;
*NextObject = NULL;
RtlFreeUnicodeString(&KeyName);
return(STATUS_REPARSE);
}
RtlFreeUnicodeString(&KeyName);
return(STATUS_REPARSE);
}
}
/* Create new key object and put into linked list */
DPRINT("CmpParseKey: %S\n", *Path);
Status = ObCreateObject(KernelMode,
CmpKeyObjectType,
NULL,
KernelMode,
NULL,
sizeof(KEY_OBJECT),
0,
0,
(PVOID*)&FoundObject);
if (!NT_SUCCESS(Status))
/* Create new key object and put into linked list */
DPRINT("CmpParseKey: %S\n", *Path);
Status = ObCreateObject(KernelMode,
CmpKeyObjectType,
NULL,
KernelMode,
NULL,
sizeof(KEY_OBJECT),
0,
0,
(PVOID*)&FoundObject);
if (!NT_SUCCESS(Status))
{
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
RtlFreeUnicodeString(&KeyName);
return(Status);
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
RtlFreeUnicodeString(&KeyName);
return(Status);
}
#if 0
DPRINT("Inserting Key into Object Tree\n");
Status = ObInsertObject((PVOID)FoundObject,
NULL,
KEY_ALL_ACCESS,
0,
NULL,
NULL);
DPRINT("Status %x\n", Status);
DPRINT("Inserting Key into Object Tree\n");
Status = ObInsertObject((PVOID)FoundObject,
NULL,
KEY_ALL_ACCESS,
0,
NULL,
NULL);
DPRINT("Status %x\n", Status);
#else
/* Free the create information */
ObpFreeAndReleaseCapturedAttributes(OBJECT_TO_OBJECT_HEADER(FoundObject)->ObjectCreateInfo);
OBJECT_TO_OBJECT_HEADER(FoundObject)->ObjectCreateInfo = NULL;
/* Free the create information */
ObpFreeAndReleaseCapturedAttributes(OBJECT_TO_OBJECT_HEADER(FoundObject)->ObjectCreateInfo);
OBJECT_TO_OBJECT_HEADER(FoundObject)->ObjectCreateInfo = NULL;
#endif
/* Add the keep-alive reference */
ObReferenceObject(FoundObject);
/* Add the keep-alive reference */
ObReferenceObject(FoundObject);
FoundObject->Flags = 0;
FoundObject->KeyCell = SubKeyCell;
FoundObject->KeyCellOffset = BlockOffset;
FoundObject->RegistryHive = ParsedKey->RegistryHive;
InsertTailList(&CmiKeyObjectListHead, &FoundObject->ListEntry);
RtlpCreateUnicodeString(&FoundObject->Name, KeyName.Buffer, NonPagedPool);
CmiAddKeyToList(ParsedKey, FoundObject);
DPRINT("Created object 0x%p\n", FoundObject);
FoundObject->Flags = 0;
FoundObject->KeyCell = SubKeyCell;
FoundObject->KeyCellOffset = BlockOffset;
FoundObject->RegistryHive = ParsedKey->RegistryHive;
InsertTailList(&CmiKeyObjectListHead, &FoundObject->ListEntry);
RtlpCreateUnicodeString(&FoundObject->Name, KeyName.Buffer, NonPagedPool);
CmiAddKeyToList(ParsedKey, FoundObject);
DPRINT("Created object 0x%p\n", FoundObject);
}
else
else
{
if ((FoundObject->KeyCell->Flags & REG_KEY_LINK_CELL) &&
!((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)))
{
DPRINT("Found link\n");
if ((FoundObject->KeyCell->Flags & REG_KEY_LINK_CELL) &&
!((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)))
{
DPRINT("Found link\n");
RtlInitUnicodeString(&LinkPath, NULL);
Status = CmiGetLinkTarget(FoundObject->RegistryHive,
FoundObject->KeyCell,
&LinkPath);
if (NT_SUCCESS(Status))
{
DPRINT("LinkPath '%wZ'\n", &LinkPath);
RtlInitUnicodeString(&LinkPath, NULL);
Status = CmiGetLinkTarget(FoundObject->RegistryHive,
FoundObject->KeyCell,
&LinkPath);
if (NT_SUCCESS(Status))
{
DPRINT("LinkPath '%wZ'\n", &LinkPath);
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
ObDereferenceObject(FoundObject);
ObDereferenceObject(FoundObject);
/* build new FullPath for reparsing */
TargetPath.MaximumLength = LinkPath.MaximumLength;
if (EndPtr != NULL)
{
TargetPath.MaximumLength += (wcslen(EndPtr) * sizeof(WCHAR));
}
TargetPath.Length = TargetPath.MaximumLength - sizeof(WCHAR);
TargetPath.Buffer = ExAllocatePool(NonPagedPool,
TargetPath.MaximumLength);
wcscpy(TargetPath.Buffer, LinkPath.Buffer);
if (EndPtr != NULL)
{
wcscat(TargetPath.Buffer, EndPtr);
}
/* build new FullPath for reparsing */
TargetPath.MaximumLength = LinkPath.MaximumLength;
if (EndPtr != NULL)
{
TargetPath.MaximumLength += (wcslen(EndPtr) * sizeof(WCHAR));
}
TargetPath.Length = TargetPath.MaximumLength - sizeof(WCHAR);
TargetPath.Buffer = ExAllocatePool(NonPagedPool,
TargetPath.MaximumLength);
wcscpy(TargetPath.Buffer, LinkPath.Buffer);
if (EndPtr != NULL)
{
wcscat(TargetPath.Buffer, EndPtr);
}
RtlFreeUnicodeString(FullPath);
RtlFreeUnicodeString(&LinkPath);
FullPath->Length = TargetPath.Length;
FullPath->MaximumLength = TargetPath.MaximumLength;
FullPath->Buffer = TargetPath.Buffer;
RtlFreeUnicodeString(FullPath);
RtlFreeUnicodeString(&LinkPath);
FullPath->Length = TargetPath.Length;
FullPath->MaximumLength = TargetPath.MaximumLength;
FullPath->Buffer = TargetPath.Buffer;
DPRINT("FullPath '%wZ'\n", FullPath);
DPRINT("FullPath '%wZ'\n", FullPath);
/* reinitialize Path for reparsing */
*Path = FullPath->Buffer;
/* reinitialize Path for reparsing */
*Path = FullPath->Buffer;
*NextObject = NULL;
*NextObject = NULL;
RtlFreeUnicodeString(&KeyName);
return(STATUS_REPARSE);
}
}
RtlFreeUnicodeString(&KeyName);
return(STATUS_REPARSE);
}
}
}
RemoveEntryList(&FoundObject->ListEntry);
InsertHeadList(&CmiKeyObjectListHead, &FoundObject->ListEntry);
FoundObject->TimeStamp = CmiTimer;
RemoveEntryList(&FoundObject->ListEntry);
InsertHeadList(&CmiKeyObjectListHead, &FoundObject->ListEntry);
FoundObject->TimeStamp = CmiTimer;
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
DPRINT("CmpParseKey: %wZ\n", &FoundObject->Name);
DPRINT("CmpParseKey: %wZ\n", &FoundObject->Name);
*Path = EndPtr;
*Path = EndPtr;
VERIFY_KEY_OBJECT(FoundObject);
VERIFY_KEY_OBJECT(FoundObject);
*NextObject = FoundObject;
*NextObject = FoundObject;
RtlFreeUnicodeString(&KeyName);
RtlFreeUnicodeString(&KeyName);
return(STATUS_SUCCESS);
return(STATUS_SUCCESS);
}
VOID STDCALL
VOID
NTAPI
CmpDeleteKeyObject(PVOID DeletedObject)
{
PKEY_OBJECT ParentKeyObject;
PKEY_OBJECT KeyObject;
REG_KEY_HANDLE_CLOSE_INFORMATION KeyHandleCloseInfo;
REG_POST_OPERATION_INFORMATION PostOperationInfo;
NTSTATUS Status;
PKEY_OBJECT ParentKeyObject;
PKEY_OBJECT KeyObject;
REG_KEY_HANDLE_CLOSE_INFORMATION KeyHandleCloseInfo;
REG_POST_OPERATION_INFORMATION PostOperationInfo;
NTSTATUS Status;
DPRINT("Delete key object (%p)\n", DeletedObject);
DPRINT("Delete key object (%p)\n", DeletedObject);
KeyObject = (PKEY_OBJECT) DeletedObject;
ParentKeyObject = KeyObject->ParentKey;
KeyObject = (PKEY_OBJECT) DeletedObject;
ParentKeyObject = KeyObject->ParentKey;
ObReferenceObject (ParentKeyObject);
ObReferenceObject (ParentKeyObject);
PostOperationInfo.Object = (PVOID)KeyObject;
KeyHandleCloseInfo.Object = (PVOID)KeyObject;
Status = CmiCallRegisteredCallbacks(RegNtPreKeyHandleClose, &KeyHandleCloseInfo);
if (!NT_SUCCESS(Status))
PostOperationInfo.Object = (PVOID)KeyObject;
KeyHandleCloseInfo.Object = (PVOID)KeyObject;
Status = CmiCallRegisteredCallbacks(RegNtPreKeyHandleClose, &KeyHandleCloseInfo);
if (!NT_SUCCESS(Status))
{
PostOperationInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostKeyHandleClose, &PostOperationInfo);
ObDereferenceObject (ParentKeyObject);
return;
PostOperationInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostKeyHandleClose, &PostOperationInfo);
ObDereferenceObject (ParentKeyObject);
return;
}
/* Acquire hive lock */
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
/* Acquire hive lock */
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
RemoveEntryList(&KeyObject->ListEntry);
RtlFreeUnicodeString(&KeyObject->Name);
RemoveEntryList(&KeyObject->ListEntry);
RtlFreeUnicodeString(&KeyObject->Name);
ASSERT((KeyObject->Flags & KO_MARKED_FOR_DELETE) == FALSE);
ASSERT((KeyObject->Flags & KO_MARKED_FOR_DELETE) == FALSE);
ObDereferenceObject (ParentKeyObject);
ObDereferenceObject (ParentKeyObject);
if (KeyObject->SizeOfSubKeys)
if (KeyObject->SizeOfSubKeys)
{
ExFreePool(KeyObject->SubKeys);
ExFreePool(KeyObject->SubKeys);
}
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
PostOperationInfo.Status = STATUS_SUCCESS;
CmiCallRegisteredCallbacks(RegNtPostKeyHandleClose, &PostOperationInfo);
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
PostOperationInfo.Status = STATUS_SUCCESS;
CmiCallRegisteredCallbacks(RegNtPostKeyHandleClose, &PostOperationInfo);
}
NTSTATUS STDCALL
CmpQueryKeyName (PVOID ObjectBody,
IN BOOLEAN HasName,
POBJECT_NAME_INFORMATION ObjectNameInfo,
ULONG Length,
PULONG ReturnLength,
IN KPROCESSOR_MODE PreviousMode)
NTSTATUS
NTAPI
CmpQueryKeyName(PVOID ObjectBody,
IN BOOLEAN HasName,
POBJECT_NAME_INFORMATION ObjectNameInfo,
ULONG Length,
PULONG ReturnLength,
IN KPROCESSOR_MODE PreviousMode)
{
PKEY_OBJECT KeyObject;
NTSTATUS Status;
PKEY_OBJECT KeyObject;
NTSTATUS Status;
DPRINT ("CmpQueryKeyName() called\n");
DPRINT ("CmpQueryKeyName() called\n");
KeyObject = (PKEY_OBJECT)ObjectBody;
KeyObject = (PKEY_OBJECT)ObjectBody;
if (KeyObject->ParentKey != KeyObject)
if (KeyObject->ParentKey != KeyObject)
{
Status = ObQueryNameString (KeyObject->ParentKey,
ObjectNameInfo,
Length,
ReturnLength);
Status = ObQueryNameString (KeyObject->ParentKey,
ObjectNameInfo,
Length,
ReturnLength);
}
else
else
{
/* KeyObject is the root key */
Status = ObQueryNameString (OBJECT_HEADER_TO_NAME_INFO(OBJECT_TO_OBJECT_HEADER(KeyObject))->Directory,
ObjectNameInfo,
Length,
ReturnLength);
/* KeyObject is the root key */
Status = ObQueryNameString (OBJECT_HEADER_TO_NAME_INFO(OBJECT_TO_OBJECT_HEADER(KeyObject))->Directory,
ObjectNameInfo,
Length,
ReturnLength);
}
if (!NT_SUCCESS(Status) && Status != STATUS_INFO_LENGTH_MISMATCH)
if (!NT_SUCCESS(Status) && Status != STATUS_INFO_LENGTH_MISMATCH)
{
return Status;
return Status;
}
(*ReturnLength) += sizeof(WCHAR) + KeyObject->Name.Length;
(*ReturnLength) += sizeof(WCHAR) + KeyObject->Name.Length;
if (Status == STATUS_INFO_LENGTH_MISMATCH || *ReturnLength > Length)
if (Status == STATUS_INFO_LENGTH_MISMATCH || *ReturnLength > Length)
{
return STATUS_INFO_LENGTH_MISMATCH;
return STATUS_INFO_LENGTH_MISMATCH;
}
if (ObjectNameInfo->Name.Buffer == NULL)
if (ObjectNameInfo->Name.Buffer == NULL)
{
ObjectNameInfo->Name.Buffer = (PWCHAR)(ObjectNameInfo + 1);
ObjectNameInfo->Name.Length = 0;
ObjectNameInfo->Name.MaximumLength = (USHORT)Length - sizeof(OBJECT_NAME_INFORMATION);
ObjectNameInfo->Name.Buffer = (PWCHAR)(ObjectNameInfo + 1);
ObjectNameInfo->Name.Length = 0;
ObjectNameInfo->Name.MaximumLength = (USHORT)Length - sizeof(OBJECT_NAME_INFORMATION);
}
DPRINT ("Parent path: %wZ\n", ObjectNameInfo->Name);
DPRINT ("Parent path: %wZ\n", ObjectNameInfo->Name);
Status = RtlAppendUnicodeToString (&ObjectNameInfo->Name,
L"\\");
if (!NT_SUCCESS (Status))
return Status;
Status = RtlAppendUnicodeStringToString (&ObjectNameInfo->Name,
&KeyObject->Name);
if (NT_SUCCESS (Status))
{
DPRINT ("Total path: %wZ\n", &ObjectNameInfo->Name);
}
Status = RtlAppendUnicodeToString (&ObjectNameInfo->Name,
L"\\");
if (!NT_SUCCESS (Status))
return Status;
Status = RtlAppendUnicodeStringToString (&ObjectNameInfo->Name,
&KeyObject->Name);
if (NT_SUCCESS (Status))
{
DPRINT ("Total path: %wZ\n", &ObjectNameInfo->Name);
}
return Status;
}
VOID
CmiAddKeyToList(PKEY_OBJECT ParentKey,
PKEY_OBJECT NewKey)
PKEY_OBJECT NewKey)
{
DPRINT("ParentKey %.08x\n", ParentKey);
DPRINT("ParentKey %.08x\n", ParentKey);
if (ParentKey->SizeOfSubKeys <= ParentKey->SubKeyCounts)
if (ParentKey->SizeOfSubKeys <= ParentKey->SubKeyCounts)
{
PKEY_OBJECT *tmpSubKeys = ExAllocatePool(NonPagedPool,
(ParentKey->SubKeyCounts + 1) * sizeof(ULONG));
PKEY_OBJECT *tmpSubKeys = ExAllocatePool(NonPagedPool,
(ParentKey->SubKeyCounts + 1) * sizeof(ULONG));
if (ParentKey->SubKeyCounts > 0)
{
RtlCopyMemory (tmpSubKeys,
ParentKey->SubKeys,
ParentKey->SubKeyCounts * sizeof(ULONG));
}
if (ParentKey->SubKeyCounts > 0)
{
RtlCopyMemory (tmpSubKeys,
ParentKey->SubKeys,
ParentKey->SubKeyCounts * sizeof(ULONG));
}
if (ParentKey->SubKeys)
ExFreePool(ParentKey->SubKeys);
if (ParentKey->SubKeys)
ExFreePool(ParentKey->SubKeys);
ParentKey->SubKeys = tmpSubKeys;
ParentKey->SizeOfSubKeys = ParentKey->SubKeyCounts + 1;
ParentKey->SubKeys = tmpSubKeys;
ParentKey->SizeOfSubKeys = ParentKey->SubKeyCounts + 1;
}
/* FIXME: Please maintain the list in alphabetic order */
/* to allow a dichotomic search */
ParentKey->SubKeys[ParentKey->SubKeyCounts++] = NewKey;
/* FIXME: Please maintain the list in alphabetic order */
/* to allow a dichotomic search */
ParentKey->SubKeys[ParentKey->SubKeyCounts++] = NewKey;
DPRINT("Reference parent key: 0x%p\n", ParentKey);
DPRINT("Reference parent key: 0x%p\n", ParentKey);
ObReferenceObjectByPointer(ParentKey,
STANDARD_RIGHTS_REQUIRED,
CmpKeyObjectType,
KernelMode);
NewKey->ParentKey = ParentKey;
ObReferenceObjectByPointer(ParentKey,
STANDARD_RIGHTS_REQUIRED,
CmpKeyObjectType,
KernelMode);
NewKey->ParentKey = ParentKey;
}
NTSTATUS
CmiScanKeyList(PKEY_OBJECT Parent,
PUNICODE_STRING KeyName,
ULONG Attributes,
PKEY_OBJECT* ReturnedObject)
PUNICODE_STRING KeyName,
ULONG Attributes,
PKEY_OBJECT* ReturnedObject)
{
PKEY_OBJECT CurKey = NULL;
ULONG Index;
PKEY_OBJECT CurKey = NULL;
ULONG Index;
DPRINT("Scanning key list for: %wZ (Parent: %wZ)\n",
KeyName, &Parent->Name);
DPRINT("Scanning key list for: %wZ (Parent: %wZ)\n",
KeyName, &Parent->Name);
/* FIXME: if list maintained in alphabetic order, use dichotomic search */
for (Index=0; Index < Parent->SubKeyCounts; Index++)
/* FIXME: if list maintained in alphabetic order, use dichotomic search */
for (Index=0; Index < Parent->SubKeyCounts; Index++)
{
CurKey = Parent->SubKeys[Index];
if (Attributes & OBJ_CASE_INSENSITIVE)
{
DPRINT("Comparing %wZ and %wZ\n", KeyName, &CurKey->Name);
if ((KeyName->Length == CurKey->Name.Length)
&& (_wcsicmp(KeyName->Buffer, CurKey->Name.Buffer) == 0))
{
break;
}
}
else
{
if ((KeyName->Length == CurKey->Name.Length)
&& (wcscmp(KeyName->Buffer, CurKey->Name.Buffer) == 0))
{
break;
}
}
CurKey = Parent->SubKeys[Index];
if (Attributes & OBJ_CASE_INSENSITIVE)
{
DPRINT("Comparing %wZ and %wZ\n", KeyName, &CurKey->Name);
if ((KeyName->Length == CurKey->Name.Length)
&& (_wcsicmp(KeyName->Buffer, CurKey->Name.Buffer) == 0))
{
break;
}
}
else
{
if ((KeyName->Length == CurKey->Name.Length)
&& (wcscmp(KeyName->Buffer, CurKey->Name.Buffer) == 0))
{
break;
}
}
}
if (Index < Parent->SubKeyCounts)
{
if (CurKey->Flags & KO_MARKED_FOR_DELETE)
{
CHECKPOINT;
if (Index < Parent->SubKeyCounts)
{
if (CurKey->Flags & KO_MARKED_FOR_DELETE)
{
CHECKPOINT;
*ReturnedObject = NULL;
return STATUS_UNSUCCESSFUL;
}
ObReferenceObject(CurKey);
*ReturnedObject = CurKey;
}
else
{
*ReturnedObject = NULL;
return STATUS_UNSUCCESSFUL;
}
ObReferenceObject(CurKey);
*ReturnedObject = CurKey;
}
else
{
*ReturnedObject = NULL;
}
return STATUS_SUCCESS;
}
return STATUS_SUCCESS;
}
static NTSTATUS
CmiGetLinkTarget(PEREGISTRY_HIVE RegistryHive,
PCM_KEY_NODE KeyCell,
PUNICODE_STRING TargetPath)
PCM_KEY_NODE KeyCell,
PUNICODE_STRING TargetPath)
{
UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"SymbolicLinkValue");
PCM_KEY_VALUE ValueCell;
PVOID DataCell;
NTSTATUS Status;
UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"SymbolicLinkValue");
PCM_KEY_VALUE ValueCell;
PVOID DataCell;
NTSTATUS Status;
DPRINT("CmiGetLinkTarget() called\n");
DPRINT("CmiGetLinkTarget() called\n");
/* Get Value block of interest */
Status = CmiScanKeyForValue(RegistryHive,
KeyCell,
&LinkName,
&ValueCell,
NULL);
if (!NT_SUCCESS(Status))
/* Get Value block of interest */
Status = CmiScanKeyForValue(RegistryHive,
KeyCell,
&LinkName,
&ValueCell,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("CmiScanKeyForValue() failed (Status %lx)\n", Status);
return(Status);
DPRINT1("CmiScanKeyForValue() failed (Status %lx)\n", Status);
return(Status);
}
if (ValueCell->DataType != REG_LINK)
if (ValueCell->DataType != REG_LINK)
{
DPRINT1("Type != REG_LINK\n!");
return(STATUS_UNSUCCESSFUL);
DPRINT1("Type != REG_LINK\n!");
return(STATUS_UNSUCCESSFUL);
}
if (TargetPath->Buffer == NULL && TargetPath->MaximumLength == 0)
if (TargetPath->Buffer == NULL && TargetPath->MaximumLength == 0)
{
TargetPath->Length = 0;
TargetPath->MaximumLength = (USHORT)ValueCell->DataSize + sizeof(WCHAR);
TargetPath->Buffer = ExAllocatePool(NonPagedPool,
TargetPath->MaximumLength);
TargetPath->Length = 0;
TargetPath->MaximumLength = (USHORT)ValueCell->DataSize + sizeof(WCHAR);
TargetPath->Buffer = ExAllocatePool(NonPagedPool,
TargetPath->MaximumLength);
}
TargetPath->Length = min((USHORT)TargetPath->MaximumLength - sizeof(WCHAR),
(USHORT)ValueCell->DataSize);
TargetPath->Length = min((USHORT)TargetPath->MaximumLength - sizeof(WCHAR),
(USHORT)ValueCell->DataSize);
if (ValueCell->DataSize > 0)
if (ValueCell->DataSize > 0)
{
DataCell = HvGetCell (&RegistryHive->Hive, ValueCell->DataOffset);
RtlCopyMemory(TargetPath->Buffer,
DataCell,
TargetPath->Length);
TargetPath->Buffer[TargetPath->Length / sizeof(WCHAR)] = 0;
DataCell = HvGetCell (&RegistryHive->Hive, ValueCell->DataOffset);
RtlCopyMemory(TargetPath->Buffer,
DataCell,
TargetPath->Length);
TargetPath->Buffer[TargetPath->Length / sizeof(WCHAR)] = 0;
}
else
else
{
RtlCopyMemory(TargetPath->Buffer,
&ValueCell->DataOffset,
TargetPath->Length);
TargetPath->Buffer[TargetPath->Length / sizeof(WCHAR)] = 0;
RtlCopyMemory(TargetPath->Buffer,
&ValueCell->DataOffset,
TargetPath->Length);
TargetPath->Buffer[TargetPath->Length / sizeof(WCHAR)] = 0;
}
DPRINT("TargetPath '%wZ'\n", TargetPath);
DPRINT("TargetPath '%wZ'\n", TargetPath);
return(STATUS_SUCCESS);
return(STATUS_SUCCESS);
}
/* EOF */