mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
Wrote initial hack at ZwCreateKey and CmInitialize
svn path=/trunk/; revision=155
This commit is contained in:
parent
4159ed2941
commit
29ef6b5bac
1 changed files with 283 additions and 61 deletions
|
@ -14,76 +14,250 @@
|
||||||
|
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
/* FILE STATICS *************************************************************/
|
||||||
|
|
||||||
|
POBJECT_TYPE CmKeyType = NULL;
|
||||||
|
PKEY_OBJECT RootKey = NULL;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
NTSTATUS
|
VOID
|
||||||
STDCALL
|
CmInitializeRegistry(VOID)
|
||||||
NtInitializeRegistry(
|
|
||||||
BOOLEAN SetUpBoot
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return ZwInitializeRegistry(SetUpBoot);
|
ANSI_STRING AnsiString;
|
||||||
|
|
||||||
|
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 = NULL;
|
||||||
|
CmKeyType->Security = NULL;
|
||||||
|
CmKeyType->QueryName = NULL;
|
||||||
|
CmKeyType->OkayToClose = NULL;
|
||||||
|
|
||||||
|
RtlInitAnsiString(&AnsiString, "Key");
|
||||||
|
RtlAnsiStringToUnicodeString(&CmKeyType->TypeName, &AnsiString, TRUE);
|
||||||
|
|
||||||
|
RtlInitAnsiString(&AnsiString,"\\Registry");
|
||||||
|
RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
|
||||||
|
InitializeObjectAttributes(&attr, &UnicodeString, 0, NULL, NULL);
|
||||||
|
ZwCreateDirectoryObject(&handle, 0, &attr);
|
||||||
|
RtlFreeUnicodeString(UnicodeString);
|
||||||
|
|
||||||
|
/* FIXME: build initial registry skeleton */
|
||||||
|
RootKey = ObGenericCreateObject(NULL,
|
||||||
|
KEY_ALL_ACCESS,
|
||||||
|
NULL,
|
||||||
|
CmKeyType);
|
||||||
|
if (NewKey == NULL)
|
||||||
|
{
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
RootKey->Flags = 0;
|
||||||
|
KeQuerySystemTime(&RootKey->LastWriteTime);
|
||||||
|
RootKey->TitleIndex = 0;
|
||||||
|
RootKey->NumSubKeys = 0;
|
||||||
|
RootKey->MaxSubNameLength = 0;
|
||||||
|
RootKey->MaxSubClassLength = 0;
|
||||||
|
RootKey->SubKeys = NULL;
|
||||||
|
RootKey->NumValues = 0;
|
||||||
|
RootKey->MaxValueNameLength = 0;
|
||||||
|
RootKey->MaxValueDataLength = 0;
|
||||||
|
RootKey->Values = NULL;
|
||||||
|
RootKey->Name = ExAllocatePool(NonPagedPool, 2);
|
||||||
|
wstrcpy(RootKey->Name, "\\");
|
||||||
|
RootKey->Class = NULL;
|
||||||
|
RootKey->NextKey = NULL;
|
||||||
|
|
||||||
|
/* FIXME: Create initial predefined symbolic links */
|
||||||
|
/* HKEY_LOCAL_MACHINE */
|
||||||
|
/* HKEY_USERS */
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
NtCreateKey(PHANDLE KeyHandle,
|
||||||
ZwInitializeRegistry(
|
ACCESS_MASK DesiredAccess,
|
||||||
BOOLEAN SetUpBoot
|
POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
)
|
ULONG TitleIndex,
|
||||||
|
PUNICODE_STRING Class,
|
||||||
|
ULONG CreateOptions,
|
||||||
|
PULONG Disposition)
|
||||||
{
|
{
|
||||||
|
return ZwCreateKey(KeyHandle,
|
||||||
|
DesiredAccess,
|
||||||
|
ObjectAttributes,
|
||||||
|
TitleIndex,
|
||||||
|
Class,
|
||||||
|
CreateOptions,
|
||||||
|
Disposition);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
ZwCreateKey(PHANDLE KeyHandle,
|
||||||
|
ACCESS_MASK DesiredAccess,
|
||||||
|
POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
|
ULONG TitleIndex,
|
||||||
|
PUNICODE_STRING Class,
|
||||||
|
ULONG CreateOptions,
|
||||||
|
PULONG Disposition)
|
||||||
|
{
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
ParentKey = ParentKey->SubKeys;
|
||||||
|
wstrncpy(CurLevel, S, T-S);
|
||||||
|
CurLevel[T-S] = 0;
|
||||||
|
DPRINT("CurLevel:[%w]", CurLevel);
|
||||||
|
while (ParentKey != NULL)
|
||||||
|
{
|
||||||
|
if (wstrcmp(CurLevel, ParentKey->Name) == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ParentKey = ParentKey->NextKey;
|
||||||
|
}
|
||||||
|
if (ParentKey == NULL)
|
||||||
|
{
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
*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
|
||||||
|
{
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS RtlCheckRegistryKey(ULONG RelativeTo, PWSTR Path)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS RtlCreateRegistryKey(ULONG RelativeTo, PWSTR Path)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS RtlDeleteRegistryValue(ULONG RelativeTo, PWSTR Path,
|
|
||||||
PWSTR ValueName)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS RtlQueryRegistryValues(ULONG RelativeTo,
|
|
||||||
PWSTR Path,
|
|
||||||
PRTL_QUERY_REGISTRY_TABLE QueryTable,
|
|
||||||
PVOID Context,
|
|
||||||
PVOID Environment)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS RtlWriteRegistryValue(ULONG RelativeTo,
|
|
||||||
PWSTR Path,
|
|
||||||
PWSTR ValueName,
|
|
||||||
ULONG ValueType,
|
|
||||||
PVOID ValueData,
|
|
||||||
ULONG ValueLength)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS NtCreateKey(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess,
|
|
||||||
POBJECT_ATTRIBUTES ObjectAttributes, ULONG TitleIndex,
|
|
||||||
PUNICODE_STRING Class, ULONG CreateOptions,
|
|
||||||
PULONG Disposition)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS ZwCreateKey(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess,
|
|
||||||
POBJECT_ATTRIBUTES ObjectAttributes, ULONG TitleIndex,
|
|
||||||
PUNICODE_STRING Class, ULONG CreateOptions,
|
|
||||||
PULONG Disposition)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS NtDeleteKey(HANDLE KeyHandle)
|
NTSTATUS NtDeleteKey(HANDLE KeyHandle)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -461,3 +635,51 @@ ZwUnloadKey(
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
NtInitializeRegistry(BOOLEAN SetUpBoot)
|
||||||
|
{
|
||||||
|
return ZwInitializeRegistry(SetUpBoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
ZwInitializeRegistry(BOOLEAN SetUpBoot)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS RtlCheckRegistryKey(ULONG RelativeTo, PWSTR Path)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS RtlCreateRegistryKey(ULONG RelativeTo, PWSTR Path)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS RtlDeleteRegistryValue(ULONG RelativeTo, PWSTR Path,
|
||||||
|
PWSTR ValueName)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS RtlQueryRegistryValues(ULONG RelativeTo,
|
||||||
|
PWSTR Path,
|
||||||
|
PRTL_QUERY_REGISTRY_TABLE QueryTable,
|
||||||
|
PVOID Context,
|
||||||
|
PVOID Environment)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS RtlWriteRegistryValue(ULONG RelativeTo,
|
||||||
|
PWSTR Path,
|
||||||
|
PWSTR ValueName,
|
||||||
|
ULONG ValueType,
|
||||||
|
PVOID ValueData,
|
||||||
|
ULONG ValueLength)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue