mirror of
https://github.com/reactos/reactos.git
synced 2024-07-12 07:35:10 +00:00
07e8b3be9b
- Implement counting interface descriptors - Fix allocating interface list - Fix multiple bugs when copying interface information - Implement support function to dump function descriptor - Fix multiple bugs when creating compatible / hardware id string - Implement legacy enumerator, which will be used for HID composite devices - Implement special enumerator for audio devices - Display static GenericCompositeUSBDeviceString, needs to be read from registry in order to be MUI aware - Device initializes and device wizard pops up - Tested in XP with Ros USB stack + USB Audio Microphone svn path=/branches/usb-bringup-trunk/; revision=55253
351 lines
8.2 KiB
C
351 lines
8.2 KiB
C
/*
|
|
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
* FILE: drivers/usb/usbccgp/pdo.c
|
|
* PURPOSE: USB device driver.
|
|
* PROGRAMMERS:
|
|
* Michael Martin (michael.martin@reactos.org)
|
|
* Johannes Anderwald (johannes.anderwald@reactos.org)
|
|
* Cameron Gutman
|
|
*/
|
|
|
|
#include "usbccgp.h"
|
|
|
|
NTSTATUS
|
|
USBCCGP_PdoHandleQueryDeviceText(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN OUT PIRP Irp)
|
|
{
|
|
LPWSTR Buffer;
|
|
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
|
LPWSTR GenericString = L"Composite USB Device";
|
|
//
|
|
// get device extension
|
|
//
|
|
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
|
|
//
|
|
// is there a device description
|
|
//
|
|
if (PDODeviceExtension->FunctionDescriptor->FunctionDescription.Length)
|
|
{
|
|
//
|
|
// allocate buffer
|
|
//
|
|
Buffer = AllocateItem(NonPagedPool, PDODeviceExtension->FunctionDescriptor->FunctionDescription.Length + sizeof(WCHAR));
|
|
if (!Buffer)
|
|
{
|
|
//
|
|
// no memory
|
|
//
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
//
|
|
// copy buffer
|
|
//
|
|
Irp->IoStatus.Information = (ULONG_PTR)Buffer;
|
|
RtlCopyMemory(Buffer, PDODeviceExtension->FunctionDescriptor->FunctionDescription.Buffer, PDODeviceExtension->FunctionDescriptor->FunctionDescription.Length);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// FIXME use GenericCompositeUSBDeviceString
|
|
//
|
|
UNIMPLEMENTED
|
|
Buffer = AllocateItem(PagedPool, (wcslen(GenericString) + 1) * sizeof(WCHAR));
|
|
if (!Buffer)
|
|
{
|
|
//
|
|
// no memory
|
|
//
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
RtlCopyMemory(Buffer, GenericString, (wcslen(GenericString) + 1) * sizeof(WCHAR));
|
|
Irp->IoStatus.Information = (ULONG_PTR)Buffer;
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS
|
|
USBCCGP_PdoHandleDeviceRelations(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN OUT PIRP Irp)
|
|
{
|
|
PDEVICE_RELATIONS DeviceRelations;
|
|
PIO_STACK_LOCATION IoStack;
|
|
|
|
DPRINT1("USBCCGP_PdoHandleDeviceRelations\n");
|
|
|
|
//
|
|
// get current irp stack location
|
|
//
|
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
//
|
|
// check if relation type is BusRelations
|
|
//
|
|
if (IoStack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
|
|
{
|
|
//
|
|
// PDO handles only target device relation
|
|
//
|
|
return Irp->IoStatus.Status;
|
|
}
|
|
|
|
//
|
|
// allocate device relations
|
|
//
|
|
DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS));
|
|
if (!DeviceRelations)
|
|
{
|
|
//
|
|
// no memory
|
|
//
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
//
|
|
// initialize device relations
|
|
//
|
|
DeviceRelations->Count = 1;
|
|
DeviceRelations->Objects[0] = DeviceObject;
|
|
ObReferenceObject(DeviceObject);
|
|
|
|
//
|
|
// store result
|
|
//
|
|
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
|
|
|
|
//
|
|
// completed successfully
|
|
//
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS
|
|
USBCCGP_PdoHandleQueryId(
|
|
PDEVICE_OBJECT DeviceObject,
|
|
PIRP Irp)
|
|
{
|
|
PIO_STACK_LOCATION IoStack;
|
|
PUNICODE_STRING DeviceString = NULL;
|
|
UNICODE_STRING TempString;
|
|
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
|
NTSTATUS Status;
|
|
LPWSTR Buffer;
|
|
|
|
//
|
|
// get current irp stack location
|
|
//
|
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
//
|
|
// get device extension
|
|
//
|
|
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
|
|
|
|
if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID)
|
|
{
|
|
//
|
|
// handle query device id
|
|
//
|
|
Status = USBCCGP_SyncForwardIrp(PDODeviceExtension->NextDeviceObject, Irp);
|
|
|
|
//
|
|
// FIXME append interface id
|
|
//
|
|
UNIMPLEMENTED
|
|
return Status;
|
|
}
|
|
else if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
|
|
{
|
|
//
|
|
// handle instance id
|
|
//
|
|
DeviceString = &PDODeviceExtension->FunctionDescriptor->HardwareId;
|
|
}
|
|
else if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID)
|
|
{
|
|
//
|
|
// handle instance id
|
|
//
|
|
RtlInitUnicodeString(&TempString, L"0000");
|
|
DeviceString = &TempString;
|
|
}
|
|
else if (IoStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs)
|
|
{
|
|
//
|
|
// handle instance id
|
|
//
|
|
DeviceString = &PDODeviceExtension->FunctionDescriptor->CompatibleId;
|
|
}
|
|
|
|
//
|
|
// sanity check
|
|
//
|
|
ASSERT(DeviceString != NULL);
|
|
|
|
//
|
|
// allocate buffer
|
|
//
|
|
Buffer = AllocateItem(NonPagedPool, DeviceString->Length + sizeof(WCHAR));
|
|
if (!Buffer)
|
|
{
|
|
//
|
|
// no memory
|
|
//
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
//
|
|
// copy buffer
|
|
//
|
|
Irp->IoStatus.Information = (ULONG_PTR)Buffer;
|
|
RtlCopyMemory(Buffer, DeviceString->Buffer, DeviceString->Length);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS
|
|
PDO_HandlePnp(
|
|
PDEVICE_OBJECT DeviceObject,
|
|
PIRP Irp)
|
|
{
|
|
PIO_STACK_LOCATION IoStack;
|
|
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
|
NTSTATUS Status;
|
|
|
|
//
|
|
// get current stack location
|
|
//
|
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
//
|
|
// get device extension
|
|
//
|
|
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
|
|
//
|
|
// sanity check
|
|
//
|
|
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
|
|
|
|
switch(IoStack->MinorFunction)
|
|
{
|
|
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
|
{
|
|
//
|
|
// handle device relations
|
|
//
|
|
Status = USBCCGP_PdoHandleDeviceRelations(DeviceObject, Irp);
|
|
break;
|
|
}
|
|
case IRP_MN_QUERY_DEVICE_TEXT:
|
|
{
|
|
//
|
|
// handle query device text
|
|
//
|
|
Status = USBCCGP_PdoHandleQueryDeviceText(DeviceObject, Irp);
|
|
break;
|
|
}
|
|
case IRP_MN_QUERY_ID:
|
|
{
|
|
//
|
|
// handle request
|
|
//
|
|
Status = USBCCGP_PdoHandleQueryId(DeviceObject, Irp);
|
|
break;
|
|
}
|
|
case IRP_MN_REMOVE_DEVICE:
|
|
{
|
|
DPRINT1("IRP_MN_REMOVE_DEVICE\n");
|
|
|
|
/* Complete the IRP */
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
/* Delete the device object */
|
|
IoDeleteDevice(DeviceObject);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
case IRP_MN_QUERY_CAPABILITIES:
|
|
{
|
|
//
|
|
// copy device capabilities
|
|
//
|
|
RtlCopyMemory(IoStack->Parameters.DeviceCapabilities.Capabilities, &PDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES));
|
|
|
|
/* Complete the IRP */
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
case IRP_MN_START_DEVICE:
|
|
{
|
|
//
|
|
// no-op for PDO
|
|
//
|
|
DPRINT1("[USBCCGP] PDO IRP_MN_START\n");
|
|
Status = STATUS_SUCCESS;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
//
|
|
// do nothing
|
|
//
|
|
Status = Irp->IoStatus.Status;
|
|
}
|
|
}
|
|
|
|
//
|
|
// complete request
|
|
//
|
|
if (Status != STATUS_PENDING)
|
|
{
|
|
//
|
|
// store result
|
|
//
|
|
Irp->IoStatus.Status = Status;
|
|
|
|
//
|
|
// complete request
|
|
//
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
}
|
|
|
|
//
|
|
// done processing
|
|
//
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
PDO_Dispatch(
|
|
PDEVICE_OBJECT DeviceObject,
|
|
PIRP Irp)
|
|
{
|
|
PIO_STACK_LOCATION IoStack;
|
|
NTSTATUS Status;
|
|
|
|
/* get stack location */
|
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
switch(IoStack->MajorFunction)
|
|
{
|
|
case IRP_MJ_PNP:
|
|
return PDO_HandlePnp(DeviceObject, Irp);
|
|
default:
|
|
DPRINT1("PDO_Dispatch Function %x not implemented\n", IoStack->MajorFunction);
|
|
ASSERT(FALSE);
|
|
Status = Irp->IoStatus.Status;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return Status;
|
|
}
|
|
|
|
}
|