mirror of
https://github.com/reactos/reactos.git
synced 2024-11-23 11:33: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">
|
||||
<xi:include href="wdmaud/wdmaud.rbuild" />
|
||||
</directory>
|
||||
<directory name="stream">
|
||||
<xi:include href="stream/stream.rbuild" />
|
||||
</directory>
|
||||
|
||||
</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