report changes from 1.29

svn path=/trunk/; revision=1359
This commit is contained in:
jean 2000-09-13 11:46:35 +00:00
parent ad66ea993a
commit 522110434e

View file

@ -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)
{ {