mirror of
https://github.com/reactos/reactos.git
synced 2024-10-15 05:37:44 +00:00
Cleaned up NtSetValueKey() and NtQueryValueKey().
Made CmiScanKeyForValue() more robust. svn path=/trunk/; revision=7602
This commit is contained in:
parent
bc5e5cf2fd
commit
46059ee5d0
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue