mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 19:05:52 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
895
drivers/usb/usbccgp/function.c
Normal file
895
drivers/usb/usbccgp/function.c
Normal file
|
@ -0,0 +1,895 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: drivers/usb/usbccgp/descriptor.c
|
||||
* PURPOSE: USB device driver.
|
||||
* PROGRAMMERS:
|
||||
* Michael Martin (michael.martin@reactos.org)
|
||||
* Johannes Anderwald (johannes.anderwald@reactos.org)
|
||||
* Cameron Gutman
|
||||
*/
|
||||
|
||||
#include "usbccgp.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
NTSTATUS
|
||||
USBCCGP_QueryInterface(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
OUT PUSBC_DEVICE_CONFIGURATION_INTERFACE_V1 BusInterface)
|
||||
{
|
||||
KEVENT Event;
|
||||
NTSTATUS Status;
|
||||
PIRP Irp;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
|
||||
/* Sanity checks */
|
||||
ASSERT(DeviceObject);
|
||||
|
||||
/* Initialize event */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
|
||||
/* Init interface */
|
||||
RtlZeroMemory(BusInterface, sizeof(USBC_DEVICE_CONFIGURATION_INTERFACE_V1));
|
||||
BusInterface->Version = USBC_DEVICE_CONFIGURATION_INTERFACE_VERSION_1;
|
||||
BusInterface->Size = sizeof(USBC_DEVICE_CONFIGURATION_INTERFACE_V1);
|
||||
|
||||
/* Create irp */
|
||||
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
&Event,
|
||||
&IoStatus);
|
||||
|
||||
//
|
||||
// was irp built
|
||||
//
|
||||
if (Irp == NULL)
|
||||
{
|
||||
//
|
||||
// no memory
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// initialize request
|
||||
//
|
||||
Stack = IoGetNextIrpStackLocation(Irp);
|
||||
Stack->MajorFunction = IRP_MJ_PNP;
|
||||
Stack->MinorFunction = IRP_MN_QUERY_INTERFACE;
|
||||
Stack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
|
||||
Stack->Parameters.QueryInterface.InterfaceType = (LPGUID)&USB_BUS_INTERFACE_USBC_CONFIGURATION_GUID;
|
||||
Stack->Parameters.QueryInterface.Version = 2;
|
||||
Stack->Parameters.QueryInterface.Interface = (PINTERFACE)&BusInterface;
|
||||
Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
|
||||
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||
|
||||
//
|
||||
// call driver
|
||||
//
|
||||
Status = IoCallDriver(DeviceObject, Irp);
|
||||
|
||||
//
|
||||
// did operation complete
|
||||
//
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
//
|
||||
// wait for completion
|
||||
//
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
|
||||
//
|
||||
// collect status
|
||||
//
|
||||
Status = IoStatus.Status;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
USBCCGP_CustomEnumWithInterface(
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||
ULONG FunctionDescriptorBufferLength = 0;
|
||||
NTSTATUS Status;
|
||||
PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptorBuffer = NULL;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||
|
||||
if (FDODeviceExtension->BusInterface.StartDeviceCallback == NULL)
|
||||
{
|
||||
//
|
||||
// not supported
|
||||
//
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// invoke callback
|
||||
//
|
||||
Status = FDODeviceExtension->BusInterface.StartDeviceCallback(FDODeviceExtension->DeviceDescriptor,
|
||||
FDODeviceExtension->ConfigurationDescriptor,
|
||||
&FunctionDescriptorBuffer,
|
||||
&FunctionDescriptorBufferLength,
|
||||
DeviceObject,
|
||||
FDODeviceExtension->PhysicalDeviceObject);
|
||||
|
||||
DPRINT("USBCCGP_CustomEnumWithInterface Status %lx\n", Status);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
DPRINT("FunctionDescriptorBufferLength %lu\n", FunctionDescriptorBufferLength);
|
||||
DPRINT("FunctionDescriptorBuffer %p\n", FunctionDescriptorBuffer);
|
||||
|
||||
//
|
||||
// assume length % function buffer size
|
||||
//
|
||||
ASSERT(FunctionDescriptorBufferLength);
|
||||
ASSERT(FunctionDescriptorBufferLength % sizeof(USBC_FUNCTION_DESCRIPTOR) == 0);
|
||||
|
||||
//
|
||||
// store result
|
||||
//
|
||||
FDODeviceExtension->FunctionDescriptor = FunctionDescriptorBuffer;
|
||||
FDODeviceExtension->FunctionDescriptorCount = FunctionDescriptorBufferLength / sizeof(USBC_FUNCTION_DESCRIPTOR);
|
||||
|
||||
//
|
||||
// success
|
||||
//
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ULONG
|
||||
USBCCGP_CountAssociationDescriptors(
|
||||
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
|
||||
{
|
||||
PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR Descriptor;
|
||||
PUCHAR Offset, End;
|
||||
ULONG Count = 0;
|
||||
|
||||
//
|
||||
// init offsets
|
||||
//
|
||||
Offset = (PUCHAR)ConfigurationDescriptor + ConfigurationDescriptor->bLength;
|
||||
End = (PUCHAR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength;
|
||||
|
||||
while (Offset < End)
|
||||
{
|
||||
//
|
||||
// get association descriptor
|
||||
//
|
||||
Descriptor = (PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR)Offset;
|
||||
|
||||
if (Descriptor->bLength == sizeof(USB_INTERFACE_ASSOCIATION_DESCRIPTOR) && Descriptor->bDescriptorType == USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE)
|
||||
{
|
||||
//
|
||||
// found descriptor
|
||||
//
|
||||
Count++;
|
||||
}
|
||||
|
||||
//
|
||||
// move to next descriptor
|
||||
//
|
||||
Offset += Descriptor->bLength;
|
||||
}
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return Count;
|
||||
}
|
||||
|
||||
PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR
|
||||
USBCCGP_GetAssociationDescriptorAtIndex(
|
||||
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
|
||||
IN ULONG Index)
|
||||
{
|
||||
PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR Descriptor;
|
||||
PUCHAR Offset, End;
|
||||
ULONG Count = 0;
|
||||
|
||||
//
|
||||
// init offsets
|
||||
//
|
||||
Offset = (PUCHAR)ConfigurationDescriptor + ConfigurationDescriptor->bLength;
|
||||
End = (PUCHAR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength;
|
||||
|
||||
while (Offset < End)
|
||||
{
|
||||
//
|
||||
// get association descriptor
|
||||
//
|
||||
Descriptor = (PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR)Offset;
|
||||
|
||||
if (Descriptor->bLength == sizeof(USB_INTERFACE_ASSOCIATION_DESCRIPTOR) && Descriptor->bDescriptorType == USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE)
|
||||
{
|
||||
if (Index == Count)
|
||||
{
|
||||
//
|
||||
// found descriptor
|
||||
//
|
||||
return Descriptor;
|
||||
}
|
||||
|
||||
//
|
||||
// not the searched one
|
||||
//
|
||||
Count++;
|
||||
}
|
||||
|
||||
//
|
||||
// move to next descriptor
|
||||
//
|
||||
Offset += Descriptor->bLength;
|
||||
}
|
||||
|
||||
//
|
||||
// failed to find descriptor at the specified index
|
||||
//
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
USBCCGP_InitInterfaceListOfFunctionDescriptor(
|
||||
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
|
||||
IN PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR AssociationDescriptor,
|
||||
OUT PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor)
|
||||
{
|
||||
PUSB_INTERFACE_DESCRIPTOR Descriptor;
|
||||
PUCHAR Offset, End;
|
||||
ULONG Count = 0;
|
||||
|
||||
//
|
||||
// init offsets
|
||||
//
|
||||
Offset = (PUCHAR)AssociationDescriptor + AssociationDescriptor->bLength;
|
||||
End = (PUCHAR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength;
|
||||
|
||||
while (Offset < End)
|
||||
{
|
||||
//
|
||||
// get association descriptor
|
||||
//
|
||||
Descriptor = (PUSB_INTERFACE_DESCRIPTOR)Offset;
|
||||
|
||||
if (Descriptor->bLength == sizeof(USB_INTERFACE_DESCRIPTOR) && Descriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
|
||||
{
|
||||
//
|
||||
// store interface descriptor
|
||||
//
|
||||
FunctionDescriptor->InterfaceDescriptorList[Count] = Descriptor;
|
||||
Count++;
|
||||
|
||||
if (Count == AssociationDescriptor->bInterfaceCount)
|
||||
{
|
||||
//
|
||||
// got all interfaces
|
||||
//
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (Descriptor->bLength == sizeof(USB_INTERFACE_ASSOCIATION_DESCRIPTOR) && Descriptor->bDescriptorType == USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE)
|
||||
{
|
||||
//
|
||||
// WTF? a association descriptor which overlaps the next association descriptor
|
||||
//
|
||||
DPRINT1("Invalid association descriptor\n");
|
||||
ASSERT(FALSE);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
//
|
||||
// move to next descriptor
|
||||
//
|
||||
Offset += Descriptor->bLength;
|
||||
}
|
||||
|
||||
//
|
||||
// invalid association descriptor
|
||||
//
|
||||
DPRINT1("Invalid association descriptor\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
USBCCGP_InitFunctionDescriptor(
|
||||
IN PFDO_DEVICE_EXTENSION FDODeviceExtension,
|
||||
IN ULONG FunctionNumber,
|
||||
OUT PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor)
|
||||
{
|
||||
PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR Descriptor;
|
||||
NTSTATUS Status;
|
||||
LPWSTR DescriptionBuffer;
|
||||
WCHAR Buffer[100];
|
||||
ULONG Index;
|
||||
|
||||
// init function number
|
||||
FunctionDescriptor->FunctionNumber = (UCHAR)FunctionNumber;
|
||||
|
||||
// get association descriptor
|
||||
Descriptor = USBCCGP_GetAssociationDescriptorAtIndex(FDODeviceExtension->ConfigurationDescriptor, FunctionNumber);
|
||||
ASSERT(Descriptor);
|
||||
|
||||
// store number interfaces
|
||||
FunctionDescriptor->NumberOfInterfaces = Descriptor->bInterfaceCount;
|
||||
|
||||
// allocate array for interface count
|
||||
FunctionDescriptor->InterfaceDescriptorList = AllocateItem(NonPagedPool, sizeof(PUSB_INTERFACE_DESCRIPTOR) * Descriptor->bInterfaceCount);
|
||||
if (!FunctionDescriptor->InterfaceDescriptorList)
|
||||
{
|
||||
//
|
||||
// no memory
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
// init interface list
|
||||
Status = USBCCGP_InitInterfaceListOfFunctionDescriptor(FDODeviceExtension->ConfigurationDescriptor, Descriptor, FunctionDescriptor);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// now init interface description
|
||||
//
|
||||
if (Descriptor->iFunction)
|
||||
{
|
||||
//
|
||||
// get interface description
|
||||
//
|
||||
Status = USBCCGP_GetStringDescriptor(FDODeviceExtension->NextDeviceObject,
|
||||
100 * sizeof(WCHAR),
|
||||
Descriptor->iFunction,
|
||||
0x0409, //FIXME
|
||||
(PVOID*)&DescriptionBuffer);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// no description
|
||||
//
|
||||
RtlInitUnicodeString(&FunctionDescriptor->FunctionDescription, L"");
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// init description
|
||||
//
|
||||
RtlInitUnicodeString(&FunctionDescriptor->FunctionDescription, DescriptionBuffer);
|
||||
}
|
||||
DPRINT1("FunctionDescription %wZ\n", &FunctionDescriptor->FunctionDescription);
|
||||
}
|
||||
|
||||
//
|
||||
// now init hardware id
|
||||
//
|
||||
Index = swprintf(Buffer, L"USB\\VID_%04x&PID_%04x&Rev_%04x&MI_%02x", FDODeviceExtension->DeviceDescriptor->idVendor,
|
||||
FDODeviceExtension->DeviceDescriptor->idProduct,
|
||||
FDODeviceExtension->DeviceDescriptor->bcdDevice,
|
||||
Descriptor->bFirstInterface) + 1;
|
||||
Index += swprintf(&Buffer[Index], L"USB\\VID_%04x&PID_%04x&MI_%02x", FDODeviceExtension->DeviceDescriptor->idVendor,
|
||||
FDODeviceExtension->DeviceDescriptor->idProduct,
|
||||
Descriptor->bFirstInterface) + 1;
|
||||
|
||||
// allocate result buffer
|
||||
DescriptionBuffer = AllocateItem(NonPagedPool, (Index + 1) * sizeof(WCHAR));
|
||||
if (!DescriptionBuffer)
|
||||
{
|
||||
//
|
||||
// failed to allocate memory
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
// copy description
|
||||
RtlCopyMemory(DescriptionBuffer, Buffer, (Index + 1) * sizeof(WCHAR));
|
||||
FunctionDescriptor->HardwareId.Buffer = DescriptionBuffer;
|
||||
FunctionDescriptor->HardwareId.Length = Index * sizeof(WCHAR);
|
||||
FunctionDescriptor->HardwareId.MaximumLength = (Index + 1) * sizeof(WCHAR);
|
||||
|
||||
//
|
||||
// now init the compatible id
|
||||
//
|
||||
Index = swprintf(Buffer, L"USB\\Class_%02x&SubClass_%02x&Prot_%02x", Descriptor->bFunctionClass, Descriptor->bFunctionSubClass, Descriptor->bFunctionProtocol) + 1;
|
||||
Index += swprintf(&Buffer[Index], L"USB\\Class_%02x&SubClass_%02x", Descriptor->bFunctionClass, Descriptor->bFunctionSubClass) + 1;
|
||||
Index += swprintf(&Buffer[Index], L"USB\\Class_%02x", Descriptor->bFunctionClass) + 1;
|
||||
|
||||
// allocate result buffer
|
||||
DescriptionBuffer = AllocateItem(NonPagedPool, (Index + 1) * sizeof(WCHAR));
|
||||
if (!DescriptionBuffer)
|
||||
{
|
||||
//
|
||||
// failed to allocate memory
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
// copy description
|
||||
RtlCopyMemory(DescriptionBuffer, Buffer, (Index + 1) * sizeof(WCHAR));
|
||||
FunctionDescriptor->CompatibleId.Buffer = DescriptionBuffer;
|
||||
FunctionDescriptor->CompatibleId.Length = Index * sizeof(WCHAR);
|
||||
FunctionDescriptor->CompatibleId.MaximumLength = (Index + 1) * sizeof(WCHAR);
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
USBCCGP_EnumWithAssociationDescriptor(
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
ULONG DescriptorCount, Index;
|
||||
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||
|
||||
//
|
||||
// count association descriptors
|
||||
//
|
||||
DescriptorCount = USBCCGP_CountAssociationDescriptors(FDODeviceExtension->ConfigurationDescriptor);
|
||||
if (!DescriptorCount)
|
||||
{
|
||||
//
|
||||
// no descriptors found
|
||||
//
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// allocate function descriptor array
|
||||
//
|
||||
FDODeviceExtension->FunctionDescriptor = AllocateItem(NonPagedPool, sizeof(USBC_FUNCTION_DESCRIPTOR) * DescriptorCount);
|
||||
if (!FDODeviceExtension->FunctionDescriptor)
|
||||
{
|
||||
//
|
||||
// no memory
|
||||
//
|
||||
DPRINT1("USBCCGP_EnumWithAssociationDescriptor failed to allocate function descriptor count %x\n", DescriptorCount);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < DescriptorCount; Index++)
|
||||
{
|
||||
//
|
||||
// init function descriptors
|
||||
//
|
||||
Status = USBCCGP_InitFunctionDescriptor(FDODeviceExtension, Index, &FDODeviceExtension->FunctionDescriptor[Index]);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// store function descriptor count
|
||||
//
|
||||
FDODeviceExtension->FunctionDescriptorCount = DescriptorCount;
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
USBCCG_InitIdsWithInterfaceDescriptor(
|
||||
IN PFDO_DEVICE_EXTENSION FDODeviceExtension,
|
||||
IN PUSB_INTERFACE_DESCRIPTOR Descriptor,
|
||||
IN ULONG FunctionIndex,
|
||||
OUT PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor)
|
||||
{
|
||||
ULONG Index;
|
||||
WCHAR Buffer[200];
|
||||
LPWSTR DescriptionBuffer;
|
||||
NTSTATUS Status;
|
||||
|
||||
//
|
||||
// now init interface description
|
||||
//
|
||||
if (Descriptor->iInterface)
|
||||
{
|
||||
//
|
||||
// get interface description
|
||||
//
|
||||
Status = USBCCGP_GetStringDescriptor(FDODeviceExtension->NextDeviceObject,
|
||||
100 * sizeof(WCHAR),
|
||||
Descriptor->iInterface,
|
||||
0x0409, //FIXME
|
||||
(PVOID*)&DescriptionBuffer);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// no description
|
||||
//
|
||||
RtlInitUnicodeString(&FunctionDescriptor->FunctionDescription, L"");
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// init description
|
||||
//
|
||||
RtlInitUnicodeString(&FunctionDescriptor->FunctionDescription, DescriptionBuffer);
|
||||
}
|
||||
DPRINT1("FunctionDescription %wZ\n", &FunctionDescriptor->FunctionDescription);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// now init hardware id
|
||||
//
|
||||
Index = swprintf(Buffer, L"USB\\VID_%04x&PID_%04x&Rev_%04x&MI_%02x", FDODeviceExtension->DeviceDescriptor->idVendor,
|
||||
FDODeviceExtension->DeviceDescriptor->idProduct,
|
||||
FDODeviceExtension->DeviceDescriptor->bcdDevice,
|
||||
FunctionIndex) + 1;
|
||||
Index += swprintf(&Buffer[Index], L"USB\\VID_%04x&PID_%04x&MI_%02x", FDODeviceExtension->DeviceDescriptor->idVendor,
|
||||
FDODeviceExtension->DeviceDescriptor->idProduct,
|
||||
FunctionIndex) + 1;
|
||||
|
||||
// allocate result buffer
|
||||
DescriptionBuffer = AllocateItem(NonPagedPool, (Index + 1) * sizeof(WCHAR));
|
||||
if (!DescriptionBuffer)
|
||||
{
|
||||
//
|
||||
// failed to allocate memory
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
// copy description
|
||||
RtlCopyMemory(DescriptionBuffer, Buffer, (Index + 1) * sizeof(WCHAR));
|
||||
FunctionDescriptor->HardwareId.Buffer = DescriptionBuffer;
|
||||
FunctionDescriptor->HardwareId.Length = Index * sizeof(WCHAR);
|
||||
FunctionDescriptor->HardwareId.MaximumLength = (Index + 1) * sizeof(WCHAR);
|
||||
|
||||
//
|
||||
// now init the compatible id
|
||||
//
|
||||
Index = swprintf(Buffer, L"USB\\Class_%02x&SubClass_%02x&Prot_%02x", Descriptor->bInterfaceClass, Descriptor->bInterfaceSubClass, Descriptor->bInterfaceProtocol) + 1;
|
||||
Index += swprintf(&Buffer[Index], L"USB\\Class_%02x&SubClass_%02x", Descriptor->bInterfaceClass, Descriptor->bInterfaceSubClass) + 1;
|
||||
Index += swprintf(&Buffer[Index], L"USB\\Class_%02x", Descriptor->bInterfaceClass) + 1;
|
||||
|
||||
// allocate result buffer
|
||||
DescriptionBuffer = AllocateItem(NonPagedPool, (Index + 1) * sizeof(WCHAR));
|
||||
if (!DescriptionBuffer)
|
||||
{
|
||||
//
|
||||
// failed to allocate memory
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
// copy description
|
||||
RtlCopyMemory(DescriptionBuffer, Buffer, (Index + 1) * sizeof(WCHAR));
|
||||
FunctionDescriptor->CompatibleId.Buffer = DescriptionBuffer;
|
||||
FunctionDescriptor->CompatibleId.Length = Index * sizeof(WCHAR);
|
||||
FunctionDescriptor->CompatibleId.MaximumLength = (Index + 1) * sizeof(WCHAR);
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
USBCCGP_LegacyEnum(
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
ULONG Index;
|
||||
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||
|
||||
//
|
||||
// sanity check
|
||||
//
|
||||
ASSERT(FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces);
|
||||
|
||||
//
|
||||
// allocate function array
|
||||
//
|
||||
FDODeviceExtension->FunctionDescriptor = AllocateItem(NonPagedPool, sizeof(USBC_FUNCTION_DESCRIPTOR) * FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces);
|
||||
if (!FDODeviceExtension->FunctionDescriptor)
|
||||
{
|
||||
//
|
||||
// no memory
|
||||
//
|
||||
DPRINT1("USBCCGP_EnumWithAssociationDescriptor failed to allocate function descriptor %lu\n", FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// init function descriptors
|
||||
//
|
||||
FDODeviceExtension->FunctionDescriptorCount = 0;
|
||||
for (Index = 0; Index < FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces; Index++)
|
||||
{
|
||||
// get interface descriptor
|
||||
InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(FDODeviceExtension->ConfigurationDescriptor, FDODeviceExtension->ConfigurationDescriptor, Index, 0, -1, -1, -1);
|
||||
if (InterfaceDescriptor == NULL)
|
||||
{
|
||||
//
|
||||
// failed to find interface descriptor
|
||||
//
|
||||
DPRINT1("[USBCCGP] Failed to find interface descriptor index %lu\n", Index);
|
||||
ASSERT(FALSE);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
//
|
||||
// init function descriptor
|
||||
//
|
||||
FDODeviceExtension->FunctionDescriptor[Index].FunctionNumber = Index;
|
||||
FDODeviceExtension->FunctionDescriptor[Index].NumberOfInterfaces = 1;
|
||||
FDODeviceExtension->FunctionDescriptor[Index].InterfaceDescriptorList = AllocateItem(NonPagedPool, sizeof(PUSB_INTERFACE_DESCRIPTOR) * 1);
|
||||
if (!FDODeviceExtension->FunctionDescriptor[Index].InterfaceDescriptorList)
|
||||
{
|
||||
//
|
||||
// no memory
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// store interface descriptor
|
||||
//
|
||||
FDODeviceExtension->FunctionDescriptor[Index].InterfaceDescriptorList[0] = InterfaceDescriptor;
|
||||
|
||||
//
|
||||
// now init the device ids
|
||||
//
|
||||
Status = USBCCG_InitIdsWithInterfaceDescriptor(FDODeviceExtension, InterfaceDescriptor, Index, &FDODeviceExtension->FunctionDescriptor[Index]);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed to init ids
|
||||
//
|
||||
DPRINT1("[USBCCGP] Failed to init ids with %lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// store function count
|
||||
//
|
||||
FDODeviceExtension->FunctionDescriptorCount++;
|
||||
}
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
USBCCGP_EnumWithUnionFunctionDescriptors(
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
USBCCGP_EnumWithAudioLegacy(
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
ULONG Index;
|
||||
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor, FirstDescriptor = NULL;
|
||||
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||
|
||||
|
||||
//
|
||||
// first check if all interfaces belong to the same audio class
|
||||
//
|
||||
for (Index = 0; Index < FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces; Index++)
|
||||
{
|
||||
//
|
||||
// get interface descriptor
|
||||
//
|
||||
InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(FDODeviceExtension->ConfigurationDescriptor, FDODeviceExtension->ConfigurationDescriptor, Index, 0, -1, -1, -1);
|
||||
DPRINT1("Index %lu Descriptor %p\n", Index, InterfaceDescriptor);
|
||||
ASSERT(InterfaceDescriptor);
|
||||
|
||||
if (InterfaceDescriptor->bInterfaceClass != 0x1)
|
||||
{
|
||||
//
|
||||
// collection contains non audio class
|
||||
//
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (FirstDescriptor == NULL)
|
||||
{
|
||||
//
|
||||
// store interface descriptor
|
||||
//
|
||||
FirstDescriptor = InterfaceDescriptor;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FirstDescriptor->bInterfaceSubClass == InterfaceDescriptor->bInterfaceSubClass)
|
||||
{
|
||||
//
|
||||
// interface subclass must be different from the first interface
|
||||
//
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// this is an composite audio device
|
||||
//
|
||||
DPRINT("[USBCCGP] Audio Composite Device detected\n");
|
||||
|
||||
//
|
||||
// audio interfaces are all grouped into one single function
|
||||
//
|
||||
FDODeviceExtension->FunctionDescriptor = AllocateItem(NonPagedPool, sizeof(USBC_FUNCTION_DESCRIPTOR));
|
||||
if (!FDODeviceExtension->FunctionDescriptor)
|
||||
{
|
||||
//
|
||||
// no memory
|
||||
//
|
||||
DPRINT1("USBCCGP_EnumWithAssociationDescriptor failed to allocate function descriptor count\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// init function number
|
||||
//
|
||||
FDODeviceExtension->FunctionDescriptor[0].FunctionNumber = 0;
|
||||
|
||||
//
|
||||
// store interfaces
|
||||
//
|
||||
Status = AllocateInterfaceDescriptorsArray(FDODeviceExtension->ConfigurationDescriptor, &FDODeviceExtension->FunctionDescriptor[0].InterfaceDescriptorList);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed to allocate descriptor array
|
||||
//
|
||||
DPRINT1("[USBCCGP] Failed to allocate descriptor array %lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// now init the device ids
|
||||
//
|
||||
Status = USBCCG_InitIdsWithInterfaceDescriptor(FDODeviceExtension, FirstDescriptor, 0, &FDODeviceExtension->FunctionDescriptor[0]);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed to init ids
|
||||
//
|
||||
DPRINT1("[USBCCGP] Failed to init ids with %lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// number of interfaces
|
||||
//
|
||||
FDODeviceExtension->FunctionDescriptor[0].NumberOfInterfaces = FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces;
|
||||
|
||||
//
|
||||
// store function count
|
||||
//
|
||||
FDODeviceExtension->FunctionDescriptorCount = 1;
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
USBCCGP_EnumerateFunctions(
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||
|
||||
//
|
||||
// first try with filter driver
|
||||
//
|
||||
Status = USBCCGP_CustomEnumWithInterface(DeviceObject);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// succeeded
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// enumerate functions with interface association descriptor
|
||||
//
|
||||
Status = USBCCGP_EnumWithAssociationDescriptor(DeviceObject);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// succeeded
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
#if 0
|
||||
//
|
||||
// try with union function descriptors
|
||||
//
|
||||
Status = USBCCGP_EnumWithUnionFunctionDescriptors(DeviceObject);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// succeeded
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// try with legacy audio methods
|
||||
//
|
||||
Status = USBCCGP_EnumWithAudioLegacy(DeviceObject);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// succeeded
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// try with legacy enumeration
|
||||
//
|
||||
return USBCCGP_LegacyEnum(DeviceObject);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue