[USBAUDIO]

- start implementing init routines
- not yet added to build

svn path=/trunk/; revision=72725
This commit is contained in:
Johannes Anderwald 2016-09-18 14:24:21 +00:00
parent 956b933a71
commit ad787661bb
8 changed files with 804 additions and 0 deletions

View file

@ -0,0 +1,25 @@
set_cpp()
remove_definitions(-D_WIN32_WINNT=0x502)
add_definitions(-D_WIN32_WINNT=0x600)
list(APPEND SOURCE
usbaudio.c
pool.c
filter.c
pin.c
guid.c)
add_library(usbaudio SHARED
${SOURCE}
usbaudio.rc)
target_link_libraries(usbaudio
libcntpr
${PSEH_LIB})
set_module_type(usbaudio kernelmodedriver)
add_importlibs(usbaudio ntoskrnl hal usbd ks)
add_cd_file(TARGET usbaudio DESTINATION reactos/system32/drivers NO_CAB FOR all)

View file

@ -0,0 +1,101 @@
/*
* PROJECT: ReactOS Universal Audio Class Driver
* LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/usb/usbaudio/filter.c
* PURPOSE: USB Audio device driver.
* PROGRAMMERS:
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/
#include "usbaudio.h"
NTSTATUS
BuildUSBAudioFilterTopology(
PKSDEVICE Device)
{
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
USBAudioPinBuildDescriptors(
PKSDEVICE Device,
PKSPIN_DESCRIPTOR_EX *PinDescriptors,
PULONG PinDescriptorsCount,
PULONG PinDescriptorSize)
{
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
USBAudioInitComponentId(
PKSDEVICE Device,
IN PKSCOMPONENTID ComponentId)
{
PDEVICE_EXTENSION DeviceExtension;
/* get device extension */
DeviceExtension = Device->Context;
INIT_USBAUDIO_MID(&ComponentId->Manufacturer, DeviceExtension->DeviceDescriptor->idVendor);
INIT_USBAUDIO_PID(&ComponentId->Product, DeviceExtension->DeviceDescriptor->idProduct);
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
USBAudioCreateFilterContext(
PKSDEVICE Device)
{
KSFILTER_DESCRIPTOR FilterDescriptor;
PKSCOMPONENTID ComponentId;
NTSTATUS Status;
/* clear filter descriptor */
RtlZeroMemory(&FilterDescriptor, sizeof(KSFILTER_DESCRIPTOR));
/* init filter descriptor*/
FilterDescriptor.Version = KSFILTER_DESCRIPTOR_VERSION;
FilterDescriptor.ReferenceGuid = &KSNAME_Filter;
/* init component id*/
ComponentId = AllocFunction(sizeof(KSCOMPONENTID));
if (!ComponentId)
{
/* no memory */
return USBD_STATUS_INSUFFICIENT_RESOURCES;
}
Status = USBAudioInitComponentId(Device, ComponentId);
if (!NT_SUCCESS(Status))
{
/* failed*/
FreeFunction(ComponentId);
return Status;
}
FilterDescriptor.ComponentId = ComponentId;
/* build pin descriptors */
Status = USBAudioPinBuildDescriptors(Device, (PKSPIN_DESCRIPTOR_EX *)&FilterDescriptor.PinDescriptors, &FilterDescriptor.PinDescriptorsCount, &FilterDescriptor.PinDescriptorSize);
if (!NT_SUCCESS(Status))
{
/* failed*/
FreeFunction(ComponentId);
return Status;
}
/* build topology */
Status = BuildUSBAudioFilterTopology(Device);
if (!NT_SUCCESS(Status))
{
/* failed*/
FreeFunction(ComponentId);
return Status;
}
return Status;
}

View file

@ -0,0 +1,14 @@
/* DO NOT USE THE PRECOMPILED HEADER FOR THIS FILE! */
//#include <wdm.h>
#include <portcls.h>
#include <initguid.h>
#include <wdmguid.h>
#include <hubbusif.h>
#include <usbbusif.h>
/* FIXME */
DEFINE_GUID(KSNAME_Filter, 0x9b365890L, 0x165f, 0x11d0, 0xa1, 0x95, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4);
/* NO CODE HERE, THIS IS JUST REQUIRED FOR THE GUID DEFINITIONS */

View file

@ -0,0 +1,11 @@
/*
* PROJECT: ReactOS Universal Audio Class Driver
* LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/usb/usbaudio/pin.c
* PURPOSE: USB Audio device driver.
* PROGRAMMERS:
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/
#include "usbaudio.h"

View file

@ -0,0 +1,35 @@
/*
* PROJECT: ReactOS Universal Audio Class Driver
* LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/usb/usbaudio/pool.c
* PURPOSE: USB Audio device driver.
* PROGRAMMERS:
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/
#include "usbaudio.h"
PVOID
NTAPI
AllocFunction(
IN ULONG ItemSize)
{
PVOID Item = ExAllocatePoolWithTag(NonPagedPool, ItemSize, USBAUDIO_TAG);
if (Item)
{
// zero item
RtlZeroMemory(Item, ItemSize);
}
// done
return Item;
}
VOID
NTAPI
FreeFunction(
IN PVOID Item)
{
/* free item */
ExFreePoolWithTag(Item, USBAUDIO_TAG);
}

View file

@ -0,0 +1,484 @@
/*
* PROJECT: ReactOS Universal Audio Class Driver
* LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/usb/usbaudio/usbaudio.c
* PURPOSE: USB Audio device driver.
* PROGRAMMERS:
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/
#include "usbaudio.h"
static KSDEVICE_DISPATCH KsDeviceDispatch = {
USBAudioAddDevice,
USBAudioPnPStart,
NULL,
USBAudioPnPQueryStop,
USBAudioPnPCancelStop,
USBAudioPnPStop,
USBAudioPnPQueryRemove,
USBAudioPnPCancelRemove,
USBAudioPnPRemove,
USBAudioPnPQueryCapabilities,
USBAudioPnPSurpriseRemoval,
USBAudioPnPQueryPower,
USBAudioPnPSetPower
};
static KSDEVICE_DESCRIPTOR KsDeviceDescriptor = {
&KsDeviceDispatch,
0,
NULL,
0x100, //KSDEVICE_DESCRIPTOR_VERSION,
0
};
NTSTATUS
NTAPI
USBAudioCancelCompleteSynch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
/* signal event */
KeSetEvent(Context, 0, FALSE);
/* done */
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
SubmitUrbSync(
IN PKSDEVICE Device,
IN PURB Urb)
{
PIRP Irp;
KEVENT Event;
PDEVICE_EXTENSION DeviceExtension;
IO_STATUS_BLOCK IoStatus;
PIO_STACK_LOCATION IoStack;
NTSTATUS Status;
// init event
KeInitializeEvent(&Event, NotificationEvent, FALSE);
// get device extension
DeviceExtension = (PDEVICE_EXTENSION)Device->Context;
// build irp
Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB,
DeviceExtension->LowerDevice,
NULL,
0,
NULL,
0,
TRUE,
&Event,
&IoStatus);
if (!Irp)
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES;
}
// get next stack location
IoStack = IoGetNextIrpStackLocation(Irp);
// store urb
IoStack->Parameters.Others.Argument1 = Urb;
// set completion routine
IoSetCompletionRoutine(Irp, USBAudioCancelCompleteSynch, &Event, TRUE, TRUE, TRUE);
// call driver
Status = IoCallDriver(DeviceExtension->LowerDevice, Irp);
// wait for the request to finish
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
}
// complete request
IoCompleteRequest(Irp, IO_NO_INCREMENT);
if (Status == STATUS_PENDING)
{
// get final status
Status = IoStatus.Status;
}
// done
return Status;
}
NTSTATUS
NTAPI
USBAudioSelectConfiguration(
IN PKSDEVICE Device,
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
{
PDEVICE_EXTENSION DeviceExtension;
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
PUSBD_INTERFACE_LIST_ENTRY InterfaceList;
PURB Urb;
NTSTATUS Status;
ULONG InterfaceDescriptorCount;
/* alloc item for configuration request */
InterfaceList = AllocFunction(sizeof(USBD_INTERFACE_LIST_ENTRY) * (ConfigurationDescriptor->bNumInterfaces + 1));
if (!InterfaceList)
{
/* insufficient resources*/
return USBD_STATUS_INSUFFICIENT_RESOURCES;
}
/* grab interface descriptor */
InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
if (!InterfaceDescriptor)
{
/* no such interface */
return STATUS_INVALID_PARAMETER;
}
/* lets enumerate the interfaces */
InterfaceDescriptorCount = 0;
while (InterfaceDescriptor != NULL)
{
if (InterfaceDescriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL*/
{
InterfaceList[InterfaceDescriptorCount++].InterfaceDescriptor = InterfaceDescriptor;
}
else if (InterfaceDescriptor->bInterfaceSubClass == 0x03) /* MIDI_STREAMING*/
{
InterfaceList[InterfaceDescriptorCount++].InterfaceDescriptor = InterfaceDescriptor;
}
InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
}
/* build urb */
Urb = USBD_CreateConfigurationRequestEx(ConfigurationDescriptor, InterfaceList);
if (!Urb)
{
/* no memory */
FreeFunction(InterfaceList);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* submit configuration urb */
Status = SubmitUrbSync(Device, Urb);
if (!NT_SUCCESS(Status))
{
/* free resources */
ExFreePool(Urb);
FreeFunction(InterfaceList);
return Status;
}
/* store configuration handle */
DeviceExtension = Device->Context;
DeviceExtension->ConfigurationHandle = Urb->UrbSelectConfiguration.ConfigurationHandle;
/* alloc interface info */
DeviceExtension->InterfaceInfo = AllocFunction(Urb->UrbSelectConfiguration.Interface.Length);
if (DeviceExtension->InterfaceInfo)
{
/* copy interface info */
RtlCopyMemory(DeviceExtension->InterfaceInfo, &Urb->UrbSelectConfiguration.Interface, Urb->UrbSelectConfiguration.Interface.Length);
}
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
USBAudioStartDevice(
IN PKSDEVICE Device)
{
PURB Urb;
PUSB_DEVICE_DESCRIPTOR DeviceDescriptor;
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
PDEVICE_EXTENSION DeviceExtension;
NTSTATUS Status;
ULONG Length;
/* allocate urb */
Urb = AllocFunction(sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
if (!Urb)
{
/* no memory */
return STATUS_INSUFFICIENT_RESOURCES;
}
/* alloc buffer for device descriptor */
DeviceDescriptor = AllocFunction(sizeof(USB_DEVICE_DESCRIPTOR));
if (!DeviceDescriptor)
{
/* insufficient resources */
FreeFunction(Urb);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* build descriptor request */
UsbBuildGetDescriptorRequest(Urb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0, DeviceDescriptor, NULL, sizeof(USB_DEVICE_DESCRIPTOR), NULL);
/* submit urb */
Status = SubmitUrbSync(Device, Urb);
if (!NT_SUCCESS(Status))
{
/* free resources */
FreeFunction(Urb);
FreeFunction(DeviceDescriptor);
return Status;
}
/* now allocate some space for partial configuration descriptor */
ConfigurationDescriptor = AllocFunction(sizeof(USB_CONFIGURATION_DESCRIPTOR));
if (!ConfigurationDescriptor)
{
/* free resources */
FreeFunction(Urb);
FreeFunction(DeviceDescriptor);
return Status;
}
/* build descriptor request */
UsbBuildGetDescriptorRequest(Urb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0, ConfigurationDescriptor, NULL, sizeof(USB_CONFIGURATION_DESCRIPTOR), NULL);
/* submit urb */
Status = SubmitUrbSync(Device, Urb);
if (!NT_SUCCESS(Status))
{
/* free resources */
FreeFunction(Urb);
FreeFunction(DeviceDescriptor);
FreeFunction(ConfigurationDescriptor);
return Status;
}
/* backup length */
Length = ConfigurationDescriptor->wTotalLength;
/* free old descriptor */
FreeFunction(ConfigurationDescriptor);
/* now allocate some space for full configuration descriptor */
ConfigurationDescriptor = AllocFunction(Length);
if (!ConfigurationDescriptor)
{
/* free resources */
FreeFunction(Urb);
FreeFunction(DeviceDescriptor);
return Status;
}
/* build descriptor request */
UsbBuildGetDescriptorRequest(Urb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0, ConfigurationDescriptor, NULL, Length, NULL);
/* submit urb */
Status = SubmitUrbSync(Device, Urb);
/* free urb */
FreeFunction(Urb);
if (!NT_SUCCESS(Status))
{
/* free resources */
FreeFunction(DeviceDescriptor);
FreeFunction(ConfigurationDescriptor);
return Status;
}
/* lets add to object bag */
KsAddItemToObjectBag(Device->Bag, DeviceDescriptor, ExFreePool);
KsAddItemToObjectBag(Device->Bag, ConfigurationDescriptor, ExFreePool);
Status = USBAudioSelectConfiguration(Device, ConfigurationDescriptor);
if (NT_SUCCESS(Status))
{
DeviceExtension = Device->Context;
DeviceExtension->ConfigurationDescriptor = ConfigurationDescriptor;
DeviceExtension->DeviceDescriptor = DeviceDescriptor;
}
return Status;
}
NTSTATUS
NTAPI
USBAudioAddDevice(
_In_ PKSDEVICE Device)
{
/* no op */
DPRINT1("USBAudioAddDevice\n");
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
USBAudioPnPStart(
_In_ PKSDEVICE Device,
_In_ PIRP Irp,
_In_opt_ PCM_RESOURCE_LIST TranslatedResourceList,
_In_opt_ PCM_RESOURCE_LIST UntranslatedResourceList)
{
NTSTATUS Status = STATUS_SUCCESS;
PDEVICE_EXTENSION DeviceExtension;
if (!Device->Started)
{
/* alloc context */
DeviceExtension = AllocFunction(sizeof(DEVICE_EXTENSION));
if (DeviceExtension == NULL)
{
/* insufficient resources */
return STATUS_INSUFFICIENT_RESOURCES;
}
/* init context */
Device->Context = DeviceExtension;
DeviceExtension->LowerDevice = Device->NextDeviceObject;
/* add to object bag*/
KsAddItemToObjectBag(Device->Bag, Device->Context, ExFreePool);
/* init device*/
Status = USBAudioStartDevice(Device);
if (NT_SUCCESS(Status))
{
/* TODO build filter topology and pin descriptors and retrieve interface */
UNIMPLEMENTED
}
}
return Status;
}
NTSTATUS
NTAPI
USBAudioPnPQueryStop(
_In_ PKSDEVICE Device,
_In_ PIRP Irp)
{
/* no op */
return STATUS_SUCCESS;
}
VOID
NTAPI
USBAudioPnPCancelStop(
_In_ PKSDEVICE Device,
_In_ PIRP Irp)
{
/* no op */
}
VOID
NTAPI
USBAudioPnPStop(
_In_ PKSDEVICE Device,
_In_ PIRP Irp)
{
/* TODO: stop device */
UNIMPLEMENTED
}
NTSTATUS
NTAPI
USBAudioPnPQueryRemove(
_In_ PKSDEVICE Device,
_In_ PIRP Irp)
{
/* no op */
return STATUS_SUCCESS;
}
VOID
NTAPI
USBAudioPnPCancelRemove(
_In_ PKSDEVICE Device,
_In_ PIRP Irp)
{
/* no op */
}
VOID
NTAPI
USBAudioPnPRemove(
_In_ PKSDEVICE Device,
_In_ PIRP Irp)
{
/* TODO: stop device */
UNIMPLEMENTED
}
NTSTATUS
NTAPI
USBAudioPnPQueryCapabilities(
_In_ PKSDEVICE Device,
_In_ PIRP Irp,
_Inout_ PDEVICE_CAPABILITIES Capabilities)
{
/* TODO: set caps */
UNIMPLEMENTED
return STATUS_SUCCESS;
}
VOID
NTAPI
USBAudioPnPSurpriseRemoval(
_In_ PKSDEVICE Device,
_In_ PIRP Irp)
{
/* TODO: stop streams */
UNIMPLEMENTED
}
NTSTATUS
NTAPI
USBAudioPnPQueryPower(
_In_ PKSDEVICE Device,
_In_ PIRP Irp,
_In_ DEVICE_POWER_STATE DeviceTo,
_In_ DEVICE_POWER_STATE DeviceFrom,
_In_ SYSTEM_POWER_STATE SystemTo,
_In_ SYSTEM_POWER_STATE SystemFrom,
_In_ POWER_ACTION Action)
{
/* no op */
return STATUS_SUCCESS;
}
VOID
NTAPI
USBAudioPnPSetPower(
_In_ PKSDEVICE Device,
_In_ PIRP Irp,
_In_ DEVICE_POWER_STATE To,
_In_ DEVICE_POWER_STATE From)
{
/* TODO: stop streams */
UNIMPLEMENTED
}
NTSTATUS
NTAPI
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
NTSTATUS Status;
// initialize driver
Status = KsInitializeDriver(DriverObject, RegistryPath, &KsDeviceDescriptor);
if (!NT_SUCCESS(Status))
{
// failed to initialize driver
DPRINT1("Failed to initialize driver with %x\n", Status);
return Status;
}
return Status;
}

View file

@ -0,0 +1,129 @@
#pragma once
#include <ntddk.h>
#include <portcls.h>
#include <ksmedia.h>
#include <hubbusif.h>
#include <usbbusif.h>
#include <usbioctl.h>
#include <usb.h>
#include <usbdlib.h>
#include <debug.h>
#define USBAUDIO_TAG 'AbsU'
typedef struct __DEVICE_EXTENSION__
{
PDEVICE_OBJECT LowerDevice; /* lower device*/
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; /* usb configuration descriptor */
PUSB_DEVICE_DESCRIPTOR DeviceDescriptor; /* usb device descriptor */
PUSBD_INTERFACE_INFORMATION InterfaceInfo; /* interface information */
USBD_CONFIGURATION_HANDLE ConfigurationHandle; /* configuration handle */
}DEVICE_EXTENSION, *PDEVICE_EXTENSION;
/* pool.c */
PVOID
NTAPI
AllocFunction(
IN ULONG ItemSize);
VOID
NTAPI
FreeFunction(
IN PVOID Item);
/* usbaudio.c */
NTSTATUS
NTAPI
USBAudioAddDevice(
_In_ PKSDEVICE Device
);
NTSTATUS
NTAPI
USBAudioPnPStart(
_In_ PKSDEVICE Device,
_In_ PIRP Irp,
_In_opt_ PCM_RESOURCE_LIST TranslatedResourceList,
_In_opt_ PCM_RESOURCE_LIST UntranslatedResourceList
);
NTSTATUS
NTAPI
USBAudioPnPQueryStop(
_In_ PKSDEVICE Device,
_In_ PIRP Irp
);
VOID
NTAPI
USBAudioPnPCancelStop(
_In_ PKSDEVICE Device,
_In_ PIRP Irp
);
VOID
NTAPI
USBAudioPnPStop(
_In_ PKSDEVICE Device,
_In_ PIRP Irp
);
NTSTATUS
NTAPI
USBAudioPnPQueryRemove(
_In_ PKSDEVICE Device,
_In_ PIRP Irp
);
VOID
NTAPI
USBAudioPnPCancelRemove(
_In_ PKSDEVICE Device,
_In_ PIRP Irp
);
VOID
NTAPI
USBAudioPnPRemove(
_In_ PKSDEVICE Device,
_In_ PIRP Irp
);
NTSTATUS
NTAPI
USBAudioPnPQueryCapabilities(
_In_ PKSDEVICE Device,
_In_ PIRP Irp,
_Inout_ PDEVICE_CAPABILITIES Capabilities
);
VOID
NTAPI
USBAudioPnPSurpriseRemoval(
_In_ PKSDEVICE Device,
_In_ PIRP Irp
);
NTSTATUS
NTAPI
USBAudioPnPQueryPower(
_In_ PKSDEVICE Device,
_In_ PIRP Irp,
_In_ DEVICE_POWER_STATE DeviceTo,
_In_ DEVICE_POWER_STATE DeviceFrom,
_In_ SYSTEM_POWER_STATE SystemTo,
_In_ SYSTEM_POWER_STATE SystemFrom,
_In_ POWER_ACTION Action
);
VOID
NTAPI
USBAudioPnPSetPower(
_In_ PKSDEVICE Device,
_In_ PIRP Irp,
_In_ DEVICE_POWER_STATE To,
_In_ DEVICE_POWER_STATE From
);

View file

@ -0,0 +1,5 @@
#define REACTOS_VERSION_DLL
#define REACTOS_STR_FILE_DESCRIPTION "USBAUDIO Driver API\0"
#define REACTOS_STR_INTERNAL_NAME "usbaudio\0"
#define REACTOS_STR_ORIGINAL_FILENAME "usbaudio.sys\0"
#include <reactos/version.rc>