IN ACCESS_MASK DesiredAccess,
OUT PHANDLE DeviceInterfaceKey)
{
- return STATUS_NOT_IMPLEMENTED;
+ 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;
}
/*++
goto cleanup;
}
RtlCopyMemory(NewBuffer, ReturnBuffer.Buffer, ReturnBuffer.Length);
- ExFreePool(ReturnBuffer.Buffer);
+ if (ReturnBuffer.Buffer)
+ ExFreePool(ReturnBuffer.Buffer);
ReturnBuffer.Buffer = NewBuffer;
}
DPRINT("Adding symbolic link %wZ\n", &KeyName);
DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status);
goto cleanup;
}
- /* RtlAppendUnicodeStringToString added a NULL at the end of the
- * destination string, but didn't increase the Length field.
- * Do it for it.
- */
- ReturnBuffer.Length += sizeof(WCHAR);
-
NextReferenceString:
ExFreePool(ReferenceBi);
ReferenceBi = NULL;
Status = STATUS_SUCCESS;
cleanup:
- if (!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status) && ReturnBuffer.Buffer)
ExFreePool(ReturnBuffer.Buffer);
if (InterfaceKey != INVALID_HANDLE_VALUE)
ZwClose(InterfaceKey);
ZwClose(ReferenceKey);
if (ControlKey != INVALID_HANDLE_VALUE)
ZwClose(ControlKey);
- ExFreePool(DeviceBi);
- ExFreePool(ReferenceBi);
- ExFreePool(bip);
+ if (DeviceBi)
+ ExFreePool(DeviceBi);
+ if (ReferenceBi)
+ ExFreePool(ReferenceBi);
+ if (bip)
+ ExFreePool(bip);
return Status;
}
SymbolicLinkName->Buffer[SymbolicLinkName->Length/sizeof(WCHAR)] = L'\0';
/* Create symbolic link */
- DPRINT1("IoRegisterDeviceInterface(): creating symbolic link %wZ -> %wZ\n", SymbolicLinkName, &PdoNameInfo->Name);
+ DPRINT("IoRegisterDeviceInterface(): creating symbolic link %wZ -> %wZ\n", SymbolicLinkName, &PdoNameInfo->Name);
Status = IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name);
if (!NT_SUCCESS(Status) && ReferenceString == NULL)
{
- DPRINT("IoCreateSymbolicLink() failed with status 0x%08lx\n", Status);
+ DPRINT1("IoCreateSymbolicLink() failed with status 0x%08lx\n", Status);
ZwClose(SubKey);
ZwClose(InterfaceKey);
ZwClose(ClassKey);
SymbolicLinkName->Length);
if (!NT_SUCCESS(Status))
{
- DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
+ DPRINT1("ZwSetValueKey() failed with status 0x%08lx\n", Status);
ExFreePool(SymbolicLinkName->Buffer);
}
else
EndPosition = wcschr(SymbolicLinkName->Buffer, L'}');
if (!StartPosition ||!EndPosition || StartPosition > EndPosition)
{
- DPRINT("IoSetDeviceInterfaceState() returning STATUS_INVALID_PARAMETER_1\n");
+ DPRINT1("IoSetDeviceInterfaceState() returning STATUS_INVALID_PARAMETER_1\n");
return STATUS_INVALID_PARAMETER_1;
}
GuidString.Buffer = StartPosition;
SymLink.Buffer = SymbolicLinkName->Buffer;
SymLink.MaximumLength = SymLink.Length = (USHORT)((ULONG_PTR)(EndPosition + 1) - (ULONG_PTR)SymLink.Buffer);
-
-
+ DPRINT("IoSetDeviceInterfaceState('%wZ', %d)\n", SymbolicLinkName, Enable);
/* Get pointer to the PDO */
Status = IoGetDeviceObjectPointer(
&SymLink,
&PhysicalDeviceObject);
if (!NT_SUCCESS(Status))
{
- DPRINT("IoGetDeviceObjectPointer() failed with status 0x%08lx\n", Status);
+ DPRINT1("IoGetDeviceObjectPointer() failed with status 0x%08lx\n", Status);
return Status;
}
(PVOID)SymbolicLinkName);
ObDereferenceObject(FileObject);
-
+ DPRINT("Status %x\n", Status);
return STATUS_SUCCESS;
}