mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 16:52:59 +00:00
report changes from 1.29
svn path=/trunk/; revision=1359
This commit is contained in:
parent
ad66ea993a
commit
522110434e
1 changed files with 192 additions and 19 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: registry.c,v 1.32 2000/09/13 09:51:58 jean Exp $
|
/* $Id: registry.c,v 1.33 2000/09/13 11:46:35 jean Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
#include <internal/ob.h>
|
#include <internal/ob.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
|
||||||
//#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
#define PROTO_REG 1 /* Comment out to disable */
|
#define PROTO_REG 1 /* Comment out to disable */
|
||||||
|
@ -235,6 +235,10 @@ static NTSTATUS CmiScanKeyForValue(IN PREGISTRY_FILE RegistryFile,
|
||||||
IN PKEY_BLOCK KeyBlock,
|
IN PKEY_BLOCK KeyBlock,
|
||||||
IN PWSTR ValueName,
|
IN PWSTR ValueName,
|
||||||
OUT PVALUE_BLOCK *ValueBlock);
|
OUT PVALUE_BLOCK *ValueBlock);
|
||||||
|
static NTSTATUS CmiGetValueFromKeyByIndex(IN PREGISTRY_FILE RegistryFile,
|
||||||
|
IN PKEY_BLOCK KeyBlock,
|
||||||
|
IN ULONG Index,
|
||||||
|
OUT PVALUE_BLOCK *ValueBlock);
|
||||||
static NTSTATUS CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
|
static NTSTATUS CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
|
||||||
IN PKEY_BLOCK KeyBlock,
|
IN PKEY_BLOCK KeyBlock,
|
||||||
IN PWSTR ValueNameBuf,
|
IN PWSTR ValueNameBuf,
|
||||||
|
@ -479,7 +483,10 @@ NtCreateKey (
|
||||||
FALSE,
|
FALSE,
|
||||||
KeyHandle);
|
KeyHandle);
|
||||||
ExFreePool(KeyNameBuf);
|
ExFreePool(KeyNameBuf);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
*Disposition = REG_OPENED_EXISTING_KEY;
|
||||||
|
}
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,11 +521,15 @@ NtCreateKey (
|
||||||
NewKey->RegistryFile = FileToUse;
|
NewKey->RegistryFile = FileToUse;
|
||||||
CmiAddKeyToList(NewKey);
|
CmiAddKeyToList(NewKey);
|
||||||
Status = ObCreateHandle(PsGetCurrentProcess(),
|
Status = ObCreateHandle(PsGetCurrentProcess(),
|
||||||
CurKey,
|
NewKey,
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
FALSE,
|
FALSE,
|
||||||
KeyHandle);
|
KeyHandle);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
*Disposition = REG_CREATED_NEW_KEY;
|
||||||
|
}
|
||||||
return Status;
|
return Status;
|
||||||
#else
|
#else
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
|
@ -616,7 +627,7 @@ NtEnumerateKey (
|
||||||
case KeyBasicInformation:
|
case KeyBasicInformation:
|
||||||
/* Check size of buffer */
|
/* Check size of buffer */
|
||||||
if (Length < sizeof(KEY_BASIC_INFORMATION) +
|
if (Length < sizeof(KEY_BASIC_INFORMATION) +
|
||||||
SubKeyBlock->NameSize * sizeof(WCHAR))
|
(SubKeyBlock->NameSize + 1) * sizeof(WCHAR))
|
||||||
{
|
{
|
||||||
Status = STATUS_BUFFER_OVERFLOW;
|
Status = STATUS_BUFFER_OVERFLOW;
|
||||||
}
|
}
|
||||||
|
@ -626,7 +637,7 @@ NtEnumerateKey (
|
||||||
BasicInformation = (PKEY_BASIC_INFORMATION) KeyInformation;
|
BasicInformation = (PKEY_BASIC_INFORMATION) KeyInformation;
|
||||||
BasicInformation->LastWriteTime = SubKeyBlock->LastWriteTime;
|
BasicInformation->LastWriteTime = SubKeyBlock->LastWriteTime;
|
||||||
BasicInformation->TitleIndex = Index;
|
BasicInformation->TitleIndex = Index;
|
||||||
BasicInformation->NameLength = SubKeyBlock->NameSize;
|
BasicInformation->NameLength = (SubKeyBlock->NameSize + 1) * sizeof(WCHAR);
|
||||||
wcsncpy(BasicInformation->Name,
|
wcsncpy(BasicInformation->Name,
|
||||||
SubKeyBlock->Name,
|
SubKeyBlock->Name,
|
||||||
SubKeyBlock->NameSize);
|
SubKeyBlock->NameSize);
|
||||||
|
@ -639,7 +650,7 @@ NtEnumerateKey (
|
||||||
case KeyNodeInformation:
|
case KeyNodeInformation:
|
||||||
/* Check size of buffer */
|
/* Check size of buffer */
|
||||||
if (Length < sizeof(KEY_NODE_INFORMATION) +
|
if (Length < sizeof(KEY_NODE_INFORMATION) +
|
||||||
SubKeyBlock->NameSize * sizeof(WCHAR) +
|
(SubKeyBlock->NameSize + 1) * sizeof(WCHAR) +
|
||||||
(SubKeyBlock->ClassSize + 1) * sizeof(WCHAR))
|
(SubKeyBlock->ClassSize + 1) * sizeof(WCHAR))
|
||||||
{
|
{
|
||||||
Status = STATUS_BUFFER_OVERFLOW;
|
Status = STATUS_BUFFER_OVERFLOW;
|
||||||
|
@ -653,7 +664,7 @@ NtEnumerateKey (
|
||||||
NodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) +
|
NodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) +
|
||||||
SubKeyBlock->NameSize * sizeof(WCHAR);
|
SubKeyBlock->NameSize * sizeof(WCHAR);
|
||||||
NodeInformation->ClassLength = SubKeyBlock->ClassSize;
|
NodeInformation->ClassLength = SubKeyBlock->ClassSize;
|
||||||
NodeInformation->NameLength = SubKeyBlock->NameSize;
|
NodeInformation->NameLength = (SubKeyBlock->NameSize + 1) * sizeof(WCHAR);
|
||||||
wcsncpy(NodeInformation->Name,
|
wcsncpy(NodeInformation->Name,
|
||||||
SubKeyBlock->Name,
|
SubKeyBlock->Name,
|
||||||
SubKeyBlock->NameSize);
|
SubKeyBlock->NameSize);
|
||||||
|
@ -708,6 +719,7 @@ NtEnumerateKey (
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CmiReleaseBlock(RegistryFile, SubKeyBlock);
|
CmiReleaseBlock(RegistryFile, SubKeyBlock);
|
||||||
|
ObDereferenceObject (KeyObject);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
#else
|
#else
|
||||||
|
@ -721,14 +733,129 @@ STDCALL
|
||||||
NtEnumerateValueKey (
|
NtEnumerateValueKey (
|
||||||
IN HANDLE KeyHandle,
|
IN HANDLE KeyHandle,
|
||||||
IN ULONG Index,
|
IN ULONG Index,
|
||||||
IN KEY_VALUE_INFORMATION_CLASS KeyInformationClass,
|
IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
|
||||||
OUT PVOID KeyInformation,
|
OUT PVOID KeyValueInformation,
|
||||||
IN ULONG Length,
|
IN ULONG Length,
|
||||||
OUT PULONG ResultLength
|
OUT PULONG ResultLength
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
#ifdef PROTO_REG
|
#ifdef PROTO_REG
|
||||||
UNIMPLEMENTED;
|
NTSTATUS Status;
|
||||||
|
PKEY_OBJECT KeyObject;
|
||||||
|
PREGISTRY_FILE RegistryFile;
|
||||||
|
PKEY_BLOCK KeyBlock;
|
||||||
|
PVALUE_BLOCK ValueBlock;
|
||||||
|
PVOID DataBlock;
|
||||||
|
PKEY_VALUE_BASIC_INFORMATION ValueBasicInformation;
|
||||||
|
PKEY_VALUE_PARTIAL_INFORMATION ValuePartialInformation;
|
||||||
|
PKEY_VALUE_FULL_INFORMATION ValueFullInformation;
|
||||||
|
|
||||||
|
/* Verify that the handle is valid and is a registry key */
|
||||||
|
Status = ObReferenceObjectByHandle(KeyHandle,
|
||||||
|
KEY_QUERY_VALUE,
|
||||||
|
CmiKeyType,
|
||||||
|
UserMode,
|
||||||
|
(PVOID *)&KeyObject,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get pointer to KeyBlock */
|
||||||
|
KeyBlock = KeyObject->KeyBlock;
|
||||||
|
RegistryFile = KeyObject->RegistryFile;
|
||||||
|
|
||||||
|
/* Get Value block of interest */
|
||||||
|
Status = CmiGetValueFromKeyByIndex(RegistryFile,
|
||||||
|
KeyBlock,
|
||||||
|
Index,
|
||||||
|
&ValueBlock);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
else if (ValueBlock != NULL)
|
||||||
|
{
|
||||||
|
switch (KeyValueInformationClass)
|
||||||
|
{
|
||||||
|
case KeyValueBasicInformation:
|
||||||
|
*ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) +
|
||||||
|
(ValueBlock->NameSize + 1) * sizeof(WCHAR);
|
||||||
|
if (Length < *ResultLength)
|
||||||
|
{
|
||||||
|
Status = STATUS_BUFFER_OVERFLOW;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ValueBasicInformation = (PKEY_VALUE_BASIC_INFORMATION)
|
||||||
|
KeyValueInformation;
|
||||||
|
ValueBasicInformation->TitleIndex = 0;
|
||||||
|
ValueBasicInformation->Type = ValueBlock->DataType;
|
||||||
|
ValueBasicInformation->NameLength =
|
||||||
|
(ValueBlock->NameSize + 1) * sizeof(WCHAR);
|
||||||
|
wcscpy(ValueBasicInformation->Name, ValueBlock->Name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KeyValuePartialInformation:
|
||||||
|
*ResultLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
|
||||||
|
ValueBlock->DataSize;
|
||||||
|
if (Length < *ResultLength)
|
||||||
|
{
|
||||||
|
Status = STATUS_BUFFER_OVERFLOW;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ValuePartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)
|
||||||
|
KeyValueInformation;
|
||||||
|
ValuePartialInformation->TitleIndex = 0;
|
||||||
|
ValuePartialInformation->Type = ValueBlock->DataType;
|
||||||
|
ValuePartialInformation->DataLength = ValueBlock->DataSize;
|
||||||
|
DataBlock = CmiGetBlock(RegistryFile, ValueBlock->DataOffset);
|
||||||
|
RtlCopyMemory(ValuePartialInformation->Data,
|
||||||
|
DataBlock,
|
||||||
|
ValueBlock->DataSize);
|
||||||
|
CmiReleaseBlock(RegistryFile, DataBlock);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KeyValueFullInformation:
|
||||||
|
*ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) +
|
||||||
|
(ValueBlock->NameSize + 1) * sizeof(WCHAR) + ValueBlock->DataSize;
|
||||||
|
if (Length < *ResultLength)
|
||||||
|
{
|
||||||
|
Status = STATUS_BUFFER_OVERFLOW;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ValueFullInformation = (PKEY_VALUE_FULL_INFORMATION)
|
||||||
|
KeyValueInformation;
|
||||||
|
ValueFullInformation->TitleIndex = 0;
|
||||||
|
ValueFullInformation->Type = ValueBlock->DataType;
|
||||||
|
ValueFullInformation->DataOffset =
|
||||||
|
sizeof(KEY_VALUE_FULL_INFORMATION) +
|
||||||
|
ValueBlock->NameSize * sizeof(WCHAR);
|
||||||
|
ValueFullInformation->DataLength = ValueBlock->DataSize;
|
||||||
|
ValueFullInformation->NameLength =
|
||||||
|
(ValueBlock->NameSize + 1) * sizeof(WCHAR);
|
||||||
|
wcscpy(ValueFullInformation->Name, ValueBlock->Name);
|
||||||
|
DataBlock = CmiGetBlock(RegistryFile, ValueBlock->DataOffset);
|
||||||
|
RtlCopyMemory(&ValueFullInformation->Name[ValueBlock->NameSize + 1],
|
||||||
|
DataBlock,
|
||||||
|
ValueBlock->DataSize);
|
||||||
|
CmiReleaseBlock(RegistryFile, DataBlock);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
ObDereferenceObject(KeyObject);
|
||||||
|
|
||||||
|
return Status;
|
||||||
#else
|
#else
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
#endif
|
#endif
|
||||||
|
@ -834,7 +961,7 @@ NtOpenKey (
|
||||||
NewKey->KeyBlock = KeyBlock;
|
NewKey->KeyBlock = KeyBlock;
|
||||||
CmiAddKeyToList(NewKey);
|
CmiAddKeyToList(NewKey);
|
||||||
Status = ObCreateHandle(PsGetCurrentProcess(),
|
Status = ObCreateHandle(PsGetCurrentProcess(),
|
||||||
CurKey,
|
NewKey,
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
FALSE,
|
FALSE,
|
||||||
KeyHandle);
|
KeyHandle);
|
||||||
|
@ -978,6 +1105,7 @@ NtQueryKey (
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
ObDereferenceObject (KeyObject);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
#else
|
#else
|
||||||
|
@ -1109,6 +1237,7 @@ NtQueryValueKey (
|
||||||
{
|
{
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
ObDereferenceObject(KeyObject);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
#else
|
#else
|
||||||
|
@ -1137,7 +1266,7 @@ NtSetValueKey (
|
||||||
|
|
||||||
/* Verify that the handle is valid and is a registry key */
|
/* Verify that the handle is valid and is a registry key */
|
||||||
Status = ObReferenceObjectByHandle(KeyHandle,
|
Status = ObReferenceObjectByHandle(KeyHandle,
|
||||||
KEY_QUERY_VALUE,
|
KEY_SET_VALUE,
|
||||||
CmiKeyType,
|
CmiKeyType,
|
||||||
UserMode,
|
UserMode,
|
||||||
(PVOID *)&KeyObject,
|
(PVOID *)&KeyObject,
|
||||||
|
@ -1156,6 +1285,7 @@ NtSetValueKey (
|
||||||
&ValueBlock);
|
&ValueBlock);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
ObDereferenceObject (KeyObject);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
if (ValueBlock == NULL)
|
if (ValueBlock == NULL)
|
||||||
|
@ -1175,6 +1305,7 @@ NtSetValueKey (
|
||||||
Data,
|
Data,
|
||||||
DataSize);
|
DataSize);
|
||||||
}
|
}
|
||||||
|
ObDereferenceObject (KeyObject);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
#else
|
#else
|
||||||
|
@ -1213,6 +1344,7 @@ NtDeleteValueKey (
|
||||||
Status = CmiDeleteValueFromKey(RegistryFile,
|
Status = CmiDeleteValueFromKey(RegistryFile,
|
||||||
KeyBlock,
|
KeyBlock,
|
||||||
ValueName->Buffer);
|
ValueName->Buffer);
|
||||||
|
ObDereferenceObject(KeyObject);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
#else
|
#else
|
||||||
|
@ -1227,7 +1359,9 @@ NtLoadKey (
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes
|
OBJECT_ATTRIBUTES ObjectAttributes
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
return NtLoadKey2(KeyHandle,
|
||||||
|
ObjectAttributes,
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1557,7 +1691,7 @@ CmiBuildKeyPath(PWSTR *KeyPath, POBJECT_ATTRIBUTES ObjectAttributes)
|
||||||
Status = ObReferenceObjectByHandle(ObjectAttributes->RootDirectory,
|
Status = ObReferenceObjectByHandle(ObjectAttributes->RootDirectory,
|
||||||
KEY_READ,
|
KEY_READ,
|
||||||
NULL,
|
NULL,
|
||||||
UserMode,
|
KernelMode,
|
||||||
(PVOID *)&ObjectBody,
|
(PVOID *)&ObjectBody,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -1940,6 +2074,9 @@ CmiFindKey(IN PREGISTRY_FILE RegistryFile,
|
||||||
PWSTR Remainder, NextSlash;
|
PWSTR Remainder, NextSlash;
|
||||||
PKEY_BLOCK CurKeyBlock, SubKeyBlock;
|
PKEY_BLOCK CurKeyBlock, SubKeyBlock;
|
||||||
|
|
||||||
|
if (RegistryFile == NULL)
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
/* FIXME: Should handle search by Class/TitleIndex */
|
/* FIXME: Should handle search by Class/TitleIndex */
|
||||||
|
|
||||||
/* Loop through each key level and find the needed subkey */
|
/* Loop through each key level and find the needed subkey */
|
||||||
|
@ -1947,6 +2084,7 @@ CmiFindKey(IN PREGISTRY_FILE RegistryFile,
|
||||||
/* FIXME: this access of RootKeyBlock should be guarded by spinlock */
|
/* FIXME: this access of RootKeyBlock should be guarded by spinlock */
|
||||||
CurKeyBlock = CmiGetBlock(RegistryFile, RegistryFile->HeaderBlock->RootKeyBlock);
|
CurKeyBlock = CmiGetBlock(RegistryFile, RegistryFile->HeaderBlock->RootKeyBlock);
|
||||||
Remainder = KeyNameBuf;
|
Remainder = KeyNameBuf;
|
||||||
|
wcscpy(CurKeyName, Remainder);
|
||||||
while (NT_SUCCESS(Status) &&
|
while (NT_SUCCESS(Status) &&
|
||||||
(NextSlash = wcschr(Remainder, L'\\')) != NULL)
|
(NextSlash = wcschr(Remainder, L'\\')) != NULL)
|
||||||
{
|
{
|
||||||
|
@ -2148,7 +2286,7 @@ CmiScanForSubKey(IN PREGISTRY_FILE RegistryFile,
|
||||||
for (Idx = 0; Idx < HashBlock->HashTableSize; Idx++)
|
for (Idx = 0; Idx < HashBlock->HashTableSize; Idx++)
|
||||||
{
|
{
|
||||||
if (HashBlock->Table[Idx].KeyOffset != 0 &&
|
if (HashBlock->Table[Idx].KeyOffset != 0 &&
|
||||||
!wcsncmp(KeyName, (PWSTR) &HashBlock->Table[Idx].HashValue, 4))
|
!wcsncmp(KeyName, (PWSTR) &HashBlock->Table[Idx].HashValue, 2))
|
||||||
{
|
{
|
||||||
CurSubKeyBlock = CmiGetBlock(RegistryFile,
|
CurSubKeyBlock = CmiGetBlock(RegistryFile,
|
||||||
HashBlock->Table[Idx].KeyOffset);
|
HashBlock->Table[Idx].KeyOffset);
|
||||||
|
@ -2254,7 +2392,7 @@ CmiScanKeyForValue(IN PREGISTRY_FILE RegistryFile,
|
||||||
ValueListBlock = CmiGetBlock(RegistryFile,
|
ValueListBlock = CmiGetBlock(RegistryFile,
|
||||||
KeyBlock->ValuesOffset);
|
KeyBlock->ValuesOffset);
|
||||||
*ValueBlock = NULL;
|
*ValueBlock = NULL;
|
||||||
if (ValueListBlock == 0)
|
if (ValueListBlock == NULL)
|
||||||
{
|
{
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -2276,6 +2414,39 @@ CmiScanKeyForValue(IN PREGISTRY_FILE RegistryFile,
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
CmiGetValueFromKeyByIndex(IN PREGISTRY_FILE RegistryFile,
|
||||||
|
IN PKEY_BLOCK KeyBlock,
|
||||||
|
IN ULONG Index,
|
||||||
|
OUT PVALUE_BLOCK *ValueBlock)
|
||||||
|
{
|
||||||
|
PVALUE_LIST_BLOCK ValueListBlock;
|
||||||
|
PVALUE_BLOCK CurValueBlock;
|
||||||
|
|
||||||
|
ValueListBlock = CmiGetBlock(RegistryFile,
|
||||||
|
KeyBlock->ValuesOffset);
|
||||||
|
*ValueBlock = NULL;
|
||||||
|
if (ValueListBlock == NULL)
|
||||||
|
{
|
||||||
|
return STATUS_NO_MORE_ENTRIES;
|
||||||
|
}
|
||||||
|
if (Index >= KeyBlock->NumberOfValues)
|
||||||
|
{
|
||||||
|
return STATUS_NO_MORE_ENTRIES;
|
||||||
|
}
|
||||||
|
CurValueBlock = CmiGetBlock(RegistryFile,
|
||||||
|
ValueListBlock->Values[Index]);
|
||||||
|
if (CurValueBlock != NULL)
|
||||||
|
{
|
||||||
|
*ValueBlock = CurValueBlock;
|
||||||
|
}
|
||||||
|
CmiReleaseBlock(RegistryFile, CurValueBlock);
|
||||||
|
CmiReleaseBlock(RegistryFile, ValueListBlock);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
|
CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
|
||||||
IN PKEY_BLOCK KeyBlock,
|
IN PKEY_BLOCK KeyBlock,
|
||||||
|
@ -2312,6 +2483,8 @@ CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
|
||||||
ValueBlock);
|
ValueBlock);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
KeyBlock->ValuesOffset = CmiGetBlockOffset(RegistryFile,
|
||||||
|
ValueListBlock);
|
||||||
}
|
}
|
||||||
else if (KeyBlock->NumberOfValues % REG_VALUE_LIST_BLOCK_MULTIPLE)
|
else if (KeyBlock->NumberOfValues % REG_VALUE_LIST_BLOCK_MULTIPLE)
|
||||||
{
|
{
|
||||||
|
@ -2337,8 +2510,8 @@ CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
|
||||||
ValueListBlock->Values[KeyBlock->NumberOfValues] =
|
ValueListBlock->Values[KeyBlock->NumberOfValues] =
|
||||||
CmiGetBlockOffset(RegistryFile, ValueBlock);
|
CmiGetBlockOffset(RegistryFile, ValueBlock);
|
||||||
KeyBlock->NumberOfValues++;
|
KeyBlock->NumberOfValues++;
|
||||||
CmiReleaseBlock(RegistryFile, ValueBlock);
|
|
||||||
CmiReleaseBlock(RegistryFile, ValueListBlock);
|
CmiReleaseBlock(RegistryFile, ValueListBlock);
|
||||||
|
CmiReleaseBlock(RegistryFile, ValueBlock);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -2613,7 +2786,7 @@ CmiAllocateValueBlock(PREGISTRY_FILE RegistryFile,
|
||||||
/* Handle volatile files first */
|
/* Handle volatile files first */
|
||||||
if (RegistryFile->Filename == NULL)
|
if (RegistryFile->Filename == NULL)
|
||||||
{
|
{
|
||||||
NewValueSize = sizeof(VALUE_BLOCK) + wcslen(ValueNameBuf);
|
NewValueSize = sizeof(VALUE_BLOCK) + wcslen(ValueNameBuf)* sizeof(WCHAR);
|
||||||
NewValueBlock = ExAllocatePool(NonPagedPool, NewValueSize);
|
NewValueBlock = ExAllocatePool(NonPagedPool, NewValueSize);
|
||||||
if (NewValueBlock == NULL)
|
if (NewValueBlock == NULL)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue