update for HEAD-2003050101
[reactos.git] / ntoskrnl / cm / ntfunc.c
index 8d0a316..91a3f95 100644 (file)
@@ -8,9 +8,6 @@
 
 /* INCLUDES *****************************************************************/
 
-#ifdef WIN32_REGDBG
-#include "cm_win32.h"
-#else
 #include <ddk/ntddk.h>
 #include <roscfg.h>
 #include <internal/ob.h>
@@ -23,7 +20,6 @@
 #include <internal/debug.h>
 
 #include "cm.h"
-#endif
 
 
 /* GLOBALS ******************************************************************/
@@ -102,7 +98,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
   if (End != NULL)
     {
       ObDereferenceObject(Object);
-      return STATUS_UNSUCCESSFUL;
+      return STATUS_OBJECT_NAME_NOT_FOUND;
     }
 
   DPRINT("RemainingPath %S  ParentObject %x\n", RemainingPath.Buffer, Object);
@@ -143,6 +139,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
                        CreateOptions);
   if (!NT_SUCCESS(Status))
     {
+      DPRINT("CmiAddSubKey() failed (Status %lx)\n", Status);
       /* Release hive lock */
       ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
       ObDereferenceObject(KeyObject);
@@ -198,7 +195,6 @@ NtDeleteKey(IN HANDLE KeyHandle)
   DPRINT("KeyHandle %x\n", KeyHandle);
 
   /* Verify that the handle is valid and is a registry key */
-CHECKPOINT1;
   Status = ObReferenceObjectByHandle(KeyHandle,
                                     KEY_WRITE,
                                     CmiKeyType,
@@ -207,32 +203,37 @@ CHECKPOINT1;
                                     NULL);
   if (!NT_SUCCESS(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;
+  /* Check for subkeys */
+  if (KeyObject->NumberOfSubKeys != 0)
+    {
+      Status = STATUS_CANNOT_DELETE;
+    }
+  else
+    {
+      /* Set the marked for delete bit in the key object */
+      KeyObject->Flags |= KO_MARKED_FOR_DELETE;
+      Status = STATUS_SUCCESS;
+    }
 
   /* Release hive lock */
   ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
 
-  DPRINT1("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
+  DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
 
   /* Dereference the object */
   ObDereferenceObject(KeyObject);
   if(KeyObject->RegistryHive != KeyObject->ParentKey->RegistryHive)
     ObDereferenceObject(KeyObject);
 
-  DPRINT1("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
+  DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
 
   /*
    * Note:
@@ -241,7 +242,7 @@ CHECKPOINT1;
    * have been released.
    */
 
-  return(STATUS_SUCCESS);
+  return(Status);
 }
 
 
@@ -332,7 +333,21 @@ NtEnumerateKey(
     }
   else
     {
+      if (KeyCell->HashTableOffset == (BLOCK_OFFSET)-1)
+       {
+         return(STATUS_NO_MORE_ENTRIES);
+         ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+         ObDereferenceObject(KeyObject);
+       }
+
       HashTableBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL);
+      if (HashTableBlock == NULL)
+       {
+         DPRINT("CmiGetBlock() failed\n");
+         ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+         ObDereferenceObject(KeyObject);
+         return STATUS_UNSUCCESSFUL;
+       }
       SubKeyCell = CmiGetKeyFromHashByIndex(RegistryHive,
                                            HashTableBlock,
                                            Index);
@@ -404,7 +419,6 @@ NtEnumerateKey(
               wcsncpy(NodeInformation->Name + SubKeyCell->NameSize ,
                       (PWCHAR) pClassData->Data,
                       SubKeyCell->ClassSize);
-              CmiReleaseBlock(RegistryHive, pClassData);
             }
         }
       break;
@@ -445,12 +459,10 @@ NtEnumerateKey(
               wcsncpy(FullInformation->Class,
                 (PWCHAR) pClassData->Data,
                 SubKeyCell->ClassSize);
-              CmiReleaseBlock(RegistryHive, pClassData);
             }
         }
       break;
     }
-  CmiReleaseBlock(RegistryHive, SubKeyCell);
 
   ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
   ObDereferenceObject(KeyObject);
@@ -588,7 +600,6 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
                 RtlCopyMemory(ValuePartialInformation->Data, 
                   DataCell->Data,
                   ValueCell->DataSize & LONG_MAX);
-                CmiReleaseBlock(RegistryHive, DataCell);
               }
               else
               {
@@ -655,7 +666,6 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
                     + ValueFullInformation->DataOffset,
                     DataCell->Data,
                     ValueCell->DataSize & LONG_MAX);
-                  CmiReleaseBlock(RegistryHive, DataCell);
                 }
               else
                 {
@@ -686,18 +696,8 @@ NtFlushKey(IN HANDLE KeyHandle)
   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);
+  DPRINT("NtFlushKey (KeyHandle %lx) called\n", KeyHandle);
 
   /* Verify that the handle is valid and is a registry key */
   Status = ObReferenceObjectByHandle(KeyHandle,
@@ -719,202 +719,16 @@ NtFlushKey(IN HANDLE KeyHandle)
   ExAcquireResourceExclusiveLite(&RegistryHive->HiveResource,
                                 TRUE);
 
-  if (IsPermanentHive(RegistryHive))
-    {
-      /* Flush non-volatile hive */
-      Status = CmiFlushRegistryHive(RegistryHive);
-    }
-  else
+  if (IsVolatileHive(RegistryHive))
     {
       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);
-
-/* BEGIN FIXME : actually (26 November 200) vfatfs.sys can't create new files
-   so we can't create log file
-  Status = ZwCreateFile(&FileHandleLog,
-               FILE_ALL_ACCESS,
-               &ObjectAttributes,
-               NULL,
-    0,
-    FILE_ATTRIBUTE_NORMAL,
-               0,
-    FILE_SUPERSEDE,
-    0,
-    NULL,
-    0);
-
-  if (!NT_SUCCESS(Status))
-    {
-      ObDereferenceObject(KeyObject);
-      return Status;
-    }
-
-  Status = ZwWriteFile(FileHandleLog, 
-               0,
-    0,
-    0,
-    0, 
-               RegistryHive->HiveHeader, 
-               sizeof(HIVE_HEADER), 
-               0,
-    0);
-
-  if (!NT_SUCCESS(Status))
-    {
-      ZwClose(FileHandleLog);
-      ObDereferenceObject(KeyObject);
-      return Status;
-    }
-
-  for (i = 0; i < RegistryHive->BlockListSize ; i++)
-  {
-    if ( RegistryHive->BlockList[i]->DateModified.dwHighDateTime
-           > RegistryHive->HiveHeader->DateModified.dwHighDateTime
-      || (RegistryHive->BlockList[i]->DateModified.dwHighDateTime
-               == RegistryHive->HiveHeader->DateModified.dwHighDateTime
-          && RegistryHive->BlockList[i]->DateModified.dwLowDateTime
-               > RegistryHive->HiveHeader->DateModified.dwLowDateTime
-         )
-       )
-
-      Status = ZwWriteFile(FileHandleLog, 
-        0,
-        0,
-        0,
-        0, 
-        RegistryHive->BlockList[i],
-        RegistryHive->BlockList[i]->BlockSize ,
-        0,
-        0);
-
-  if (!NT_SUCCESS(Status))
-    {
-      ZwClose(FileHandleLog);
-      ObDereferenceObject(KeyObject);
-      return Status;
-    }
-  }
-  ZwClose(FileHandleLog);
-END FIXME*/
-
-  /* Update header of RegistryHive with Version >VersionOld */
-  /* this allow recover if system crash while updating hove file */
-  InitializeObjectAttributes(&ObjectAttributes,
-               &RegistryHive->Filename,
-               0,
-               NULL,
-               NULL);
-
-  Status = NtOpenFile(&FileHandle,
-                     FILE_ALL_ACCESS,
-                     &ObjectAttributes,
-                     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);
-  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
-           > RegistryHive->HiveHeader->DateModified.dwHighDateTime
-         || (RegistryHive->BlockList[i]->DateModified.dwHighDateTime
-               == RegistryHive->HiveHeader->DateModified.dwHighDateTime
-             && 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))
-           {
-             ZwClose(FileHandle);
-             ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
-             ObDereferenceObject(KeyObject);
-             return(Status);
-           }
-       }
-    }
-
-  /* Change version in header */
-  RegistryHive->HiveHeader->VersionOld = RegistryHive->HiveHeader->Version;
-  ZwQuerySystemTime((PTIME) &RegistryHive->HiveHeader->DateModified);
-
-  /* Calculate checksum */
-  RegistryHive->HiveHeader->Checksum = 0;
-  pEntDword = (DWORD *) RegistryHive->HiveHeader;
-  for (i = 0; i < 127 ; i++)
-    {
-      RegistryHive->HiveHeader->Checksum ^= pEntDword[i];
-    }
-
-  /* Write new header */
-  fileOffset.u.LowPart = 0;
-  Status = ZwWriteFile(FileHandle,
-                      0,
-                      0,
-                      0,
-                      0,
-                      RegistryHive->HiveHeader,
-                      sizeof(HIVE_HEADER),
-                      &fileOffset,
-                      0);
-
-  if (!NT_SUCCESS(Status))
+  else
     {
-      ZwClose(FileHandle);
-      ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
-      ObDereferenceObject(KeyObject);
-      return Status;
+      /* Flush non-volatile hive */
+      Status = CmiFlushRegistryHive(RegistryHive);
     }
 
-  ZwClose(FileHandle);
-#endif
-
   ExReleaseResourceLite(&RegistryHive->HiveResource);
 
   ObDereferenceObject(KeyObject);
@@ -1013,14 +827,11 @@ NtQueryKey(IN HANDLE KeyHandle,
                NULL);
   if (!NT_SUCCESS(Status))
     {
-CHECKPOINT1;
       return Status;
     }
-CHECKPOINT1;
 
   /* Acquire hive lock */
   ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE);
-CHECKPOINT1;
 
   VERIFY_KEY_OBJECT(KeyObject);
 
@@ -1032,7 +843,6 @@ CHECKPOINT1;
   switch (KeyInformationClass)
     {
     case KeyBasicInformation:
-CHECKPOINT1;
       /* Check size of buffer */
       if (Length < sizeof(KEY_BASIC_INFORMATION) + 
           KeyObject->NameSize * sizeof(WCHAR))
@@ -1053,7 +863,6 @@ CHECKPOINT1;
           *ResultLength = sizeof(KEY_BASIC_INFORMATION) + 
             KeyObject->NameSize * sizeof(WCHAR);
         }
-CHECKPOINT1;
       break;
 
     case KeyNodeInformation:
@@ -1087,7 +896,6 @@ CHECKPOINT1;
               wcsncpy(NodeInformation->Name + KeyObject->NameSize * sizeof(WCHAR),
                 (PWCHAR)pClassData->Data,
                 KeyCell->ClassSize);
-              CmiReleaseBlock(RegistryHive, pClassData);
             }
           *ResultLength = sizeof(KEY_NODE_INFORMATION)
             + KeyObject->NameSize * sizeof(WCHAR)
@@ -1128,18 +936,14 @@ CHECKPOINT1;
               wcsncpy(FullInformation->Class,
                 (PWCHAR)pClassData->Data,
                 KeyCell->ClassSize);
-              CmiReleaseBlock(RegistryHive, pClassData);
             }
           *ResultLength = sizeof(KEY_FULL_INFORMATION) + KeyCell->ClassSize;
         }
       break;
     }
 
-CHECKPOINT1;
   ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
-CHECKPOINT1;
   ObDereferenceObject(KeyObject);
-CHECKPOINT1;
 
   return(Status);
 }
@@ -1268,7 +1072,6 @@ NtQueryValueKey(IN HANDLE KeyHandle,
                   RtlCopyMemory(ValuePartialInformation->Data,
                     DataCell->Data,
                     ValueCell->DataSize & LONG_MAX);
-                  CmiReleaseBlock(RegistryHive, DataCell);
                 }
               else
                 {
@@ -1333,7 +1136,6 @@ NtQueryValueKey(IN HANDLE KeyHandle,
                                 + ValueFullInformation->DataOffset,
                                 DataCell->Data,
                                 ValueCell->DataSize & LONG_MAX);
-                  CmiReleaseBlock(RegistryHive, DataCell);
                 }
               else
                 {
@@ -1377,8 +1179,8 @@ NtSetValueKey(IN HANDLE KeyHandle,
   PHBIN pBin;
   ULONG DesiredAccess;
 
-  DPRINT("NtSetValueKey(KeyHandle %x  ValueName %S  Type %d)\n",
-        KeyHandle, ValueName? ValueName->Buffer : NULL, Type);
+  DPRINT("NtSetValueKey(KeyHandle %x  ValueName '%wZ'  Type %d)\n",
+        KeyHandle, ValueName, Type);
 
   DesiredAccess = KEY_SET_VALUE;
   if (Type == REG_LINK)
@@ -1409,7 +1211,7 @@ NtSetValueKey(IN HANDLE KeyHandle,
                              &VBOffset);
   if (!NT_SUCCESS(Status))
     {
-      DPRINT1("Value not found. Status 0x%X\n", Status);
+      DPRINT("Value not found. Status 0x%X\n", Status);
 
       ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
       ObDereferenceObject(KeyObject);
@@ -1432,7 +1234,7 @@ NtSetValueKey(IN HANDLE KeyHandle,
 
   if (!NT_SUCCESS(Status))
     {
-      DPRINT1("Cannot add value. Status 0x%X\n", Status);
+      DPRINT("Cannot add value. Status 0x%X\n", Status);
 
       ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
       ObDereferenceObject(KeyObject);
@@ -1467,12 +1269,11 @@ NtSetValueKey(IN HANDLE KeyHandle,
       RtlCopyMemory(DataCell->Data, Data, DataSize);
       ValueCell->DataSize = DataSize;
       ValueCell->DataType = Type;
-      CmiReleaseBlock(RegistryHive, DataCell);
 
       /* Update time of heap */
-      if (IsPermanentHive(RegistryHive))
+      if (!IsVolatileHive(RegistryHive))
        {
-         ZwQuerySystemTime((PTIME) &pBin->DateModified);
+         NtQuerySystemTime((PTIME) &pBin->DateModified);
        }
       CmiMarkBlockDirty(RegistryHive, ValueCell->DataOffset);
     }
@@ -1512,7 +1313,6 @@ NtSetValueKey(IN HANDLE KeyHandle,
       RtlCopyMemory(&NewDataCell->Data[0], Data, DataSize);
       ValueCell->DataSize = DataSize;
       ValueCell->DataType = Type;
-      CmiReleaseBlock(RegistryHive, NewDataCell);
       ValueCell->DataOffset = NewOffset;
       CmiMarkBlockDirty(RegistryHive, ValueCell->DataOffset);
     }
@@ -1526,9 +1326,9 @@ NtSetValueKey(IN HANDLE KeyHandle,
     }
 
   /* Update time of heap */
-  if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin))
+  if (!IsVolatileHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin))
     {
-      ZwQuerySystemTime((PTIME) &pBin->DateModified);
+      NtQuerySystemTime((PTIME) &pBin->DateModified);
     }
 
   ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
@@ -1581,21 +1381,31 @@ NtDeleteValueKey(IN HANDLE KeyHandle,
   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(PHANDLE KeyHandle,
-         POBJECT_ATTRIBUTES ObjectAttributes)
+NtLoadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
+         IN POBJECT_ATTRIBUTES FileObjectAttributes)
 {
-  return NtLoadKey2(KeyHandle, ObjectAttributes, 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.
+ */
 NTSTATUS STDCALL
-NtLoadKey2(IN PHANDLE KeyHandle,
-       IN POBJECT_ATTRIBUTES ObjectAttributes,
-       IN ULONG Flags)
+NtLoadKey2(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
+          IN POBJECT_ATTRIBUTES FileObjectAttributes,
+          IN ULONG Flags)
 {
-       UNIMPLEMENTED;
+  UNIMPLEMENTED;
+  return STATUS_NOT_IMPLEMENTED;
 }
 
 
@@ -1692,9 +1502,12 @@ NtQueryMultipleValueKey(IN HANDLE KeyHandle,
 
          if (ValueCell->DataSize > 0)
            {
-             DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
-             RtlCopyMemory(DataPtr, DataCell->Data, ValueCell->DataSize & LONG_MAX);
-             CmiReleaseBlock(RegistryHive, DataCell);
+             DataCell = CmiGetBlock(RegistryHive,
+                                    ValueCell->DataOffset,
+                                    NULL);
+             RtlCopyMemory(DataPtr,
+                           DataCell->Data,
+                           ValueCell->DataSize & LONG_MAX);
            }
          else
            {
@@ -1771,8 +1584,13 @@ NtSetInformationKey(
 }
 
 
+/*
+ * NOTE:
+ * KeyObjectAttributes->RootDirectory specifies the handle to the parent key and
+ * KeyObjectAttributes->Name specifies the name of the key to unload.
+ */
 NTSTATUS STDCALL
-NtUnloadKey(IN HANDLE KeyHandle)
+NtUnloadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes)
 {
   UNIMPLEMENTED;
 }