Added a few more functions for registry

svn path=/trunk/; revision=542
This commit is contained in:
Rex Jolliff 1999-06-08 07:11:29 +00:00
parent a5e573f1b3
commit 0a1f866c8f
3 changed files with 443 additions and 265 deletions

View file

@ -0,0 +1,15 @@
//
// PDEV
// DESCRIPTION
// This structure will contain all state information
// required to maintain the video device
// ACCESS
// Allocated from non-paged pool by the GDI
typedef struct _PDEV
{
HANDLE KMDriver;
} PDEV, *PPDEV;

View file

@ -87,4 +87,12 @@ typedef struct _KEY_VALUE_PARTIAL_INFORMATION
UCHAR Data[1];
} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;
#define REG_OPTION_VOLATILE 0x00000000
#define REG_OPTION_NON_VOLATILE 0x00000001
#define REG_OPTION_CREATE_LINK 0x00000002
#define REG_OPTION_BACKUP_RESTORE 0x00000004
#define REG_CREATED_NEW_KEY 1
#define REG_OPENED_EXISTING_KEY 2

View file

@ -8,20 +8,55 @@
* Created 22/05/98
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/ob.h>
#include <wchar.h>
//#define NDEBUG
#include <internal/debug.h>
// #define PROTO_REG 1 /* Comment out to disable */
//#define PROTO_REG 1 /* Comment out to disable */
/* FILE STATICS *************************************************************/
/* ----------------------------------------------------- Typedefs */
#if PROTO_REG
#define REG_BLOCK_SIZE 4096
#define REG_HEAP_BLOCK_DATA_OFFSET 32
#define SYSTEM_REG_FILE L"\\SystemDir\\System32\\Config\\SYSTEM.DAT"
typedef DWORD BLOCK_OFFSET;
typedef struct _HEADER_BLOCK
{
DWORD BlockId;
DWORD Unused1;
DWORD Unused2;
LARGE_INTEGER DateModified;
DWORD Unused3;
DWORD Unused4;
DWORD Unused5;
DWORD Unused6;
BLOCK_OFFSET RootKeyBlock;
DWORD BlockSize;
DWORD Unused7;
DWORD Unused8[115];
DWORD Checksum;
} HEADER_BLOCK, *PHEADER_BLOCK;
typedef struct _HEAP_BLOCK
{
DWORD BlockId;
BLOCK_OFFSET PreviousHeapBlock;
BLOCK_OFFSET NextHeapBlock;
DWORD BlockSize;
} HEAP_BLOCK, *PHEAP_BLOCK;
typedef struct _FREE_SUB_BLOCK
{
DWORD SubBlockSize;
} FREE_SUB_BLOCK, *PFREE_SUB_BLOCK;
typedef struct _KEY_BLOCK
{
DWORD SubBlockId;
@ -30,14 +65,14 @@ typedef struct _KEY_BLOCK
BLOCK_OFFSET ParentKeyOffset;
DWORD NumberOfSubKeys;
BLOCK_OFFSET HashTableOffset;
DWORD NumberValues;
DWORD NumberOfValues;
BLOCK_OFFSET ValuesOffset;
BLOCK_OFFSET SecurityKeyOffset;
BLOCK_OFFSET ClassNameOffset;
DWORD Unused1;
DWORD NameSize;
DWORD ClassSize;
CHAR Name[1];
WCHAR Name[1];
} KEY_BLOCK, *PKEY_BLOCK;
typedef struct _HASH_RECORD
@ -46,26 +81,12 @@ typedef struct _HASH_RECORD
ULONG HashValue;
} HASH_RECORD, *PHASH_RECORD;
typedef struct _HASH_BLOCK
typedef struct _HASH_TABLE_BLOCK
{
DWORD SubBlockId;
DWORD HashTableSize;
HASH_RECORD Table[1];
} HASH_BLOCK, *PHASH_BLOCK;
/* Type defining the Object Manager Key Object */
typedef struct _KEY_OBJECT
{
CSHORT Type;
CSHORT Size;
ULONG Flags;
WCHAR *Name;
PKEY_BLOCK KeyBlock;
struct _KEY_OBJECT *NextKey;
} KEY_OBJECT, *PKEY_OBJECT;
#define KO_MARKED_FOR_DELETE 0x00000001
} HASH_TABLE_BLOCK, *PHASH_TABLE_BLOCK;
typedef struct _REGISTRY_FILE
{
@ -75,16 +96,39 @@ typedef struct _REGISTRY_FILE
PVOID (*Flush)(VOID);
} REGISTRY_FILE, *PREGISTRY_FILE;
/* Type defining the Object Manager Key Object */
typedef struct _KEY_OBJECT
{
CSHORT Type;
CSHORT Size;
ULONG Flags;
WCHAR *Name;
PREGISTRY_FILE RegistryFile;
PKEY_BLOCK KeyBlock;
struct _KEY_OBJECT *NextKey;
} KEY_OBJECT, *PKEY_OBJECT;
#define KO_MARKED_FOR_DELETE 0x00000001
/* ------------------------------------------------- File Statics */
static POBJECT_TYPE CmiKeyType = NULL;
static PKEY_OBJECT CmiKeyList = NULL;
static KSPIN_LOCK CmiKeyListLock;
static PREGISTRY_FILE CmiVolatileFile = NULL;
static PREGISTRY_FILE CmiSystemFile = NULL;
/* ----------------------------------------- Forward Declarations */
static PVOID CmiObjectParse(PVOID ParsedObject, PWSTR *Path);
static PVOID CmiObjectDelete(PVOID DeletedObject);
static VOID CmiObjectDelete(PVOID DeletedObject);
static NTSTATUS CmiBuildKeyPath(PWSTR *KeyPath,
POBJECT_ATTRIBUTES ObjectAttributes);
static VOID CmiAddKeyToList(PKEY_OBJECT NewKey);
static PKEY_OBJECT CmiScanKeyList(PWSTR *KeyNameBuf);
static PKEY_OBJECT CmiScanKeyList(PWSTR KeyNameBuf);
static PREGISTRY_FILE CmiCreateRegistry(PWSTR Filename);
static PVOID CmiExtendVolatileFile(PVOID *Data, ULONG NewSize);
static NTSTATUS CmiCreateKey(PREGISTRY_FILE RegistryFile,
PWSTR KeyNameBuf,
PKEY_BLOCK *KeyBlock,
@ -99,14 +143,34 @@ static NTSTATUS CmiFindKey(PREGISTRY_FILE RegistryFile,
ACCESS_MASK DesiredAccess,
ULONG TitleIndex,
PUNICODE_STRING Class);
static PHASH_TABLE_BLOCK CmiGetHashTableBlock(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock);
static PKEY_BLOCK CmiGetKeyFromHashByIndex(PREGISTRY_FILE RegistryFile,
PHASH_TABLE_BLOCK HashTableBlock,
ULONG Index);
static VOID CmiLockBlock(PREGISTRY_FILE RegistryFile,
PVOID Block);
static VOID CmiUnlockBlock(PREGISTRY_FILE RegistryFile,
PVOID Block);
static PWSTR CmiGetClassBlock(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock);
static ULONG CmiGetMaxNameLength(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock);
static ULONG CmiGetMaxClassLength(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock);
static ULONG CmiGetMaxValueNameLength(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock);
static ULONG CmiGetMaxValueDataLength(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock);
#endif
/* FUNCTIONS *****************************************************************/
/* --------------------------------------------- Public Interface */
VOID
CmInitializeRegistry(VOID)
{
#if PROTO_REG
HANDLE RootKeyHandle;
UNICODE_STRING RootKeyName;
OBJECT_ATTRIBUTES ObjectAttributes;
@ -121,8 +185,8 @@ CmInitializeRegistry(VOID)
CmiKeyType->Dump = NULL;
CmiKeyType->Open = NULL;
CmiKeyType->Close = NULL;
CmiKeyType->Delete = CmiKeyDelete;
CmiKeyType->Parse = CmiKeyParse;
CmiKeyType->Delete = CmiObjectDelete;
CmiKeyType->Parse = CmiObjectParse;
CmiKeyType->Security = NULL;
CmiKeyType->QueryName = NULL;
CmiKeyType->OkayToClose = NULL;
@ -132,15 +196,19 @@ CmInitializeRegistry(VOID)
/* FIXME: This should be split into two objects, 1 system and 1 user */
RtlInitUnicodeString(&RootKeyName, L"\\Registry");
InitializeObjectAttributes(&ObjectAttributes, &RootKeyName, 0, NULL, NULL);
Status = ObCreateObject(&RootKeyHandle,
ObCreateObject(&RootKeyHandle,
STANDARD_RIGHTS_REQUIRED,
&ObjectAttributes,
CmiKeyType);
KeInitializeSpinLock(&CmiKeylistLock);
KeInitializeSpinLock(&CmiKeyListLock);
/* Build volitile registry store */
CmiVolatileFile = CmiCreateRegistry(NULL);
/* Build system registry store */
CmiSystemFile = CmiCreateRegistry(SYSTEM_REG_FILE);
/* FIXME: build volitile registry store */
/* FIXME: map / build registry data */
/* FIXME: Create initial predefined symbolic links */
/* HKEY_LOCAL_MACHINE */
/* HKEY_USERS */
@ -179,7 +247,7 @@ ZwCreateKey(OUT PHANDLE KeyHandle,
#if PROTO_REG
PWSTR KeyNameBuf;
NTSTATUS Status;
PKEY_TYPE CurKey;
PKEY_OBJECT CurKey, NewKey;
PREGISTRY_FILE FileToUse;
PKEY_BLOCK KeyBlock;
@ -233,7 +301,7 @@ ZwCreateKey(OUT PHANDLE KeyHandle,
}
/* Create new key object and put into linked list */
NewKey = ObGenericCreateObject(KeyHandle,
NewKey = ObCreateObject(KeyHandle,
DesiredAccess,
NULL,
CmiKeyType);
@ -244,6 +312,7 @@ ZwCreateKey(OUT PHANDLE KeyHandle,
NewKey->Flags = 0;
NewKey->Name = KeyNameBuf;
NewKey->KeyBlock = KeyBlock;
NewKey->RegistryFile = FileToUse;
CmiAddKeyToList(NewKey);
Status = ObCreateHandle(PsGetCurrentProcess(),
CurKey,
@ -267,30 +336,22 @@ NTSTATUS
ZwDeleteKey(IN HANDLE KeyHandle)
{
#ifdef PROTO_REG
PHANDLE_REP KeyHandleRep;
POBJECT_HEADER KeyObjectHeader;
NTSTATUS Status;
PKEY_OBJECT KeyObject;
/* Verify that the handle is valid and is a registry key */
KeyHandleRep = ObTranslateHandle(PsGetCurrentProcess(), KeyHandle);
if (KeyHandleRep == NULL)
Status = ObReferenceObjectByHandle(KeyHandle,
KEY_WRITE,
CmiKeyType,
UserMode,
(PVOID *)&KeyObject,
NULL);
if (!NT_SUCCESS(Status))
{
return STATUS_INVALID_HANDLE;
}
KeyObjectHeader = BODY_TO_HEADER(KeyHandleRep->ObjectBody);
if (KeyObjectHeader->ObjectType != CmiKeyType)
{
return STATUS_INVALID_HANDLE;
}
/* Verify required access for delete */
if ((KeyHandleRep & KEY_DELETE_ACCESS) != KEY_DELETE_ACCESS)
{
return STATUS_ACCESS_DENIED;
return Status;
}
/* Set the marked for delete bit in the key object */
KeyObject = (PKEY_OBJECT) KeyHandleRep->ObjectBody;
KeyObject->Flags |= KO_MARKED_FOR_DELETE;
/* Dereference the object */
@ -330,48 +391,42 @@ ZwEnumerateKey(IN HANDLE KeyHandle,
{
#ifdef PROTO_REG
NTSTATUS Status;
PHANDLE_REP KeyHandleRep;
POBJECT_HEADER KeyObjectHeader;
PKEY_OBJECT KeyObject;
PREGISTRY_FILE RegistryFile;
PKEY_BLOCK KeyBlock, SubKeyBlock;
PHASH_TABLE_BLOCK HashTableBlock;
PWSTR ClassBlock;
PKEY_BASIC_INFORMATION KeyBasicInformation;
PKEY_NODE_INFORMATION KeyNodeInformation;
PKEY_FULL_INFORMATION KeyFullInformation;
PKEY_BASIC_INFORMATION BasicInformation;
PKEY_NODE_INFORMATION NodeInformation;
PKEY_FULL_INFORMATION FullInformation;
/* Verify that the handle is valid and is a registry key */
KeyHandleRep = ObTranslateHandle(PsGetCurrentProcess(), KeyHandle);
if (KeyHandleRep == NULL)
Status = ObReferenceObjectByHandle(KeyHandle,
KEY_ENUMERATE_SUB_KEYS,
CmiKeyType,
UserMode,
(PVOID *)&KeyObject,
NULL);
if (!NT_SUCCESS(Status))
{
return STATUS_INVALID_HANDLE;
}
KeyObjectHeader = BODY_TO_HEADER(KeyHandleRep->ObjectBody);
if (KeyObjectHeader->ObjectType != CmiKeyObject)
{
return STATUS_INVALID_HANDLE;
}
/* Verify required access for enumerate */
if ((KeyHandleRep->AccessGranted & KEY_ENUMERATE_SUB_KEY) !=
KEY_ENUMERATE_SUB_KEY)
{
return STATUS_ACCESS_DENIED;
return Status;
}
/* Get pointer to KeyBlock */
KeyObject = (PKEY_OBJECT) KeyHandleRep->ObjectBody;
KeyBlock = KeyObject->KeyBlock;
RegistryFile = KeyObject->RegistryFile;
/* Get pointer to SubKey */
HashTableBlock = CmiGetHashTableBlock(KeyBlock);
SubKeyBlock = CmiGetKeyFromHashByIndex(HashTableBlock, Index);
HashTableBlock = CmiGetHashTableBlock(RegistryFile, KeyBlock);
SubKeyBlock = CmiGetKeyFromHashByIndex(RegistryFile,
HashTableBlock,
Index);
if (SubKeyBlock == NULL)
{
return STATUS_NO_MORE_ENTRIES;
}
CmiLockBlock(SubKeyBlock);
CmiLockBlock(RegistryFile, SubKeyBlock);
Status = STATUS_SUCCESS;
switch (KeyInformationClass)
{
@ -385,15 +440,15 @@ ZwEnumerateKey(IN HANDLE KeyHandle,
else
{
/* Fill buffer with requested info */
KeyBasicInformation = (PKEY_BASIC_INFORMATION) KeyInformation;
KeyBasicInformation->LastWriteTime = SubKeyBlock->LastWriteTime;
KeyBasicInformation->TitleIndex = Index;
KeyBasicInformation->NameLength = SubKeyBlock->NameSize;
wcsncpy(KeyBasicInformation->Name,
BasicInformation = (PKEY_BASIC_INFORMATION) KeyInformation;
BasicInformation->LastWriteTime = SubKeyBlock->LastWriteTime;
BasicInformation->TitleIndex = Index;
BasicInformation->NameLength = SubKeyBlock->NameSize;
wcsncpy(BasicInformation->Name,
SubKeyBlock->Name,
SubKeyBlock->NameSize);
KeyBasicInformation->Name[SubKeyBlock->NameSize] = 0;
*ReturnLength = sizeof(KEY_BASIC_INFORMATION) +
BasicInformation->Name[SubKeyBlock->NameSize] = 0;
*ResultLength = sizeof(KEY_BASIC_INFORMATION) +
SubKeyBlock->NameSize * sizeof(WCHAR);
}
break;
@ -409,27 +464,30 @@ ZwEnumerateKey(IN HANDLE KeyHandle,
else
{
/* Fill buffer with requested info */
KeyNodeInformation = (PKEY_NODE_INFORMATION) KeyInformation;
KeyNodeInformation->LastWriteTime = SubKeyBlock->LastWriteTime;
KeyNodeInformation->TitleIndex = Index;
KeyNodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) +
NodeInformation = (PKEY_NODE_INFORMATION) KeyInformation;
NodeInformation->LastWriteTime = SubKeyBlock->LastWriteTime;
NodeInformation->TitleIndex = Index;
NodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) +
SubKeyBlock->NameSize * sizeof(WCHAR);
KeyNodeInformation->ClassLength = SubKeyBlock->ClassSize;
KeyNodeInformation->NameLength = SubKeyBlock->NameSize;
wcsncpy(KeyNodeInformation->Name,
NodeInformation->ClassLength = SubKeyBlock->ClassSize;
NodeInformation->NameLength = SubKeyBlock->NameSize;
wcsncpy(NodeInformation->Name,
SubKeyBlock->Name,
SubKeyBlock->NameSize);
KeyNodeInformation->Name[SubKeyBlock->NameSize] = 0;
NodeInformation->Name[SubKeyBlock->NameSize] = 0;
if (SubKeyBlock->ClassSize != 0)
{
ClassBlock = CmiGetClassBlock(SubKeyBlock);
ClassBlock = CmiGetClassBlock(RegistryFile, SubKeyBlock);
wcsncpy(KeyNodeInformation->Name + SubKeyBlock->NameSize + 1,
wcsncpy(NodeInformation->Name + SubKeyBlock->NameSize + 1,
ClassBlock,
SubKeyBlock->ClassSize);
KeyNodeInformation->
NodeInformation->
Name[SubKeyBlock->NameSize + 1 + SubKeyBlock->ClassSize] = 0;
}
*ResultLength = sizeof(KEY_NODE_INFORMATION) +
SubKeyBlock->NameSize * sizeof(WCHAR) +
(SubKeyBlock->ClassSize + 1) * sizeof(WCHAR);
}
break;
@ -443,31 +501,35 @@ ZwEnumerateKey(IN HANDLE KeyHandle,
else
{
/* FIXME: fill buffer with requested info */
KeyFullInformation = (PKEY_FULL_INFORMATION) KeyInformation;
KeyFullInformation->LastWriteTime = SubKeyBlock->LastWriteTime;
KeyFullInformation->TitleIndex = Index;
KeyFullInformation->ClassOffset = sizeof(KEY_FULL_INFORMATION) -
FullInformation = (PKEY_FULL_INFORMATION) KeyInformation;
FullInformation->LastWriteTime = SubKeyBlock->LastWriteTime;
FullInformation->TitleIndex = Index;
FullInformation->ClassOffset = sizeof(KEY_FULL_INFORMATION) -
sizeof(WCHAR);
KeyFullInformation->ClassLength = SubKeyBlock->ClassSize;
KeyFullInformation->SubKeys = SubKeyBlock->NumberOfSubKeys;
KeyFullInformation->MaxNameLen = CmiGetMaxNameLength(SubKeyBlock);
KeyFullInformation->MaxClassLen = CmiGetMaxClassLength(SubKeyBlock);
KeyFullInformation->Values = ;
KeyFullInformation->MaxValueNameLen =
CmiGetMaxValueNameLength(SubKeyBlock);
KeyFullInformation->MaxValueDataLen =
CmiGetMaxValueDataLength(SubKeyBlock);
ClassBlock = CmiGetClassBlock(SubKeyBlock);
CmiLockBlock(ClassBlock);
wcsncpy(KeyFullInformation->Class,
FullInformation->ClassLength = SubKeyBlock->ClassSize;
FullInformation->SubKeys = SubKeyBlock->NumberOfSubKeys;
FullInformation->MaxNameLen =
CmiGetMaxNameLength(RegistryFile, SubKeyBlock);
FullInformation->MaxClassLen =
CmiGetMaxClassLength(RegistryFile, SubKeyBlock);
FullInformation->Values = SubKeyBlock->NumberOfValues;
FullInformation->MaxValueNameLen =
CmiGetMaxValueNameLength(RegistryFile, SubKeyBlock);
FullInformation->MaxValueDataLen =
CmiGetMaxValueDataLength(RegistryFile, SubKeyBlock);
ClassBlock = CmiGetClassBlock(RegistryFile, SubKeyBlock);
CmiLockBlock(RegistryFile, ClassBlock);
wcsncpy(FullInformation->Class,
ClassBlock,
SubKeyBlock->ClassSize);
CmiUnlockBlock(ClassBlock);
KeyFullInformation->Class[SubKeyBlock->ClassSize] = 0;
CmiUnlockBlock(RegistryFile, ClassBlock);
FullInformation->Class[SubKeyBlock->ClassSize] = 0;
*ResultLength = sizeof(KEY_FULL_INFORMATION) +
SubKeyBlock->ClassSize * sizeof(WCHAR);
}
break;
}
CmiUnlockBlock(SubKeyBlock);
CmiUnlockBlock(RegistryFile, SubKeyBlock);
return Status;
#else
@ -538,9 +600,11 @@ ZwOpenKey(OUT PHANDLE KeyHandle,
IN POBJECT_ATTRIBUTES ObjectAttributes)
{
#ifdef PROTO_REG
NTSTATUS Status;
PWSTR KeyNameBuf;
PREGISTRY_FILE FileToUse;
PKEY_BLOCK KeyBlock;
PKEY_OBJECT CurKey;
PKEY_OBJECT CurKey, NewKey;
/* Construct the complete registry relative pathname */
Status = CmiBuildKeyPath(&KeyNameBuf, ObjectAttributes);
@ -573,6 +637,16 @@ ZwOpenKey(OUT PHANDLE KeyHandle,
}
/* Open the key in the registry file */
FileToUse = CmiSystemFile;
Status = CmiFindKey(FileToUse,
KeyNameBuf,
&KeyBlock,
DesiredAccess,
0,
NULL);
if (!NT_SUCCESS(Status))
{
FileToUse = CmiVolatileFile;
Status = CmiFindKey(FileToUse,
KeyNameBuf,
&KeyBlock,
@ -585,9 +659,10 @@ ZwOpenKey(OUT PHANDLE KeyHandle,
return Status;
}
}
/* Create new key object and put into linked list */
NewKey = ObGenericCreateObject(KeyHandle,
NewKey = ObCreateObject(KeyHandle,
DesiredAccess,
NULL,
CmiKeyType);
@ -597,6 +672,7 @@ ZwOpenKey(OUT PHANDLE KeyHandle,
}
NewKey->Flags = 0;
NewKey->Name = KeyNameBuf;
NewKey->RegistryFile = FileToUse;
NewKey->KeyBlock = KeyBlock;
CmiAddKeyToList(NewKey);
Status = ObCreateHandle(PsGetCurrentProcess(),
@ -634,38 +710,31 @@ ZwQueryKey(IN HANDLE KeyHandle,
{
#ifdef PROTO_REG
NTSTATUS Status;
PHANDLE_REP KeyHandleRep;
POBJECT_HEADER KeyObjectHeader;
PKEY_OBJECT KeyObject;
PREGISTRY_FILE RegistryFile;
PKEY_BLOCK KeyBlock;
PWSTR ClassBlock;
PKEY_BASIC_INFORMATION KeyBasicInformation;
PKEY_NODE_INFORMATION KeyNodeInformation;
PKEY_FULL_INFORMATION KeyFullInformation;
PKEY_BASIC_INFORMATION BasicInformation;
PKEY_NODE_INFORMATION NodeInformation;
PKEY_FULL_INFORMATION FullInformation;
/* Verify that the handle is valid and is a registry key */
KeyHandleRep = ObTranslateHandle(PsGetCurrentProcess(), KeyHandle);
if (KeyHandleRep == NULL)
Status = ObReferenceObjectByHandle(KeyHandle,
KEY_READ,
CmiKeyType,
UserMode,
(PVOID *)&KeyObject,
NULL);
if (!NT_SUCCESS(Status))
{
return STATUS_INVALID_HANDLE;
}
KeyObjectHeader = BODY_TO_HEADER(KeyHandleRep->ObjectBody);
if (KeyObjectHeader->ObjectType != CmiKeyObject)
{
return STATUS_INVALID_HANDLE;
}
/* Verify required access for enumerate */
if ((KeyHandleRep->AccessGranted & KEY_QUERY_KEY) != KEY_QUERY_KEY)
{
return STATUS_ACCESS_DENIED;
return Status;
}
/* Get pointer to KeyBlock */
KeyObject = (PKEY_OBJECT) KeyHandleRep->ObjectBody;
KeyBlock = KeyObject->KeyBlock;
RegistryFile = KeyObject->RegistryFile;
CmiLockBlock(KeyBlock);
CmiLockBlock(RegistryFile, KeyBlock);
Status = STATUS_SUCCESS;
switch (KeyInformationClass)
{
@ -679,15 +748,15 @@ ZwQueryKey(IN HANDLE KeyHandle,
else
{
/* Fill buffer with requested info */
KeyBasicInformation = (PKEY_BASIC_INFORMATION) KeyInformation;
KeyBasicInformation->LastWriteTime = KeyBlock->LastWriteTime;
KeyBasicInformation->TitleIndex = 0;
KeyBasicInformation->NameLength = KeyBlock->NameSize;
wcsncpy(KeyBasicInformation->Name,
BasicInformation = (PKEY_BASIC_INFORMATION) KeyInformation;
BasicInformation->LastWriteTime = KeyBlock->LastWriteTime;
BasicInformation->TitleIndex = 0;
BasicInformation->NameLength = KeyBlock->NameSize;
wcsncpy(BasicInformation->Name,
KeyBlock->Name,
KeyBlock->NameSize);
KeyBasicInformation->Name[KeyBlock->NameSize] = 0;
*ReturnLength = sizeof(KEY_BASIC_INFORMATION) +
BasicInformation->Name[KeyBlock->NameSize] = 0;
*ResultLength = sizeof(KEY_BASIC_INFORMATION) +
KeyBlock->NameSize * sizeof(WCHAR);
}
break;
@ -703,28 +772,31 @@ ZwQueryKey(IN HANDLE KeyHandle,
else
{
/* Fill buffer with requested info */
KeyNodeInformation = (PKEY_NODE_INFORMATION) KeyInformation;
KeyNodeInformation->LastWriteTime = KeyBlock->LastWriteTime;
KeyNodeInformation->TitleIndex = 0;
KeyNodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) +
NodeInformation = (PKEY_NODE_INFORMATION) KeyInformation;
NodeInformation->LastWriteTime = KeyBlock->LastWriteTime;
NodeInformation->TitleIndex = 0;
NodeInformation->ClassOffset = sizeof(KEY_NODE_INFORMATION) +
KeyBlock->NameSize * sizeof(WCHAR);
KeyNodeInformation->ClassLength = KeyBlock->ClassSize;
KeyNodeInformation->NameLength = KeyBlock->NameSize;
wcsncpy(KeyNodeInformation->Name,
NodeInformation->ClassLength = KeyBlock->ClassSize;
NodeInformation->NameLength = KeyBlock->NameSize;
wcsncpy(NodeInformation->Name,
KeyBlock->Name,
KeyBlock->NameSize);
KeyNodeInformation->Name[KeyBlock->NameSize] = 0;
NodeInformation->Name[KeyBlock->NameSize] = 0;
if (KeyBlock->ClassSize != 0)
{
ClassBlock = CmiGetClassBlock(KeyBlock);
CmiLockBlock(ClassBlock);
wcsncpy(KeyNodeInformation->Name + KeyBlock->NameSize + 1,
ClassBlock = CmiGetClassBlock(RegistryFile, KeyBlock);
CmiLockBlock(RegistryFile, ClassBlock);
wcsncpy(NodeInformation->Name + KeyBlock->NameSize + 1,
ClassBlock,
KeyBlock->ClassSize);
CmiUnlockBlock(ClassBlock);
KeyNodeInformation->
CmiUnlockBlock(RegistryFile, ClassBlock);
NodeInformation->
Name[KeyBlock->NameSize + 1 + KeyBlock->ClassSize] = 0;
}
*ResultLength = sizeof(KEY_NODE_INFORMATION) +
KeyBlock->NameSize * sizeof(WCHAR) +
(KeyBlock->ClassSize + 1) * sizeof(WCHAR);
}
break;
@ -737,32 +809,36 @@ ZwQueryKey(IN HANDLE KeyHandle,
}
else
{
/* FIXME: fill buffer with requested info */
KeyFullInformation = (PKEY_FULL_INFORMATION) KeyInformation;
KeyFullInformation->LastWriteTime = KeyBlock->LastWriteTime;
KeyFullInformation->TitleIndex = 0;
KeyFullInformation->ClassOffset = sizeof(KEY_FULL_INFORMATION) -
/* Fill buffer with requested info */
FullInformation = (PKEY_FULL_INFORMATION) KeyInformation;
FullInformation->LastWriteTime = KeyBlock->LastWriteTime;
FullInformation->TitleIndex = 0;
FullInformation->ClassOffset = sizeof(KEY_FULL_INFORMATION) -
sizeof(WCHAR);
KeyFullInformation->ClassLength = KeyBlock->ClassSize;
KeyFullInformation->SubKeys = KeyBlock->NumberOfSubKeys;
KeyFullInformation->MaxNameLen = CmiGetMaxNameLength(KeyBlock);
KeyFullInformation->MaxClassLen = CmiGetMaxClassLength(KeyBlock);
KeyFullInformation->Values = ?;
KeyFullInformation->MaxValueNameLen =
CmiGetMaxValueNameLength(KeyBlock);
KeyFullInformation->MaxValueDataLen =
CmiGetMaxValueDataLength(KeyBlock);
ClassBlock = CmiGetClassBlock(KeyBlock);
CmiLockBlock(ClassBlock);
wcsncpy(KeyFullInformation->Class,
FullInformation->ClassLength = KeyBlock->ClassSize;
FullInformation->SubKeys = KeyBlock->NumberOfSubKeys;
FullInformation->MaxNameLen =
CmiGetMaxNameLength(RegistryFile, KeyBlock);
FullInformation->MaxClassLen =
CmiGetMaxClassLength(RegistryFile, KeyBlock);
FullInformation->Values = KeyBlock->NumberOfValues;
FullInformation->MaxValueNameLen =
CmiGetMaxValueNameLength(RegistryFile, KeyBlock);
FullInformation->MaxValueDataLen =
CmiGetMaxValueDataLength(RegistryFile, KeyBlock);
ClassBlock = CmiGetClassBlock(RegistryFile, KeyBlock);
CmiLockBlock(RegistryFile, ClassBlock);
wcsncpy(FullInformation->Class,
ClassBlock,
KeyBlock->ClassSize);
CmiUnlockBlock(ClassBlock);
KeyFullInformation->Class[KeyBlock->ClassSize] = 0;
CmiUnlockBlock(RegistryFile, ClassBlock);
FullInformation->Class[KeyBlock->ClassSize] = 0;
*ResultLength = sizeof(KEY_FULL_INFORMATION) +
KeyBlock->ClassSize * sizeof(WCHAR);
}
break;
}
CmiUnlockBlock(KeyBlock);
CmiUnlockBlock(RegistryFile, KeyBlock);
return Status;
#else
@ -796,38 +872,31 @@ ZwQueryValueKey(IN HANDLE KeyHandle,
{
#ifdef PROTO_REG
NTSTATUS Status;
PHANDLE_REP KeyHandleRep;
POBJECT_HEADER KeyObjectHeader;
PKEY_OBJECT KeyObject;
PREGISTRY_FILE RegistryFile;
PKEY_BLOCK KeyBlock;
PKEY_VALUE_BASIC_INFORMATION KeyValueBasicInformation;
PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInformation;
PKEY_VALUE_FULL_INFORMATION KeyValueFullInformation;
PKEY_VALUE_BASIC_INFORMATION ValueBasicInformation;
PKEY_VALUE_PARTIAL_INFORMATION ValuePartialInformation;
PKEY_VALUE_FULL_INFORMATION ValueFullInformation;
/* Verify that the handle is valid and is a registry key */
KeyHandleRep = ObTranslateHandle(PsGetCurrentProcess(), KeyHandle);
if (KeyHandleRep == NULL)
Status = ObReferenceObjectByHandle(KeyHandle,
KEY_QUERY_VALUE,
CmiKeyType,
UserMode,
(PVOID *)&KeyObject,
NULL);
if (!NT_SUCCESS(Status))
{
return STATUS_INVALID_HANDLE;
}
KeyObjectHeader = BODY_TO_HEADER(KeyHandleRep->ObjectBody);
if (KeyObjectHeader->ObjectType != CmiKeyObject)
{
return STATUS_INVALID_HANDLE;
}
/* Verify required access for enumerate */
if ((KeyHandleRep->AccessGranted & KEY_QUERY_KEY) != KEY_QUERY_KEY)
{
return STATUS_ACCESS_DENIED;
return Status;
}
/* Get pointer to KeyBlock */
KeyObject = (PKEY_OBJECT) KeyHandleRep->ObjectBody;
KeyBlock = KeyObject->KeyBlock;
RegistryFile = KeyObject->RegistryFile;
Status = STATUS_SUCCESS;
CmiLockBlock(KeyBlock);
CmiLockBlock(RegistryFile, KeyBlock);
/* FIXME: get value list block */
/* FIXME: loop through value list */
@ -838,7 +907,7 @@ ZwQueryValueKey(IN HANDLE KeyHandle,
/* FIXME: copy data into buffer */
/* FIXME: set ResultLength */
CmiUnlockBlock(KeyBlock);
CmiUnlockBlock(RegistryFile, KeyBlock);
return Status;
#else
@ -1138,71 +1207,26 @@ NTSTATUS RtlWriteRegistryValue(ULONG RelativeTo,
/* ------------------------------------------ Private Implementation */
#if PROTO_REG
static PVOID
CmiObjectParse(PVOID ParsedObject, PWSTR* Path)
CmiObjectParse(PVOID ParsedObject, PWSTR *Path)
{
PWSTR S, SubKeyBuffer;
PKEY_OBJECT CurrentKey, ChildKey;
UNIMPLEMENTED
/* If the path is an empty string, we're done */
if (Path == NULL || Path[0] == 0)
{
/* FIXME: return the root key */
return NULL;
}
/* Extract subkey name from path */
S = *Path;
while (*S != '\\')
{
S++;
}
SubKeyBuffer = ExAllocatePool(NonPagedPool, (S - *Path) * sizeof(WSTR));
wstrncpy(SubKeyBuffer, *Path, (S - *Path));
SubKeyBuffer[S - *Path] = 0;
/* %%% Scan Key for matching SubKey */
CurrentKey = (PKEY_OBJECT) ParsedObject;
ChildKey = CurrentKey->
/* Move Key Object pointer to first child */
ParentKey = ParentKey->SubKeys;
/* Extract the next path component from requested path */
wstrncpy(CurLevel, S, T-S);
CurLevel[T-S] = 0;
DPRINT("CurLevel:[%w]", CurLevel);
/* Walk through children looking for path component */
while (ParentKey != NULL)
{
if (wstrcmp(CurLevel, ParentKey->Name) == 0)
{
break;
}
ParentKey = ParentKey->NextKey;
}
/* %%% If SubKey is not found return NULL */
/* %%% Adjust path to next level */
/* %%% Return object for SubKey */
ExFreePool(SubKeyBuffer);
}
static PVOID CmiObjectDelete(PVOID DeletedObject)
static VOID
CmiObjectDelete(PVOID DeletedObject)
{
/* FIXME: if marked for delete, then call CmiDeleteKey */
UNIMPLEMENTED;
}
static NTSTATUS
CmiBuildKeyPath(PWSTR *KeyPath, POBJECT_ATTRIBUTES ObjectAttributes)
{
ULONG KeyNameSize;
PWSTR KeyNameBuf;
/* FIXME: Verify ObjectAttributes is in \\Registry space and comppute size for path */
KeyNameSize = 0;
if (ObjectAttributes->RootDirectory != NULL)
@ -1262,33 +1286,164 @@ CmiAddKeyToList(PKEY_OBJECT NewKey)
}
static PKEY_OBJECT
CmiScanKeyList(PWSTR *KeyNameBuf)
CmiScanKeyList(PWSTR KeyName)
{
KIRQL OldIrql;
PKEY_OBJECT CurKey;
KeAcquireSpinLock(CmiKeyListLock, &OldIrql);
KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
CurKey = CmiKeyList;
while (CurKey != NULL && wcscmp(KeyPath, CurKey->Name) != 0)
while (CurKey != NULL && wcscmp(KeyName, CurKey->Name) != 0)
{
CurKey = CurKey->Next;
CurKey = CurKey->NextKey;
}
KeReleaseSpinLock(CmiKeyListLock, OldIrql);
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
return CurKey;
}
static PREGISTRY_FILE
CmiCreateRegistry(PWSTR Filename)
{
ULONG Idx;
PREGISTRY_FILE RegistryFile;
PHEADER_BLOCK HeaderBlock;
PHEAP_BLOCK HeapBlock;
PFREE_SUB_BLOCK FreeSubBlock;
RegistryFile = ExAllocatePool(NonPagedPool, sizeof(REGISTRY_FILE));
if (Filename != NULL)
{
UNIMPLEMENTED;
/* FIXME: Duplicate Filename */
/* FIXME: if file does not exist, create new file */
/* FIXME: else attempt to map the file */
}
else
{
RegistryFile->Filename = NULL;
RegistryFile->Data = NULL;
RegistryFile->Extend = CmiExtendVolatileFile;
RegistryFile->Flush = NULL;
RegistryFile->Data = CmiExtendVolatileFile(NULL, REG_BLOCK_SIZE * 2);
RtlZeroMemory(RegistryFile->Data, REG_BLOCK_SIZE * 2);
HeaderBlock = (PHEADER_BLOCK) RegistryFile->Data;
HeaderBlock->BlockId = 0x66676572;
HeaderBlock->DateModified.QuadPart = 0;
HeaderBlock->Unused2 = 1;
HeaderBlock->Unused3 = 3;
HeaderBlock->Unused5 = 1;
HeaderBlock->RootKeyBlock = 0;
HeaderBlock->BlockSize = REG_BLOCK_SIZE;
HeaderBlock->Unused6 = 1;
HeaderBlock->Checksum = 0;
for (Idx = 0; Idx < 127; Idx++)
{
HeaderBlock->Checksum += ((DWORD *)HeaderBlock)[Idx];
}
HeapBlock = (PHEAP_BLOCK)
((DWORD)RegistryFile->Data + REG_BLOCK_SIZE);
HeapBlock->BlockId = 0x6e696268;
HeapBlock->PreviousHeapBlock = -1;
HeapBlock->NextHeapBlock = -1;
HeapBlock->BlockSize = REG_BLOCK_SIZE;
FreeSubBlock = (PFREE_SUB_BLOCK)
((DWORD)HeapBlock + REG_HEAP_BLOCK_DATA_OFFSET);
FreeSubBlock->SubBlockSize =
-(REG_BLOCK_SIZE - REG_HEAP_BLOCK_DATA_OFFSET);
}
return RegistryFile;
}
static NTSTATUS
CmiCreateKey(PREGISTRY_FILE RegistryFile,
PWSTR KeyNameBuf,
PKEY_BLOCK KeyBlock,
PKEY_BLOCK *KeyBlock,
ACCESS_MASK DesiredAccess,
ULONG TitleIndex,
PUNICODE_STRING Class,
ULONG CreateOptions,
PULONG Disposition)
{
UNIMPLEMENTED;
}
static NTSTATUS
CmiFindKey(PREGISTRY_FILE RegistryFile,
PWSTR KeyNameBuf,
PKEY_BLOCK *KeyBlock,
ACCESS_MASK DesiredAccess,
ULONG TitleIndex,
PUNICODE_STRING Class)
{
UNIMPLEMENTED;
}
static PHASH_TABLE_BLOCK
CmiGetHashTableBlock(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock)
{
UNIMPLEMENTED;
}
static PKEY_BLOCK
CmiGetKeyFromHashByIndex(PREGISTRY_FILE RegistryFile,
PHASH_TABLE_BLOCK HashTableBlock,
ULONG Index)
{
UNIMPLEMENTED;
}
static VOID
CmiLockBlock(PREGISTRY_FILE RegistryFile,
PVOID Block)
{
UNIMPLEMENTED;
}
static VOID
CmiUnlockBlock(PREGISTRY_FILE RegistryFile,
PVOID Block)
{
UNIMPLEMENTED;
}
static PWSTR
CmiGetClassBlock(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock)
{
UNIMPLEMENTED;
}
static ULONG
CmiGetMaxNameLength(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock)
{
UNIMPLEMENTED;
}
static ULONG
CmiGetMaxClassLength(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock)
{
UNIMPLEMENTED;
}
static ULONG
CmiGetMaxValueNameLength(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock)
{
UNIMPLEMENTED;
}
static ULONG
CmiGetMaxValueDataLength(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock)
{
UNIMPLEMENTED;
}
#endif