mirror of
https://github.com/reactos/reactos.git
synced 2024-07-21 03:37:57 +00:00
[FORMATTING]
Fix formatting, to have an indentation of 4 spaces No code change svn path=/trunk/; revision=27553
This commit is contained in:
parent
4216adf631
commit
8b12884393
File diff suppressed because it is too large
Load diff
|
@ -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
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue