- WCHAR StrBuff[MAX_PATH], PathBuff[MAX_PATH];
- PWCHAR Guid, RefString;
- UNICODE_STRING DevParamU = RTL_CONSTANT_STRING(L"\\Device Parameters");
- UNICODE_STRING PrefixU = RTL_CONSTANT_STRING(L"\\??\\");
- UNICODE_STRING KeyPath, KeyName;
- UNICODE_STRING MatchableGuid;
- UNICODE_STRING GuidString;
- HANDLE GuidKey, hInterfaceKey;
- ULONG Index = 0;
- PKEY_BASIC_INFORMATION KeyInformation;
- ULONG KeyInformationLength;
- OBJECT_ATTRIBUTES ObjectAttributes;
- NTSTATUS Status;
- ULONG RequiredLength;
-
- swprintf(StrBuff, L"##?#%s", &SymbolicLinkName->Buffer[PrefixU.Length / sizeof(WCHAR)]);
-
- RefString = wcsstr(StrBuff, L"\\");
- if (RefString)
- {
- RefString[0] = 0;
- }
-
- RtlInitUnicodeString(&MatchableGuid, StrBuff);
-
- Guid = wcsstr(StrBuff, L"{");
- if (!Guid)
- return STATUS_OBJECT_NAME_NOT_FOUND;
-
- KeyPath.Buffer = PathBuff;
- KeyPath.Length = 0;
- KeyPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
-
- GuidString.Buffer = Guid;
- GuidString.Length = GuidString.MaximumLength = 38 * sizeof(WCHAR);
-
- RtlAppendUnicodeToString(&KeyPath, BaseKeyString);
- RtlAppendUnicodeStringToString(&KeyPath, &GuidString);
-
- 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))
- {
- ExFreePool(KeyInformation);
- continue;
- }
-
- KeyPath.Length = 0;
- RtlAppendUnicodeStringToString(&KeyPath, &KeyName);
- RtlAppendUnicodeToString(&KeyPath, L"\\");
-
- /* check for presence of a reference string */
- if (RefString)
- {
- /* append reference string */
- RefString[0] = L'#';
- RtlInitUnicodeString(&KeyName, RefString);
- }
- else
- {
- /* no reference string */
- RtlInitUnicodeString(&KeyName, L"#");
- }
- RtlAppendUnicodeStringToString(&KeyPath, &KeyName);
-
- /* initialize reference string attributes */
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyPath,
- OBJ_CASE_INSENSITIVE,
- GuidKey,
- NULL);
-
- /* now open device interface key */
- Status = ZwOpenKey(&hInterfaceKey, KEY_CREATE_SUB_KEY, &ObjectAttributes);
-
- if (NT_SUCCESS(Status))
- {
- /* check if it provides a DeviceParameters key */
- InitializeObjectAttributes(&ObjectAttributes, &DevParamU, OBJ_CASE_INSENSITIVE, hInterfaceKey, NULL);
-
- Status = ZwCreateKey(DeviceInterfaceKey, DesiredAccess, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL);
-
- if (NT_SUCCESS(Status))
- {
- /* DeviceParameters key present */
- ZwClose(hInterfaceKey);
- }
- else
- {
- /* fall back to device interface */
- *DeviceInterfaceKey = hInterfaceKey;
- Status = STATUS_SUCCESS;
- }
- }
-
- /* close class key */
- ZwClose(GuidKey);
- ExFreePool(KeyInformation);
- return Status;
- }
-
- return STATUS_OBJECT_PATH_NOT_FOUND;