diff --git a/reactos/ntoskrnl/cm/cm.h b/reactos/ntoskrnl/cm/cm.h index 326835a2c5f..c6a3833a532 100644 --- a/reactos/ntoskrnl/cm/cm.h +++ b/reactos/ntoskrnl/cm/cm.h @@ -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 diff --git a/reactos/ntoskrnl/cm/import.c b/reactos/ntoskrnl/cm/import.c index 972cccc17bd..7da07ff08e2 100644 --- a/reactos/ntoskrnl/cm/import.c +++ b/reactos/ntoskrnl/cm/import.c @@ -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)) { diff --git a/reactos/ntoskrnl/cm/ntfunc.c b/reactos/ntoskrnl/cm/ntfunc.c index ebf4edc95e6..057030a2893 100644 --- a/reactos/ntoskrnl/cm/ntfunc.c +++ b/reactos/ntoskrnl/cm/ntfunc.c @@ -13,7 +13,8 @@ #include #include #include -#include +//#include +#include #include #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)) { diff --git a/reactos/ntoskrnl/cm/regfile.c b/reactos/ntoskrnl/cm/regfile.c index a5f3073aafd..b1fe6a3b417 100644 --- a/reactos/ntoskrnl/cm/regfile.c +++ b/reactos/ntoskrnl/cm/regfile.c @@ -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)) { diff --git a/reactos/ntoskrnl/cm/registry.c b/reactos/ntoskrnl/cm/registry.c index 0a994c24c2b..eec1616a239 100644 --- a/reactos/ntoskrnl/cm/registry.c +++ b/reactos/ntoskrnl/cm/registry.c @@ -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, - NULL, - STANDARD_RIGHTS_REQUIRED, - CmiKeyType, - KernelMode, - NULL, - (PVOID*)&KeyObject); + 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, + (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)) {