mirror of
https://github.com/reactos/reactos.git
synced 2024-08-07 19:58:21 +00:00
Configuration manager cleanup.
Added consistency checks. svn path=/trunk/; revision=2716
This commit is contained in:
parent
bcc0a8a082
commit
190f4b2256
|
@ -1,7 +1,12 @@
|
|||
|
||||
#ifndef __INCLUDE_CM_H
|
||||
#define __INCLUDE_CM_H
|
||||
|
||||
#ifdef DBG
|
||||
#define CHECKED 1
|
||||
#else
|
||||
#define CHECKED 0
|
||||
#endif
|
||||
|
||||
#define REG_ROOT_KEY_NAME L"\\Registry"
|
||||
#define REG_MACHINE_KEY_NAME L"\\Registry\\Machine"
|
||||
#define REG_HARDWARE_KEY_NAME L"\\Registry\\Machine\\HARDWARE"
|
||||
|
@ -31,68 +36,139 @@
|
|||
#define REG_DYN_STD_HANDLE_NAME "HKEY_DYN_DATA"
|
||||
#define MAX_REG_STD_HANDLE_NAME 19
|
||||
|
||||
#define KO_MARKED_FOR_DELETE 0x00000001
|
||||
|
||||
// BLOCK_OFFSET = offset in file after header block
|
||||
typedef DWORD BLOCK_OFFSET;
|
||||
typedef DWORD BLOCK_OFFSET;
|
||||
|
||||
/* header for registry hive file : */
|
||||
typedef struct _HEADER_BLOCK
|
||||
typedef struct _HIVE_HEADER
|
||||
{
|
||||
ULONG BlockId; /* ="regf" */
|
||||
ULONG Version; /* file version ?*/
|
||||
ULONG VersionOld; /* file version ?*/
|
||||
FILETIME DateModified; /* please don't replace with LARGE_INTEGER !*/
|
||||
ULONG Unused3; /* registry format version ? */
|
||||
ULONG Unused4; /* registry format version ? */
|
||||
ULONG Unused5; /* registry format version ? */
|
||||
ULONG Unused6; /* registry format version ? */
|
||||
BLOCK_OFFSET RootKeyBlock;
|
||||
/* Hive identifier "regf" (0x66676572) */
|
||||
ULONG BlockId;
|
||||
|
||||
/* File version ? */
|
||||
ULONG Version;
|
||||
|
||||
/* File version ? - same as Version */
|
||||
ULONG VersionOld;
|
||||
|
||||
/* When this hive file was last modified */
|
||||
FILETIME DateModified;
|
||||
|
||||
/* Registry format version ? (1?) */
|
||||
ULONG Unused3;
|
||||
|
||||
/* Registry format version ? (3?) */
|
||||
ULONG Unused4;
|
||||
|
||||
/* Registry format version ? (0?) */
|
||||
ULONG Unused5;
|
||||
|
||||
/* Registry format version ? (1?) */
|
||||
ULONG Unused6;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Size of each hive block ? */
|
||||
ULONG BlockSize;
|
||||
|
||||
/* (1?) */
|
||||
ULONG Unused7;
|
||||
WCHAR FileName[64]; /* end of file name */
|
||||
|
||||
/* Name of hive file */
|
||||
WCHAR FileName[64];
|
||||
|
||||
/* ? */
|
||||
ULONG Unused8[83];
|
||||
|
||||
/* Checksum of first 0x200 bytes */
|
||||
ULONG Checksum;
|
||||
} HEADER_BLOCK, *PHEADER_BLOCK;
|
||||
} __attribute__((packed)) HIVE_HEADER, *PHIVE_HEADER;
|
||||
|
||||
typedef struct _HEAP_BLOCK
|
||||
typedef struct _HBIN
|
||||
{
|
||||
ULONG BlockId; /* = "hbin" */
|
||||
BLOCK_OFFSET BlockOffset; /* block offset of this heap */
|
||||
ULONG BlockSize; /* size in bytes, 4k multiple */
|
||||
/* Bin identifier "hbin" (0x6E696268) */
|
||||
ULONG BlockId;
|
||||
|
||||
/* Block offset of this bin */
|
||||
BLOCK_OFFSET BlockOffset;
|
||||
|
||||
/* Size in bytes, multiple of the block size (4KB) */
|
||||
ULONG BlockSize;
|
||||
|
||||
/* ? */
|
||||
ULONG Unused1;
|
||||
FILETIME DateModified; /* please don't replace with LARGE_INTEGER !*/
|
||||
|
||||
/* When this bin was last modified */
|
||||
FILETIME DateModified;
|
||||
|
||||
/* ? */
|
||||
ULONG Unused2;
|
||||
} HEAP_BLOCK, *PHEAP_BLOCK;
|
||||
} __attribute__((packed)) HBIN, *PHBIN;
|
||||
|
||||
// each sub_block begin with this struct :
|
||||
// in a free subblock, higher bit of SubBlockSize is set
|
||||
typedef struct _FREE_SUB_BLOCK
|
||||
typedef struct _CELL_HEADER
|
||||
{
|
||||
LONG SubBlockSize;/* <0 if used, >0 if free */
|
||||
} FREE_SUB_BLOCK, *PFREE_SUB_BLOCK;
|
||||
/* <0 if used, >0 if free */
|
||||
LONG CellSize;
|
||||
} __attribute__((packed)) CELL_HEADER, *PCELL_HEADER;
|
||||
|
||||
typedef struct _KEY_BLOCK
|
||||
typedef struct _KEY_CELL
|
||||
{
|
||||
LONG SubBlockSize;
|
||||
USHORT SubBlockId;
|
||||
USHORT Type;
|
||||
FILETIME LastWriteTime; /* please don't replace with LARGE_INTEGER !*/
|
||||
/* Size of this cell */
|
||||
LONG CellSize;
|
||||
|
||||
/* Key cell identifier "kn" (0x6b6e) */
|
||||
USHORT Id;
|
||||
|
||||
/* ? */
|
||||
USHORT Type;
|
||||
|
||||
/* Time of last flush */
|
||||
FILETIME 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 ValuesOffset;
|
||||
|
||||
/* 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;
|
||||
USHORT ClassSize; /* size of ClassName in bytes */
|
||||
UCHAR Name[0]; /* warning : not zero terminated */
|
||||
} KEY_BLOCK, *PKEY_BLOCK;
|
||||
|
||||
/* Size of class name in bytes */
|
||||
USHORT ClassSize;
|
||||
|
||||
/* Name of key (not zero terminated) */
|
||||
UCHAR Name[0];
|
||||
} __attribute__((packed)) KEY_CELL, *PKEY_CELL;
|
||||
|
||||
// hash record :
|
||||
// HashValue=four letters of value's name
|
||||
|
@ -100,88 +176,158 @@ typedef struct _HASH_RECORD
|
|||
{
|
||||
BLOCK_OFFSET KeyOffset;
|
||||
ULONG HashValue;
|
||||
} HASH_RECORD, *PHASH_RECORD;
|
||||
} __attribute__((packed)) HASH_RECORD, *PHASH_RECORD;
|
||||
|
||||
typedef struct _HASH_TABLE_BLOCK
|
||||
typedef struct _HASH_TABLE_CELL
|
||||
{
|
||||
LONG SubBlockSize;
|
||||
USHORT SubBlockId;
|
||||
USHORT HashTableSize;
|
||||
LONG CellSize;
|
||||
USHORT Id;
|
||||
USHORT HashTableSize;
|
||||
HASH_RECORD Table[0];
|
||||
} HASH_TABLE_BLOCK, *PHASH_TABLE_BLOCK;
|
||||
} __attribute__((packed)) HASH_TABLE_CELL, *PHASH_TABLE_CELL;
|
||||
|
||||
typedef struct _VALUE_LIST_BLOCK
|
||||
typedef struct _VALUE_LIST_CELL
|
||||
{
|
||||
LONG SubBlockSize;
|
||||
LONG CellSize;
|
||||
BLOCK_OFFSET Values[0];
|
||||
} VALUE_LIST_BLOCK, *PVALUE_LIST_BLOCK;
|
||||
} __attribute__((packed)) VALUE_LIST_CELL, *PVALUE_LIST_CELL;
|
||||
|
||||
typedef struct _VALUE_BLOCK
|
||||
typedef struct _VALUE_CELL
|
||||
{
|
||||
LONG SubBlockSize;
|
||||
USHORT SubBlockId; // "kv"
|
||||
LONG CellSize;
|
||||
USHORT Id; // "kv"
|
||||
USHORT NameSize; // length of Name
|
||||
LONG DataSize; // length of datas in the subblock pointed by DataOffset
|
||||
LONG 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_BLOCK, *PVALUE_BLOCK;
|
||||
} __attribute__((packed)) VALUE_CELL, *PVALUE_CELL;
|
||||
|
||||
typedef struct _DATA_BLOCK
|
||||
typedef struct _DATA_CELL
|
||||
{
|
||||
LONG SubBlockSize;
|
||||
LONG CellSize;
|
||||
UCHAR Data[0];
|
||||
} DATA_BLOCK, *PDATA_BLOCK;
|
||||
} __attribute__((packed)) DATA_CELL, *PDATA_CELL;
|
||||
|
||||
typedef struct _REGISTRY_FILE
|
||||
typedef struct _REGISTRY_HIVE
|
||||
{
|
||||
PWSTR Filename;
|
||||
ULONG Flags;
|
||||
UNICODE_STRING Filename;
|
||||
ULONG FileSize;
|
||||
PFILE_OBJECT FileObject;
|
||||
PHEADER_BLOCK HeaderBlock;
|
||||
// ULONG NumberOfBlocks;
|
||||
PFILE_OBJECT FileObject;
|
||||
PVOID Bcb;
|
||||
PHIVE_HEADER HiveHeader;
|
||||
ULONG BlockListSize;
|
||||
PHEAP_BLOCK *BlockList;
|
||||
PHBIN *BlockList;
|
||||
ULONG FreeListSize;
|
||||
ULONG FreeListMax;
|
||||
PFREE_SUB_BLOCK *FreeList;
|
||||
PCELL_HEADER *FreeList;
|
||||
BLOCK_OFFSET *FreeListOffset;
|
||||
// KSPIN_LOCK RegLock;
|
||||
KSEMAPHORE RegSem;
|
||||
|
||||
|
||||
// NTSTATUS (*Extend)(ULONG NewSize);
|
||||
// PVOID (*Flush)(VOID);
|
||||
} REGISTRY_FILE, *PREGISTRY_FILE;
|
||||
} REGISTRY_HIVE, *PREGISTRY_HIVE;
|
||||
|
||||
/* Type defining the Object Manager Key Object */
|
||||
/* REGISTRY_HIVE.Flags constants */
|
||||
#define HIVE_VOLATILE 0x00000001
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
/* KEY_OBJECT.Flags */
|
||||
|
||||
/* When set, the key is sheduled for deletion, and all
|
||||
atempts to access the key must not succeed */
|
||||
#define KO_MARKED_FOR_DELETE 0x00000001
|
||||
|
||||
/* Type defining the Object Manager Key Object */
|
||||
typedef struct _KEY_OBJECT
|
||||
{
|
||||
CSHORT Type;
|
||||
CSHORT Size;
|
||||
|
||||
ULONG Flags;
|
||||
USHORT NameSize; // length of Name
|
||||
UCHAR *Name;
|
||||
PREGISTRY_FILE RegistryFile;
|
||||
/* Fields used by the Object Manager */
|
||||
CSHORT Type;
|
||||
CSHORT Size;
|
||||
|
||||
/* Key flags */
|
||||
ULONG Flags;
|
||||
|
||||
/* Length of Name */
|
||||
USHORT NameSize;
|
||||
|
||||
/* Name of key */
|
||||
PCHAR Name;
|
||||
|
||||
/* Registry hive the key belong to */
|
||||
PREGISTRY_HIVE RegistryHive;
|
||||
|
||||
/* Block offset of the key cell this key belong in */
|
||||
BLOCK_OFFSET BlockOffset;
|
||||
PKEY_BLOCK KeyBlock;
|
||||
struct _KEY_OBJECT *ParentKey;
|
||||
ULONG NumberOfSubKeys; /* subkeys loaded in SubKeys */
|
||||
ULONG SizeOfSubKeys; /* space allocated in SubKeys */
|
||||
struct _KEY_OBJECT **SubKeys; /* list of subkeys loaded */
|
||||
|
||||
/* KEY_CELL this key belong in */
|
||||
PKEY_CELL KeyCell;
|
||||
|
||||
/* Link to the parent KEY_OBJECT for this key */
|
||||
struct _KEY_OBJECT *ParentKey;
|
||||
|
||||
/* Subkeys loaded in SubKeys */
|
||||
ULONG NumberOfSubKeys;
|
||||
|
||||
/* Space allocated in SubKeys */
|
||||
ULONG SizeOfSubKeys;
|
||||
|
||||
/* List of subkeys loaded */
|
||||
struct _KEY_OBJECT **SubKeys;
|
||||
} KEY_OBJECT, *PKEY_OBJECT;
|
||||
|
||||
/* Bits 31-22 (top 10 bits) of the cell index is the directory index */
|
||||
#define CmiDirectoryIndex(CellIndex)(CellIndex & 0xffc000000)
|
||||
/* Bits 21-12 (middle 10 bits) of the cell index is the table index */
|
||||
#define CmiTableIndex(Cellndex)(CellIndex & 0x003ff000)
|
||||
/* Bits 11-0 (bottom 12 bits) of the cell index is the byte offset */
|
||||
#define CmiByteOffset(Cellndex)(CellIndex & 0x00000fff)
|
||||
|
||||
VOID
|
||||
CmiVerifyBinCell(PHBIN BinCell);
|
||||
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_CELL CmiVerifyBinCell
|
||||
#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_CELL(x)
|
||||
#define VERIFY_KEY_CELL(x)
|
||||
#define VERIFY_ROOT_KEY_CELL(x)
|
||||
#define VERIFY_VALUE_CELL(x)
|
||||
#define VERIFY_VALUE_LIST_CELL(x)
|
||||
#define VERIFY_KEY_OBJECT(x)
|
||||
#define VERIFY_REGISTRY_HIVE(x)
|
||||
#endif
|
||||
|
||||
NTSTATUS STDCALL
|
||||
CmiObjectParse(PVOID ParsedObject,
|
||||
PVOID *NextObject,
|
||||
PUNICODE_STRING FullPath,
|
||||
PWSTR *Path,
|
||||
POBJECT_TYPE ObjectType,
|
||||
ULONG Attribute);
|
||||
CmiObjectParse(IN PVOID ParsedObject,
|
||||
OUT PVOID *NextObject,
|
||||
IN PUNICODE_STRING FullPath,
|
||||
IN OUT PWSTR *Path,
|
||||
IN POBJECT_TYPE ObjectType,
|
||||
IN ULONG Attribute);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
CmiObjectCreate(PVOID ObjectBody,
|
||||
|
@ -192,91 +338,135 @@ CmiObjectCreate(PVOID ObjectBody,
|
|||
VOID STDCALL
|
||||
CmiObjectDelete(PVOID DeletedObject);
|
||||
|
||||
VOID CmiAddKeyToList(PKEY_OBJECT ParentKey,PKEY_OBJECT NewKey);
|
||||
NTSTATUS CmiRemoveKeyFromList(PKEY_OBJECT NewKey);
|
||||
PKEY_OBJECT CmiScanKeyList(PKEY_OBJECT Parent,
|
||||
PCHAR KeyNameBuf,
|
||||
ULONG Attributes);
|
||||
VOID
|
||||
CmiAddKeyToList(PKEY_OBJECT ParentKey,
|
||||
IN PKEY_OBJECT NewKey);
|
||||
|
||||
PREGISTRY_FILE CmiCreateRegistry(PWSTR Filename);
|
||||
|
||||
ULONG CmiGetMaxNameLength(PREGISTRY_FILE RegistryFile,
|
||||
PKEY_BLOCK KeyBlock);
|
||||
ULONG CmiGetMaxClassLength(PREGISTRY_FILE RegistryFile,
|
||||
PKEY_BLOCK KeyBlock);
|
||||
ULONG CmiGetMaxValueNameLength(PREGISTRY_FILE RegistryFile,
|
||||
PKEY_BLOCK KeyBlock);
|
||||
ULONG CmiGetMaxValueDataLength(PREGISTRY_FILE RegistryFile,
|
||||
PKEY_BLOCK KeyBlock);
|
||||
|
||||
NTSTATUS CmiScanForSubKey(IN PREGISTRY_FILE RegistryFile,
|
||||
IN PKEY_BLOCK KeyBlock,
|
||||
OUT PKEY_BLOCK *SubKeyBlock,
|
||||
OUT BLOCK_OFFSET *BlockOffset,
|
||||
IN PCHAR KeyName,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN ULONG Attributes);
|
||||
NTSTATUS CmiAddSubKey(IN PREGISTRY_FILE RegistryFile,
|
||||
IN PKEY_OBJECT Parent,
|
||||
OUT PKEY_OBJECT SubKey,
|
||||
IN PWSTR NewSubKeyName,
|
||||
IN USHORT NewSubKeyNameSize,
|
||||
IN ULONG TitleIndex,
|
||||
IN PUNICODE_STRING Class,
|
||||
IN ULONG CreateOptions);
|
||||
|
||||
NTSTATUS CmiScanKeyForValue(IN PREGISTRY_FILE RegistryFile,
|
||||
IN PKEY_BLOCK KeyBlock,
|
||||
IN PCHAR ValueName,
|
||||
OUT PVALUE_BLOCK *ValueBlock,
|
||||
OUT BLOCK_OFFSET *VBOffset);
|
||||
NTSTATUS CmiGetValueFromKeyByIndex(IN PREGISTRY_FILE RegistryFile,
|
||||
IN PKEY_BLOCK KeyBlock,
|
||||
IN ULONG Index,
|
||||
OUT PVALUE_BLOCK *ValueBlock);
|
||||
NTSTATUS CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
|
||||
IN PKEY_BLOCK KeyBlock,
|
||||
IN PCHAR ValueNameBuf,
|
||||
OUT PVALUE_BLOCK *pValueBlock,
|
||||
OUT BLOCK_OFFSET *pVBOffset);
|
||||
NTSTATUS CmiDeleteValueFromKey(IN PREGISTRY_FILE RegistryFile,
|
||||
IN PKEY_BLOCK KeyBlock,
|
||||
IN PCHAR ValueName);
|
||||
|
||||
NTSTATUS CmiAllocateHashTableBlock(IN PREGISTRY_FILE RegistryFile,
|
||||
OUT PHASH_TABLE_BLOCK *HashBlock,
|
||||
OUT BLOCK_OFFSET *HBOffset,
|
||||
IN ULONG HashTableSize);
|
||||
PKEY_BLOCK CmiGetKeyFromHashByIndex(PREGISTRY_FILE RegistryFile,
|
||||
PHASH_TABLE_BLOCK HashBlock,
|
||||
ULONG Index);
|
||||
NTSTATUS CmiAddKeyToHashTable(PREGISTRY_FILE RegistryFile,
|
||||
PHASH_TABLE_BLOCK HashBlock,
|
||||
PKEY_BLOCK NewKeyBlock,
|
||||
BLOCK_OFFSET NKBOffset);
|
||||
|
||||
NTSTATUS CmiAllocateValueBlock(IN PREGISTRY_FILE RegistryFile,
|
||||
OUT PVALUE_BLOCK *ValueBlock,
|
||||
OUT BLOCK_OFFSET *VBOffset,
|
||||
IN PCHAR ValueNameBuf);
|
||||
NTSTATUS CmiDestroyValueBlock(PREGISTRY_FILE RegistryFile,
|
||||
PVALUE_BLOCK ValueBlock, BLOCK_OFFSET VBOffset);
|
||||
|
||||
NTSTATUS CmiAllocateBlock(PREGISTRY_FILE RegistryFile,
|
||||
PVOID *Block,
|
||||
LONG BlockSize,
|
||||
BLOCK_OFFSET * pBlockOffset);
|
||||
NTSTATUS CmiDestroyBlock(PREGISTRY_FILE RegistryFile,
|
||||
PVOID Block,BLOCK_OFFSET Offset);
|
||||
PVOID CmiGetBlock(PREGISTRY_FILE RegistryFile,
|
||||
BLOCK_OFFSET BlockOffset,
|
||||
OUT PHEAP_BLOCK * ppHeap);
|
||||
VOID CmiLockBlock(PREGISTRY_FILE RegistryFile,
|
||||
PVOID Block);
|
||||
VOID CmiReleaseBlock(PREGISTRY_FILE RegistryFile,
|
||||
PVOID Block);
|
||||
NTSTATUS
|
||||
CmiAddFree(PREGISTRY_FILE RegistryFile,
|
||||
PFREE_SUB_BLOCK FreeBlock,BLOCK_OFFSET FreeOffset);
|
||||
CmiRemoveKeyFromList(IN PKEY_OBJECT NewKey);
|
||||
|
||||
PKEY_OBJECT CmiScanKeyList(IN PKEY_OBJECT Parent,
|
||||
IN PCHAR KeyNameBuf,
|
||||
IN ULONG Attributes);
|
||||
|
||||
PREGISTRY_HIVE
|
||||
CmiCreateRegistryHive(IN PWSTR Filename,
|
||||
IN BOOLEAN CreateNew);
|
||||
|
||||
ULONG CmiGetMaxNameLength(IN PREGISTRY_HIVE RegistryHive,
|
||||
IN PKEY_CELL KeyCell);
|
||||
|
||||
ULONG
|
||||
CmiGetMaxClassLength(IN PREGISTRY_HIVE RegistryHive,
|
||||
IN PKEY_CELL KeyCell);
|
||||
|
||||
ULONG
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
NTSTATUS
|
||||
CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
|
||||
IN PKEY_CELL KeyCell,
|
||||
IN PCHAR ValueName,
|
||||
OUT PVALUE_CELL *ValueCell,
|
||||
OUT BLOCK_OFFSET *VBOffset);
|
||||
|
||||
NTSTATUS
|
||||
CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
|
||||
IN PKEY_CELL KeyCell,
|
||||
IN ULONG Index,
|
||||
OUT PVALUE_CELL *ValueCell);
|
||||
|
||||
NTSTATUS
|
||||
CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
|
||||
IN PKEY_CELL KeyCell,
|
||||
IN PCHAR ValueNameBuf,
|
||||
OUT PVALUE_CELL *pValueCell,
|
||||
OUT BLOCK_OFFSET *pVBOffset);
|
||||
|
||||
NTSTATUS
|
||||
CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
|
||||
IN PKEY_CELL KeyCell,
|
||||
IN PCHAR ValueName);
|
||||
|
||||
NTSTATUS
|
||||
CmiAllocateHashTableBlock(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);
|
||||
|
||||
NTSTATUS
|
||||
CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive,
|
||||
PHASH_TABLE_CELL HashBlock,
|
||||
PKEY_CELL NewKeyCell,
|
||||
BLOCK_OFFSET NKBOffset);
|
||||
|
||||
NTSTATUS
|
||||
CmiAllocateValueCell(IN PREGISTRY_HIVE RegistryHive,
|
||||
OUT PVALUE_CELL *ValueCell,
|
||||
OUT BLOCK_OFFSET *VBOffset,
|
||||
IN PCHAR ValueNameBuf);
|
||||
|
||||
NTSTATUS
|
||||
CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive,
|
||||
PVALUE_CELL ValueCell,
|
||||
BLOCK_OFFSET VBOffset);
|
||||
|
||||
NTSTATUS
|
||||
CmiAllocateBlock(PREGISTRY_HIVE RegistryHive,
|
||||
PVOID *Block,
|
||||
LONG BlockSize,
|
||||
BLOCK_OFFSET * pBlockOffset);
|
||||
|
||||
NTSTATUS
|
||||
CmiDestroyBlock(PREGISTRY_HIVE RegistryHive,
|
||||
PVOID Block,
|
||||
BLOCK_OFFSET Offset);
|
||||
|
||||
PVOID
|
||||
CmiGetBlock(PREGISTRY_HIVE RegistryHive,
|
||||
BLOCK_OFFSET BlockOffset,
|
||||
OUT PHBIN * ppBin);
|
||||
|
||||
VOID
|
||||
CmiLockBlock(PREGISTRY_HIVE RegistryHive,
|
||||
PVOID Block);
|
||||
|
||||
VOID
|
||||
CmiReleaseBlock(PREGISTRY_HIVE RegistryHive,
|
||||
PVOID Block);
|
||||
|
||||
NTSTATUS
|
||||
CmiAddFree(PREGISTRY_HIVE RegistryHive,
|
||||
PCELL_HEADER FreeBlock,
|
||||
BLOCK_OFFSET FreeOffset);
|
||||
|
||||
#endif /*__INCLUDE_CM_H*/
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
|||
/* $Id: registry.c,v 1.68 2002/02/19 00:09:22 ekohl Exp $
|
||||
/* $Id: registry.c,v 1.69 2002/03/15 19:46:07 chorns Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -26,7 +26,7 @@
|
|||
/* ------------------------------------------------- File Statics */
|
||||
|
||||
POBJECT_TYPE CmiKeyType = NULL;
|
||||
PREGISTRY_FILE CmiVolatileFile = NULL;
|
||||
PREGISTRY_HIVE CmiVolatileHive = NULL;
|
||||
KSPIN_LOCK CmiKeyListLock;
|
||||
|
||||
static PKEY_OBJECT CmiRootKey = NULL;
|
||||
|
@ -38,18 +38,212 @@ static GENERIC_MAPPING CmiKeyMapping =
|
|||
{KEY_READ, KEY_WRITE, KEY_EXECUTE, KEY_ALL_ACCESS};
|
||||
|
||||
|
||||
VOID
|
||||
CmiCheckKey(BOOLEAN Verbose,
|
||||
HANDLE Key);
|
||||
|
||||
|
||||
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 = NtEnumerateKey(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 = NtOpenKey(&SubKey,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes);
|
||||
|
||||
assert(NT_SUCCESS(Status));
|
||||
|
||||
CmiCheckKey(Verbose, SubKey);
|
||||
|
||||
NtClose(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 = NtEnumerateValueKey(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 = NtOpenKey(&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);
|
||||
|
||||
NtClose(Key);
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
CmiCheckRegistry(BOOLEAN Verbose)
|
||||
{
|
||||
if (Verbose)
|
||||
DbgPrint("Checking registry internals\n");
|
||||
|
||||
CmiCheckByName(Verbose, L"Machine");
|
||||
CmiCheckByName(Verbose, L"User");
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
CmInitializeRegistry(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE RootKeyHandle;
|
||||
UNICODE_STRING RootKeyName;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING RootKeyName;
|
||||
HANDLE RootKeyHandle;
|
||||
PKEY_OBJECT NewKey;
|
||||
HANDLE KeyHandle;
|
||||
HANDLE KeyHandle;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Initialize the Key object type */
|
||||
CmiKeyType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
|
||||
assert(CmiKeyType);
|
||||
CmiKeyType->TotalObjects = 0;
|
||||
CmiKeyType->TotalHandles = 0;
|
||||
CmiKeyType->MaxObjects = LONG_MAX;
|
||||
|
@ -70,294 +264,363 @@ CmInitializeRegistry(VOID)
|
|||
RtlInitUnicodeString(&CmiKeyType->TypeName, L"Key");
|
||||
|
||||
/* Build volitile registry store */
|
||||
CmiVolatileFile = CmiCreateRegistry(NULL);
|
||||
CmiVolatileHive = CmiCreateRegistryHive(NULL, FALSE);
|
||||
assert(CmiVolatileHive != NULL);
|
||||
|
||||
/* Build the Root Key Object */
|
||||
/* Build the Root Key Object */
|
||||
RtlInitUnicodeString(&RootKeyName, REG_ROOT_KEY_NAME);
|
||||
DPRINT("Creating root\n");
|
||||
InitializeObjectAttributes(&ObjectAttributes, &RootKeyName, 0, NULL, NULL);
|
||||
Status = ObCreateObject(&RootKeyHandle,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
&ObjectAttributes,
|
||||
CmiKeyType,
|
||||
(PVOID*)&NewKey);
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
&ObjectAttributes,
|
||||
CmiKeyType,
|
||||
(PVOID *) &NewKey);
|
||||
assert(NT_SUCCESS(Status));
|
||||
CmiRootKey = NewKey;
|
||||
Status = ObReferenceObjectByHandle(RootKeyHandle,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
CmiKeyType,
|
||||
UserMode,
|
||||
(PVOID*)&CmiRootKey,
|
||||
NULL);
|
||||
CmiRootKey->RegistryFile = CmiVolatileFile;
|
||||
CmiRootKey->KeyBlock = CmiGetBlock(CmiVolatileFile,CmiVolatileFile->HeaderBlock->RootKeyBlock,NULL);
|
||||
|
||||
CmiRootKey->BlockOffset = CmiVolatileFile->HeaderBlock->RootKeyBlock;
|
||||
CmiRootKey->Flags = 0;
|
||||
CmiRootKey->NumberOfSubKeys=0;
|
||||
CmiRootKey->SubKeys= NULL;
|
||||
CmiRootKey->SizeOfSubKeys= 0;
|
||||
CmiRootKey->Name=ExAllocatePool(PagedPool,strlen("Registry"));
|
||||
CmiRootKey->NameSize=strlen("Registry");
|
||||
memcpy(CmiRootKey->Name,"Registry",strlen("Registry"));
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
CmiKeyType,
|
||||
KernelMode,
|
||||
(PVOID *) &CmiRootKey,
|
||||
NULL);
|
||||
assert(NT_SUCCESS(Status));
|
||||
CmiRootKey->RegistryHive = CmiVolatileHive;
|
||||
NewKey->BlockOffset = CmiVolatileHive->HiveHeader->RootKeyCell;
|
||||
NewKey->KeyCell = CmiGetBlock(CmiVolatileHive, NewKey->BlockOffset, NULL);
|
||||
CmiRootKey->Flags = 0;
|
||||
CmiRootKey->NumberOfSubKeys = 0;
|
||||
CmiRootKey->SubKeys = NULL;
|
||||
CmiRootKey->SizeOfSubKeys = 0;
|
||||
CmiRootKey->Name = ExAllocatePool(PagedPool, strlen("Registry"));
|
||||
CmiRootKey->NameSize = strlen("Registry");
|
||||
memcpy(CmiRootKey->Name, "Registry", strlen("Registry"));
|
||||
|
||||
KeInitializeSpinLock(&CmiKeyListLock);
|
||||
|
||||
/* Create initial predefined symbolic links */
|
||||
/* HKEY_LOCAL_MACHINE */
|
||||
DPRINT("Creating HKLM\n");
|
||||
Status=ObCreateObject(&KeyHandle,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
CmiKeyType,
|
||||
(PVOID*)&NewKey);
|
||||
Status = CmiAddSubKey(CmiVolatileFile,
|
||||
CmiRootKey,
|
||||
NewKey,
|
||||
L"Machine",
|
||||
14,
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
NewKey->RegistryFile = CmiVolatileFile;
|
||||
NewKey->Flags = 0;
|
||||
NewKey->NumberOfSubKeys=0;
|
||||
NewKey->SubKeys= NULL;
|
||||
NewKey->SizeOfSubKeys= NewKey->KeyBlock->NumberOfSubKeys;
|
||||
NewKey->Name=ExAllocatePool(PagedPool,strlen("Machine"));
|
||||
NewKey->NameSize=strlen("Machine");
|
||||
memcpy(NewKey->Name,"Machine",strlen("Machine"));
|
||||
CmiAddKeyToList(CmiRootKey,NewKey);
|
||||
CmiMachineKey=NewKey;
|
||||
/* Create initial predefined symbolic links */
|
||||
|
||||
/* HKEY_USERS */
|
||||
DPRINT("Creating HKU\n");
|
||||
Status=ObCreateObject(&KeyHandle,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
CmiKeyType,
|
||||
(PVOID*)&NewKey);
|
||||
Status = CmiAddSubKey(CmiVolatileFile,
|
||||
CmiRootKey,
|
||||
NewKey,
|
||||
L"User",
|
||||
8,
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
NewKey->RegistryFile = CmiVolatileFile;
|
||||
NewKey->Flags = 0;
|
||||
NewKey->NumberOfSubKeys=0;
|
||||
NewKey->SubKeys= NULL;
|
||||
NewKey->SizeOfSubKeys= NewKey->KeyBlock->NumberOfSubKeys;
|
||||
NewKey->Name=ExAllocatePool(PagedPool,strlen("User"));
|
||||
NewKey->NameSize=strlen("User");
|
||||
memcpy(NewKey->Name,"User",strlen("User"));
|
||||
CmiAddKeyToList(CmiRootKey,NewKey);
|
||||
CmiUserKey=NewKey;
|
||||
/* HKEY_LOCAL_MACHINE */
|
||||
Status = ObCreateObject(&KeyHandle,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
CmiKeyType,
|
||||
(PVOID*) &NewKey);
|
||||
assert(NT_SUCCESS(Status));
|
||||
Status = CmiAddSubKey(CmiVolatileHive,
|
||||
CmiRootKey,
|
||||
NewKey,
|
||||
L"Machine",
|
||||
wcslen(L"Machine") * sizeof(WCHAR),
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
assert(NT_SUCCESS(Status));
|
||||
NewKey->RegistryHive = CmiVolatileHive;
|
||||
NewKey->Flags = 0;
|
||||
NewKey->NumberOfSubKeys = 0;
|
||||
NewKey->SubKeys = NULL;
|
||||
NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys;
|
||||
NewKey->Name = ExAllocatePool(PagedPool, strlen("Machine"));
|
||||
NewKey->NameSize = strlen("Machine");
|
||||
memcpy(NewKey->Name, "Machine", strlen("Machine"));
|
||||
CmiAddKeyToList(CmiRootKey, NewKey);
|
||||
CmiMachineKey = NewKey;
|
||||
|
||||
/* HKEY_USERS */
|
||||
Status = ObCreateObject(&KeyHandle,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
CmiKeyType,
|
||||
(PVOID*) &NewKey);
|
||||
assert(NT_SUCCESS(Status));
|
||||
Status = CmiAddSubKey(CmiVolatileHive,
|
||||
CmiRootKey,
|
||||
NewKey,
|
||||
L"User",
|
||||
wcslen(L"User") * sizeof(WCHAR),
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
assert(NT_SUCCESS(Status));
|
||||
NewKey->RegistryHive = CmiVolatileHive;
|
||||
NewKey->Flags = 0;
|
||||
NewKey->NumberOfSubKeys = 0;
|
||||
NewKey->SubKeys = NULL;
|
||||
NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys;
|
||||
NewKey->Name = ExAllocatePool(PagedPool, strlen("User"));
|
||||
NewKey->NameSize = strlen("User");
|
||||
memcpy(NewKey->Name, "User", strlen("User"));
|
||||
CmiAddKeyToList(CmiRootKey, NewKey);
|
||||
CmiUserKey = NewKey;
|
||||
|
||||
/* Create '\\Registry\\Machine\\HARDWARE' key. */
|
||||
Status=ObCreateObject(&KeyHandle,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
CmiKeyType,
|
||||
(PVOID*)&NewKey);
|
||||
Status = CmiAddSubKey(CmiVolatileFile,
|
||||
CmiMachineKey,
|
||||
NewKey,
|
||||
L"HARDWARE",
|
||||
16,
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
NewKey->RegistryFile = CmiVolatileFile;
|
||||
Status = ObCreateObject(&KeyHandle,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
CmiKeyType,
|
||||
(PVOID*)&NewKey);
|
||||
assert(NT_SUCCESS(Status));
|
||||
Status = CmiAddSubKey(CmiVolatileHive,
|
||||
CmiMachineKey,
|
||||
NewKey,
|
||||
L"HARDWARE",
|
||||
wcslen(L"HARDWARE") * sizeof(WCHAR),
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
assert(NT_SUCCESS(Status));
|
||||
NewKey->RegistryHive = CmiVolatileHive;
|
||||
NewKey->Flags = 0;
|
||||
NewKey->NumberOfSubKeys=0;
|
||||
NewKey->SubKeys= NULL;
|
||||
NewKey->SizeOfSubKeys= NewKey->KeyBlock->NumberOfSubKeys;
|
||||
NewKey->Name=ExAllocatePool(PagedPool,strlen("HARDWARE"));
|
||||
NewKey->NameSize=strlen("HARDWARE");
|
||||
memcpy(NewKey->Name,"HARDWARE",strlen("HARDWARE"));
|
||||
CmiAddKeyToList(CmiMachineKey,NewKey);
|
||||
CmiHardwareKey=NewKey;
|
||||
NewKey->NumberOfSubKeys = 0;
|
||||
NewKey->SubKeys = NULL;
|
||||
NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys;
|
||||
NewKey->Name = ExAllocatePool(PagedPool, strlen("HARDWARE"));
|
||||
NewKey->NameSize = strlen("HARDWARE");
|
||||
memcpy(NewKey->Name, "HARDWARE", strlen("HARDWARE"));
|
||||
CmiAddKeyToList(CmiMachineKey, NewKey);
|
||||
CmiHardwareKey = NewKey;
|
||||
|
||||
/* Create '\\Registry\\Machine\\HARDWARE\\DESCRIPTION' key. */
|
||||
Status=ObCreateObject(&KeyHandle,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
CmiKeyType,
|
||||
(PVOID*)&NewKey);
|
||||
Status = CmiAddSubKey(CmiVolatileFile,
|
||||
CmiHardwareKey,
|
||||
NewKey,
|
||||
L"DESCRIPTION",
|
||||
22,
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
NewKey->RegistryFile = CmiVolatileFile;
|
||||
Status = ObCreateObject(&KeyHandle,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
CmiKeyType,
|
||||
(PVOID*) &NewKey);
|
||||
assert(NT_SUCCESS(Status));
|
||||
Status = CmiAddSubKey(CmiVolatileHive,
|
||||
CmiHardwareKey,
|
||||
NewKey,
|
||||
L"DESCRIPTION",
|
||||
wcslen(L"DESCRIPTION") * sizeof(WCHAR),
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
assert(NT_SUCCESS(Status));
|
||||
NewKey->RegistryHive = CmiVolatileHive;
|
||||
NewKey->Flags = 0;
|
||||
NewKey->NumberOfSubKeys=0;
|
||||
NewKey->SubKeys= NULL;
|
||||
NewKey->SizeOfSubKeys= NewKey->KeyBlock->NumberOfSubKeys;
|
||||
NewKey->Name=ExAllocatePool(PagedPool,strlen("DESCRIPTION"));
|
||||
NewKey->NameSize=strlen("DESCRIPTION");
|
||||
memcpy(NewKey->Name,"DESCRIPTION",strlen("DESCRIPTION"));
|
||||
CmiAddKeyToList(CmiHardwareKey,NewKey);
|
||||
NewKey->NumberOfSubKeys = 0;
|
||||
NewKey->SubKeys = NULL;
|
||||
NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys;
|
||||
NewKey->Name = ExAllocatePool(PagedPool, strlen("DESCRIPTION"));
|
||||
NewKey->NameSize = strlen("DESCRIPTION");
|
||||
memcpy(NewKey->Name, "DESCRIPTION", strlen("DESCRIPTION"));
|
||||
CmiAddKeyToList(CmiHardwareKey, NewKey);
|
||||
|
||||
/* Create '\\Registry\\Machine\\HARDWARE\\DEVICEMAP' key. */
|
||||
Status=ObCreateObject(&KeyHandle,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
CmiKeyType,
|
||||
(PVOID*)&NewKey);
|
||||
Status = CmiAddSubKey(CmiVolatileFile,
|
||||
CmiHardwareKey,
|
||||
NewKey,
|
||||
L"DEVICEMAP",
|
||||
18,
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
NewKey->RegistryFile = CmiVolatileFile;
|
||||
Status = ObCreateObject(&KeyHandle,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
CmiKeyType,
|
||||
(PVOID*) &NewKey);
|
||||
assert(NT_SUCCESS(Status));
|
||||
Status = CmiAddSubKey(CmiVolatileHive,
|
||||
CmiHardwareKey,
|
||||
NewKey,
|
||||
L"DEVICEMAP",
|
||||
wcslen(L"DEVICEMAP") * sizeof(WCHAR),
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
assert(NT_SUCCESS(Status));
|
||||
NewKey->RegistryHive = CmiVolatileHive;
|
||||
NewKey->Flags = 0;
|
||||
NewKey->NumberOfSubKeys=0;
|
||||
NewKey->SubKeys= NULL;
|
||||
NewKey->SizeOfSubKeys= NewKey->KeyBlock->NumberOfSubKeys;
|
||||
NewKey->Name=ExAllocatePool(PagedPool,strlen("DEVICEMAP"));
|
||||
NewKey->NameSize=strlen("DEVICEMAP");
|
||||
memcpy(NewKey->Name,"DEVICEMAP",strlen("DEVICEMAP"));
|
||||
NewKey->NumberOfSubKeys = 0;
|
||||
NewKey->SubKeys = NULL;
|
||||
NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys;
|
||||
NewKey->Name = ExAllocatePool(PagedPool, strlen("DEVICEMAP"));
|
||||
NewKey->NameSize = strlen("DEVICEMAP");
|
||||
memcpy(NewKey->Name, "DEVICEMAP", strlen("DEVICEMAP"));
|
||||
CmiAddKeyToList(CmiHardwareKey,NewKey);
|
||||
|
||||
/* Create '\\Registry\\Machine\\HARDWARE\\RESOURCEMAP' key. */
|
||||
Status=ObCreateObject(&KeyHandle,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL, //&ObjectAttributes,
|
||||
CmiKeyType,
|
||||
(PVOID*)&NewKey);
|
||||
Status = CmiAddSubKey(CmiVolatileFile,
|
||||
CmiHardwareKey,
|
||||
NewKey,
|
||||
L"RESOURCEMAP",
|
||||
22,
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
NewKey->RegistryFile = CmiVolatileFile;
|
||||
Status = ObCreateObject(&KeyHandle,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
CmiKeyType,
|
||||
(PVOID*) &NewKey);
|
||||
assert(NT_SUCCESS(Status));
|
||||
Status = CmiAddSubKey(CmiVolatileHive,
|
||||
CmiHardwareKey,
|
||||
NewKey,
|
||||
L"RESOURCEMAP",
|
||||
wcslen(L"RESOURCEMAP") * sizeof(WCHAR),
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
assert(NT_SUCCESS(Status));
|
||||
NewKey->RegistryHive = CmiVolatileHive;
|
||||
NewKey->Flags = 0;
|
||||
NewKey->NumberOfSubKeys=0;
|
||||
NewKey->SubKeys= NULL;
|
||||
NewKey->SizeOfSubKeys= NewKey->KeyBlock->NumberOfSubKeys;
|
||||
NewKey->Name=ExAllocatePool(PagedPool,strlen("RESOURCEMAP"));
|
||||
NewKey->NameSize=strlen("RESOURCEMAP");
|
||||
memcpy(NewKey->Name,"RESOURCEMAP",strlen("RESOURCEMAP"));
|
||||
CmiAddKeyToList(CmiHardwareKey,NewKey);
|
||||
NewKey->NumberOfSubKeys = 0;
|
||||
NewKey->SubKeys = NULL;
|
||||
NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys;
|
||||
NewKey->Name = ExAllocatePool(PagedPool, strlen("RESOURCEMAP"));
|
||||
NewKey->NameSize = strlen("RESOURCEMAP");
|
||||
memcpy(NewKey->Name, "RESOURCEMAP", strlen("RESOURCEMAP"));
|
||||
CmiAddKeyToList(CmiHardwareKey, NewKey);
|
||||
|
||||
/* FIXME: create remaining structure needed for default handles */
|
||||
/* FIXME: load volatile registry data from ROSDTECT */
|
||||
|
||||
}
|
||||
|
||||
NTSTATUS CmConnectHive(PWSTR FileName,PWSTR FullName,CHAR *KeyName,PKEY_OBJECT Parent)
|
||||
|
||||
NTSTATUS
|
||||
CmiConnectHive(PWSTR FileName,
|
||||
PWSTR FullName,
|
||||
PCHAR KeyName,
|
||||
PKEY_OBJECT Parent,
|
||||
BOOLEAN CreateNew)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
PKEY_OBJECT NewKey;
|
||||
HANDLE KeyHandle;
|
||||
UNICODE_STRING uKeyName;
|
||||
PREGISTRY_FILE RegistryFile = NULL;
|
||||
NTSTATUS Status;
|
||||
RegistryFile = CmiCreateRegistry(FileName);
|
||||
if( RegistryFile )
|
||||
{
|
||||
RtlInitUnicodeString(&uKeyName, FullName);
|
||||
DPRINT("CCH %S ;",FullName);
|
||||
InitializeObjectAttributes(&ObjectAttributes, &uKeyName, 0, NULL, NULL);
|
||||
Status=ObCreateObject(&KeyHandle,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
&ObjectAttributes,
|
||||
CmiKeyType,
|
||||
(PVOID*)&NewKey);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return (Status);
|
||||
NewKey->RegistryFile = RegistryFile;
|
||||
NewKey->BlockOffset = RegistryFile->HeaderBlock->RootKeyBlock;
|
||||
NewKey->KeyBlock = CmiGetBlock(RegistryFile,NewKey->BlockOffset,NULL);
|
||||
NewKey->Flags = 0;
|
||||
NewKey->NumberOfSubKeys=0;
|
||||
NewKey->SubKeys= ExAllocatePool(PagedPool
|
||||
, NewKey->KeyBlock->NumberOfSubKeys * sizeof(DWORD));
|
||||
NewKey->SizeOfSubKeys= NewKey->KeyBlock->NumberOfSubKeys;
|
||||
NewKey->Name=ExAllocatePool(PagedPool,strlen(KeyName));
|
||||
NewKey->NameSize=strlen(KeyName);
|
||||
memcpy(NewKey->Name,KeyName,strlen(KeyName));
|
||||
CmiAddKeyToList(Parent,NewKey);
|
||||
}
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
PREGISTRY_HIVE RegistryHive = NULL;
|
||||
UNICODE_STRING uKeyName;
|
||||
PKEY_OBJECT NewKey;
|
||||
HANDLE KeyHandle;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Called. FileName %S\n", FullName);
|
||||
|
||||
RegistryHive = CmiCreateRegistryHive(FileName, CreateNew);
|
||||
if (RegistryHive)
|
||||
{
|
||||
RtlInitUnicodeString(&uKeyName, FullName);
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&uKeyName,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
Status = ObCreateObject(&KeyHandle,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
&ObjectAttributes,
|
||||
CmiKeyType,
|
||||
(PVOID*) &NewKey);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
NewKey->RegistryHive = RegistryHive;
|
||||
NewKey->BlockOffset = RegistryHive->HiveHeader->RootKeyCell;
|
||||
NewKey->KeyCell = CmiGetBlock(RegistryHive, NewKey->BlockOffset, NULL);
|
||||
NewKey->Flags = 0;
|
||||
NewKey->NumberOfSubKeys = 0;
|
||||
NewKey->SubKeys = ExAllocatePool(PagedPool,
|
||||
NewKey->KeyCell->NumberOfSubKeys * sizeof(DWORD));
|
||||
|
||||
if ((NewKey->SubKeys == NULL) && (NewKey->KeyCell->NumberOfSubKeys != 0))
|
||||
{
|
||||
/* FIXME: Cleanup from CmiCreateRegistryHive() */
|
||||
DPRINT("NumberOfSubKeys %d\n", NewKey->KeyCell->NumberOfSubKeys);
|
||||
ZwClose(NewKey);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys;
|
||||
NewKey->Name = ExAllocatePool(PagedPool, strlen(KeyName));
|
||||
|
||||
if ((NewKey->Name == NULL) && (strlen(KeyName) != 0))
|
||||
{
|
||||
/* FIXME: Cleanup from CmiCreateRegistryHive() */
|
||||
DPRINT("strlen(KeyName) %d\n", strlen(KeyName));
|
||||
if (NewKey->SubKeys != NULL)
|
||||
ExFreePool(NewKey->SubKeys);
|
||||
ZwClose(NewKey);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
NewKey->NameSize = strlen(KeyName);
|
||||
memcpy(NewKey->Name, KeyName, strlen(KeyName));
|
||||
CmiAddKeyToList(Parent, NewKey);
|
||||
|
||||
VERIFY_KEY_OBJECT(NewKey);
|
||||
}
|
||||
else
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CmiInitializeHive(PWSTR FileName,
|
||||
PWSTR FullName,
|
||||
PCHAR KeyName,
|
||||
PKEY_OBJECT Parent)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Try to connect the hive */
|
||||
//Status = CmiConnectHive(FileName, FullName, KeyName, Parent, FALSE);
|
||||
Status = CmiConnectHive(FileName, FullName, KeyName, Parent, TRUE);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Status %.08x\n", Status);
|
||||
#if 0
|
||||
WCHAR AltFileName[MAX_PATH];
|
||||
|
||||
CPRINT("WARNING! Registry file %S not found\n", FileName);
|
||||
|
||||
wcscpy(AltFileName, FileName);
|
||||
wcscat(AltFileName, L".alt");
|
||||
|
||||
/* Try to connect the alternative hive */
|
||||
Status = CmiConnectHive(AltFileName, FullName, KeyName, Parent, TRUE);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
CPRINT("WARNING! Alternative registry file %S not found\n", AltFileName);
|
||||
DPRINT("Status %.08x\n", Status);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
extern BOOLEAN CmiDoVerify;
|
||||
|
||||
VOID
|
||||
CmInitializeRegistry2(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
/* FIXME : delete temporary \Registry\Machine\System */
|
||||
/* connect the SYSTEM Hive */
|
||||
Status=CmConnectHive(SYSTEM_REG_FILE,REG_SYSTEM_KEY_NAME
|
||||
,"System",CmiMachineKey);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME : search SYSTEM.alt, or create new */
|
||||
CPRINT(" warning : registry file %S not found\n",SYSTEM_REG_FILE);
|
||||
}
|
||||
/* connect the SOFTWARE Hive */
|
||||
Status=CmConnectHive(SOFTWARE_REG_FILE,REG_SOFTWARE_KEY_NAME
|
||||
,"Software",CmiMachineKey);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME : search SOFTWARE.alt, or create new */
|
||||
CPRINT(" warning : registry file %S not found\n",SOFTWARE_REG_FILE);
|
||||
}
|
||||
/* connect the SAM Hive */
|
||||
Status=CmConnectHive(SAM_REG_FILE,REG_SAM_KEY_NAME
|
||||
,"Sam",CmiMachineKey);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME : search SAM.alt, or create new */
|
||||
CPRINT(" warning : registry file %S not found\n",SAM_REG_FILE);
|
||||
}
|
||||
/* connect the SECURITY Hive */
|
||||
Status=CmConnectHive(SEC_REG_FILE,REG_SEC_KEY_NAME
|
||||
,"Security",CmiMachineKey);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME : search SECURITY.alt, or create new */
|
||||
CPRINT(" warning : registry file %S not found\n",SEC_REG_FILE);
|
||||
}
|
||||
/* connect the DEFAULT Hive */
|
||||
Status=CmConnectHive(USER_REG_FILE,REG_USER_KEY_NAME
|
||||
,".Default",CmiUserKey);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME : search DEFAULT.alt, or create new */
|
||||
CPRINT(" warning : registry file %S not found\n",USER_REG_FILE);
|
||||
}
|
||||
NTSTATUS Status;
|
||||
|
||||
CmiDoVerify = TRUE;
|
||||
|
||||
/* FIXME: Delete temporary \Registry\Machine\System */
|
||||
|
||||
/* Connect the SYSTEM hive */
|
||||
Status = CmiInitializeHive(SYSTEM_REG_FILE, REG_SYSTEM_KEY_NAME, "System", CmiMachineKey);
|
||||
assert(NT_SUCCESS(Status));
|
||||
|
||||
/* Connect the SOFTWARE hive */
|
||||
Status = CmiInitializeHive(SOFTWARE_REG_FILE, REG_SOFTWARE_KEY_NAME, "Software", CmiMachineKey);
|
||||
assert(NT_SUCCESS(Status));
|
||||
|
||||
/* Connect the SAM hive */
|
||||
Status = CmiInitializeHive(SAM_REG_FILE,REG_SAM_KEY_NAME, "Sam", CmiMachineKey);
|
||||
assert(NT_SUCCESS(Status));
|
||||
|
||||
/* Connect the SECURITY hive */
|
||||
Status = CmiInitializeHive(SEC_REG_FILE, REG_SEC_KEY_NAME, "Security", CmiMachineKey);
|
||||
assert(NT_SUCCESS(Status));
|
||||
|
||||
/* Connect the DEFAULT hive */
|
||||
Status = CmiInitializeHive(USER_REG_FILE, REG_USER_KEY_NAME, ".Default", CmiUserKey);
|
||||
assert(NT_SUCCESS(Status));
|
||||
|
||||
/* FIXME : initialize standards symbolic links */
|
||||
/*
|
||||
for(;;)
|
||||
{
|
||||
__asm__ ("hlt\n\t");
|
||||
}
|
||||
*/
|
||||
|
||||
// CmiCheckRegistry(TRUE);
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
CmShutdownRegistry(VOID)
|
||||
{
|
||||
DPRINT("CmShutdownRegistry()...\n");
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -24,245 +24,290 @@ extern KSPIN_LOCK CmiKeyListLock;
|
|||
|
||||
NTSTATUS STDCALL
|
||||
CmiObjectParse(PVOID ParsedObject,
|
||||
PVOID *NextObject,
|
||||
PUNICODE_STRING FullPath,
|
||||
PWSTR *Path,
|
||||
POBJECT_TYPE ObjectType,
|
||||
ULONG Attributes)
|
||||
PVOID *NextObject,
|
||||
PUNICODE_STRING FullPath,
|
||||
PWSTR *Path,
|
||||
POBJECT_TYPE ObjectType,
|
||||
ULONG Attributes)
|
||||
{
|
||||
CHAR cPath[MAX_PATH];
|
||||
PWSTR end;
|
||||
PKEY_OBJECT FoundObject;
|
||||
PKEY_OBJECT ParsedKey=ParsedObject;
|
||||
PKEY_BLOCK SubKeyBlock;
|
||||
BLOCK_OFFSET BlockOffset;
|
||||
NTSTATUS Status;
|
||||
*NextObject = NULL;
|
||||
if ((*Path) == NULL)
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if((*Path[0])=='\\')
|
||||
{
|
||||
end = wcschr((*Path)+1, '\\');
|
||||
if (end != NULL)
|
||||
*end = 0;
|
||||
wcstombs(cPath,(*Path)+1,wcslen((*Path)+1));
|
||||
cPath[wcslen( (*Path)+1)]=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
end = wcschr((*Path), '\\');
|
||||
if (end != NULL)
|
||||
*end = 0;
|
||||
wcstombs(cPath,(*Path),wcslen((*Path)));
|
||||
cPath[wcslen( (*Path))]=0;
|
||||
}
|
||||
|
||||
FoundObject = CmiScanKeyList(ParsedKey,cPath,Attributes);
|
||||
if (FoundObject == NULL)
|
||||
{
|
||||
Status = CmiScanForSubKey(ParsedKey->RegistryFile,
|
||||
ParsedKey->KeyBlock,
|
||||
&SubKeyBlock,
|
||||
&BlockOffset,
|
||||
cPath,
|
||||
0,
|
||||
Attributes);
|
||||
if(!NT_SUCCESS(Status) || SubKeyBlock == NULL)
|
||||
{
|
||||
BLOCK_OFFSET BlockOffset;
|
||||
PKEY_OBJECT FoundObject;
|
||||
PKEY_OBJECT ParsedKey;
|
||||
PKEY_CELL SubKeyCell;
|
||||
CHAR cPath[MAX_PATH];
|
||||
NTSTATUS Status;
|
||||
PWSTR end;
|
||||
|
||||
ParsedKey = ParsedObject;
|
||||
|
||||
VERIFY_KEY_OBJECT(ParsedKey);
|
||||
|
||||
*NextObject = NULL;
|
||||
|
||||
if ((*Path) == NULL)
|
||||
{
|
||||
DPRINT("*Path is NULL\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if ((*Path[0]) == '\\')
|
||||
{
|
||||
end = wcschr((*Path) + 1, '\\');
|
||||
if (end != NULL)
|
||||
*end = 0;
|
||||
wcstombs(cPath, (*Path) + 1, wcslen((*Path) + 1));
|
||||
cPath[wcslen((*Path) + 1)] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
end = wcschr((*Path), '\\');
|
||||
if (end != NULL)
|
||||
*end = 0;
|
||||
wcstombs(cPath, (*Path), wcslen((*Path)));
|
||||
cPath[wcslen((*Path))] = 0;
|
||||
}
|
||||
|
||||
FoundObject = CmiScanKeyList(ParsedKey, cPath, Attributes);
|
||||
if (FoundObject == NULL)
|
||||
{
|
||||
Status = CmiScanForSubKey(ParsedKey->RegistryHive,
|
||||
ParsedKey->KeyCell,
|
||||
&SubKeyCell,
|
||||
&BlockOffset,
|
||||
cPath,
|
||||
0,
|
||||
Attributes);
|
||||
|
||||
if (!NT_SUCCESS(Status) || (SubKeyCell == NULL))
|
||||
{
|
||||
if (end != NULL)
|
||||
{
|
||||
*end = '\\';
|
||||
}
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* Create new key object and put into linked list */
|
||||
DPRINT("CmiObjectParse %s\n", cPath);
|
||||
Status = ObCreateObject(NULL,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
CmiKeyType,
|
||||
(PVOID*) &FoundObject);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
FoundObject->Flags = 0;
|
||||
FoundObject->Name = SubKeyCell->Name;
|
||||
FoundObject->NameSize = SubKeyCell->NameSize;
|
||||
FoundObject->KeyCell = SubKeyCell;
|
||||
FoundObject->BlockOffset = BlockOffset;
|
||||
FoundObject->RegistryHive = ParsedKey->RegistryHive;
|
||||
CmiAddKeyToList(ParsedKey, FoundObject);
|
||||
DPRINT("Created object 0x%x\n", FoundObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
ObReferenceObjectByPointer(FoundObject,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
UserMode);
|
||||
}
|
||||
|
||||
DPRINT("CmiObjectParse %s\n", FoundObject->Name);
|
||||
|
||||
if (end != NULL)
|
||||
{
|
||||
*end = '\\';
|
||||
}
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
/* Create new key object and put into linked list */
|
||||
DPRINT("CmiObjectParse %s\n",cPath);
|
||||
Status = ObCreateObject(NULL,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
CmiKeyType,
|
||||
(PVOID*)&FoundObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
FoundObject->Flags = 0;
|
||||
FoundObject->Name = SubKeyBlock->Name;
|
||||
FoundObject->NameSize = SubKeyBlock->NameSize;
|
||||
FoundObject->KeyBlock = SubKeyBlock;
|
||||
FoundObject->BlockOffset = BlockOffset;
|
||||
FoundObject->RegistryFile = ParsedKey->RegistryFile;
|
||||
CmiAddKeyToList(ParsedKey,FoundObject);
|
||||
DPRINT("CmiObjectParse(): created object 0x%x\n",FoundObject);
|
||||
}
|
||||
else
|
||||
ObReferenceObjectByPointer(FoundObject,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
UserMode);
|
||||
DPRINT("CmiObjectParse %s\n",FoundObject->Name);
|
||||
if (end != NULL)
|
||||
{
|
||||
*end = '\\';
|
||||
*Path = end;
|
||||
}
|
||||
else
|
||||
{
|
||||
*Path = NULL;
|
||||
}
|
||||
{
|
||||
*end = '\\';
|
||||
*Path = end;
|
||||
}
|
||||
else
|
||||
{
|
||||
*Path = NULL;
|
||||
}
|
||||
|
||||
*NextObject = FoundObject;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
VERIFY_KEY_OBJECT(FoundObject);
|
||||
|
||||
*NextObject = FoundObject;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
CmiObjectCreate(PVOID ObjectBody,
|
||||
PVOID Parent,
|
||||
PWSTR RemainingPath,
|
||||
struct _OBJECT_ATTRIBUTES* ObjectAttributes)
|
||||
PVOID Parent,
|
||||
PWSTR RemainingPath,
|
||||
struct _OBJECT_ATTRIBUTES* ObjectAttributes)
|
||||
{
|
||||
PKEY_OBJECT pKey=ObjectBody;
|
||||
pKey->ParentKey = Parent;
|
||||
if (RemainingPath)
|
||||
{
|
||||
if(RemainingPath[0]== L'\\')
|
||||
{
|
||||
pKey->Name = (PCHAR) (&RemainingPath[1]);
|
||||
pKey->NameSize = wcslen(RemainingPath)-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pKey->Name = (PCHAR) RemainingPath;
|
||||
pKey->NameSize = wcslen(RemainingPath);
|
||||
}
|
||||
}
|
||||
PKEY_OBJECT pKey = ObjectBody;
|
||||
pKey->ParentKey = Parent;
|
||||
if (RemainingPath)
|
||||
{
|
||||
if(RemainingPath[0]== L'\\')
|
||||
{
|
||||
pKey->Name = (PCHAR) (&RemainingPath[1]);
|
||||
pKey->NameSize = wcslen(RemainingPath) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pKey->Name = (PCHAR) RemainingPath;
|
||||
pKey->NameSize = wcslen(RemainingPath);
|
||||
}
|
||||
}
|
||||
else
|
||||
pKey->NameSize = 0;
|
||||
{
|
||||
pKey->NameSize = 0;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
VOID STDCALL
|
||||
CmiObjectDelete(PVOID DeletedObject)
|
||||
{
|
||||
PKEY_OBJECT KeyObject;
|
||||
PKEY_OBJECT KeyObject;
|
||||
|
||||
DPRINT("Delete object key\n");
|
||||
|
||||
DPRINT("delete object key\n");
|
||||
KeyObject = (PKEY_OBJECT) DeletedObject;
|
||||
if(!NT_SUCCESS(CmiRemoveKeyFromList(KeyObject)))
|
||||
{
|
||||
DPRINT1("Key not found in parent list ???\n");
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(CmiRemoveKeyFromList(KeyObject)))
|
||||
{
|
||||
DPRINT1("Key not found in parent list ???\n");
|
||||
}
|
||||
|
||||
if (KeyObject->Flags & KO_MARKED_FOR_DELETE)
|
||||
{
|
||||
DPRINT("delete really key\n");
|
||||
CmiDestroyBlock(KeyObject->RegistryFile,
|
||||
KeyObject->KeyBlock,
|
||||
KeyObject->BlockOffset);
|
||||
CmiDestroyBlock(KeyObject->RegistryHive,
|
||||
KeyObject->KeyCell,
|
||||
KeyObject->BlockOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
CmiReleaseBlock(KeyObject->RegistryFile,
|
||||
KeyObject->KeyBlock);
|
||||
CmiReleaseBlock(KeyObject->RegistryHive, KeyObject->KeyCell);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CmiAddKeyToList(PKEY_OBJECT ParentKey,PKEY_OBJECT NewKey)
|
||||
VOID
|
||||
CmiAddKeyToList(PKEY_OBJECT ParentKey,
|
||||
PKEY_OBJECT NewKey)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
KIRQL OldIrql;
|
||||
|
||||
DPRINT("ParentKey %.08x\n", ParentKey);
|
||||
|
||||
KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
|
||||
|
||||
if (ParentKey->SizeOfSubKeys <= ParentKey->NumberOfSubKeys)
|
||||
{
|
||||
PKEY_OBJECT *tmpSubKeys = ExAllocatePool(PagedPool
|
||||
, (ParentKey->NumberOfSubKeys+1) * sizeof(DWORD));
|
||||
if(ParentKey->NumberOfSubKeys > 0)
|
||||
memcpy(tmpSubKeys,ParentKey->SubKeys
|
||||
,ParentKey->NumberOfSubKeys*sizeof(DWORD));
|
||||
if(ParentKey->SubKeys) ExFreePool(ParentKey->SubKeys);
|
||||
ParentKey->SubKeys=tmpSubKeys;
|
||||
ParentKey->SizeOfSubKeys = ParentKey->NumberOfSubKeys+1;
|
||||
}
|
||||
/* FIXME : please maintain the list in alphabetic order */
|
||||
{
|
||||
PKEY_OBJECT *tmpSubKeys = ExAllocatePool(PagedPool,
|
||||
(ParentKey->NumberOfSubKeys + 1) * sizeof(DWORD));
|
||||
|
||||
if (ParentKey->NumberOfSubKeys > 0)
|
||||
{
|
||||
memcpy(tmpSubKeys,
|
||||
ParentKey->SubKeys,
|
||||
ParentKey->NumberOfSubKeys * sizeof(DWORD));
|
||||
}
|
||||
|
||||
if (ParentKey->SubKeys)
|
||||
ExFreePool(ParentKey->SubKeys);
|
||||
|
||||
ParentKey->SubKeys = tmpSubKeys;
|
||||
ParentKey->SizeOfSubKeys = ParentKey->NumberOfSubKeys + 1;
|
||||
}
|
||||
|
||||
/* FIXME: Please maintain the list in alphabetic order */
|
||||
/* to allow a dichotomic search */
|
||||
ParentKey->SubKeys[ParentKey->NumberOfSubKeys++] = NewKey;
|
||||
|
||||
DPRINT("Reference parent key: 0x%x\n", ParentKey);
|
||||
|
||||
ObReferenceObjectByPointer(ParentKey,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
UserMode);
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
UserMode);
|
||||
NewKey->ParentKey = ParentKey;
|
||||
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CmiRemoveKeyFromList(PKEY_OBJECT KeyToRemove)
|
||||
CmiRemoveKeyFromList(PKEY_OBJECT KeyToRemove)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
PKEY_OBJECT ParentKey;
|
||||
PKEY_OBJECT ParentKey;
|
||||
KIRQL OldIrql;
|
||||
DWORD Index;
|
||||
|
||||
ParentKey=KeyToRemove->ParentKey;
|
||||
ParentKey = KeyToRemove->ParentKey;
|
||||
KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
|
||||
/* FIXME : if list maintained in alphabetic order, use dichotomic search */
|
||||
for (Index=0; Index < ParentKey->NumberOfSubKeys; Index++)
|
||||
{
|
||||
if(ParentKey->SubKeys[Index] == KeyToRemove)
|
||||
{
|
||||
if (Index < ParentKey->NumberOfSubKeys-1)
|
||||
memmove(&ParentKey->SubKeys[Index]
|
||||
,&ParentKey->SubKeys[Index+1]
|
||||
,(ParentKey->NumberOfSubKeys-Index-1)*sizeof(PKEY_OBJECT));
|
||||
ParentKey->NumberOfSubKeys--;
|
||||
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
|
||||
DPRINT("Dereference parent key: 0x%x\n",ParentKey);
|
||||
ObDereferenceObject(ParentKey);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
/* FIXME: If list maintained in alphabetic order, use dichotomic search */
|
||||
for (Index = 0; Index < ParentKey->NumberOfSubKeys; Index++)
|
||||
{
|
||||
if (ParentKey->SubKeys[Index] == KeyToRemove)
|
||||
{
|
||||
if (Index < ParentKey->NumberOfSubKeys-1)
|
||||
RtlMoveMemory(&ParentKey->SubKeys[Index],
|
||||
&ParentKey->SubKeys[Index + 1],
|
||||
(ParentKey->NumberOfSubKeys - Index - 1) * sizeof(PKEY_OBJECT));
|
||||
ParentKey->NumberOfSubKeys--;
|
||||
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
|
||||
|
||||
DPRINT("Dereference parent key: 0x%x\n", ParentKey);
|
||||
|
||||
ObDereferenceObject(ParentKey);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
PKEY_OBJECT
|
||||
CmiScanKeyList(PKEY_OBJECT Parent,
|
||||
PCHAR KeyName,
|
||||
ULONG Attributes)
|
||||
PCHAR KeyName,
|
||||
ULONG Attributes)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
PKEY_OBJECT CurKey;
|
||||
DWORD Index;
|
||||
WORD NameSize;
|
||||
NameSize=strlen(KeyName);
|
||||
PKEY_OBJECT CurKey;
|
||||
KIRQL OldIrql;
|
||||
WORD NameSize;
|
||||
DWORD Index;
|
||||
|
||||
DPRINT("Scanning key list for %s (Parent %s)\n",
|
||||
KeyName, Parent->Name);
|
||||
|
||||
NameSize = strlen(KeyName);
|
||||
KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
|
||||
/* FIXME : if list maintained in alphabetic order, use dichotomic search */
|
||||
/* FIXME: if list maintained in alphabetic order, use dichotomic search */
|
||||
for (Index=0; Index < Parent->NumberOfSubKeys; Index++)
|
||||
{
|
||||
CurKey=Parent->SubKeys[Index];
|
||||
if (Attributes & OBJ_CASE_INSENSITIVE)
|
||||
{
|
||||
if( NameSize == CurKey->NameSize
|
||||
&& !_strnicmp(KeyName,CurKey->Name,NameSize))
|
||||
{
|
||||
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
|
||||
return CurKey;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( NameSize == CurKey->NameSize
|
||||
&& !strncmp(KeyName,CurKey->Name,NameSize))
|
||||
{
|
||||
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
|
||||
return CurKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
CurKey = Parent->SubKeys[Index];
|
||||
if (Attributes & OBJ_CASE_INSENSITIVE)
|
||||
{
|
||||
if ((NameSize == CurKey->NameSize)
|
||||
&& (_strnicmp(KeyName, CurKey->Name, NameSize) == 0))
|
||||
{
|
||||
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
|
||||
return CurKey;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((NameSize == CurKey->NameSize)
|
||||
&& (strncmp(KeyName,CurKey->Name,NameSize) == 0))
|
||||
{
|
||||
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
|
||||
return CurKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
|
||||
|
||||
return NULL;
|
||||
|
|
Loading…
Reference in a new issue