mirror of
https://github.com/reactos/reactos.git
synced 2025-02-25 01:39:30 +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
|
* 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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue