[ros-diffs] [ion] 23485: - Add cmhive.c now that the code mostly makes sense. (requires changes in cmlib to compile).

ion at svn.reactos.org ion at svn.reactos.org
Sat Aug 5 18:29:40 CEST 2006


Author: ion
Date: Sat Aug  5 20:29:40 2006
New Revision: 23485

URL: http://svn.reactos.org/svn/reactos?rev=23485&view=rev
Log:
- Add cmhive.c now that the code mostly makes sense. (requires changes in cmlib to compile).

Added:
    branches/alex-cm-branch/reactos/ntoskrnl/cm/cmhive.c
Modified:
    branches/alex-cm-branch/reactos/ntoskrnl/cm/cm.h

Modified: branches/alex-cm-branch/reactos/ntoskrnl/cm/cm.h
URL: http://svn.reactos.org/svn/reactos/branches/alex-cm-branch/reactos/ntoskrnl/cm/cm.h?rev=23485&r1=23484&r2=23485&view=diff
==============================================================================
--- branches/alex-cm-branch/reactos/ntoskrnl/cm/cm.h (original)
+++ branches/alex-cm-branch/reactos/ntoskrnl/cm/cm.h Sat Aug  5 20:29:40 2006
@@ -6,7 +6,7 @@
 * PROGRAMMERS:     Alex Ionescu (alex.ionescu at reactos.org)
 */
 
-//#include "cmlib.h"
+#include "cmlib.h"
 
 //
 // Define this if you want debugging support
@@ -66,6 +66,13 @@
 #define HFILE_TYPE_LOG                                  2
 #define HFILE_TYPE_EXTERNAL                             3
 #define HFILE_TYPE_MAX                                  4
+
+//
+// Hive sizes
+//
+#define HBLOCK_SIZE                                     0x1000
+#define HSECTOR_SIZE                                    0x200
+#define HSECTOR_COUNT                                   8
 
 //
 // CM_KEY_CONTROL_BLOCK Flags

Added: branches/alex-cm-branch/reactos/ntoskrnl/cm/cmhive.c
URL: http://svn.reactos.org/svn/reactos/branches/alex-cm-branch/reactos/ntoskrnl/cm/cmhive.c?rev=23485&view=auto
==============================================================================
--- branches/alex-cm-branch/reactos/ntoskrnl/cm/cmhive.c (added)
+++ branches/alex-cm-branch/reactos/ntoskrnl/cm/cmhive.c Sat Aug  5 20:29:40 2006
@@ -1,0 +1,325 @@
+/*
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            ntoskrnl/cm/cmhive.c
+ * PURPOSE:         Routines for managing Registry Hives in general
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu at reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS *******************************************************************/
+
+EX_PUSH_LOCK CmpHiveListHeadLock;
+LIST_ENTRY CmpHiveListHead;
+
+/* FUNCTIONS *****************************************************************/
+
+PVOID
+NTAPI
+CmpAllocate(IN ULONG Size,
+            IN BOOLEAN Paged)
+{
+    /* FIXME: TODO */
+    DbgBreakPoint();
+    return NULL;
+}
+
+VOID
+NTAPI
+CmpFree(IN PVOID Block)
+{
+    /* FIXME: TODO */
+    DbgBreakPoint();
+}
+
+BOOLEAN
+NTAPI
+CmpFileRead(IN PHHIVE Hive,
+            IN ULONG FileType,
+            IN ULONG FileOffset,
+            IN PVOID Buffer,
+            IN ULONG BufferLength)
+{
+    /* FIXME: TODO */
+    DbgBreakPoint();
+    return FALSE;
+}
+
+BOOLEAN
+NTAPI
+CmpFileWrite(IN PHHIVE Hive,
+             IN ULONG FileType,
+             IN ULONG FileOffset,
+             IN PVOID Buffer,
+             IN ULONG BufferLength)
+{
+    /* FIXME: TODO */
+    DbgBreakPoint();
+    return FALSE;
+}
+
+BOOLEAN
+NTAPI
+CmpFileSetSize(IN PHHIVE Hive,
+               IN ULONG FileType,
+               IN ULONG FileSize)
+{
+    /* FIXME: TODO */
+    DbgBreakPoint();
+    return FALSE;
+}
+
+BOOLEAN
+NTAPI
+CmpFileFlush(IN PHHIVE Hive,
+             IN ULONG FileType)
+{
+    /* FIXME: TODO */
+    DbgBreakPoint();
+    return FALSE;
+}
+
+VOID
+NTAPI
+CmpInitializeSecurityCache(IN PCMHIVE Hive)
+{
+    ULONG i;
+    PAGED_CODE();
+
+    /* Initialize defaults */
+    Hive->SecurityCache = NULL;
+    Hive->SecurityCount = 0;
+    Hive->SecurityHitHint = -1;
+    Hive->SecurityCacheSize = 0;
+
+    /* Loop the lists */
+    for (i = 0; i < CMP_SECURITY_HASH_LISTS; i++)
+    {
+        /* Initialize this list */
+        InitializeListHead(&Hive->SecurityHash[i]);
+    }
+}
+
+VOID
+NTAPI
+CmpInitializeHiveViewList(IN PCMHIVE Hive)
+{
+    PAGED_CODE();
+
+    /* Initialize the lists */
+    InitializeListHead(&Hive->PinViewListHead);
+    InitializeListHead(&Hive->LRUViewListHead);
+
+    /* Setup defaults */
+    Hive->MappedViews = 0;
+    Hive->PinnedViews = 0;
+    Hive->UseCount = 0;
+}
+
+NTSTATUS
+NTAPI
+CmpInitializeHive(OUT PCMHIVE *CmHive,
+                  IN ULONG Operation,
+                  IN ULONG Flags,
+                  IN ULONG FileType,
+                  IN PVOID Context,
+                  IN HANDLE Primary,
+                  IN HANDLE Alternate,
+                  IN HANDLE Log,
+                  IN HANDLE External,
+                  IN PUNICODE_STRING FileName)
+{
+    PCMHIVE Hive;
+    IO_STATUS_BLOCK IoStatusBlock;
+    FILE_FS_SIZE_INFORMATION FileSizeInformation;
+    NTSTATUS Status;
+    ULONG Cluster;
+
+    /*
+     * The following are invalid:
+     * An alternate hive that's also a log file.
+     * An external hive that is also internal.
+     * An alternate hive or a log hive that's not a primary hive too.
+     * A volatile hive that's linked to permanent storage.
+     * An in-memory initailization without context data.
+     * A log hive or alternative hive that's not linked to a correct file type.
+     */
+    if ((Alternate && Log) ||
+        (External && (Primary || Alternate || Log)) ||
+        (Alternate && !Primary) ||
+        (Log && !Primary) ||
+        ((Flags & HIVE_VOLATILE) &&
+         (Alternate || Primary || External || Log)) ||
+        ((Operation == HINIT_MEMORY) && (!Context)) ||
+        (Log && (FileType != HFILE_TYPE_LOG)) ||
+        (Alternate && (FileType != HFILE_TYPE_ALTERNATE)))
+    {
+        /* Fail the request */
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Check if this is a primary hive */
+    if (Primary)
+    {
+        /* Get the cluster size */
+        Status = ZwQueryVolumeInformationFile(Primary,
+                                              &IoStatusBlock,
+                                              &FileSizeInformation,
+                                              sizeof(FILE_FS_SIZE_INFORMATION),
+                                              FileFsSizeInformation);
+        if (!NT_SUCCESS(Status)) return Status;
+
+        /* Make sure it's not larger then the block size */
+        if (FileSizeInformation.BytesPerSector > HBLOCK_SIZE)
+        {
+            /* Fail */
+            return STATUS_REGISTRY_IO_FAILED;
+        }
+
+        /* Otherwise, calculate the cluster */
+        Cluster = FileSizeInformation.BytesPerSector / HSECTOR_SIZE;
+        Cluster = max(1, Cluster);
+    }
+    else
+    {
+        /* Otherwise use cluster 1 */
+        Cluster = 1;
+    }
+
+    /* Allocate a hive */
+    Hive = ExAllocatePoolWithTag(PagedPool,
+                                 sizeof(CMHIVE),
+                                 TAG_CM);
+    if (!Hive) return STATUS_INSUFFICIENT_RESOURCES;
+
+    /* Setup null fields */
+    Hive->UnloadEvent = NULL;
+    Hive->RootKcb = NULL;
+    Hive->Frozen = FALSE;
+    Hive->UnloadWorkItem = NULL;
+    Hive->GrowOnlyMode = FALSE;
+    Hive->GrowOffset = 0;
+    Hive->CellRemapArray = NULL;
+    Hive->UseCountLog.Next = 0;
+    Hive->LockHiveLog.Next = 0;
+    Hive->FileObject = NULL;
+    Hive->NotifyList.Flink = NULL;
+    Hive->NotifyList.Blink = NULL;
+
+    /* Set loading flag */
+    Hive->HiveIsLoading = TRUE;
+
+    /* Set the current thread as creator */
+    Hive->CreatorOwner = KeGetCurrentThread();
+
+    /* Initialize lists */
+    InitializeListHead(&Hive->KcbConvertListHead);
+    InitializeListHead(&Hive->KnodeConvertListHead);
+    InitializeListHead(&Hive->TrustClassEntry);
+
+    /* Allocate the view log */
+    Hive->ViewLock = ExAllocatePoolWithTag(NonPagedPool,
+                                           sizeof(KGUARDED_MUTEX),
+                                           TAG_CM);
+    if (!Hive->ViewLock) return STATUS_INSUFFICIENT_RESOURCES;
+
+    /* Allocate the flush lock */
+    Hive->FlusherLock = ExAllocatePoolWithTag(NonPagedPool,
+                                              sizeof(ERESOURCE),
+                                              TAG_CM);
+    if (!Hive->FlusherLock) return STATUS_INSUFFICIENT_RESOURCES;
+
+    /* Setup the handles */
+    Hive->FileHandles[HFILE_TYPE_PRIMARY] = Primary;
+    Hive->FileHandles[HFILE_TYPE_ALTERNATE] = Alternate;
+    Hive->FileHandles[HFILE_TYPE_LOG] = Log;
+    Hive->FileHandles[HFILE_TYPE_EXTERNAL] = External;
+
+    /* Initailize the guarded mutex */
+    KeInitializeGuardedMutex(Hive->ViewLock);
+    Hive->ViewLockOwner = NULL;
+
+    /* Initialize the flush lock */
+    ExInitializeResourceLite(Hive->FlusherLock);
+
+    /* Setup hive locks */
+    ExInitializePushLock(&Hive->HiveLock);
+    Hive->HiveLockOwner = NULL;
+    ExInitializePushLock(&Hive->WriterLock);
+    Hive->WriterLockOwner = NULL;
+    ExInitializePushLock(&Hive->SecurityLock);
+    Hive->HiveSecurityLockOwner = NULL;
+
+    /* Clear file names */
+    RtlInitEmptyUnicodeString(&Hive->FileUserName, NULL, 0);
+    RtlInitEmptyUnicodeString(&Hive->FileFullPath, NULL, 0);
+
+    /* Initialize the view list */
+    CmpInitializeHiveViewList(Hive);
+
+    /* Initailize the security cache */
+    CmpInitializeSecurityCache(Hive);
+
+    /* Setup flags */
+    Hive->Flags = 0;
+    Hive->FlushCount = 0;
+
+    /* Initialize the hive */
+    Status = HvInitialize(&Hive->Hive,
+                          Operation,
+                          Flags,
+                          FileType,
+                          Context,
+                          CmpAllocate,
+                          CmpFree,
+                          CmpFileRead,
+                          CmpFileWrite,
+                          CmpFileSetSize,
+                          CmpFileFlush,
+                          Cluster,
+                          FileName);
+    if (NT_SUCCESS(Status))
+    {
+        /* Free all alocations */
+        ExFreePool(Hive->ViewLock);
+        ExFreePool(Hive->FlusherLock);
+        ExFreePool(Hive);
+        return Status;
+    }
+
+    /* Check if we should verify the registry */
+    if ((Operation == HINIT_FILE) ||
+        (Operation == HINIT_MEMORY) ||
+        (Operation == HINIT_MEMORY_INPLACE) ||
+        (Operation == HINIT_MAPFILE))
+    {
+        /* Verify integrity */
+        if (CmCheckRegistry(Hive, TRUE))
+        {
+            /* Free all alocations */
+            ExFreePool(Hive->ViewLock);
+            ExFreePool(Hive->FlusherLock);
+            ExFreePool(Hive);
+            return STATUS_REGISTRY_CORRUPT;
+        }
+    }
+
+    /* Lock the hive list */
+    ExAcquirePushLockExclusive(&CmpHiveListHeadLock);
+
+    /* Insert this hive */
+    InsertHeadList(&CmpHiveListHead, &Hive->HiveList);
+
+    /* Release the lock */
+    ExReleasePushLock(&CmpHiveListHeadLock);
+
+    /* Return the hive and success */
+    *CmHive = Hive;
+    return STATUS_SUCCESS;
+}
+




More information about the Ros-diffs mailing list