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/p... ============================================================================== --- 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/p... ============================================================================== --- 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/p... ============================================================================== --- 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/p... ============================================================================== --- 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/p... ============================================================================== --- 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/p... ============================================================================== --- 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/p... ============================================================================== --- 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/p... ============================================================================== --- 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/p... ============================================================================== --- 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)\