forget update de.rc
[reactos.git] / reactos / ntoskrnl / cm / cm.h
index ffcd26c..fd34016 100644 (file)
 #define  REG_DEVICEMAP_KEY_NAME                L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP"
 #define  REG_RESOURCEMAP_KEY_NAME      L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP"
 #define  REG_CLASSES_KEY_NAME          L"\\Registry\\Machine\\Software\\Classes"
-#define  REG_SYSTEM_KEY_NAME           L"\\Registry\\Machine\\System"
-#define  REG_SOFTWARE_KEY_NAME         L"\\Registry\\Machine\\Software"
-#define  REG_SAM_KEY_NAME              L"\\Registry\\Machine\\Sam"
-#define  REG_SEC_KEY_NAME              L"\\Registry\\Machine\\Security"
-#define  REG_USERS_KEY_NAME            L"\\Registry\\User"
-#define  REG_USER_KEY_NAME             L"\\Registry\\User\\CurrentUser"
+#define  REG_SYSTEM_KEY_NAME           L"\\Registry\\Machine\\SYSTEM"
+#define  REG_SOFTWARE_KEY_NAME         L"\\Registry\\Machine\\SOFTWARE"
+#define  REG_SAM_KEY_NAME              L"\\Registry\\Machine\\SAM"
+#define  REG_SEC_KEY_NAME              L"\\Registry\\Machine\\SECURITY"
+#define  REG_USER_KEY_NAME             L"\\Registry\\User"
+#define  REG_DEFAULT_USER_KEY_NAME     L"\\Registry\\User\\.Default"
+#define  REG_CURRENT_USER_KEY_NAME     L"\\Registry\\User\\CurrentUser"
+
 #define  SYSTEM_REG_FILE               L"\\SystemRoot\\System32\\Config\\SYSTEM"
+#define  SYSTEM_LOG_FILE               L"\\SystemRoot\\System32\\Config\\SYSTEM.log"
 #define  SOFTWARE_REG_FILE             L"\\SystemRoot\\System32\\Config\\SOFTWARE"
-#define  USER_REG_FILE                 L"\\SystemRoot\\System32\\Config\\DEFAULT"
+#define  DEFAULT_USER_REG_FILE         L"\\SystemRoot\\System32\\Config\\DEFAULT"
 #define  SAM_REG_FILE                  L"\\SystemRoot\\System32\\Config\\SAM"
 #define  SEC_REG_FILE                  L"\\SystemRoot\\System32\\Config\\SECURITY"
 
-#define  REG_SYSTEM_FILE_NAME          L"\\SYSTEM"
-#define  REG_SOFTWARE_FILE_NAME                L"\\SOFTWARE"
-#define  REG_USER_FILE_NAME            L"\\DEFAULT"
-#define  REG_SAM_FILE_NAME             L"\\SAM"
-#define  REG_SEC_FILE_NAME             L"\\SECURITY"
+#define  REG_SYSTEM_FILE_NAME          L"\\system"
+#define  REG_SOFTWARE_FILE_NAME                L"\\software"
+#define  REG_DEFAULT_USER_FILE_NAME    L"\\default"
+#define  REG_SAM_FILE_NAME             L"\\sam"
+#define  REG_SEC_FILE_NAME             L"\\security"
 
 #define  REG_BLOCK_SIZE                4096
 #define  REG_HBIN_DATA_OFFSET          32
-#define  REG_BIN_ID                    0x6e696268
 #define  REG_INIT_BLOCK_LIST_SIZE      32
 #define  REG_INIT_HASH_TABLE_SIZE      3
 #define  REG_EXTEND_HASH_TABLE_SIZE    4
 #define  REG_VALUE_LIST_CELL_MULTIPLE  4
+
+#define  REG_HIVE_ID                   0x66676572
+#define  REG_BIN_ID                    0x6e696268
 #define  REG_KEY_CELL_ID               0x6b6e
-#define  REG_HASH_TABLE_BLOCK_ID       0x666c
+#define  REG_HASH_TABLE_CELL_ID        0x666c
 #define  REG_VALUE_CELL_ID             0x6b76
-#define  REG_HIVE_ID                   0x66676572
+#define  REG_SECURITY_CELL_ID          0x6b73
 
-#define  REGISTRY_FILE_MAGIC    "REGEDIT4"
-
-#define  REG_MACHINE_STD_HANDLE_NAME  "HKEY_LOCAL_MACHINE"
-#define  REG_CLASSES_STD_HANDLE_NAME  "HKEY_CLASSES_ROOT"
-#define  REG_USERS_STD_HANDLE_NAME    "HKEY_USERS"
-#define  REG_USER_STD_HANDLE_NAME     "HKEY_CURRENT_USER"
-#define  REG_CONFIG_STD_HANDLE_NAME   "HKEY_CURRENT_CONFIG"
-#define  REG_DYN_STD_HANDLE_NAME      "HKEY_DYN_DATA"
-#define  MAX_REG_STD_HANDLE_NAME      19
 
 // BLOCK_OFFSET = offset in file after header block
-typedef DWORD BLOCK_OFFSET;
+typedef ULONG BLOCK_OFFSET, *PBLOCK_OFFSET;
+
+#include <pshpack1.h>
 
 /* header for registry hive file : */
 typedef struct _HIVE_HEADER
@@ -63,30 +61,31 @@ typedef struct _HIVE_HEADER
   /* Hive identifier "regf" (0x66676572) */
   ULONG  BlockId;
 
-  /* File version ? */
-  ULONG  Version;
+  /* Update counter */
+  ULONG  UpdateCounter1;
 
-  /* File version ? - same as Version */
-  ULONG  VersionOld;
+  /* Update counter */
+  ULONG  UpdateCounter2;
 
   /* When this hive file was last modified */
-  FILETIME  DateModified;
+  LARGE_INTEGER  DateModified;
 
-  /* Registry format version ? (1?) */
-  ULONG  Unused3;
+  /* Registry format major version (1) */
+  ULONG  MajorVersion;
 
-  /* Registry format version ? (3?) */
-  ULONG  Unused4;
+  /* Registry format minor version (3)
+     Version 3 added fast indexes, version 5 has large value optimizations */
+  ULONG  MinorVersion;
 
-  /* Registry format version ? (0?) */
-  ULONG  Unused5;
+  /* Registry file type (0 - Primary, 1 - Log) */
+  ULONG  Type;
 
-  /* Registry format version ? (1?) */
-  ULONG  Unused6;
+  /* Registry format (1 is the only defined value so far) */
+  ULONG  Format;
 
   /* Offset into file from the byte after the end of the base block.
      If the hive is volatile, this is the actual pointer to the KEY_CELL */
-  BLOCK_OFFSET  RootKeyCell;
+  BLOCK_OFFSET  RootKeyOffset;
 
   /* Size of each hive block ? */
   ULONG  BlockSize;
@@ -95,41 +94,39 @@ typedef struct _HIVE_HEADER
   ULONG  Unused7;
 
   /* Name of hive file */
-  WCHAR  FileName[64];
+  WCHAR  FileName[48];
 
-  /* ? */
-  ULONG  Unused8[83];
+  ULONG  Reserved[99];
 
   /* Checksum of first 0x200 bytes */
   ULONG  Checksum;
-} __attribute__((packed)) HIVE_HEADER, *PHIVE_HEADER;
+} HIVE_HEADER, *PHIVE_HEADER;
 
-typedef struct _HBIN
+typedef struct _BIN_HEADER
 {
   /* Bin identifier "hbin" (0x6E696268) */
-  ULONG  BlockId;
+  ULONG  HeaderId;
 
   /* Block offset of this bin */
-  BLOCK_OFFSET  BlockOffset;
+  BLOCK_OFFSET  BinOffset;
 
   /* Size in bytes, multiple of the block size (4KB) */
-  ULONG  BlockSize;
+  ULONG  BinSize;
 
-  /* ? */
-  ULONG  Unused1;
+  ULONG  Reserved[2];
 
   /* When this bin was last modified */
-  FILETIME  DateModified;
+  LARGE_INTEGER  DateModified;
 
-  /* ? */
-  ULONG  Unused2;
-} __attribute__((packed)) HBIN, *PHBIN;
+  /* ? (In-memory only) */
+  ULONG  MemAlloc;
+} HBIN, *PHBIN;
 
 typedef struct _CELL_HEADER
 {
   /* <0 if used, >0 if free */
   LONG  CellSize;
-} __attribute__((packed)) CELL_HEADER, *PCELL_HEADER;
+} CELL_HEADER, *PCELL_HEADER;
 
 typedef struct _KEY_CELL
 {
@@ -139,11 +136,11 @@ typedef struct _KEY_CELL
   /* Key cell identifier "kn" (0x6b6e) */
   USHORT  Id;
 
-  /* ? */
-  USHORT  Type;
+  /* Flags */
+  USHORT  Flags;
 
   /* Time of last flush */
-  FILETIME  LastWriteTime;
+  LARGE_INTEGER  LastWriteTime;
 
   /* ? */
   ULONG  UnUsed1;
@@ -167,7 +164,7 @@ typedef struct _KEY_CELL
   ULONG  NumberOfValues;
 
   /* Block offset of VALUE_LIST_CELL */
-  BLOCK_OFFSET  ValuesOffset;
+  BLOCK_OFFSET  ValueListOffset;
 
   /* Block offset of security cell */
   BLOCK_OFFSET  SecurityKeyOffset;
@@ -186,21 +183,25 @@ typedef struct _KEY_CELL
 
   /* Name of key (not zero terminated) */
   UCHAR  Name[0];
-} __attribute__((packed)) KEY_CELL, *PKEY_CELL;
-
-/* KEY_CELL.Type constants */
-#define  REG_LINK_KEY_CELL_TYPE        0x10
-#define  REG_KEY_CELL_TYPE             0x20
-#define  REG_ROOT_KEY_CELL_TYPE        0x2c
-
-
-// hash record :
-// HashValue=four letters of value's name
+} KEY_CELL, *PKEY_CELL;
+
+/* KEY_CELL.Flags constants */
+#define  REG_KEY_ROOT_CELL                 0x0C
+#define  REG_KEY_LINK_CELL                 0x10
+#define  REG_KEY_NAME_PACKED               0x20
+
+/*
+ * Hash record
+ *
+ * HashValue:
+ *     packed name: four letters of value's name
+ *     otherwise: Zero!
+ */
 typedef struct _HASH_RECORD
 {
   BLOCK_OFFSET  KeyOffset;
   ULONG  HashValue;
-} __attribute__((packed)) HASH_RECORD, *PHASH_RECORD;
+} HASH_RECORD, *PHASH_RECORD;
 
 typedef struct _HASH_TABLE_CELL
 {
@@ -208,63 +209,104 @@ typedef struct _HASH_TABLE_CELL
   USHORT  Id;
   USHORT  HashTableSize;
   HASH_RECORD  Table[0];
-} __attribute__((packed)) HASH_TABLE_CELL, *PHASH_TABLE_CELL;
+} HASH_TABLE_CELL, *PHASH_TABLE_CELL;
+
 
 typedef struct _VALUE_LIST_CELL
 {
   LONG  CellSize;
-  BLOCK_OFFSET  Values[0];
-} __attribute__((packed)) VALUE_LIST_CELL, *PVALUE_LIST_CELL;
+  BLOCK_OFFSET  ValueOffset[0];
+} VALUE_LIST_CELL, *PVALUE_LIST_CELL;
 
 typedef struct _VALUE_CELL
 {
   LONG  CellSize;
   USHORT Id;   // "kv"
   USHORT NameSize;     // length of Name
-  LONG  DataSize;      // length of datas in the cell pointed by DataOffset
+  ULONG  DataSize;     // length of datas in the cell pointed by DataOffset
   BLOCK_OFFSET  DataOffset;// datas are here if high bit of DataSize is set
   ULONG  DataType;
   USHORT Flags;
   USHORT Unused1;
   UCHAR  Name[0]; /* warning : not zero terminated */
-} __attribute__((packed)) VALUE_CELL, *PVALUE_CELL;
+} VALUE_CELL, *PVALUE_CELL;
 
 /* VALUE_CELL.Flags constants */
 #define REG_VALUE_NAME_PACKED             0x0001
 
+/* VALUE_CELL.DataSize mask constants */
+#define REG_DATA_SIZE_MASK                 0x7FFFFFFF
+#define REG_DATA_IN_OFFSET                 0x80000000
+
+
+typedef struct _SECURITY_CELL
+{
+  LONG  CellSize;
+  USHORT Id;   // "sk"
+  USHORT Reserved;
+  BLOCK_OFFSET PrevSecurityCell;
+  BLOCK_OFFSET NextSecurityCell;
+  ULONG RefCount;
+  ULONG SdSize;
+  UCHAR Data[0];
+} SECURITY_CELL, *PSECURITY_CELL;
+
 
 typedef struct _DATA_CELL
 {
   LONG  CellSize;
   UCHAR  Data[0];
-} __attribute__((packed)) DATA_CELL, *PDATA_CELL;
+} DATA_CELL, *PDATA_CELL;
+
+#include <poppack.h>
+
+
+typedef struct _BLOCK_LIST_ENTRY
+{
+  PHBIN Bin;
+  PVOID Block;
+} BLOCK_LIST_ENTRY, *PBLOCK_LIST_ENTRY;
+
 
 typedef struct _REGISTRY_HIVE
 {
-  LIST_ENTRY HiveList;
+  LIST_ENTRY  HiveList;
   ULONG  Flags;
-  UNICODE_STRING  Filename;
+  UNICODE_STRING  HiveFileName;
+  UNICODE_STRING  LogFileName;
   ULONG  FileSize;
-  PFILE_OBJECT  FileObject;
-  PVOID  Bcb;
   PHIVE_HEADER  HiveHeader;
+  ULONG  UpdateCounter;
   ULONG  BlockListSize;
-  PHBIN  *BlockList;
+  PBLOCK_LIST_ENTRY BlockList;
   ULONG  FreeListSize;
   ULONG  FreeListMax;
   PCELL_HEADER *FreeList;
   BLOCK_OFFSET *FreeListOffset;
-  ERESOURCE HiveResource;
 
-//  NTSTATUS  (*Extend)(ULONG NewSize);
-//  PVOID  (*Flush)(VOID);
+  PSECURITY_CELL RootSecurityCell;
+
+  PULONG BitmapBuffer;
+  RTL_BITMAP  DirtyBitMap;
+  BOOLEAN  HiveDirty;
 } REGISTRY_HIVE, *PREGISTRY_HIVE;
 
 /* REGISTRY_HIVE.Flags constants */
-#define HIVE_VOLATILE   0x00000001
+/* When set, the hive uses pointers instead of offsets. */
+#define HIVE_POINTER    0x00000001
+
+/* When set, the hive is not backed by a file.
+   Therefore, it can not be flushed to disk. */
+#define HIVE_NO_FILE    0x00000002
+
+/* When set, a modified (dirty) hive is not synchronized automatically.
+   Explicit synchronization (save/flush) works. */
+#define HIVE_NO_SYNCH   0x00000004
+
+#define IsPointerHive(Hive)  ((Hive)->Flags & HIVE_POINTER)
+#define IsNoFileHive(Hive)  ((Hive)->Flags & HIVE_NO_FILE)
+#define IsNoSynchHive(Hive)  ((Hive)->Flags & HIVE_NO_SYNCH)
 
-#define IsVolatileHive(Hive)(Hive->Flags & HIVE_VOLATILE)
-#define IsPermanentHive(Hive)(!(Hive->Flags & HIVE_VOLATILE))
 
 #define IsFreeCell(Cell)(Cell->CellSize >= 0)
 #define IsUsedCell(Cell)(Cell->CellSize < 0)
@@ -287,17 +329,14 @@ typedef struct _KEY_OBJECT
   /* Key flags */
   ULONG Flags;
 
-  /* Length of Name */
-  USHORT NameSize;
-
-  /* Name of key */
-  PCHAR Name;
+  /* Key name */
+  UNICODE_STRING Name;
 
   /* Registry hive the key belongs to */
   PREGISTRY_HIVE RegistryHive;
 
   /* Block offset of the key cell this key belongs in */
-  BLOCK_OFFSET BlockOffset;
+  BLOCK_OFFSET KeyCellOffset;
 
   /* KEY_CELL this key belong in */
   PKEY_CELL KeyCell;
@@ -313,6 +352,12 @@ typedef struct _KEY_OBJECT
 
   /* List of subkeys loaded */
   struct _KEY_OBJECT **SubKeys;
+
+  /* List entry into the global key object list */
+  LIST_ENTRY ListEntry;
+
+  /* Time stamp for the last access by the parse routine */
+  ULONG TimeStamp;
 } KEY_OBJECT, *PKEY_OBJECT;
 
 /* Bits 31-22 (top 10 bits) of the cell index is the directory index */
@@ -329,11 +374,33 @@ extern POBJECT_TYPE CmiKeyType;
 extern KSPIN_LOCK CmiKeyListLock;
 
 extern LIST_ENTRY CmiHiveListHead;
-extern KSPIN_LOCK CmiHiveListLock;
 
+extern ERESOURCE CmiRegistryLock;
+
+
+/* Registry Callback Function */
+typedef NTSTATUS (STDCALL *PEX_CALLBACK_FUNCTION ) (
+    IN PVOID CallbackContext,
+    IN REG_NOTIFY_CLASS Argument1,
+    IN PVOID Argument2
+    );
+
+typedef struct _REGISTRY_CALLBACK
+{
+    LIST_ENTRY ListEntry;
+    EX_RUNDOWN_REF RundownRef;
+    PEX_CALLBACK_FUNCTION Function;
+    PVOID Context;
+    LARGE_INTEGER Cookie;
+    BOOLEAN PendingDelete;
+} REGISTRY_CALLBACK, *PREGISTRY_CALLBACK;
+
+NTSTATUS
+CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1,
+                           IN PVOID Argument2);
 
 VOID
-CmiVerifyBinCell(PHBIN BinCell);
+CmiVerifyBinHeader(PHBIN BinHeader);
 VOID
 CmiVerifyKeyCell(PKEY_CELL KeyCell);
 VOID
@@ -344,7 +411,7 @@ VOID
 CmiVerifyRegistryHive(PREGISTRY_HIVE RegistryHive);
 
 #ifdef DBG
-#define VERIFY_BIN_CELL CmiVerifyBinCell
+#define VERIFY_BIN_HEADER CmiVerifyBinHeader
 #define VERIFY_KEY_CELL CmiVerifyKeyCell
 #define VERIFY_ROOT_KEY_CELL CmiVerifyRootKeyCell
 #define VERIFY_VALUE_CELL CmiVerifyValueCell
@@ -352,7 +419,7 @@ CmiVerifyRegistryHive(PREGISTRY_HIVE RegistryHive);
 #define VERIFY_KEY_OBJECT CmiVerifyKeyObject
 #define VERIFY_REGISTRY_HIVE CmiVerifyRegistryHive
 #else
-#define VERIFY_BIN_CELL(x)
+#define VERIFY_BIN_HEADER(x)
 #define VERIFY_KEY_CELL(x)
 #define VERIFY_ROOT_KEY_CELL(x)
 #define VERIFY_VALUE_CELL(x)
@@ -362,159 +429,229 @@ CmiVerifyRegistryHive(PREGISTRY_HIVE RegistryHive);
 #endif
 
 NTSTATUS STDCALL
-CmiObjectParse(IN PVOID  ParsedObject,
-              OUT PVOID  *NextObject,
-              IN PUNICODE_STRING  FullPath,
-              IN OUT PWSTR  *Path,
-              IN ULONG  Attribute);
+CmRegisterCallback(IN PEX_CALLBACK_FUNCTION Function,
+                   IN PVOID                 Context,
+                   IN OUT PLARGE_INTEGER    Cookie
+                    );
+
+NTSTATUS STDCALL
+CmUnRegisterCallback(IN LARGE_INTEGER    Cookie);
 
 NTSTATUS STDCALL
-CmiObjectCreate(PVOID ObjectBody,
-               PVOID Parent,
-               PWSTR RemainingPath,
-               struct _OBJECT_ATTRIBUTES* ObjectAttributes);
+CmiObjectParse(IN PVOID ParsedObject,
+              OUT PVOID *NextObject,
+              IN PUNICODE_STRING FullPath,
+              IN OUT PWSTR *Path,
+              IN ULONG Attribute);
 
 VOID STDCALL
 CmiObjectDelete(PVOID  DeletedObject);
 
+NTSTATUS STDCALL
+CmiObjectSecurity(PVOID ObjectBody,
+                 SECURITY_OPERATION_CODE OperationCode,
+                 SECURITY_INFORMATION SecurityInformation,
+                 PSECURITY_DESCRIPTOR SecurityDescriptor,
+                 PULONG BufferLength,
+                 PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
+                 POOL_TYPE PoolType,
+                 PGENERIC_MAPPING GenericMapping);
+
+NTSTATUS STDCALL
+CmiObjectQueryName (PVOID ObjectBody,
+                   POBJECT_NAME_INFORMATION ObjectNameInfo,
+                   ULONG Length,
+                   PULONG ReturnLength);
+
+NTSTATUS
+CmiImportHiveBins(PREGISTRY_HIVE Hive,
+                 PUCHAR ChunkPtr);
+
+VOID
+CmiFreeHiveBins(PREGISTRY_HIVE Hive);
+
+NTSTATUS
+CmiCreateHiveFreeCellList(PREGISTRY_HIVE Hive);
+
 VOID
-CmiAddKeyToList(PKEY_OBJECT ParentKey,
-  IN PKEY_OBJECT  NewKey);
+CmiFreeHiveFreeCellList(PREGISTRY_HIVE Hive);
 
 NTSTATUS
-CmiRemoveKeyFromList(IN PKEY_OBJECT  NewKey);
+CmiCreateHiveBitmap(PREGISTRY_HIVE Hive);
+
 
-PKEY_OBJECT  CmiScanKeyList(IN PKEY_OBJECT Parent,
-  IN PCHAR  KeyNameBuf,
-  IN ULONG  Attributes);
+VOID
+CmiAddKeyToList(IN PKEY_OBJECT ParentKey,
+               IN PKEY_OBJECT NewKey);
+
+NTSTATUS
+CmiRemoveKeyFromList(IN PKEY_OBJECT NewKey);
 
 NTSTATUS
-CmiCreateRegistryHive(PWSTR Filename,
-  PREGISTRY_HIVE *RegistryHive,
-  BOOLEAN CreateNew);
+CmiScanKeyList(IN PKEY_OBJECT Parent,
+              IN PUNICODE_STRING KeyName,
+              IN ULONG Attributes,
+              PKEY_OBJECT* ReturnedObject);
+
+NTSTATUS
+CmiCreateVolatileHive(PREGISTRY_HIVE *RegistryHive);
+
+NTSTATUS
+CmiLoadHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
+           PUNICODE_STRING FileName,
+           ULONG Flags);
 
 NTSTATUS
 CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive);
 
+NTSTATUS
+CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive);
+
 ULONG
-CmiGetMaxNameLength(IN PREGISTRY_HIVE  RegistryHive,
-  IN PKEY_CELL  KeyCell);
+CmiGetNumberOfSubKeys(PKEY_OBJECT KeyObject);
 
 ULONG
-CmiGetMaxClassLength(IN PREGISTRY_HIVE  RegistryHive,
-  IN PKEY_CELL  KeyCell);
+CmiGetMaxNameLength(IN PKEY_OBJECT KeyObject);
 
 ULONG
-CmiGetMaxValueNameLength(IN PREGISTRY_HIVE  RegistryHive,
-  IN PKEY_CELL  KeyCell);
+CmiGetMaxClassLength(IN PKEY_OBJECT KeyObject);
 
 ULONG
-CmiGetMaxValueDataLength(IN PREGISTRY_HIVE  RegistryHive,
-  IN PKEY_CELL  KeyCell);
+CmiGetMaxValueNameLength(IN PREGISTRY_HIVE RegistryHive,
+                        IN PKEY_CELL KeyCell);
+
+ULONG
+CmiGetMaxValueDataLength(IN PREGISTRY_HIVE RegistryHive,
+                        IN PKEY_CELL KeyCell);
 
 NTSTATUS
-CmiScanForSubKey(IN PREGISTRY_HIVE  RegistryHive,
-  IN PKEY_CELL  KeyCell,
-  OUT PKEY_CELL  *SubKeyCell,
-  OUT BLOCK_OFFSET *BlockOffset,
-  IN PCHAR  KeyName,
-  IN ACCESS_MASK  DesiredAccess,
-  IN ULONG Attributes);
+CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive,
+                IN PKEY_CELL KeyCell,
+                OUT PKEY_CELL *SubKeyCell,
+                OUT BLOCK_OFFSET *BlockOffset,
+                IN PUNICODE_STRING KeyName,
+                IN ACCESS_MASK DesiredAccess,
+                IN ULONG Attributes);
 
 NTSTATUS
-CmiAddSubKey(IN PREGISTRY_HIVE  RegistryHive,
-  IN PKEY_OBJECT Parent,
-  OUT PKEY_OBJECT SubKey,
-  IN PWSTR  NewSubKeyName,
-  IN USHORT  NewSubKeyNameSize,
-  IN ULONG  TitleIndex,
-  IN PUNICODE_STRING  Class,
-  IN ULONG  CreateOptions);
+CmiAddSubKey(IN PREGISTRY_HIVE RegistryHive,
+            IN PKEY_OBJECT ParentKey,
+            OUT PKEY_OBJECT SubKey,
+            IN PUNICODE_STRING SubKeyName,
+            IN ULONG TitleIndex,
+            IN PUNICODE_STRING Class,
+            IN ULONG CreateOptions);
 
 NTSTATUS
-CmiScanKeyForValue(IN PREGISTRY_HIVE  RegistryHive,
-  IN PKEY_CELL  KeyCell,
-  IN PUNICODE_STRING  ValueName,
-  OUT PVALUE_CELL  *ValueCell,
-  OUT BLOCK_OFFSET *VBOffset);
+CmiRemoveSubKey(IN PREGISTRY_HIVE RegistryHive,
+               IN PKEY_OBJECT Parent,
+               IN PKEY_OBJECT SubKey);
 
 NTSTATUS
-CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE  RegistryHive,
-  IN PKEY_CELL  KeyCell,
-  IN ULONG  Index,
-  OUT PVALUE_CELL  *ValueCell);
+CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
+                  IN PKEY_CELL KeyCell,
+                  IN PUNICODE_STRING ValueName,
+                  OUT PVALUE_CELL *ValueCell,
+                  OUT BLOCK_OFFSET *VBOffset);
 
 NTSTATUS
-CmiAddValueToKey(IN PREGISTRY_HIVE  RegistryHive,
-  IN PKEY_CELL  KeyCell,
-  IN PUNICODE_STRING ValueName,
-  OUT PVALUE_CELL *pValueCell,
-  OUT BLOCK_OFFSET *pVBOffset);
+CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
+                         IN PKEY_CELL KeyCell,
+                         IN ULONG Index,
+                         OUT PVALUE_CELL *ValueCell);
 
 NTSTATUS
-CmiDeleteValueFromKey(IN PREGISTRY_HIVE  RegistryHive,
-  IN PKEY_CELL  KeyCell,
-  IN PUNICODE_STRING ValueName);
+CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
+                IN PKEY_CELL KeyCell,
+                IN BLOCK_OFFSET KeyCellOffset,
+                IN PUNICODE_STRING ValueName,
+                OUT PVALUE_CELL *pValueCell,
+                OUT BLOCK_OFFSET *pValueCellOffset);
 
 NTSTATUS
-CmiAllocateHashTableBlock(IN PREGISTRY_HIVE  RegistryHive,
-  OUT PHASH_TABLE_CELL  *HashBlock,
-  OUT BLOCK_OFFSET  *HBOffset,
-  IN ULONG  HashTableSize);
+CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
+                     IN PKEY_CELL KeyCell,
+                     IN BLOCK_OFFSET KeyCellOffset,
+                     IN PUNICODE_STRING ValueName);
+
+NTSTATUS
+CmiAllocateHashTableCell(IN PREGISTRY_HIVE RegistryHive,
+                        OUT PHASH_TABLE_CELL *HashBlock,
+                        OUT BLOCK_OFFSET *HBOffset,
+                        IN ULONG HashTableSize);
 
 PKEY_CELL
 CmiGetKeyFromHashByIndex(PREGISTRY_HIVE RegistryHive,
-PHASH_TABLE_CELL  HashBlock,
-ULONG  Index);
+                        PHASH_TABLE_CELL HashBlock,
+                        ULONG Index);
 
 NTSTATUS
-CmiAddKeyToHashTable(PREGISTRY_HIVE  RegistryHive,
-  PHASH_TABLE_CELL  HashBlock,
-  PKEY_CELL  NewKeyCell,
-  BLOCK_OFFSET  NKBOffset);
+CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive,
+                    PHASH_TABLE_CELL HashCell,
+                    BLOCK_OFFSET HashCellOffset,
+                    PKEY_CELL NewKeyCell,
+                    BLOCK_OFFSET NKBOffset);
 
 NTSTATUS
-CmiAllocateValueCell(IN PREGISTRY_HIVE  RegistryHive,
-  OUT PVALUE_CELL  *ValueCell,
-  OUT BLOCK_OFFSET  *VBOffset,
-  IN PUNICODE_STRING ValueName);
+CmiRemoveKeyFromHashTable(PREGISTRY_HIVE RegistryHive,
+                         PHASH_TABLE_CELL HashBlock,
+                         BLOCK_OFFSET NKBOffset);
 
 NTSTATUS
-CmiDestroyValueCell(PREGISTRY_HIVE  RegistryHive,
-  PVALUE_CELL  ValueCell,
-  BLOCK_OFFSET  VBOffset);
+CmiAllocateValueCell(IN PREGISTRY_HIVE RegistryHive,
+                    OUT PVALUE_CELL *ValueCell,
+                    OUT BLOCK_OFFSET *VBOffset,
+                    IN PUNICODE_STRING ValueName);
 
 NTSTATUS
-CmiAllocateBlock(PREGISTRY_HIVE  RegistryHive,
-  PVOID  *Block,
-  LONG  BlockSize,
-       BLOCK_OFFSET * pBlockOffset);
+CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive,
+                   PVALUE_CELL ValueCell,
+                   BLOCK_OFFSET VBOffset);
 
 NTSTATUS
-CmiDestroyBlock(PREGISTRY_HIVE  RegistryHive,
-  PVOID  Block,
-  BLOCK_OFFSET Offset);
+CmiAllocateCell(PREGISTRY_HIVE RegistryHive,
+               LONG CellSize,
+               PVOID *Cell,
+               BLOCK_OFFSET *CellOffset);
+
+NTSTATUS
+CmiDestroyCell(PREGISTRY_HIVE RegistryHive,
+              PVOID Cell,
+              BLOCK_OFFSET CellOffset);
+
+PHBIN
+CmiGetBin (PREGISTRY_HIVE RegistryHive,
+          BLOCK_OFFSET CellOffset);
 
 PVOID
-CmiGetBlock(PREGISTRY_HIVE  RegistryHive,
-  BLOCK_OFFSET  BlockOffset,
-       OUT PHBIN * ppBin);
+CmiGetCell (PREGISTRY_HIVE RegistryHive,
+           BLOCK_OFFSET CellOffset,
+           OUT PHBIN *Bin);
 
 VOID
-CmiLockBlock(PREGISTRY_HIVE  RegistryHive,
-  PVOID  Block);
+CmiMarkBlockDirty(PREGISTRY_HIVE RegistryHive,
+                 BLOCK_OFFSET BlockOffset);
 
 VOID
-CmiReleaseBlock(PREGISTRY_HIVE  RegistryHive,
-  PVOID  Block);
+CmiMarkBinDirty(PREGISTRY_HIVE RegistryHive,
+               BLOCK_OFFSET BinOffset);
+
+NTSTATUS
+CmiAddFree(PREGISTRY_HIVE RegistryHive,
+          PCELL_HEADER FreeBlock,
+          BLOCK_OFFSET FreeOffset,
+          BOOLEAN MergeFreeBlocks);
+
+NTSTATUS
+CmiConnectHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
+              PREGISTRY_HIVE RegistryHive);
 
 NTSTATUS
-CmiAddFree(PREGISTRY_HIVE  RegistryHive,
-       PCELL_HEADER FreeBlock,
-  BLOCK_OFFSET FreeOffset);
+CmiDisconnectHive (POBJECT_ATTRIBUTES KeyObjectAttributes,
+                  PREGISTRY_HIVE *RegistryHive);
 
 NTSTATUS
-CmiInitHives(BOOLEAN SetUpBoot);
+CmiInitHives(BOOLEAN SetupBoot);
 
 ULONG
 CmiGetPackedNameLength(IN PUNICODE_STRING Name,
@@ -522,16 +659,47 @@ CmiGetPackedNameLength(IN PUNICODE_STRING Name,
 
 BOOLEAN
 CmiComparePackedNames(IN PUNICODE_STRING Name,
-                     IN PCHAR NameBuffer,
+                     IN PUCHAR NameBuffer,
                      IN USHORT NameBufferSize,
                      IN BOOLEAN NamePacked);
 
 VOID
 CmiCopyPackedName(PWCHAR NameBuffer,
-                 PCHAR PackedNameBuffer,
+                 PUCHAR PackedNameBuffer,
                  ULONG PackedNameSize);
 
+BOOLEAN
+CmiCompareHash(PUNICODE_STRING KeyName,
+              PCHAR HashString);
+
+BOOLEAN
+CmiCompareHashI(PUNICODE_STRING KeyName,
+               PCHAR HashString);
+
+BOOLEAN
+CmiCompareKeyNames(PUNICODE_STRING KeyName,
+                  PKEY_CELL KeyCell);
+
+BOOLEAN
+CmiCompareKeyNamesI(PUNICODE_STRING KeyName,
+                   PKEY_CELL KeyCell);
+
+
 VOID
 CmiSyncHives(VOID);
 
+
+NTSTATUS
+CmiCreateTempHive(PREGISTRY_HIVE *RegistryHive);
+
+NTSTATUS
+CmiCopyKey (PREGISTRY_HIVE DstHive,
+           PKEY_CELL DstKeyCell,
+           PREGISTRY_HIVE SrcHive,
+           PKEY_CELL SrcKeyCell);
+
+NTSTATUS
+CmiSaveTempHive (PREGISTRY_HIVE Hive,
+                HANDLE FileHandle);
+
 #endif /*__INCLUDE_CM_H*/