From 66c160f1d644a9561bce0a74d8540c1f9eb93ae2 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 2 Apr 2010 07:29:54 +0000 Subject: [PATCH] [NTOSKRNL] - Implement IoOpenDeviceInterfaceRegistryKey - Dedicated to Janderwald svn path=/trunk/; revision=46665 --- reactos/ntoskrnl/io/iomgr/deviface.c | 164 ++++++++++++++++++++++++++- 1 file changed, 163 insertions(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/io/iomgr/deviface.c b/reactos/ntoskrnl/io/iomgr/deviface.c index cc6d5444de3..2b0789b5a60 100644 --- a/reactos/ntoskrnl/io/iomgr/deviface.c +++ b/reactos/ntoskrnl/io/iomgr/deviface.c @@ -50,7 +50,169 @@ IoOpenDeviceInterfaceRegistryKey(IN PUNICODE_STRING SymbolicLinkName, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DeviceInterfaceKey) { - return STATUS_NOT_IMPLEMENTED; + WCHAR StrBuff[MAX_PATH], PathBuff[MAX_PATH]; + PWCHAR Guid; + UNICODE_STRING EnumU = RTL_CONSTANT_STRING(ENUM_ROOT L"\\"); + UNICODE_STRING DevParamU = RTL_CONSTANT_STRING(L"\\Device Parameters"); + UNICODE_STRING PrefixU = RTL_CONSTANT_STRING(L"\\??\\"); + UNICODE_STRING KeyPath, KeyName; + UNICODE_STRING MatchableGuid; + HANDLE GuidKey, ChildKey; + ULONG Index = 0; + PKEY_BASIC_INFORMATION KeyInformation; + ULONG KeyInformationLength; + PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation; + ULONG KeyValueInformationLength; + OBJECT_ATTRIBUTES ObjectAttributes; + NTSTATUS Status; + ULONG RequiredLength; + + MatchableGuid.Length = 0; + MatchableGuid.Length += swprintf(StrBuff, + L"##?#%ls", + &SymbolicLinkName->Buffer[PrefixU.Length / sizeof(WCHAR)]); + StrBuff[++MatchableGuid.Length] = UNICODE_NULL; + + MatchableGuid.Buffer = StrBuff; + MatchableGuid.MaximumLength = MAX_PATH * sizeof(WCHAR); + MatchableGuid.Length = (MatchableGuid.Length-1) * sizeof(WCHAR); + + Guid = wcsstr(StrBuff, L"{"); + if (!Guid) + return STATUS_OBJECT_NAME_NOT_FOUND; + + KeyPath.Buffer = PathBuff; + KeyPath.Length = 0; + KeyPath.MaximumLength = MAX_PATH * sizeof(WCHAR); + + RtlAppendUnicodeToString(&KeyPath, BaseKeyString); + RtlAppendUnicodeToString(&KeyPath, Guid); + + InitializeObjectAttributes(&ObjectAttributes, + &KeyPath, + OBJ_CASE_INSENSITIVE, + 0, + NULL); + + Status = ZwOpenKey(&GuidKey, KEY_CREATE_SUB_KEY, &ObjectAttributes); + if (!NT_SUCCESS(Status)) + return Status; + + while (TRUE) + { + Status = ZwEnumerateKey(GuidKey, + Index, + KeyBasicInformation, + NULL, + 0, + &RequiredLength); + if (Status == STATUS_NO_MORE_ENTRIES) + break; + else if (Status == STATUS_BUFFER_TOO_SMALL) + { + KeyInformationLength = RequiredLength; + KeyInformation = ExAllocatePool(PagedPool, KeyInformationLength); + if (!KeyInformation) + { + ZwClose(GuidKey); + return STATUS_INSUFFICIENT_RESOURCES; + } + + Status = ZwEnumerateKey(GuidKey, + Index, + KeyBasicInformation, + KeyInformation, + KeyInformationLength, + &RequiredLength); + } + else + { + ZwClose(GuidKey); + return STATUS_OBJECT_PATH_NOT_FOUND; + } + Index++; + + if (!NT_SUCCESS(Status)) + { + ZwClose(GuidKey); + return Status; + } + + KeyName.Length = KeyName.MaximumLength = KeyInformation->NameLength; + KeyName.Buffer = KeyInformation->Name; + + if (!RtlEqualUnicodeString(&KeyName, &MatchableGuid, TRUE)) + continue; + + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + GuidKey, + NULL); + Status = ZwOpenKey(&ChildKey, KEY_QUERY_VALUE, &ObjectAttributes); + ZwClose(GuidKey); + if (!NT_SUCCESS(Status)) + return Status; + + RtlInitUnicodeString(&KeyName, L"DeviceInstance"); + Status = ZwQueryValueKey(ChildKey, + &KeyName, + KeyValuePartialInformation, + NULL, + 0, + &RequiredLength); + if (Status == STATUS_BUFFER_TOO_SMALL) + { + KeyValueInformationLength = RequiredLength; + KeyValueInformation = ExAllocatePool(PagedPool, KeyValueInformationLength); + if (!KeyValueInformation) + { + ZwClose(ChildKey); + return Status; + } + + Status = ZwQueryValueKey(ChildKey, + &KeyName, + KeyValuePartialInformation, + KeyValueInformation, + KeyValueInformationLength, + &RequiredLength); + } + else + { + ZwClose(ChildKey); + return STATUS_OBJECT_PATH_NOT_FOUND; + } + ZwClose(ChildKey); + + if (!NT_SUCCESS(Status)) + return Status; + + KeyPath.Length = 0; + + KeyName.Length = KeyName.MaximumLength = KeyValueInformation->DataLength; + KeyName.Buffer = (PWCHAR)KeyValueInformation->Data; + + RtlAppendUnicodeStringToString(&KeyPath, &EnumU); + RtlAppendUnicodeStringToString(&KeyPath, &KeyName); + RtlAppendUnicodeStringToString(&KeyPath, &DevParamU); + + InitializeObjectAttributes(&ObjectAttributes, + &KeyPath, + OBJ_CASE_INSENSITIVE, + 0, + NULL); + Status = ZwCreateKey(DeviceInterfaceKey, + DesiredAccess, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + NULL); + return Status; + } + + return STATUS_OBJECT_PATH_NOT_FOUND; } /*++ -- 2.17.1