Author: janderwald
Date: Mon Apr 27 04:33:49 2009
New Revision: 40712
URL:
http://svn.reactos.org/svn/reactos?rev=40712&view=rev
Log:
- Experimental IPortPinWavePci implementation
- Refactor IPortWavePciStream initilization
- Add test code for IDrmAudioStream
Modified:
trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.c
trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c
trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h
trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c
trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c
trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c
trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c
trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepcistream.c
trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.c [iso-8859-1]
(original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.c [iso-8859-1] Mon Apr
27 04:33:49 2009
@@ -131,7 +131,7 @@
}
/* initialize the pin */
- Status = Pin->lpVtbl->Init(Pin, This->Port, iface, ConnectDetails,
&This->Descriptor->Factory.KsPinDescriptor[ConnectDetails->PinId],
GetDeviceObjectFromWaveCyclic(This->Port));
+ Status = Pin->lpVtbl->Init(Pin, This->Port, iface, ConnectDetails,
&This->Descriptor->Factory.KsPinDescriptor[ConnectDetails->PinId],
GetDeviceObjectFromPortWavePci(This->Port));
if (!NT_SUCCESS(Status))
{
Pin->lpVtbl->Release(Pin);
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c [iso-8859-1] Mon Apr 27
04:33:49 2009
@@ -51,7 +51,7 @@
const GUID IID_IPortEvents = {0xA80F29C4L, 0x5498, 0x11D2, {0x95, 0xD9, 0x00, 0xC0, 0x4F,
0xB9, 0x25, 0xD3}};
const GUID KSNAME_PIN = {0x146F1A80, 0x4791, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB,
0x04, 0xC1, 0x00, 0x00}};
-
+const GUID IID_IDrmAudioStream = {0x1915c967, 0x3299, 0x48cb, {0xa3, 0xe4, 0x69, 0xfd,
0x1d, 0x1b, 0x30, 0x6e}};
//FIXME
//
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] Mon Apr 27
04:33:49 2009
@@ -230,6 +230,7 @@
STDMETHOD_(VOID, ReleaseMappingWithTag)(THIS_
IN PVOID Tag);
+ STDMETHOD_(BOOL, HasLastMappingFailed)(THIS);
};
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c [iso-8859-1] Mon Apr 27
04:33:49 2009
@@ -43,6 +43,8 @@
BOOL OutOfMapping;
ULONG MaxFrameSize;
+ BOOL LastMappingFailed;
+
}IIrpQueueImpl;
VOID
@@ -189,11 +191,14 @@
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
if (!This->FirstMap)
+ {
+ This->LastMappingFailed = TRUE;
return STATUS_UNSUCCESSFUL;
+ }
*Buffer = (PUCHAR)This->FirstMap->Header->Data + This->CurrentOffset;
*BufferSize = This->FirstMap->Header->DataUsed - This->CurrentOffset;
-
+ This->LastMappingFailed = FALSE;
return STATUS_SUCCESS;
}
@@ -365,13 +370,17 @@
KeReleaseSpinLock(&This->Lock, OldIrql);
if (!Result)
+ {
+ This->LastMappingFailed = TRUE;
return STATUS_UNSUCCESSFUL;
+ }
Result->Tag = Tag;
*PhysicalAddress = MmGetPhysicalAddress(Result->Header->Data);
*VirtualAddress = Result->Header->Data;
*ByteCount = Result->Header->DataUsed;
This->LastTag = Tag;
+ This->LastMappingFailed = FALSE;
return STATUS_SUCCESS;
}
@@ -421,6 +430,15 @@
KeReleaseSpinLock(&This->Lock, OldIrql);
}
+BOOL
+NTAPI
+IIrpQueue_fnHasLastMappingFailed(
+ IN IIrpQueue *iface)
+{
+ IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
+ return This->LastMappingFailed;
+}
+
static IIrpQueueVtbl vt_IIrpQueue =
{
IIrpQueue_fnQueryInterface,
@@ -436,7 +454,9 @@
IIrpQueue_fnCancelBuffers,
IIrpQueue_fnUpdateFormat,
IIrpQueue_fnGetMappingWithTag,
- IIrpQueue_fnReleaseMappingWithTag
+ IIrpQueue_fnReleaseMappingWithTag,
+ IIrpQueue_fnHasLastMappingFailed
+
};
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1]
(original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1] Mon Apr
27 04:33:49 2009
@@ -37,6 +37,10 @@
ULONG FrameSize;
BOOL Capture;
+ ULONG TotalPackets;
+ ULONG PreCompleted;
+ ULONG PostCompleted;
+
}IPortPinWaveCyclicImpl;
@@ -120,6 +124,8 @@
ULONG BufferSize;
PUCHAR Buffer;
NTSTATUS Status;
+ PUSHORT Data;
+ ULONG Index;
BufferLength = Position - This->CommonBufferOffset;
while(BufferLength)
@@ -140,6 +146,10 @@
}
else
{
+ Data = (PUSHORT)Buffer;
+ for(Index = 0; Index < BytesToCopy / sizeof(USHORT); Index++)
+ Data[Index] = Data[Index] + 32768;
+
This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
(PUCHAR)This->CommonBuffer +
This->CommonBufferOffset,
Buffer,
@@ -164,6 +174,8 @@
ULONG BufferSize;
PUCHAR Buffer;
NTSTATUS Status;
+ PUSHORT Data;
+ ULONG Index;
BufferLength = This->CommonBufferSize - This->CommonBufferOffset;
while(BufferLength)
@@ -183,6 +195,10 @@
}
else
{
+ Data = (PUSHORT)Buffer;
+ for(Index = 0; Index < BytesToCopy / sizeof(USHORT); Index++)
+ Data[Index] = Data[Index] + 32768;
+
This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
(PUCHAR)This->CommonBuffer +
This->CommonBufferOffset,
Buffer,
@@ -228,7 +244,7 @@
{
/* reset start stream */
This->IrpQueue->lpVtbl->CancelBuffers(This->IrpQueue); //FIX
function name
- DPRINT1("Stopping %u Irql %u\n", This,
This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue), KeGetCurrentIrql());
+ DPRINT1("Stopping PreCompleted %u PostCompleted %u\n",
This->PreCompleted, This->PostCompleted);
}
}
}
@@ -908,7 +924,9 @@
PIRP Irp;
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
- DPRINT("IPortPinWaveCyclic_fnFastWrite entered\n");
+ InterlockedIncrement((PLONG)&This->TotalPackets);
+
+ DPRINT("IPortPinWaveCyclic_fnFastWrite entered Total %u Pre %u Post %u\n",
This->TotalPackets, This->PreCompleted, This->PostCompleted);
Packet = (PCONTEXT_WRITE)Buffer;
@@ -917,6 +935,7 @@
{
Irp = Packet->Irp;
StatusBlock->Status = STATUS_PENDING;
+ InterlockedIncrement((PLONG)&This->PostCompleted);
}
else
{
@@ -925,6 +944,7 @@
Packet->Irp->IoStatus.Information = Packet->Header.FrameExtent;
IoCompleteRequest(Packet->Irp, IO_SOUND_INCREMENT);
StatusBlock->Status = STATUS_SUCCESS;
+ InterlockedIncrement((PLONG)&This->PreCompleted);
}
Status = This->IrpQueue->lpVtbl->AddMapping(This->IrpQueue, Buffer,
Length, Irp);
@@ -958,6 +978,7 @@
PKSDATAFORMAT DataFormat;
PDEVICE_OBJECT DeviceObject;
BOOL Capture;
+ //IDrmAudioStream * DrmAudio = NULL;
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
@@ -1016,6 +1037,21 @@
This->Format,
&This->DmaChannel,
&This->ServiceGroup);
+#if 0
+ Status = This->Stream->lpVtbl->QueryInterface(This->Stream,
&IID_IDrmAudioStream, (PVOID*)&DrmAudio);
+ if (NT_SUCCESS(Status))
+ {
+ DRMRIGHTS DrmRights;
+ DPRINT1("Got IID_IDrmAudioStream interface %p\n", DrmAudio);
+
+ DrmRights.CopyProtect = FALSE;
+ DrmRights.Reserved = 0;
+ DrmRights.DigitalOutputDisable = FALSE;
+
+ Status = DrmAudio->lpVtbl->SetContentId(DrmAudio, 1, &DrmRights);
+ DPRINT("Status %x\n", Status);
+ }
+#endif
DPRINT("IPortPinWaveCyclic_fnInit Status %x\n", Status);
@@ -1033,7 +1069,7 @@
This->ServiceGroup->lpVtbl->SupportDelayedService(This->ServiceGroup);
//This->DmaChannel->lpVtbl->AddRef(This->DmaChannel);
-
+ This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP);
This->State = KSSTATE_STOP;
This->CommonBufferOffset = 0;
This->CommonBufferSize =
This->DmaChannel->lpVtbl->AllocatedBufferSize(This->DmaChannel);
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.c [iso-8859-1] Mon Apr 27
04:33:49 2009
@@ -1,16 +1,829 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Kernel Streaming
- * FILE: drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c
- * PURPOSE: WaveCyclic IRP Audio Pin
+ * FILE: drivers/wdm/audio/backpln/portcls/pin_WavePci.c
+ * PURPOSE: WavePci IRP Audio Pin
* PROGRAMMER: Johannes Anderwald
*/
#include "private.h"
-NTSTATUS
-NewPortPinWavePci(
+#include "private.h"
+
+typedef struct
+{
+ IPortPinWavePciVtbl *lpVtbl;
+ IServiceSinkVtbl *lpVtblServiceSink;
+
+ LONG ref;
+ IPortWavePci * Port;
+ IPortFilterWavePci * Filter;
+ KSPIN_DESCRIPTOR * KsPinDescriptor;
+ PMINIPORTWAVEPCI Miniport;
+ PSERVICEGROUP ServiceGroup;
+ PDMACHANNEL DmaChannel;
+ PMINIPORTWAVEPCISTREAM Stream;
+ KSSTATE State;
+ PKSDATAFORMAT Format;
+ KSPIN_CONNECT * ConnectDetails;
+
+ BOOL Capture;
+ PDEVICE_OBJECT DeviceObject;
+ PPORTWAVEPCISTREAM WaveStream;
+ IIrpQueue * IrpQueue;
+
+ ULONG TotalPackets;
+ ULONG PreCompleted;
+ ULONG PostCompleted;
+
+}IPortPinWavePciImpl;
+
+
+typedef struct
+{
+ IPortPinWavePciImpl *Pin;
+ PIO_WORKITEM WorkItem;
+ KSSTATE State;
+}SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT;
+
+NTSTATUS
+NTAPI
+IPortWavePci_fnProcessNewIrp(
+ IPortPinWavePciImpl * This);
+
+//==================================================================================================================================
+
+static
+NTSTATUS
+NTAPI
+IServiceSink_fnQueryInterface(
+ IServiceSink* iface,
+ IN REFIID refiid,
+ OUT PVOID* Output)
+{
+ IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface,
IPortPinWavePciImpl, lpVtblServiceSink);
+
+ DPRINT("IServiceSink_fnQueryInterface entered\n");
+
+ if (IsEqualGUIDAligned(refiid, &IID_IServiceSink) ||
+ IsEqualGUIDAligned(refiid, &IID_IUnknown))
+ {
+ *Output = &This->lpVtblServiceSink;
+ InterlockedIncrement(&This->ref);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+static
+ULONG
+NTAPI
+IServiceSink_fnAddRef(
+ IServiceSink* iface)
+{
+ IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface,
IPortPinWavePciImpl, lpVtblServiceSink);
+ DPRINT("IServiceSink_fnAddRef entered\n");
+
+ return InterlockedIncrement(&This->ref);
+}
+
+static
+ULONG
+NTAPI
+IServiceSink_fnRelease(
+ IServiceSink* iface)
+{
+ IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface,
IPortPinWavePciImpl, lpVtblServiceSink);
+
+ InterlockedDecrement(&This->ref);
+
+ DPRINT("IServiceSink_fnRelease entered %u\n", This->ref);
+
+ if (This->ref == 0)
+ {
+ FreeItem(This, TAG_PORTCLASS);
+ return 0;
+ }
+ /* Return new reference count */
+ return This->ref;
+}
+static
+VOID
+NTAPI
+SetStreamWorkerRoutine(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context)
+{
+ IPortPinWavePciImpl * This;
+ PSETSTREAM_CONTEXT Ctx = (PSETSTREAM_CONTEXT)Context;
+ KSSTATE State;
+
+ This = Ctx->Pin;
+ State = Ctx->State;
+
+ IoFreeWorkItem(Ctx->WorkItem);
+ FreeItem(Ctx, TAG_PORTCLASS);
+
+ /* Has the audio stream resumed? */
+ if (This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue) && State
== KSSTATE_STOP)
+ return;
+
+ /* Set the state */
+ if (NT_SUCCESS(This->Stream->lpVtbl->SetState(This->Stream, State)))
+ {
+ /* Set internal state to stop */
+ This->State = State;
+
+ if (This->State == KSSTATE_STOP)
+ {
+ /* reset start stream */
+ This->IrpQueue->lpVtbl->CancelBuffers(This->IrpQueue); //FIX
function name
+ DPRINT1("Stopping PreCompleted %u PostCompleted %u\n",
This->PreCompleted, This->PostCompleted);
+ }
+ }
+}
+static
+VOID
+NTAPI
+SetStreamState(
+ IN IPortPinWavePciImpl * This,
+ IN KSSTATE State)
+{
+ PDEVICE_OBJECT DeviceObject;
+ PIO_WORKITEM WorkItem;
+ PSETSTREAM_CONTEXT Context;
+
+ ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+
+ /* Has the audio stream resumed? */
+ if (This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue) && State
== KSSTATE_STOP)
+ return;
+
+ /* Has the audio state already been set? */
+ if (This->State == State)
+ return;
+
+ /* Get device object */
+ DeviceObject = GetDeviceObjectFromPortWavePci(This->Port);
+
+ /* allocate set state context */
+ Context = AllocateItem(NonPagedPool, sizeof(SETSTREAM_CONTEXT), TAG_PORTCLASS);
+
+ if (!Context)
+ return;
+
+ /* allocate work item */
+ WorkItem = IoAllocateWorkItem(DeviceObject);
+
+ if (!WorkItem)
+ {
+ ExFreePool(Context);
+ return;
+ }
+
+ Context->Pin = (PVOID)This;
+ Context->WorkItem = WorkItem;
+ Context->State = State;
+
+ /* queue the work item */
+ IoQueueWorkItem(WorkItem, SetStreamWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
+}
+
+static
+VOID
+NTAPI
+IServiceSink_fnRequestService(
+ IServiceSink* iface)
+{
+ ULONGLONG Position;
+ NTSTATUS Status;
+ IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface,
IPortPinWavePciImpl, lpVtblServiceSink);
+
+ ASSERT_IRQL(DISPATCH_LEVEL);
+
+ Status = This->Stream->lpVtbl->GetPosition(This->Stream, &Position);
+ DPRINT("Position %llu Status %x\n", Position, Status);
+
+ This->Stream->lpVtbl->Service(This->Stream);
+}
+
+static IServiceSinkVtbl vt_IServiceSink =
+{
+ IServiceSink_fnQueryInterface,
+ IServiceSink_fnAddRef,
+ IServiceSink_fnRelease,
+ IServiceSink_fnRequestService
+};
+
+//==================================================================================================================================
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinWavePci_fnQueryInterface(
+ IPortPinWavePci* iface,
+ IN REFIID refiid,
+ OUT PVOID* Output)
+{
+ IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
+
+ if (IsEqualGUIDAligned(refiid, &IID_IIrpTarget) ||
+ IsEqualGUIDAligned(refiid, &IID_IUnknown))
+ {
+ *Output = &This->lpVtbl;
+ InterlockedIncrement(&This->ref);
+ return STATUS_SUCCESS;
+ }
+
+ return STATUS_UNSUCCESSFUL;
+}
+
+/*
+ * @implemented
+ */
+ULONG
+NTAPI
+IPortPinWavePci_fnAddRef(
+ IPortPinWavePci* iface)
+{
+ IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
+
+ return InterlockedIncrement(&This->ref);
+}
+
+/*
+ * @implemented
+ */
+ULONG
+NTAPI
+IPortPinWavePci_fnRelease(
+ IPortPinWavePci* iface)
+{
+ IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
+
+ InterlockedDecrement(&This->ref);
+
+ if (This->ref == 0)
+ {
+ FreeItem(This, TAG_PORTCLASS);
+ return 0;
+ }
+ return This->ref;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+IPortPinWavePci_fnNewIrpTarget(
+ IN IPortPinWavePci* iface,
+ OUT struct IIrpTarget **OutTarget,
+ IN WCHAR * Name,
+ IN PUNKNOWN Unknown,
+ IN POOL_TYPE PoolType,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN KSOBJECT_CREATE *CreateObject)
+{
+ UNIMPLEMENTED
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_UNSUCCESSFUL;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+IPortPinWavePci_fnDeviceIoControl(
+ IN IPortPinWavePci* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ UNIMPLEMENTED
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_UNSUCCESSFUL;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinWavePci_fnRead(
+ IN IPortPinWavePci* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinWavePci_fnWrite(
+ IN IPortPinWavePci* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinWavePci_fnFlush(
+ IN IPortPinWavePci* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+static
+VOID
+NTAPI
+CloseStreamRoutine(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context)
+{
+ PMINIPORTWAVEPCISTREAM Stream;
+ NTSTATUS Status;
+ ISubdevice *ISubDevice;
+ PSUBDEVICE_DESCRIPTOR Descriptor;
+ IPortPinWavePciImpl * This;
+ PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context;
+
+ This = (IPortPinWavePciImpl*)Ctx->Pin;
+
+ if (This->Stream)
+ {
+ if (This->State != KSSTATE_STOP)
+ {
+ This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP);
+ KeStallExecutionProcessor(10);
+ }
+ }
+
+ if (This->ServiceGroup)
+ {
+ This->ServiceGroup->lpVtbl->RemoveMember(This->ServiceGroup,
(PSERVICESINK)&This->lpVtblServiceSink);
+ This->ServiceGroup->lpVtbl->Release(This->ServiceGroup);
+ }
+
+ Status = This->Port->lpVtbl->QueryInterface(This->Port,
&IID_ISubdevice, (PVOID*)&ISubDevice);
+ if (NT_SUCCESS(Status))
+ {
+ Status = ISubDevice->lpVtbl->GetDescriptor(ISubDevice, &Descriptor);
+ if (NT_SUCCESS(Status))
+ {
+ ISubDevice->lpVtbl->Release(ISubDevice);
+
Descriptor->Factory.Instances[This->ConnectDetails->PinId].CurrentPinInstanceCount--;
+ }
+ }
+
+ if (This->Format)
+ {
+ ExFreePool(This->Format);
+ This->Format = NULL;
+ }
+
+ if (This->WaveStream)
+ {
+ This->WaveStream->lpVtbl->Release(This->WaveStream);
+ }
+
+ /* complete the irp */
+ Ctx->Irp->IoStatus.Information = 0;
+ Ctx->Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Ctx->Irp, IO_NO_INCREMENT);
+
+ /* free the work item */
+ IoFreeWorkItem(Ctx->WorkItem);
+
+ /* free work item ctx */
+ FreeItem(Ctx, TAG_PORTCLASS);
+
+ if (This->Stream)
+ {
+ Stream = This->Stream;
+ This->Stream = NULL;
+ DPRINT1("Closing stream at Irql %u\n", KeGetCurrentIrql());
+ Stream->lpVtbl->Release(Stream);
+ /* this line is never reached */
+ }
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinWavePci_fnClose(
+ IN IPortPinWavePci* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PCLOSESTREAM_CONTEXT Ctx;
+ IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
+
+ if (This->Stream)
+ {
+ Ctx = AllocateItem(NonPagedPool, sizeof(CLOSESTREAM_CONTEXT), TAG_PORTCLASS);
+ if (!Ctx)
+ {
+ DPRINT1("Failed to allocate stream context\n");
+ goto cleanup;
+ }
+
+ Ctx->WorkItem = IoAllocateWorkItem(DeviceObject);
+ if (!Ctx->WorkItem)
+ {
+ DPRINT1("Failed to allocate work item\n");
+ goto cleanup;
+ }
+
+ Ctx->Irp = Irp;
+ Ctx->Pin = (PVOID)This;
+
+ IoMarkIrpPending(Irp);
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_PENDING;
+
+ /* defer work item */
+ IoQueueWorkItem(Ctx->WorkItem, CloseStreamRoutine, DelayedWorkQueue,
(PVOID)Ctx);
+ /* Return result */
+ return STATUS_PENDING;
+ }
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_SUCCESS;
+
+cleanup:
+
+ if (Ctx)
+ FreeItem(Ctx, TAG_PORTCLASS);
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_UNSUCCESSFUL;
+
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinWavePci_fnQuerySecurity(
+ IN IPortPinWavePci* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IPortPinWavePci_fnSetSecurity(
+ IN IPortPinWavePci* iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+IPortPinWavePci_fnFastDeviceIoControl(
+ IN IPortPinWavePci* iface,
+ IN PFILE_OBJECT FileObject,
+ IN BOOLEAN Wait,
+ IN PVOID InputBuffer,
+ IN ULONG InputBufferLength,
+ OUT PVOID OutputBuffer,
+ IN ULONG OutputBufferLength,
+ IN ULONG IoControlCode,
+ OUT PIO_STATUS_BLOCK StatusBlock,
+ IN PDEVICE_OBJECT DeviceObject)
+{
+ UNIMPLEMENTED
+ return FALSE;
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+IPortPinWavePci_fnFastRead(
+ IN IPortPinWavePci* iface,
+ IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN BOOLEAN Wait,
+ IN ULONG LockKey,
+ IN PVOID Buffer,
+ OUT PIO_STATUS_BLOCK StatusBlock,
+ IN PDEVICE_OBJECT DeviceObject)
+{
+ NTSTATUS Status;
+ PCONTEXT_WRITE Packet;
+ PIRP Irp;
+ IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
+
+ DPRINT("IPortPinWavePci_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\n",
This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue));
+
+ This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_RUN);
+ This->State = KSSTATE_RUN;
+ }
+ return TRUE;
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+IPortPinWavePci_fnFastWrite(
+ IN IPortPinWavePci* iface,
+ IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN BOOLEAN Wait,
+ IN ULONG LockKey,
+ IN PVOID Buffer,
+ OUT PIO_STATUS_BLOCK StatusBlock,
+ IN PDEVICE_OBJECT DeviceObject)
+{
+ NTSTATUS Status;
+ PCONTEXT_WRITE Packet;
+ PIRP Irp;
+ IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
+
+ InterlockedIncrement((PLONG)&This->TotalPackets);
+
+ DPRINT("IPortPinWavePci_fnFastWrite entered Total %u Pre %u Post %u\n",
This->TotalPackets, This->PreCompleted, This->PostCompleted);
+
+ Packet = (PCONTEXT_WRITE)Buffer;
+
+
+ if (This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue))
+ {
+ Irp = Packet->Irp;
+ StatusBlock->Status = STATUS_PENDING;
+ InterlockedIncrement((PLONG)&This->PostCompleted);
+ }
+ else
+ {
+ Irp = NULL;
+ Packet->Irp->IoStatus.Status = STATUS_SUCCESS;
+ Packet->Irp->IoStatus.Information = Packet->Header.FrameExtent;
+ IoCompleteRequest(Packet->Irp, IO_SOUND_INCREMENT);
+ StatusBlock->Status = STATUS_SUCCESS;
+ InterlockedIncrement((PLONG)&This->PreCompleted);
+ }
+
+ 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)
+ {
+ SetStreamState(This, KSSTATE_RUN);
+ /* some should initiate a state request but didnt do it */
+ DPRINT1("Starting stream with %lu mappings Status %x\n",
This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue), Status);
+ }
+
+ if (This->IrpQueue->lpVtbl->HasLastMappingFailed(This->IrpQueue))
+ {
+ /* notify port driver that new mapping is available */
+ This->Stream->lpVtbl->MappingAvailable(This->Stream);
+ }
+
+ return TRUE;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+IPortPinWavePci_fnInit(
+ IN IPortPinWavePci* iface,
+ IN PPORTWAVEPCI Port,
+ IN PPORTFILTERWAVEPCI Filter,
+ IN KSPIN_CONNECT * ConnectDetails,
+ IN KSPIN_DESCRIPTOR * KsPinDescriptor,
+ IN PDEVICE_OBJECT DeviceObject)
+{
+ NTSTATUS Status;
+ PKSDATAFORMAT DataFormat;
+ BOOL Capture;
+ KSALLOCATOR_FRAMING AllocatorFraming;
+
+ IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
+
+ Port->lpVtbl->AddRef(Port);
+ Filter->lpVtbl->AddRef(Filter);
+
+ This->Port = Port;
+ This->Filter = Filter;
+ This->KsPinDescriptor = KsPinDescriptor;
+ This->ConnectDetails = ConnectDetails;
+ This->Miniport = GetWavePciMiniport(Port);
+ This->DeviceObject = DeviceObject;
+
+ DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1);
+
+ DPRINT("IPortPinWavePci_fnInit entered\n");
+
+ This->Format = ExAllocatePoolWithTag(NonPagedPool, DataFormat->FormatSize,
TAG_PORTCLASS);
+ if (!This->Format)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ RtlMoveMemory(This->Format, DataFormat, DataFormat->FormatSize);
+
+ Status = NewIPortWavePciStream(&This->WaveStream);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(This->Format);
+ This->Format = NULL;
+ 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,
+ This->WaveStream,
+ Capture,
+ ConnectDetails->PinId,
+ This->Format,
+ &This->DmaChannel,
+ &This->ServiceGroup);
+
+ DPRINT("IPortPinWavePci_fnInit Status %x\n", Status);
+
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ if (This->ServiceGroup)
+ {
+ Status = This->ServiceGroup->lpVtbl->AddMember(This->ServiceGroup,
+
(PSERVICESINK)&This->lpVtblServiceSink);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to add pin to service group\n");
+ return Status;
+ }
+
This->ServiceGroup->lpVtbl->SupportDelayedService(This->ServiceGroup);
+ }
+
+ This->IrpQueue = IPortWavePciStream_GetIrpQueue(This->WaveStream);
+
+ Status = This->Stream->lpVtbl->GetAllocatorFraming(This->Stream,
&AllocatorFraming);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("GetAllocatorFraming failed with %x\n", Status);
+ return Status;
+ }
+
+ Status = This->IrpQueue->lpVtbl->Init(This->IrpQueue, ConnectDetails,
This->Format, DeviceObject, AllocatorFraming.FrameSize);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IrpQueue_Init failed with %x\n", Status);
+ return Status;
+ }
+
+ This->State = KSSTATE_STOP;
+ This->Capture = Capture;
+
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+PVOID
+NTAPI
+IPortPinWavePci_fnGetIrpStream(
+ IN IPortPinWavePci* iface)
+{
+ IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
+
+ return (PVOID)This->IrpQueue;
+}
+
+
+/*
+ * @implemented
+ */
+PMINIPORT
+NTAPI
+IPortPinWavePci_fnGetMiniport(
+ IN IPortPinWavePci* iface)
+{
+ IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
+
+ return (PMINIPORT)This->Miniport;
+}
+
+static IPortPinWavePciVtbl vt_IPortPinWavePci =
+{
+ IPortPinWavePci_fnQueryInterface,
+ IPortPinWavePci_fnAddRef,
+ IPortPinWavePci_fnRelease,
+ IPortPinWavePci_fnNewIrpTarget,
+ IPortPinWavePci_fnDeviceIoControl,
+ IPortPinWavePci_fnRead,
+ IPortPinWavePci_fnWrite,
+ IPortPinWavePci_fnFlush,
+ IPortPinWavePci_fnClose,
+ IPortPinWavePci_fnQuerySecurity,
+ IPortPinWavePci_fnSetSecurity,
+ IPortPinWavePci_fnFastDeviceIoControl,
+ IPortPinWavePci_fnFastRead,
+ IPortPinWavePci_fnFastWrite,
+ IPortPinWavePci_fnInit,
+ IPortPinWavePci_fnGetIrpStream,
+ IPortPinWavePci_fnGetMiniport
+};
+
+
+
+
+NTSTATUS NewPortPinWavePci(
OUT IPortPinWavePci ** OutPin)
{
- return STATUS_UNSUCCESSFUL;
-}
+ IPortPinWavePciImpl * This;
+
+ This = AllocateItem(NonPagedPool, sizeof(IPortPinWavePciImpl), TAG_PORTCLASS);
+ if (!This)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* initialize IPortPinWavePci */
+ This->ref = 1;
+ This->lpVtbl = &vt_IPortPinWavePci;
+ This->lpVtblServiceSink = &vt_IServiceSink;
+
+
+ /* store result */
+ *OutPin = (IPortPinWavePci*)&This->lpVtbl;
+
+ return STATUS_SUCCESS;
+}
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c [iso-8859-1]
(original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c [iso-8859-1] Mon Apr 27
04:33:49 2009
@@ -813,10 +813,17 @@
}
PDEVICE_OBJECT
-GetDeviceObjectFromWaveCyclic(
+GetDeviceObjectFromPortWavePci(
IPortWavePci* iface)
{
IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
return This->pDeviceObject;
}
+PMINIPORTWAVEPCI
+GetWavePciMiniport(
+ PPORTWAVEPCI iface)
+{
+ IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
+ return This->Miniport;
+}
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepcistream.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepcistream.c [iso-8859-1]
(original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepcistream.c [iso-8859-1] Mon
Apr 27 04:33:49 2009
@@ -66,6 +66,7 @@
if (This->ref == 0)
{
+ This->Queue->lpVtbl->Release(This->Queue);
FreeItem(This, TAG_PORTCLASS);
return 0;
}
@@ -131,11 +132,7 @@
NTSTATUS
NTAPI
NewIPortWavePciStream(
- OUT PPORTWAVEPCISTREAM *Stream,
- IN KSPIN_CONNECT *ConnectDetails,
- IN PKSDATAFORMAT DataFormat,
- IN PDEVICE_OBJECT DeviceObject,
- IN ULONG FrameSize)
+ OUT PPORTWAVEPCISTREAM *Stream)
{
IIrpQueue * Queue;
IPortWavePciStreamImpl * This;
@@ -144,13 +141,6 @@
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)
@@ -167,15 +157,12 @@
return STATUS_SUCCESS;
}
-NTSTATUS
+IIrpQueue*
NTAPI
-IPortWavePciStream_AddMapping(
- IN IPortWavePciStream *iface,
- IN PUCHAR Buffer,
- IN ULONG BufferSize,
- IN PIRP Irp)
+IPortWavePciStream_GetIrpQueue(
+ IN IPortWavePciStream *iface)
{
IPortWavePciStreamImpl * This = (IPortWavePciStreamImpl*)iface;
- return This->Queue->lpVtbl->AddMapping(This->Queue, Buffer, BufferSize,
Irp);
+ return This->Queue;
}
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] Mon Apr 27
04:33:49 2009
@@ -101,6 +101,13 @@
GetDeviceObjectFromWaveCyclic(
IPortWavePci* iface);
+PDEVICE_OBJECT
+GetDeviceObjectFromPortWavePci(
+ IPortWavePci* iface);
+
+PMINIPORTWAVEPCI
+GetWavePciMiniport(
+ PPORTWAVEPCI Port);
NTSTATUS
NTAPI
@@ -272,22 +279,15 @@
GetDeviceObject(
IPortWaveCyclic* iface);
-NTSTATUS
-NTAPI
-IPortWavePciStream_AddMapping(
- IN IPortWavePciStream *iface,
- IN PUCHAR Buffer,
- IN ULONG BufferSize,
- IN PIRP Irp);
+IIrpQueue*
+NTAPI
+IPortWavePciStream_GetIrpQueue(
+ IN IPortWavePciStream *iface);
NTSTATUS
NTAPI
NewIPortWavePciStream(
- OUT PPORTWAVEPCISTREAM *Stream,
- IN KSPIN_CONNECT *ConnectDetails,
- IN PKSDATAFORMAT DataFormat,
- IN PDEVICE_OBJECT DeviceObject,
- IN ULONG FrameSize);
+ OUT PPORTWAVEPCISTREAM *Stream);
#define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet,\
PropGeneral, PropInstances, PropIntersection)\