more registry changes

svn path=/trunk/; revision=540
This commit is contained in:
Rex Jolliff 1999-06-07 15:14:23 +00:00
parent b5118cc48f
commit 06938a9103
2 changed files with 134 additions and 203 deletions

View file

@ -3,42 +3,6 @@
* Object Manager structures and typedefs * Object Manager structures and typedefs
*/ */
typedef struct _KEY_VALUE
{
ULONG Flags;
ULONG TitleIndex;
ULONG Type;
WCHAR *Name;
ULONG DataLength;
PVOID Data;
} KEY_VALUE, *PKEY_VALUE;
typedef struct _KEY_OBJECT
/*
* Type defining the Object Manager Key Object
*/
{
CSHORT Type;
CSHORT Size;
ULONG Flags;
LARGE_INTEGER LastWriteTime;
ULONG TitleIndex;
ULONG NumSubKeys;
ULONG MaxSubNameLength;
ULONG MaxSubClassLength;
struct _KEY_OBJECT *SubKeys;
ULONG NumValues;
ULONG MaxValueNameLength;
ULONG MaxValueDataLength;
PKEY_VALUE *Values;
WCHAR *Name;
WCHAR *Class;
struct _KEY_OBJECT *NextKey;
} KEY_OBJECT, *PKEY_OBJECT;
#define KO_MARKED_FOR_DELETE 0x00000001
/* /*
* key query information class * key query information class
*/ */

View file

@ -19,10 +19,26 @@
/* FILE STATICS *************************************************************/ /* FILE STATICS *************************************************************/
#if PROTO_REG #if PROTO_REG
POBJECT_TYPE CmKeyType = NULL;
PKEY_OBJECT RootKey = NULL;
static PVOID CmpObjectParse(PVOID ParsedObject, PWSTR *Path); typedef struct _KEY_OBJECT
/*
* Type defining the Object Manager Key Object
*/
{
CSHORT Type;
CSHORT Size;
ULONG Flags;
WCHAR *Name;
struct _KEY_OBJECT *NextKey;
} KEY_OBJECT, *PKEY_OBJECT;
#define KO_MARKED_FOR_DELETE 0x00000001
static POBJECT_TYPE CmiKeyType = NULL;
static PKEY_OBJECT CmiKeyList = NULL;
static PVOID CmiObjectParse(PVOID ParsedObject, PWSTR *Path);
#endif #endif
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -35,30 +51,31 @@ CmInitializeRegistry(VOID)
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
/* Initialize the Key object type */ /* Initialize the Key object type */
CmKeyType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); CmiKeyType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
CmKeyType->TotalObjects = 0; CmiKeyType->TotalObjects = 0;
CmKeyType->TotalHandles = 0; CmiKeyType->TotalHandles = 0;
CmKeyType->MaxObjects = ULONG_MAX; CmiKeyType->MaxObjects = ULONG_MAX;
CmKeyType->MaxHandles = ULONG_MAX; CmiKeyType->MaxHandles = ULONG_MAX;
CmKeyType->PagedPoolCharge = 0; CmiKeyType->PagedPoolCharge = 0;
CmKeyType->NonpagedPoolCharge = sizeof(KEY_OBJECT); CmiKeyType->NonpagedPoolCharge = sizeof(KEY_OBJECT);
CmKeyType->Dump = NULL; CmiKeyType->Dump = NULL;
CmKeyType->Open = NULL; CmiKeyType->Open = NULL;
CmKeyType->Close = NULL; CmiKeyType->Close = NULL;
CmKeyType->Delete = NULL; CmiKeyType->Delete = NULL;
CmKeyType->Parse = CmpObjectParse; CmiKeyType->Parse = CmpObjectParse;
CmKeyType->Security = NULL; CmiKeyType->Security = NULL;
CmKeyType->QueryName = NULL; CmiKeyType->QueryName = NULL;
CmKeyType->OkayToClose = NULL; CmiKeyType->OkayToClose = NULL;
RtlInitUnicodeString(&CmKeyType->TypeName, L"Key"); RtlInitUnicodeString(&CmiKeyType->TypeName, L"Key");
/* Build the Root Key Object */ /* Build the Root Key Object */
/* FIXME: This should be split into two objects, 1 system and 1 user */
RtlInitUnicodeString(&RootKeyName, L"\\Registry"); RtlInitUnicodeString(&RootKeyName, L"\\Registry");
InitializeObjectAttributes(&ObjectAttributes, &RootKeyName, 0, NULL, NULL); InitializeObjectAttributes(&ObjectAttributes, &RootKeyName, 0, NULL, NULL);
Status = ObCreateObject(&RootKeyHandle, Status = ObCreateObject(&RootKeyHandle,
STANDARD_RIGHTS_REQUIRED, STANDARD_RIGHTS_REQUIRED,
&ObjectAttributes, &ObjectAttributes,
ObKeyType); CmiKeyType);
/* FIXME: map / build registry data */ /* FIXME: map / build registry data */
/* FIXME: Create initial predefined symbolic links */ /* FIXME: Create initial predefined symbolic links */
@ -97,161 +114,52 @@ ZwCreateKey(PHANDLE KeyHandle,
PULONG Disposition) PULONG Disposition)
{ {
#if PROTO_REG #if PROTO_REG
NTSTATUS Status;
PKEY_TYPE CurKey;
/* FIXME: Should CurLevel be alloced to handle arbitrary size components? */ /* FIXME: Should CurLevel be alloced to handle arbitrary size components? */
WCHAR *S, *T, CurLevel[255]; WCHAR *S, *T, CurLevel[255];
PKEY_OBJECT ParentKey, CurSubKey, NewKey; PKEY_OBJECT ParentKey, CurSubKey, NewKey;
assert(ObjectAttributes != NULL); assert(ObjectAttributes != NULL);
/* FIXME: Verify ObjectAttributes is in \\Registry space */ Status = CmiBuildKeyPath(&KeyNameBuf, ObjectAttributes);
if (ObjectAttributes->RootDirectory == NULL) if (!NT_SUCCESS(Status))
{ {
S = ObjectAttributes->ObjectName; return Status;
if (wstrncmp(S, "\\Registry", 9))
{
return STATUS_UNSUCCESSFUL;
}
ParentKey = RootKey;
/* Get remainder of full key path after removal of \\Registry */
S += 9;
if (S[0] != '\\')
{
return STATUS_UNSUCCESSFUL;
}
S++;
/* Walk through key path and fail if any component does not exist */
while ((T = wstrchr(S, '\\')) != NULL)
{
/* 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;
}
/* Fail if path component was not one of the children */
if (ParentKey == NULL)
{
return STATUS_UNSUCCESSFUL;
}
/* Advance path string pointer to next component */
S = wstrchr(S, '\\') + 1;
}
/* Check for existance of subkey , return if it exists */
CurSubKey = ParentKey->SubKeys;
while (CurSubKey != NULL && wstrcmp(S, CurSubKey->Name) != 0)
{
CurSubKey = CurSubKey->NextKey;
}
if (CurSubKey != NULL)
{
/* FIXME: Fail if key is marked for deletion */
*Disposition = REG_KEY_ALREADY_EXISTS;
*KeyHandle = ObInsertHandle(KeGetCurrentProcess(),
HEADER_TO_BODY(CurSubKey),
DesiredAccess,
FALSE);
return STATUS_SUCCESS;
}
else
{
/* If KeyHandle is not the parent key, or is not open with */
/* KEY_CREATE_SUB_KEY permission, then fail */
KeyHandleRep = ObTranslateHandle(KeGetCurrentProcess(), KeyHandle);
if (KeyHandleRep == NULL ||
KeyHandleRep->ObjectBody != ParentKey ||
(KeyHandleRep->GrantedAccess & KEY_CREATE_SUB_KEY) == 0)
{
return STATUS_UNSUCCESSFUL;
}
/* Build new CmKeyType object */
NewKey = ObGenericCreateObject(KeyHandle,
DesiredAccess,
NULL,
CmKeyType);
if (NewKey == NULL)
{
return STATUS_UNSUCCESSFUL;
}
NewKey->Flags = 0;
KeQuerySystemTime(&NewKey->LastWriteTime);
NewKey->TitleIndex = 0;
NewKey->NumSubKeys = 0;
NewKey->MaxSubNameLength = 0;
NewKey->MaxSubClassLength = 0;
NewKey->SubKeys = NULL;
NewKey->NumValues = 0;
NewKey->MaxValueNameLength = 0;
NewKey->MaxValueDataLength = 0;
NewKey->Values = NULL;
NewKey->Name = ExAllocatePool(NonPagedPool,
(wstrlen(S) + 1) * sizeof(WCHAR));
wstrcpy(NewKey->Name, S);
if (Class != NULL)
{
NewKey->Class = ExAllocatePool(NonPagedPool,
(wstrlen(Class) + 1) *
sizeof(WCHAR));
wstrcpy(NewKey->Class, Class);
}
else
{
NewKey->Class = NULL;
}
NewKey->NextKey = NULL;
/* Add to end of parent key subkey list */
if (ParentKey->SubKeys == NULL)
{
ParentKey->SubKeys = NewKey;
}
else
{
CurSubKey = ParentKey->SubKeys;
while (CurSubKey->NextKey != NULL)
{
CurSubKey = CurSubKey->NextKey;
}
NewKey->TitleIndex = CurSubKey->TitleIndex + 1;
CurSubKey->NextKey = NewKey;
}
/* Increment parent key subkey count and set parent subkey maxes */
ParentKey->NumSubKeys++;
if (ParentKey->MaxSubNameLength < wstrlen(NewKey->Name))
{
ParentKey->MaxSubNameLength = wstrlen(NewKey->Name);
}
if (NewKey->Class != NULL &&
ParentKey->MaxSubClassLength < wstrlen(NewKey->Class))
{
ParentKey->MaxSubClassLength = wstrlen(NewKey->Class);
}
return STATUS_SUCCESS;
}
} }
else
/* FIXME: Scan the key list to see if key already open */
CurKey = CmiKeyList;
while (CurKey != NULL && wcscmp(KeyPath, CurKey->Name) != 0)
{ {
return STATUS_UNSUCCESSFUL; CurKey = CurKey->Next;
} }
if (CurKey != NULL)
{
/* FIXME: If so, return a reference to it */
/* FIXME: destroy KeyNameBuf before return */
/* FIXME:(?) we could check to see if the key still exists here... */
}
/* FIXME: Call CmiCreateKey to create/open the key in the registry file */
Status = CmiCreateKey(KeyNameBuf, TitleIndex, Class, Disposition);
/* Create new key object and put into linked list */
NewKey = ObGenericCreateObject(KeyHandle,
DesiredAccess,
NULL,
CmiKeyType);
if (NewKey == NULL)
{
return STATUS_UNSUCCESSFUL;
}
NewKey->Flags = 0;
NewKey->Name = KeyNameBuf;
NewKey->NextKey = CmiKeyList;
CmiKeyList = NewKey;
return STATUS_SUCCESS;
#endif #endif
UNIMPLEMENTED; UNIMPLEMENTED;
@ -679,9 +587,9 @@ NTSTATUS RtlWriteRegistryValue(ULONG RelativeTo,
/* ------------------------------------------ Private Implementation */ /* ------------------------------------------ Private Implementation */
#if 0 #if PROTO_REG
static PVOID static PVOID
CmpObjectParse(PVOID ParsedObject, PWSTR* Path) CmiObjectParse(PVOID ParsedObject, PWSTR* Path)
{ {
PWSTR S, SubKeyBuffer; PWSTR S, SubKeyBuffer;
PKEY_OBJECT CurrentKey, ChildKey; PKEY_OBJECT CurrentKey, ChildKey;
@ -733,6 +641,65 @@ CmpObjectParse(PVOID ParsedObject, PWSTR* Path)
ExFreePool(SubKeyBuffer); ExFreePool(SubKeyBuffer);
}
static NTSTATUS
CmiBuildKeyPath(PWSTR *KeyPath, POBJECT_ATTRIBUTES ObjectAttributes)
{
/* FIXME: Verify ObjectAttributes is in \\Registry space and comppute size for path */
KeyNameSize = 0;
if (ObjectAttributes->RootDirectory != NULL)
{
/* FIXME: determine type of object for RootDirectory */
/* FIXME: if object type is ObDirType */
/* FIXME: fail if RootDirectory != '\\' */
/* FIXME: check for 'Registry' in ObjectName, fail if missing */
/* FIXME: add size for remainder to KeyNameSize */
/* FIXME: else if object type is CmiKeyType */
/* FIXME: add size of Name from RootDirectory object to KeyNameSize */
/* FIXME: add 1 to KeyNamesize for '\\' */
/* FIXME: add size of ObjectName to KeyNameSize */
/* FIXME: else fail on incorrect type */
}
else
{
/* FIXME: check for \\Registry and fail if missing */
/* FIXME: add size of remainder to KeyNameSize */
}
KeyNameBuf = ExAllocatePool(NonPagedPool, KeyNameSize);
/* FIXME: Construct relative pathname */
KeyNameBuf[0] = 0;
if (ObjectAttributes->RootDirectory != NULL)
{
/* FIXME: determine type of object for RootDirectory */
/* FIXME: if object type is ObDirType */
/* FIXME: fail if RootDirectory != '\\' */
/* FIXME: check for 'Registry' in ObjectName, fail if missing */
/* FIXME: copy remainder into KeyNameBuf */
/* FIXME: else if object type is CmiKeyType */
/* FIXME: copy Name from RootDirectory object into KeyNameBuf */
/* FIXME: append '\\' into KeyNameBuf */
/* FIXME: append ObjectName into KeyNameBuf */
}
else
{
/* FIXME: check for \\Registry\\ and fail if missing */
/* FIXME: copy remainder into KeyNameBuf */
}
*KeyPath = KeyNameBuf;
return STATUS_SUCCESS;
}
static NTSTATUS
CmiCreateKey(PWSTR KeyNameBuf,
ULONG TitleIndex,
PUNICODE_STRING Class,
PULONG Disposition)
{
} }
#endif #endif