/* INCLUDES *****************************************************************/
-#include <ddk/ntddk.h>
+#define NTOS_MODE_KERNEL
+#include <ntos.h>
#include <roscfg.h>
#include <internal/ob.h>
#include <limits.h>
#include <string.h>
-#include <internal/pool.h>
+#include <internal/se.h>
#include <internal/registry.h>
#define NDEBUG
NTSTATUS Status;
PVOID Object;
PWSTR End;
+ PWSTR Start;
DPRINT("NtCreateKey (Name %wZ KeyHandle %x Root %x)\n",
ObjectAttributes->ObjectName,
KeyHandle,
ObjectAttributes->RootDirectory);
- /* FIXME: check for standard handle prefix and adjust objectAttributes accordingly */
-
Status = ObFindObject(ObjectAttributes,
&Object,
&RemainingPath,
/* If RemainingPath contains \ we must return error
because NtCreateKey don't create trees */
- if (RemainingPath.Buffer[0] == '\\')
- End = wcschr(RemainingPath.Buffer + 1, '\\');
- else
- End = wcschr(RemainingPath.Buffer, '\\');
+ Start = RemainingPath.Buffer;
+ if (*Start == L'\\')
+ Start++;
+ End = wcschr(Start, L'\\');
if (End != NULL)
{
ObDereferenceObject(Object);
DPRINT("RemainingPath %S ParentObject %x\n", RemainingPath.Buffer, Object);
- Status = ObCreateObject(KeyHandle,
+ Status = ObRosCreateObject(KeyHandle,
DesiredAccess,
NULL,
CmiKeyType,
Status = CmiAddSubKey(KeyObject->RegistryHive,
KeyObject->ParentKey,
KeyObject,
- RemainingPath.Buffer,
- RemainingPath.Length,
+ &RemainingPath,
TitleIndex,
Class,
CreateOptions);
return STATUS_UNSUCCESSFUL;
}
- KeyObject->Name = KeyObject->KeyCell->Name;
- KeyObject->NameSize = KeyObject->KeyCell->NameSize;
+ RtlCreateUnicodeString(&KeyObject->Name,
+ Start);
if (KeyObject->RegistryHive == KeyObject->ParentKey->RegistryHive)
{
NTSTATUS STDCALL
-NtEnumerateKey(
- IN HANDLE KeyHandle,
- IN ULONG Index,
- IN KEY_INFORMATION_CLASS KeyInformationClass,
- OUT PVOID KeyInformation,
- IN ULONG Length,
- OUT PULONG ResultLength
- )
+NtEnumerateKey(IN HANDLE KeyHandle,
+ IN ULONG Index,
+ IN KEY_INFORMATION_CLASS KeyInformationClass,
+ OUT PVOID KeyInformation,
+ IN ULONG Length,
+ OUT PULONG ResultLength)
{
- NTSTATUS Status;
PKEY_OBJECT KeyObject;
PREGISTRY_HIVE RegistryHive;
PKEY_CELL KeyCell, SubKeyCell;
PKEY_BASIC_INFORMATION BasicInformation;
PKEY_NODE_INFORMATION NodeInformation;
PKEY_FULL_INFORMATION FullInformation;
- PDATA_CELL pClassData;
+ PDATA_CELL ClassData;
+ ULONG NameSize;
+ NTSTATUS Status;
DPRINT("KH %x I %d KIC %x KI %x L %d RL %x\n",
KeyHandle,
CurKey = KeyObject->SubKeys[i];
if (CurKey->RegistryHive == CmiVolatileHive)
{
- if (Index-- == KeyObject->NumberOfSubKeys)
+ if (Index-- == KeyCell->NumberOfSubKeys)
break;
}
}
{
if (KeyCell->HashTableOffset == (BLOCK_OFFSET)-1)
{
- return(STATUS_NO_MORE_ENTRIES);
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
+ return(STATUS_NO_MORE_ENTRIES);
}
HashTableBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL);
Status = STATUS_SUCCESS;
switch (KeyInformationClass)
{
- case KeyBasicInformation:
- /* Check size of buffer */
- *ResultLength = sizeof(KEY_BASIC_INFORMATION) +
- (SubKeyCell->NameSize ) * sizeof(WCHAR);
- if (Length < *ResultLength)
- {
- Status = STATUS_BUFFER_OVERFLOW;
- }
- else
- {
- /* Fill buffer with requested info */
- BasicInformation = (PKEY_BASIC_INFORMATION) KeyInformation;
- BasicInformation->LastWriteTime.u.LowPart = SubKeyCell->LastWriteTime.dwLowDateTime;
- BasicInformation->LastWriteTime.u.HighPart = SubKeyCell->LastWriteTime.dwHighDateTime;
- BasicInformation->TitleIndex = Index;
- BasicInformation->NameLength = SubKeyCell->NameSize * sizeof(WCHAR);
- mbstowcs(BasicInformation->Name,
- SubKeyCell->Name,
- SubKeyCell->NameSize * 2);
-// BasicInformation->Name[SubKeyCell->NameSize] = 0;
- }
- break;
-
- case KeyNodeInformation:
- /* Check size of buffer */
- *ResultLength = sizeof(KEY_NODE_INFORMATION) +
- SubKeyCell->NameSize * sizeof(WCHAR) +
- SubKeyCell->ClassSize;
- if (Length < *ResultLength)
- {
- Status = STATUS_BUFFER_OVERFLOW;
- }
- else
- {
- /* Fill buffer with requested info */
- NodeInformation = (PKEY_NODE_INFORMATION) KeyInformation;
- NodeInformation->LastWriteTime.u.LowPart = SubKeyCell->LastWriteTime.dwLowDateTime;
- NodeInformation->LastWriteTime.u.HighPart = SubKeyCell->LastWriteTime.dwHighDateTime;
- NodeInformation->TitleIndex = Index;
- NodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) +
- SubKeyCell->NameSize * sizeof(WCHAR);
- NodeInformation->ClassLength = SubKeyCell->ClassSize;
- NodeInformation->NameLength = SubKeyCell->NameSize * sizeof(WCHAR);
- mbstowcs(NodeInformation->Name,
- SubKeyCell->Name,
- SubKeyCell->NameSize * 2);
-// NodeInformation->Name[SubKeyCell->NameSize] = 0;
- if (SubKeyCell->ClassSize != 0)
- {
- pClassData=CmiGetBlock(KeyObject->RegistryHive,
- SubKeyCell->ClassNameOffset,
- NULL);
- wcsncpy(NodeInformation->Name + SubKeyCell->NameSize ,
- (PWCHAR) pClassData->Data,
- SubKeyCell->ClassSize);
- }
- }
- break;
-
- case KeyFullInformation:
- /* check size of buffer */
- *ResultLength = sizeof(KEY_FULL_INFORMATION) +
- SubKeyCell->ClassSize;
- if (Length < *ResultLength)
- {
- Status = STATUS_BUFFER_OVERFLOW;
- }
- else
- {
- /* fill buffer with requested info */
- FullInformation = (PKEY_FULL_INFORMATION) KeyInformation;
- FullInformation->LastWriteTime.u.LowPart = SubKeyCell->LastWriteTime.dwLowDateTime;
- FullInformation->LastWriteTime.u.HighPart = SubKeyCell->LastWriteTime.dwHighDateTime;
- FullInformation->TitleIndex = Index;
- FullInformation->ClassOffset = sizeof(KEY_FULL_INFORMATION) -
- sizeof(WCHAR);
- FullInformation->ClassLength = SubKeyCell->ClassSize;
- FullInformation->SubKeys = SubKeyCell->NumberOfSubKeys;
- FullInformation->MaxNameLen =
- CmiGetMaxNameLength(RegistryHive, SubKeyCell);
- FullInformation->MaxClassLen =
- CmiGetMaxClassLength(RegistryHive, SubKeyCell);
- FullInformation->Values = SubKeyCell->NumberOfValues;
- FullInformation->MaxValueNameLen =
- CmiGetMaxValueNameLength(RegistryHive, SubKeyCell);
- FullInformation->MaxValueDataLen =
- CmiGetMaxValueDataLength(RegistryHive, SubKeyCell);
- if (SubKeyCell->ClassSize != 0)
- {
- pClassData = CmiGetBlock(KeyObject->RegistryHive,
- SubKeyCell->ClassNameOffset,
- NULL);
- wcsncpy(FullInformation->Class,
- (PWCHAR) pClassData->Data,
- SubKeyCell->ClassSize);
- }
- }
- break;
+ case KeyBasicInformation:
+ /* Check size of buffer */
+ NameSize = SubKeyCell->NameSize;
+ if (SubKeyCell->Flags & REG_KEY_NAME_PACKED)
+ {
+ NameSize *= sizeof(WCHAR);
+ }
+ *ResultLength = sizeof(KEY_BASIC_INFORMATION) + NameSize;
+
+ if (Length < *ResultLength)
+ {
+ Status = STATUS_BUFFER_OVERFLOW;
+ }
+ else
+ {
+ /* Fill buffer with requested info */
+ BasicInformation = (PKEY_BASIC_INFORMATION) KeyInformation;
+ BasicInformation->LastWriteTime.u.LowPart = SubKeyCell->LastWriteTime.u.LowPart;
+ BasicInformation->LastWriteTime.u.HighPart = SubKeyCell->LastWriteTime.u.HighPart;
+ BasicInformation->TitleIndex = Index;
+ BasicInformation->NameLength = NameSize;
+
+ if (SubKeyCell->Flags & REG_KEY_NAME_PACKED)
+ {
+ CmiCopyPackedName(BasicInformation->Name,
+ SubKeyCell->Name,
+ SubKeyCell->NameSize);
+ }
+ else
+ {
+ RtlCopyMemory(BasicInformation->Name,
+ SubKeyCell->Name,
+ SubKeyCell->NameSize);
+ }
+ }
+ break;
+
+ case KeyNodeInformation:
+ /* Check size of buffer */
+ if (SubKeyCell->Flags & REG_KEY_NAME_PACKED)
+ {
+ NameSize = SubKeyCell->NameSize * sizeof(WCHAR);
+ }
+ else
+ {
+ NameSize = SubKeyCell->NameSize;
+ }
+ *ResultLength = sizeof(KEY_NODE_INFORMATION) +
+ NameSize + SubKeyCell->ClassSize;
+
+ if (Length < *ResultLength)
+ {
+ Status = STATUS_BUFFER_OVERFLOW;
+ }
+ else
+ {
+ /* Fill buffer with requested info */
+ NodeInformation = (PKEY_NODE_INFORMATION) KeyInformation;
+ NodeInformation->LastWriteTime.u.LowPart = SubKeyCell->LastWriteTime.u.LowPart;
+ NodeInformation->LastWriteTime.u.HighPart = SubKeyCell->LastWriteTime.u.HighPart;
+ NodeInformation->TitleIndex = Index;
+ NodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) + NameSize;
+ NodeInformation->ClassLength = SubKeyCell->ClassSize;
+ NodeInformation->NameLength = NameSize;
+
+ if (SubKeyCell->Flags & REG_KEY_NAME_PACKED)
+ {
+ CmiCopyPackedName(NodeInformation->Name,
+ SubKeyCell->Name,
+ SubKeyCell->NameSize);
+ }
+ else
+ {
+ RtlCopyMemory(NodeInformation->Name,
+ SubKeyCell->Name,
+ SubKeyCell->NameSize);
+ }
+
+ if (SubKeyCell->ClassSize != 0)
+ {
+ ClassData=CmiGetBlock(KeyObject->RegistryHive,
+ SubKeyCell->ClassNameOffset,
+ NULL);
+ wcsncpy(NodeInformation->Name + SubKeyCell->NameSize,
+ (PWCHAR)ClassData->Data,
+ SubKeyCell->ClassSize);
+ }
+ }
+ break;
+
+ case KeyFullInformation:
+ /* Check size of buffer */
+ *ResultLength = sizeof(KEY_FULL_INFORMATION) +
+ SubKeyCell->ClassSize;
+
+ if (Length < *ResultLength)
+ {
+ Status = STATUS_BUFFER_OVERFLOW;
+ }
+ else
+ {
+ /* Fill buffer with requested info */
+ FullInformation = (PKEY_FULL_INFORMATION) KeyInformation;
+ FullInformation->LastWriteTime.u.LowPart = SubKeyCell->LastWriteTime.u.LowPart;
+ FullInformation->LastWriteTime.u.HighPart = SubKeyCell->LastWriteTime.u.HighPart;
+ FullInformation->TitleIndex = Index;
+ FullInformation->ClassOffset = sizeof(KEY_FULL_INFORMATION) -
+ sizeof(WCHAR);
+ FullInformation->ClassLength = SubKeyCell->ClassSize;
+ FullInformation->SubKeys = SubKeyCell->NumberOfSubKeys;
+ FullInformation->MaxNameLen = CmiGetMaxNameLength(KeyObject);
+ FullInformation->MaxClassLen = CmiGetMaxClassLength(KeyObject);
+ FullInformation->Values = SubKeyCell->NumberOfValues;
+ FullInformation->MaxValueNameLen =
+ CmiGetMaxValueNameLength(RegistryHive, SubKeyCell);
+ FullInformation->MaxValueDataLen =
+ CmiGetMaxValueDataLength(RegistryHive, SubKeyCell);
+ if (SubKeyCell->ClassSize != 0)
+ {
+ ClassData = CmiGetBlock(KeyObject->RegistryHive,
+ SubKeyCell->ClassNameOffset,
+ NULL);
+ wcsncpy(FullInformation->Class,
+ (PWCHAR)ClassData->Data,
+ SubKeyCell->ClassSize);
+ }
+ }
+ break;
+
+ default:
+ DPRINT1("Not handling 0x%x\n", KeyInformationClass);
+ break;
}
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
PKEY_CELL KeyCell;
PVALUE_CELL ValueCell;
PDATA_CELL DataCell;
+ ULONG NameSize;
PKEY_VALUE_BASIC_INFORMATION ValueBasicInformation;
PKEY_VALUE_PARTIAL_INFORMATION ValuePartialInformation;
PKEY_VALUE_FULL_INFORMATION ValueFullInformation;
switch (KeyValueInformationClass)
{
case KeyValueBasicInformation:
- if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
+ NameSize = ValueCell->NameSize;
+ if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
{
- *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) +
- (ValueCell->NameSize + 1) * sizeof(WCHAR);
- }
- else
- {
- *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) +
- ValueCell->NameSize + sizeof(WCHAR);
- }
+ NameSize *= sizeof(WCHAR);
+ }
+ *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) + NameSize;
if (Length < *ResultLength)
{
Status = STATUS_BUFFER_OVERFLOW;
KeyValueInformation;
ValueBasicInformation->TitleIndex = 0;
ValueBasicInformation->Type = ValueCell->DataType;
+ ValueBasicInformation->NameLength = NameSize;
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
{
- ValueBasicInformation->NameLength =
- (ValueCell->NameSize + 1) * sizeof(WCHAR);
CmiCopyPackedName(ValueBasicInformation->Name,
ValueCell->Name,
ValueCell->NameSize);
- ValueBasicInformation->Name[ValueCell->NameSize] = 0;
}
else
{
- ValueBasicInformation->NameLength =
- ValueCell->NameSize + sizeof(WCHAR);
RtlCopyMemory(ValueBasicInformation->Name,
ValueCell->Name,
- ValueCell->NameSize * sizeof(WCHAR));
- ValueBasicInformation->Name[ValueCell->NameSize / sizeof(WCHAR)] = 0;
+ NameSize);
}
}
break;
break;
case KeyValueFullInformation:
+ NameSize = ValueCell->NameSize;
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
{
- *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) +
- (ValueCell->NameSize + 1) * sizeof(WCHAR) +
- (ValueCell->DataSize & LONG_MAX);
- }
- else
- {
- *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) +
- ValueCell->NameSize + sizeof(WCHAR) +
- (ValueCell->DataSize & LONG_MAX);
- }
+ NameSize *= sizeof(WCHAR);
+ }
+ *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) +
+ NameSize + (ValueCell->DataSize & LONG_MAX);
if (Length < *ResultLength)
{
Status = STATUS_BUFFER_OVERFLOW;
KeyValueInformation;
ValueFullInformation->TitleIndex = 0;
ValueFullInformation->Type = ValueCell->DataType;
+ ValueFullInformation->NameLength = NameSize;
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
{
- ValueFullInformation->NameLength =
- (ValueCell->NameSize + 1) * sizeof(WCHAR);
-
CmiCopyPackedName(ValueFullInformation->Name,
ValueCell->Name,
ValueCell->NameSize);
- ValueFullInformation->Name[ValueCell->NameSize] = 0;
}
else
{
- ValueFullInformation->NameLength =
- ValueCell->NameSize + sizeof(WCHAR);
RtlCopyMemory(ValueFullInformation->Name,
ValueCell->Name,
ValueCell->NameSize);
- ValueFullInformation->Name[ValueCell->NameSize / sizeof(WCHAR)] = 0;
}
ValueFullInformation->DataOffset =
(ULONG)ValueFullInformation->Name - (ULONG)ValueFullInformation +
}
}
break;
+
+ default:
+ DPRINT1("Not handling 0x%x\n", KeyValueInformationClass);
+ break;
}
}
else
ExAcquireResourceExclusiveLite(&RegistryHive->HiveResource,
TRUE);
- if (IsVolatileHive(RegistryHive))
+ if (IsNoFileHive(RegistryHive))
{
Status = STATUS_SUCCESS;
}
PKEY_NODE_INFORMATION NodeInformation;
PKEY_FULL_INFORMATION FullInformation;
PREGISTRY_HIVE RegistryHive;
- PDATA_CELL pClassData;
+ PDATA_CELL ClassData;
PKEY_OBJECT KeyObject;
PKEY_CELL KeyCell;
NTSTATUS Status;
- DPRINT("KH %x KIC %x KI %x L %d RL %x\n",
+ DPRINT("NtQueryKey(KH %x KIC %x KI %x L %d RL %x)\n",
KeyHandle,
KeyInformationClass,
KeyInformation,
Status = STATUS_SUCCESS;
switch (KeyInformationClass)
{
- case KeyBasicInformation:
- /* Check size of buffer */
- if (Length < sizeof(KEY_BASIC_INFORMATION) +
- KeyObject->NameSize * sizeof(WCHAR))
- {
- Status = STATUS_BUFFER_OVERFLOW;
- }
- else
- {
- /* Fill buffer with requested info */
- BasicInformation = (PKEY_BASIC_INFORMATION) KeyInformation;
- BasicInformation->LastWriteTime.u.LowPart = KeyCell->LastWriteTime.dwLowDateTime;
- BasicInformation->LastWriteTime.u.HighPart = KeyCell->LastWriteTime.dwHighDateTime;
- BasicInformation->TitleIndex = 0;
- BasicInformation->NameLength = (KeyObject->NameSize) * sizeof(WCHAR);
- mbstowcs(BasicInformation->Name,
- KeyObject->Name,
- KeyObject->NameSize*sizeof(WCHAR));
- *ResultLength = sizeof(KEY_BASIC_INFORMATION) +
- KeyObject->NameSize * sizeof(WCHAR);
- }
- break;
-
- case KeyNodeInformation:
- /* Check size of buffer */
- if (Length < sizeof(KEY_NODE_INFORMATION)
- + KeyObject->NameSize * sizeof(WCHAR)
- + KeyCell->ClassSize)
- {
- Status = STATUS_BUFFER_OVERFLOW;
- }
- else
- {
- /* Fill buffer with requested info */
- NodeInformation = (PKEY_NODE_INFORMATION) KeyInformation;
- NodeInformation->LastWriteTime.u.LowPart = KeyCell->LastWriteTime.dwLowDateTime;
- NodeInformation->LastWriteTime.u.HighPart = KeyCell->LastWriteTime.dwHighDateTime;
- NodeInformation->TitleIndex = 0;
- NodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) +
- KeyObject->NameSize * sizeof(WCHAR);
- NodeInformation->ClassLength = KeyCell->ClassSize;
- NodeInformation->NameLength = KeyObject->NameSize * sizeof(WCHAR);
- mbstowcs(NodeInformation->Name,
- KeyObject->Name,
- KeyObject->NameSize * sizeof(WCHAR));
-
- if (KeyCell->ClassSize != 0)
- {
- pClassData = CmiGetBlock(KeyObject->RegistryHive,
- KeyCell->ClassNameOffset,
- NULL);
- wcsncpy(NodeInformation->Name + KeyObject->NameSize * sizeof(WCHAR),
- (PWCHAR)pClassData->Data,
- KeyCell->ClassSize);
- }
- *ResultLength = sizeof(KEY_NODE_INFORMATION)
- + KeyObject->NameSize * sizeof(WCHAR)
- + KeyCell->ClassSize;
- }
- break;
-
- case KeyFullInformation:
- /* Check size of buffer */
- if (Length < sizeof(KEY_FULL_INFORMATION) + KeyCell->ClassSize)
- {
- Status = STATUS_BUFFER_OVERFLOW;
- }
- else
- {
- /* Fill buffer with requested info */
- FullInformation = (PKEY_FULL_INFORMATION) KeyInformation;
- FullInformation->LastWriteTime.u.LowPart = KeyCell->LastWriteTime.dwLowDateTime;
- FullInformation->LastWriteTime.u.HighPart = KeyCell->LastWriteTime.dwHighDateTime;
- FullInformation->TitleIndex = 0;
- FullInformation->ClassOffset = sizeof(KEY_FULL_INFORMATION) - sizeof(WCHAR);
- FullInformation->ClassLength = KeyCell->ClassSize;
- FullInformation->SubKeys = KeyCell->NumberOfSubKeys;
- FullInformation->MaxNameLen =
- CmiGetMaxNameLength(RegistryHive, KeyCell);
- FullInformation->MaxClassLen =
- CmiGetMaxClassLength(RegistryHive, KeyCell);
- FullInformation->Values = KeyCell->NumberOfValues;
- FullInformation->MaxValueNameLen =
- CmiGetMaxValueNameLength(RegistryHive, KeyCell);
- FullInformation->MaxValueDataLen =
- CmiGetMaxValueDataLength(RegistryHive, KeyCell);
- if (KeyCell->ClassSize != 0)
- {
- pClassData=CmiGetBlock(KeyObject->RegistryHive,
- KeyCell->ClassNameOffset,
- NULL);
- wcsncpy(FullInformation->Class,
- (PWCHAR)pClassData->Data,
- KeyCell->ClassSize);
- }
- *ResultLength = sizeof(KEY_FULL_INFORMATION) + KeyCell->ClassSize;
- }
- break;
+ case KeyBasicInformation:
+ /* Check size of buffer */
+ *ResultLength = sizeof(KEY_BASIC_INFORMATION) +
+ KeyObject->Name.Length;
+
+ if (Length < *ResultLength)
+ {
+ Status = STATUS_BUFFER_OVERFLOW;
+ }
+ else
+ {
+ /* Fill buffer with requested info */
+ BasicInformation = (PKEY_BASIC_INFORMATION) KeyInformation;
+ BasicInformation->LastWriteTime.u.LowPart = KeyCell->LastWriteTime.u.LowPart;
+ BasicInformation->LastWriteTime.u.HighPart = KeyCell->LastWriteTime.u.HighPart;
+ BasicInformation->TitleIndex = 0;
+ BasicInformation->NameLength = KeyObject->Name.Length;
+
+ if (KeyCell->Flags & REG_KEY_NAME_PACKED)
+ {
+ CmiCopyPackedName(BasicInformation->Name,
+ KeyCell->Name,
+ KeyCell->NameSize);
+ }
+ else
+ {
+ RtlCopyMemory(BasicInformation->Name,
+ KeyCell->Name,
+ KeyCell->NameSize);
+ }
+ }
+ break;
+
+ case KeyNodeInformation:
+ /* Check size of buffer */
+ *ResultLength = sizeof(KEY_NODE_INFORMATION) +
+ KeyObject->Name.Length + KeyCell->ClassSize;
+
+ if (Length < *ResultLength)
+ {
+ Status = STATUS_BUFFER_OVERFLOW;
+ }
+ else
+ {
+ /* Fill buffer with requested info */
+ NodeInformation = (PKEY_NODE_INFORMATION) KeyInformation;
+ NodeInformation->LastWriteTime.u.LowPart = KeyCell->LastWriteTime.u.LowPart;
+ NodeInformation->LastWriteTime.u.HighPart = KeyCell->LastWriteTime.u.HighPart;
+ NodeInformation->TitleIndex = 0;
+ NodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) +
+ KeyObject->Name.Length;
+ NodeInformation->ClassLength = KeyCell->ClassSize;
+ NodeInformation->NameLength = KeyObject->Name.Length;
+
+ if (KeyCell->Flags & REG_KEY_NAME_PACKED)
+ {
+ CmiCopyPackedName(NodeInformation->Name,
+ KeyCell->Name,
+ KeyCell->NameSize);
+ }
+ else
+ {
+ RtlCopyMemory(NodeInformation->Name,
+ KeyCell->Name,
+ KeyCell->NameSize);
+ }
+
+ if (KeyCell->ClassSize != 0)
+ {
+ ClassData = CmiGetBlock(KeyObject->RegistryHive,
+ KeyCell->ClassNameOffset,
+ NULL);
+ wcsncpy(NodeInformation->Name + KeyObject->Name.Length,
+ (PWCHAR)ClassData->Data,
+ KeyCell->ClassSize);
+ }
+ }
+ break;
+
+ case KeyFullInformation:
+ /* Check size of buffer */
+ *ResultLength = sizeof(KEY_FULL_INFORMATION) +
+ KeyCell->ClassSize;
+
+ if (Length < *ResultLength)
+ {
+ Status = STATUS_BUFFER_OVERFLOW;
+ }
+ else
+ {
+ /* Fill buffer with requested info */
+ FullInformation = (PKEY_FULL_INFORMATION) KeyInformation;
+ FullInformation->LastWriteTime.u.LowPart = KeyCell->LastWriteTime.u.LowPart;
+ FullInformation->LastWriteTime.u.HighPart = KeyCell->LastWriteTime.u.HighPart;
+ FullInformation->TitleIndex = 0;
+ FullInformation->ClassOffset = sizeof(KEY_FULL_INFORMATION) - sizeof(WCHAR);
+ FullInformation->ClassLength = KeyCell->ClassSize;
+ FullInformation->SubKeys = KeyCell->NumberOfSubKeys;
+ FullInformation->MaxNameLen = CmiGetMaxNameLength(KeyObject);
+ FullInformation->MaxClassLen = CmiGetMaxClassLength(KeyObject);
+ FullInformation->Values = KeyCell->NumberOfValues;
+ FullInformation->MaxValueNameLen =
+ CmiGetMaxValueNameLength(RegistryHive, KeyCell);
+ FullInformation->MaxValueDataLen =
+ CmiGetMaxValueDataLength(RegistryHive, KeyCell);
+ if (KeyCell->ClassSize != 0)
+ {
+ ClassData=CmiGetBlock(KeyObject->RegistryHive,
+ KeyCell->ClassNameOffset,
+ NULL);
+ wcsncpy(FullInformation->Class,
+ (PWCHAR)ClassData->Data,
+ KeyCell->ClassSize);
+ }
+ }
+ break;
+ default:
+ DPRINT1("Not handling 0x%x\n", KeyInformationClass);
+ break;
}
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
OUT PULONG ResultLength)
{
NTSTATUS Status;
+ ULONG NameSize;
PKEY_OBJECT KeyObject;
PREGISTRY_HIVE RegistryHive;
PKEY_CELL KeyCell;
switch (KeyValueInformationClass)
{
case KeyValueBasicInformation:
+ NameSize = ValueCell->NameSize;
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
{
- *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) +
- (ValueCell->NameSize + 1) * sizeof(WCHAR);
- }
- else
- {
- *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) +
- ValueCell->NameSize + sizeof(WCHAR);
- }
+ NameSize *= sizeof(WCHAR);
+ }
+ *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) + NameSize;
if (Length < *ResultLength)
{
Status = STATUS_BUFFER_TOO_SMALL;
KeyValueInformation;
ValueBasicInformation->TitleIndex = 0;
ValueBasicInformation->Type = ValueCell->DataType;
+ ValueBasicInformation->NameLength = NameSize;
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
{
- ValueBasicInformation->NameLength =
- (ValueCell->NameSize + 1) * sizeof(WCHAR);
CmiCopyPackedName(ValueBasicInformation->Name,
ValueCell->Name,
ValueCell->NameSize);
- ValueBasicInformation->Name[ValueCell->NameSize] = 0;
}
else
{
- ValueBasicInformation->NameLength =
- ValueCell->NameSize + sizeof(WCHAR);
RtlCopyMemory(ValueBasicInformation->Name,
ValueCell->Name,
ValueCell->NameSize * sizeof(WCHAR));
- ValueBasicInformation->Name[ValueCell->NameSize / sizeof(WCHAR)] = 0;
}
}
break;
break;
case KeyValueFullInformation:
+ NameSize = ValueCell->NameSize;
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
{
- *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) +
- (ValueCell->NameSize + 1) * sizeof(WCHAR) +
- (ValueCell->DataSize & LONG_MAX);
- }
- else
- {
- *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) +
- ValueCell->NameSize + sizeof(WCHAR) +
- (ValueCell->DataSize & LONG_MAX);
- }
+ NameSize *= sizeof(WCHAR);
+ }
+ *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) +
+ NameSize + (ValueCell->DataSize & LONG_MAX);
if (Length < *ResultLength)
{
Status = STATUS_BUFFER_TOO_SMALL;
KeyValueInformation;
ValueFullInformation->TitleIndex = 0;
ValueFullInformation->Type = ValueCell->DataType;
+ ValueFullInformation->NameLength = NameSize;
if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
{
- ValueFullInformation->NameLength =
- (ValueCell->NameSize + 1) * sizeof(WCHAR);
CmiCopyPackedName(ValueFullInformation->Name,
ValueCell->Name,
ValueCell->NameSize);
- ValueFullInformation->Name[ValueCell->NameSize] = 0;
}
else
{
- ValueFullInformation->NameLength =
- ValueCell->NameSize + sizeof(WCHAR);
RtlCopyMemory(ValueFullInformation->Name,
ValueCell->Name,
ValueCell->NameSize);
- ValueFullInformation->Name[ValueCell->NameSize / sizeof(WCHAR)] = 0;
}
ValueFullInformation->DataOffset =
(ULONG)ValueFullInformation->Name - (ULONG)ValueFullInformation +
}
}
break;
+ default:
+ DPRINT1("Not handling 0x%x\n", KeyValueInformationClass);
+ break;
}
}
else
ValueCell->DataType = Type;
/* Update time of heap */
- if (!IsVolatileHive(RegistryHive))
+ if (!IsNoFileHive(RegistryHive))
{
- NtQuerySystemTime((PTIME) &pBin->DateModified);
+ NtQuerySystemTime(&pBin->DateModified);
}
CmiMarkBlockDirty(RegistryHive, ValueCell->DataOffset);
}
if ((_wcsicmp(ValueName->Buffer, L"SymbolicLinkValue") == 0) &&
(Type == REG_LINK))
{
- KeyCell->Type = REG_LINK_KEY_CELL_TYPE;
+ KeyCell->Flags |= REG_KEY_LINK_CELL;
CmiMarkBlockDirty(RegistryHive, KeyObject->BlockOffset);
}
/* Update time of heap */
- if (!IsVolatileHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin))
+ if (!IsNoFileHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin))
{
- NtQuerySystemTime((PTIME) &pBin->DateModified);
+ NtQuerySystemTime(&pBin->DateModified);
}
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
NTSTATUS STDCALL
-NtDeleteValueKey(IN HANDLE KeyHandle,
- IN PUNICODE_STRING ValueName)
+NtDeleteValueKey (IN HANDLE KeyHandle,
+ IN PUNICODE_STRING ValueName)
{
PKEY_OBJECT KeyObject;
NTSTATUS Status;
return Status;
}
+
/*
* NOTE:
* KeyObjectAttributes->RootDirectory specifies the handle to the parent key and
* KeyObjectAttributes->Name specifies the name of the key to load.
*/
NTSTATUS STDCALL
-NtLoadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
- IN POBJECT_ATTRIBUTES FileObjectAttributes)
+NtLoadKey (IN POBJECT_ATTRIBUTES KeyObjectAttributes,
+ IN POBJECT_ATTRIBUTES FileObjectAttributes)
{
- return NtLoadKey2(KeyObjectAttributes, FileObjectAttributes, 0);
+ return NtLoadKey2 (KeyObjectAttributes,
+ FileObjectAttributes,
+ 0);
}
* NOTE:
* KeyObjectAttributes->RootDirectory specifies the handle to the parent key and
* KeyObjectAttributes->Name specifies the name of the key to load.
+ * Flags can be 0 or REG_NO_LAZY_FLUSH.
*/
NTSTATUS STDCALL
-NtLoadKey2(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
- IN POBJECT_ATTRIBUTES FileObjectAttributes,
- IN ULONG Flags)
+NtLoadKey2 (IN POBJECT_ATTRIBUTES KeyObjectAttributes,
+ IN POBJECT_ATTRIBUTES FileObjectAttributes,
+ IN ULONG Flags)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ POBJECT_NAME_INFORMATION NameInfo;
+ PUNICODE_STRING NamePointer;
+ PUCHAR Buffer;
+ ULONG BufferSize;
+ ULONG Length;
+ NTSTATUS Status;
+
+ DPRINT ("NtLoadKey2() called\n");
+
+#if 0
+ if (!SeSinglePrivilegeCheck (SeRestorePrivilege, KeGetPreviousMode ()))
+ return STATUS_PRIVILEGE_NOT_HELD;
+#endif
+
+ if (FileObjectAttributes->RootDirectory != NULL)
+ {
+ BufferSize =
+ sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR);
+ Buffer = ExAllocatePool (NonPagedPool,
+ BufferSize);
+ if (Buffer == NULL)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ Status = NtQueryObject (FileObjectAttributes->RootDirectory,
+ ObjectNameInformation,
+ Buffer,
+ BufferSize,
+ &Length);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1 ("NtQueryObject() failed (Status %lx)\n", Status);
+ ExFreePool (Buffer);
+ return Status;
+ }
+
+ NameInfo = (POBJECT_NAME_INFORMATION)Buffer;
+ DPRINT ("ObjectPath: '%wZ' Length %hu\n",
+ &NameInfo->Name, NameInfo->Name.Length);
+
+ NameInfo->Name.MaximumLength = MAX_PATH * sizeof(WCHAR);
+ if (FileObjectAttributes->ObjectName->Buffer[0] != L'\\')
+ {
+ RtlAppendUnicodeToString (&NameInfo->Name,
+ L"\\");
+ DPRINT ("ObjectPath: '%wZ' Length %hu\n",
+ &NameInfo->Name, NameInfo->Name.Length);
+ }
+ RtlAppendUnicodeStringToString (&NameInfo->Name,
+ FileObjectAttributes->ObjectName);
+
+ DPRINT ("ObjectPath: '%wZ' Length %hu\n",
+ &NameInfo->Name, NameInfo->Name.Length);
+ NamePointer = &NameInfo->Name;
+ }
+ else
+ {
+ if (FileObjectAttributes->ObjectName->Buffer[0] == L'\\')
+ {
+ Buffer = NULL;
+ NamePointer = FileObjectAttributes->ObjectName;
+ }
+ else
+ {
+ BufferSize =
+ sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR);
+ Buffer = ExAllocatePool (NonPagedPool,
+ BufferSize);
+ if (Buffer == NULL)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ NameInfo = (POBJECT_NAME_INFORMATION)Buffer;
+ NameInfo->Name.MaximumLength = MAX_PATH * sizeof(WCHAR);
+ NameInfo->Name.Length = 0;
+ NameInfo->Name.Buffer = (PWSTR)((ULONG_PTR)Buffer + sizeof(OBJECT_NAME_INFORMATION));
+ NameInfo->Name.Buffer[0] = 0;
+
+ RtlAppendUnicodeToString (&NameInfo->Name,
+ L"\\");
+ RtlAppendUnicodeStringToString (&NameInfo->Name,
+ FileObjectAttributes->ObjectName);
+
+ NamePointer = &NameInfo->Name;
+ }
+ }
+
+ DPRINT ("Full name: '%wZ'\n", NamePointer);
+
+ Status = CmiLoadHive (KeyObjectAttributes,
+ NamePointer,
+ Flags);
+ if (!NT_SUCCESS (Status))
+ {
+ DPRINT1 ("CmiLoadHive() failed (Status %lx)\n", Status);
+ }
+
+ if (Buffer != NULL)
+ ExFreePool (Buffer);
+
+ return Status;
}
NTSTATUS STDCALL
-NtNotifyChangeKey(
- IN HANDLE KeyHandle,
- IN HANDLE Event,
- IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
- IN PVOID ApcContext OPTIONAL,
- OUT PIO_STATUS_BLOCK IoStatusBlock,
- IN ULONG CompletionFilter,
- IN BOOLEAN Asynchroneous,
- OUT PVOID ChangeBuffer,
- IN ULONG Length,
- IN BOOLEAN WatchSubtree)
+NtNotifyChangeKey (IN HANDLE KeyHandle,
+ IN HANDLE Event,
+ IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
+ IN PVOID ApcContext OPTIONAL,
+ OUT PIO_STATUS_BLOCK IoStatusBlock,
+ IN ULONG CompletionFilter,
+ IN BOOLEAN Asynchroneous,
+ OUT PVOID ChangeBuffer,
+ IN ULONG Length,
+ IN BOOLEAN WatchSubtree)
{
UNIMPLEMENTED;
+ return(STATUS_NOT_IMPLEMENTED);
}
NTSTATUS STDCALL
-NtQueryMultipleValueKey(IN HANDLE KeyHandle,
- IN OUT PKEY_VALUE_ENTRY ValueList,
- IN ULONG NumberOfValues,
- OUT PVOID Buffer,
- IN OUT PULONG Length,
- OUT PULONG ReturnLength)
+NtQueryMultipleValueKey (IN HANDLE KeyHandle,
+ IN OUT PKEY_VALUE_ENTRY ValueList,
+ IN ULONG NumberOfValues,
+ OUT PVOID Buffer,
+ IN OUT PULONG Length,
+ OUT PULONG ReturnLength)
{
PREGISTRY_HIVE RegistryHive;
PVALUE_CELL ValueCell;
DPRINT("Return Status 0x%X\n", Status);
- return(Status);
+ return Status;
}
NTSTATUS STDCALL
-NtReplaceKey(
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN HANDLE Key,
- IN POBJECT_ATTRIBUTES ReplacedObjectAttributes
- )
+NtReplaceKey (IN POBJECT_ATTRIBUTES ObjectAttributes,
+ IN HANDLE Key,
+ IN POBJECT_ATTRIBUTES ReplacedObjectAttributes)
{
UNIMPLEMENTED;
+ return(STATUS_NOT_IMPLEMENTED);
}
NTSTATUS STDCALL
-NtRestoreKey(
- IN HANDLE KeyHandle,
- IN HANDLE FileHandle,
- IN ULONG RestoreFlags
- )
+NtRestoreKey (IN HANDLE KeyHandle,
+ IN HANDLE FileHandle,
+ IN ULONG RestoreFlags)
{
UNIMPLEMENTED;
+ return(STATUS_NOT_IMPLEMENTED);
}
NTSTATUS STDCALL
-NtSaveKey(
- IN HANDLE KeyHandle,
- IN HANDLE FileHandle)
+NtSaveKey (IN HANDLE KeyHandle,
+ IN HANDLE FileHandle)
{
- UNIMPLEMENTED;
+ PREGISTRY_HIVE TempHive;
+ PKEY_OBJECT KeyObject;
+ NTSTATUS Status;
+
+ DPRINT ("NtSaveKey() called\n");
+
+#if 0
+ if (!SeSinglePrivilegeCheck (SeBackupPrivilege, KeGetPreviousMode ()))
+ return STATUS_PRIVILEGE_NOT_HELD;
+#endif
+
+ Status = ObReferenceObjectByHandle (KeyHandle,
+ 0,
+ CmiKeyType,
+ KeGetPreviousMode(),
+ (PVOID *)&KeyObject,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1 ("ObReferenceObjectByHandle() failed (Status %lx)\n", Status);
+ return Status;
+ }
+
+ /* Acquire hive lock exclucively */
+ ExAcquireResourceExclusiveLite (&KeyObject->RegistryHive->HiveResource,
+ TRUE);
+
+ /* Refuse to save a volatile key */
+ if (KeyObject->RegistryHive == CmiVolatileHive)
+ {
+ DPRINT1 ("Cannot save a volatile key\n");
+ ExReleaseResourceLite (&KeyObject->RegistryHive->HiveResource);
+ ObDereferenceObject (KeyObject);
+ return STATUS_ACCESS_DENIED;
+ }
+
+ Status = CmiCreateTempHive(&TempHive);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1 ("CmiCreateTempHive() failed (Status %lx)\n", Status);
+ ExReleaseResourceLite (&KeyObject->RegistryHive->HiveResource);
+ ObDereferenceObject (KeyObject);
+ return(Status);
+ }
+
+ Status = CmiCopyKey (TempHive,
+ NULL,
+ KeyObject->RegistryHive,
+ KeyObject->KeyCell);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1 ("CmiCopyKey() failed (Status %lx)\n", Status);
+ CmiRemoveRegistryHive (TempHive);
+ ExReleaseResourceLite (&KeyObject->RegistryHive->HiveResource);
+ ObDereferenceObject (KeyObject);
+ return(Status);
+ }
+
+ Status = CmiSaveTempHive (TempHive,
+ FileHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1 ("CmiSaveTempHive() failed (Status %lx)\n", Status);
+ }
+
+ CmiRemoveRegistryHive (TempHive);
+
+ /* Release hive lock */
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+
+ ObDereferenceObject (KeyObject);
+
+ DPRINT ("NtSaveKey() done\n");
+
+ return STATUS_SUCCESS;
}
NTSTATUS STDCALL
-NtSetInformationKey(
- IN HANDLE KeyHandle,
- IN CINT KeyInformationClass,
- IN PVOID KeyInformation,
- IN ULONG KeyInformationLength)
+NtSetInformationKey (IN HANDLE KeyHandle,
+ IN CINT KeyInformationClass,
+ IN PVOID KeyInformation,
+ IN ULONG KeyInformationLength)
{
- UNIMPLEMENTED;
+ UNIMPLEMENTED;
+ return(STATUS_NOT_IMPLEMENTED);
}
* KeyObjectAttributes->Name specifies the name of the key to unload.
*/
NTSTATUS STDCALL
-NtUnloadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes)
+NtUnloadKey (IN POBJECT_ATTRIBUTES KeyObjectAttributes)
{
- UNIMPLEMENTED;
+ PREGISTRY_HIVE RegistryHive;
+ NTSTATUS Status;
+
+ DPRINT ("NtUnloadKey() called\n");
+
+#if 0
+ if (!SeSinglePrivilegeCheck (SeRestorePrivilege, KeGetPreviousMode ()))
+ return STATUS_PRIVILEGE_NOT_HELD;
+#endif
+
+ Status = CmiDisconnectHive (KeyObjectAttributes,
+ &RegistryHive);
+ if (!NT_SUCCESS (Status))
+ {
+ DPRINT1 ("CmiDisconnectHive() failed (Status %lx)\n", Status);
+ return Status;
+ }
+
+ DPRINT ("RegistryHive %p\n", RegistryHive);
+
+ /* Acquire hive list lock exclusively */
+ ExAcquireResourceExclusiveLite (&CmiHiveListLock,
+ TRUE);
+
+#if 0
+ /* Flush hive */
+ if (!IsNoFileHive (RegistryHive))
+ CmiFlushRegistryHive (RegistryHive);
+#endif
+
+ /* Release hive list lock */
+ ExReleaseResourceLite (&CmiHiveListLock);
+
+ CmiRemoveRegistryHive (RegistryHive);
+
+ DPRINT ("NtUnloadKey() done\n");
+
+ return STATUS_SUCCESS;
}
NTSTATUS STDCALL
-NtInitializeRegistry(IN BOOLEAN SetUpBoot)
+NtInitializeRegistry (IN BOOLEAN SetUpBoot)
{
- NTSTATUS Status = STATUS_ACCESS_DENIED;
+ NTSTATUS Status;
- if (CmiRegistryInitialized == FALSE)
- {
- /* FIXME: save boot log file */
+ if (CmiRegistryInitialized == TRUE)
+ return STATUS_ACCESS_DENIED;
- Status = CmiInitHives(SetUpBoot);
+ /* FIXME: save boot log file */
- CmiRegistryInitialized = TRUE;
- }
+ Status = CmiInitHives (SetUpBoot);
- return(Status);
+ CmiRegistryInitialized = TRUE;
+
+ return Status;
}
/* EOF */