Author: janderwald Date: Fri Jul 17 21:15:52 2009 New Revision: 42016
URL: http://svn.reactos.org/svn/reactos?rev=42016&view=rev Log: [WDMAUD.DRV] - Implement retrieving the preferred frame size - Set Maximum buffer limit to one second [PORTCLS] - Implement a dynamic buffer enlarging. In case a audio stream stops prematurely, increase the audio buffer limit by 1/3 - Implement KSPROPERTY_CONNECTION_ALLOCATORFRAMING for IPortPinWaveCyclic + IPortPinWavePci - Move IPortWavePciStream object to IPortPinWavePci, as IPrefetchOffset needs a tight integration (TBD) - Define pin property handler for IPortDMus (some audio devices may now show more than one waveout device) - Implement IPortEvents_fnAddEventToEventList for IPortWavePci [WDMAUD_KERNEL] - Implement IOCTL_GETFRAMESIZE [SYSAUDIO] - Fix a bug in the Pin_fnWrite, though code isnt used yet -? - Adobe Flash Player & Vlc may now have a better playback because the audio stream is now updated more often (because audio packet now use the preferred frame size which is in most cases 10ms).
Removed: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepcistream.c Modified: trunk/reactos/dll/win32/wdmaud.drv/wdmaud.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_dmus.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c trunk/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h trunk/reactos/drivers/wdm/audio/sysaudio/pin.c
Modified: trunk/reactos/dll/win32/wdmaud.drv/wdmaud.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/wdmaud.drv/wdmaud... ============================================================================== --- trunk/reactos/dll/win32/wdmaud.drv/wdmaud.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/wdmaud.drv/wdmaud.c [iso-8859-1] Fri Jul 17 21:15:52 2009 @@ -299,6 +299,26 @@
Instance->Handle = (PVOID)DeviceInfo.hDevice;
+ /* Now determine framing requirements */ + Result = SyncOverlappedDeviceIoControl(KernelHandle, + IOCTL_GETFRAMESIZE, + (LPVOID) &DeviceInfo, + sizeof(WDMAUD_DEVICE_INFO), + (LPVOID) &DeviceInfo, + sizeof(WDMAUD_DEVICE_INFO), + NULL); + + if ( MMSUCCESS(Result) ) + { + if (DeviceInfo.u.FrameSize) + { + Instance->FrameSize = DeviceInfo.u.FrameSize; + Instance->BufferCount = WaveFormat->nAvgBytesPerSec / Instance->FrameSize; + SND_TRACE(L"FrameSize %u BufferCount %u\n", Instance->FrameSize, Instance->BufferCount); + } + } + + return MMSYSERR_NOERROR; }
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] Fri Jul 17 21:15:52 2009 @@ -234,6 +234,9 @@
STDMETHOD_(BOOL, HasLastMappingFailed)(THIS); STDMETHOD_(VOID, PrintQueueStatus)(THIS); + STDMETHOD_(VOID, SetMinimumDataThreshold)(THIS_ + IN ULONG MinimumDataThreshold); + STDMETHOD_(ULONG, GetMinimumDataThreshold)(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] Fri Jul 17 21:15:52 2009 @@ -40,6 +40,7 @@ ULONG OutOfMapping; ULONG MaxFrameSize; ULONG Alignment; + ULONG MinimumDataThreshold;
}IIrpQueueImpl;
@@ -128,6 +129,7 @@ This->DataFormat = (PKSDATAFORMAT_WAVEFORMATEX)DataFormat; This->MaxFrameSize = FrameSize; This->Alignment = Alignment; + This->MinimumDataThreshold = ((PKSDATAFORMAT_WAVEFORMATEX)DataFormat)->WaveFormatEx.nAvgBytesPerSec / 3;
InitializeListHead(&This->ListHead); InitializeListHead(&This->FreeHead); @@ -315,7 +317,7 @@ if (This->StartStream) return TRUE;
- if (This->DataFormat->WaveFormatEx.nAvgBytesPerSec/3 < This->NumDataAvailable) + if (This->MinimumDataThreshold < This->NumDataAvailable) { This->StartStream = TRUE; Result = TRUE; @@ -346,9 +348,9 @@ { IIrpQueueImpl * This = (IIrpQueueImpl*)iface; This->DataFormat = (PKSDATAFORMAT_WAVEFORMATEX)DataFormat; + This->MinimumDataThreshold = This->DataFormat->WaveFormatEx.nAvgBytesPerSec / 3; This->StartStream = FALSE; This->NumDataAvailable = 0; - }
NTSTATUS @@ -473,6 +475,27 @@
KeReleaseSpinLockFromDpcLevel(&This->Lock); DPRINT("IIrpQueue_fnPrintQueueStatus ===============\n"); +} + +VOID +NTAPI +IIrpQueue_fnSetMinimumDataThreshold( + IN IIrpQueue *iface, + ULONG MinimumDataThreshold) +{ + IIrpQueueImpl * This = (IIrpQueueImpl*)iface; + + This->MinimumDataThreshold = MinimumDataThreshold; +} + +ULONG +NTAPI +IIrpQueue_fnGetMinimumDataThreshold( + IN IIrpQueue *iface) +{ + IIrpQueueImpl * This = (IIrpQueueImpl*)iface; + + return This->MinimumDataThreshold; }
@@ -493,10 +516,10 @@ IIrpQueue_fnGetMappingWithTag, IIrpQueue_fnReleaseMappingWithTag, IIrpQueue_fnHasLastMappingFailed, - IIrpQueue_fnPrintQueueStatus - + IIrpQueue_fnPrintQueueStatus, + IIrpQueue_fnSetMinimumDataThreshold, + IIrpQueue_fnGetMinimumDataThreshold }; -
NTSTATUS NTAPI @@ -515,44 +538,3 @@
}
-NTSTATUS -NewIrpStreamPhysical( - OUT IIrpStreamPhysical ** OutIIrpStreamPhysical, - IN IUnknown *OuterUnknown) -{ - return STATUS_UNSUCCESSFUL; -} - - -/* - * @implemented - */ - -NTSTATUS -NTAPI -PcNewIrpStreamPhysical( - OUT IIrpStreamPhysical ** OutIrpStreamPhysical, - IN IUnknown * OuterUnknown, - IN BOOLEAN Wait, - IN KSPIN_CONNECT *ConnectDetails, - IN PDEVICE_OBJECT DeviceObject, - IN PDMA_ADAPTER DmaAdapter) -{ - NTSTATUS Status; - IIrpStreamPhysical * Irp; - - Status = NewIrpStreamPhysical(&Irp, OuterUnknown); - if (!NT_SUCCESS(Status)) - return Status; - - - Status = Irp->lpVtbl->Init(Irp, Wait, ConnectDetails, DeviceObject, DmaAdapter); - if (!NT_SUCCESS(Status)) - { - Irp->lpVtbl->Release(Irp); - return Status; - } - - *OutIrpStreamPhysical = Irp; - return Status; -}
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] Fri Jul 17 21:15:52 2009 @@ -37,6 +37,7 @@ ULONG TotalPackets; ULONG PreCompleted; ULONG PostCompleted; + ULONG StopCount;
ULONG Delay; }IPortPinWaveCyclicImpl; @@ -224,6 +225,8 @@ IPortPinWaveCyclicImpl * This; PSETSTREAM_CONTEXT Ctx = (PSETSTREAM_CONTEXT)Context; KSSTATE State; + ULONG MinimumDataThreshold; + ULONG MaximumDataThreshold;
This = Ctx->Pin; State = Ctx->State; @@ -233,6 +236,10 @@
/* 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;
/* Set the state */ @@ -245,12 +252,26 @@ { /* reset start stream */ This->IrpQueue->lpVtbl->CancelBuffers(This->IrpQueue); //FIX function name - DPRINT1("Stopping PreCompleted %u PostCompleted %u\n", This->PreCompleted, This->PostCompleted); + + /* increase stop counter */ + This->StopCount++; + /* get current data threshold */ + MinimumDataThreshold = This->IrpQueue->lpVtbl->GetMinimumDataThreshold(This->IrpQueue); + /* get maximum data threshold */ + MaximumDataThreshold = ((PKSDATAFORMAT_WAVEFORMATEX)This->Format)->WaveFormatEx.nAvgBytesPerSec; + /* increase minimum data threshold by a third sec */ + MinimumDataThreshold += ((PKSDATAFORMAT_WAVEFORMATEX)This->Format)->WaveFormatEx.nAvgBytesPerSec / 3; + + /* assure it has not exceeded */ + MinimumDataThreshold = min(MinimumDataThreshold, MaximumDataThreshold); + /* store minimum data threshold */ + This->IrpQueue->lpVtbl->SetMinimumDataThreshold(This->IrpQueue, MinimumDataThreshold); + + DPRINT1("Stopping PreCompleted %u PostCompleted %u StopCount %u MinimumDataThreshold %u\n", This->PreCompleted, This->PostCompleted, This->StopCount, MinimumDataThreshold); } if (This->State == KSSTATE_RUN) { DPRINT1("State RUN %x MinAvailable %u\n", State, This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue)); - } } } @@ -570,11 +591,34 @@ return STATUS_SUCCESS; } } - - } + else if (Property->Id == KSPROPERTY_CONNECTION_ALLOCATORFRAMING) + { + PKSALLOCATOR_FRAMING Framing = (PKSALLOCATOR_FRAMING)Irp->UserBuffer; + + ASSERT_IRQL(DISPATCH_LEVEL); + /* Validate input buffer */ + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSALLOCATOR_FRAMING)) + { + Irp->IoStatus.Information = sizeof(KSALLOCATOR_FRAMING); + Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_BUFFER_TOO_SMALL; + } + /* Clear frame structure */ + RtlZeroMemory(Framing, sizeof(KSALLOCATOR_FRAMING)); + /* store requested frame size */ + Framing->FrameSize = This->FrameSize; + /* FIXME fill in struct */ + + Irp->IoStatus.Information = sizeof(KSALLOCATOR_FRAMING); + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + } + RtlStringFromGUID(&Property->Set, &GuidString); DPRINT1("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); - DbgBreakPoint(); RtlFreeUnicodeString(&GuidString);
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; @@ -640,7 +684,6 @@ }
UNIMPLEMENTED - DbgBreakPoint();
Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; @@ -696,21 +739,24 @@ { PMINIPORTWAVECYCLICSTREAM Stream; IPortPinWaveCyclicImpl * This; + NTSTATUS Status; PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context;
This = (IPortPinWaveCyclicImpl*)Ctx->Pin;
- if (This->Stream) - { - if (This->State != KSSTATE_STOP) - { - This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP); - KeStallExecutionProcessor(10); - } + if (This->State != KSSTATE_STOP) + { + /* stop stream in case it hasn't been */ + Status = This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP); + if (!NT_SUCCESS(Status)) + DPRINT1("Warning: failed to stop stream with %x\n", Status); + + This->State = KSSTATE_STOP; }
if (This->Format) { + /* free format */ ExFreePool(This->Format); This->Format = NULL; } @@ -848,7 +894,7 @@ OUT PIO_STATUS_BLOCK StatusBlock, IN PDEVICE_OBJECT DeviceObject) { - UNIMPLEMENTED + //UNIMPLEMENTED return FALSE; }
@@ -915,14 +961,18 @@ NTSTATUS Status; PCONTEXT_WRITE Packet; PIRP Irp; + ULONG PrePostRatio; + ULONG MinData; IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
InterlockedIncrement((PLONG)&This->TotalPackets);
- DPRINT("IPortPinWaveCyclic_fnFastWrite entered Total %u Pre %u Post %u State %x MinData %u\n", This->TotalPackets, This->PreCompleted, This->PostCompleted, This->State, This->IrpQueue->lpVtbl->NumData(This->IrpQueue)); + PrePostRatio = (This->PreCompleted * 100) / This->TotalPackets; + MinData = This->IrpQueue->lpVtbl->NumData(This->IrpQueue); + + DPRINT1("IPortPinWaveCyclic_fnFastWrite entered Total %u Pre %u Post %u State %x MinData %u Ratio %u\n", This->TotalPackets, This->PreCompleted, This->PostCompleted, This->State, This->IrpQueue->lpVtbl->NumData(This->IrpQueue), PrePostRatio);
Packet = (PCONTEXT_WRITE)Buffer; -
if (This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue)) { @@ -945,7 +995,7 @@ if (!NT_SUCCESS(Status)) return FALSE;
- if (This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue) == TRUE && This->State != KSSTATE_RUN) + if (This->State != KSSTATE_RUN && This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue) == TRUE) { SetStreamState(This, KSSTATE_RUN); /* some should initiate a state request but didnt do it */ @@ -999,13 +1049,6 @@ Status = NewIrpQueue(&This->IrpQueue); if (!NT_SUCCESS(Status)) return Status; - - Status = This->IrpQueue->lpVtbl->Init(This->IrpQueue, ConnectDetails, DataFormat, DeviceObject, 0, 0); - if (!NT_SUCCESS(Status)) - { - This->IrpQueue->lpVtbl->Release(This->IrpQueue); - return Status; - }
if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN) { @@ -1070,6 +1113,14 @@ This->Delay = Int32x32To64(10, -10000);
Status = This->Stream->lpVtbl->SetNotificationFreq(This->Stream, 10, &This->FrameSize); + + Status = This->IrpQueue->lpVtbl->Init(This->IrpQueue, ConnectDetails, DataFormat, DeviceObject, This->FrameSize, 0); + if (!NT_SUCCESS(Status)) + { + This->IrpQueue->lpVtbl->Release(This->IrpQueue); + return Status; + } +
//This->Stream->lpVtbl->SetFormat(This->Stream, (PKSDATAFORMAT)This->Format); DPRINT1("Setting state to acquire %x\n", This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_ACQUIRE));
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] Fri Jul 17 21:15:52 2009 @@ -12,6 +12,7 @@ { IPortPinWavePciVtbl *lpVtbl; IServiceSinkVtbl *lpVtblServiceSink; + IPortWavePciStreamVtbl *lpVtblPortWavePciStream;
LONG ref; IPortWavePci * Port; @@ -27,17 +28,21 @@
BOOL Capture; PDEVICE_OBJECT DeviceObject; - PPORTWAVEPCISTREAM WaveStream; IIrpQueue * IrpQueue;
ULONG TotalPackets; ULONG PreCompleted; ULONG PostCompleted; + ULONG StopCount;
ULONG Delay;
+ BOOL bUsePrefetch; + ULONG PrefetchOffset; + + KSALLOCATOR_FRAMING AllocatorFraming; + }IPortPinWavePciImpl; -
typedef struct { @@ -46,12 +51,110 @@ KSSTATE State; }SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT;
-NTSTATUS -NTAPI -IPortWavePci_fnProcessNewIrp( - IPortPinWavePciImpl * This); - //================================================================================================================================== +static +NTSTATUS +NTAPI +IPortWavePciStream_fnQueryInterface( + IPortWavePciStream* iface, + IN REFIID refiid, + OUT PVOID* Output) +{ + IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface, IPortPinWavePciImpl, lpVtblPortWavePciStream); + + 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) +{ + IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface, IPortPinWavePciImpl, lpVtblPortWavePciStream); + DPRINT("IPortWavePciStream_fnAddRef entered\n"); + + return InterlockedIncrement(&This->ref); +} + +static +ULONG +NTAPI +IPortWavePciStream_fnRelease( + IPortWavePciStream* iface) +{ + IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface, IPortPinWavePciImpl, lpVtblPortWavePciStream); + + InterlockedDecrement(&This->ref); + + DPRINT("IPortWavePciStream_fnRelease entered %u\n", This->ref); + + /* 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) +{ + IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface, IPortPinWavePciImpl, lpVtblPortWavePciStream); + + ASSERT_IRQL(DISPATCH_LEVEL); + return This->IrpQueue->lpVtbl->GetMappingWithTag(This->IrpQueue, Tag, PhysicalAddress, VirtualAddress, ByteCount, Flags); +} + +static +NTSTATUS +NTAPI +IPortWavePciStream_fnReleaseMapping( + IN IPortWavePciStream *iface, + IN PVOID Tag) +{ + IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface, IPortPinWavePciImpl, lpVtblPortWavePciStream); + + ASSERT_IRQL(DISPATCH_LEVEL); + return This->IrpQueue->lpVtbl->ReleaseMappingWithTag(This->IrpQueue, Tag); +} + +static +NTSTATUS +NTAPI +IPortWavePciStream_fnTerminatePacket( + IN IPortWavePciStream *iface) +{ + UNIMPLEMENTED + ASSERT_IRQL(DISPATCH_LEVEL); + return STATUS_SUCCESS; +} + + +static IPortWavePciStreamVtbl vt_PortWavePciStream = +{ + IPortWavePciStream_fnQueryInterface, + IPortWavePciStream_fnAddRef, + IPortWavePciStream_fnRelease, + IPortWavePciStream_fnGetMapping, + IPortWavePciStream_fnReleaseMapping, + IPortWavePciStream_fnTerminatePacket +}; +
static NTSTATUS @@ -117,6 +220,8 @@ IPortPinWavePciImpl * This; PSETSTREAM_CONTEXT Ctx = (PSETSTREAM_CONTEXT)Context; KSSTATE State; + ULONG MinimumDataThreshold; + ULONG MaximumDataThreshold;
This = Ctx->Pin; State = Ctx->State; @@ -138,13 +243,27 @@ { /* reset start stream */ This->IrpQueue->lpVtbl->CancelBuffers(This->IrpQueue); //FIX function name - This->ServiceGroup->lpVtbl->CancelDelayedService(This->ServiceGroup); - DPRINT1("Stopping PreCompleted %u PostCompleted %u\n", This->PreCompleted, This->PostCompleted); + //This->ServiceGroup->lpVtbl->CancelDelayedService(This->ServiceGroup); + /* increase stop counter */ + This->StopCount++; + /* get current data threshold */ + MinimumDataThreshold = This->IrpQueue->lpVtbl->GetMinimumDataThreshold(This->IrpQueue); + /* get maximum data threshold */ + MaximumDataThreshold = ((PKSDATAFORMAT_WAVEFORMATEX)This->Format)->WaveFormatEx.nAvgBytesPerSec * 3; + /* increase minimum data threshold by a third sec */ + MinimumDataThreshold += ((PKSDATAFORMAT_WAVEFORMATEX)This->Format)->WaveFormatEx.nAvgBytesPerSec / 3; + + /* assure it has not exceeded */ + MinimumDataThreshold = min(MinimumDataThreshold, MaximumDataThreshold); + /* store minimum data threshold */ + This->IrpQueue->lpVtbl->SetMinimumDataThreshold(This->IrpQueue, MinimumDataThreshold); + + DPRINT1("Stopping PreCompleted %u PostCompleted %u StopCount %u MinimumDataThreshold %u\n", This->PreCompleted, This->PostCompleted, This->StopCount, MinimumDataThreshold); } if (This->State == KSSTATE_RUN) { /* start the notification timer */ - This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, This->Delay); + //This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, This->Delay); } } } @@ -201,26 +320,23 @@ IServiceSink_fnRequestService( IServiceSink* iface) { - ULONGLONG Position; - NTSTATUS Status; IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface, IPortPinWavePciImpl, lpVtblServiceSink);
ASSERT_IRQL(DISPATCH_LEVEL);
if (This->IrpQueue->lpVtbl->HasLastMappingFailed(This->IrpQueue)) { - This->IrpQueue->lpVtbl->PrintQueueStatus(This->IrpQueue); if (This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue) == 0) { DPRINT("Stopping stream...\n"); SetStreamState(This, KSSTATE_STOP); + return; } }
- Status = This->Stream->lpVtbl->GetPosition(This->Stream, &Position); - DPRINT("Position %lu Status %x\n", Position, Status); - This->Stream->lpVtbl->Service(This->Stream); + //TODO + //generate events }
static IServiceSinkVtbl vt_IServiceSink = @@ -312,6 +428,191 @@ return STATUS_UNSUCCESSFUL; }
+NTSTATUS +NTAPI +IPortPinWavePci_HandleKsProperty( + IN IPortPinWavePci * iface, + IN PIRP Irp) +{ + PKSPROPERTY Property; + NTSTATUS Status; + UNICODE_STRING GuidString; + PIO_STACK_LOCATION IoStack; + + IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface; + + IoStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT("IPortPinWavePci_HandleKsProperty entered\n"); + + if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY)) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INVALID_PARAMETER; + } + + Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + + if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Connection)) + { + if (Property->Id == KSPROPERTY_CONNECTION_STATE) + { + PKSSTATE State = (PKSSTATE)Irp->UserBuffer; + + ASSERT_IRQL(DISPATCH_LEVEL); + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSSTATE)) + { + Irp->IoStatus.Information = sizeof(KSSTATE); + Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_BUFFER_TOO_SMALL; + } + + if (Property->Flags & KSPROPERTY_TYPE_SET) + { + Status = STATUS_UNSUCCESSFUL; + Irp->IoStatus.Information = 0; + + if (This->Stream) + { + Status = This->Stream->lpVtbl->SetState(This->Stream, *State); + + DPRINT1("Setting state %u %x\n", *State, Status); + if (NT_SUCCESS(Status)) + { + This->State = *State; + } + } + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + else if (Property->Flags & KSPROPERTY_TYPE_GET) + { + *State = This->State; + Irp->IoStatus.Information = sizeof(KSSTATE); + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + } + else if (Property->Id == KSPROPERTY_CONNECTION_DATAFORMAT) + { + PKSDATAFORMAT DataFormat = (PKSDATAFORMAT)Irp->UserBuffer; + if (Property->Flags & KSPROPERTY_TYPE_SET) + { + PKSDATAFORMAT NewDataFormat; + if (!RtlCompareMemory(DataFormat, This->Format, DataFormat->FormatSize)) + { + Irp->IoStatus.Information = DataFormat->FormatSize; + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + + NewDataFormat = AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); + if (!NewDataFormat) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_NO_MEMORY; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NO_MEMORY; + } + RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize); + + if (This->Stream) + { + ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); + ASSERT(NewDataFormat->FormatSize == sizeof(KSDATAFORMAT_WAVEFORMATEX)); + ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.MajorFormat, &KSDATAFORMAT_TYPE_AUDIO)); + ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)); + ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)); + + ASSERT(This->State == KSSTATE_STOP); + DPRINT1("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nChannels, + ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.wBitsPerSample, + ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nSamplesPerSec); + + Status = This->Stream->lpVtbl->SetFormat(This->Stream, NewDataFormat); + if (NT_SUCCESS(Status)) + { + if (This->Format) + ExFreePoolWithTag(This->Format, TAG_PORTCLASS); + + This->IrpQueue->lpVtbl->UpdateFormat(This->IrpQueue, (PKSDATAFORMAT)NewDataFormat); + This->Format = NewDataFormat; + Irp->IoStatus.Information = DataFormat->FormatSize; + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + } + DPRINT1("Failed to set format\n"); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; + } + else if (Property->Flags & KSPROPERTY_TYPE_GET) + { + if (!This->Format) + { + DPRINT1("No format\n"); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; + } + if (This->Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength) + { + Irp->IoStatus.Information = This->Format->FormatSize; + Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_BUFFER_TOO_SMALL; + } + + RtlMoveMemory(DataFormat, This->Format, This->Format->FormatSize); + Irp->IoStatus.Information = DataFormat->FormatSize; + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + } + else if (Property->Id == KSPROPERTY_CONNECTION_ALLOCATORFRAMING) + { + PKSALLOCATOR_FRAMING Framing = (PKSALLOCATOR_FRAMING)Irp->UserBuffer; + + ASSERT_IRQL(DISPATCH_LEVEL); + /* Validate input buffer */ + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSALLOCATOR_FRAMING)) + { + Irp->IoStatus.Information = sizeof(KSALLOCATOR_FRAMING); + Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_BUFFER_TOO_SMALL; + } + /* copy frame allocator struct */ + RtlMoveMemory(Framing, &This->AllocatorFraming, sizeof(KSALLOCATOR_FRAMING)); + + Irp->IoStatus.Information = sizeof(KSALLOCATOR_FRAMING); + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + } + + RtlStringFromGUID(&Property->Set, &GuidString); + DPRINT1("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); + RtlFreeUnicodeString(&GuidString); + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} + /* * @unimplemented */ @@ -322,6 +623,16 @@ IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { + PIO_STACK_LOCATION IoStack; + + IoStack = IoGetCurrentIrpStackLocation(Irp); + + if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) + { + return IPortPinWavePci_HandleKsProperty(iface, Irp); + } + + UNIMPLEMENTED
Irp->IoStatus.Information = 0; @@ -614,7 +925,6 @@
Packet = (PCONTEXT_WRITE)Buffer;
- if (This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue)) { Irp = Packet->Irp; @@ -669,7 +979,6 @@ NTSTATUS Status; PKSDATAFORMAT DataFormat; BOOL Capture; - KSALLOCATOR_FRAMING AllocatorFraming;
IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
@@ -693,14 +1002,6 @@
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; @@ -719,7 +1020,7 @@ &This->Stream, NULL, NonPagedPool, - This->WaveStream, + (PPORTWAVEPCISTREAM)&This->lpVtblPortWavePciStream, ConnectDetails->PinId, Capture, This->Format, @@ -746,9 +1047,7 @@ /* delay of 10 milisec */ This->Delay = Int32x32To64(10, -10000);
- This->IrpQueue = IPortWavePciStream_GetIrpQueue(This->WaveStream); - - Status = This->Stream->lpVtbl->GetAllocatorFraming(This->Stream, &AllocatorFraming); + Status = This->Stream->lpVtbl->GetAllocatorFraming(This->Stream, &This->AllocatorFraming); if (!NT_SUCCESS(Status)) { DPRINT1("GetAllocatorFraming failed with %x\n", Status); @@ -756,9 +1055,13 @@ }
DPRINT("OptionFlags %x RequirementsFlag %x PoolType %x Frames %lu FrameSize %lu FileAlignment %lu\n", - AllocatorFraming.OptionsFlags, AllocatorFraming.RequirementsFlags, AllocatorFraming.PoolType, AllocatorFraming.Frames, AllocatorFraming.FrameSize, AllocatorFraming.FileAlignment); - - Status = This->IrpQueue->lpVtbl->Init(This->IrpQueue, ConnectDetails, This->Format, DeviceObject, AllocatorFraming.FrameSize, AllocatorFraming.FileAlignment); + This->AllocatorFraming.OptionsFlags, This->AllocatorFraming.RequirementsFlags, This->AllocatorFraming.PoolType, This->AllocatorFraming.Frames, This->AllocatorFraming.FrameSize, This->AllocatorFraming.FileAlignment); + + Status = NewIrpQueue(&This->IrpQueue); + if (!NT_SUCCESS(Status)) + return Status; + + Status = This->IrpQueue->lpVtbl->Init(This->IrpQueue, ConnectDetails, This->Format, DeviceObject, This->AllocatorFraming.FrameSize, This->AllocatorFraming.FileAlignment); if (!NT_SUCCESS(Status)) { DPRINT1("IrpQueue_Init failed with %x\n", Status); @@ -835,6 +1138,7 @@ This->ref = 1; This->lpVtbl = &vt_IPortPinWavePci; This->lpVtblServiceSink = &vt_IServiceSink; + This->lpVtblPortWavePciStream = &vt_PortWavePciStream;
/* store result */
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c [iso-8859-1] Fri Jul 17 21:15:52 2009 @@ -45,6 +45,28 @@ } };
+DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterDMusTopologySet, TopologyPropertyHandler); +DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterDMusPinSet, PinPropertyHandler, PinPropertyHandler, PinPropertyHandler); + +KSPROPERTY_SET PortDMusPropertySet[] = +{ + { + &KSPROPSETID_Topology, + sizeof(PortFilterDMusTopologySet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PortFilterDMusTopologySet, + 0, + NULL + }, + { + &KSPROPSETID_Pin, + sizeof(PortFilterDMusPinSet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PortFilterDMusPinSet, + 0, + NULL + } +}; + + //--------------------------------------------------------------- // IUnknown interface functions // @@ -249,8 +271,8 @@ InterfaceGuids, 0, NULL, - 0, - NULL, + 2, + PortDMusPropertySet, 0, 0, 0,
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] Fri Jul 17 21:15:52 2009 @@ -30,6 +30,10 @@ PPCFILTER_DESCRIPTOR pDescriptor; PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor; IPortFilterWavePci * Filter; + + LIST_ENTRY EventList; + KSPIN_LOCK EventListLock; + }IPortWavePciImpl;
static GUID InterfaceGuids[3] = @@ -133,8 +137,14 @@ IPortEvents* iface, IN PKSEVENT_ENTRY EventEntry) { - UNIMPLEMENTED + KIRQL OldIrql; + IPortWavePciImpl * This = (IPortWavePciImpl*)CONTAINING_RECORD(iface, IPortWavePciImpl, lpVtblPortEvents); + ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + KeAcquireSpinLock(&This->EventListLock, &OldIrql); + InsertTailList(&This->EventList, &EventEntry->ListEntry); + KeReleaseSpinLock(&This->EventListLock, OldIrql); }
@@ -377,6 +387,8 @@ This->pDeviceObject = DeviceObject; This->bInitialized = TRUE; This->pResourceList = ResourceList; + InitializeListHead(&This->EventList); + KeInitializeSpinLock(&This->EventListLock);
/* increment reference on miniport adapter */ Miniport->lpVtbl->AddRef(Miniport);
Removed: 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 (removed) @@ -1,165 +1,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Kernel Streaming - * FILE: drivers/wdm/audio/backpln/portcls/port_wavepcistream.c - * PURPOSE: Wave PCI Stream object - * PROGRAMMER: Johannes Anderwald - */ - -#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) - { - This->Queue->lpVtbl->Release(This->Queue); - 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; - - ASSERT_IRQL(DISPATCH_LEVEL); - 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; - - ASSERT_IRQL(DISPATCH_LEVEL); - return This->Queue->lpVtbl->ReleaseMappingWithTag(This->Queue, Tag); -} - -static -NTSTATUS -NTAPI -IPortWavePciStream_fnTerminatePacket( - IN IPortWavePciStream *iface) -{ - UNIMPLEMENTED - ASSERT_IRQL(DISPATCH_LEVEL); - 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) -{ - IIrpQueue * Queue; - IPortWavePciStreamImpl * This; - NTSTATUS Status; - - Status = NewIrpQueue(&Queue); - if (!NT_SUCCESS(Status)) - 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; -} - -IIrpQueue* -NTAPI -IPortWavePciStream_GetIrpQueue( - IN IPortWavePciStream *iface) -{ - IPortWavePciStreamImpl * This = (IPortWavePciStreamImpl*)iface; - return This->Queue; -} -
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild [iso-8859-1] Fri Jul 17 21:15:52 2009 @@ -10,6 +10,7 @@ <library>drmk</library> <library>hal</library> <library>libcntpr</library> + <library>pseh</library> <file>adapter.c</file> <file>api.c</file> <file>connection.c</file> @@ -40,7 +41,6 @@ <file>port_topology.c</file> <file>port_wavecyclic.c</file> <file>port_wavepci.c</file> - <file>port_wavepcistream.c</file> <file>port_wavert.c</file> <file>port_wavertstream.c</file> <file>power.c</file>
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] Fri Jul 17 21:15:52 2009 @@ -278,16 +278,6 @@ PDEVICE_OBJECT GetDeviceObject( IPortWaveCyclic* iface); - -IIrpQueue* -NTAPI -IPortWavePciStream_GetIrpQueue( - IN IPortWavePciStream *iface); - -NTSTATUS -NTAPI -NewIPortWavePciStream( - OUT PPORTWAVEPCISTREAM *Stream);
VOID NTAPI
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wd... ============================================================================== --- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] Fri Jul 17 21:15:52 2009 @@ -597,6 +597,49 @@
NTSTATUS NTAPI +WdmAudFrameSize( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PWDMAUD_DEVICE_INFO DeviceInfo, + IN PWDMAUD_CLIENT ClientInfo) +{ + PFILE_OBJECT FileObject; + KSPROPERTY Property; + ULONG BytesReturned; + KSALLOCATOR_FRAMING Framing; + NTSTATUS Status; + + /* Get sysaudio pin file object */ + Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Invalid buffer handle %x\n", DeviceInfo->hDevice); + return SetIrpIoStatus(Irp, Status, 0); + } + + /* Setup get framing request */ + Property.Id = KSPROPERTY_CONNECTION_ALLOCATORFRAMING; + Property.Flags = KSPROPERTY_TYPE_GET; + Property.Set = KSPROPSETID_Connection; + + Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&Framing, sizeof(KSALLOCATOR_FRAMING), &BytesReturned); + /* Did we succeed */ + if (NT_SUCCESS(Status)) + { + /* Store framesize */ + DeviceInfo->u.FrameSize = Framing.FrameSize; + } + + /* Release file object */ + ObDereferenceObject(FileObject); + + return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO)); + +} + + +NTSTATUS +NTAPI WdmAudDeviceControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) @@ -647,8 +690,9 @@ return WdmAudCapabilities(DeviceObject, Irp, DeviceInfo, ClientInfo); case IOCTL_CLOSE_WDMAUD: return WdmAudIoctlClose(DeviceObject, Irp, DeviceInfo, ClientInfo); + case IOCTL_GETFRAMESIZE: + return WdmAudFrameSize(DeviceObject, Irp, DeviceInfo, ClientInfo); case IOCTL_GETPOS: - DPRINT1("IOCTL_GETPOS\n"); case IOCTL_GETDEVID: case IOCTL_GETVOLUME: case IOCTL_SETVOLUME: @@ -793,4 +837,3 @@ ObDereferenceObject(FileObject); return IoStatusBlock.Status; } -
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wd... ============================================================================== --- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h [iso-8859-1] Fri Jul 17 21:15:52 2009 @@ -43,6 +43,7 @@ ULONGLONG Position; KSSTATE State; ULONG Volume; + ULONG FrameSize; }u;
}WDMAUD_DEVICE_INFO, *PWDMAUD_DEVICE_INFO; @@ -212,7 +213,7 @@ /// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure, /// InputBufferSize is size of WDMAUD_DEVICE_INFO structure /// Note: The DeviceType and hDevice must be set -/// Result: The result is returned in Volume +/// Result: The result is returned in Position /// ReturnCode: STATUS_SUCCESS indicates success /// Prequsites: opened device
@@ -222,5 +223,22 @@ METHOD_BUFFERED, \ FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
+/// IOCTL_GETFRAMESIZE +/// +/// Description: This IOCTL retrieves the frame size requirements for an audio pin +/// +/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure, +/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure +/// Note: The DeviceType and hDevice must be set +/// Result: The result is returned in FrameSize +/// ReturnCode: STATUS_SUCCESS indicates success +/// Prequsites: opened device + +#define IOCTL_GETFRAMESIZE \ + CTL_CODE(FILE_DEVICE_SOUND, \ + 10, \ + METHOD_BUFFERED, \ + FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS) +
#endif
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/pin.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/... ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/pin.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/pin.c [iso-8859-1] Fri Jul 17 21:15:52 2009 @@ -128,9 +128,9 @@ { PDISPATCH_CONTEXT Context; PIO_STACK_LOCATION IoStack; - ULONG BytesReturned; PFILE_OBJECT FileObject; NTSTATUS Status; + ULONG BytesReturned;
/* Get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -159,20 +159,21 @@ return Status; }
- /* Re-dispatch the request to the real target pin */ + /* call the portcls audio pin */ Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_WRITE_STREAM, MmGetMdlVirtualAddress(Irp->MdlAddress), - IoStack->Parameters.Read.Length, + IoStack->Parameters.Write.Length, NULL, 0, &BytesReturned);
- /* release file object */ + + /* Release file object */ ObDereferenceObject(FileObject);
/* Save status and information */ Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = 0; + Irp->IoStatus.Information = BytesReturned; /* Complete the irp */ IoCompleteRequest(Irp, IO_NO_INCREMENT); /* Done */