/* INCLUDES *****************************************************************/
+#ifdef WIN32_REGDBG
+#include "cm_win32.h"
+#else
#include <ddk/ntddk.h>
#include <roscfg.h>
#include <internal/ob.h>
#include <internal/debug.h>
#include "cm.h"
+#endif
/* GLOBALS ******************************************************************/
NTSTATUS STDCALL
NtCreateKey(OUT PHANDLE KeyHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN ULONG TitleIndex,
- IN PUNICODE_STRING Class,
- IN ULONG CreateOptions,
- OUT PULONG Disposition)
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes,
+ IN ULONG TitleIndex,
+ IN PUNICODE_STRING Class,
+ IN ULONG CreateOptions,
+ OUT PULONG Disposition)
{
UNICODE_STRING RemainingPath;
PKEY_OBJECT KeyObject;
PWSTR End;
DPRINT("NtCreateKey (Name %wZ KeyHandle %x Root %x)\n",
- ObjectAttributes->ObjectName,
- KeyHandle,
- ObjectAttributes->RootDirectory);
+ ObjectAttributes->ObjectName,
+ KeyHandle,
+ ObjectAttributes->RootDirectory);
/* FIXME: check for standard handle prefix and adjust objectAttributes accordingly */
- Status = ObFindObject(ObjectAttributes, &Object, &RemainingPath, CmiKeyType);
-
+ Status = ObFindObject(ObjectAttributes,
+ &Object,
+ &RemainingPath,
+ CmiKeyType);
if (!NT_SUCCESS(Status))
{
- return Status;
+ return(Status);
}
DPRINT("RemainingPath %wZ\n", &RemainingPath);
if (((PKEY_OBJECT) Object)->Flags & KO_MARKED_FOR_DELETE)
{
ObDereferenceObject(Object);
- return STATUS_UNSUCCESSFUL;
+ return(STATUS_UNSUCCESSFUL);
}
if (Disposition)
NULL,
CmiKeyType,
(PVOID*)&KeyObject);
-
if (!NT_SUCCESS(Status))
- return(Status);
+ {
+ return(Status);
+ }
KeyObject->ParentKey = Object;
KeyObject->NumberOfSubKeys = 0;
KeyObject->SizeOfSubKeys = 0;
KeyObject->SubKeys = NULL;
-// KeAcquireSpinLock(&Key->RegistryHive->RegLock, &OldIrql);
+
+ /* Acquire hive lock */
+ ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
+
/* add key to subkeys of parent if needed */
Status = CmiAddSubKey(KeyObject->RegistryHive,
KeyObject->ParentKey,
TitleIndex,
Class,
CreateOptions);
-
if (!NT_SUCCESS(Status))
{
+ /* Release hive lock */
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
ObDereferenceObject(Object);
return STATUS_UNSUCCESSFUL;
{
KeyObject->KeyCell->ParentKeyOffset = -1;
KeyObject->KeyCell->SecurityKeyOffset = -1;
- /* This key must rest in memory unless it is deleted
+ /* This key must remain in memory unless it is deleted
or file is unloaded */
ObReferenceObjectByPointer(KeyObject,
STANDARD_RIGHTS_REQUIRED,
}
CmiAddKeyToList(KeyObject->ParentKey, KeyObject);
-// KeReleaseSpinLock(&KeyObject->RegistryHive->RegLock, OldIrql);
+
+ VERIFY_KEY_OBJECT(KeyObject);
+
+ /* Release hive lock */
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
ObDereferenceObject(Object);
if (Disposition)
*Disposition = REG_CREATED_NEW_KEY;
- VERIFY_KEY_OBJECT(KeyObject);
+ CmiSyncHives();
return Status;
}
DPRINT("KeyHandle %x\n", KeyHandle);
/* Verify that the handle is valid and is a registry key */
+CHECKPOINT1;
Status = ObReferenceObjectByHandle(KeyHandle,
- KEY_WRITE,
- CmiKeyType,
- UserMode,
- (PVOID *) &KeyObject,
- NULL);
-
+ KEY_WRITE,
+ CmiKeyType,
+ UserMode,
+ (PVOID *)&KeyObject,
+ NULL);
if (!NT_SUCCESS(Status))
{
- return Status;
+CHECKPOINT1;
+ return(Status);
}
+CHECKPOINT1;
+ /* Acquire hive lock */
+ ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
+CHECKPOINT1;
+
VERIFY_KEY_OBJECT(KeyObject);
/* Set the marked for delete bit in the key object */
KeyObject->Flags |= KO_MARKED_FOR_DELETE;
+CHECKPOINT1;
+
+ /* Release hive lock */
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+
+ DPRINT1("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
/* Dereference the object */
ObDereferenceObject(KeyObject);
if(KeyObject->RegistryHive != KeyObject->ParentKey->RegistryHive)
ObDereferenceObject(KeyObject);
- /* Close the handle */
- ObDeleteHandle(PsGetCurrentProcess(), KeyHandle);
- /* FIXME: I think that ObDeleteHandle should dereference the object */
- ObDereferenceObject(KeyObject);
- return STATUS_SUCCESS;
+ DPRINT1("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
+
+ /*
+ * Note:
+ * Hive-Synchronization will not be triggered here. This is done in
+ * CmiObjectDelete() (in regobj.c) after all key-related structures
+ * have been released.
+ */
+
+ return(STATUS_SUCCESS);
}
PDATA_CELL pClassData;
DPRINT("KH %x I %d KIC %x KI %x L %d RL %x\n",
- KeyHandle,
- Index,
- KeyInformationClass,
- KeyInformation,
- Length,
- ResultLength);
-
+ KeyHandle,
+ Index,
+ KeyInformationClass,
+ KeyInformation,
+ Length,
+ ResultLength);
+
/* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle,
KEY_ENUMERATE_SUB_KEYS,
if (!NT_SUCCESS(Status))
{
DPRINT("ObReferenceObjectByHandle() failed with status %x\n", Status);
- return Status;
+ return(Status);
}
+ /* Acquire hive lock */
+ ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE);
+
VERIFY_KEY_OBJECT(KeyObject);
/* Get pointer to KeyCell */
KeyCell = KeyObject->KeyCell;
RegistryHive = KeyObject->RegistryHive;
-
+
/* Get pointer to SubKey */
if (Index >= KeyCell->NumberOfSubKeys)
- {
- if (RegistryHive == CmiVolatileHive)
- {
- ObDereferenceObject (KeyObject);
- DPRINT("No more volatile entries\n");
- return STATUS_NO_MORE_ENTRIES;
- }
- else
- {
- ULONG i;
- PKEY_OBJECT CurKey = NULL;
-
- /* Search volatile keys */
- for (i = 0; i < KeyObject->NumberOfSubKeys; i++)
- {
- CurKey = KeyObject->SubKeys[i];
- if (CurKey->RegistryHive == CmiVolatileHive)
- {
- if (Index-- == KeyObject->NumberOfSubKeys)
- break;
- }
- }
- if(Index >= KeyCell->NumberOfSubKeys)
- {
- ObDereferenceObject (KeyObject);
- DPRINT("No more non-volatile entries\n");
- return STATUS_NO_MORE_ENTRIES;
- }
- SubKeyCell = CurKey->KeyCell;
- }
- }
+ {
+ if (RegistryHive == CmiVolatileHive)
+ {
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+ ObDereferenceObject(KeyObject);
+ DPRINT("No more volatile entries\n");
+ return(STATUS_NO_MORE_ENTRIES);
+ }
+ else
+ {
+ ULONG i;
+ PKEY_OBJECT CurKey = NULL;
+
+ /* Search volatile keys */
+ for (i = 0; i < KeyObject->NumberOfSubKeys; i++)
+ {
+ CurKey = KeyObject->SubKeys[i];
+ if (CurKey->RegistryHive == CmiVolatileHive)
+ {
+ if (Index-- == KeyObject->NumberOfSubKeys)
+ break;
+ }
+ }
+ if (Index >= KeyCell->NumberOfSubKeys)
+ {
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+ ObDereferenceObject(KeyObject);
+ DPRINT("No more non-volatile entries\n");
+ return(STATUS_NO_MORE_ENTRIES);
+ }
+ SubKeyCell = CurKey->KeyCell;
+ }
+ }
else
- {
- HashTableBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL);
- SubKeyCell = CmiGetKeyFromHashByIndex(RegistryHive,
- HashTableBlock,
- Index);
- }
+ {
+ HashTableBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL);
+ SubKeyCell = CmiGetKeyFromHashByIndex(RegistryHive,
+ HashTableBlock,
+ Index);
+ }
if (SubKeyCell == NULL)
- {
- ObDereferenceObject (KeyObject);
- DPRINT("No more entries\n");
- return STATUS_NO_MORE_ENTRIES;
- }
+ {
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+ ObDereferenceObject(KeyObject);
+ DPRINT("No more entries\n");
+ return(STATUS_NO_MORE_ENTRIES);
+ }
Status = STATUS_SUCCESS;
switch (KeyInformationClass)
break;
}
CmiReleaseBlock(RegistryHive, SubKeyCell);
- ObDereferenceObject (KeyObject);
+
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+ ObDereferenceObject(KeyObject);
DPRINT("Returning status %x\n", Status);
- return Status;
+ return(Status);
}
PKEY_VALUE_FULL_INFORMATION ValueFullInformation;
DPRINT("KH %x I %d KVIC %x KVI %x L %d RL %x\n",
- KeyHandle,
- Index,
- KeyValueInformationClass,
- KeyValueInformation,
- Length,
- ResultLength);
+ KeyHandle,
+ Index,
+ KeyValueInformationClass,
+ KeyValueInformation,
+ Length,
+ ResultLength);
/* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle,
return Status;
}
+ /* Acquire hive lock */
+ ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE);
+
VERIFY_KEY_OBJECT(KeyObject);
/* Get pointer to KeyCell */
KeyCell = KeyObject->KeyCell;
RegistryHive = KeyObject->RegistryHive;
-
+
/* Get Value block of interest */
Status = CmiGetValueFromKeyByIndex(RegistryHive,
KeyCell,
if (!NT_SUCCESS(Status))
{
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
return Status;
}
- else if (ValueCell != NULL)
+
+ if (ValueCell != NULL)
{
switch (KeyValueInformationClass)
{
case KeyValueBasicInformation:
- *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) +
- (ValueCell->NameSize + 1) * sizeof(WCHAR);
+ 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);
+ }
if (Length < *ResultLength)
{
Status = STATUS_BUFFER_OVERFLOW;
KeyValueInformation;
ValueBasicInformation->TitleIndex = 0;
ValueBasicInformation->Type = ValueCell->DataType;
- ValueBasicInformation->NameLength =
- (ValueCell->NameSize + 1) * sizeof(WCHAR);
- mbstowcs(ValueBasicInformation->Name,
- ValueCell->Name,
- ValueCell->NameSize * 2);
- ValueBasicInformation->Name[ValueCell->NameSize] = 0;
+ 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:
- *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) +
- ValueCell->NameSize * sizeof(WCHAR) + (ValueCell->DataSize & LONG_MAX);
+ 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);
+ }
if (Length < *ResultLength)
{
Status = STATUS_BUFFER_OVERFLOW;
KeyValueInformation;
ValueFullInformation->TitleIndex = 0;
ValueFullInformation->Type = ValueCell->DataType;
+ 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 =
- (DWORD)ValueFullInformation->Name - (DWORD) ValueFullInformation
- + (ValueCell->NameSize + 1) * sizeof(WCHAR);
+ (ULONG)ValueFullInformation->Name - (ULONG)ValueFullInformation +
+ ValueFullInformation->NameLength;
ValueFullInformation->DataOffset =
- (ValueFullInformation->DataOffset + 3) & 0xfffffffc;
+ (ValueFullInformation->DataOffset + 3) & 0xfffffffc;
ValueFullInformation->DataLength = ValueCell->DataSize & LONG_MAX;
- ValueFullInformation->NameLength =
- (ValueCell->NameSize + 1) * sizeof(WCHAR);
- mbstowcs(ValueFullInformation->Name,
- ValueCell->Name,
- ValueCell->NameSize * 2);
- ValueFullInformation->Name[ValueCell->NameSize] = 0;
if (ValueCell->DataSize > 0)
- {
- DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
- RtlCopyMemory((PCHAR) ValueFullInformation
- + ValueFullInformation->DataOffset,
- DataCell->Data,
- ValueCell->DataSize & LONG_MAX);
- CmiReleaseBlock(RegistryHive, DataCell);
- }
+ {
+ DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
+ RtlCopyMemory((PCHAR) ValueFullInformation
+ + ValueFullInformation->DataOffset,
+ DataCell->Data,
+ ValueCell->DataSize & LONG_MAX);
+ CmiReleaseBlock(RegistryHive, DataCell);
+ }
else
- {
- RtlCopyMemory((PCHAR) ValueFullInformation
- + ValueFullInformation->DataOffset,
- &ValueCell->DataOffset,
- ValueCell->DataSize & LONG_MAX);
- }
+ {
+ RtlCopyMemory((PCHAR) ValueFullInformation
+ + ValueFullInformation->DataOffset,
+ &ValueCell->DataOffset,
+ ValueCell->DataSize & LONG_MAX);
+ }
}
break;
}
{
Status = STATUS_UNSUCCESSFUL;
}
+
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
return Status;
NTSTATUS STDCALL
NtFlushKey(IN HANDLE KeyHandle)
{
- NTSTATUS Status;
- PKEY_OBJECT KeyObject;
- PREGISTRY_HIVE RegistryHive;
- WCHAR LogName[MAX_PATH];
- UNICODE_STRING TmpFileName;
- HANDLE FileHandle;
- // HANDLE FileHandleLog;
- OBJECT_ATTRIBUTES ObjectAttributes;
- // KIRQL OldIrql;
- LARGE_INTEGER fileOffset;
- DWORD * pEntDword;
- ULONG i;
+ NTSTATUS Status;
+ PKEY_OBJECT KeyObject;
+ PREGISTRY_HIVE RegistryHive;
+#if 0
+ WCHAR LogName[MAX_PATH];
+ UNICODE_STRING TmpFileName;
+ HANDLE FileHandle;
+// HANDLE FileHandleLog;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ LARGE_INTEGER fileOffset;
+ DWORD * pEntDword;
+ ULONG i;
+#endif
DPRINT("KeyHandle %x\n", KeyHandle);
- /* Verify that the handle is valid and is a registry key */
- Status = ObReferenceObjectByHandle(KeyHandle,
- KEY_QUERY_VALUE,
- CmiKeyType,
- UserMode,
- (PVOID *) &KeyObject,
- NULL);
-
+ /* 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;
+ return(Status);
}
VERIFY_KEY_OBJECT(KeyObject);
RegistryHive = KeyObject->RegistryHive;
-// KeAcquireSpinLock(&RegistryHive->RegLock, &OldIrql);
+
+ /* Acquire hive lock */
+ ExAcquireResourceExclusiveLite(&RegistryHive->HiveResource,
+ TRUE);
+
+ if (IsPermanentHive(RegistryHive))
+ {
+ /* Flush non-volatile hive */
+ Status = CmiFlushRegistryHive(RegistryHive);
+ }
+ else
+ {
+ Status = STATUS_SUCCESS;
+ }
+
+
+#if 0
/* Then write changed blocks in .log */
wcscpy(LogName,RegistryHive->Filename.Buffer);
wcscat(LogName,L".log");
RtlInitUnicodeString (&TmpFileName, LogName);
InitializeObjectAttributes(&ObjectAttributes,
- &TmpFileName,
- 0,
- NULL,
- NULL);
+ &TmpFileName,
+ 0,
+ NULL,
+ NULL);
/* BEGIN FIXME : actually (26 November 200) vfatfs.sys can't create new files
so we can't create log file
NULL,
0,
FILE_SYNCHRONOUS_IO_NONALERT);
-
if (!NT_SUCCESS(Status))
{
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
return Status;
}
RegistryHive->HiveHeader->Version++;
- Status = ZwWriteFile(FileHandle,
- 0,
- 0,
- 0,
- 0,
- RegistryHive->HiveHeader,
- sizeof(HIVE_HEADER),
- 0,
- 0);
-
+ Status = ZwWriteFile(FileHandle,
+ 0,
+ 0,
+ 0,
+ 0,
+ RegistryHive->HiveHeader,
+ sizeof(HIVE_HEADER),
+ 0,
+ 0);
if (!NT_SUCCESS(Status))
{
ZwClose(FileHandle);
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
return Status;
}
/* Update changed blocks in file */
fileOffset.u.HighPart = 0;
for (i = 0; i < RegistryHive->BlockListSize ; i++)
- {
- if (RegistryHive->BlockList[i]->DateModified.dwHighDateTime
+ {
+ if (RegistryHive->BlockList[i]->DateModified.dwHighDateTime
> RegistryHive->HiveHeader->DateModified.dwHighDateTime
- || (RegistryHive->BlockList[i]->DateModified.dwHighDateTime
+ || (RegistryHive->BlockList[i]->DateModified.dwHighDateTime
== RegistryHive->HiveHeader->DateModified.dwHighDateTime
- && RegistryHive->BlockList[i]->DateModified.dwLowDateTime
- > RegistryHive->HiveHeader->DateModified.dwLowDateTime
- )
- )
+ && RegistryHive->BlockList[i]->DateModified.dwLowDateTime
+ > RegistryHive->HiveHeader->DateModified.dwLowDateTime))
+ {
+ fileOffset.u.LowPart = RegistryHive->BlockList[i]->BlockOffset+4096;
+ Status = NtWriteFile(FileHandle,
+ 0,
+ 0,
+ 0,
+ 0,
+ RegistryHive->BlockList[i],
+ RegistryHive->BlockList[i]->BlockSize,
+ &fileOffset,
+ 0);
+ if (!NT_SUCCESS(Status))
{
- fileOffset.u.LowPart = RegistryHive->BlockList[i]->BlockOffset+4096;
- Status = NtWriteFile(FileHandle,
- 0,
- 0,
- 0,
- 0,
- RegistryHive->BlockList[i],
- RegistryHive->BlockList[i]->BlockSize ,
- &fileOffset,
- 0);
-
- if (!NT_SUCCESS(Status))
- {
- ZwClose(FileHandle);
- ObDereferenceObject(KeyObject);
- return Status;
- }
+ ZwClose(FileHandle);
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+ ObDereferenceObject(KeyObject);
+ return(Status);
}
- }
+ }
+ }
/* Change version in header */
RegistryHive->HiveHeader->VersionOld = RegistryHive->HiveHeader->Version;
/* Write new header */
fileOffset.u.LowPart = 0;
- Status = ZwWriteFile(FileHandle,
- 0,
- 0,
- 0,
- 0,
- RegistryHive->HiveHeader,
- sizeof(HIVE_HEADER),
- &fileOffset,
- 0);
+ Status = ZwWriteFile(FileHandle,
+ 0,
+ 0,
+ 0,
+ 0,
+ RegistryHive->HiveHeader,
+ sizeof(HIVE_HEADER),
+ &fileOffset,
+ 0);
if (!NT_SUCCESS(Status))
{
ZwClose(FileHandle);
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
return Status;
}
ZwClose(FileHandle);
-// KeReleaseSpinLock(&RegistryHive->RegLock, OldIrql);
+#endif
+
+ ExReleaseResourceLite(&RegistryHive->HiveResource);
+
ObDereferenceObject(KeyObject);
+
return STATUS_SUCCESS;
}
NTSTATUS Status;
PVOID Object;
- DPRINT("KH %x DA %x OA %x OA->ON %x\n",
+ DPRINT("NtOpenFile(KH %x DA %x OA %x OA->ON '%wZ'\n",
KeyHandle,
DesiredAccess,
ObjectAttributes,
VERIFY_KEY_OBJECT((PKEY_OBJECT) Object);
- DPRINT("RemainingPath.Buffer %x\n", RemainingPath.Buffer);
+ DPRINT("RemainingPath '%wZ'\n", &RemainingPath);
if ((RemainingPath.Buffer != NULL) && (RemainingPath.Buffer[0] != 0))
{
NTSTATUS STDCALL
-NtQueryKey(IN HANDLE KeyHandle,
- IN KEY_INFORMATION_CLASS KeyInformationClass,
- OUT PVOID KeyInformation,
- IN ULONG Length,
- OUT PULONG ResultLength)
+NtQueryKey(IN HANDLE KeyHandle,
+ IN KEY_INFORMATION_CLASS KeyInformationClass,
+ OUT PVOID KeyInformation,
+ IN ULONG Length,
+ OUT PULONG ResultLength)
{
PKEY_BASIC_INFORMATION BasicInformation;
PKEY_NODE_INFORMATION NodeInformation;
NTSTATUS Status;
DPRINT("KH %x KIC %x KI %x L %d RL %x\n",
- KeyHandle,
- KeyInformationClass,
- KeyInformation,
- Length,
- ResultLength);
-
+ KeyHandle,
+ KeyInformationClass,
+ KeyInformation,
+ Length,
+ ResultLength);
+
/* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle,
KEY_READ,
UserMode,
(PVOID *) &KeyObject,
NULL);
-
if (!NT_SUCCESS(Status))
{
+CHECKPOINT1;
return Status;
}
+CHECKPOINT1;
+
+ /* Acquire hive lock */
+ ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE);
+CHECKPOINT1;
VERIFY_KEY_OBJECT(KeyObject);
/* Get pointer to KeyCell */
KeyCell = KeyObject->KeyCell;
RegistryHive = KeyObject->RegistryHive;
-
+
Status = STATUS_SUCCESS;
switch (KeyInformationClass)
{
case KeyBasicInformation:
+CHECKPOINT1;
/* Check size of buffer */
if (Length < sizeof(KEY_BASIC_INFORMATION) +
KeyObject->NameSize * sizeof(WCHAR))
*ResultLength = sizeof(KEY_BASIC_INFORMATION) +
KeyObject->NameSize * sizeof(WCHAR);
}
+CHECKPOINT1;
break;
-
+
case KeyNodeInformation:
/* Check size of buffer */
if (Length < sizeof(KEY_NODE_INFORMATION)
break;
}
+CHECKPOINT1;
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+CHECKPOINT1;
ObDereferenceObject(KeyObject);
+CHECKPOINT1;
- return Status;
+ return(Status);
}
+
NTSTATUS STDCALL
NtQueryValueKey(IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName,
PKEY_VALUE_BASIC_INFORMATION ValueBasicInformation;
PKEY_VALUE_PARTIAL_INFORMATION ValuePartialInformation;
PKEY_VALUE_FULL_INFORMATION ValueFullInformation;
- char ValueName2[MAX_PATH];
DPRINT("NtQueryValueKey(KeyHandle %x ValueName %S Length %x)\n",
KeyHandle, ValueName->Buffer, Length);
- wcstombs(ValueName2, ValueName->Buffer, ValueName->Length >> 1);
- ValueName2[ValueName->Length >> 1] = 0;
-
/* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle,
KEY_QUERY_VALUE,
return Status;
}
+ /* Acquire hive lock */
+ ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE);
+
VERIFY_KEY_OBJECT(KeyObject);
/* Get pointer to KeyCell */
KeyCell = KeyObject->KeyCell;
RegistryHive = KeyObject->RegistryHive;
- /* Get Value block of interest */
- Status = CmiScanKeyForValue(RegistryHive,
- KeyCell,
- ValueName2,
- &ValueCell,NULL);
+ /* Get Value block of interest */
+ Status = CmiScanKeyForValue(RegistryHive,
+ KeyCell,
+ ValueName,
+ &ValueCell,
+ NULL);
if (!NT_SUCCESS(Status))
{
DPRINT("CmiScanKeyForValue() failed with status %x\n", Status);
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
- return Status;
+ return(Status);
}
else if (ValueCell != NULL)
{
switch (KeyValueInformationClass)
{
case KeyValueBasicInformation:
- *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION)
- + ValueCell->NameSize * sizeof(WCHAR);
+ 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);
+ }
if (Length < *ResultLength)
{
Status = STATUS_BUFFER_TOO_SMALL;
KeyValueInformation;
ValueBasicInformation->TitleIndex = 0;
ValueBasicInformation->Type = ValueCell->DataType;
- ValueBasicInformation->NameLength =
- (ValueCell->NameSize + 1) * sizeof(WCHAR);
- mbstowcs(ValueBasicInformation->Name,
- ValueCell->Name,ValueCell->NameSize * 2);
- ValueBasicInformation->Name[ValueCell->NameSize] = 0;
+ 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;
}
else
{
- ValuePartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)
+ ValuePartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)
KeyValueInformation;
ValuePartialInformation->TitleIndex = 0;
ValuePartialInformation->Type = ValueCell->DataType;
ValuePartialInformation->DataLength = ValueCell->DataSize & LONG_MAX;
if (ValueCell->DataSize > 0)
- {
- DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
- RtlCopyMemory(ValuePartialInformation->Data,
+ {
+ DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
+ RtlCopyMemory(ValuePartialInformation->Data,
DataCell->Data,
ValueCell->DataSize & LONG_MAX);
- CmiReleaseBlock(RegistryHive, DataCell);
- }
+ CmiReleaseBlock(RegistryHive, DataCell);
+ }
else
- {
- RtlCopyMemory(ValuePartialInformation->Data,
- &ValueCell->DataOffset,
+ {
+ RtlCopyMemory(ValuePartialInformation->Data,
+ &ValueCell->DataOffset,
ValueCell->DataSize & LONG_MAX);
- }
+ }
}
break;
case KeyValueFullInformation:
- *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION)
- + (ValueCell->NameSize -1) * sizeof(WCHAR)
- + (ValueCell->DataSize & LONG_MAX);
+ 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);
+ }
if (Length < *ResultLength)
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
- ValueFullInformation = (PKEY_VALUE_FULL_INFORMATION)
+ ValueFullInformation = (PKEY_VALUE_FULL_INFORMATION)
KeyValueInformation;
ValueFullInformation->TitleIndex = 0;
ValueFullInformation->Type = ValueCell->DataType;
+ 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 =
- (DWORD)ValueFullInformation->Name - (DWORD)ValueFullInformation
- + (ValueCell->NameSize + 1) * sizeof(WCHAR);
+ (ULONG)ValueFullInformation->Name - (ULONG)ValueFullInformation +
+ ValueFullInformation->NameLength;
ValueFullInformation->DataOffset =
- (ValueFullInformation->DataOffset + 3) &0xfffffffc;
+ (ValueFullInformation->DataOffset + 3) & 0xfffffffc;
ValueFullInformation->DataLength = ValueCell->DataSize & LONG_MAX;
- ValueFullInformation->NameLength =
- (ValueCell->NameSize + 1) * sizeof(WCHAR);
- mbstowcs(ValueFullInformation->Name, ValueCell->Name,ValueCell->NameSize*2);
- ValueFullInformation->Name[ValueCell->NameSize] = 0;
if (ValueCell->DataSize > 0)
- {
- DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
- RtlCopyMemory((PCHAR) ValueFullInformation
- + ValueFullInformation->DataOffset,
- DataCell->Data,
- ValueCell->DataSize & LONG_MAX);
- CmiReleaseBlock(RegistryHive, DataCell);
- }
+ {
+ DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
+ RtlCopyMemory((PCHAR) ValueFullInformation
+ + ValueFullInformation->DataOffset,
+ DataCell->Data,
+ ValueCell->DataSize & LONG_MAX);
+ CmiReleaseBlock(RegistryHive, DataCell);
+ }
else
- {
- RtlCopyMemory((PCHAR) ValueFullInformation
- + ValueFullInformation->DataOffset,
- &ValueCell->DataOffset,
- ValueCell->DataSize & LONG_MAX);
- }
+ {
+ RtlCopyMemory((PCHAR) ValueFullInformation
+ + ValueFullInformation->DataOffset,
+ &ValueCell->DataOffset,
+ ValueCell->DataSize & LONG_MAX);
+ }
}
break;
}
Status = STATUS_OBJECT_NAME_NOT_FOUND;
}
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
-
+
return Status;
}
PKEY_CELL KeyCell;
PVALUE_CELL ValueCell;
BLOCK_OFFSET VBOffset;
- char ValueName2[MAX_PATH];
PDATA_CELL DataCell;
PDATA_CELL NewDataCell;
PHBIN pBin;
ULONG DesiredAccess;
-// KIRQL OldIrql;
- DPRINT("KeyHandle %x ValueName %S Type %d\n",
- KeyHandle, ValueName? ValueName->Buffer : NULL, Type);
-
- wcstombs(ValueName2,ValueName->Buffer, ValueName->Length >> 1);
- ValueName2[ValueName->Length>>1] = 0;
+ DPRINT("NtSetValueKey(KeyHandle %x ValueName %S Type %d)\n",
+ KeyHandle, ValueName? ValueName->Buffer : NULL, Type);
DesiredAccess = KEY_SET_VALUE;
if (Type == REG_LINK)
if (!NT_SUCCESS(Status))
return(Status);
+ /* Acquire hive lock exclucively */
+ ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
+
VERIFY_KEY_OBJECT(KeyObject);
/* Get pointer to key cell */
RegistryHive = KeyObject->RegistryHive;
Status = CmiScanKeyForValue(RegistryHive,
KeyCell,
- ValueName2,
+ ValueName,
&ValueCell,
&VBOffset);
if (!NT_SUCCESS(Status))
{
DPRINT1("Value not found. Status 0x%X\n", Status);
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
return(Status);
}
-// KeAcquireSpinLock(&RegistryHive->RegLock, &OldIrql);
-
if (ValueCell == NULL)
{
+ DPRINT("Allocate new value cell\n");
Status = CmiAddValueToKey(RegistryHive,
KeyCell,
- ValueName2,
+ ValueName,
&ValueCell,
&VBOffset);
+ if (NT_SUCCESS(Status))
+ {
+ CmiMarkBlockDirty(RegistryHive, VBOffset);
+ }
}
if (!NT_SUCCESS(Status))
{
DPRINT1("Cannot add value. Status 0x%X\n", Status);
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
return(Status);
}
- else
- {
- DPRINT("DataSize (%d)\n", DataSize);
+ DPRINT("DataSize %lu\n", DataSize);
+ DPRINT("ValueCell %p\n", ValueCell);
+ DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
+
+ if (DataSize <= 4)
+ {
/* If datasize <= 4 then write in valueblock directly */
- if (DataSize <= 4)
+ DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
+ if ((ValueCell->DataSize >= 0) &&
+ (DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL)))
{
- DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
- if ((ValueCell->DataSize >= 0) &&
- (DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL)))
- {
- CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset);
- }
-
- RtlCopyMemory(&ValueCell->DataOffset, Data, DataSize);
- ValueCell->DataSize = DataSize | 0x80000000;
- ValueCell->DataType = Type;
- RtlMoveMemory(&ValueCell->DataOffset, Data, DataSize);
+ CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset);
}
+
+ RtlCopyMemory(&ValueCell->DataOffset, Data, DataSize);
+ ValueCell->DataSize = DataSize | 0x80000000;
+ ValueCell->DataType = Type;
+ RtlMoveMemory(&ValueCell->DataOffset, Data, DataSize);
+ CmiMarkBlockDirty(RegistryHive, VBOffset);
+ }
+ else if (DataSize <= (ULONG) (ValueCell->DataSize & 0x7fffffff))
+ {
/* If new data size is <= current then overwrite current data */
- else if (DataSize <= (ValueCell->DataSize & 0x7fffffff))
+ DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset,&pBin);
+ RtlZeroMemory(DataCell->Data, ValueCell->DataSize);
+ RtlCopyMemory(DataCell->Data, Data, DataSize);
+ ValueCell->DataSize = DataSize;
+ ValueCell->DataType = Type;
+ CmiReleaseBlock(RegistryHive, DataCell);
+
+ /* Update time of heap */
+ if (IsPermanentHive(RegistryHive))
{
- DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset,&pBin);
- RtlCopyMemory(DataCell->Data, Data, DataSize);
- ValueCell->DataSize = DataSize;
- ValueCell->DataType = Type;
- CmiReleaseBlock(RegistryHive, DataCell);
- /* Update time of heap */
- if (IsPermanentHive(RegistryHive))
- {
- ZwQuerySystemTime((PTIME) &pBin->DateModified);
- }
+ ZwQuerySystemTime((PTIME) &pBin->DateModified);
}
- else
- {
- BLOCK_OFFSET NewOffset;
+ CmiMarkBlockDirty(RegistryHive, ValueCell->DataOffset);
+ }
+ else
+ {
+ /*
+ * New data size is larger than the current, destroy current
+ * data block and allocate a new one.
+ */
+ BLOCK_OFFSET NewOffset;
- /* Destroy current data block and allocate a new one */
- if ((ValueCell->DataSize >= 0) &&
- (DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL)))
- {
- CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset);
- }
- Status = CmiAllocateBlock(RegistryHive,
- (PVOID *)&NewDataCell,
- DataSize,
- &NewOffset);
- RtlCopyMemory(&NewDataCell->Data[0], Data, DataSize);
- ValueCell->DataSize = DataSize;
- ValueCell->DataType = Type;
- CmiReleaseBlock(RegistryHive, NewDataCell);
- ValueCell->DataOffset = NewOffset;
- }
+ DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
- if (strcmp(ValueName2, "SymbolicLinkValue") == 0)
+ if ((ValueCell->DataSize >= 0) &&
+ (DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL)))
{
- KeyCell->Type = REG_LINK_KEY_CELL_TYPE;
+ CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset);
+ ValueCell->DataSize = 0;
+ ValueCell->DataType = 0;
+ ValueCell->DataOffset = 0xffffffff;
}
- /* Update time of heap */
- if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin))
+ Status = CmiAllocateBlock(RegistryHive,
+ (PVOID *)&NewDataCell,
+ DataSize,
+ &NewOffset);
+ if (!NT_SUCCESS(Status))
{
- ZwQuerySystemTime((PTIME) &pBin->DateModified);
+ DPRINT("CmiAllocateBlock() failed (Status %lx)\n", Status);
+
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+ ObDereferenceObject(KeyObject);
+
+ return(Status);
}
+
+ RtlCopyMemory(&NewDataCell->Data[0], Data, DataSize);
+ ValueCell->DataSize = DataSize;
+ ValueCell->DataType = Type;
+ CmiReleaseBlock(RegistryHive, NewDataCell);
+ ValueCell->DataOffset = NewOffset;
+ CmiMarkBlockDirty(RegistryHive, ValueCell->DataOffset);
+ }
+
+ /* Mark link key */
+ if ((_wcsicmp(ValueName->Buffer, L"SymbolicLinkValue") == 0) &&
+ (Type == REG_LINK))
+ {
+ KeyCell->Type = REG_LINK_KEY_CELL_TYPE;
+ CmiMarkBlockDirty(RegistryHive, KeyObject->BlockOffset);
}
-// KeReleaseSpinLock(&RegistryHive->RegLock, OldIrql);
+ /* Update time of heap */
+ if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin))
+ {
+ ZwQuerySystemTime((PTIME) &pBin->DateModified);
+ }
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
+ CmiSyncHives();
+
DPRINT("Return Status 0x%X\n", Status);
return(Status);
NTSTATUS STDCALL
NtDeleteValueKey(IN HANDLE KeyHandle,
- IN PUNICODE_STRING ValueName)
+ IN PUNICODE_STRING ValueName)
{
- PREGISTRY_HIVE RegistryHive;
- CHAR ValueName2[MAX_PATH];
PKEY_OBJECT KeyObject;
- PKEY_CELL KeyCell;
NTSTATUS Status;
-// KIRQL OldIrql;
-
- wcstombs(ValueName2, ValueName->Buffer, ValueName->Length >> 1);
- ValueName2[ValueName->Length>>1] = 0;
/* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle,
UserMode,
(PVOID *)&KeyObject,
NULL);
-
if (!NT_SUCCESS(Status))
{
return Status;
}
+ /* Acquire hive lock */
+ ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
+
VERIFY_KEY_OBJECT(KeyObject);
- /* Get pointer to KeyCell */
- KeyCell = KeyObject->KeyCell;
- RegistryHive = KeyObject->RegistryHive;
-// KeAcquireSpinLock(&RegistryHive->RegLock, &OldIrql);
- Status = CmiDeleteValueFromKey(RegistryHive, KeyCell, ValueName2);
-// KeReleaseSpinLock(&RegistryHive->RegLock, OldIrql);
+ Status = CmiDeleteValueFromKey(KeyObject->RegistryHive,
+ KeyObject->KeyCell,
+ KeyObject->BlockOffset,
+ ValueName);
+
+ /* Release hive lock */
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+
ObDereferenceObject(KeyObject);
+ CmiSyncHives();
+
return Status;
}
NTSTATUS STDCALL
NtNotifyChangeKey(
IN HANDLE KeyHandle,
- IN HANDLE Event,
- IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
- IN PVOID ApcContext OPTIONAL,
+ IN HANDLE Event,
+ IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
+ IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG CompletionFilter,
- IN BOOLEAN Asynchroneous,
+ IN BOOLEAN Asynchroneous,
OUT PVOID ChangeBuffer,
IN ULONG Length,
IN BOOLEAN WatchSubtree)
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)
+ IN OUT PKEY_VALUE_ENTRY ValueList,
+ IN ULONG NumberOfValues,
+ OUT PVOID Buffer,
+ IN OUT PULONG Length,
+ OUT PULONG ReturnLength)
{
PREGISTRY_HIVE RegistryHive;
- UCHAR ValueName[MAX_PATH];
PVALUE_CELL ValueCell;
PKEY_OBJECT KeyObject;
PDATA_CELL DataCell;
return(Status);
}
+ /* Acquire hive lock */
+ ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE);
+
VERIFY_KEY_OBJECT(KeyObject);
/* Get pointer to KeyCell */
for (i = 0; i < NumberOfValues; i++)
{
- wcstombs(ValueName,
- ValueList[i].ValueName->Buffer,
- ValueList[i].ValueName->Length >> 1);
- ValueName[ValueList[i].ValueName->Length >> 1] = 0;
-
- DPRINT("ValueName: '%s'\n", ValueName);
+ DPRINT("ValueName: '%wZ'\n", ValueList[i].ValueName);
/* Get Value block of interest */
Status = CmiScanKeyForValue(RegistryHive,
KeyCell,
- ValueName,
+ ValueList[i].ValueName,
&ValueCell,
NULL);
*ReturnLength = BufferLength;
+ /* Release hive lock */
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+
ObDereferenceObject(KeyObject);
DPRINT("Return Status 0x%X\n", Status);
- return Status;
+ return(Status);
}