mirror of
https://github.com/reactos/reactos.git
synced 2025-04-25 08:00:24 +00:00
- Silence a few debug prints
- Add a tag for each queued irp which will be used by the future IPortPinWavePci object - Add support for basic support for capture devices - Implement IPortWavePciStream object svn path=/trunk/; revision=40015
This commit is contained in:
parent
d74173888a
commit
4a74095169
9 changed files with 446 additions and 32 deletions
|
@ -150,9 +150,7 @@ IPortFilterWaveCyclic_fnDeviceIoControl(
|
|||
ISubdevice *SubDevice = NULL;
|
||||
SUBDEVICE_DESCRIPTOR * Descriptor;
|
||||
NTSTATUS Status;
|
||||
#if defined(DBG)
|
||||
IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl *)iface;
|
||||
#endif
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY);
|
||||
|
|
|
@ -24,6 +24,7 @@ const GUID IID_IDrmPort = {0x286D3DF8L, 0xCA22, 0x4E2E, {0xB9, 0xBC, 0x20, 0xB4,
|
|||
const GUID IID_IDrmPort2 = {0x1ACCE59CL, 0x7311, 0x4B6B, {0x9F, 0xBA, 0xCC, 0x3B, 0xA5, 0x9A, 0xCD, 0xCE}};
|
||||
const GUID IID_IInterruptSync = {0x22C6AC63L, 0x851B, 0x11D0, {0x9A, 0x7F, 0x00, 0xAA, 0x00, 0x38, 0xAC, 0xFE}};
|
||||
const GUID IID_IPortWavePci = {0xb4c90a50L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
|
||||
const GUID IID_IPortWavePciStream = {0xb4c90a51L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
|
||||
const GUID IID_IPortMidi = {0xb4c90a40L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
|
||||
const GUID IID_IMiniportMidi = {0xb4c90a41L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
|
||||
const GUID IID_IMiniportWavePci = {0xb4c90a52L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
|
||||
|
|
|
@ -194,7 +194,8 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown)
|
|||
STDMETHOD_(NTSTATUS, Init)(THIS_
|
||||
IN KSPIN_CONNECT *ConnectDetails,
|
||||
IN PKSDATAFORMAT DataFormat,
|
||||
IN PDEVICE_OBJECT DeviceObject);
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN ULONG FrameSize);
|
||||
|
||||
STDMETHOD_(NTSTATUS, AddMapping)(THIS_
|
||||
IN PUCHAR Buffer,
|
||||
|
@ -219,11 +220,19 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown)
|
|||
STDMETHOD_(VOID, UpdateFormat)(THIS_
|
||||
IN PKSDATAFORMAT DataFormat);
|
||||
|
||||
STDMETHOD_(NTSTATUS, GetMappingWithTag)(THIS_
|
||||
IN PVOID Tag,
|
||||
OUT PPHYSICAL_ADDRESS PhysicalAddress,
|
||||
OUT PVOID *VirtualAddress,
|
||||
OUT PULONG ByteCount,
|
||||
OUT PULONG Flags);
|
||||
|
||||
STDMETHOD_(VOID, ReleaseMappingWithTag)(THIS_
|
||||
IN PVOID Tag);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* IKsWorkSink
|
||||
*****************************************************************************
|
||||
|
|
|
@ -106,7 +106,7 @@ IInterruptSynchronizedRoutine(
|
|||
IN PVOID ServiceContext)
|
||||
{
|
||||
IInterruptSyncImpl * This = (IInterruptSyncImpl*)ServiceContext;
|
||||
DPRINT1("IInterruptSynchronizedRoutine This %p SyncRoutine %p Context %p\n", This, This->SyncRoutine, This->DynamicContext);
|
||||
//DPRINT1("IInterruptSynchronizedRoutine This %p SyncRoutine %p Context %p\n", This, This->SyncRoutine, This->DynamicContext);
|
||||
return This->SyncRoutine((IInterruptSync*)&This->lpVtbl, This->DynamicContext);
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ IInterruptSync_fnCallSynchronizedRoutine(
|
|||
KIRQL OldIrql;
|
||||
IInterruptSyncImpl * This = (IInterruptSyncImpl*)iface;
|
||||
|
||||
DPRINT1("IInterruptSync_fnCallSynchronizedRoutine This %p Routine %p DynamicContext %p Irql %x Interrupt %p\n", This, Routine, DynamicContext, KeGetCurrentIrql(), This->Interrupt);
|
||||
//DPRINT1("IInterruptSync_fnCallSynchronizedRoutine This %p Routine %p DynamicContext %p Irql %x Interrupt %p\n", This, Routine, DynamicContext, KeGetCurrentIrql(), This->Interrupt);
|
||||
|
||||
if (!This->Interrupt)
|
||||
{
|
||||
|
@ -169,7 +169,7 @@ IInterruptServiceRoutine(
|
|||
BOOL Success;
|
||||
IInterruptSyncImpl * This = (IInterruptSyncImpl*)ServiceContext;
|
||||
|
||||
DPRINT("IInterruptServiceRoutine\n");
|
||||
DPRINT("IInterruptServiceRoutine Mode %u\n", This->Mode);
|
||||
|
||||
if (This->Mode == InterruptSyncModeNormal)
|
||||
{
|
||||
|
@ -249,7 +249,7 @@ IInterruptSync_fnConnect(
|
|||
Descriptor->u.Interrupt.Vector,
|
||||
Descriptor->u.Interrupt.Level,
|
||||
Descriptor->u.Interrupt.Level, //FIXME
|
||||
LevelSensitive, //FIXME
|
||||
Descriptor->Flags,
|
||||
TRUE,
|
||||
Descriptor->u.Interrupt.Affinity,
|
||||
FALSE);
|
||||
|
|
|
@ -18,6 +18,10 @@ typedef struct _IRP_MAPPING_
|
|||
PIRP Irp;
|
||||
KDPC Dpc;
|
||||
|
||||
ULONG NumTags;
|
||||
PVOID * Tag;
|
||||
LONG ReferenceCount;
|
||||
|
||||
}IRP_MAPPING, *PIRP_MAPPING;
|
||||
|
||||
typedef struct
|
||||
|
@ -38,6 +42,10 @@ typedef struct
|
|||
KSPIN_LOCK Lock;
|
||||
LIST_ENTRY ListHead;
|
||||
|
||||
PVOID LastTag;
|
||||
BOOL OutOfMapping;
|
||||
ULONG MaxFrameSize;
|
||||
|
||||
}IIrpQueueImpl;
|
||||
|
||||
VOID
|
||||
|
@ -119,12 +127,16 @@ IIrpQueue_fnInit(
|
|||
IN IIrpQueue *iface,
|
||||
IN KSPIN_CONNECT *ConnectDetails,
|
||||
IN PKSDATAFORMAT DataFormat,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN ULONG FrameSize)
|
||||
{
|
||||
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
|
||||
|
||||
This->ConnectDetails = ConnectDetails;
|
||||
This->DataFormat = (PKSDATAFORMAT_WAVEFORMATEX)DataFormat;
|
||||
This->MaxFrameSize = FrameSize;
|
||||
This->LastTag = (PVOID)0x12345678;
|
||||
|
||||
InitializeListHead(&This->ListHead);
|
||||
KeInitializeSpinLock(&This->Lock);
|
||||
|
||||
|
@ -142,7 +154,8 @@ IIrpQueue_fnAddMapping(
|
|||
PIRP_MAPPING Mapping;
|
||||
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
|
||||
|
||||
Mapping = ExAllocatePool(NonPagedPool, sizeof(IRP_MAPPING));
|
||||
|
||||
Mapping = AllocateItem(NonPagedPool, sizeof(IRP_MAPPING), TAG_PORTCLASS);
|
||||
if (!Mapping)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
||||
|
@ -150,9 +163,15 @@ IIrpQueue_fnAddMapping(
|
|||
Mapping->Irp = Irp;
|
||||
KeInitializeDpc(&Mapping->Dpc, DpcRoutine, (PVOID)Mapping);
|
||||
|
||||
if (This->MaxFrameSize)
|
||||
{
|
||||
Mapping->NumTags = max((Mapping->Header->DataUsed / This->MaxFrameSize) + 1, 1);
|
||||
Mapping->Tag = AllocateItem(NonPagedPool, sizeof(PVOID) * This->NumMappings, TAG_PORTCLASS);
|
||||
}
|
||||
|
||||
This->NumDataAvailable += Mapping->Header->DataUsed;
|
||||
|
||||
DPRINT1("IIrpQueue_fnAddMapping NumMappings %u SizeOfMapping %lu NumDataAvailable %lu Irp %p\n", This->NumMappings, Mapping->Header->DataUsed, This->NumDataAvailable, Irp);
|
||||
DPRINT("IIrpQueue_fnAddMapping NumMappings %u SizeOfMapping %lu NumDataAvailable %lu Irp %p\n", This->NumMappings, Mapping->Header->DataUsed, This->NumDataAvailable, Irp);
|
||||
|
||||
/* FIXME use InterlockedCompareExchangePointer */
|
||||
if (InterlockedCompareExchange((volatile long *)&This->FirstMap, (LONG)Mapping, (LONG)0) != 0)
|
||||
|
@ -160,6 +179,8 @@ IIrpQueue_fnAddMapping(
|
|||
|
||||
(void)InterlockedIncrement((volatile long*)&This->NumMappings);
|
||||
|
||||
|
||||
|
||||
if (Irp)
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_PENDING;
|
||||
|
@ -200,6 +221,7 @@ IIrpQueue_fnUpdateMapping(
|
|||
PIRP_MAPPING Mapping;
|
||||
|
||||
This->CurrentOffset += BytesWritten;
|
||||
This->NumDataAvailable -= BytesWritten;
|
||||
|
||||
if (This->FirstMap->Header->DataUsed <=This->CurrentOffset)
|
||||
{
|
||||
|
@ -207,11 +229,9 @@ IIrpQueue_fnUpdateMapping(
|
|||
Mapping = (PIRP_MAPPING)ExInterlockedRemoveHeadList(&This->ListHead, &This->Lock);
|
||||
|
||||
InterlockedDecrement(&This->NumMappings);
|
||||
This->NumDataAvailable -= This->FirstMap->Header->DataUsed;
|
||||
|
||||
KeInsertQueueDpc(&This->FirstMap->Dpc, (PVOID)This->FirstMap, NULL);
|
||||
(void)InterlockedExchangePointer((PVOID volatile*)&This->FirstMap, (PVOID)Mapping);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -270,6 +290,137 @@ IIrpQueue_fnUpdateFormat(
|
|||
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IIrpQueue_fnGetMappingWithTag(
|
||||
IN IIrpQueue *iface,
|
||||
IN PVOID Tag,
|
||||
OUT PPHYSICAL_ADDRESS PhysicalAddress,
|
||||
OUT PVOID *VirtualAddress,
|
||||
OUT PULONG ByteCount,
|
||||
OUT PULONG Flags)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
PIRP_MAPPING CurMapping;
|
||||
PIRP_MAPPING Result;
|
||||
PLIST_ENTRY CurEntry;
|
||||
ULONG Index;
|
||||
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
|
||||
|
||||
*Flags = 0;
|
||||
Result = NULL;
|
||||
|
||||
KeAcquireSpinLock(&This->Lock, &OldIrql);
|
||||
|
||||
CurEntry = This->ListHead.Flink;
|
||||
|
||||
while (CurEntry != &This->ListHead)
|
||||
{
|
||||
CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry);
|
||||
for(Index = 0; Index < CurMapping->NumTags; Index++)
|
||||
{
|
||||
if (This->LastTag == (PVOID)0x12345678)
|
||||
{
|
||||
CurMapping->Tag[Index] = Tag;
|
||||
CurMapping->ReferenceCount++;
|
||||
Result = CurMapping;
|
||||
if (Index + 1 == CurMapping->NumTags - 1)
|
||||
{
|
||||
/* indicate end of packet */
|
||||
*Flags = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (CurMapping->Tag[Index] == This->LastTag)
|
||||
{
|
||||
if (Index + 1 < CurMapping->NumTags)
|
||||
{
|
||||
CurMapping->Tag[Index+1] = Tag;
|
||||
CurMapping->ReferenceCount++;
|
||||
Result = CurMapping;
|
||||
|
||||
if (Index + 1 == CurMapping->NumTags - 1)
|
||||
{
|
||||
/* indicate end of packet */
|
||||
*Flags = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
CurEntry = CurEntry->Flink;
|
||||
if (&This->ListHead == CurEntry)
|
||||
{
|
||||
This->OutOfMapping = TRUE;
|
||||
break;
|
||||
}
|
||||
Result = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry);
|
||||
Result->Tag[0] = Tag;
|
||||
Result->ReferenceCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CurEntry = CurEntry->Flink;
|
||||
}
|
||||
|
||||
KeReleaseSpinLock(&This->Lock, OldIrql);
|
||||
if (!Result)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
||||
Result->Tag = Tag;
|
||||
*PhysicalAddress = MmGetPhysicalAddress(Result->Header->Data);
|
||||
*VirtualAddress = Result->Header->Data;
|
||||
*ByteCount = Result->Header->DataUsed;
|
||||
This->LastTag = Tag;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
IIrpQueue_fnReleaseMappingWithTag(
|
||||
IN IIrpQueue *iface,
|
||||
IN PVOID Tag)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
PIRP_MAPPING CurMapping;
|
||||
PLIST_ENTRY CurEntry;
|
||||
ULONG Index;
|
||||
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
|
||||
|
||||
KeAcquireSpinLock(&This->Lock, &OldIrql);
|
||||
CurEntry = This->ListHead.Flink;
|
||||
|
||||
while (CurEntry != &This->ListHead)
|
||||
{
|
||||
CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry);
|
||||
for(Index = 0; Index < CurMapping->NumTags; Index++)
|
||||
{
|
||||
if (CurMapping->Tag[Index] == Tag)
|
||||
{
|
||||
CurMapping->ReferenceCount--;
|
||||
if (!CurMapping->ReferenceCount)
|
||||
{
|
||||
RemoveEntryList(&CurMapping->Entry);
|
||||
if (CurMapping->Irp)
|
||||
{
|
||||
CurMapping->Irp->IoStatus.Information = CurMapping->Header->FrameExtent;
|
||||
CurMapping->Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(CurMapping->Irp, IO_SOUND_INCREMENT);
|
||||
}
|
||||
ExFreePool(CurMapping->Header->Data);
|
||||
ExFreePool(CurMapping->Header);
|
||||
ExFreePool(CurMapping->Tag);
|
||||
ExFreePool(CurMapping);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
CurEntry = CurEntry->Flink;
|
||||
}
|
||||
|
||||
KeReleaseSpinLock(&This->Lock, OldIrql);
|
||||
}
|
||||
|
||||
static IIrpQueueVtbl vt_IIrpQueue =
|
||||
{
|
||||
|
@ -284,7 +435,9 @@ static IIrpQueueVtbl vt_IIrpQueue =
|
|||
IIrpQueue_fnMinMappings,
|
||||
IIrpQueue_fnMinimumDataAvailable,
|
||||
IIrpQueue_fnCancelBuffers,
|
||||
IIrpQueue_fnUpdateFormat
|
||||
IIrpQueue_fnUpdateFormat,
|
||||
IIrpQueue_fnGetMappingWithTag,
|
||||
IIrpQueue_fnReleaseMappingWithTag
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ typedef struct
|
|||
ULONG ActiveIrpOffset;
|
||||
ULONG DelayedRequestInProgress;
|
||||
ULONG FrameSize;
|
||||
BOOL Capture;
|
||||
|
||||
}IPortPinWaveCyclicImpl;
|
||||
|
||||
|
@ -113,10 +114,22 @@ UpdateCommonBuffer(
|
|||
return;
|
||||
|
||||
BytesToCopy = min(BufferLength, BufferSize);
|
||||
This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
|
||||
(PUCHAR)This->CommonBuffer + This->CommonBufferOffset,
|
||||
Buffer,
|
||||
BytesToCopy);
|
||||
|
||||
|
||||
if (This->Capture)
|
||||
{
|
||||
This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
|
||||
Buffer,
|
||||
(PUCHAR)This->CommonBuffer + This->CommonBufferOffset,
|
||||
BytesToCopy);
|
||||
}
|
||||
else
|
||||
{
|
||||
This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
|
||||
(PUCHAR)This->CommonBuffer + This->CommonBufferOffset,
|
||||
Buffer,
|
||||
BytesToCopy);
|
||||
}
|
||||
|
||||
This->IrpQueue->lpVtbl->UpdateMapping(This->IrpQueue, BytesToCopy);
|
||||
This->CommonBufferOffset += BytesToCopy;
|
||||
|
@ -145,10 +158,21 @@ UpdateCommonBufferOverlap(
|
|||
return;
|
||||
|
||||
BytesToCopy = min(BufferLength, BufferSize);
|
||||
This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
|
||||
(PUCHAR)This->CommonBuffer + This->CommonBufferOffset,
|
||||
Buffer,
|
||||
BytesToCopy);
|
||||
|
||||
if (This->Capture)
|
||||
{
|
||||
This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
|
||||
Buffer,
|
||||
(PUCHAR)This->CommonBuffer + This->CommonBufferOffset,
|
||||
BytesToCopy);
|
||||
}
|
||||
else
|
||||
{
|
||||
This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
|
||||
(PUCHAR)This->CommonBuffer + This->CommonBufferOffset,
|
||||
Buffer,
|
||||
BytesToCopy);
|
||||
}
|
||||
|
||||
This->IrpQueue->lpVtbl->UpdateMapping(This->IrpQueue, BytesToCopy);
|
||||
This->CommonBufferOffset += BytesToCopy;
|
||||
|
@ -197,7 +221,6 @@ IServiceSink_fnRequestService(
|
|||
Status = This->Stream->lpVtbl->GetPosition(This->Stream, &Position);
|
||||
DPRINT("Position %u BufferSize %u ActiveIrpOffset %u\n", Position, This->CommonBufferSize, BufferSize);
|
||||
|
||||
|
||||
if (Position < This->CommonBufferOffset)
|
||||
{
|
||||
UpdateCommonBufferOverlap(This, Position);
|
||||
|
@ -230,7 +253,6 @@ IPortPinWaveCyclic_fnQueryInterface(
|
|||
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
|
||||
|
||||
if (IsEqualGUIDAligned(refiid, &IID_IIrpTarget) ||
|
||||
//IsEqualGUIDAligned(refiid, &IID_IPortPinWaveCyclic) ||
|
||||
IsEqualGUIDAligned(refiid, &IID_IUnknown))
|
||||
{
|
||||
*Output = &This->lpVtbl;
|
||||
|
@ -702,7 +724,32 @@ IPortPinWaveCyclic_fnFastRead(
|
|||
OUT PIO_STATUS_BLOCK StatusBlock,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
NTSTATUS Status;
|
||||
PCONTEXT_WRITE Packet;
|
||||
PIRP Irp;
|
||||
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
|
||||
|
||||
DPRINT1("IPortPinWaveCyclic_fnFastRead entered\n");
|
||||
|
||||
Packet = (PCONTEXT_WRITE)Buffer;
|
||||
|
||||
Irp = Packet->Irp;
|
||||
StatusBlock->Status = STATUS_PENDING;
|
||||
|
||||
Status = This->IrpQueue->lpVtbl->AddMapping(This->IrpQueue, Buffer, Length, Irp);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
return FALSE;
|
||||
|
||||
if (This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue) == TRUE && This->State != KSSTATE_RUN)
|
||||
{
|
||||
/* some should initiate a state request but didnt do it */
|
||||
DPRINT1("Starting stream with %lu mappings Offset %u\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue), This->ActiveIrpOffset);
|
||||
|
||||
This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_RUN);
|
||||
This->State = KSSTATE_RUN;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -753,7 +800,7 @@ IPortPinWaveCyclic_fnFastWrite(
|
|||
if (This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue) == TRUE && This->State != KSSTATE_RUN)
|
||||
{
|
||||
/* some should initiate a state request but didnt do it */
|
||||
DPRINT1("Starting stream with %lu mappings\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue));
|
||||
DPRINT1("Starting stream with %lu mappings Offset %u\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue), This->ActiveIrpOffset);
|
||||
|
||||
This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_RUN);
|
||||
This->State = KSSTATE_RUN;
|
||||
|
@ -777,6 +824,8 @@ IPortPinWaveCyclic_fnInit(
|
|||
NTSTATUS Status;
|
||||
PKSDATAFORMAT DataFormat;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
BOOL Capture;
|
||||
|
||||
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
|
||||
|
||||
Port->lpVtbl->AddRef(Port);
|
||||
|
@ -804,13 +853,32 @@ IPortPinWaveCyclic_fnInit(
|
|||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
Status = This->IrpQueue->lpVtbl->Init(This->IrpQueue, ConnectDetails, DataFormat, DeviceObject);
|
||||
Status = This->IrpQueue->lpVtbl->Init(This->IrpQueue, ConnectDetails, DataFormat, DeviceObject, 0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
This->IrpQueue->lpVtbl->Release(This->IrpQueue);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN)
|
||||
{
|
||||
Capture = FALSE;
|
||||
}
|
||||
else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT)
|
||||
{
|
||||
Capture = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor->Communication, KsPinDescriptor->DataFlow);
|
||||
KeBugCheck(0);
|
||||
}
|
||||
|
||||
Status = This->Miniport->lpVtbl->NewStream(This->Miniport,
|
||||
&This->Stream,
|
||||
NULL,
|
||||
NonPagedPool,
|
||||
FALSE, //FIXME
|
||||
Capture,
|
||||
ConnectDetails->PinId,
|
||||
This->Format,
|
||||
&This->DmaChannel,
|
||||
|
@ -834,10 +902,10 @@ IPortPinWaveCyclic_fnInit(
|
|||
This->CommonBufferOffset = 0;
|
||||
This->CommonBufferSize = This->DmaChannel->lpVtbl->AllocatedBufferSize(This->DmaChannel);
|
||||
This->CommonBuffer = This->DmaChannel->lpVtbl->SystemAddress(This->DmaChannel);
|
||||
This->Capture = Capture;
|
||||
|
||||
//Status = This->Stream->lpVtbl->SetNotificationFreq(This->Stream, 10, &This->FrameSize);
|
||||
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -879,15 +947,16 @@ IPortPinWaveCyclic_fnGetDeviceBufferSize(
|
|||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
PVOID
|
||||
NTAPI
|
||||
IPortPinWaveCyclic_fnGetIrpStream(
|
||||
IN IPortPinWaveCyclic* iface)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return NULL;
|
||||
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
|
||||
|
||||
return (PVOID)This->IrpQueue;
|
||||
}
|
||||
|
||||
|
||||
|
|
167
reactos/drivers/wdm/audio/backpln/portcls/port_wavepcistream.c
Normal file
167
reactos/drivers/wdm/audio/backpln/portcls/port_wavepcistream.c
Normal file
|
@ -0,0 +1,167 @@
|
|||
#include "private.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
IPortWavePciStreamVtbl * lpVtbl;
|
||||
IIrpQueue *Queue;
|
||||
LONG ref;
|
||||
|
||||
|
||||
}IPortWavePciStreamImpl;
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IPortWavePciStream_fnQueryInterface(
|
||||
IPortWavePciStream* iface,
|
||||
IN REFIID refiid,
|
||||
OUT PVOID* Output)
|
||||
{
|
||||
IPortWavePciStreamImpl * This = (IPortWavePciStreamImpl*)iface;
|
||||
|
||||
DPRINT("IPortWavePciStream_fnQueryInterface entered\n");
|
||||
|
||||
if (IsEqualGUIDAligned(refiid, &IID_IPortWavePciStream) ||
|
||||
IsEqualGUIDAligned(refiid, &IID_IUnknown))
|
||||
{
|
||||
*Output = &This->lpVtbl;
|
||||
InterlockedIncrement(&This->ref);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
static
|
||||
ULONG
|
||||
NTAPI
|
||||
IPortWavePciStream_fnAddRef(
|
||||
IPortWavePciStream* iface)
|
||||
{
|
||||
IPortWavePciStreamImpl * This = (IPortWavePciStreamImpl*)iface;
|
||||
DPRINT("IPortWavePciStream_fnAddRef entered\n");
|
||||
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static
|
||||
ULONG
|
||||
NTAPI
|
||||
IPortWavePciStream_fnRelease(
|
||||
IPortWavePciStream* iface)
|
||||
{
|
||||
IPortWavePciStreamImpl * This = (IPortWavePciStreamImpl*)iface;
|
||||
|
||||
InterlockedDecrement(&This->ref);
|
||||
|
||||
DPRINT("IPortWavePciStream_fnRelease entered %u\n", This->ref);
|
||||
|
||||
if (This->ref == 0)
|
||||
{
|
||||
FreeItem(This, TAG_PORTCLASS);
|
||||
return 0;
|
||||
}
|
||||
/* Return new reference count */
|
||||
return This->ref;
|
||||
}
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IPortWavePciStream_fnGetMapping(
|
||||
IN IPortWavePciStream *iface,
|
||||
IN PVOID Tag,
|
||||
OUT PPHYSICAL_ADDRESS PhysicalAddress,
|
||||
OUT PVOID *VirtualAddress,
|
||||
OUT PULONG ByteCount,
|
||||
OUT PULONG Flags)
|
||||
{
|
||||
IPortWavePciStreamImpl * This = (IPortWavePciStreamImpl*)iface;
|
||||
|
||||
return This->Queue->lpVtbl->GetMappingWithTag(This->Queue, Tag, PhysicalAddress, VirtualAddress, ByteCount, Flags);
|
||||
}
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IPortWavePciStream_fnReleaseMapping(
|
||||
IN IPortWavePciStream *iface,
|
||||
IN PVOID Tag)
|
||||
{
|
||||
IPortWavePciStreamImpl * This = (IPortWavePciStreamImpl*)iface;
|
||||
This->Queue->lpVtbl->ReleaseMappingWithTag(This->Queue, Tag);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IPortWavePciStream_fnTerminatePacket(
|
||||
IN IPortWavePciStream *iface)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static IPortWavePciStreamVtbl vt_PortWavePciStream =
|
||||
{
|
||||
IPortWavePciStream_fnQueryInterface,
|
||||
IPortWavePciStream_fnAddRef,
|
||||
IPortWavePciStream_fnRelease,
|
||||
IPortWavePciStream_fnGetMapping,
|
||||
IPortWavePciStream_fnReleaseMapping,
|
||||
IPortWavePciStream_fnTerminatePacket
|
||||
};
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NewIPortWavePciStream(
|
||||
OUT PPORTWAVEPCISTREAM *Stream,
|
||||
IN KSPIN_CONNECT *ConnectDetails,
|
||||
IN PKSDATAFORMAT DataFormat,
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN ULONG FrameSize)
|
||||
{
|
||||
IIrpQueue * Queue;
|
||||
IPortWavePciStreamImpl * This;
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = NewIrpQueue(&Queue);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
Status = Queue->lpVtbl->Init(Queue, ConnectDetails, DataFormat, DeviceObject, FrameSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Queue->lpVtbl->Release(Queue);
|
||||
return Status;
|
||||
}
|
||||
|
||||
This = AllocateItem(NonPagedPool, sizeof(IPortWavePciStreamImpl), TAG_PORTCLASS);
|
||||
if (!This)
|
||||
{
|
||||
Queue->lpVtbl->Release(Queue);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
This->lpVtbl = &vt_PortWavePciStream;
|
||||
This->ref = 1;
|
||||
This->Queue = Queue;
|
||||
|
||||
*Stream = (PPORTWAVEPCISTREAM)&This->lpVtbl;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IPortWavePciStream_AddMapping(
|
||||
IN IPortWavePciStream *iface,
|
||||
IN PUCHAR Buffer,
|
||||
IN ULONG BufferSize,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
IPortWavePciStreamImpl * This = (IPortWavePciStreamImpl*)iface;
|
||||
return This->Queue->lpVtbl->AddMapping(This->Queue, Buffer, BufferSize, Irp);
|
||||
}
|
||||
|
|
@ -37,6 +37,7 @@
|
|||
<file>port_topology.c</file>
|
||||
<file>port_wavepci.c</file>
|
||||
<file>port_wavecyclic.c</file>
|
||||
<file>port_wavepcistream.c</file>
|
||||
<file>propertyhandler.c</file>
|
||||
<file>miniport.c</file>
|
||||
<file>miniport_dmus.c</file>
|
||||
|
|
|
@ -241,6 +241,22 @@ PDEVICE_OBJECT
|
|||
GetDeviceObject(
|
||||
IPortWaveCyclic* iface);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IPortWavePciStream_AddMapping(
|
||||
IN IPortWavePciStream *iface,
|
||||
IN PUCHAR Buffer,
|
||||
IN ULONG BufferSize,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NewIPortWavePciStream(
|
||||
OUT PPORTWAVEPCISTREAM *Stream,
|
||||
IN KSPIN_CONNECT *ConnectDetails,
|
||||
IN PKSDATAFORMAT DataFormat,
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN ULONG FrameSize);
|
||||
|
||||
#define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet,\
|
||||
PropGeneral, PropInstances, PropIntersection)\
|
||||
|
|
Loading…
Reference in a new issue