- Silence a few debug prints
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Sat, 14 Mar 2009 18:57:51 +0000 (18:57 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Sat, 14 Mar 2009 18:57:51 +0000 (18:57 +0000)
- 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

reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c
reactos/drivers/wdm/audio/backpln/portcls/guids.c
reactos/drivers/wdm/audio/backpln/portcls/interfaces.h
reactos/drivers/wdm/audio/backpln/portcls/interrupt.c
reactos/drivers/wdm/audio/backpln/portcls/irpstream.c
reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c
reactos/drivers/wdm/audio/backpln/portcls/port_wavepcistream.c [new file with mode: 0644]
reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild
reactos/drivers/wdm/audio/backpln/portcls/private.h

index 981ba16..a1d53dc 100644 (file)
@@ -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);
index e846ba6..61949e0 100644 (file)
@@ -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}};
index e5a3cde..ba1962d 100644 (file)
@@ -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,9 +220,17 @@ 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);
 
+};
 
 
 /*****************************************************************************
index 297f517..3d30cae 100644 (file)
@@ -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);
index 14326d1..ddf3937 100644 (file)
@@ -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
 };
 
 
index b10f94f..4bf1a2d 100644 (file)
@@ -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;
 }
 
 
diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_wavepcistream.c b/reactos/drivers/wdm/audio/backpln/portcls/port_wavepcistream.c
new file mode 100644 (file)
index 0000000..8a8cf90
--- /dev/null
@@ -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);
+}
+
index be095d2..84f4a48 100644 (file)
@@ -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>
index a3db516..c71661f 100644 (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)\