mirror of
https://github.com/reactos/reactos.git
synced 2024-11-23 19:43:31 +08:00
- Start implementing the stream class driver
- Implemented StreamClassRegisterAdapter, StreamClassReenumerateStreams, StreamClassDebugAssert, StreamClassDebugPrint, StreamClassGetDmaBuffer - Drivers using stream class driver should now be able to initialize svn path=/trunk/; revision=41662
This commit is contained in:
parent
593091354a
commit
4a0debf9c8
@ -4,4 +4,8 @@
|
|||||||
<directory name="wdmaud">
|
<directory name="wdmaud">
|
||||||
<xi:include href="wdmaud/wdmaud.rbuild" />
|
<xi:include href="wdmaud/wdmaud.rbuild" />
|
||||||
</directory>
|
</directory>
|
||||||
|
<directory name="stream">
|
||||||
|
<xi:include href="stream/stream.rbuild" />
|
||||||
|
</directory>
|
||||||
|
|
||||||
</group>
|
</group>
|
||||||
|
71
reactos/drivers/wdm/audio/legacy/stream/control.c
Normal file
71
reactos/drivers/wdm/audio/legacy/stream/control.c
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Kernel Streaming
|
||||||
|
* FILE: drivers/wdm/audio/legacy/stream/dll.c
|
||||||
|
* PURPOSE: kernel mode driver initialization
|
||||||
|
* PROGRAMMER: Johannes Anderwald
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "stream.h"
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
StreamClassPower(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
StreamClassSystemControl(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
StreamClassCleanup(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
StreamClassFlushBuffers(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
StreamClassDeviceControl(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
30
reactos/drivers/wdm/audio/legacy/stream/dll.c
Normal file
30
reactos/drivers/wdm/audio/legacy/stream/dll.c
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Kernel Streaming
|
||||||
|
* FILE: drivers/wdm/audio/legacy/stream/dll.c
|
||||||
|
* PURPOSE: kernel mode driver initialization
|
||||||
|
* PROGRAMMER: Johannes Anderwald
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "stream.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
DllInitialize(ULONG Unknown)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
DllUnload(VOID)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
299
reactos/drivers/wdm/audio/legacy/stream/driver.c
Normal file
299
reactos/drivers/wdm/audio/legacy/stream/driver.c
Normal file
@ -0,0 +1,299 @@
|
|||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Kernel Streaming
|
||||||
|
* FILE: drivers/wdm/audio/legacy/stream/driver.c
|
||||||
|
* PURPOSE: WDM Codec Class Driver
|
||||||
|
* PROGRAMMER: Johannes Anderwald
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stream.h"
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
StreamClassAddDevice(
|
||||||
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
IN PDEVICE_OBJECT PhysicalDeviceObject)
|
||||||
|
{
|
||||||
|
PSTREAM_CLASS_DRIVER_EXTENSION DriverObjectExtension;
|
||||||
|
PDEVICE_OBJECT DeviceObject, LowerDeviceObject;
|
||||||
|
PSTREAM_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
PKSOBJECT_CREATE_ITEM ItemList;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Fetch driver object extension */
|
||||||
|
DriverObjectExtension = IoGetDriverObjectExtension(DriverObject, (PVOID)StreamClassAddDevice);
|
||||||
|
if (!DriverObjectExtension)
|
||||||
|
{
|
||||||
|
/* Failed to get driver extension */
|
||||||
|
return STATUS_DEVICE_DOES_NOT_EXIST;
|
||||||
|
}
|
||||||
|
/* Allocate Create Item */
|
||||||
|
ItemList = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
|
||||||
|
if (!ItemList)
|
||||||
|
{
|
||||||
|
/* Failed to allocated Create Item */
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the FDO */
|
||||||
|
Status = IoCreateDevice(DriverObject, DriverObjectExtension->Data.DeviceExtensionSize + sizeof(STREAM_DEVICE_EXTENSION), NULL, FILE_DEVICE_KS, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, 0, &DeviceObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Failed to create the FDO */
|
||||||
|
ExFreePool(ItemList);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attach to device stack */
|
||||||
|
LowerDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
|
||||||
|
if (!LowerDeviceObject)
|
||||||
|
{
|
||||||
|
/* Failed to attach */
|
||||||
|
IoDeleteDevice(DeviceObject);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zero Create item */
|
||||||
|
RtlZeroMemory(ItemList, sizeof(KSOBJECT_CREATE_ITEM));
|
||||||
|
/* Setup object class */
|
||||||
|
RtlInitUnicodeString(&ItemList->ObjectClass, L"STREAMCLASS");
|
||||||
|
/* Setup CreateDispatch routine */
|
||||||
|
ItemList->Create = StreamClassCreateFilter;
|
||||||
|
|
||||||
|
/* Get device extension */
|
||||||
|
DeviceExtension = (PSTREAM_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
/* Zero device extension */
|
||||||
|
RtlZeroMemory(DeviceExtension, sizeof(STREAM_DEVICE_EXTENSION));
|
||||||
|
/* Initialize Ks streaming */
|
||||||
|
Status = KsAllocateDeviceHeader(&DeviceExtension->Header, 1, ItemList);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Cleanup resources */
|
||||||
|
IoDetachDevice(LowerDeviceObject);
|
||||||
|
IoDeleteDevice(DeviceObject);
|
||||||
|
ExFreePool(ItemList);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store lower device object */
|
||||||
|
DeviceExtension->LowerDeviceObject = LowerDeviceObject;
|
||||||
|
|
||||||
|
/* Store physical device object */
|
||||||
|
DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
|
||||||
|
/* Store driver object extension */
|
||||||
|
DeviceExtension->DriverExtension = DriverObjectExtension;
|
||||||
|
/* Initialize memory list */
|
||||||
|
InitializeListHead(&DeviceExtension->MemoryResourceList);
|
||||||
|
/* Setup device extension */
|
||||||
|
DeviceExtension->DeviceExtension = (PVOID) (DeviceExtension + 1);
|
||||||
|
/* Init interrupt dpc */
|
||||||
|
KeInitializeDpc(&DeviceExtension->InterruptDpc, StreamClassInterruptDpc, (PVOID)DeviceExtension);
|
||||||
|
|
||||||
|
/* Set device transfer method */
|
||||||
|
DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
|
||||||
|
/* Clear init flag */
|
||||||
|
DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*@implemented
|
||||||
|
*/
|
||||||
|
NTSTATUS
|
||||||
|
STREAMAPI
|
||||||
|
StreamClassRegisterAdapter(
|
||||||
|
IN PVOID Argument1,
|
||||||
|
IN PVOID Argument2,
|
||||||
|
IN PHW_INITIALIZATION_DATA HwInitializationData)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PSTREAM_CLASS_DRIVER_EXTENSION DriverObjectExtension;
|
||||||
|
PDRIVER_OBJECT DriverObject = (PDRIVER_OBJECT)Argument1;
|
||||||
|
|
||||||
|
/* Allocate driver extension */
|
||||||
|
Status = IoAllocateDriverObjectExtension(DriverObject, (PVOID)StreamClassAddDevice, sizeof(STREAM_CLASS_DRIVER_EXTENSION), (PVOID*)&DriverObjectExtension);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Failed to allocate */
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zero driver object extension */
|
||||||
|
RtlZeroMemory(DriverObjectExtension, sizeof(STREAM_CLASS_DRIVER_EXTENSION));
|
||||||
|
|
||||||
|
/* copy HwInitializationData */
|
||||||
|
RtlCopyMemory(&DriverObjectExtension->Data, HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
|
||||||
|
|
||||||
|
/* Setup device init methods */
|
||||||
|
DriverObject->DriverExtension->AddDevice = StreamClassAddDevice;
|
||||||
|
DriverObject->DriverUnload = KsNullDriverUnload;
|
||||||
|
|
||||||
|
/* Setup irp handlers */
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_PNP] = StreamClassPnp;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_POWER] = StreamClassPower;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = StreamClassSystemControl;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = StreamClassCleanup;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = StreamClassFlushBuffers;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = StreamClassDeviceControl;
|
||||||
|
|
||||||
|
/* Let Ks handle these */
|
||||||
|
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CREATE);
|
||||||
|
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CLOSE);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*@implemented
|
||||||
|
*/
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
StreamClassReenumerateStreams(
|
||||||
|
IN PVOID HwDeviceExtension,
|
||||||
|
IN ULONG StreamDescriptorSize)
|
||||||
|
{
|
||||||
|
HW_STREAM_REQUEST_BLOCK_EXT RequestBlock;
|
||||||
|
PSTREAM_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
PHW_STREAM_DESCRIPTOR StreamDescriptor;
|
||||||
|
|
||||||
|
if (!HwDeviceExtension || !StreamDescriptorSize)
|
||||||
|
return;
|
||||||
|
|
||||||
|
StreamDescriptor = ExAllocatePool(NonPagedPool, StreamDescriptorSize);
|
||||||
|
if (!StreamDescriptor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Zero stream descriptor */
|
||||||
|
RtlZeroMemory(StreamDescriptor, StreamDescriptorSize);
|
||||||
|
|
||||||
|
/* Get our DeviceExtension */
|
||||||
|
DeviceExtension = (PSTREAM_DEVICE_EXTENSION) ((ULONG_PTR)HwDeviceExtension - sizeof(STREAM_DEVICE_EXTENSION));
|
||||||
|
ASSERT(DeviceExtension->DeviceExtension == HwDeviceExtension);
|
||||||
|
|
||||||
|
|
||||||
|
/* Zero RequestBlock */
|
||||||
|
RtlZeroMemory(&RequestBlock, sizeof(HW_STREAM_REQUEST_BLOCK_EXT));
|
||||||
|
|
||||||
|
/* Setup get stream info struct */
|
||||||
|
RequestBlock.Block.SizeOfThisPacket = sizeof(HW_STREAM_REQUEST_BLOCK);
|
||||||
|
RequestBlock.Block.Command = SRB_GET_STREAM_INFO;
|
||||||
|
RequestBlock.Block.CommandData.StreamBuffer = StreamDescriptor;
|
||||||
|
KeInitializeEvent(&RequestBlock.Event, SynchronizationEvent, FALSE);
|
||||||
|
|
||||||
|
/* FIXME SYNCHRONIZATION */
|
||||||
|
|
||||||
|
/* Send the request */
|
||||||
|
DeviceExtension->DriverExtension->Data.HwReceivePacket ((PHW_STREAM_REQUEST_BLOCK)&RequestBlock);
|
||||||
|
|
||||||
|
/* Is the device already completed? */
|
||||||
|
if (RequestBlock.Block.Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
/* Request is pending, wait for result */
|
||||||
|
KeWaitForSingleObject(&RequestBlock.Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(RequestBlock.Block.Status))
|
||||||
|
{
|
||||||
|
/* Release Stream descriptor */
|
||||||
|
ExFreePool(StreamDescriptor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (DeviceExtension->StreamDescriptor)
|
||||||
|
{
|
||||||
|
/* Release old stream descriptor */
|
||||||
|
ExFreePool(DeviceExtension->StreamDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store stream descriptor */
|
||||||
|
DeviceExtension->StreamDescriptor = StreamDescriptor;
|
||||||
|
DeviceExtension->StreamDescriptorSize = StreamDescriptorSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*@implemented
|
||||||
|
*/
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
StreamClassDebugAssert(
|
||||||
|
IN PCHAR File,
|
||||||
|
IN ULONG Line,
|
||||||
|
IN PCHAR AssertText,
|
||||||
|
IN ULONG AssertValue)
|
||||||
|
{
|
||||||
|
#ifdef DBG
|
||||||
|
DbgBreakPoint();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*@implemented
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
__cdecl
|
||||||
|
StreamClassDebugPrint(
|
||||||
|
IN STREAM_DEBUG_LEVEL DebugPrintLevel,
|
||||||
|
IN PCCHAR DebugMessage,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
#ifdef DBG
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
if (DebugPrintLevel <=STREAMDEBUG_LEVEL)
|
||||||
|
{
|
||||||
|
va_start(ap, DebugMessage);
|
||||||
|
|
||||||
|
DbgPrint(DebugMessage, ap);
|
||||||
|
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*@unimplemented
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
__cdecl
|
||||||
|
StreamClassDeviceNotification(
|
||||||
|
IN STREAM_MINIDRIVER_DEVICE_NOTIFICATION_TYPE NotificationType,
|
||||||
|
IN PVOID HwDeviceExtension,
|
||||||
|
IN PHW_STREAM_REQUEST_BLOCK pSrb,
|
||||||
|
IN PKSEVENT_ENTRY EventEntry,
|
||||||
|
IN GUID *EventSet,
|
||||||
|
IN ULONG EventId)
|
||||||
|
{
|
||||||
|
PHW_STREAM_REQUEST_BLOCK_EXT RequestBlock;
|
||||||
|
if (NotificationType == DeviceRequestComplete)
|
||||||
|
{
|
||||||
|
RequestBlock = (PHW_STREAM_REQUEST_BLOCK_EXT)pSrb;
|
||||||
|
|
||||||
|
KeSetEvent(&RequestBlock->Event, 0, FALSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNIMPLEMENTED
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*@implemented
|
||||||
|
*/
|
||||||
|
PVOID
|
||||||
|
STREAMAPI
|
||||||
|
StreamClassGetDmaBuffer(
|
||||||
|
IN PVOID HwDeviceExtension)
|
||||||
|
{
|
||||||
|
PSTREAM_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
/* Get our DeviceExtension */
|
||||||
|
DeviceExtension = (PSTREAM_DEVICE_EXTENSION) ((ULONG_PTR)HwDeviceExtension - sizeof(STREAM_DEVICE_EXTENSION));
|
||||||
|
ASSERT(DeviceExtension->DeviceExtension == HwDeviceExtension);
|
||||||
|
|
||||||
|
return DeviceExtension->DmaCommonBuffer;
|
||||||
|
}
|
||||||
|
|
194
reactos/drivers/wdm/audio/legacy/stream/filter.c
Normal file
194
reactos/drivers/wdm/audio/legacy/stream/filter.c
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Kernel Streaming
|
||||||
|
* FILE: drivers/wdm/audio/legacy/stream/filter.c
|
||||||
|
* PURPOSE: filter instance handling
|
||||||
|
* PROGRAMMER: Johannes Anderwald
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "stream.h"
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
FilterDispatch_fnDeviceIoControl(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
DPRINT1("FilterDispatch Called\n");
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
FilterDispatch_fnClose(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PSTREAM_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
HW_STREAM_REQUEST_BLOCK_EXT RequestBlock;
|
||||||
|
|
||||||
|
/* Get device extension */
|
||||||
|
DeviceExtension = (PSTREAM_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
if (!DeviceExtension->DriverExtension->Data.FilterInstanceExtensionSize)
|
||||||
|
{
|
||||||
|
/* driver supports only one instance */
|
||||||
|
if (DeviceExtension->InstanceCount)
|
||||||
|
{
|
||||||
|
/* there is already one instance open */
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* driver supports more than one filter instance */
|
||||||
|
RtlZeroMemory(&RequestBlock, sizeof(HW_STREAM_REQUEST_BLOCK_EXT));
|
||||||
|
|
||||||
|
/* set up request block */
|
||||||
|
RequestBlock.Block.Command = SRB_CLOSE_DEVICE_INSTANCE;
|
||||||
|
RequestBlock.Block.HwDeviceExtension = DeviceExtension->DeviceExtension;
|
||||||
|
RequestBlock.Block.Irp = Irp;
|
||||||
|
KeInitializeEvent(&RequestBlock.Event, SynchronizationEvent, FALSE);
|
||||||
|
|
||||||
|
/*FIXME SYNCHRONIZATION */
|
||||||
|
|
||||||
|
/* Send the request */
|
||||||
|
DeviceExtension->DriverExtension->Data.HwReceivePacket((PHW_STREAM_REQUEST_BLOCK)&RequestBlock);
|
||||||
|
if (RequestBlock.Block.Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
/* Wait for the request */
|
||||||
|
KeWaitForSingleObject(&RequestBlock.Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment total instance count */
|
||||||
|
InterlockedDecrement(&DeviceExtension->InstanceCount);
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static KSDISPATCH_TABLE DispatchTable =
|
||||||
|
{
|
||||||
|
FilterDispatch_fnDeviceIoControl,
|
||||||
|
KsDispatchInvalidDeviceRequest,
|
||||||
|
KsDispatchInvalidDeviceRequest,
|
||||||
|
KsDispatchInvalidDeviceRequest,
|
||||||
|
FilterDispatch_fnClose,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
InitializeFilterWithKs(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PSTREAM_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
KSOBJECT_HEADER ObjectHeader;
|
||||||
|
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
HW_STREAM_REQUEST_BLOCK_EXT RequestBlock;
|
||||||
|
|
||||||
|
/* Get device extension */
|
||||||
|
DeviceExtension = (PSTREAM_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
if (!DeviceExtension->DriverExtension->Data.FilterInstanceExtensionSize)
|
||||||
|
{
|
||||||
|
/* driver supports only one instance */
|
||||||
|
if (DeviceExtension->InstanceCount)
|
||||||
|
{
|
||||||
|
/* there is already one instance open */
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* driver supports more than one filter instance */
|
||||||
|
RtlZeroMemory(&RequestBlock, sizeof(HW_STREAM_REQUEST_BLOCK_EXT));
|
||||||
|
|
||||||
|
/* set up request block */
|
||||||
|
RequestBlock.Block.Command = SRB_OPEN_DEVICE_INSTANCE;
|
||||||
|
RequestBlock.Block.HwDeviceExtension = DeviceExtension->DeviceExtension;
|
||||||
|
RequestBlock.Block.Irp = Irp;
|
||||||
|
KeInitializeEvent(&RequestBlock.Event, SynchronizationEvent, FALSE);
|
||||||
|
|
||||||
|
/*FIXME SYNCHRONIZATION */
|
||||||
|
|
||||||
|
/* Send the request */
|
||||||
|
DeviceExtension->DriverExtension->Data.HwReceivePacket((PHW_STREAM_REQUEST_BLOCK)&RequestBlock);
|
||||||
|
if (RequestBlock.Block.Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
/* Wait for the request */
|
||||||
|
KeWaitForSingleObject(&RequestBlock.Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
}
|
||||||
|
/* Check for success */
|
||||||
|
if (!NT_SUCCESS(RequestBlock.Block.Status))
|
||||||
|
{
|
||||||
|
/* Resource is not available */
|
||||||
|
return RequestBlock.Block.Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate create item */
|
||||||
|
CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
|
||||||
|
if (!CreateItem)
|
||||||
|
{
|
||||||
|
/* not enough memory */
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
/* Zero create item */
|
||||||
|
RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
|
||||||
|
/* Set item class */
|
||||||
|
RtlInitUnicodeString(&CreateItem->ObjectClass, L"STREAMCLASS");
|
||||||
|
/* Get current irp stack location */
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
/* Create Ks streaming object header */
|
||||||
|
Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Failed to create header */
|
||||||
|
ExFreePool(CreateItem);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
/* Increment total instance count */
|
||||||
|
InterlockedIncrement(&DeviceExtension->InstanceCount);
|
||||||
|
/* Return result */
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
StreamClassCreateFilter(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
DPRINT1("StreamClassCreateFilter Called\n");
|
||||||
|
|
||||||
|
/* FIXME Support Pins/Clocks */
|
||||||
|
/* Init filter */
|
||||||
|
Status = InitializeFilterWithKs(DeviceObject, Irp);
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
56
reactos/drivers/wdm/audio/legacy/stream/helper.c
Normal file
56
reactos/drivers/wdm/audio/legacy/stream/helper.c
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Kernel Streaming
|
||||||
|
* FILE: drivers/wdm/audio/legacy/stream/helper.c
|
||||||
|
* PURPOSE: irp helper routines
|
||||||
|
* PROGRAMMER: Johannes Anderwald
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "stream.h"
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
CompletionRoutine(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PVOID Context)
|
||||||
|
{
|
||||||
|
if (Irp->PendingReturned == TRUE)
|
||||||
|
{
|
||||||
|
KeSetEvent ((PKEVENT) Context, IO_NO_INCREMENT, FALSE);
|
||||||
|
}
|
||||||
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ForwardIrpSynchronous(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
KEVENT Event;
|
||||||
|
PSTREAM_DEVICE_EXTENSION DeviceExt;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
DeviceExt = (PSTREAM_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
/* initialize the notification event */
|
||||||
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
|
IoCopyCurrentIrpStackLocationToNext(Irp);
|
||||||
|
|
||||||
|
IoSetCompletionRoutine(Irp, CompletionRoutine, (PVOID)&Event, TRUE, TRUE, TRUE);
|
||||||
|
|
||||||
|
/* now call the driver */
|
||||||
|
Status = IoCallDriver(DeviceExt->LowerDeviceObject, Irp);
|
||||||
|
/* did the request complete yet */
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
/* not yet, lets wait a bit */
|
||||||
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
Status = Irp->IoStatus.Status;
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
|
}
|
465
reactos/drivers/wdm/audio/legacy/stream/pnp.c
Normal file
465
reactos/drivers/wdm/audio/legacy/stream/pnp.c
Normal file
@ -0,0 +1,465 @@
|
|||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Kernel Streaming
|
||||||
|
* FILE: drivers/wdm/audio/legacy/stream/pnp.c
|
||||||
|
* PURPOSE: pnp handling
|
||||||
|
* PROGRAMMER: Johannes Anderwald
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stream.h"
|
||||||
|
|
||||||
|
VOID
|
||||||
|
CompleteIrp(
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN NTSTATUS Status,
|
||||||
|
IN ULONG_PTR Information)
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
Irp->IoStatus.Information = Information;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
StreamClassReleaseResources(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
PSTREAM_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
PLIST_ENTRY Entry;
|
||||||
|
PMEMORY_RESOURCE_LIST Mem;
|
||||||
|
|
||||||
|
/* Get device extension */
|
||||||
|
DeviceExtension = (PSTREAM_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
/* Disconnect interrupt */
|
||||||
|
if (DeviceExtension->Interrupt)
|
||||||
|
{
|
||||||
|
IoDisconnectInterrupt(DeviceExtension->Interrupt);
|
||||||
|
DeviceExtension->Interrupt = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release DmaAdapter */
|
||||||
|
if (DeviceExtension->DmaAdapter)
|
||||||
|
{
|
||||||
|
DeviceExtension->DmaAdapter->DmaOperations->PutDmaAdapter(DeviceExtension->DmaAdapter);
|
||||||
|
DeviceExtension->DmaAdapter = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release mem mapped I/O */
|
||||||
|
while(!IsListEmpty(&DeviceExtension->MemoryResourceList))
|
||||||
|
{
|
||||||
|
Entry = RemoveHeadList(&DeviceExtension->MemoryResourceList);
|
||||||
|
Mem = (PMEMORY_RESOURCE_LIST)CONTAINING_RECORD(Entry, MEMORY_RESOURCE_LIST, Entry);
|
||||||
|
|
||||||
|
MmUnmapIoSpace(Mem->Start, Mem->Length);
|
||||||
|
ExFreePool(Entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
StreamClassSynchronize(
|
||||||
|
IN PKINTERRUPT Interrupt,
|
||||||
|
IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine,
|
||||||
|
IN PVOID SynchronizeContext)
|
||||||
|
{
|
||||||
|
/* This function is used when the driver either implements synchronization on its own
|
||||||
|
* or if there is no interrupt assigned
|
||||||
|
*/
|
||||||
|
return SynchronizeRoutine(SynchronizeContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
StreamClassInterruptDpc(
|
||||||
|
IN PKDPC Dpc,
|
||||||
|
IN PVOID DeferredContext,
|
||||||
|
IN PVOID SystemArgument1,
|
||||||
|
IN PVOID SystemArgument2)
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
//read/write data
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
StreamClassInterruptRoutine(
|
||||||
|
IN PKINTERRUPT Interrupt,
|
||||||
|
IN PVOID ServiceContext)
|
||||||
|
{
|
||||||
|
BOOLEAN Ret = FALSE;
|
||||||
|
PSTREAM_DEVICE_EXTENSION DeviceExtension = (PSTREAM_DEVICE_EXTENSION)ServiceContext;
|
||||||
|
|
||||||
|
/* Does the driver implement HwInterrupt routine */
|
||||||
|
if (DeviceExtension->DriverExtension->Data.HwInterrupt)
|
||||||
|
{
|
||||||
|
/* Check if the interrupt was coming from this device */
|
||||||
|
Ret = DeviceExtension->DriverExtension->Data.HwInterrupt(DeviceExtension->DeviceExtension);
|
||||||
|
if (Ret)
|
||||||
|
{
|
||||||
|
/* Interrupt has from this device, schedule a Dpc for us */
|
||||||
|
KeInsertQueueDpc(&DeviceExtension->InterruptDpc, NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Return result */
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
StreamClassStartDevice(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
PHW_STREAM_REQUEST_BLOCK_EXT RequestBlock;
|
||||||
|
PPORT_CONFIGURATION_INFORMATION Config;
|
||||||
|
PSTREAM_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
PCM_RESOURCE_LIST List;
|
||||||
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
|
||||||
|
PSTREAM_CLASS_DRIVER_EXTENSION DriverObjectExtension;
|
||||||
|
PDMA_ADAPTER Adapter;
|
||||||
|
DEVICE_DESCRIPTION DeviceDesc;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
ULONG ResultLength, Index;
|
||||||
|
BOOLEAN bUseDMA, bUseInterrupt;
|
||||||
|
ULONG MapRegisters;
|
||||||
|
KAFFINITY Affinity = 0;
|
||||||
|
PHW_STREAM_DESCRIPTOR StreamDescriptor;
|
||||||
|
PACCESS_RANGE Range;
|
||||||
|
PVOID MappedAddr;
|
||||||
|
PMEMORY_RESOURCE_LIST Mem;
|
||||||
|
|
||||||
|
/* Get current stack location */
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
/* Get resource list */
|
||||||
|
List = IoStack->Parameters.StartDevice.AllocatedResourcesTranslated;
|
||||||
|
/* Calculate request length */
|
||||||
|
ResultLength = sizeof(HW_STREAM_REQUEST_BLOCK_EXT) + sizeof(PPORT_CONFIGURATION_INFORMATION) + List->List[0].PartialResourceList.Count * sizeof(ACCESS_RANGE);
|
||||||
|
|
||||||
|
/* Allocate Request Block */
|
||||||
|
RequestBlock = ExAllocatePool(NonPagedPool, ResultLength);
|
||||||
|
|
||||||
|
if (!RequestBlock)
|
||||||
|
{
|
||||||
|
/* Not enough memory */
|
||||||
|
CompleteIrp(Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get device extension */
|
||||||
|
DeviceExtension = (PSTREAM_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
/* Get driver object extension */
|
||||||
|
DriverObjectExtension = IoGetDriverObjectExtension(DeviceObject->DriverObject, (PVOID)StreamClassAddDevice);
|
||||||
|
|
||||||
|
/* Zero request block */
|
||||||
|
RtlZeroMemory(RequestBlock, ResultLength);
|
||||||
|
|
||||||
|
/* Locate Config struct */
|
||||||
|
Config = (PPORT_CONFIGURATION_INFORMATION) (RequestBlock + 1);
|
||||||
|
Range = (PACCESS_RANGE) (Config + 1);
|
||||||
|
|
||||||
|
/* Initialize Request */
|
||||||
|
RequestBlock->Block.SizeOfThisPacket = sizeof(HW_STREAM_REQUEST_BLOCK);
|
||||||
|
RequestBlock->Block.Command = SRB_INITIALIZE_DEVICE;
|
||||||
|
RequestBlock->Block.CommandData.ConfigInfo = Config;
|
||||||
|
KeInitializeEvent(&RequestBlock->Event, SynchronizationEvent, FALSE);
|
||||||
|
|
||||||
|
Config->SizeOfThisPacket = sizeof(PPORT_CONFIGURATION_INFORMATION);
|
||||||
|
Config->HwDeviceExtension = (PVOID) (DeviceExtension + 1);
|
||||||
|
Config->ClassDeviceObject = DeviceObject;
|
||||||
|
Config->PhysicalDeviceObject = DeviceExtension->LowerDeviceObject;
|
||||||
|
Config->RealPhysicalDeviceObject = DeviceExtension->PhysicalDeviceObject;
|
||||||
|
Config->AccessRanges = Range;
|
||||||
|
|
||||||
|
IoGetDeviceProperty(DeviceObject, DevicePropertyBusNumber, sizeof(ULONG), (PVOID)&Config->SystemIoBusNumber, &ResultLength);
|
||||||
|
IoGetDeviceProperty(DeviceObject, DevicePropertyLegacyBusType, sizeof(INTERFACE_TYPE), (PVOID)&Config->AdapterInterfaceType, &ResultLength);
|
||||||
|
|
||||||
|
/* Get resource list */
|
||||||
|
List = IoStack->Parameters.StartDevice.AllocatedResourcesTranslated;
|
||||||
|
|
||||||
|
/* Scan the translated resources */
|
||||||
|
bUseDMA = FALSE;
|
||||||
|
bUseInterrupt = FALSE;
|
||||||
|
|
||||||
|
Range = (PACCESS_RANGE) (Config + 1);
|
||||||
|
|
||||||
|
for(Index = 0; Index < List->List[0].PartialResourceList.Count; Index++)
|
||||||
|
{
|
||||||
|
/* Locate partial descriptor */
|
||||||
|
Descriptor = &List->List[0].PartialResourceList.PartialDescriptors[Index];
|
||||||
|
|
||||||
|
switch(Descriptor->Type)
|
||||||
|
{
|
||||||
|
case CmResourceTypePort:
|
||||||
|
{
|
||||||
|
/* Store resource information in AccessRange struct */
|
||||||
|
Range[Config->NumberOfAccessRanges].RangeLength = Descriptor->u.Port.Length;
|
||||||
|
Range[Config->NumberOfAccessRanges].RangeStart.QuadPart = Descriptor->u.Port.Start.QuadPart;
|
||||||
|
Range[Config->NumberOfAccessRanges].RangeInMemory = FALSE;
|
||||||
|
Config->NumberOfAccessRanges++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CmResourceTypeInterrupt:
|
||||||
|
{
|
||||||
|
/* Store resource information */
|
||||||
|
Config->BusInterruptLevel = Descriptor->u.Interrupt.Level;
|
||||||
|
Config->BusInterruptVector = Descriptor->u.Interrupt.Vector;
|
||||||
|
Config->InterruptMode = Descriptor->Flags;
|
||||||
|
Affinity = Descriptor->u.Interrupt.Affinity;
|
||||||
|
bUseInterrupt = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CmResourceTypeMemory:
|
||||||
|
{
|
||||||
|
Mem = ExAllocatePool(NonPagedPool, sizeof(MEMORY_RESOURCE_LIST));
|
||||||
|
MappedAddr = MmMapIoSpace(Descriptor->u.Memory.Start, Descriptor->u.Memory.Length, MmNonCached);
|
||||||
|
if (!MappedAddr || !Mem)
|
||||||
|
{
|
||||||
|
if (Mem)
|
||||||
|
{
|
||||||
|
/* Release Memory resource descriptor */
|
||||||
|
ExFreePool(Mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MappedAddr)
|
||||||
|
{
|
||||||
|
/* Release mem mapped I/O */
|
||||||
|
MmUnmapIoSpace(MappedAddr, Descriptor->u.Memory.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release resources */
|
||||||
|
StreamClassReleaseResources(DeviceObject);
|
||||||
|
/* Complete irp */
|
||||||
|
CompleteIrp(Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
|
||||||
|
ExFreePool(RequestBlock);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
/* Store range for driver */
|
||||||
|
Range[Config->NumberOfAccessRanges].RangeLength = Descriptor->u.Memory.Length;
|
||||||
|
Range[Config->NumberOfAccessRanges].RangeStart.QuadPart = Descriptor->u.Memory.Start.QuadPart;
|
||||||
|
Range[Config->NumberOfAccessRanges].RangeInMemory = TRUE;
|
||||||
|
Config->NumberOfAccessRanges++;
|
||||||
|
/* Initialize Memory resource descriptor */
|
||||||
|
Mem->Length = Descriptor->u.Memory.Length;
|
||||||
|
Mem->Start = MappedAddr;
|
||||||
|
InsertTailList(&DeviceExtension->MemoryResourceList, &Mem->Entry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CmResourceTypeDma:
|
||||||
|
{
|
||||||
|
bUseDMA = TRUE;
|
||||||
|
Config->DmaChannel = Descriptor->u.Dma.Channel;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!!bUseInterrupt || DriverObjectExtension->Data.HwInterrupt == NULL || Config->BusInterruptLevel == 0 || Config->BusInterruptVector == 0)
|
||||||
|
{
|
||||||
|
/* requirements not satisfied */
|
||||||
|
DeviceExtension->SynchronizeFunction = StreamClassSynchronize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* use real sync routine */
|
||||||
|
DeviceExtension->SynchronizeFunction = KeSynchronizeExecution;
|
||||||
|
|
||||||
|
/* connect interrupt */
|
||||||
|
Status = IoConnectInterrupt(&DeviceExtension->Interrupt,
|
||||||
|
StreamClassInterruptRoutine,
|
||||||
|
(PVOID)DeviceExtension,
|
||||||
|
NULL,
|
||||||
|
Config->BusInterruptVector,
|
||||||
|
Config->BusInterruptLevel,
|
||||||
|
Config->BusInterruptLevel,
|
||||||
|
Config->InterruptMode,
|
||||||
|
TRUE,
|
||||||
|
Affinity,
|
||||||
|
FALSE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Release resources */
|
||||||
|
StreamClassReleaseResources(DeviceObject);
|
||||||
|
/* Failed to connect interrupt */
|
||||||
|
CompleteIrp(Irp, Status, 0);
|
||||||
|
/* Release request block */
|
||||||
|
ExFreePool(RequestBlock);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* store interrupt object */
|
||||||
|
Config->InterruptObject = DeviceExtension->Interrupt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* does the device use DMA */
|
||||||
|
if (bUseDMA && DriverObjectExtension->Data.BusMasterDMA)
|
||||||
|
{
|
||||||
|
/* Zero device description */
|
||||||
|
RtlZeroMemory(&DeviceDesc, sizeof(DEVICE_DESCRIPTION));
|
||||||
|
|
||||||
|
DeviceDesc.Version = DEVICE_DESCRIPTION_VERSION;
|
||||||
|
DeviceDesc.Master = TRUE;
|
||||||
|
DeviceDesc.ScatterGather = TRUE;
|
||||||
|
DeviceDesc.AutoInitialize = FALSE;
|
||||||
|
DeviceDesc.DmaChannel = Config->DmaChannel;
|
||||||
|
DeviceDesc.InterfaceType = Config->AdapterInterfaceType;
|
||||||
|
DeviceDesc.DmaWidth = Width32Bits;
|
||||||
|
DeviceDesc.DmaSpeed = Compatible;
|
||||||
|
DeviceDesc.MaximumLength = (ULONG)-1;
|
||||||
|
DeviceDesc.Dma32BitAddresses = DriverObjectExtension->Data.Dma24BitAddresses;
|
||||||
|
|
||||||
|
Adapter = IoGetDmaAdapter(DeviceExtension->PhysicalDeviceObject, &DeviceDesc, &MapRegisters);
|
||||||
|
if (!Adapter)
|
||||||
|
{
|
||||||
|
/* Failed to claim DMA Adapter */
|
||||||
|
CompleteIrp(Irp, Status, 0);
|
||||||
|
/* Release resources */
|
||||||
|
StreamClassReleaseResources(DeviceObject);
|
||||||
|
/* Release request block */
|
||||||
|
ExFreePool(RequestBlock);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DeviceExtension->DriverExtension->Data.DmaBufferSize)
|
||||||
|
{
|
||||||
|
DeviceExtension->DmaCommonBuffer = Adapter->DmaOperations->AllocateCommonBuffer(Adapter, DeviceExtension->DriverExtension->Data.DmaBufferSize, &DeviceExtension->DmaPhysicalAddress, FALSE);
|
||||||
|
if (!DeviceExtension->DmaCommonBuffer)
|
||||||
|
{
|
||||||
|
/* Failed to allocate a common buffer */
|
||||||
|
CompleteIrp(Irp, Status, 0);
|
||||||
|
/* Release resources */
|
||||||
|
StreamClassReleaseResources(DeviceObject);
|
||||||
|
/* Release request block */
|
||||||
|
ExFreePool(RequestBlock);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DeviceExtension->MapRegisters = MapRegisters;
|
||||||
|
DeviceExtension->DmaAdapter = Adapter;
|
||||||
|
Config->DmaAdapterObject = (PADAPTER_OBJECT)Adapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* First forward the request to lower attached device object */
|
||||||
|
Status = ForwardIrpSynchronous(DeviceObject, Irp);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Failed to start lower devices */
|
||||||
|
CompleteIrp(Irp, Status, 0);
|
||||||
|
/* Release resources */
|
||||||
|
StreamClassReleaseResources(DeviceObject);
|
||||||
|
/* Release request block */
|
||||||
|
ExFreePool(RequestBlock);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Config->Irp = Irp;
|
||||||
|
|
||||||
|
/* FIXME SYNCHRONIZATION */
|
||||||
|
|
||||||
|
/* Send the request */
|
||||||
|
DriverObjectExtension->Data.HwReceivePacket((PHW_STREAM_REQUEST_BLOCK)RequestBlock);
|
||||||
|
if (RequestBlock->Block.Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
/* Request is pending, wait for result */
|
||||||
|
KeWaitForSingleObject(&RequestBlock->Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
/* Get final status code */
|
||||||
|
Status = RequestBlock->Block.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy stream descriptor size */
|
||||||
|
DeviceExtension->StreamDescriptorSize = Config->StreamDescriptorSize;
|
||||||
|
|
||||||
|
/* check if the request has succeeded or if stream size is valid*/
|
||||||
|
if (!NT_SUCCESS(Status)|| !Config->StreamDescriptorSize)
|
||||||
|
{
|
||||||
|
/* Failed to start device */
|
||||||
|
CompleteIrp(Irp, Status, 0);
|
||||||
|
/* Release resources */
|
||||||
|
StreamClassReleaseResources(DeviceObject);
|
||||||
|
/* Release request block */
|
||||||
|
ExFreePool(RequestBlock);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate a stream Descriptor */
|
||||||
|
StreamDescriptor = ExAllocatePool(NonPagedPool, DeviceExtension->StreamDescriptorSize);
|
||||||
|
if (!StreamDescriptor)
|
||||||
|
{
|
||||||
|
/* Not enough memory */
|
||||||
|
CompleteIrp(Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
|
||||||
|
/* Release resources */
|
||||||
|
StreamClassReleaseResources(DeviceObject);
|
||||||
|
/* Release request block */
|
||||||
|
ExFreePool(RequestBlock);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zero stream descriptor */
|
||||||
|
RtlZeroMemory(StreamDescriptor, DeviceExtension->StreamDescriptorSize);
|
||||||
|
|
||||||
|
/* Setup get stream info struct */
|
||||||
|
RequestBlock->Block.Command = SRB_GET_STREAM_INFO;
|
||||||
|
RequestBlock->Block.CommandData.StreamBuffer = StreamDescriptor;
|
||||||
|
KeResetEvent(&RequestBlock->Event);
|
||||||
|
|
||||||
|
/* send the request */
|
||||||
|
DriverObjectExtension->Data.HwReceivePacket((PHW_STREAM_REQUEST_BLOCK)RequestBlock);
|
||||||
|
if (RequestBlock->Block.Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
/* Request is pending, wait for result */
|
||||||
|
KeWaitForSingleObject(&RequestBlock->Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
/* Get final status code */
|
||||||
|
Status = RequestBlock->Block.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* store stream descriptor */
|
||||||
|
DeviceExtension->StreamDescriptor = StreamDescriptor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* cleanup resources */
|
||||||
|
ExFreePool(StreamDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExFreePool(RequestBlock);
|
||||||
|
/* Complete Irp */
|
||||||
|
CompleteIrp(Irp, Status, 0);
|
||||||
|
/* Return result */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
StreamClassPnp(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
|
||||||
|
/* Get current irp stack location */
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
switch (IoStack->MinorFunction)
|
||||||
|
{
|
||||||
|
case IRP_MN_START_DEVICE:
|
||||||
|
{
|
||||||
|
return StreamClassStartDevice(DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return STATUS_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
140
reactos/drivers/wdm/audio/legacy/stream/stream.h
Normal file
140
reactos/drivers/wdm/audio/legacy/stream/stream.h
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
#ifndef STREAM_H__
|
||||||
|
#define STREAM_H__
|
||||||
|
|
||||||
|
#include <strmini.h>
|
||||||
|
#define YDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#define STREAMDEBUG_LEVEL DebugLevelMaximum
|
||||||
|
|
||||||
|
typedef BOOLEAN (NTAPI *SYNCHRONIZE_FUNC) (IN PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
HW_INITIALIZATION_DATA Data;
|
||||||
|
|
||||||
|
}STREAM_CLASS_DRIVER_EXTENSION, *PSTREAM_CLASS_DRIVER_EXTENSION;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
LIST_ENTRY Entry;
|
||||||
|
PVOID Start;
|
||||||
|
ULONG Length;
|
||||||
|
}MEMORY_RESOURCE_LIST, *PMEMORY_RESOURCE_LIST;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
KSDEVICE_HEADER Header;
|
||||||
|
PDEVICE_OBJECT LowerDeviceObject;
|
||||||
|
PDEVICE_OBJECT PhysicalDeviceObject;
|
||||||
|
|
||||||
|
SYNCHRONIZE_FUNC SynchronizeFunction;
|
||||||
|
|
||||||
|
ULONG MapRegisters;
|
||||||
|
PDMA_ADAPTER DmaAdapter;
|
||||||
|
PVOID DmaCommonBuffer;
|
||||||
|
PHYSICAL_ADDRESS DmaPhysicalAddress;
|
||||||
|
|
||||||
|
PKINTERRUPT Interrupt;
|
||||||
|
KDPC InterruptDpc;
|
||||||
|
|
||||||
|
LIST_ENTRY MemoryResourceList;
|
||||||
|
|
||||||
|
ULONG StreamDescriptorSize;
|
||||||
|
PHW_STREAM_DESCRIPTOR StreamDescriptor;
|
||||||
|
PSTREAM_CLASS_DRIVER_EXTENSION DriverExtension;
|
||||||
|
|
||||||
|
PVOID DeviceExtension;
|
||||||
|
LONG InstanceCount;
|
||||||
|
|
||||||
|
}STREAM_DEVICE_EXTENSION, *PSTREAM_DEVICE_EXTENSION;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
HW_STREAM_REQUEST_BLOCK Block;
|
||||||
|
KEVENT Event;
|
||||||
|
}HW_STREAM_REQUEST_BLOCK_EXT, *PHW_STREAM_REQUEST_BLOCK_EXT;
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
StreamClassCreateFilter(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
StreamClassPnp(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
StreamClassPower(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
StreamClassSystemControl(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
StreamClassCleanup(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
StreamClassFlushBuffers(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
StreamClassDeviceControl(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
StreamClassAddDevice(
|
||||||
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
IN PDEVICE_OBJECT PhysicalDeviceObject);
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ForwardIrpSynchronous(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
StreamClassSynchronize(
|
||||||
|
IN PKINTERRUPT Interrupt,
|
||||||
|
IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine,
|
||||||
|
IN PVOID SynchronizeContext);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
StreamClassInterruptRoutine(
|
||||||
|
IN PKINTERRUPT Interrupt,
|
||||||
|
IN PVOID ServiceContext);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
StreamClassInterruptDpc(
|
||||||
|
IN PKDPC Dpc,
|
||||||
|
IN PVOID DeferredContext,
|
||||||
|
IN PVOID SystemArgument1,
|
||||||
|
IN PVOID SystemArgument2);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
CompleteIrp(
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN NTSTATUS Status,
|
||||||
|
IN ULONG_PTR Information);
|
||||||
|
|
||||||
|
#endif
|
17
reactos/drivers/wdm/audio/legacy/stream/stream.rbuild
Normal file
17
reactos/drivers/wdm/audio/legacy/stream/stream.rbuild
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE module SYSTEM "../../../../../tools/rbuild/project.dtd">
|
||||||
|
<module name="stream" type="kernelmodedriver" installbase="system32/drivers" installname="stream.sys" entrypoint="0">
|
||||||
|
<include base="stream">.</include>
|
||||||
|
<define name="_COMDDK_" />
|
||||||
|
<importlibrary definition="stream.spec" />
|
||||||
|
<library>ntoskrnl</library>
|
||||||
|
<library>ks</library>
|
||||||
|
<library>pseh</library>
|
||||||
|
<file>control.c</file>
|
||||||
|
<file>driver.c</file>
|
||||||
|
<file>dll.c</file>
|
||||||
|
<file>filter.c</file>
|
||||||
|
<file>helper.c</file>
|
||||||
|
<file>pnp.c</file>
|
||||||
|
<file>stream.rc</file>
|
||||||
|
</module>
|
5
reactos/drivers/wdm/audio/legacy/stream/stream.rc
Normal file
5
reactos/drivers/wdm/audio/legacy/stream/stream.rc
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#define REACTOS_VERSION_DLL
|
||||||
|
#define REACTOS_STR_FILE_DESCRIPTION "WDM CODEC Class Device Driver 2.0\0"
|
||||||
|
#define REACTOS_STR_INTERNAL_NAME "stream.sys\0"
|
||||||
|
#define REACTOS_STR_ORIGINAL_FILENAME "stream.sys\0"
|
||||||
|
#include <reactos/version.rc>
|
8
reactos/drivers/wdm/audio/legacy/stream/stream.spec
Normal file
8
reactos/drivers/wdm/audio/legacy/stream/stream.spec
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
@ stdcall DllInitialize(long)
|
||||||
|
@ stdcall DllUnload()
|
||||||
|
@ stdcall StreamClassRegisterAdapter(ptr ptr ptr)
|
||||||
|
@ stdcall StreamClassReenumerateStreams(ptr long)
|
||||||
|
@ stdcall StreamClassDebugAssert(long long ptr long)
|
||||||
|
@ cdecl StreamClassDebugPrint (long str)
|
||||||
|
@ cdecl StreamClassDeviceNotification(long ptr)
|
||||||
|
@ stdcall StreamClassGetDmaBuffer(ptr)
|
Loading…
Reference in New Issue
Block a user