mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
more registry changes
svn path=/trunk/; revision=540
This commit is contained in:
parent
b5118cc48f
commit
06938a9103
2 changed files with 134 additions and 203 deletions
|
@ -3,42 +3,6 @@
|
|||
* 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
|
||||
*/
|
||||
|
|
|
@ -19,10 +19,26 @@
|
|||
/* FILE STATICS *************************************************************/
|
||||
|
||||
#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
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
@ -35,30 +51,31 @@ CmInitializeRegistry(VOID)
|
|||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
|
||||
/* Initialize the Key object type */
|
||||
CmKeyType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
|
||||
CmKeyType->TotalObjects = 0;
|
||||
CmKeyType->TotalHandles = 0;
|
||||
CmKeyType->MaxObjects = ULONG_MAX;
|
||||
CmKeyType->MaxHandles = ULONG_MAX;
|
||||
CmKeyType->PagedPoolCharge = 0;
|
||||
CmKeyType->NonpagedPoolCharge = sizeof(KEY_OBJECT);
|
||||
CmKeyType->Dump = NULL;
|
||||
CmKeyType->Open = NULL;
|
||||
CmKeyType->Close = NULL;
|
||||
CmKeyType->Delete = NULL;
|
||||
CmKeyType->Parse = CmpObjectParse;
|
||||
CmKeyType->Security = NULL;
|
||||
CmKeyType->QueryName = NULL;
|
||||
CmKeyType->OkayToClose = NULL;
|
||||
RtlInitUnicodeString(&CmKeyType->TypeName, L"Key");
|
||||
CmiKeyType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
|
||||
CmiKeyType->TotalObjects = 0;
|
||||
CmiKeyType->TotalHandles = 0;
|
||||
CmiKeyType->MaxObjects = ULONG_MAX;
|
||||
CmiKeyType->MaxHandles = ULONG_MAX;
|
||||
CmiKeyType->PagedPoolCharge = 0;
|
||||
CmiKeyType->NonpagedPoolCharge = sizeof(KEY_OBJECT);
|
||||
CmiKeyType->Dump = NULL;
|
||||
CmiKeyType->Open = NULL;
|
||||
CmiKeyType->Close = NULL;
|
||||
CmiKeyType->Delete = NULL;
|
||||
CmiKeyType->Parse = CmpObjectParse;
|
||||
CmiKeyType->Security = NULL;
|
||||
CmiKeyType->QueryName = NULL;
|
||||
CmiKeyType->OkayToClose = NULL;
|
||||
RtlInitUnicodeString(&CmiKeyType->TypeName, L"Key");
|
||||
|
||||
/* Build the Root Key Object */
|
||||
/* 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,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
&ObjectAttributes,
|
||||
ObKeyType);
|
||||
CmiKeyType);
|
||||
|
||||
/* FIXME: map / build registry data */
|
||||
/* FIXME: Create initial predefined symbolic links */
|
||||
|
@ -97,161 +114,52 @@ ZwCreateKey(PHANDLE KeyHandle,
|
|||
PULONG Disposition)
|
||||
{
|
||||
#if PROTO_REG
|
||||
NTSTATUS Status;
|
||||
PKEY_TYPE CurKey;
|
||||
|
||||
/* FIXME: Should CurLevel be alloced to handle arbitrary size components? */
|
||||
WCHAR *S, *T, CurLevel[255];
|
||||
PKEY_OBJECT ParentKey, CurSubKey, NewKey;
|
||||
|
||||
assert(ObjectAttributes != NULL);
|
||||
|
||||
/* FIXME: Verify ObjectAttributes is in \\Registry space */
|
||||
if (ObjectAttributes->RootDirectory == NULL)
|
||||
Status = CmiBuildKeyPath(&KeyNameBuf, ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
S = ObjectAttributes->ObjectName;
|
||||
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;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
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
|
||||
|
||||
UNIMPLEMENTED;
|
||||
|
@ -679,9 +587,9 @@ NTSTATUS RtlWriteRegistryValue(ULONG RelativeTo,
|
|||
|
||||
/* ------------------------------------------ Private Implementation */
|
||||
|
||||
#if 0
|
||||
#if PROTO_REG
|
||||
static PVOID
|
||||
CmpObjectParse(PVOID ParsedObject, PWSTR* Path)
|
||||
CmiObjectParse(PVOID ParsedObject, PWSTR* Path)
|
||||
{
|
||||
PWSTR S, SubKeyBuffer;
|
||||
PKEY_OBJECT CurrentKey, ChildKey;
|
||||
|
@ -733,6 +641,65 @@ CmpObjectParse(PVOID ParsedObject, PWSTR* Path)
|
|||
|
||||
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
|
||||
|
||||
|
|
Loading…
Reference in a new issue