Fixed remaining object name issues in NtLoadKey2() and NtUnloadKey().

svn path=/trunk/; revision=4809
This commit is contained in:
Eric Kohl 2003-06-01 15:10:52 +00:00
parent 813549499b
commit f170e40b0a
5 changed files with 221 additions and 88 deletions

View file

@ -428,7 +428,7 @@ CmiCreateRegistryHive(PWSTR Filename,
BOOLEAN CreateNew);
NTSTATUS
CmiLoadHive(PUNICODE_STRING KeyName,
CmiLoadHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
PUNICODE_STRING FileName,
ULONG Flags);
@ -567,11 +567,11 @@ CmiAddFree(PREGISTRY_HIVE RegistryHive,
BOOLEAN MergeFreeBlocks);
NTSTATUS
CmiConnectHive(PUNICODE_STRING KeyName,
CmiConnectHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
PREGISTRY_HIVE RegistryHive);
NTSTATUS
CmiDisconnectHive (PUNICODE_STRING KeyName,
CmiDisconnectHive (POBJECT_ATTRIBUTES KeyObjectAttributes,
PREGISTRY_HIVE *RegistryHive);
NTSTATUS

View file

@ -1,4 +1,4 @@
/* $Id: import.c,v 1.20 2003/05/30 22:28:14 ekohl Exp $
/* $Id: import.c,v 1.21 2003/06/01 15:10:52 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -166,6 +166,7 @@ BOOLEAN
CmImportSystemHive(PCHAR ChunkBase,
ULONG ChunkSize)
{
OBJECT_ATTRIBUTES ObjectAttributes;
PREGISTRY_HIVE RegistryHive;
UNICODE_STRING KeyName;
NTSTATUS Status;
@ -190,7 +191,12 @@ CmImportSystemHive(PCHAR ChunkBase,
/* Attach it to the machine key */
RtlInitUnicodeString (&KeyName,
L"\\Registry\\Machine\\System");
Status = CmiConnectHive (&KeyName,
InitializeObjectAttributes (&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = CmiConnectHive (&ObjectAttributes,
RegistryHive);
if (!NT_SUCCESS(Status))
{
@ -215,8 +221,8 @@ BOOLEAN
CmImportHardwareHive(PCHAR ChunkBase,
ULONG ChunkSize)
{
PREGISTRY_HIVE RegistryHive;
OBJECT_ATTRIBUTES ObjectAttributes;
PREGISTRY_HIVE RegistryHive;
UNICODE_STRING KeyName;
HANDLE HardwareKey;
ULONG Disposition;
@ -235,7 +241,7 @@ CmImportHardwareHive(PCHAR ChunkBase,
L"\\Registry\\Machine\\HARDWARE");
InitializeObjectAttributes (&ObjectAttributes,
&KeyName,
0,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtCreateKey (&HardwareKey,
@ -256,7 +262,7 @@ CmImportHardwareHive(PCHAR ChunkBase,
L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION");
InitializeObjectAttributes (&ObjectAttributes,
&KeyName,
0,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtCreateKey (&HardwareKey,
@ -277,7 +283,7 @@ CmImportHardwareHive(PCHAR ChunkBase,
L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP");
InitializeObjectAttributes (&ObjectAttributes,
&KeyName,
0,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtCreateKey (&HardwareKey,
@ -298,7 +304,7 @@ CmImportHardwareHive(PCHAR ChunkBase,
L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
InitializeObjectAttributes (&ObjectAttributes,
&KeyName,
0,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtCreateKey (&HardwareKey,
@ -337,7 +343,12 @@ CmImportHardwareHive(PCHAR ChunkBase,
/* Attach it to the machine key */
RtlInitUnicodeString (&KeyName,
L"\\Registry\\Machine\\HARDWARE");
Status = CmiConnectHive (&KeyName,
InitializeObjectAttributes (&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = CmiConnectHive (&ObjectAttributes,
RegistryHive);
if (!NT_SUCCESS(Status))
{

View file

@ -13,7 +13,8 @@
#include <internal/ob.h>
#include <limits.h>
#include <string.h>
#include <internal/pool.h>
//#include <internal/pool.h>
#include <internal/se.h>
#include <internal/registry.h>
#define NDEBUG
@ -1437,23 +1438,104 @@ NtLoadKey2 (IN POBJECT_ATTRIBUTES KeyObjectAttributes,
IN POBJECT_ATTRIBUTES FileObjectAttributes,
IN ULONG Flags)
{
POBJECT_NAME_INFORMATION NameInfo;
PUNICODE_STRING NamePointer;
PUCHAR Buffer;
ULONG BufferSize;
ULONG Length;
NTSTATUS Status;
DPRINT ("NtLoadKey2() called\n");
if (Flags & ~REG_NO_LAZY_FLUSH)
return STATUS_INVALID_PARAMETER;
#if 0
if (!SeSinglePrivilegeCheck (SeRestorePrivilege, KeGetPreviousMode ()))
return STATUS_PRIVILEGE_NOT_HELD;
#endif
/* FIXME: Get the absolute file name */
if (FileObjectAttributes->RootDirectory != NULL)
{
BufferSize =
sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR);
Buffer = ExAllocatePool (NonPagedPool,
BufferSize);
if (Buffer == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
Status = CmiLoadHive (KeyObjectAttributes->ObjectName,
FileObjectAttributes->ObjectName,
Status = NtQueryObject (FileObjectAttributes->RootDirectory,
ObjectNameInformation,
Buffer,
BufferSize,
&Length);
if (!NT_SUCCESS(Status))
{
DPRINT1 ("NtQueryObject() failed (Status %lx)\n", Status);
ExFreePool (Buffer);
return Status;
}
NameInfo = (POBJECT_NAME_INFORMATION)Buffer;
DPRINT ("ObjectPath: '%wZ' Length %hu\n",
&NameInfo->Name, NameInfo->Name.Length);
NameInfo->Name.MaximumLength = MAX_PATH * sizeof(WCHAR);
if (FileObjectAttributes->ObjectName->Buffer[0] != L'\\')
{
RtlAppendUnicodeToString (&NameInfo->Name,
L"\\");
DPRINT ("ObjectPath: '%wZ' Length %hu\n",
&NameInfo->Name, NameInfo->Name.Length);
}
RtlAppendUnicodeStringToString (&NameInfo->Name,
FileObjectAttributes->ObjectName);
DPRINT ("ObjectPath: '%wZ' Length %hu\n",
&NameInfo->Name, NameInfo->Name.Length);
NamePointer = &NameInfo->Name;
}
else
{
if (FileObjectAttributes->ObjectName->Buffer[0] == L'\\')
{
Buffer = NULL;
NamePointer = FileObjectAttributes->ObjectName;
}
else
{
BufferSize =
sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR);
Buffer = ExAllocatePool (NonPagedPool,
BufferSize);
if (Buffer == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
NameInfo = (POBJECT_NAME_INFORMATION)Buffer;
NameInfo->Name.MaximumLength = MAX_PATH * sizeof(WCHAR);
NameInfo->Name.Length = 0;
NameInfo->Name.Buffer = (PWSTR)((ULONG_PTR)Buffer + sizeof(OBJECT_NAME_INFORMATION));
NameInfo->Name.Buffer[0] = 0;
RtlAppendUnicodeToString (&NameInfo->Name,
L"\\");
RtlAppendUnicodeStringToString (&NameInfo->Name,
FileObjectAttributes->ObjectName);
NamePointer = &NameInfo->Name;
}
}
DPRINT ("Full name: '%wZ'\n", NamePointer);
Status = CmiLoadHive (KeyObjectAttributes,
NamePointer,
Flags);
if (!NT_SUCCESS (Status))
{
DPRINT1 ("CmiLoadHive() failed (Status %lx)\n", Status);
}
if (Buffer != NULL)
ExFreePool (Buffer);
return Status;
}
@ -1639,7 +1721,7 @@ NtUnloadKey (IN POBJECT_ATTRIBUTES KeyObjectAttributes)
DPRINT ("NtUnloadKey() called\n");
Status = CmiDisconnectHive (KeyObjectAttributes->ObjectName,
Status = CmiDisconnectHive (KeyObjectAttributes,
&RegistryHive);
if (!NT_SUCCESS (Status))
{

View file

@ -1157,7 +1157,7 @@ CmiCreateRegistryHive(PWSTR Filename,
NTSTATUS
CmiLoadHive(IN PUNICODE_STRING KeyName,
CmiLoadHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
IN PUNICODE_STRING FileName,
IN ULONG Flags)
{
@ -1166,6 +1166,9 @@ CmiLoadHive(IN PUNICODE_STRING KeyName,
DPRINT ("CmiLoadHive(Filename %wZ)\n", FileName);
if (Flags & ~REG_NO_LAZY_FLUSH)
return STATUS_INVALID_PARAMETER;
Hive = ExAllocatePool (NonPagedPool,
sizeof(REGISTRY_HIVE));
if (Hive == NULL)
@ -1211,7 +1214,7 @@ CmiLoadHive(IN PUNICODE_STRING KeyName,
VERIFY_REGISTRY_HIVE(Hive);
Status = CmiConnectHive (KeyName,
Status = CmiConnectHive (KeyObjectAttributes,
Hive);
if (!NT_SUCCESS(Status))
{

View file

@ -1,4 +1,4 @@
/* $Id: registry.c,v 1.99 2003/05/30 22:28:14 ekohl Exp $
/* $Id: registry.c,v 1.100 2003/06/01 15:10:52 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -498,11 +498,10 @@ CmiCreateCurrentControlSetLink(VOID)
NTSTATUS
CmiConnectHive(IN PUNICODE_STRING KeyName,
CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
IN PREGISTRY_HIVE RegistryHive)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING ParentKeyName;
UNICODE_STRING RemainingPath;
PKEY_OBJECT ParentKey;
PKEY_OBJECT NewKey;
NTSTATUS Status;
@ -511,48 +510,47 @@ CmiConnectHive(IN PUNICODE_STRING KeyName,
DPRINT("CmiConnectHive(%p, %wZ) called.\n",
RegistryHive, KeyName);
SubName = wcsrchr (KeyName->Buffer, L'\\');
if (SubName == NULL)
{
return STATUS_UNSUCCESSFUL;
}
ParentKeyName.Length = (USHORT)(SubName - KeyName->Buffer) * sizeof(WCHAR);
ParentKeyName.MaximumLength = ParentKeyName.Length + sizeof(WCHAR);
ParentKeyName.Buffer = ExAllocatePool (NonPagedPool,
ParentKeyName.MaximumLength);
RtlCopyMemory (ParentKeyName.Buffer,
KeyName->Buffer,
ParentKeyName.Length);
ParentKeyName.Buffer[ParentKeyName.Length / sizeof(WCHAR)] = 0;
SubName++;
Status = ObReferenceObjectByName (&ParentKeyName,
OBJ_CASE_INSENSITIVE,
NULL,
STANDARD_RIGHTS_REQUIRED,
CmiKeyType,
KernelMode,
NULL,
(PVOID*)&ParentKey);
RtlFreeUnicodeString (&ParentKeyName);
Status = ObFindObject(KeyObjectAttributes,
(PVOID*)&ParentKey,
&RemainingPath,
CmiKeyType);
if (!NT_SUCCESS(Status))
{
DPRINT1 ("ObReferenceObjectByName() failed (Status %lx)\n", Status);
return Status;
return(Status);
}
InitializeObjectAttributes(&ObjectAttributes,
KeyName,
0,
NULL,
NULL);
DPRINT ("RemainingPath %wZ\n", &RemainingPath);
if ((RemainingPath.Buffer == NULL) || (RemainingPath.Buffer[0] == 0))
{
ObDereferenceObject (ParentKey);
return STATUS_OBJECT_NAME_COLLISION;
}
/* If RemainingPath contains \ we must return error
because CmiConnectHive() can not create trees */
SubName = RemainingPath.Buffer;
if (*SubName == L'\\')
SubName++;
if (wcschr (SubName, L'\\') != NULL)
{
ObDereferenceObject (ParentKey);
return STATUS_OBJECT_NAME_NOT_FOUND;
}
DPRINT("RemainingPath %S ParentObject %x\n", RemainingPath.Buffer, Object);
Status = ObCreateObject(NULL,
STANDARD_RIGHTS_REQUIRED,
&ObjectAttributes,
NULL,
CmiKeyType,
(PVOID*)&NewKey);
if (!NT_SUCCESS(Status))
{
return(Status);
}
if (!NT_SUCCESS(Status))
{
DPRINT1 ("ObCreateObject() failed (Status %lx)\n", Status);
@ -560,6 +558,7 @@ CmiConnectHive(IN PUNICODE_STRING KeyName,
return Status;
}
NewKey->ParentKey = ParentKey;
NewKey->RegistryHive = RegistryHive;
NewKey->BlockOffset = RegistryHive->HiveHeader->RootKeyCell;
NewKey->KeyCell = CmiGetBlock(RegistryHive, NewKey->BlockOffset, NULL);
@ -602,64 +601,77 @@ CmiConnectHive(IN PUNICODE_STRING KeyName,
NTSTATUS
CmiDisconnectHive (IN PUNICODE_STRING KeyName,
CmiDisconnectHive (IN POBJECT_ATTRIBUTES KeyObjectAttributes,
OUT PREGISTRY_HIVE *RegistryHive)
{
PKEY_OBJECT KeyObject;
PREGISTRY_HIVE Hive;
HANDLE KeyHandle;
NTSTATUS Status;
DPRINT("CmiDisconnectHive() called\n");
*RegistryHive = NULL;
Status = ObReferenceObjectByName (KeyName,
OBJ_CASE_INSENSITIVE,
Status = ObOpenObjectByName (KeyObjectAttributes,
CmiKeyType,
NULL,
KernelMode,
STANDARD_RIGHTS_REQUIRED,
NULL,
&KeyHandle);
if (!NT_SUCCESS(Status))
{
DPRINT1 ("ObOpenObjectByName() failed (Status %lx)\n", Status);
return Status;
}
Status = ObReferenceObjectByHandle (KeyHandle,
STANDARD_RIGHTS_REQUIRED,
CmiKeyType,
KernelMode,
NULL,
(PVOID*)&KeyObject);
(PVOID*)&KeyObject,
NULL);
NtClose (KeyHandle);
if (!NT_SUCCESS(Status))
{
DPRINT1 ("ObReferenceObjectByName() failed (Status %lx)\n", Status);
return Status;
}
DPRINT("KeyObject %p Hive %p\n", KeyObject, KeyObject->RegistryHive);
DPRINT ("KeyObject %p Hive %p\n", KeyObject, KeyObject->RegistryHive);
if (!(KeyObject->KeyCell->Flags & REG_KEY_ROOT_CELL))
{
DPRINT1("Key is not the Hive-Root-Key\n");
ObDereferenceObject(KeyObject);
DPRINT1 ("Key is not the Hive-Root-Key\n");
ObDereferenceObject (KeyObject);
return STATUS_INVALID_PARAMETER;
}
if (ObGetObjectHandleCount(KeyObject) != 0 ||
ObGetObjectPointerCount(KeyObject) != 2)
if (ObGetObjectHandleCount (KeyObject) != 0 ||
ObGetObjectPointerCount (KeyObject) != 2)
{
DPRINT1("Hive is still in use\n");
ObDereferenceObject(KeyObject);
DPRINT1 ("Hive is still in use\n");
ObDereferenceObject (KeyObject);
return STATUS_UNSUCCESSFUL;
}
Hive = KeyObject->RegistryHive;
/* Dereference KeyObject twice to delete it */
ObDereferenceObject(KeyObject);
ObDereferenceObject(KeyObject);
ObDereferenceObject (KeyObject);
ObDereferenceObject (KeyObject);
*RegistryHive = Hive;
DPRINT("CmiDisconnectHive() done\n");
DPRINT ("CmiDisconnectHive() done\n");
return STATUS_SUCCESS;
}
static NTSTATUS
CmiInitializeSystemHive (PWSTR FileName,
PUNICODE_STRING KeyName)
CmiInitializeSystemHive (POBJECT_ATTRIBUTES KeyObjectAttributes,
PWSTR FileName)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING ControlSetKeyName;
@ -678,7 +690,7 @@ CmiInitializeSystemHive (PWSTR FileName,
return Status;
}
Status = CmiConnectHive (KeyName,
Status = CmiConnectHive (KeyObjectAttributes,
RegistryHive);
if (!NT_SUCCESS(Status))
{
@ -749,8 +761,8 @@ CmiInitializeSystemHive (PWSTR FileName,
NTSTATUS
CmiInitializeHive(PWSTR FileName,
PUNICODE_STRING KeyName,
CmiInitializeHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
PWSTR FileName,
BOOLEAN CreateNew)
{
PREGISTRY_HIVE RegistryHive;
@ -772,7 +784,7 @@ CmiInitializeHive(PWSTR FileName,
}
/* Connect the hive */
Status = CmiConnectHive(KeyName,
Status = CmiConnectHive(KeyObjectAttributes, //KeyName,
RegistryHive);
if (!NT_SUCCESS(Status))
{
@ -878,8 +890,13 @@ CmiInitHives(BOOLEAN SetupBoot)
RtlInitUnicodeString (&KeyName,
REG_SYSTEM_KEY_NAME);
Status = CmiInitializeSystemHive (ConfigPath,
&KeyName);
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = CmiInitializeSystemHive (&ObjectAttributes,
ConfigPath);
if (!NT_SUCCESS(Status))
{
DPRINT1("CmiInitializeSystemHive() failed (Status %lx)\n", Status);
@ -893,8 +910,13 @@ CmiInitHives(BOOLEAN SetupBoot)
RtlInitUnicodeString (&KeyName,
REG_SOFTWARE_KEY_NAME);
Status = CmiInitializeHive(ConfigPath,
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = CmiInitializeHive(&ObjectAttributes,
ConfigPath,
SetupBoot);
if (!NT_SUCCESS(Status))
{
@ -908,8 +930,13 @@ CmiInitHives(BOOLEAN SetupBoot)
RtlInitUnicodeString (&KeyName,
REG_SAM_KEY_NAME);
Status = CmiInitializeHive(ConfigPath,
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = CmiInitializeHive(&ObjectAttributes,
ConfigPath,
SetupBoot);
if (!NT_SUCCESS(Status))
{
@ -923,8 +950,13 @@ CmiInitHives(BOOLEAN SetupBoot)
RtlInitUnicodeString (&KeyName,
REG_SEC_KEY_NAME);
Status = CmiInitializeHive(ConfigPath,
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = CmiInitializeHive(&ObjectAttributes,
ConfigPath,
SetupBoot);
if (!NT_SUCCESS(Status))
{
@ -938,8 +970,13 @@ CmiInitHives(BOOLEAN SetupBoot)
RtlInitUnicodeString (&KeyName,
REG_DEFAULT_USER_KEY_NAME);
Status = CmiInitializeHive(ConfigPath,
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = CmiInitializeHive(&ObjectAttributes,
ConfigPath,
SetupBoot);
if (!NT_SUCCESS(Status))
{