* UPDATE HISTORY:
*/
-#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/registry.h>
#include <ntos/minmax.h>
PKEY_OBJECT FoundObject;
PKEY_OBJECT ParsedKey;
PKEY_CELL SubKeyCell;
- CHAR cPath[MAX_PATH];
NTSTATUS Status;
PWSTR StartPtr;
PWSTR EndPtr;
ULONG Length;
UNICODE_STRING LinkPath;
UNICODE_STRING TargetPath;
+ UNICODE_STRING KeyName;
ParsedKey = ParsedObject;
else
Length = wcslen(StartPtr);
- wcstombs(cPath, StartPtr, Length);
- cPath[Length] = 0;
+ KeyName.Length = Length * sizeof(WCHAR);
+ KeyName.MaximumLength = KeyName.Length + sizeof(WCHAR);
+ KeyName.Buffer = ExAllocatePool(NonPagedPool,
+ KeyName.MaximumLength);
+ RtlCopyMemory(KeyName.Buffer,
+ StartPtr,
+ KeyName.Length);
+ KeyName.Buffer[KeyName.Length / sizeof(WCHAR)] = 0;
- FoundObject = CmiScanKeyList(ParsedKey, cPath, Attributes);
+
+ FoundObject = CmiScanKeyList(ParsedKey,
+ &KeyName,
+ Attributes);
if (FoundObject == NULL)
{
Status = CmiScanForSubKey(ParsedKey->RegistryHive,
ParsedKey->KeyCell,
&SubKeyCell,
&BlockOffset,
- cPath,
+ &KeyName,
0,
Attributes);
if (!NT_SUCCESS(Status) || (SubKeyCell == NULL))
{
+ RtlFreeUnicodeString(&KeyName);
return(STATUS_UNSUCCESSFUL);
}
- if ((SubKeyCell->Type == REG_LINK_KEY_CELL_TYPE) &&
- !((Attributes & OBJ_OPENLINK) && (EndPtr == NULL) /*(end == NULL)*/))
+ if ((SubKeyCell->Flags & REG_KEY_LINK_CELL) &&
+ !((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)))
{
RtlInitUnicodeString(&LinkPath, NULL);
Status = CmiGetLinkTarget(ParsedKey->RegistryHive,
*Path = FullPath->Buffer;
*NextObject = NULL;
+
+ RtlFreeUnicodeString(&KeyName);
return(STATUS_REPARSE);
}
}
/* Create new key object and put into linked list */
- DPRINT("CmiObjectParse: %s\n", cPath);
- Status = ObCreateObject(NULL,
+ DPRINT("CmiObjectParse: %s\n", Path);
+ Status = ObRosCreateObject(NULL,
STANDARD_RIGHTS_REQUIRED,
NULL,
CmiKeyType,
(PVOID*)&FoundObject);
if (!NT_SUCCESS(Status))
{
+ RtlFreeUnicodeString(&KeyName);
return(Status);
}
FoundObject->Flags = 0;
- FoundObject->Name = SubKeyCell->Name;
- FoundObject->NameSize = SubKeyCell->NameSize;
FoundObject->KeyCell = SubKeyCell;
FoundObject->BlockOffset = BlockOffset;
FoundObject->RegistryHive = ParsedKey->RegistryHive;
+ RtlCreateUnicodeString(&FoundObject->Name,
+ KeyName.Buffer);
CmiAddKeyToList(ParsedKey, FoundObject);
DPRINT("Created object 0x%x\n", FoundObject);
}
else
{
- if ((FoundObject->KeyCell->Type == REG_LINK_KEY_CELL_TYPE) &&
- !((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)/*(end == NULL)*/))
+ if ((FoundObject->KeyCell->Flags & REG_KEY_LINK_CELL) &&
+ !((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)))
{
DPRINT("Found link\n");
*Path = FullPath->Buffer;
*NextObject = NULL;
+
+ RtlFreeUnicodeString(&KeyName);
return(STATUS_REPARSE);
}
}
*NextObject = FoundObject;
+ RtlFreeUnicodeString(&KeyName);
+
return(STATUS_SUCCESS);
}
PWSTR RemainingPath,
POBJECT_ATTRIBUTES ObjectAttributes)
{
- PKEY_OBJECT pKey = ObjectBody;
+ PKEY_OBJECT KeyObject = ObjectBody;
+ PWSTR Start;
- pKey->ParentKey = Parent;
+ KeyObject->ParentKey = Parent;
if (RemainingPath)
{
- if(RemainingPath[0]== L'\\')
- {
- pKey->Name = (PCHAR)(&RemainingPath[1]);
- pKey->NameSize = wcslen(RemainingPath) - 1;
- }
- else
- {
- pKey->Name = (PCHAR)RemainingPath;
- pKey->NameSize = wcslen(RemainingPath);
- }
+ Start = RemainingPath;
+ if(*Start == L'\\')
+ Start++;
+ RtlCreateUnicodeString(&KeyObject->Name,
+ Start);
}
else
{
- pKey->NameSize = 0;
+ RtlInitUnicodeString(&KeyObject->Name,
+ NULL);
}
return STATUS_SUCCESS;
{
PKEY_OBJECT KeyObject;
- DPRINT("Delete object key\n");
+ DPRINT("Delete key object (%p)\n", DeletedObject);
KeyObject = (PKEY_OBJECT) DeletedObject;
+
+ ObReferenceObject(KeyObject->ParentKey);
if (!NT_SUCCESS(CmiRemoveKeyFromList(KeyObject)))
{
DPRINT1("Key not found in parent list ???\n");
}
+ RtlFreeUnicodeString(&KeyObject->Name);
+
if (KeyObject->Flags & KO_MARKED_FOR_DELETE)
{
DPRINT("delete really key\n");
KeyObject->ParentKey,
KeyObject);
- if (!IsVolatileHive(KeyObject->RegistryHive))
+ if (!IsNoFileHive(KeyObject->RegistryHive))
{
CmiSyncHives();
}
}
+ ObDereferenceObject(KeyObject->ParentKey);
+ if (KeyObject->NumberOfSubKeys)
+ {
+ KEBUGCHECK(0);
+ }
+ if (KeyObject->SizeOfSubKeys)
+ {
+ ExFreePool(KeyObject->SubKeys);
+ }
+
}
PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG BufferLength)
{
- DPRINT1("CmiObjectSecurity() called\n");
+ DPRINT1 ("CmiObjectSecurity() called\n");
- return(STATUS_SUCCESS);
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS STDCALL
+CmiObjectQueryName (PVOID ObjectBody,
+ POBJECT_NAME_INFORMATION ObjectNameInfo,
+ ULONG Length,
+ PULONG ReturnLength)
+{
+ POBJECT_NAME_INFORMATION LocalInfo;
+ PKEY_OBJECT KeyObject;
+ ULONG LocalReturnLength;
+ NTSTATUS Status;
+
+ DPRINT ("CmiObjectQueryName() called\n");
+
+ KeyObject = (PKEY_OBJECT)ObjectBody;
+
+ LocalInfo = ExAllocatePool (NonPagedPool,
+ sizeof(OBJECT_NAME_INFORMATION) +
+ MAX_PATH * sizeof(WCHAR));
+ if (LocalInfo == NULL)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ if (KeyObject->ParentKey != KeyObject)
+ {
+ Status = ObQueryNameString (KeyObject->ParentKey,
+ LocalInfo,
+ MAX_PATH * sizeof(WCHAR),
+ &LocalReturnLength);
+ }
+ else
+ {
+ /* KeyObject is the root key */
+ Status = ObQueryNameString (BODY_TO_HEADER(KeyObject)->Parent,
+ LocalInfo,
+ MAX_PATH * sizeof(WCHAR),
+ &LocalReturnLength);
+ }
+
+ if (!NT_SUCCESS (Status))
+ {
+ ExFreePool (LocalInfo);
+ return Status;
+ }
+ DPRINT ("Parent path: %wZ\n", &LocalInfo->Name);
+
+ Status = RtlAppendUnicodeStringToString (&ObjectNameInfo->Name,
+ &LocalInfo->Name);
+ ExFreePool (LocalInfo);
+ if (!NT_SUCCESS (Status))
+ return Status;
+
+ Status = RtlAppendUnicodeToString (&ObjectNameInfo->Name,
+ L"\\");
+ if (!NT_SUCCESS (Status))
+ return Status;
+
+ Status = RtlAppendUnicodeStringToString (&ObjectNameInfo->Name,
+ &KeyObject->Name);
+ if (NT_SUCCESS (Status))
+ {
+ DPRINT ("Total path: %wZ\n", &ObjectNameInfo->Name);
+ }
+
+ return Status;
}
PKEY_OBJECT
CmiScanKeyList(PKEY_OBJECT Parent,
- PCHAR KeyName,
+ PUNICODE_STRING KeyName,
ULONG Attributes)
{
PKEY_OBJECT CurKey;
KIRQL OldIrql;
- WORD NameSize;
- DWORD Index;
+ ULONG Index;
- DPRINT("Scanning key list for: %s (Parent: %s)\n",
- KeyName, Parent->Name);
+ DPRINT("Scanning key list for: %wZ (Parent: %wZ)\n",
+ KeyName, &Parent->Name);
- NameSize = strlen(KeyName);
KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
/* FIXME: if list maintained in alphabetic order, use dichotomic search */
for (Index=0; Index < Parent->NumberOfSubKeys; Index++)
CurKey = Parent->SubKeys[Index];
if (Attributes & OBJ_CASE_INSENSITIVE)
{
- if ((NameSize == CurKey->NameSize)
- && (_strnicmp(KeyName, CurKey->Name, NameSize) == 0))
+ if ((KeyName->Length == CurKey->Name.Length)
+ && (_wcsicmp(KeyName->Buffer, CurKey->Name.Buffer) == 0))
{
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
return CurKey;
}
else
{
- if ((NameSize == CurKey->NameSize)
- && (strncmp(KeyName,CurKey->Name,NameSize) == 0))
+ if ((KeyName->Length == CurKey->Name.Length)
+ && (wcscmp(KeyName->Buffer, CurKey->Name.Buffer) == 0))
{
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
return CurKey;