Add 2nd half of the Filip Navara's cmlib. Now both freeldr and ntoskrnl utilise the same base library to access the registry.

Remember that you need to recreate binary hives, your old reactos registry isn't compatible (due to slight difference in the on-disk structure).

svn path=/trunk/; revision=23348
This commit is contained in:
Aleksey Bragin 2006-07-29 14:43:32 +00:00
parent 677d2a40df
commit bcd159805c
8 changed files with 1001 additions and 3674 deletions

View file

@ -28,6 +28,16 @@ HvpVerifyHiveHeader(
HiveHeader->Sequence1 != HiveHeader->Sequence2 ||
HvpHiveHeaderChecksum(HiveHeader) != HiveHeader->Checksum)
{
DPRINT1("Verify Hive Header failed: \n");
DPRINT1(" Signature: 0x%x and not 0x%x, Major: 0x%x and not 0x%x\n",
HiveHeader->Signature, HV_SIGNATURE, HiveHeader->Major, HV_MAJOR_VER);
DPRINT1(" Minor: 0x%x is not > 0x%x, Type: 0x%x and not 0x%x\n",
HiveHeader->Minor, HV_MINOR_VER, HiveHeader->Type, HV_TYPE_PRIMARY);
DPRINT1(" Format: 0x%x and not 0x%x, Cluster: 0x%x and not 1\n",
HiveHeader->Format, HV_FORMAT_MEMORY, HiveHeader->Cluster);
DPRINT1(" Sequence: 0x%x and not 0x%x, Checksum: 0x%x and not 0x%x\n",
HiveHeader->Sequence1, HiveHeader->Sequence2,
HvpHiveHeaderChecksum(HiveHeader), HiveHeader->Checksum);
return FALSE;
}
@ -139,6 +149,8 @@ HvpInitializeMemoryHive(
if (ChunkSize < sizeof(HIVE_HEADER) ||
!HvpVerifyHiveHeader((PHIVE_HEADER)ChunkBase))
{
DPRINT1("Registry is corrupt: ChunkSize %d < sizeof(HIVE_HEADER) %d, "
"or HvpVerifyHiveHeader() failed\n", ChunkSize, sizeof(HIVE_HEADER));
return STATUS_REGISTRY_CORRUPT;
}

View file

@ -1,6 +1,8 @@
#ifndef __INCLUDE_CM_H
#define __INCLUDE_CM_H
#include <cmlib.h>
#ifdef DBG
#define CHECKED 1
#else
@ -35,265 +37,17 @@
#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_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_CELL_ID 0x666c
#define REG_VALUE_CELL_ID 0x6b76
#define REG_SECURITY_CELL_ID 0x6b73
// BLOCK_OFFSET = offset in file after header block
typedef ULONG BLOCK_OFFSET, *PBLOCK_OFFSET;
#include <pshpack1.h>
/* header for registry hive file : */
typedef struct _HIVE_HEADER
{
/* Hive identifier "regf" (0x66676572) */
ULONG BlockId;
/* Update counter */
ULONG UpdateCounter1;
/* Update counter */
ULONG UpdateCounter2;
/* When this hive file was last modified */
LARGE_INTEGER DateModified;
/* Registry format major version (1) */
ULONG MajorVersion;
/* Registry format minor version (3)
Version 3 added fast indexes, version 5 has large value optimizations */
ULONG MinorVersion;
/* Registry file type (0 - Primary, 1 - Log) */
ULONG Type;
/* 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 RootKeyOffset;
/* Size of each hive block ? */
ULONG BlockSize;
/* (1?) */
ULONG Unused7;
/* Name of hive file */
WCHAR FileName[32];
ULONG Reserved[99];
/* Checksum of first 0x200 bytes */
ULONG Checksum;
} HIVE_HEADER, *PHIVE_HEADER;
typedef struct _BIN_HEADER
{
/* Bin identifier "hbin" (0x6E696268) */
ULONG HeaderId;
/* Block offset of this bin */
BLOCK_OFFSET BinOffset;
/* Size in bytes, multiple of the block size (4KB) */
ULONG BinSize;
ULONG Reserved[2];
/* When this bin was last modified */
LARGE_INTEGER DateModified;
/* ? (In-memory only) */
ULONG MemAlloc;
} HBIN, *PHBIN;
typedef struct _CELL_HEADER
{
/* <0 if used, >0 if free */
LONG CellSize;
} CELL_HEADER, *PCELL_HEADER;
typedef struct _KEY_CELL
{
/* Size of this cell */
LONG CellSize;
/* Key cell identifier "kn" (0x6b6e) */
USHORT Id;
/* Flags */
USHORT Flags;
/* Time of last flush */
LARGE_INTEGER LastWriteTime;
/* ? */
ULONG UnUsed1;
/* Block offset of parent key cell */
BLOCK_OFFSET ParentKeyOffset;
/* Count of sub keys for the key in this key cell */
ULONG NumberOfSubKeys;
/* ? */
ULONG UnUsed2;
/* Block offset of has table for FIXME: subkeys/values? */
BLOCK_OFFSET HashTableOffset;
/* ? */
ULONG UnUsed3;
/* Count of values contained in this key cell */
ULONG NumberOfValues;
/* Block offset of VALUE_LIST_CELL */
BLOCK_OFFSET ValueListOffset;
/* Block offset of security cell */
BLOCK_OFFSET SecurityKeyOffset;
/* Block offset of registry key class */
BLOCK_OFFSET ClassNameOffset;
/* ? */
ULONG Unused4[5];
/* Size in bytes of key name */
USHORT NameSize;
/* Size of class name in bytes */
USHORT ClassSize;
/* Name of key (not zero terminated) */
UCHAR Name[0];
} 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;
} HASH_RECORD, *PHASH_RECORD;
typedef struct _HASH_TABLE_CELL
{
LONG CellSize;
USHORT Id;
USHORT HashTableSize;
HASH_RECORD Table[0];
} HASH_TABLE_CELL, *PHASH_TABLE_CELL;
typedef struct _VALUE_LIST_CELL
{
LONG CellSize;
BLOCK_OFFSET ValueOffset[0];
} VALUE_LIST_CELL, *PVALUE_LIST_CELL;
typedef struct _VALUE_CELL
{
LONG CellSize;
USHORT Id; // "kv"
USHORT NameSize; // length of Name
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 */
} 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];
} 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
typedef struct _EREGISTRY_HIVE
{
LIST_ENTRY HiveList;
ULONG Flags;
PREGISTRY_HIVE Hive;
UNICODE_STRING HiveFileName;
UNICODE_STRING LogFileName;
ULONG FileSize;
PHIVE_HEADER HiveHeader;
ULONG UpdateCounter;
ULONG BlockListSize;
PBLOCK_LIST_ENTRY BlockList;
ULONG FreeListSize;
ULONG FreeListMax;
PCELL_HEADER *FreeList;
BLOCK_OFFSET *FreeListOffset;
PSECURITY_CELL RootSecurityCell;
PULONG BitmapBuffer;
RTL_BITMAP DirtyBitMap;
BOOLEAN HiveDirty;
} REGISTRY_HIVE, *PREGISTRY_HIVE;
/* REGISTRY_HIVE.Flags constants */
/* When set, the hive uses pointers instead of offsets. */
#define HIVE_POINTER 0x00000001
PSECURITY_CELL RootSecurityCell;
ULONG Flags;
HANDLE HiveHandle;
HANDLE LogHandle;
} EREGISTRY_HIVE, *PEREGISTRY_HIVE;
/* When set, the hive is not backed by a file.
Therefore, it can not be flushed to disk. */
@ -303,22 +57,15 @@ typedef struct _REGISTRY_HIVE
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 IsFreeCell(Cell)(Cell->CellSize >= 0)
#define IsUsedCell(Cell)(Cell->CellSize < 0)
/* KEY_OBJECT.Flags */
/* When set, the key is scheduled for deletion, and all
attempts to access the key must not succeed */
#define KO_MARKED_FOR_DELETE 0x00000001
/* Type defining the Object Manager Key Object */
typedef struct _KEY_OBJECT
{
@ -333,10 +80,10 @@ typedef struct _KEY_OBJECT
UNICODE_STRING Name;
/* Registry hive the key belongs to */
PREGISTRY_HIVE RegistryHive;
PEREGISTRY_HIVE RegistryHive;
/* Block offset of the key cell this key belongs in */
BLOCK_OFFSET KeyCellOffset;
HCELL_INDEX KeyCellOffset;
/* KEY_CELL this key belong in */
PKEY_CELL KeyCell;
@ -344,6 +91,9 @@ typedef struct _KEY_OBJECT
/* Link to the parent KEY_OBJECT for this key */
struct _KEY_OBJECT *ParentKey;
/* List entry into the global key object list */
LIST_ENTRY ListEntry;
/* Subkeys loaded in SubKeys */
ULONG NumberOfSubKeys;
@ -353,9 +103,6 @@ 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;
@ -371,8 +118,7 @@ typedef struct _KEY_OBJECT
#define CmiByteOffset(Cellndex)(CellIndex & 0x00000fff)
extern BOOLEAN CmiDoVerify;
extern PREGISTRY_HIVE CmiVolatileHive;
extern PEREGISTRY_HIVE CmiVolatileHive;
extern POBJECT_TYPE CmiKeyType;
extern KSPIN_LOCK CmiKeyListLock;
@ -402,34 +148,13 @@ NTSTATUS
CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1,
IN PVOID Argument2);
VOID
CmiVerifyBinHeader(PHBIN BinHeader);
VOID
CmiVerifyKeyCell(PKEY_CELL KeyCell);
VOID
CmiVerifyRootKeyCell(PKEY_CELL RootKeyCell);
VOID
CmiVerifyKeyObject(PKEY_OBJECT KeyObject);
VOID
CmiVerifyRegistryHive(PREGISTRY_HIVE RegistryHive);
#ifdef DBG
#define VERIFY_BIN_HEADER CmiVerifyBinHeader
#define VERIFY_KEY_CELL CmiVerifyKeyCell
#define VERIFY_ROOT_KEY_CELL CmiVerifyRootKeyCell
#define VERIFY_VALUE_CELL CmiVerifyValueCell
#define VERIFY_VALUE_LIST_CELL CmiVerifyValueListCell
#define VERIFY_KEY_OBJECT CmiVerifyKeyObject
#define VERIFY_REGISTRY_HIVE CmiVerifyRegistryHive
#else
#define VERIFY_BIN_HEADER(x)
#define VERIFY_KEY_CELL(x)
#define VERIFY_ROOT_KEY_CELL(x)
#define VERIFY_VALUE_CELL(x)
#define VERIFY_BIN_HEADER(x) ASSERT(x->HeaderId == REG_BIN_ID)
#define VERIFY_KEY_CELL(x) ASSERT(x->Id == REG_KEY_CELL_ID)
#define VERIFY_ROOT_KEY_CELL(x) ASSERT(x->Id == REG_KEY_CELL_ID)
#define VERIFY_VALUE_CELL(x) ASSERT(x->Id == REG_VALUE_CELL_ID)
#define VERIFY_VALUE_LIST_CELL(x)
#define VERIFY_KEY_OBJECT(x)
#define VERIFY_REGISTRY_HIVE(x)
#endif
NTSTATUS STDCALL
CmRegisterCallback(IN PEX_CALLBACK_FUNCTION Function,
@ -473,23 +198,6 @@ CmiObjectQueryName (PVOID ObjectBody,
PULONG ReturnLength,
IN KPROCESSOR_MODE PreviousMode);
NTSTATUS
CmiImportHiveBins(PREGISTRY_HIVE Hive,
PUCHAR ChunkPtr);
VOID
CmiFreeHiveBins(PREGISTRY_HIVE Hive);
NTSTATUS
CmiCreateHiveFreeCellList(PREGISTRY_HIVE Hive);
VOID
CmiFreeHiveFreeCellList(PREGISTRY_HIVE Hive);
NTSTATUS
CmiCreateHiveBitmap(PREGISTRY_HIVE Hive);
VOID
CmiAddKeyToList(IN PKEY_OBJECT ParentKey,
IN PKEY_OBJECT NewKey);
@ -504,7 +212,7 @@ CmiScanKeyList(IN PKEY_OBJECT Parent,
PKEY_OBJECT* ReturnedObject);
NTSTATUS
CmiCreateVolatileHive(PREGISTRY_HIVE *RegistryHive);
CmiCreateVolatileHive(PEREGISTRY_HIVE *RegistryHive);
NTSTATUS
CmiLoadHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
@ -512,10 +220,10 @@ CmiLoadHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
ULONG Flags);
NTSTATUS
CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive);
CmiRemoveRegistryHive(PEREGISTRY_HIVE RegistryHive);
NTSTATUS
CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive);
CmiFlushRegistryHive(PEREGISTRY_HIVE RegistryHive);
ULONG
CmiGetNumberOfSubKeys(PKEY_OBJECT KeyObject);
@ -527,24 +235,24 @@ ULONG
CmiGetMaxClassLength(IN PKEY_OBJECT KeyObject);
ULONG
CmiGetMaxValueNameLength(IN PREGISTRY_HIVE RegistryHive,
CmiGetMaxValueNameLength(IN PEREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell);
ULONG
CmiGetMaxValueDataLength(IN PREGISTRY_HIVE RegistryHive,
CmiGetMaxValueDataLength(IN PEREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell);
NTSTATUS
CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive,
CmiScanForSubKey(IN PEREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell,
OUT PKEY_CELL *SubKeyCell,
OUT BLOCK_OFFSET *BlockOffset,
OUT HCELL_INDEX *BlockOffset,
IN PUNICODE_STRING KeyName,
IN ACCESS_MASK DesiredAccess,
IN ULONG Attributes);
NTSTATUS
CmiAddSubKey(IN PREGISTRY_HIVE RegistryHive,
CmiAddSubKey(IN PEREGISTRY_HIVE RegistryHive,
IN PKEY_OBJECT ParentKey,
OUT PKEY_OBJECT SubKey,
IN PUNICODE_STRING SubKeyName,
@ -553,112 +261,81 @@ CmiAddSubKey(IN PREGISTRY_HIVE RegistryHive,
IN ULONG CreateOptions);
NTSTATUS
CmiRemoveSubKey(IN PREGISTRY_HIVE RegistryHive,
CmiRemoveSubKey(IN PEREGISTRY_HIVE RegistryHive,
IN PKEY_OBJECT Parent,
IN PKEY_OBJECT SubKey);
NTSTATUS
CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
CmiScanKeyForValue(IN PEREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell,
IN PUNICODE_STRING ValueName,
OUT PVALUE_CELL *ValueCell,
OUT BLOCK_OFFSET *VBOffset);
OUT HCELL_INDEX *VBOffset);
NTSTATUS
CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
CmiGetValueFromKeyByIndex(IN PEREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell,
IN ULONG Index,
OUT PVALUE_CELL *ValueCell);
NTSTATUS
CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
CmiAddValueToKey(IN PEREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell,
IN BLOCK_OFFSET KeyCellOffset,
IN HCELL_INDEX KeyCellOffset,
IN PUNICODE_STRING ValueName,
OUT PVALUE_CELL *pValueCell,
OUT BLOCK_OFFSET *pValueCellOffset);
OUT HCELL_INDEX *pValueCellOffset);
NTSTATUS
CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
CmiDeleteValueFromKey(IN PEREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell,
IN BLOCK_OFFSET KeyCellOffset,
IN HCELL_INDEX KeyCellOffset,
IN PUNICODE_STRING ValueName);
NTSTATUS
CmiAllocateHashTableCell(IN PREGISTRY_HIVE RegistryHive,
CmiAllocateHashTableCell(IN PEREGISTRY_HIVE RegistryHive,
OUT PHASH_TABLE_CELL *HashBlock,
OUT BLOCK_OFFSET *HBOffset,
IN ULONG HashTableSize);
OUT HCELL_INDEX *HBOffset,
IN ULONG HashTableSize,
IN HV_STORAGE_TYPE Storage);
PKEY_CELL
CmiGetKeyFromHashByIndex(PREGISTRY_HIVE RegistryHive,
CmiGetKeyFromHashByIndex(PEREGISTRY_HIVE RegistryHive,
PHASH_TABLE_CELL HashBlock,
ULONG Index);
NTSTATUS
CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive,
CmiAddKeyToHashTable(PEREGISTRY_HIVE RegistryHive,
PHASH_TABLE_CELL HashCell,
BLOCK_OFFSET HashCellOffset,
PKEY_CELL KeyCell,
HV_STORAGE_TYPE StorageType,
PKEY_CELL NewKeyCell,
BLOCK_OFFSET NKBOffset);
HCELL_INDEX NKBOffset);
NTSTATUS
CmiRemoveKeyFromHashTable(PREGISTRY_HIVE RegistryHive,
CmiRemoveKeyFromHashTable(PEREGISTRY_HIVE RegistryHive,
PHASH_TABLE_CELL HashBlock,
BLOCK_OFFSET NKBOffset);
HCELL_INDEX NKBOffset);
NTSTATUS
CmiAllocateValueCell(IN PREGISTRY_HIVE RegistryHive,
CmiAllocateValueCell(IN PEREGISTRY_HIVE RegistryHive,
OUT PVALUE_CELL *ValueCell,
OUT BLOCK_OFFSET *VBOffset,
IN PUNICODE_STRING ValueName);
OUT HCELL_INDEX *VBOffset,
IN PUNICODE_STRING ValueName,
IN HV_STORAGE_TYPE Storage);
NTSTATUS
CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive,
CmiDestroyValueCell(PEREGISTRY_HIVE RegistryHive,
PVALUE_CELL ValueCell,
BLOCK_OFFSET VBOffset);
NTSTATUS
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
CmiGetCell (PREGISTRY_HIVE RegistryHive,
BLOCK_OFFSET CellOffset,
OUT PHBIN *Bin);
VOID
CmiMarkBlockDirty(PREGISTRY_HIVE RegistryHive,
BLOCK_OFFSET BlockOffset);
VOID
CmiMarkBinDirty(PREGISTRY_HIVE RegistryHive,
BLOCK_OFFSET BinOffset);
NTSTATUS
CmiAddFree(PREGISTRY_HIVE RegistryHive,
PCELL_HEADER FreeBlock,
BLOCK_OFFSET FreeOffset,
BOOLEAN MergeFreeBlocks);
HCELL_INDEX VBOffset);
NTSTATUS
CmiConnectHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
PREGISTRY_HIVE RegistryHive);
PEREGISTRY_HIVE RegistryHive);
NTSTATUS
CmiDisconnectHive (POBJECT_ATTRIBUTES KeyObjectAttributes,
PREGISTRY_HIVE *RegistryHive);
PEREGISTRY_HIVE *RegistryHive);
NTSTATUS
CmiInitHives(BOOLEAN SetupBoot);
@ -700,16 +377,16 @@ CmiSyncHives(VOID);
NTSTATUS
CmiCreateTempHive(PREGISTRY_HIVE *RegistryHive);
CmiCreateTempHive(PEREGISTRY_HIVE *RegistryHive);
NTSTATUS
CmiCopyKey (PREGISTRY_HIVE DstHive,
CmiCopyKey (PEREGISTRY_HIVE DstHive,
PKEY_CELL DstKeyCell,
PREGISTRY_HIVE SrcHive,
PEREGISTRY_HIVE SrcHive,
PKEY_CELL SrcKeyCell);
NTSTATUS
CmiSaveTempHive (PREGISTRY_HIVE Hive,
CmiSaveTempHive (PEREGISTRY_HIVE Hive,
HANDLE FileHandle);
NTSTATUS
@ -723,4 +400,65 @@ CmFindObject(
IN PACCESS_STATE AccessState,
IN PVOID ParseContext
);
PVOID CMAPI
CmpAllocate(
ULONG Size,
BOOLEAN Paged);
VOID CMAPI
CmpFree(
PVOID Ptr);
BOOLEAN CMAPI
CmpFileRead(
PREGISTRY_HIVE RegistryHive,
ULONG FileType,
ULONG FileOffset,
PVOID Buffer,
ULONG BufferLength);
BOOLEAN CMAPI
CmpFileWrite(
PREGISTRY_HIVE RegistryHive,
ULONG FileType,
ULONG FileOffset,
PVOID Buffer,
ULONG BufferLength);
BOOLEAN CMAPI
CmpFileSetSize(
PREGISTRY_HIVE RegistryHive,
ULONG FileType,
ULONG FileSize);
BOOLEAN CMAPI
CmpFileFlush(
PREGISTRY_HIVE RegistryHive,
ULONG FileType);
#if 0
static __inline PVOID xHvGetCell(char *file, int line, PREGISTRY_HIVE Hive, HCELL_INDEX Cell)
{
DPRINT1("xHvGetCell @ %s:%d %x @ %x\n", file, line, Cell, Hive);
return HvGetCell(Hive, Cell);
}
static __inline VOID xHvFreeCell(char *file, int line, PREGISTRY_HIVE Hive, HCELL_INDEX Cell)
{
DPRINT1("xHvFreeCell @ %s:%d %x @ %x\n", file, line, Cell, Hive);
HvFreeCell(Hive, Cell);
}
static __inline HCELL_INDEX xHvAllocateCell(char *file, int line, PREGISTRY_HIVE Hive, SIZE_T Size)
{
HCELL_INDEX Offset = HvAllocateCell(Hive, Size);
DPRINT1("xHvAllocateCell @ %s:%d (%x) %x @ %x\n", file, line, Size, Offset, Hive);
return Offset;
}
#define HvGetCell(hive, cell) xHvGetCell(__FILE__, __LINE__, hive, cell)
#define HvFreeCell(hive, cell) xHvFreeCell(__FILE__, __LINE__, hive, cell)
#define HvAllocateCell(hive, size) xHvAllocateCell(__FILE__, __LINE__, hive, size)
#endif
#endif /*__INCLUDE_CM_H*/

View file

@ -24,120 +24,46 @@
static BOOLEAN CmiHardwareHiveImported = FALSE;
/* FUNCTIONS ****************************************************************/
static BOOLEAN
CmImportBinaryHive (PCHAR ChunkBase,
ULONG ChunkSize,
ULONG Flags,
PREGISTRY_HIVE *RegistryHive)
PEREGISTRY_HIVE *RegistryHive)
{
PREGISTRY_HIVE Hive;
PEREGISTRY_HIVE Hive;
NTSTATUS Status;
*RegistryHive = NULL;
if (strncmp (ChunkBase, "regf", 4))
{
DPRINT1 ("Found invalid '%*s' magic\n", 4, ChunkBase);
return FALSE;
}
/* Create a new hive */
Hive = ExAllocatePool (NonPagedPool,
sizeof(REGISTRY_HIVE));
sizeof(EREGISTRY_HIVE));
if (Hive == NULL)
{
return FALSE;
}
RtlZeroMemory (Hive,
sizeof(REGISTRY_HIVE));
sizeof(EREGISTRY_HIVE));
/* Set hive flags */
Hive->Flags = Flags;
/* Allocate hive header */
Hive->HiveHeader = (PHIVE_HEADER)ExAllocatePool (NonPagedPool,
sizeof(HIVE_HEADER));
if (Hive->HiveHeader == NULL)
Status = HvInitialize(&Hive->Hive, HV_OPERATION_MEMORY,
(ULONG_PTR)ChunkBase, ChunkSize,
CmpAllocate, CmpFree,
CmpFileRead, CmpFileWrite, CmpFileSetSize,
CmpFileFlush, Hive);
if (!NT_SUCCESS(Status))
{
DPRINT1 ("Allocating hive header failed\n");
DPRINT1 ("Opening hive failed (%x)\n", Status);
ExFreePool (Hive);
return FALSE;
}
/* Import the hive header */
RtlCopyMemory (Hive->HiveHeader,
ChunkBase,
sizeof(HIVE_HEADER));
/* Read update counter */
Hive->UpdateCounter = Hive->HiveHeader->UpdateCounter1;
/* Set the hive's size */
Hive->FileSize = ChunkSize;
/* Set the size of the block list */
Hive->BlockListSize = (Hive->FileSize / 4096) - 1;
/* Allocate block list */
DPRINT("Space needed for block list describing hive: 0x%x\n",
Hive->BlockListSize * sizeof(BLOCK_LIST_ENTRY));
Hive->BlockList = ExAllocatePool (NonPagedPool,
Hive->BlockListSize * sizeof(BLOCK_LIST_ENTRY));
if (Hive->BlockList == NULL)
{
DPRINT1 ("Allocating block list failed\n");
ExFreePool (Hive->HiveHeader);
ExFreePool (Hive);
return FALSE;
}
RtlZeroMemory (Hive->BlockList,
Hive->BlockListSize * sizeof(BLOCK_LIST_ENTRY));
/* Import the bins */
Status = CmiImportHiveBins(Hive,
(PUCHAR)((ULONG_PTR)ChunkBase + 4096));
if (!NT_SUCCESS(Status))
{
DPRINT1 ("CmiImportHiveBins() failed (Status %lx)\n", Status);
CmiFreeHiveBins (Hive);
ExFreePool (Hive->BlockList);
ExFreePool (Hive->HiveHeader);
ExFreePool (Hive);
return (BOOLEAN)Status;
}
/* Initialize the free cell list */
Status = CmiCreateHiveFreeCellList (Hive);
if (!NT_SUCCESS(Status))
{
DPRINT1 ("CmiCreateHiveFreeCellList() failed (Status %lx)\n", Status);
CmiFreeHiveBins (Hive);
ExFreePool (Hive->BlockList);
ExFreePool (Hive->HiveHeader);
ExFreePool (Hive);
return (BOOLEAN)Status;
}
if (!(Hive->Flags & HIVE_NO_FILE))
{
/* Create the block bitmap */
Status = CmiCreateHiveBitmap (Hive);
if (!NT_SUCCESS(Status))
{
DPRINT1 ("CmiCreateHiveBitmap() failed (Status %lx)\n", Status);
CmiFreeHiveFreeCellList (Hive);
CmiFreeHiveBins (Hive);
ExFreePool (Hive->BlockList);
ExFreePool (Hive->HiveHeader);
ExFreePool (Hive);
return (BOOLEAN)Status;
}
}
CmPrepareHive(Hive->Hive);
/* Acquire hive list lock exclusively */
KeEnterCriticalRegion();
@ -163,7 +89,7 @@ CmImportSystemHive(PCHAR ChunkBase,
ULONG ChunkSize)
{
OBJECT_ATTRIBUTES ObjectAttributes;
PREGISTRY_HIVE RegistryHive;
PEREGISTRY_HIVE RegistryHive;
UNICODE_STRING KeyName;
NTSTATUS Status;
@ -217,7 +143,7 @@ CmImportHardwareHive(PCHAR ChunkBase,
ULONG ChunkSize)
{
OBJECT_ATTRIBUTES ObjectAttributes;
PREGISTRY_HIVE RegistryHive;
PEREGISTRY_HIVE RegistryHive;
UNICODE_STRING KeyName;
HANDLE HardwareKey;
ULONG Disposition;

View file

@ -16,11 +16,9 @@
#include "cm.h"
/* GLOBALS ******************************************************************/
extern POBJECT_TYPE CmiKeyType;
extern PREGISTRY_HIVE CmiVolatileHive;
extern LIST_ENTRY CmiKeyObjectListHead;
static BOOLEAN CmiRegistryInitialized = FALSE;
@ -481,12 +479,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
}
KeyObject->ParentKey = Object;
if (CreateOptions & REG_OPTION_VOLATILE)
KeyObject->RegistryHive = CmiVolatileHive;
else
KeyObject->RegistryHive = KeyObject->ParentKey->RegistryHive;
KeyObject->RegistryHive = KeyObject->ParentKey->RegistryHive;
KeyObject->Flags = 0;
KeyObject->NumberOfSubKeys = 0;
KeyObject->SizeOfSubKeys = 0;
@ -532,19 +525,10 @@ NtCreateKey(OUT PHANDLE KeyHandle,
RtlpCreateUnicodeString(&KeyObject->Name, Start, NonPagedPool);
}
if (KeyObject->RegistryHive == KeyObject->ParentKey->RegistryHive)
{
KeyObject->KeyCell->ParentKeyOffset = KeyObject->ParentKey->KeyCellOffset;
KeyObject->KeyCell->SecurityKeyOffset = KeyObject->ParentKey->KeyCell->SecurityKeyOffset;
}
else
{
KeyObject->KeyCell->ParentKeyOffset = -1;
KeyObject->KeyCell->SecurityKeyOffset = -1;
/* This key must remain in memory unless it is deleted
or file is unloaded */
ObReferenceObject(KeyObject);
}
KeyObject->KeyCell->ParentKeyOffset = KeyObject->ParentKey->KeyCellOffset;
KeyObject->KeyCell->SecurityKeyOffset = KeyObject->ParentKey->KeyCell->SecurityKeyOffset;
DPRINT("RemainingPath: %wZ\n", &RemainingPath);
CmiAddKeyToList(KeyObject->ParentKey, KeyObject);
@ -638,7 +622,8 @@ NtDeleteKey(IN HANDLE KeyHandle)
VERIFY_KEY_OBJECT(KeyObject);
/* Check for subkeys */
if (KeyObject->NumberOfSubKeys != 0)
if (KeyObject->KeyCell->NumberOfSubKeys[HvStable] != 0 ||
KeyObject->KeyCell->NumberOfSubKeys[HvVolatile] != 0)
{
Status = STATUS_CANNOT_DELETE;
}
@ -653,7 +638,7 @@ NtDeleteKey(IN HANDLE KeyHandle)
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
//DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
/* Remove the keep-alive reference */
ObDereferenceObject(KeyObject);
@ -667,8 +652,8 @@ NtDeleteKey(IN HANDLE KeyHandle)
/* Dereference the object */
ObDereferenceObject(KeyObject);
DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
DPRINT("HandleCount %lu\n", ObGetObjectHandleCount((PVOID)KeyObject));
//DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
//DPRINT("HandleCount %lu\n", ObGetObjectHandleCount((PVOID)KeyObject));
/*
* Note:
@ -690,19 +675,20 @@ NtEnumerateKey(IN HANDLE KeyHandle,
OUT PULONG ResultLength)
{
PKEY_OBJECT KeyObject;
PKEY_OBJECT SubKeyObject;
PREGISTRY_HIVE RegistryHive;
PEREGISTRY_HIVE RegistryHive;
PKEY_CELL KeyCell, SubKeyCell;
PHASH_TABLE_CELL HashTableBlock;
PKEY_BASIC_INFORMATION BasicInformation;
PKEY_NODE_INFORMATION NodeInformation;
PKEY_FULL_INFORMATION FullInformation;
PDATA_CELL ClassCell;
PVOID ClassCell;
ULONG NameSize, ClassSize;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
REG_ENUMERATE_KEY_INFORMATION EnumerateKeyInfo;
REG_POST_OPERATION_INFORMATION PostOperationInfo;
HV_STORAGE_TYPE Storage;
ULONG BaseIndex;
PAGED_CODE();
@ -753,10 +739,9 @@ NtEnumerateKey(IN HANDLE KeyHandle,
KeyCell = KeyObject->KeyCell;
RegistryHive = KeyObject->RegistryHive;
SubKeyObject = NULL;
/* Check for hightest possible sub key index */
if (Index >= KeyCell->NumberOfSubKeys + KeyObject->NumberOfSubKeys)
if (Index >= KeyCell->NumberOfSubKeys[HvStable] +
KeyCell->NumberOfSubKeys[HvVolatile])
{
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
@ -768,95 +753,43 @@ NtEnumerateKey(IN HANDLE KeyHandle,
}
/* Get pointer to SubKey */
if (Index >= KeyCell->NumberOfSubKeys)
if (Index >= KeyCell->NumberOfSubKeys[HvStable])
{
PKEY_OBJECT CurKey = NULL;
ULONG i;
ULONG j;
/* Search for volatile or 'foreign' keys */
j = KeyCell->NumberOfSubKeys;
for (i = 0; i < KeyObject->NumberOfSubKeys; i++)
{
CurKey = KeyObject->SubKeys[i];
if (CurKey->RegistryHive != RegistryHive)
{
if (j == Index)
break;
j++;
}
}
if (i >= KeyObject->NumberOfSubKeys)
{
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
PostOperationInfo.Status = STATUS_NO_MORE_ENTRIES;
CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo);
ObDereferenceObject(KeyObject);
DPRINT("No more non-volatile entries\n");
return STATUS_NO_MORE_ENTRIES;
}
SubKeyObject = CurKey;
SubKeyCell = CurKey->KeyCell;
Storage = HvVolatile;
BaseIndex = Index - KeyCell->NumberOfSubKeys[HvStable];
}
else
{
if (KeyCell->HashTableOffset == (BLOCK_OFFSET)-1)
{
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
PostOperationInfo.Status = STATUS_NO_MORE_ENTRIES;
CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo);
ObDereferenceObject(KeyObject);
return STATUS_NO_MORE_ENTRIES;
}
HashTableBlock = CmiGetCell (RegistryHive, KeyCell->HashTableOffset, NULL);
if (HashTableBlock == NULL)
{
DPRINT("CmiGetBlock() failed\n");
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
PostOperationInfo.Status = STATUS_UNSUCCESSFUL;
CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo);
ObDereferenceObject(KeyObject);
return STATUS_UNSUCCESSFUL;
}
SubKeyCell = CmiGetKeyFromHashByIndex(RegistryHive,
HashTableBlock,
Index);
Storage = HvStable;
BaseIndex = Index;
}
if (SubKeyCell == NULL)
if (KeyCell->HashTableOffset[Storage] == HCELL_NULL)
{
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
PostOperationInfo.Status = STATUS_NO_MORE_ENTRIES;
CmiCallRegisteredCallbacks(RegNtPostEnumerateKey, &PostOperationInfo);
ObDereferenceObject(KeyObject);
DPRINT("No more entries\n");
return STATUS_NO_MORE_ENTRIES;
}
ASSERT(KeyCell->HashTableOffset[Storage] != HCELL_NULL);
HashTableBlock = HvGetCell (RegistryHive->Hive, KeyCell->HashTableOffset[Storage]);
SubKeyCell = CmiGetKeyFromHashByIndex(RegistryHive,
HashTableBlock,
BaseIndex);
Status = STATUS_SUCCESS;
switch (KeyInformationClass)
{
case KeyBasicInformation:
/* Check size of buffer */
if (SubKeyObject != NULL)
NameSize = SubKeyCell->NameSize;
if (SubKeyCell->Flags & REG_KEY_NAME_PACKED)
{
NameSize = SubKeyObject->Name.Length;
}
else
{
NameSize = SubKeyCell->NameSize;
if (SubKeyCell->Flags & REG_KEY_NAME_PACKED)
{
NameSize *= sizeof(WCHAR);
}
NameSize *= sizeof(WCHAR);
}
*ResultLength = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]) + NameSize;
@ -887,43 +820,27 @@ NtEnumerateKey(IN HANDLE KeyHandle,
CHECKPOINT;
}
if (SubKeyObject != NULL)
if (SubKeyCell->Flags & REG_KEY_NAME_PACKED)
{
RtlCopyMemory(BasicInformation->Name,
SubKeyObject->Name.Buffer,
NameSize);
CmiCopyPackedName(BasicInformation->Name,
SubKeyCell->Name,
NameSize / sizeof(WCHAR));
}
else
{
if (SubKeyCell->Flags & REG_KEY_NAME_PACKED)
{
CmiCopyPackedName(BasicInformation->Name,
SubKeyCell->Name,
NameSize / sizeof(WCHAR));
}
else
{
RtlCopyMemory(BasicInformation->Name,
SubKeyCell->Name,
NameSize);
}
RtlCopyMemory(BasicInformation->Name,
SubKeyCell->Name,
NameSize);
}
}
break;
case KeyNodeInformation:
/* Check size of buffer */
if (SubKeyObject != NULL)
NameSize = SubKeyCell->NameSize;
if (SubKeyCell->Flags & REG_KEY_NAME_PACKED)
{
NameSize = SubKeyObject->Name.Length;
}
else
{
NameSize = SubKeyCell->NameSize;
if (SubKeyCell->Flags & REG_KEY_NAME_PACKED)
{
NameSize *= sizeof(WCHAR);
}
NameSize *= sizeof(WCHAR);
}
ClassSize = SubKeyCell->ClassSize;
@ -961,35 +878,25 @@ NtEnumerateKey(IN HANDLE KeyHandle,
CHECKPOINT;
}
if (SubKeyObject != NULL)
if (SubKeyCell->Flags & REG_KEY_NAME_PACKED)
{
RtlCopyMemory(NodeInformation->Name,
SubKeyObject->Name.Buffer,
NameSize);
CmiCopyPackedName(NodeInformation->Name,
SubKeyCell->Name,
NameSize / sizeof(WCHAR));
}
else
{
if (SubKeyCell->Flags & REG_KEY_NAME_PACKED)
{
CmiCopyPackedName(NodeInformation->Name,
SubKeyCell->Name,
NameSize / sizeof(WCHAR));
}
else
{
RtlCopyMemory(NodeInformation->Name,
SubKeyCell->Name,
NameSize);
}
}
RtlCopyMemory(NodeInformation->Name,
SubKeyCell->Name,
NameSize);
}
if (ClassSize != 0)
{
ClassCell = CmiGetCell (KeyObject->RegistryHive,
SubKeyCell->ClassNameOffset,
NULL);
ClassCell = HvGetCell (KeyObject->RegistryHive->Hive,
SubKeyCell->ClassNameOffset);
RtlCopyMemory (NodeInformation->Name + SubKeyCell->NameSize,
ClassCell->Data,
ClassCell,
ClassSize);
}
}
@ -1034,11 +941,10 @@ NtEnumerateKey(IN HANDLE KeyHandle,
if (ClassSize != 0)
{
ClassCell = CmiGetCell (KeyObject->RegistryHive,
SubKeyCell->ClassNameOffset,
NULL);
ClassCell = HvGetCell (KeyObject->RegistryHive->Hive,
SubKeyCell->ClassNameOffset);
RtlCopyMemory (FullInformation->Class,
ClassCell->Data,
ClassCell,
ClassSize);
}
}
@ -1073,10 +979,10 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
{
NTSTATUS Status;
PKEY_OBJECT KeyObject;
PREGISTRY_HIVE RegistryHive;
PEREGISTRY_HIVE RegistryHive;
PKEY_CELL KeyCell;
PVALUE_CELL ValueCell;
PDATA_CELL DataCell;
PVOID DataCell;
ULONG NameSize, DataSize;
PKEY_VALUE_BASIC_INFORMATION ValueBasicInformation;
PKEY_VALUE_PARTIAL_INFORMATION ValuePartialInformation;
@ -1205,9 +1111,9 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
if (!(ValueCell->DataSize & REG_DATA_IN_OFFSET))
{
DataCell = CmiGetCell (RegistryHive, ValueCell->DataOffset, NULL);
DataCell = HvGetCell (RegistryHive->Hive, ValueCell->DataOffset);
RtlCopyMemory(ValuePartialInformation->Data,
DataCell->Data,
DataCell,
DataSize);
}
else
@ -1278,10 +1184,10 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
if (!(ValueCell->DataSize & REG_DATA_IN_OFFSET))
{
DataCell = CmiGetCell (RegistryHive, ValueCell->DataOffset, NULL);
DataCell = HvGetCell (RegistryHive->Hive, ValueCell->DataOffset);
RtlCopyMemory((PCHAR) ValueFullInformation
+ ValueFullInformation->DataOffset,
DataCell->Data, DataSize);
DataCell, DataSize);
}
else
{
@ -1315,7 +1221,7 @@ NtFlushKey(IN HANDLE KeyHandle)
{
NTSTATUS Status;
PKEY_OBJECT KeyObject;
PREGISTRY_HIVE RegistryHive;
PEREGISTRY_HIVE RegistryHive;
KPROCESSOR_MODE PreviousMode;
PAGED_CODE();
@ -1526,8 +1432,8 @@ NtQueryKey(IN HANDLE KeyHandle,
PKEY_BASIC_INFORMATION BasicInformation;
PKEY_NODE_INFORMATION NodeInformation;
PKEY_FULL_INFORMATION FullInformation;
PREGISTRY_HIVE RegistryHive;
PDATA_CELL ClassCell;
PEREGISTRY_HIVE RegistryHive;
PVOID ClassCell;
PKEY_OBJECT KeyObject;
PKEY_CELL KeyCell;
ULONG NameSize, ClassSize;
@ -1662,11 +1568,10 @@ NtQueryKey(IN HANDLE KeyHandle,
if (ClassSize != 0)
{
ClassCell = CmiGetCell (KeyObject->RegistryHive,
KeyCell->ClassNameOffset,
NULL);
ClassCell = HvGetCell (KeyObject->RegistryHive->Hive,
KeyCell->ClassNameOffset);
RtlCopyMemory (NodeInformation->Name + KeyObject->Name.Length,
ClassCell->Data,
ClassCell,
ClassSize);
}
}
@ -1710,11 +1615,10 @@ NtQueryKey(IN HANDLE KeyHandle,
if (ClassSize)
{
ClassCell = CmiGetCell (KeyObject->RegistryHive,
KeyCell->ClassNameOffset,
NULL);
ClassCell = HvGetCell (KeyObject->RegistryHive->Hive,
KeyCell->ClassNameOffset);
RtlCopyMemory (FullInformation->Class,
ClassCell->Data, ClassSize);
ClassCell, ClassSize);
}
}
break;
@ -1755,10 +1659,10 @@ NtQueryValueKey(IN HANDLE KeyHandle,
NTSTATUS Status;
ULONG NameSize, DataSize;
PKEY_OBJECT KeyObject;
PREGISTRY_HIVE RegistryHive;
PEREGISTRY_HIVE RegistryHive;
PKEY_CELL KeyCell;
PVALUE_CELL ValueCell;
PDATA_CELL DataCell;
PVOID DataCell;
PKEY_VALUE_BASIC_INFORMATION ValueBasicInformation;
PKEY_VALUE_PARTIAL_INFORMATION ValuePartialInformation;
PKEY_VALUE_FULL_INFORMATION ValueFullInformation;
@ -1896,9 +1800,9 @@ NtQueryValueKey(IN HANDLE KeyHandle,
if (!(ValueCell->DataSize & REG_DATA_IN_OFFSET))
{
DataCell = CmiGetCell (RegistryHive, ValueCell->DataOffset, NULL);
DataCell = HvGetCell (RegistryHive->Hive, ValueCell->DataOffset);
RtlCopyMemory(ValuePartialInformation->Data,
DataCell->Data,
DataCell,
DataSize);
}
else
@ -1971,10 +1875,10 @@ NtQueryValueKey(IN HANDLE KeyHandle,
}
if (!(ValueCell->DataSize & REG_DATA_IN_OFFSET))
{
DataCell = CmiGetCell (RegistryHive, ValueCell->DataOffset, NULL);
DataCell = HvGetCell (RegistryHive->Hive, ValueCell->DataOffset);
RtlCopyMemory((PCHAR) ValueFullInformation
+ ValueFullInformation->DataOffset,
DataCell->Data,
DataCell,
DataSize);
}
else
@ -2015,12 +1919,11 @@ NtSetValueKey(IN HANDLE KeyHandle,
{
NTSTATUS Status;
PKEY_OBJECT KeyObject;
PREGISTRY_HIVE RegistryHive;
PEREGISTRY_HIVE RegistryHive;
PKEY_CELL KeyCell;
PVALUE_CELL ValueCell;
BLOCK_OFFSET ValueCellOffset;
PDATA_CELL DataCell;
PDATA_CELL NewDataCell;
HCELL_INDEX ValueCellOffset;
PVOID DataCell;
ULONG DesiredAccess;
REG_SET_VALUE_KEY_INFORMATION SetValueKeyInfo;
REG_POST_OPERATION_INFORMATION PostOperationInfo;
@ -2101,8 +2004,8 @@ NtSetValueKey(IN HANDLE KeyHandle,
if (!(ValueCell->DataSize & REG_DATA_IN_OFFSET) &&
(ValueCell->DataSize & REG_DATA_SIZE_MASK) != 0)
{
DataCell = CmiGetCell (RegistryHive, ValueCell->DataOffset, NULL);
DataCellSize = (DataCell->CellSize < 0 ? -DataCell->CellSize : DataCell->CellSize) - sizeof(CELL_HEADER);
DataCell = HvGetCell (RegistryHive->Hive, ValueCell->DataOffset);
DataCellSize = -HvGetCellSize (RegistryHive->Hive, DataCell);
}
else
{
@ -2111,19 +2014,19 @@ NtSetValueKey(IN HANDLE KeyHandle,
}
if (DataSize <= sizeof(BLOCK_OFFSET))
if (DataSize <= sizeof(HCELL_INDEX))
{
/* If data size <= sizeof(BLOCK_OFFSET) then store data in the data offset */
/* If data size <= sizeof(HCELL_INDEX) then store data in the data offset */
DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
if (DataCell)
{
CmiDestroyCell(RegistryHive, DataCell, ValueCell->DataOffset);
HvFreeCell(RegistryHive->Hive, ValueCell->DataOffset);
}
RtlCopyMemory(&ValueCell->DataOffset, Data, DataSize);
ValueCell->DataSize = DataSize | REG_DATA_IN_OFFSET;
ValueCell->DataType = Type;
CmiMarkBlockDirty(RegistryHive, ValueCellOffset);
HvMarkCellDirty(RegistryHive->Hive, ValueCellOffset);
}
else
{
@ -2133,15 +2036,12 @@ NtSetValueKey(IN HANDLE KeyHandle,
* New data size is larger than the current, destroy current
* data block and allocate a new one.
*/
BLOCK_OFFSET NewOffset;
HCELL_INDEX NewOffset;
DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
Status = CmiAllocateCell (RegistryHive,
sizeof(CELL_HEADER) + DataSize,
(PVOID *)&NewDataCell,
&NewOffset);
if (!NT_SUCCESS(Status))
NewOffset = HvAllocateCell (RegistryHive->Hive, DataSize, HvStable);
if (NewOffset == HCELL_NULL)
{
DPRINT("CmiAllocateBlock() failed (Status %lx)\n", Status);
@ -2156,18 +2056,18 @@ NtSetValueKey(IN HANDLE KeyHandle,
if (DataCell)
{
CmiDestroyCell(RegistryHive, DataCell, ValueCell->DataOffset);
HvFreeCell(RegistryHive->Hive, ValueCell->DataOffset);
}
ValueCell->DataOffset = NewOffset;
DataCell = NewDataCell;
DataCell = HvGetCell(RegistryHive->Hive, NewOffset);
}
RtlCopyMemory(DataCell->Data, Data, DataSize);
RtlCopyMemory(DataCell, Data, DataSize);
ValueCell->DataSize = DataSize & REG_DATA_SIZE_MASK;
ValueCell->DataType = Type;
CmiMarkBlockDirty(RegistryHive, ValueCell->DataOffset);
CmiMarkBlockDirty(RegistryHive, ValueCellOffset);
HvMarkCellDirty(RegistryHive->Hive, ValueCell->DataOffset);
HvMarkCellDirty(RegistryHive->Hive, ValueCellOffset);
}
/* Mark link key */
@ -2178,7 +2078,7 @@ NtSetValueKey(IN HANDLE KeyHandle,
}
KeQuerySystemTime (&KeyCell->LastWriteTime);
CmiMarkBlockDirty (RegistryHive, KeyObject->KeyCellOffset);
HvMarkCellDirty (RegistryHive->Hive, KeyObject->KeyCellOffset);
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
@ -2254,7 +2154,7 @@ Fail:
ValueName);
KeQuerySystemTime (&KeyObject->KeyCell->LastWriteTime);
CmiMarkBlockDirty (KeyObject->RegistryHive, KeyObject->KeyCellOffset);
HvMarkCellDirty (KeyObject->RegistryHive->Hive, KeyObject->KeyCellOffset);
/* Release hive lock */
ExReleaseResourceLite(&CmiRegistryLock);
@ -2467,10 +2367,10 @@ NtQueryMultipleValueKey (IN HANDLE KeyHandle,
IN OUT PULONG Length,
OUT PULONG ReturnLength)
{
PREGISTRY_HIVE RegistryHive;
PEREGISTRY_HIVE RegistryHive;
PVALUE_CELL ValueCell;
PKEY_OBJECT KeyObject;
PDATA_CELL DataCell;
PVOID DataCell;
ULONG BufferLength = 0;
PKEY_CELL KeyCell;
NTSTATUS Status;
@ -2555,11 +2455,9 @@ NtQueryMultipleValueKey (IN HANDLE KeyHandle,
if (!(ValueCell->DataSize & REG_DATA_IN_OFFSET))
{
DataCell = CmiGetCell (RegistryHive,
ValueCell->DataOffset,
NULL);
RtlCopyMemory(DataPtr,
DataCell->Data,
DataCell = HvGetCell (RegistryHive->Hive,
ValueCell->DataOffset);
RtlCopyMemory(DataPtr, DataCell,
ValueCell->DataSize & REG_DATA_SIZE_MASK);
}
else
@ -2623,7 +2521,7 @@ NTSTATUS STDCALL
NtSaveKey (IN HANDLE KeyHandle,
IN HANDLE FileHandle)
{
PREGISTRY_HIVE TempHive;
PEREGISTRY_HIVE TempHive;
PKEY_OBJECT KeyObject;
NTSTATUS Status;
@ -2653,7 +2551,7 @@ NtSaveKey (IN HANDLE KeyHandle,
ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
/* Refuse to save a volatile key */
if (KeyObject->RegistryHive == CmiVolatileHive)
if (KeyObject->KeyCell->Flags & REG_KEY_VOLATILE_CELL)
{
DPRINT1 ("Cannot save a volatile key\n");
ExReleaseResourceLite(&CmiRegistryLock);
@ -2781,8 +2679,8 @@ NtSetInformationKey (IN HANDLE KeyHandle,
KeyObject->KeyCell->LastWriteTime.QuadPart =
((PKEY_WRITE_TIME_INFORMATION)KeyInformation)->LastWriteTime.QuadPart;
CmiMarkBlockDirty (KeyObject->RegistryHive,
KeyObject->KeyCellOffset);
HvMarkCellDirty (KeyObject->RegistryHive->Hive,
KeyObject->KeyCellOffset);
/* Release hive lock */
ExReleaseResourceLite(&CmiRegistryLock);
@ -2813,7 +2711,7 @@ NtSetInformationKey (IN HANDLE KeyHandle,
NTSTATUS STDCALL
NtUnloadKey (IN POBJECT_ATTRIBUTES KeyObjectAttributes)
{
PREGISTRY_HIVE RegistryHive;
PEREGISTRY_HIVE RegistryHive;
NTSTATUS Status;
PAGED_CODE();

File diff suppressed because it is too large Load diff

View file

@ -28,7 +28,7 @@
/* GLOBALS ******************************************************************/
POBJECT_TYPE CmiKeyType = NULL;
PREGISTRY_HIVE CmiVolatileHive = NULL;
PEREGISTRY_HIVE CmiVolatileHive = NULL;
LIST_ENTRY CmiHiveListHead;
@ -67,193 +67,6 @@ extern FAST_MUTEX CmiCallbackLock;
/* FUNCTIONS ****************************************************************/
VOID
CmiCheckSubKeys(BOOLEAN Verbose,
HANDLE Key)
{
OBJECT_ATTRIBUTES ObjectAttributes;
PKEY_NODE_INFORMATION KeyInfo;
WCHAR KeyBuffer[MAX_PATH];
UNICODE_STRING KeyPath;
WCHAR Name[MAX_PATH];
ULONG BufferSize;
ULONG ResultSize;
NTSTATUS Status;
HANDLE SubKey;
ULONG Index;
Index = 0;
while (TRUE)
{
BufferSize = sizeof(KEY_NODE_INFORMATION) + 4096;
KeyInfo = ExAllocatePool(PagedPool, BufferSize);
Status = ZwEnumerateKey(Key,
Index,
KeyNodeInformation,
KeyInfo,
BufferSize,
&ResultSize);
if (!NT_SUCCESS(Status))
{
ExFreePool(KeyInfo);
if (Status == STATUS_NO_MORE_ENTRIES)
Status = STATUS_SUCCESS;
break;
}
wcsncpy(Name,
KeyInfo->Name,
KeyInfo->NameLength / sizeof(WCHAR));
if (Verbose)
{
DbgPrint("Key: %S\n", Name);
}
/* FIXME: Check info. */
ExFreePool(KeyInfo);
wcscpy(KeyBuffer, L"\\Registry\\");
wcscat(KeyBuffer, Name);
RtlInitUnicodeString(&KeyPath, KeyBuffer);
InitializeObjectAttributes(&ObjectAttributes,
&KeyPath,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = ZwOpenKey(&SubKey,
KEY_ALL_ACCESS,
&ObjectAttributes);
ASSERT(NT_SUCCESS(Status));
CmiCheckKey(Verbose, SubKey);
ZwClose(SubKey);
Index++;
}
ASSERT(NT_SUCCESS(Status));
}
VOID
CmiCheckValues(BOOLEAN Verbose,
HANDLE Key)
{
PKEY_NODE_INFORMATION ValueInfo;
WCHAR Name[MAX_PATH];
ULONG BufferSize;
ULONG ResultSize;
NTSTATUS Status;
ULONG Index;
Index = 0;
while (TRUE)
{
BufferSize = sizeof(KEY_NODE_INFORMATION) + 4096;
ValueInfo = ExAllocatePool(PagedPool, BufferSize);
Status = ZwEnumerateValueKey(Key,
Index,
KeyNodeInformation,
ValueInfo,
BufferSize,
&ResultSize);
if (!NT_SUCCESS(Status))
{
ExFreePool(ValueInfo);
if (Status == STATUS_NO_MORE_ENTRIES)
Status = STATUS_SUCCESS;
break;
}
wcsncpy(Name,
ValueInfo->Name,
ValueInfo->NameLength / sizeof(WCHAR));
if (Verbose)
{
DbgPrint("Value: %S\n", Name);
}
/* FIXME: Check info. */
ExFreePool(ValueInfo);
Index++;
}
ASSERT(NT_SUCCESS(Status));
}
VOID
CmiCheckKey(BOOLEAN Verbose,
HANDLE Key)
{
CmiCheckValues(Verbose, Key);
CmiCheckSubKeys(Verbose, Key);
}
VOID
CmiCheckByName(BOOLEAN Verbose,
PWSTR KeyName)
{
OBJECT_ATTRIBUTES ObjectAttributes;
WCHAR KeyPathBuffer[MAX_PATH];
UNICODE_STRING KeyPath;
NTSTATUS Status;
HANDLE Key;
wcscpy(KeyPathBuffer, L"\\Registry\\");
wcscat(KeyPathBuffer, KeyName);
RtlInitUnicodeString(&KeyPath, KeyPathBuffer);
InitializeObjectAttributes(&ObjectAttributes,
&KeyPath,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = ZwOpenKey(&Key,
KEY_ALL_ACCESS,
&ObjectAttributes);
if (CHECKED)
{
if (!NT_SUCCESS(Status))
{
DbgPrint("KeyPath %wZ Status: %.08x", KeyPath, Status);
DbgPrint("KeyPath %S Status: %.08x", KeyPath.Buffer, Status);
ASSERT(NT_SUCCESS(Status));
}
}
CmiCheckKey(Verbose, Key);
ZwClose(Key);
}
VOID
CmiCheckRegistry(BOOLEAN Verbose)
{
if (Verbose)
DbgPrint("Checking registry internals\n");
CmiCheckByName(Verbose, L"Machine");
CmiCheckByName(Verbose, L"User");
}
VOID STDCALL
CmiWorkerThread(PVOID Param)
{
@ -315,6 +128,7 @@ CmiWorkerThread(PVOID Param)
}
}
VOID
INIT_FUNCTION
STDCALL
@ -436,8 +250,8 @@ CmInitializeRegistry(VOID)
&RootKeyHandle);
ASSERT(NT_SUCCESS(Status));
RootKey->RegistryHive = CmiVolatileHive;
RootKey->KeyCellOffset = CmiVolatileHive->HiveHeader->RootKeyOffset;
RootKey->KeyCell = CmiGetCell (CmiVolatileHive, RootKey->KeyCellOffset, NULL);
RootKey->KeyCellOffset = CmiVolatileHive->Hive->HiveHeader->RootCell;
RootKey->KeyCell = HvGetCell (CmiVolatileHive->Hive, RootKey->KeyCellOffset);
RootKey->ParentKey = RootKey;
RootKey->Flags = 0;
RootKey->NumberOfSubKeys = 0;
@ -698,7 +512,7 @@ CmiCreateCurrentControlSetLink(VOID)
NTSTATUS
CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
IN PREGISTRY_HIVE RegistryHive)
IN PEREGISTRY_HIVE RegistryHive)
{
UNICODE_STRING RemainingPath;
PKEY_OBJECT ParentKey;
@ -791,34 +605,50 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
0,
NULL,
NULL);
DPRINT("Status %x\n", Status);
NewKey->RegistryHive = RegistryHive;
NewKey->KeyCellOffset = RegistryHive->HiveHeader->RootKeyOffset;
NewKey->KeyCell = CmiGetCell (RegistryHive, NewKey->KeyCellOffset, NULL);
NewKey->Flags = 0;
NewKey->NumberOfSubKeys = 0;
NewKey->SubKeys = NULL;
InsertTailList(&CmiKeyObjectListHead, &NewKey->ListEntry);
InsertTailList(&CmiConnectedHiveList, &NewKey->HiveList);
DPRINT("Status %x\n", Status);
NewKey->Flags = 0;
NewKey->NumberOfSubKeys = 0;
NewKey->SubKeys = NULL;
NewKey->SizeOfSubKeys = 0;
InsertTailList(&CmiKeyObjectListHead, &NewKey->ListEntry);
DPRINT ("SubName %S\n", SubName);
DPRINT ("SubName %S\n", SubName);
Status = RtlpCreateUnicodeString(&NewKey->Name,
SubName, NonPagedPool);
RtlFreeUnicodeString(&RemainingPath);
if (!NT_SUCCESS(Status))
{
DPRINT1("RtlpCreateUnicodeString() failed (Status %lx)\n", Status);
if (NewKey->SubKeys != NULL)
{
ExFreePool (NewKey->SubKeys);
}
ObDereferenceObject (NewKey);
ObDereferenceObject (ParentKey);
return STATUS_INSUFFICIENT_RESOURCES;
}
Status = CmiAddSubKey(ParentKey->RegistryHive,
ParentKey,
NewKey,
&RemainingPath,
0,
NULL,
REG_OPTION_VOLATILE);
if (!NT_SUCCESS(Status))
{
DPRINT1("CmiAddSubKey() failed (Status %lx)\n", Status);
ObDereferenceObject (NewKey);
ObDereferenceObject (ParentKey);
return STATUS_INSUFFICIENT_RESOURCES;
}
CmiAddKeyToList (ParentKey, NewKey);
NewKey->KeyCellOffset = RegistryHive->Hive->HiveHeader->RootCell;
NewKey->KeyCell = HvGetCell (RegistryHive->Hive, NewKey->KeyCellOffset);
NewKey->RegistryHive = RegistryHive;
Status = RtlpCreateUnicodeString(&NewKey->Name,
SubName, NonPagedPool);
RtlFreeUnicodeString(&RemainingPath);
if (!NT_SUCCESS(Status))
{
DPRINT1("RtlpCreateUnicodeString() failed (Status %lx)\n", Status);
ObDereferenceObject (NewKey);
ObDereferenceObject (ParentKey);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* FN1 */
ObReferenceObject (NewKey);
CmiAddKeyToList (ParentKey, NewKey);
ObDereferenceObject (ParentKey);
VERIFY_KEY_OBJECT(NewKey);
@ -832,9 +662,10 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
NTSTATUS
CmiDisconnectHive (IN POBJECT_ATTRIBUTES KeyObjectAttributes,
OUT PREGISTRY_HIVE *RegistryHive)
OUT PEREGISTRY_HIVE *RegistryHive)
{
PKEY_OBJECT KeyObject;
PEREGISTRY_HIVE Hive;
HANDLE KeyHandle;
NTSTATUS Status = STATUS_OBJECT_NAME_NOT_FOUND;
PLIST_ENTRY CurrentEntry;
@ -876,25 +707,47 @@ CmiDisconnectHive (IN POBJECT_ATTRIBUTES KeyObjectAttributes,
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
/* Find out if we represent a connected hive. */
for( CurrentEntry = CmiConnectedHiveList.Flink;
CurrentEntry != &CmiConnectedHiveList;
CurrentEntry = CurrentEntry->Flink ) {
CurrentKey = CONTAINING_RECORD(CurrentEntry, KEY_OBJECT, HiveList);
if( CurrentKey == KeyObject ) {
/* Remove the connected hive from the connected hive list */
RemoveEntryList(CurrentEntry);
/* found ourselves in the connected hive list */
*RegistryHive = KeyObject->RegistryHive;
Status = STATUS_SUCCESS;
Hive = KeyObject->RegistryHive;
/* Release references captured in CmiConnectHive */
ObDereferenceObject (KeyObject->ParentKey);
ObDereferenceObject (KeyObject);
break;
}
CurrentEntry = CmiKeyObjectListHead.Flink;
while (CurrentEntry != &CmiKeyObjectListHead)
{
CurrentKey = CONTAINING_RECORD(CurrentEntry, KEY_OBJECT, ListEntry);
if (CurrentKey->RegistryHive == Hive &&
1 == ObGetObjectPointerCount(CurrentKey) &&
!(CurrentKey->Flags & KO_MARKED_FOR_DELETE))
{
ObDereferenceObject(CurrentKey);
CurrentEntry = CmiKeyObjectListHead.Flink;
}
else
{
CurrentEntry = CurrentEntry->Flink;
}
}
/* FN1 */
ObDereferenceObject (KeyObject);
if (ObGetObjectHandleCount (KeyObject) != 0 ||
ObGetObjectPointerCount (KeyObject) != 2)
{
DPRINT1 ("Hive is still in use (hc %d, rc %d)\n", ObGetObjectHandleCount (KeyObject), ObGetObjectPointerCount (KeyObject));
ObDereferenceObject (KeyObject);
/* Release registry lock */
ExReleaseResourceLite (&CmiRegistryLock);
KeLeaveCriticalRegion();
return STATUS_UNSUCCESSFUL;
}
/* Dereference KeyObject twice to delete it */
ObDereferenceObject (KeyObject);
ObDereferenceObject (KeyObject);
*RegistryHive = Hive;
/* Release registry lock */
ExReleaseResourceLite (&CmiRegistryLock);
KeLeaveCriticalRegion();
@ -1050,8 +903,6 @@ CmiInitHives(BOOLEAN SetupBoot)
EndPtr = ConfigPath + wcslen(ConfigPath);
CmiDoVerify = TRUE;
/* FIXME: Save boot log */
/* Connect the SYSTEM hive only if it has been created */
@ -1194,7 +1045,7 @@ CmiInitHives(BOOLEAN SetupBoot)
VOID
CmShutdownRegistry(VOID)
{
PREGISTRY_HIVE Hive;
PEREGISTRY_HIVE Hive;
PLIST_ENTRY Entry;
DPRINT("CmShutdownRegistry() called\n");
@ -1216,7 +1067,7 @@ CmShutdownRegistry(VOID)
Entry = CmiHiveListHead.Flink;
while (Entry != &CmiHiveListHead)
{
Hive = CONTAINING_RECORD(Entry, REGISTRY_HIVE, HiveList);
Hive = CONTAINING_RECORD(Entry, EREGISTRY_HIVE, HiveList);
if (!(IsNoFileHive(Hive) || IsNoSynchHive(Hive)))
{
@ -1238,7 +1089,7 @@ CmShutdownRegistry(VOID)
VOID STDCALL
CmiHiveSyncRoutine(PVOID DeferredContext)
{
PREGISTRY_HIVE Hive;
PEREGISTRY_HIVE Hive;
PLIST_ENTRY Entry;
DPRINT("CmiHiveSyncRoutine() called\n");
@ -1252,7 +1103,7 @@ CmiHiveSyncRoutine(PVOID DeferredContext)
Entry = CmiHiveListHead.Flink;
while (Entry != &CmiHiveListHead)
{
Hive = CONTAINING_RECORD(Entry, REGISTRY_HIVE, HiveList);
Hive = CONTAINING_RECORD(Entry, EREGISTRY_HIVE, HiveList);
if (!(IsNoFileHive(Hive) || IsNoSynchHive(Hive)))
{

View file

@ -18,7 +18,7 @@ extern LIST_ENTRY CmiKeyObjectListHead;
extern ULONG CmiTimer;
static NTSTATUS
CmiGetLinkTarget(PREGISTRY_HIVE RegistryHive,
CmiGetLinkTarget(PEREGISTRY_HIVE RegistryHive,
PKEY_CELL KeyCell,
PUNICODE_STRING TargetPath);
@ -233,7 +233,7 @@ CmiObjectParse(IN PVOID ParsedObject,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
OUT PVOID *NextObject)
{
BLOCK_OFFSET BlockOffset;
HCELL_INDEX BlockOffset;
PKEY_OBJECT FoundObject;
PKEY_OBJECT ParsedKey;
PKEY_CELL SubKeyCell;
@ -285,7 +285,6 @@ CmiObjectParse(IN PVOID ParsedObject,
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
Status = CmiScanKeyList(ParsedKey,
&KeyName,
Attributes,
@ -300,93 +299,93 @@ CmiObjectParse(IN PVOID ParsedObject,
if (FoundObject == NULL)
{
Status = CmiScanForSubKey(ParsedKey->RegistryHive,
ParsedKey->KeyCell,
&SubKeyCell,
&BlockOffset,
&KeyName,
0,
Attributes);
if (!NT_SUCCESS(Status) || (SubKeyCell == NULL))
{
ParsedKey->KeyCell,
&SubKeyCell,
&BlockOffset,
&KeyName,
0,
Attributes);
if (!NT_SUCCESS(Status))
{
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
RtlFreeUnicodeString(&KeyName);
return(STATUS_UNSUCCESSFUL);
}
RtlFreeUnicodeString(&KeyName);
return(STATUS_UNSUCCESSFUL);
}
if ((SubKeyCell->Flags & REG_KEY_LINK_CELL) &&
!((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)))
{
RtlInitUnicodeString(&LinkPath, NULL);
Status = CmiGetLinkTarget(ParsedKey->RegistryHive,
SubKeyCell,
&LinkPath);
if (NT_SUCCESS(Status))
{
!((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)))
{
RtlInitUnicodeString(&LinkPath, NULL);
Status = CmiGetLinkTarget(ParsedKey->RegistryHive,
SubKeyCell,
&LinkPath);
if (NT_SUCCESS(Status))
{
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
DPRINT("LinkPath '%wZ'\n", &LinkPath);
DPRINT("LinkPath '%wZ'\n", &LinkPath);
/* build new FullPath for reparsing */
TargetPath.MaximumLength = LinkPath.MaximumLength;
if (EndPtr != NULL)
{
TargetPath.MaximumLength += (wcslen(EndPtr) * sizeof(WCHAR));
}
TargetPath.Length = TargetPath.MaximumLength - sizeof(WCHAR);
TargetPath.Buffer = ExAllocatePool(NonPagedPool,
TargetPath.MaximumLength);
wcscpy(TargetPath.Buffer, LinkPath.Buffer);
if (EndPtr != NULL)
{
wcscat(TargetPath.Buffer, EndPtr);
}
/* build new FullPath for reparsing */
TargetPath.MaximumLength = LinkPath.MaximumLength;
if (EndPtr != NULL)
{
TargetPath.MaximumLength += (wcslen(EndPtr) * sizeof(WCHAR));
}
TargetPath.Length = TargetPath.MaximumLength - sizeof(WCHAR);
TargetPath.Buffer = ExAllocatePool(NonPagedPool,
TargetPath.MaximumLength);
wcscpy(TargetPath.Buffer, LinkPath.Buffer);
if (EndPtr != NULL)
{
wcscat(TargetPath.Buffer, EndPtr);
}
RtlFreeUnicodeString(FullPath);
RtlFreeUnicodeString(&LinkPath);
FullPath->Length = TargetPath.Length;
FullPath->MaximumLength = TargetPath.MaximumLength;
FullPath->Buffer = TargetPath.Buffer;
RtlFreeUnicodeString(FullPath);
RtlFreeUnicodeString(&LinkPath);
FullPath->Length = TargetPath.Length;
FullPath->MaximumLength = TargetPath.MaximumLength;
FullPath->Buffer = TargetPath.Buffer;
DPRINT("FullPath '%wZ'\n", FullPath);
DPRINT("FullPath '%wZ'\n", FullPath);
/* reinitialize Path for reparsing */
*Path = FullPath->Buffer;
/* reinitialize Path for reparsing */
*Path = FullPath->Buffer;
*NextObject = NULL;
*NextObject = NULL;
RtlFreeUnicodeString(&KeyName);
return(STATUS_REPARSE);
}
}
RtlFreeUnicodeString(&KeyName);
return(STATUS_REPARSE);
}
}
/* Create new key object and put into linked list */
DPRINT("CmiObjectParse: %S\n", *Path);
Status = ObCreateObject(KernelMode,
CmiKeyType,
NULL,
KernelMode,
NULL,
sizeof(KEY_OBJECT),
0,
0,
(PVOID*)&FoundObject);
CmiKeyType,
NULL,
KernelMode,
NULL,
sizeof(KEY_OBJECT),
0,
0,
(PVOID*)&FoundObject);
if (!NT_SUCCESS(Status))
{
{
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
RtlFreeUnicodeString(&KeyName);
return(Status);
}
DPRINT("Inserting Key into Object Tree\n");
Status = ObInsertObject((PVOID)FoundObject,
NULL,
KEY_ALL_ACCESS,
0,
NULL,
NULL);
DPRINT("Status %x\n", Status);
RtlFreeUnicodeString(&KeyName);
return(Status);
}
DPRINT("Inserting Key into Object Tree\n");
Status = ObInsertObject((PVOID)FoundObject,
NULL,
KEY_ALL_ACCESS,
0,
NULL,
NULL);
DPRINT("Status %x\n", Status);
/* Add the keep-alive reference */
ObReferenceObject(FoundObject);
@ -396,8 +395,7 @@ CmiObjectParse(IN PVOID ParsedObject,
FoundObject->KeyCellOffset = BlockOffset;
FoundObject->RegistryHive = ParsedKey->RegistryHive;
InsertTailList(&CmiKeyObjectListHead, &FoundObject->ListEntry);
RtlpCreateUnicodeString(&FoundObject->Name,
KeyName.Buffer, NonPagedPool);
RtlpCreateUnicodeString(&FoundObject->Name, KeyName.Buffer, NonPagedPool);
CmiAddKeyToList(ParsedKey, FoundObject);
DPRINT("Created object 0x%p\n", FoundObject);
}
@ -462,7 +460,7 @@ CmiObjectParse(IN PVOID ParsedObject,
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
//DPRINT("CmiObjectParse: %s\n", FoundObject->Name);
DPRINT("CmiObjectParse: %wZ\n", &FoundObject->Name);
*Path = EndPtr;
@ -509,8 +507,8 @@ CmiObjectDelete(PVOID DeletedObject)
KeyObject);
KeQuerySystemTime (&ParentKeyObject->KeyCell->LastWriteTime);
CmiMarkBlockDirty (ParentKeyObject->RegistryHive,
ParentKeyObject->KeyCellOffset);
HvMarkCellDirty (ParentKeyObject->RegistryHive->Hive,
ParentKeyObject->KeyCellOffset);
if (!IsNoFileHive (KeyObject->RegistryHive) ||
!IsNoFileHive (ParentKeyObject->RegistryHive))
@ -521,9 +519,6 @@ CmiObjectDelete(PVOID DeletedObject)
ObDereferenceObject (ParentKeyObject);
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
if (KeyObject->NumberOfSubKeys)
{
KEBUGCHECK(REGISTRY_ERROR);
@ -533,6 +528,9 @@ CmiObjectDelete(PVOID DeletedObject)
{
ExFreePool(KeyObject->SubKeys);
}
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
}
@ -618,7 +616,7 @@ CmiAssignSecurityDescriptor(PKEY_OBJECT KeyObject,
PSECURITY_DESCRIPTOR SecurityDescriptor)
{
#if 0
PREGISTRY_HIVE Hive;
PEREGISTRY_HIVE Hive;
DPRINT1("CmiAssignSecurityDescriptor() callled\n");
@ -755,6 +753,7 @@ CmiObjectQueryName (PVOID ObjectBody,
}
VOID
CmiAddKeyToList(PKEY_OBJECT ParentKey,
PKEY_OBJECT NewKey)
@ -843,6 +842,7 @@ CmiScanKeyList(PKEY_OBJECT Parent,
CurKey = Parent->SubKeys[Index];
if (Attributes & OBJ_CASE_INSENSITIVE)
{
DPRINT("Comparing %wZ and %wZ\n", KeyName, &CurKey->Name);
if ((KeyName->Length == CurKey->Name.Length)
&& (_wcsicmp(KeyName->Buffer, CurKey->Name.Buffer) == 0))
{
@ -863,6 +863,7 @@ CmiScanKeyList(PKEY_OBJECT Parent,
{
if (CurKey->Flags & KO_MARKED_FOR_DELETE)
{
CHECKPOINT;
*ReturnedObject = NULL;
return STATUS_UNSUCCESSFUL;
}
@ -878,13 +879,13 @@ CmiScanKeyList(PKEY_OBJECT Parent,
static NTSTATUS
CmiGetLinkTarget(PREGISTRY_HIVE RegistryHive,
CmiGetLinkTarget(PEREGISTRY_HIVE RegistryHive,
PKEY_CELL KeyCell,
PUNICODE_STRING TargetPath)
{
UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"SymbolicLinkValue");
PVALUE_CELL ValueCell;
PDATA_CELL DataCell;
PVOID DataCell;
NTSTATUS Status;
DPRINT("CmiGetLinkTarget() called\n");
@ -920,9 +921,9 @@ CmiGetLinkTarget(PREGISTRY_HIVE RegistryHive,
if (ValueCell->DataSize > 0)
{
DataCell = CmiGetCell (RegistryHive, ValueCell->DataOffset, NULL);
DataCell = HvGetCell (RegistryHive->Hive, ValueCell->DataOffset);
RtlCopyMemory(TargetPath->Buffer,
DataCell->Data,
DataCell,
TargetPath->Length);
TargetPath->Buffer[TargetPath->Length / sizeof(WCHAR)] = 0;
}

View file

@ -8,12 +8,14 @@
<define name="__NO_CTYPE_INLINES" />
<define name="__USE_W32API" />
<include base="kjs">include</include>
<include base="cmlib">.</include>
<include base="ntoskrnl">include</include>
<include base="ReactOS">include/reactos/drivers</include>
<library>csq</library>
<library>hal</library>
<library>kjs</library>
<library>pseh</library>
<library>cmlib</library>
<library>rtl</library>
<library>rossym</library>
<library>string</library>