reactos/drivers/usb/usbport/iface.c

908 lines
27 KiB
C

/*
* PROJECT: ReactOS USB Port Driver
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: USBPort interface functions
* COPYRIGHT: Copyright 2017 Vadim Galyant <vgal@rambler.ru>
*/
#include "usbport.h"
#define NDEBUG
#include <debug.h>
VOID
USB_BUSIFFN
USBI_InterfaceReference(IN PVOID BusContext)
{
DPRINT("USBI_InterfaceReference\n");
}
VOID
USB_BUSIFFN
USBI_InterfaceDereference(IN PVOID BusContext)
{
DPRINT("USBI_InterfaceDereference\n");
}
/* USB port driver Interface functions */
NTSTATUS
USB_BUSIFFN
USBHI_CreateUsbDevice(IN PVOID BusContext,
IN OUT PUSB_DEVICE_HANDLE *UsbdDeviceHandle,
IN PUSB_DEVICE_HANDLE UsbdHubDeviceHandle,
IN USHORT PortStatus,
IN USHORT PortNumber)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PUSB_DEVICE_HANDLE deviceHandle = NULL;
NTSTATUS Status;
DPRINT("USBHI_CreateUsbDevice: ...\n");
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
Status = USBPORT_CreateDevice(&deviceHandle,
PdoExtension->FdoDevice,
(PUSBPORT_DEVICE_HANDLE)UsbdHubDeviceHandle,
PortStatus,
PortNumber);
*UsbdDeviceHandle = deviceHandle;
return Status;
}
NTSTATUS
USB_BUSIFFN
USBHI_InitializeUsbDevice(IN PVOID BusContext,
OUT PUSB_DEVICE_HANDLE UsbdDeviceHandle)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
DPRINT("USBHI_InitializeUsbDevice\n");
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
return USBPORT_InitializeDevice((PUSBPORT_DEVICE_HANDLE)UsbdDeviceHandle,
PdoExtension->FdoDevice);
}
NTSTATUS
USB_BUSIFFN
USBHI_GetUsbDescriptors(IN PVOID BusContext,
IN PUSB_DEVICE_HANDLE UsbdDeviceHandle,
IN PUCHAR DeviceDescBuffer,
IN PULONG DeviceDescBufferLen,
IN PUCHAR ConfigDescBuffer,
IN PULONG ConfigDescBufferLen)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PUSBPORT_DEVICE_HANDLE DeviceHandle;
NTSTATUS Status;
DPRINT("USBHI_GetUsbDescriptors ...\n");
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
DeviceHandle = (PUSBPORT_DEVICE_HANDLE)UsbdDeviceHandle;
if (DeviceDescBuffer && *DeviceDescBufferLen)
{
if (*DeviceDescBufferLen > sizeof(USB_DEVICE_DESCRIPTOR))
*DeviceDescBufferLen = sizeof(USB_DEVICE_DESCRIPTOR);
RtlCopyMemory(DeviceDescBuffer,
&DeviceHandle->DeviceDescriptor,
*DeviceDescBufferLen);
}
Status = USBPORT_GetUsbDescriptor(DeviceHandle,
PdoExtension->FdoDevice,
USB_CONFIGURATION_DESCRIPTOR_TYPE,
ConfigDescBuffer,
ConfigDescBufferLen);
USBPORT_DumpingDeviceDescriptor((PUSB_DEVICE_DESCRIPTOR)DeviceDescBuffer);
return Status;
}
NTSTATUS
USB_BUSIFFN
USBHI_RemoveUsbDevice(IN PVOID BusContext,
IN OUT PUSB_DEVICE_HANDLE UsbdDeviceHandle,
IN ULONG Flags)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
DPRINT("USBHI_RemoveUsbDevice: UsbdDeviceHandle - %p, Flags - %x\n",
UsbdDeviceHandle,
Flags);
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
return USBPORT_RemoveDevice(PdoExtension->FdoDevice,
(PUSBPORT_DEVICE_HANDLE)UsbdDeviceHandle,
Flags);
}
NTSTATUS
USB_BUSIFFN
USBHI_RestoreUsbDevice(IN PVOID BusContext,
OUT PUSB_DEVICE_HANDLE OldUsbdDeviceHandle,
OUT PUSB_DEVICE_HANDLE NewUsbdDeviceHandle)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
DPRINT("USBHI_RestoreUsbDevice: OldUsbdDeviceHandle - %p, NewUsbdDeviceHandle - %x\n",
OldUsbdDeviceHandle,
NewUsbdDeviceHandle);
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
return USBPORT_RestoreDevice(PdoExtension->FdoDevice,
(PUSBPORT_DEVICE_HANDLE)OldUsbdDeviceHandle,
(PUSBPORT_DEVICE_HANDLE)NewUsbdDeviceHandle);
}
NTSTATUS
USB_BUSIFFN
USBHI_QueryDeviceInformation(IN PVOID BusContext,
IN PUSB_DEVICE_HANDLE UsbdDeviceHandle,
OUT PVOID DeviceInfoBuffer,
IN ULONG DeviceInfoBufferLen,
OUT PULONG LenDataReturned)
{
PUSB_DEVICE_INFORMATION_0 DeviceInfo;
PUSBPORT_CONFIGURATION_HANDLE ConfigHandle;
PLIST_ENTRY InterfaceEntry;
PUSBPORT_DEVICE_HANDLE DeviceHandle;
ULONG NumberOfOpenPipes = 0;
PUSB_PIPE_INFORMATION_0 PipeInfo;
PUSBPORT_PIPE_HANDLE PipeHandle;
PUSBPORT_INTERFACE_HANDLE InterfaceHandle;
ULONG ActualLength;
ULONG ix;
DPRINT("USBHI_QueryDeviceInformation: ...\n");
*LenDataReturned = 0;
if (DeviceInfoBufferLen < sizeof(USB_LEVEL_INFORMATION))
{
return STATUS_BUFFER_TOO_SMALL;
}
DeviceInfo = DeviceInfoBuffer;
if (DeviceInfo->InformationLevel > 0)
{
return STATUS_NOT_SUPPORTED;
}
DeviceHandle = UsbdDeviceHandle;
ConfigHandle = DeviceHandle->ConfigHandle;
if (ConfigHandle)
{
InterfaceEntry = ConfigHandle->InterfaceHandleList.Flink;
while (InterfaceEntry &&
InterfaceEntry != &ConfigHandle->InterfaceHandleList)
{
InterfaceHandle = CONTAINING_RECORD(InterfaceEntry,
USBPORT_INTERFACE_HANDLE,
InterfaceLink);
NumberOfOpenPipes += InterfaceHandle->InterfaceDescriptor.bNumEndpoints;
InterfaceEntry = InterfaceEntry->Flink;
}
}
ActualLength = FIELD_OFFSET(USB_DEVICE_INFORMATION_0, PipeList) +
NumberOfOpenPipes * sizeof(USB_PIPE_INFORMATION_0);
if (DeviceInfoBufferLen < ActualLength)
{
DeviceInfo->ActualLength = ActualLength;
*LenDataReturned = sizeof(USB_LEVEL_INFORMATION);
return STATUS_BUFFER_TOO_SMALL;
}
RtlZeroMemory(DeviceInfo, ActualLength);
DeviceInfo->InformationLevel = 0;
DeviceInfo->ActualLength = ActualLength;
DeviceInfo->DeviceAddress = DeviceHandle->DeviceAddress;
DeviceInfo->NumberOfOpenPipes = NumberOfOpenPipes;
DeviceInfo->DeviceSpeed = DeviceHandle->DeviceSpeed;
RtlCopyMemory(&DeviceInfo->DeviceDescriptor,
&DeviceHandle->DeviceDescriptor,
sizeof(USB_DEVICE_DESCRIPTOR));
USBPORT_DumpingDeviceDescriptor(&DeviceInfo->DeviceDescriptor);
if (DeviceHandle->DeviceSpeed == UsbFullSpeed ||
DeviceHandle->DeviceSpeed == UsbLowSpeed)
{
DeviceInfo->DeviceType = Usb11Device;
}
else if (DeviceHandle->DeviceSpeed == UsbHighSpeed)
{
DeviceInfo->DeviceType = Usb20Device;
}
DeviceInfo->CurrentConfigurationValue = 0;
if (!ConfigHandle)
{
*LenDataReturned = ActualLength;
return STATUS_SUCCESS;
}
DeviceInfo->CurrentConfigurationValue =
ConfigHandle->ConfigurationDescriptor->bConfigurationValue;
InterfaceEntry = ConfigHandle->InterfaceHandleList.Flink;
while (InterfaceEntry &&
InterfaceEntry != &ConfigHandle->InterfaceHandleList)
{
InterfaceHandle = CONTAINING_RECORD(InterfaceEntry,
USBPORT_INTERFACE_HANDLE,
InterfaceLink);
if (InterfaceHandle->InterfaceDescriptor.bNumEndpoints > 0)
{
PipeInfo = &DeviceInfo->PipeList[0];
PipeHandle = &InterfaceHandle->PipeHandle[0];
for (ix = 0;
ix < InterfaceHandle->InterfaceDescriptor.bNumEndpoints;
ix++)
{
if (PipeHandle->Flags & PIPE_HANDLE_FLAG_NULL_PACKET_SIZE)
{
PipeInfo->ScheduleOffset = 1;
}
else
{
PipeInfo->ScheduleOffset =
PipeHandle->Endpoint->EndpointProperties.ScheduleOffset;
}
RtlCopyMemory(&PipeInfo->EndpointDescriptor,
&PipeHandle->EndpointDescriptor,
sizeof(USB_ENDPOINT_DESCRIPTOR));
PipeInfo += 1;
PipeHandle += 1;
}
}
InterfaceEntry = InterfaceEntry->Flink;
}
*LenDataReturned = ActualLength;
return STATUS_SUCCESS;
}
NTSTATUS
USB_BUSIFFN
USBHI_GetControllerInformation(IN PVOID BusContext,
OUT PVOID ControllerInfoBuffer,
IN ULONG ControllerInfoBufferLen,
OUT PULONG LenDataReturned)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PDEVICE_OBJECT FdoDevice;
PUSBPORT_DEVICE_EXTENSION FdoExtension;
PUSB_CONTROLLER_INFORMATION_0 InfoBuffer;
NTSTATUS Status;
DPRINT("USBHI_GetControllerInformation: ControllerInfoBufferLen - %x\n",
ControllerInfoBufferLen);
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
FdoDevice = PdoExtension->FdoDevice;
FdoExtension = FdoDevice->DeviceExtension;
InfoBuffer = ControllerInfoBuffer;
*LenDataReturned = 0;
if (ControllerInfoBufferLen < sizeof(USB_LEVEL_INFORMATION))
{
Status = STATUS_BUFFER_TOO_SMALL;
return Status;
}
*LenDataReturned = sizeof(USB_LEVEL_INFORMATION);
if (InfoBuffer->InformationLevel > 0)
{
Status = STATUS_NOT_SUPPORTED;
return Status;
}
InfoBuffer->ActualLength = sizeof(USB_CONTROLLER_INFORMATION_0);
if (ControllerInfoBufferLen >= sizeof(USB_CONTROLLER_INFORMATION_0))
{
InfoBuffer->SelectiveSuspendEnabled =
(FdoExtension->Flags & USBPORT_FLAG_SELECTIVE_SUSPEND) ==
USBPORT_FLAG_SELECTIVE_SUSPEND;
}
*LenDataReturned = sizeof(USB_CONTROLLER_INFORMATION_0);
return STATUS_SUCCESS;
}
NTSTATUS
USB_BUSIFFN
USBHI_ControllerSelectiveSuspend(IN PVOID BusContext,
IN BOOLEAN Enable)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PDEVICE_OBJECT FdoDevice;
PUSBPORT_DEVICE_EXTENSION FdoExtension;
ULONG Flags;
ULONG HcDisable;
NTSTATUS Status;
DPRINT("USBHI_ControllerSelectiveSuspend: Enable - %x\n", Enable);
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
FdoDevice = PdoExtension->FdoDevice;
FdoExtension = FdoDevice->DeviceExtension;
Flags = FdoExtension->Flags;
if (Flags & USBPORT_FLAG_BIOS_DISABLE_SS)
{
return STATUS_SUCCESS;
}
if (Enable)
{
FdoExtension->Flags |= USBPORT_FLAG_SELECTIVE_SUSPEND;
HcDisable = 0;
}
else
{
FdoExtension->Flags &= ~USBPORT_FLAG_SELECTIVE_SUSPEND;
HcDisable = 1;
}
Status = USBPORT_SetRegistryKeyValue(FdoExtension->CommonExtension.LowerPdoDevice,
TRUE,
REG_DWORD,
L"HcDisableSelectiveSuspend",
&HcDisable,
sizeof(HcDisable));
if (NT_SUCCESS(Status))
{
if (Enable)
FdoExtension->Flags |= USBPORT_FLAG_SELECTIVE_SUSPEND;
else
FdoExtension->Flags &= ~USBPORT_FLAG_SELECTIVE_SUSPEND;
}
return Status;
}
NTSTATUS
USB_BUSIFFN
USBHI_GetExtendedHubInformation(IN PVOID BusContext,
IN PDEVICE_OBJECT HubPhysicalDeviceObject,
IN OUT PVOID HubInformationBuffer,
IN ULONG HubInfoLen,
IN OUT PULONG LenDataReturned)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PDEVICE_OBJECT FdoDevice;
PUSBPORT_DEVICE_EXTENSION FdoExtension;
PUSBPORT_REGISTRATION_PACKET Packet;
ULONG NumPorts;
ULONG ix;
PUSB_EXTHUB_INFORMATION_0 HubInfoBuffer;
USB_PORT_STATUS_AND_CHANGE PortStatus;
ULONG PortAttrX;
DPRINT("USBHI_GetExtendedHubInformation: ...\n");
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
FdoDevice = PdoExtension->FdoDevice;
FdoExtension = FdoDevice->DeviceExtension;
Packet = &FdoExtension->MiniPortInterface->Packet;
HubInfoBuffer = HubInformationBuffer;
PortStatus.AsUlong32 = 0;
if (HubPhysicalDeviceObject != PdoDevice)
{
*LenDataReturned = 0;
return STATUS_NOT_SUPPORTED;
}
if (HubInfoLen < sizeof(USB_EXTHUB_INFORMATION_0))
{
*LenDataReturned = 0;
return STATUS_BUFFER_TOO_SMALL;
}
NumPorts = PdoExtension->RootHubDescriptors->Descriptor.bNumberOfPorts;
HubInfoBuffer->NumberOfPorts = NumPorts;
if (NumPorts == 0)
{
*LenDataReturned = sizeof(USB_EXTHUB_INFORMATION_0);
return STATUS_SUCCESS;
}
for (ix = 0; ix < HubInfoBuffer->NumberOfPorts; ++ix)
{
HubInfoBuffer->Port[ix].PhysicalPortNumber = ix + 1;
HubInfoBuffer->Port[ix].PortLabelNumber = ix;
HubInfoBuffer->Port[ix].VidOverride = 0;
HubInfoBuffer->Port[ix].PidOverride = 0;
HubInfoBuffer->Port[ix].PortAttributes = 0;
if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2)
{
HubInfoBuffer->Port[ix].PortAttributes = USB_PORTATTR_SHARED_USB2;
Packet->RH_GetPortStatus(FdoExtension->MiniPortExt,
ix + 1,
&PortStatus);
if (PortStatus.PortStatus.Usb20PortStatus.AsUshort16 & 0x8000)
{
HubInfoBuffer->Port[ix].PortAttributes |= USB_PORTATTR_OWNED_BY_CC;
}
}
else
{
if (!(FdoExtension->Flags & USBPORT_FLAG_COMPANION_HC))
{
continue;
}
if (USBPORT_FindUSB2Controller(FdoDevice))
{
HubInfoBuffer->Port[ix].PortAttributes |= USB_PORTATTR_NO_OVERCURRENT_UI;
}
}
}
for (ix = 0; ix < HubInfoBuffer->NumberOfPorts; ++ix)
{
PortAttrX = 0;
USBPORT_GetRegistryKeyValueFullInfo(FdoDevice,
FdoExtension->CommonExtension.LowerPdoDevice,
FALSE,
L"PortAttrX",
sizeof(L"PortAttrX"),
&PortAttrX,
sizeof(PortAttrX));
HubInfoBuffer->Port[ix].PortAttributes |= PortAttrX;
}
*LenDataReturned = sizeof(USB_EXTHUB_INFORMATION_0);
return STATUS_SUCCESS;
}
NTSTATUS
USB_BUSIFFN
USBHI_GetRootHubSymbolicName(IN PVOID BusContext,
IN OUT PVOID HubInfoBuffer,
IN ULONG HubInfoBufferLen,
OUT PULONG HubNameActualLen)
{
PDEVICE_OBJECT PdoDevice;
UNICODE_STRING HubName;
PUNICODE_STRING InfoBuffer;
NTSTATUS Status;
DPRINT("USBHI_GetRootHubSymbolicName: ...\n");
PdoDevice = BusContext;
Status = USBPORT_GetSymbolicName(PdoDevice, &HubName);
if (HubInfoBufferLen < HubName.Length)
{
InfoBuffer = HubInfoBuffer;
InfoBuffer->Length = 0;
}
else
{
RtlCopyMemory(HubInfoBuffer, HubName.Buffer, HubName.Length);
}
*HubNameActualLen = HubName.Length;
if (NT_SUCCESS(Status))
RtlFreeUnicodeString(&HubName);
return Status;
}
PVOID
USB_BUSIFFN
USBHI_GetDeviceBusContext(IN PVOID BusContext,
IN PVOID DeviceHandle)
{
DPRINT1("USBHI_GetDeviceBusContext: UNIMPLEMENTED. FIXME.\n");
return NULL;
}
NTSTATUS
USB_BUSIFFN
USBHI_Initialize20Hub(IN PVOID BusContext,
IN PUSB_DEVICE_HANDLE UsbdHubDeviceHandle,
IN ULONG TtCount)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
DPRINT("USBHI_Initialize20Hub: UsbdHubDeviceHandle - %p, TtCount - %x\n",
UsbdHubDeviceHandle,
TtCount);
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
return USBPORT_Initialize20Hub(PdoExtension->FdoDevice,
(PUSBPORT_DEVICE_HANDLE)UsbdHubDeviceHandle,
TtCount);
}
NTSTATUS
USB_BUSIFFN
USBHI_RootHubInitNotification(IN PVOID BusContext,
IN PVOID CallbackContext,
IN PRH_INIT_CALLBACK CallbackFunction)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PDEVICE_OBJECT FdoDevice;
PUSBPORT_DEVICE_EXTENSION FdoExtension;
KIRQL OldIrql;
DPRINT("USBHI_RootHubInitNotification\n");
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
FdoDevice = PdoExtension->FdoDevice;
FdoExtension = FdoDevice->DeviceExtension;
KeAcquireSpinLock(&FdoExtension->RootHubCallbackSpinLock, &OldIrql);
PdoExtension->RootHubInitContext = CallbackContext;
PdoExtension->RootHubInitCallback = CallbackFunction;
KeReleaseSpinLock(&FdoExtension->RootHubCallbackSpinLock, OldIrql);
return STATUS_SUCCESS;
}
VOID
USB_BUSIFFN
USBHI_FlushTransfers(IN PVOID BusContext,
OUT PUSB_DEVICE_HANDLE UsbdDeviceHandle)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
DPRINT("USBHI_FlushTransfers: ...\n");
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
USBPORT_BadRequestFlush(PdoExtension->FdoDevice);
}
VOID
USB_BUSIFFN
USBHI_SetDeviceHandleData(IN PVOID BusContext,
IN PVOID DeviceHandle,
IN PDEVICE_OBJECT UsbDevicePdo)
{
DPRINT1("USBHI_SetDeviceHandleData: UNIMPLEMENTED. FIXME.\n");
}
/* USB bus driver Interface functions */
VOID
USB_BUSIFFN
USBDI_GetUSBDIVersion(IN PVOID BusContext,
OUT PUSBD_VERSION_INFORMATION VersionInfo,
OUT PULONG HcdCapabilities)
{
DPRINT1("USBDI_GetUSBDIVersion: UNIMPLEMENTED. FIXME.\n");
}
NTSTATUS
USB_BUSIFFN
USBDI_QueryBusTime(IN PVOID BusContext,
OUT PULONG CurrentFrame)
{
DPRINT1("USBDI_QueryBusTime: UNIMPLEMENTED. FIXME.\n");
return STATUS_SUCCESS;
}
NTSTATUS
USB_BUSIFFN
USBDI_SubmitIsoOutUrb(IN PVOID BusContext,
IN PURB Urb)
{
DPRINT1("USBDI_SubmitIsoOutUrb: UNIMPLEMENTED. FIXME.\n");
return STATUS_SUCCESS;
}
NTSTATUS
USB_BUSIFFN
USBDI_QueryBusInformation(IN PVOID BusContext,
IN ULONG Level,
OUT PVOID BusInfoBuffer,
OUT PULONG BusInfoBufferLen,
OUT PULONG BusInfoActualLen)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PDEVICE_OBJECT FdoDevice;
PUSBPORT_DEVICE_EXTENSION FdoExtension;
SIZE_T Length;
PUSB_BUS_INFORMATION_LEVEL_1 Buffer1;
DPRINT("USBDI_QueryBusInformation: Level - %p\n", Level);
if ((Level != 0) && (Level != 1))
{
DPRINT1("USBDI_QueryBusInformation: Level should be 0 or 1\n");
return STATUS_NOT_SUPPORTED;
}
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
FdoDevice = PdoExtension->FdoDevice;
FdoExtension = FdoDevice->DeviceExtension;
if (Level == 0)
{
if (BusInfoActualLen)
*BusInfoActualLen = sizeof(USB_BUS_INFORMATION_LEVEL_0);
if (*BusInfoBufferLen < sizeof(USB_BUS_INFORMATION_LEVEL_0))
{
return STATUS_BUFFER_TOO_SMALL;
}
*BusInfoBufferLen = sizeof(USB_BUS_INFORMATION_LEVEL_0);
//Buffer0 = BusInfoBuffer;
DPRINT1("USBDI_QueryBusInformation: LEVEL_0 UNIMPLEMENTED. FIXME\n");
//Buffer0->TotalBandwidth = USBPORT_GetTotalBandwidth();
//Buffer0->ConsumedBandwidth = USBPORT_GetAllocatedBandwidth();
return STATUS_SUCCESS;
}
if (Level == 1)
{
Length = sizeof(USB_BUS_INFORMATION_LEVEL_1) +
FdoExtension->CommonExtension.SymbolicLinkName.Length;
if (BusInfoActualLen)
*BusInfoActualLen = Length;
if (*BusInfoBufferLen < Length)
{
return STATUS_BUFFER_TOO_SMALL;
}
*BusInfoBufferLen = Length;
Buffer1 = BusInfoBuffer;
DPRINT1("USBDI_QueryBusInformation: LEVEL_1 UNIMPLEMENTED. FIXME\n");
//Buffer1->TotalBandwidth = USBPORT_GetTotalBandwidth();
//Buffer1->ConsumedBandwidth = USBPORT_GetAllocatedBandwidth();
Buffer1->ControllerNameLength = FdoExtension->CommonExtension.SymbolicLinkName.Length;
RtlCopyMemory(&Buffer1->ControllerNameUnicodeString,
FdoExtension->CommonExtension.SymbolicLinkName.Buffer,
FdoExtension->CommonExtension.SymbolicLinkName.Length);
return STATUS_SUCCESS;
}
return STATUS_SUCCESS;
}
BOOLEAN
USB_BUSIFFN
USBDI_IsDeviceHighSpeed(IN PVOID BusContext)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PDEVICE_OBJECT FdoDevice;
PUSBPORT_DEVICE_EXTENSION FdoExtension;
PUSBPORT_REGISTRATION_PACKET Packet;
DPRINT("USBDI_IsDeviceHighSpeed: ...\n");
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
FdoDevice = PdoExtension->FdoDevice;
FdoExtension = FdoDevice->DeviceExtension;
Packet = &FdoExtension->MiniPortInterface->Packet;
return (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2) != 0;
}
NTSTATUS
USB_BUSIFFN
USBDI_EnumLogEntry(IN PVOID BusContext,
IN ULONG DriverTag,
IN ULONG EnumTag,
IN ULONG P1,
IN ULONG P2)
{
DPRINT1("USBDI_EnumLogEntry: UNIMPLEMENTED. FIXME.\n");
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
USBPORT_PdoQueryInterface(IN PDEVICE_OBJECT FdoDevice,
IN PDEVICE_OBJECT PdoDevice,
IN PIRP Irp)
{
PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
PUSB_BUS_INTERFACE_HUB_V5 InterfaceHub;
PUSB_BUS_INTERFACE_USBDI_V2 InterfaceDI;
UNICODE_STRING GuidBuffer;
NTSTATUS Status;
DPRINT("USBPORT_PdoQueryInterface: ...\n");
if (IsEqualGUIDAligned(IoStack->Parameters.QueryInterface.InterfaceType,
&USB_BUS_INTERFACE_HUB_GUID))
{
/* Get request parameters */
InterfaceHub = (PUSB_BUS_INTERFACE_HUB_V5)IoStack->Parameters.QueryInterface.Interface;
InterfaceHub->Version = IoStack->Parameters.QueryInterface.Version;
/* Check version */
if (IoStack->Parameters.QueryInterface.Version >= 6)
{
DPRINT1("USB_BUS_INTERFACE_HUB_GUID version %x not supported!\n",
IoStack->Parameters.QueryInterface.Version);
return Irp->IoStatus.Status; // Version not supported
}
/* Interface version 0 */
InterfaceHub->Size = IoStack->Parameters.QueryInterface.Size;
InterfaceHub->BusContext = PdoDevice;
InterfaceHub->InterfaceReference = USBI_InterfaceReference;
InterfaceHub->InterfaceDereference = USBI_InterfaceDereference;
/* Interface version 1 */
if (IoStack->Parameters.QueryInterface.Version >= 1)
{
InterfaceHub->CreateUsbDevice = USBHI_CreateUsbDevice;
InterfaceHub->InitializeUsbDevice = USBHI_InitializeUsbDevice;
InterfaceHub->GetUsbDescriptors = USBHI_GetUsbDescriptors;
InterfaceHub->RemoveUsbDevice = USBHI_RemoveUsbDevice;
InterfaceHub->RestoreUsbDevice = USBHI_RestoreUsbDevice;
InterfaceHub->QueryDeviceInformation = USBHI_QueryDeviceInformation;
}
/* Interface version 2 */
if (IoStack->Parameters.QueryInterface.Version >= 2)
{
InterfaceHub->GetControllerInformation = USBHI_GetControllerInformation;
InterfaceHub->ControllerSelectiveSuspend = USBHI_ControllerSelectiveSuspend;
InterfaceHub->GetExtendedHubInformation = USBHI_GetExtendedHubInformation;
InterfaceHub->GetRootHubSymbolicName = USBHI_GetRootHubSymbolicName;
InterfaceHub->GetDeviceBusContext = USBHI_GetDeviceBusContext;
InterfaceHub->Initialize20Hub = USBHI_Initialize20Hub;
}
/* Interface version 3 */
if (IoStack->Parameters.QueryInterface.Version >= 3)
InterfaceHub->RootHubInitNotification = USBHI_RootHubInitNotification;
/* Interface version 4 */
if (IoStack->Parameters.QueryInterface.Version >= 4)
InterfaceHub->FlushTransfers = USBHI_FlushTransfers;
/* Interface version 5 */
if (IoStack->Parameters.QueryInterface.Version >= 5)
InterfaceHub->SetDeviceHandleData = USBHI_SetDeviceHandleData;
/* Request completed */
return STATUS_SUCCESS;
}
else if (IsEqualGUIDAligned(IoStack->Parameters.QueryInterface.InterfaceType,
&USB_BUS_INTERFACE_USBDI_GUID))
{
/* Get request parameters */
InterfaceDI = (PUSB_BUS_INTERFACE_USBDI_V2)IoStack->Parameters.QueryInterface.Interface;
InterfaceDI->Version = IoStack->Parameters.QueryInterface.Version;
/* Check version */
if (IoStack->Parameters.QueryInterface.Version >= 3)
{
DPRINT1("USB_BUS_INTERFACE_USBDI_GUID version %x not supported!\n",
IoStack->Parameters.QueryInterface.Version);
return Irp->IoStatus.Status; // Version not supported
}
/* Interface version 0 */
InterfaceDI->Size = IoStack->Parameters.QueryInterface.Size;
InterfaceDI->BusContext = PdoDevice;
InterfaceDI->InterfaceReference = USBI_InterfaceReference;
InterfaceDI->InterfaceDereference = USBI_InterfaceDereference;
InterfaceDI->GetUSBDIVersion = USBDI_GetUSBDIVersion;
InterfaceDI->QueryBusTime = USBDI_QueryBusTime;
InterfaceDI->SubmitIsoOutUrb = USBDI_SubmitIsoOutUrb;
InterfaceDI->QueryBusInformation = USBDI_QueryBusInformation;
/* Interface version 1 */
if (IoStack->Parameters.QueryInterface.Version >= 1)
InterfaceDI->IsDeviceHighSpeed = USBDI_IsDeviceHighSpeed;
/* Interface version 2 */
if (IoStack->Parameters.QueryInterface.Version >= 2)
InterfaceDI->EnumLogEntry = USBDI_EnumLogEntry;
return STATUS_SUCCESS;
}
else
{
/* Convert GUID to string */
Status = RtlStringFromGUID(IoStack->Parameters.QueryInterface.InterfaceType,
&GuidBuffer);
if (NT_SUCCESS(Status))
{
/* Print interface */
DPRINT1("HandleQueryInterface UNKNOWN INTERFACE GUID: %wZ Version %x\n",
&GuidBuffer,
IoStack->Parameters.QueryInterface.Version);
RtlFreeUnicodeString(&GuidBuffer); // Free GUID buffer
}
}
return Irp->IoStatus.Status;
}