branch update for HEAD-2003091401
[reactos.git] / ntoskrnl / cm / regobj.c
index 27944d5..9c6d25c 100644 (file)
@@ -6,12 +6,12 @@
  * 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>
 
@@ -39,13 +39,13 @@ CmiObjectParse(PVOID ParsedObject,
   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;
 
@@ -72,27 +72,37 @@ CmiObjectParse(PVOID 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,
@@ -129,35 +139,38 @@ CmiObjectParse(PVOID ParsedObject,
              *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");
 
@@ -196,6 +209,8 @@ CmiObjectParse(PVOID ParsedObject,
              *Path = FullPath->Buffer;
 
              *NextObject = NULL;
+
+             RtlFreeUnicodeString(&KeyName);
              return(STATUS_REPARSE);
            }
        }
@@ -214,6 +229,8 @@ CmiObjectParse(PVOID ParsedObject,
 
   *NextObject = FoundObject;
 
+  RtlFreeUnicodeString(&KeyName);
+
   return(STATUS_SUCCESS);
 }
 
@@ -224,25 +241,22 @@ CmiObjectCreate(PVOID ObjectBody,
                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;
@@ -254,15 +268,19 @@ CmiObjectDelete(PVOID DeletedObject)
 {
   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");
@@ -271,11 +289,21 @@ CmiObjectDelete(PVOID DeletedObject)
                      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);
+    }
+
 }
 
 
@@ -286,9 +314,75 @@ CmiObjectSecurity(PVOID ObjectBody,
                  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;
 }
 
 
@@ -371,18 +465,16 @@ CmiRemoveKeyFromList(PKEY_OBJECT KeyToRemove)
 
 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++)
@@ -390,8 +482,8 @@ CmiScanKeyList(PKEY_OBJECT Parent,
       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;
@@ -399,8 +491,8 @@ CmiScanKeyList(PKEY_OBJECT Parent,
        }
       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;