X-Git-Url: http://git.jankratochvil.net/?p=reactos.git;a=blobdiff_plain;f=ntoskrnl%2Fcm%2Fregobj.c;fp=ntoskrnl%2Fcm%2Fregobj.c;h=9c6d25cbc74d6a2ba4c80e21bd2c2b85fb1026fd;hp=27944d557675e81869715dff96a730999fcebe96;hb=7c0cf90e3b750f1f0dc83b2eec9e5c68a512c30f;hpb=ee8b63255465d8c28be3e7bd11628015708fc1ab diff --git a/ntoskrnl/cm/regobj.c b/ntoskrnl/cm/regobj.c index 27944d5..9c6d25c 100644 --- a/ntoskrnl/cm/regobj.c +++ b/ntoskrnl/cm/regobj.c @@ -6,12 +6,12 @@ * UPDATE HISTORY: */ -#include +#define NTOS_MODE_KERNEL +#include #include #include #include #include -#include #include #include @@ -39,13 +39,13 @@ CmiObjectParse(PVOID ParsedObject, PKEY_OBJECT FoundObject; PKEY_OBJECT ParsedKey; PKEY_CELL SubKeyCell; - CHAR cPath[MAX_PATH]; NTSTATUS Status; PWSTR StartPtr; PWSTR EndPtr; ULONG Length; UNICODE_STRING LinkPath; UNICODE_STRING TargetPath; + UNICODE_STRING KeyName; ParsedKey = ParsedObject; @@ -72,27 +72,37 @@ CmiObjectParse(PVOID ParsedObject, else Length = wcslen(StartPtr); - wcstombs(cPath, StartPtr, Length); - cPath[Length] = 0; + KeyName.Length = Length * sizeof(WCHAR); + KeyName.MaximumLength = KeyName.Length + sizeof(WCHAR); + KeyName.Buffer = ExAllocatePool(NonPagedPool, + KeyName.MaximumLength); + RtlCopyMemory(KeyName.Buffer, + StartPtr, + KeyName.Length); + KeyName.Buffer[KeyName.Length / sizeof(WCHAR)] = 0; - FoundObject = CmiScanKeyList(ParsedKey, cPath, Attributes); + + FoundObject = CmiScanKeyList(ParsedKey, + &KeyName, + Attributes); if (FoundObject == NULL) { Status = CmiScanForSubKey(ParsedKey->RegistryHive, ParsedKey->KeyCell, &SubKeyCell, &BlockOffset, - cPath, + &KeyName, 0, Attributes); if (!NT_SUCCESS(Status) || (SubKeyCell == NULL)) { + RtlFreeUnicodeString(&KeyName); return(STATUS_UNSUCCESSFUL); } - if ((SubKeyCell->Type == REG_LINK_KEY_CELL_TYPE) && - !((Attributes & OBJ_OPENLINK) && (EndPtr == NULL) /*(end == NULL)*/)) + if ((SubKeyCell->Flags & REG_KEY_LINK_CELL) && + !((Attributes & OBJ_OPENLINK) && (EndPtr == NULL))) { RtlInitUnicodeString(&LinkPath, NULL); Status = CmiGetLinkTarget(ParsedKey->RegistryHive, @@ -129,35 +139,38 @@ CmiObjectParse(PVOID ParsedObject, *Path = FullPath->Buffer; *NextObject = NULL; + + RtlFreeUnicodeString(&KeyName); return(STATUS_REPARSE); } } /* Create new key object and put into linked list */ - DPRINT("CmiObjectParse: %s\n", cPath); - Status = ObCreateObject(NULL, + DPRINT("CmiObjectParse: %s\n", Path); + Status = ObRosCreateObject(NULL, STANDARD_RIGHTS_REQUIRED, NULL, CmiKeyType, (PVOID*)&FoundObject); if (!NT_SUCCESS(Status)) { + RtlFreeUnicodeString(&KeyName); return(Status); } FoundObject->Flags = 0; - FoundObject->Name = SubKeyCell->Name; - FoundObject->NameSize = SubKeyCell->NameSize; FoundObject->KeyCell = SubKeyCell; FoundObject->BlockOffset = BlockOffset; FoundObject->RegistryHive = ParsedKey->RegistryHive; + RtlCreateUnicodeString(&FoundObject->Name, + KeyName.Buffer); CmiAddKeyToList(ParsedKey, FoundObject); DPRINT("Created object 0x%x\n", FoundObject); } else { - if ((FoundObject->KeyCell->Type == REG_LINK_KEY_CELL_TYPE) && - !((Attributes & OBJ_OPENLINK) && (EndPtr == NULL)/*(end == NULL)*/)) + if ((FoundObject->KeyCell->Flags & REG_KEY_LINK_CELL) && + !((Attributes & OBJ_OPENLINK) && (EndPtr == NULL))) { DPRINT("Found link\n"); @@ -196,6 +209,8 @@ CmiObjectParse(PVOID ParsedObject, *Path = FullPath->Buffer; *NextObject = NULL; + + RtlFreeUnicodeString(&KeyName); return(STATUS_REPARSE); } } @@ -214,6 +229,8 @@ CmiObjectParse(PVOID ParsedObject, *NextObject = FoundObject; + RtlFreeUnicodeString(&KeyName); + return(STATUS_SUCCESS); } @@ -224,25 +241,22 @@ CmiObjectCreate(PVOID ObjectBody, PWSTR RemainingPath, POBJECT_ATTRIBUTES ObjectAttributes) { - PKEY_OBJECT pKey = ObjectBody; + PKEY_OBJECT KeyObject = ObjectBody; + PWSTR Start; - pKey->ParentKey = Parent; + KeyObject->ParentKey = Parent; if (RemainingPath) { - if(RemainingPath[0]== L'\\') - { - pKey->Name = (PCHAR)(&RemainingPath[1]); - pKey->NameSize = wcslen(RemainingPath) - 1; - } - else - { - pKey->Name = (PCHAR)RemainingPath; - pKey->NameSize = wcslen(RemainingPath); - } + Start = RemainingPath; + if(*Start == L'\\') + Start++; + RtlCreateUnicodeString(&KeyObject->Name, + Start); } else { - pKey->NameSize = 0; + RtlInitUnicodeString(&KeyObject->Name, + NULL); } return STATUS_SUCCESS; @@ -254,15 +268,19 @@ CmiObjectDelete(PVOID DeletedObject) { PKEY_OBJECT KeyObject; - DPRINT("Delete object key\n"); + DPRINT("Delete key object (%p)\n", DeletedObject); KeyObject = (PKEY_OBJECT) DeletedObject; + + ObReferenceObject(KeyObject->ParentKey); if (!NT_SUCCESS(CmiRemoveKeyFromList(KeyObject))) { DPRINT1("Key not found in parent list ???\n"); } + RtlFreeUnicodeString(&KeyObject->Name); + if (KeyObject->Flags & KO_MARKED_FOR_DELETE) { DPRINT("delete really key\n"); @@ -271,11 +289,21 @@ CmiObjectDelete(PVOID DeletedObject) KeyObject->ParentKey, KeyObject); - if (!IsVolatileHive(KeyObject->RegistryHive)) + if (!IsNoFileHive(KeyObject->RegistryHive)) { CmiSyncHives(); } } + ObDereferenceObject(KeyObject->ParentKey); + if (KeyObject->NumberOfSubKeys) + { + KEBUGCHECK(0); + } + if (KeyObject->SizeOfSubKeys) + { + ExFreePool(KeyObject->SubKeys); + } + } @@ -286,9 +314,75 @@ CmiObjectSecurity(PVOID ObjectBody, PSECURITY_DESCRIPTOR SecurityDescriptor, PULONG BufferLength) { - DPRINT1("CmiObjectSecurity() called\n"); + DPRINT1 ("CmiObjectSecurity() called\n"); - return(STATUS_SUCCESS); + return STATUS_SUCCESS; +} + + +NTSTATUS STDCALL +CmiObjectQueryName (PVOID ObjectBody, + POBJECT_NAME_INFORMATION ObjectNameInfo, + ULONG Length, + PULONG ReturnLength) +{ + POBJECT_NAME_INFORMATION LocalInfo; + PKEY_OBJECT KeyObject; + ULONG LocalReturnLength; + NTSTATUS Status; + + DPRINT ("CmiObjectQueryName() called\n"); + + KeyObject = (PKEY_OBJECT)ObjectBody; + + LocalInfo = ExAllocatePool (NonPagedPool, + sizeof(OBJECT_NAME_INFORMATION) + + MAX_PATH * sizeof(WCHAR)); + if (LocalInfo == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + if (KeyObject->ParentKey != KeyObject) + { + Status = ObQueryNameString (KeyObject->ParentKey, + LocalInfo, + MAX_PATH * sizeof(WCHAR), + &LocalReturnLength); + } + else + { + /* KeyObject is the root key */ + Status = ObQueryNameString (BODY_TO_HEADER(KeyObject)->Parent, + LocalInfo, + MAX_PATH * sizeof(WCHAR), + &LocalReturnLength); + } + + if (!NT_SUCCESS (Status)) + { + ExFreePool (LocalInfo); + return Status; + } + DPRINT ("Parent path: %wZ\n", &LocalInfo->Name); + + Status = RtlAppendUnicodeStringToString (&ObjectNameInfo->Name, + &LocalInfo->Name); + ExFreePool (LocalInfo); + if (!NT_SUCCESS (Status)) + return Status; + + Status = RtlAppendUnicodeToString (&ObjectNameInfo->Name, + L"\\"); + if (!NT_SUCCESS (Status)) + return Status; + + Status = RtlAppendUnicodeStringToString (&ObjectNameInfo->Name, + &KeyObject->Name); + if (NT_SUCCESS (Status)) + { + DPRINT ("Total path: %wZ\n", &ObjectNameInfo->Name); + } + + return Status; } @@ -371,18 +465,16 @@ CmiRemoveKeyFromList(PKEY_OBJECT KeyToRemove) PKEY_OBJECT CmiScanKeyList(PKEY_OBJECT Parent, - PCHAR KeyName, + PUNICODE_STRING KeyName, ULONG Attributes) { PKEY_OBJECT CurKey; KIRQL OldIrql; - WORD NameSize; - DWORD Index; + ULONG Index; - DPRINT("Scanning key list for: %s (Parent: %s)\n", - KeyName, Parent->Name); + DPRINT("Scanning key list for: %wZ (Parent: %wZ)\n", + KeyName, &Parent->Name); - NameSize = strlen(KeyName); KeAcquireSpinLock(&CmiKeyListLock, &OldIrql); /* FIXME: if list maintained in alphabetic order, use dichotomic search */ for (Index=0; Index < Parent->NumberOfSubKeys; Index++) @@ -390,8 +482,8 @@ CmiScanKeyList(PKEY_OBJECT Parent, CurKey = Parent->SubKeys[Index]; if (Attributes & OBJ_CASE_INSENSITIVE) { - if ((NameSize == CurKey->NameSize) - && (_strnicmp(KeyName, CurKey->Name, NameSize) == 0)) + if ((KeyName->Length == CurKey->Name.Length) + && (_wcsicmp(KeyName->Buffer, CurKey->Name.Buffer) == 0)) { KeReleaseSpinLock(&CmiKeyListLock, OldIrql); return CurKey; @@ -399,8 +491,8 @@ CmiScanKeyList(PKEY_OBJECT Parent, } else { - if ((NameSize == CurKey->NameSize) - && (strncmp(KeyName,CurKey->Name,NameSize) == 0)) + if ((KeyName->Length == CurKey->Name.Length) + && (wcscmp(KeyName->Buffer, CurKey->Name.Buffer) == 0)) { KeReleaseSpinLock(&CmiKeyListLock, OldIrql); return CurKey;