Cleaned up NtSetValueKey() and NtQueryValueKey().

Made CmiScanKeyForValue() more robust.

svn path=/trunk/; revision=7602
This commit is contained in:
Eric Kohl 2004-01-13 12:29:27 +00:00
parent bc5e5cf2fd
commit 46059ee5d0
2 changed files with 145 additions and 156 deletions

View file

@ -1012,8 +1012,10 @@ NtQueryKey(IN HANDLE KeyHandle,
} }
} }
break; break;
default:
DPRINT1("Not handling 0x%x\n", KeyInformationClass); default:
DPRINT1("Not handling 0x%x\n", KeyInformationClass);
Status = STATUS_INVALID_INFO_CLASS;
break; break;
} }
@ -1057,7 +1059,7 @@ NtQueryValueKey(IN HANDLE KeyHandle,
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("ObReferenceObjectByHandle() failed with status %x\n", Status); DPRINT1("ObReferenceObjectByHandle() failed with status %x\n", Status);
return Status; return Status;
} }
@ -1071,7 +1073,7 @@ NtQueryValueKey(IN HANDLE KeyHandle,
KeyCell = KeyObject->KeyCell; KeyCell = KeyObject->KeyCell;
RegistryHive = KeyObject->RegistryHive; RegistryHive = KeyObject->RegistryHive;
/* Get Value block of interest */ /* Get value cell by name */
Status = CmiScanKeyForValue(RegistryHive, Status = CmiScanKeyForValue(RegistryHive,
KeyCell, KeyCell,
ValueName, ValueName,
@ -1080,142 +1082,137 @@ NtQueryValueKey(IN HANDLE KeyHandle,
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("CmiScanKeyForValue() failed with status %x\n", Status); DPRINT("CmiScanKeyForValue() failed with status %x\n", Status);
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); goto ByeBye;
KeLeaveCriticalRegion();
ObDereferenceObject(KeyObject);
return(Status);
} }
else if (ValueCell != NULL)
Status = STATUS_SUCCESS;
switch (KeyValueInformationClass)
{ {
switch (KeyValueInformationClass) case KeyValueBasicInformation:
{ NameSize = ValueCell->NameSize;
case KeyValueBasicInformation: if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
NameSize = ValueCell->NameSize; {
if (ValueCell->Flags & REG_VALUE_NAME_PACKED) NameSize *= sizeof(WCHAR);
{ }
NameSize *= sizeof(WCHAR); *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) + NameSize;
} if (Length < *ResultLength)
*ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) + NameSize; {
if (Length < *ResultLength) Status = STATUS_BUFFER_TOO_SMALL;
{ }
Status = STATUS_BUFFER_TOO_SMALL; else
} {
else ValueBasicInformation = (PKEY_VALUE_BASIC_INFORMATION)
{ KeyValueInformation;
ValueBasicInformation = (PKEY_VALUE_BASIC_INFORMATION) ValueBasicInformation->TitleIndex = 0;
KeyValueInformation; ValueBasicInformation->Type = ValueCell->DataType;
ValueBasicInformation->TitleIndex = 0; ValueBasicInformation->NameLength = NameSize;
ValueBasicInformation->Type = ValueCell->DataType; if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
ValueBasicInformation->NameLength = NameSize; {
if (ValueCell->Flags & REG_VALUE_NAME_PACKED) CmiCopyPackedName(ValueBasicInformation->Name,
{ ValueCell->Name,
CmiCopyPackedName(ValueBasicInformation->Name, ValueCell->NameSize);
ValueCell->Name, }
ValueCell->NameSize); else
} {
else RtlCopyMemory(ValueBasicInformation->Name,
{ ValueCell->Name,
RtlCopyMemory(ValueBasicInformation->Name, ValueCell->NameSize * sizeof(WCHAR));
ValueCell->Name, }
ValueCell->NameSize * sizeof(WCHAR)); }
} break;
}
break;
case KeyValuePartialInformation: case KeyValuePartialInformation:
*ResultLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) *ResultLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION)
+ (ValueCell->DataSize & REG_DATA_SIZE_MASK); + (ValueCell->DataSize & REG_DATA_SIZE_MASK);
if (Length < *ResultLength) if (Length < *ResultLength)
{ {
Status = STATUS_BUFFER_TOO_SMALL; Status = STATUS_BUFFER_TOO_SMALL;
} }
else else
{ {
ValuePartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION) ValuePartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)
KeyValueInformation; KeyValueInformation;
ValuePartialInformation->TitleIndex = 0; ValuePartialInformation->TitleIndex = 0;
ValuePartialInformation->Type = ValueCell->DataType; ValuePartialInformation->Type = ValueCell->DataType;
ValuePartialInformation->DataLength = ValueCell->DataSize & REG_DATA_SIZE_MASK; ValuePartialInformation->DataLength = ValueCell->DataSize & REG_DATA_SIZE_MASK;
if (!(ValueCell->DataSize & REG_DATA_IN_OFFSET)) if (!(ValueCell->DataSize & REG_DATA_IN_OFFSET))
{ {
DataCell = CmiGetCell (RegistryHive, ValueCell->DataOffset, NULL); DataCell = CmiGetCell (RegistryHive, ValueCell->DataOffset, NULL);
RtlCopyMemory(ValuePartialInformation->Data, RtlCopyMemory(ValuePartialInformation->Data,
DataCell->Data, DataCell->Data,
ValueCell->DataSize & REG_DATA_SIZE_MASK); ValueCell->DataSize & REG_DATA_SIZE_MASK);
} }
else else
{ {
RtlCopyMemory(ValuePartialInformation->Data, RtlCopyMemory(ValuePartialInformation->Data,
&ValueCell->DataOffset, &ValueCell->DataOffset,
ValueCell->DataSize & REG_DATA_SIZE_MASK); ValueCell->DataSize & REG_DATA_SIZE_MASK);
} }
} }
break; break;
case KeyValueFullInformation: case KeyValueFullInformation:
NameSize = ValueCell->NameSize; NameSize = ValueCell->NameSize;
if (ValueCell->Flags & REG_VALUE_NAME_PACKED) if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
{ {
NameSize *= sizeof(WCHAR); NameSize *= sizeof(WCHAR);
} }
*ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) + *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) +
NameSize + (ValueCell->DataSize & REG_DATA_SIZE_MASK); NameSize + (ValueCell->DataSize & REG_DATA_SIZE_MASK);
if (Length < *ResultLength) if (Length < *ResultLength)
{ {
Status = STATUS_BUFFER_TOO_SMALL; Status = STATUS_BUFFER_TOO_SMALL;
} }
else else
{ {
ValueFullInformation = (PKEY_VALUE_FULL_INFORMATION) ValueFullInformation = (PKEY_VALUE_FULL_INFORMATION)
KeyValueInformation; KeyValueInformation;
ValueFullInformation->TitleIndex = 0; ValueFullInformation->TitleIndex = 0;
ValueFullInformation->Type = ValueCell->DataType; ValueFullInformation->Type = ValueCell->DataType;
ValueFullInformation->NameLength = NameSize; ValueFullInformation->NameLength = NameSize;
if (ValueCell->Flags & REG_VALUE_NAME_PACKED) if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
{ {
CmiCopyPackedName(ValueFullInformation->Name, CmiCopyPackedName(ValueFullInformation->Name,
ValueCell->Name, ValueCell->Name,
ValueCell->NameSize); ValueCell->NameSize);
} }
else else
{ {
RtlCopyMemory(ValueFullInformation->Name, RtlCopyMemory(ValueFullInformation->Name,
ValueCell->Name, ValueCell->Name,
ValueCell->NameSize); ValueCell->NameSize);
} }
ValueFullInformation->DataOffset = ValueFullInformation->DataOffset =
(ULONG)ValueFullInformation->Name - (ULONG)ValueFullInformation + (ULONG)ValueFullInformation->Name - (ULONG)ValueFullInformation +
ValueFullInformation->NameLength; ValueFullInformation->NameLength;
ValueFullInformation->DataOffset = ValueFullInformation->DataOffset =
ROUND_UP(ValueFullInformation->DataOffset, sizeof(PVOID)); ROUND_UP(ValueFullInformation->DataOffset, sizeof(PVOID));
ValueFullInformation->DataLength = ValueCell->DataSize & REG_DATA_SIZE_MASK; ValueFullInformation->DataLength = ValueCell->DataSize & REG_DATA_SIZE_MASK;
if (!(ValueCell->DataSize & REG_DATA_IN_OFFSET)) if (!(ValueCell->DataSize & REG_DATA_IN_OFFSET))
{ {
DataCell = CmiGetCell (RegistryHive, ValueCell->DataOffset, NULL); DataCell = CmiGetCell (RegistryHive, ValueCell->DataOffset, NULL);
RtlCopyMemory((PCHAR) ValueFullInformation RtlCopyMemory((PCHAR) ValueFullInformation
+ ValueFullInformation->DataOffset, + ValueFullInformation->DataOffset,
DataCell->Data, DataCell->Data,
ValueCell->DataSize & REG_DATA_SIZE_MASK); ValueCell->DataSize & REG_DATA_SIZE_MASK);
} }
else else
{ {
RtlCopyMemory((PCHAR) ValueFullInformation RtlCopyMemory((PCHAR) ValueFullInformation
+ ValueFullInformation->DataOffset, + ValueFullInformation->DataOffset,
&ValueCell->DataOffset, &ValueCell->DataOffset,
ValueCell->DataSize & REG_DATA_SIZE_MASK); ValueCell->DataSize & REG_DATA_SIZE_MASK);
} }
} }
break; break;
default:
DPRINT1("Not handling 0x%x\n", KeyValueInformationClass); default:
break; DPRINT1("Not handling 0x%x\n", KeyValueInformationClass);
} Status = STATUS_INVALID_INFO_CLASS;
} break;
else
{
Status = STATUS_OBJECT_NAME_NOT_FOUND;
} }
ByeBye:;
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
@ -1274,17 +1271,7 @@ NtSetValueKey(IN HANDLE KeyHandle,
ValueName, ValueName,
&ValueCell, &ValueCell,
&ValueCellOffset); &ValueCellOffset);
if (!NT_SUCCESS(Status)) if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
{
DPRINT("Value not found. Status 0x%X\n", Status);
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
KeLeaveCriticalRegion();
ObDereferenceObject(KeyObject);
return(Status);
}
if (ValueCell == NULL)
{ {
DPRINT("Allocate new value cell\n"); DPRINT("Allocate new value cell\n");
Status = CmiAddValueToKey(RegistryHive, Status = CmiAddValueToKey(RegistryHive,
@ -1303,9 +1290,9 @@ NtSetValueKey(IN HANDLE KeyHandle,
DPRINT("Cannot add value. Status 0x%X\n", Status); DPRINT("Cannot add value. Status 0x%X\n", Status);
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
return(Status); return Status;
} }
DPRINT("DataSize %lu\n", DataSize); DPRINT("DataSize %lu\n", DataSize);
@ -1368,10 +1355,10 @@ NtSetValueKey(IN HANDLE KeyHandle,
DPRINT("CmiAllocateBlock() failed (Status %lx)\n", Status); DPRINT("CmiAllocateBlock() failed (Status %lx)\n", Status);
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
ObDereferenceObject(KeyObject); ObDereferenceObject(KeyObject);
return(Status); return Status;
} }
RtlCopyMemory(&NewDataCell->Data[0], Data, DataSize); RtlCopyMemory(&NewDataCell->Data[0], Data, DataSize);
@ -1400,7 +1387,7 @@ NtSetValueKey(IN HANDLE KeyHandle,
DPRINT("Return Status 0x%X\n", Status); DPRINT("Return Status 0x%X\n", Status);
return(Status); return Status;
} }

View file

@ -2714,18 +2714,20 @@ CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell, IN PKEY_CELL KeyCell,
IN PUNICODE_STRING ValueName, IN PUNICODE_STRING ValueName,
OUT PVALUE_CELL *ValueCell, OUT PVALUE_CELL *ValueCell,
OUT BLOCK_OFFSET *VBOffset) OUT BLOCK_OFFSET *ValueCellOffset)
{ {
PVALUE_LIST_CELL ValueListCell; PVALUE_LIST_CELL ValueListCell;
PVALUE_CELL CurValueCell; PVALUE_CELL CurValueCell;
ULONG i; ULONG i;
*ValueCell = NULL; *ValueCell = NULL;
if (ValueCellOffset != NULL)
*ValueCellOffset = (BLOCK_OFFSET)-1;
/* The key does not have any values */ /* The key does not have any values */
if (KeyCell->ValueListOffset == (BLOCK_OFFSET)-1) if (KeyCell->ValueListOffset == (BLOCK_OFFSET)-1)
{ {
return STATUS_SUCCESS; return STATUS_OBJECT_NAME_NOT_FOUND;
} }
ValueListCell = CmiGetCell (RegistryHive, KeyCell->ValueListOffset, NULL); ValueListCell = CmiGetCell (RegistryHive, KeyCell->ValueListOffset, NULL);
@ -2755,14 +2757,14 @@ CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
(BOOLEAN)((CurValueCell->Flags & REG_VALUE_NAME_PACKED) ? TRUE : FALSE))) (BOOLEAN)((CurValueCell->Flags & REG_VALUE_NAME_PACKED) ? TRUE : FALSE)))
{ {
*ValueCell = CurValueCell; *ValueCell = CurValueCell;
if (VBOffset) if (ValueCellOffset != NULL)
*VBOffset = ValueListCell->ValueOffset[i]; *ValueCellOffset = ValueListCell->ValueOffset[i];
//DPRINT("Found value %s\n", ValueName); //DPRINT("Found value %s\n", ValueName);
break; return STATUS_SUCCESS;
} }
} }
return STATUS_SUCCESS; return STATUS_OBJECT_NAME_NOT_FOUND;
} }