Author: janderwald Date: Mon Oct 12 21:20:33 2009 New Revision: 43414 URL: http://svn.reactos.org/svn/reactos?rev=43414&view=rev Log: [PORTCLS] - Store MiniportStream & pin instance in subdevice descriptor - Simplify irp handling code in class IIrpStream - Rewrite CPortPinWaveCyclic code to handle property request. It now uses PcHandlePropertyWithTable, which calls the supported property request handlers via a callback. The code is now a lot cleaner as KsPropertyHandler peforms input & output length checks and also handles basic support requests - Implement a Audio position handler for CPortPinWaveCyclic - Use the IDmaChannel::CopyFrom when copying sound bytes from an dma buffer. Fixes recording of sound with KsStudio - Make sure that the GUID_NULL handler only adds guid which are not already present in the guid array. Fixes duplicate entries of properties of Nodes in KsStudio - Handle Basic Support requests in a default way when the driver doesnt provide a BasicSupport handler
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp trunk/reactos/drivers/wdm/audio/backpln/portcls/private.hpp trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp?rev=43414&r1=43413&r2=43414&view=diff ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp [iso-8859-1] Mon Oct 12 21:20:33 2009 @@ -215,6 +215,8 @@ LIST_ENTRY PhysicalConnectionList; UNICODE_STRING RefString; PUNKNOWN UnknownMiniport; + PUNKNOWN UnknownStream; + PVOID PortPin; }SUBDEVICE_DESCRIPTOR, *PSUBDEVICE_DESCRIPTOR; #undef INTERFACE Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp?rev=43414&r1=43413&r2=43414&view=diff ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp [iso-8859-1] Mon Oct 12 21:20:33 2009 @@ -111,41 +111,32 @@ // get current irp stack location IoStack = IoGetCurrentIrpStackLocation(Irp); - if (!Buffer) - { - if (!Irp->MdlAddress) + PC_ASSERT(!Buffer); + + if (!Irp->MdlAddress) + { + // ioctl from KsStudio + // Wdmaud already probes buffers, therefore no need to probe it again + // probe the stream irp + Status = KsProbeStreamIrp(Irp, KSSTREAM_READ | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_ALLOWFORMATCHANGE | KSPROBE_SYSTEMADDRESS, 0); + + // check for success + if (!NT_SUCCESS(Status)) { - // ioctl from KsStudio - // Wdmaud already probes buffers, therefore no need to probe it again - // probe the stream irp - Status = KsProbeStreamIrp(Irp, KSSTREAM_WRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_ALLOWFORMATCHANGE | KSPROBE_SYSTEMADDRESS, 0); - - // check for success - if (!NT_SUCCESS(Status)) - { - DPRINT1("KsProbeStreamIrp failed with %x\n", Status); - return Status; - } + DPRINT1("KsProbeStreamIrp failed with %x\n", Status); + return Status; } - // get the stream header - Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; - PC_ASSERT(Header); - PC_ASSERT(Irp->MdlAddress); - - DPRINT("Size %u DataUsed %u FrameExtent %u SizeHeader %u\n", Header->Size, Header->DataUsed, Header->FrameExtent, sizeof(KSSTREAM_HEADER)); - - if (Irp->RequestorMode != KernelMode) - { - // use allocated mdl - Header->Data = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); - PC_ASSERT(Header->Data); - } - } - else - { - // HACK - Header = (PKSSTREAM_HEADER)Buffer; - } + } + // get the stream header + Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; + PC_ASSERT(Header); + PC_ASSERT(Irp->MdlAddress); + + DPRINT1("Size %u DataUsed %u FrameExtent %u SizeHeader %u NumDataAvailable %u OutputLength %u\n", Header->Size, Header->DataUsed, Header->FrameExtent, sizeof(KSSTREAM_HEADER), m_NumDataAvailable, IoStack->Parameters.DeviceIoControl.OutputBufferLength); + + Header->Data = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); + PC_ASSERT(Header->Data); + //PC_ASSERT(Header->Size == IoStack->Parameters.DeviceIoControl.OutputBufferLength); // HACK Irp->Tail.Overlay.DriverContext[2] = (PVOID)Header; @@ -209,6 +200,8 @@ if (!Irp) { + DPRINT1("NoIrp\n"); + return STATUS_UNSUCCESSFUL; // no irp available, use silence buffer *Buffer = (PUCHAR)m_SilenceBuffer; *BufferSize = m_MaxFrameSize; Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp?rev=43414&r1=43413&r2=43414&view=diff ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp [iso-8859-1] Mon Oct 12 21:20:33 2009 @@ -698,7 +698,7 @@ DPRINT("CPortPinDMus::Init entered\n"); - m_Format = (PKSDATAFORMAT)ExAllocatePoolWithTag(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); + m_Format = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); if (!m_Format) return STATUS_INSUFFICIENT_RESOURCES; Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp?rev=43414&r1=43413&r2=43414&view=diff ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp [iso-8859-1] Mon Oct 12 21:20:33 2009 @@ -48,6 +48,9 @@ friend VOID NTAPI CloseStreamRoutineWaveCyclic(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context); friend VOID NTAPI SetStreamWorkerRoutineWaveCyclic(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context); + friend NTSTATUS NTAPI PinWaveCyclicState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); + friend NTSTATUS NTAPI PinWaveCyclicDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); + friend NTSTATUS NTAPI PinWaveCyclicAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); IPortWaveCyclic * m_Port; IPortFilterWaveCyclic * m_Filter; @@ -71,6 +74,8 @@ ULONG m_TotalPackets; ULONG m_StopCount; + KSAUDIO_POSITION m_Position; + SUBDEVICE_DESCRIPTOR m_Descriptor; ULONG m_Delay; @@ -85,6 +90,32 @@ KSSTATE State; }SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT; +NTSTATUS NTAPI PinWaveCyclicState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI PinWaveCyclicDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI PinWaveCyclicAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); + + +DEFINE_KSPROPERTY_CONNECTIONSET(PinWaveCyclicConnectionSet, PinWaveCyclicState, PinWaveCyclicDataFormat); +DEFINE_KSPROPERTY_AUDIOSET(PinWaveCyclicAudioSet, PinWaveCyclicAudioPosition); + +KSPROPERTY_SET PinWaveCyclicPropertySet[] = +{ + { + &KSPROPSETID_Connection, + sizeof(PinWaveCyclicConnectionSet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PinWaveCyclicConnectionSet, + 0, + NULL + }, + { + &KSPROPSETID_Audio, + sizeof(PinWaveCyclicAudioSet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PinWaveCyclicAudioSet, + 0, + NULL + } +}; + //================================================================================================================================== NTSTATUS @@ -111,6 +142,222 @@ } return STATUS_UNSUCCESSFUL; +} + + + +NTSTATUS +NTAPI +PinWaveCyclicAudioPosition( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + CPortPinWaveCyclic *Pin; + PSUBDEVICE_DESCRIPTOR Descriptor; + + // get sub device descriptor + Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); + + // sanity check + PC_ASSERT(Descriptor); + PC_ASSERT(Descriptor->PortPin); + PC_ASSERT_IRQL(DISPATCH_LEVEL); + + // cast to pin impl + Pin = (CPortPinWaveCyclic*)Descriptor->PortPin; + + //sanity check + PC_ASSERT(Pin->m_Stream); + + if (Request->Flags & KSPROPERTY_TYPE_GET) + { + // FIXME non multithreading-safe + // copy audio position + RtlMoveMemory(Data, &Pin->m_Position, sizeof(KSAUDIO_POSITION)); + + DPRINT1("Play %lu Record %lu\n", Pin->m_Position.PlayOffset, Pin->m_Position.WriteOffset); + Irp->IoStatus.Information = sizeof(KSAUDIO_POSITION); + return STATUS_SUCCESS; + } + + // not supported + return STATUS_NOT_SUPPORTED; +} + + +NTSTATUS +NTAPI +PinWaveCyclicState( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + NTSTATUS Status = STATUS_UNSUCCESSFUL; + CPortPinWaveCyclic *Pin; + PSUBDEVICE_DESCRIPTOR Descriptor; + PKSSTATE State = (PKSSTATE)Data; + + // get sub device descriptor + Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); + + // sanity check + PC_ASSERT(Descriptor); + PC_ASSERT(Descriptor->PortPin); + PC_ASSERT_IRQL(DISPATCH_LEVEL); + + // cast to pin impl + Pin = (CPortPinWaveCyclic*)Descriptor->PortPin; + + //sanity check + PC_ASSERT(Pin->m_Stream); + + if (Request->Flags & KSPROPERTY_TYPE_SET) + { + // try set stream + Status = Pin->m_Stream->SetState(*State); + + DPRINT("Setting state %u %x\n", *State, Status); + if (NT_SUCCESS(Status)) + { + // store new state + Pin->m_State = *State; + } + // store result + Irp->IoStatus.Information = sizeof(KSSTATE); + return Status; + } + else if (Request->Flags & KSPROPERTY_TYPE_GET) + { + // get current stream state + *State = Pin->m_State; + // store result + Irp->IoStatus.Information = sizeof(KSSTATE); + + return STATUS_SUCCESS; + } + + // unsupported request + return STATUS_NOT_SUPPORTED; +} + +NTSTATUS +NTAPI +PinWaveCyclicDataFormat( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + NTSTATUS Status = STATUS_UNSUCCESSFUL; + CPortPinWaveCyclic *Pin; + PSUBDEVICE_DESCRIPTOR Descriptor; + PIO_STACK_LOCATION IoStack; + + // get current irp stack location + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // get sub device descriptor + Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); + + // sanity check + PC_ASSERT(Descriptor); + PC_ASSERT(Descriptor->PortPin); + + // cast to pin impl + Pin = (CPortPinWaveCyclic*)Descriptor->PortPin; + + //sanity check + PC_ASSERT(Pin->m_Stream); + PC_ASSERT(Pin->m_Format); + + if (Request->Flags & KSPROPERTY_TYPE_SET) + { + // try to change data format + PKSDATAFORMAT NewDataFormat, DataFormat = (PKSDATAFORMAT)Irp->UserBuffer; + ULONG Size = min(Pin->m_Format->FormatSize, DataFormat->FormatSize); + + if (RtlCompareMemory(DataFormat, Pin->m_Format, Size) == Size) + { + // format is identical + Irp->IoStatus.Information = DataFormat->FormatSize; + return STATUS_SUCCESS; + } + + // new change request + PC_ASSERT(Pin->m_State == KSSTATE_STOP); + // FIXME queue a work item when Irql != PASSIVE_LEVEL + PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); + + // allocate new data format + NewDataFormat = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); + if (!NewDataFormat) + { + // not enough memory + return STATUS_NO_MEMORY; + } + + // copy new data format + RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize); + + // set new format + Status = Pin->m_Stream->SetFormat(NewDataFormat); + if (NT_SUCCESS(Status)) + { + // free old format + FreeItem(Pin->m_Format, TAG_PORTCLASS); + + // update irp queue with new format + Pin->m_IrpQueue->UpdateFormat((PKSDATAFORMAT)NewDataFormat); + + // store new format + Pin->m_Format = NewDataFormat; + Irp->IoStatus.Information = NewDataFormat->FormatSize; + +#if 0 + PC_ASSERT(NewDataFormat->FormatSize == sizeof(KSDATAFORMAT_WAVEFORMATEX)); + PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.MajorFormat, KSDATAFORMAT_TYPE_AUDIO)); + PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.SubFormat, KSDATAFORMAT_SUBTYPE_PCM)); + PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.Specifier, KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)); + + + DPRINT1("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nChannels, + ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.wBitsPerSample, + ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nSamplesPerSec); +#endif + + } + else + { + // failed to set format + FreeItem(NewDataFormat, TAG_PORTCLASS); + } + + + // done + return Status; + } + else if (Request->Flags & KSPROPERTY_TYPE_GET) + { + // get current data format + PC_ASSERT(Pin->m_Format); + + if (Pin->m_Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength) + { + // buffer too small + Irp->IoStatus.Information = Pin->m_Format->FormatSize; + return STATUS_MORE_ENTRIES; + } + // copy data format + RtlMoveMemory(Data, Pin->m_Format, Pin->m_Format->FormatSize); + // store result size + Irp->IoStatus.Information = Pin->m_Format->FormatSize; + + // done + return STATUS_SUCCESS; + } + + // unsupported request + return STATUS_NOT_SUPPORTED; } @@ -138,7 +385,7 @@ if (m_Capture) { - m_DmaChannel->CopyTo(Buffer, (PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BytesToCopy); + m_DmaChannel->CopyFrom(Buffer, (PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BytesToCopy); } else { @@ -149,6 +396,7 @@ m_CommonBufferOffset += BytesToCopy; BufferLength = Position - m_CommonBufferOffset; + m_Position.PlayOffset += BytesToCopy; } } @@ -174,9 +422,9 @@ BytesToCopy = min(BufferLength, BufferSize); - if (m_Capture) - { - m_DmaChannel->CopyTo(Buffer, + if (m_Capture) + { + m_DmaChannel->CopyFrom(Buffer, (PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BytesToCopy); } @@ -189,6 +437,7 @@ m_IrpQueue->UpdateMapping(BytesToCopy); m_CommonBufferOffset += BytesToCopy; + m_Position.PlayOffset += BytesToCopy; BufferLength = m_CommonBufferSize - m_CommonBufferOffset; } @@ -330,7 +579,7 @@ } Status = m_Stream->GetPosition(&Position); - DPRINT("Position %u Buffer %p BufferSize %u ActiveIrpOffset %u\n", Position, Buffer, m_CommonBufferSize, BufferSize); + DPRINT1("Position %u Buffer %p BufferSize %u ActiveIrpOffset %u Capture %u\n", Position, Buffer, m_CommonBufferSize, BufferSize, m_Capture); if (Position < m_CommonBufferOffset) { @@ -372,203 +621,36 @@ DPRINT("IPortPinWave_HandleKsProperty entered\n"); - if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY)) - { - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + IoStack = IoGetCurrentIrpStackLocation(Irp); + + if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY) + { + DPRINT1("Unhandled function %lx Length %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength); + + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_INVALID_PARAMETER; - } - - Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; - - if (IsEqualGUIDAligned(Property->Set, GUID_NULL)) - { - if (Property->Flags & KSPROPERTY_TYPE_SETSUPPORT) - { - if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GUID)) - { - // buffer too small - Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; - Irp->IoStatus.Information = sizeof(GUID); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_BUFFER_OVERFLOW; - } - // FIXME copy guids - // KSPROPSETID_Audio when available - // KSPROPSETID_Sysaudio_Pin - - RtlMoveMemory(Irp->UserBuffer, &KSPROPSETID_Connection, sizeof(GUID)); - - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = sizeof(GUID); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_SUCCESS; - } - } - - - if (IsEqualGUIDAligned(Property->Set, KSPROPSETID_Connection)) - { - if (Property->Id == KSPROPERTY_CONNECTION_STATE) - { - PKSSTATE State = (PKSSTATE)Irp->UserBuffer; - - PC_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 (m_Stream) - { - Status = m_Stream->SetState(*State); - - DPRINT1("Setting state %u %x\n", *State, Status); - if (NT_SUCCESS(Status)) - { - m_State = *State; - } - } - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return Status; - } - else if (Property->Flags & KSPROPERTY_TYPE_GET) - { - *State = m_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, m_Format, DataFormat->FormatSize)) - { - Irp->IoStatus.Information = DataFormat->FormatSize; - Irp->IoStatus.Status = STATUS_SUCCESS; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; - } - - NewDataFormat = (PKSDATAFORMAT)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 (m_Stream) - { - PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); - PC_ASSERT(NewDataFormat->FormatSize == sizeof(KSDATAFORMAT_WAVEFORMATEX)); - PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.MajorFormat, KSDATAFORMAT_TYPE_AUDIO)); - PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.SubFormat, KSDATAFORMAT_SUBTYPE_PCM)); - PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.Specifier, KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)); - - PC_ASSERT(m_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 = m_Stream->SetFormat(NewDataFormat); - if (NT_SUCCESS(Status)) - { - if (m_Format) - ExFreePoolWithTag(m_Format, TAG_PORTCLASS); - - m_IrpQueue->UpdateFormat((PKSDATAFORMAT)NewDataFormat); - m_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 (!m_Format) - { - DPRINT1("No format\n"); - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; - } - if (m_Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength) - { - Irp->IoStatus.Information = m_Format->FormatSize; - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_BUFFER_TOO_SMALL; - } - - RtlMoveMemory(DataFormat, m_Format, m_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; - - PC_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 = m_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); - RtlFreeUnicodeString(&GuidString); - - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_NOT_IMPLEMENTED; + return STATUS_SUCCESS; + } + + Status = PcHandlePropertyWithTable(Irp, m_Descriptor.FilterPropertySetCount, m_Descriptor.FilterPropertySet, &m_Descriptor); + + if (Status == STATUS_NOT_FOUND) + { + Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + + RtlStringFromGUID(Property->Set, &GuidString); + DPRINT1("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); + RtlFreeUnicodeString(&GuidString); + } + + if (Status != STATUS_PENDING) + { + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + + return Status; } NTSTATUS @@ -576,11 +658,26 @@ CPortPinWaveCyclic::HandleKsStream( IN PIRP Irp) { + NTSTATUS Status; InterlockedIncrement((PLONG)&m_TotalPackets); DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData()); - m_IrpQueue->AddMapping(NULL, 0, Irp); + Status = m_IrpQueue->AddMapping(NULL, 0, Irp); + + if (NT_SUCCESS(Status)) + { + + PKSSTREAM_HEADER Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; + PC_ASSERT(Header); + + if (m_Capture) + m_Position.WriteOffset += Header->FrameExtent; + else + m_Position.WriteOffset += Header->DataUsed; + + } + return STATUS_PENDING; } @@ -918,10 +1015,39 @@ } #endif - DPRINT("CPortPinWaveCyclic::Init Status %x\n", Status); - if (!NT_SUCCESS(Status)) return Status; + + ISubdevice * Subdevice = NULL; + // get subdevice interface + Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&Subdevice); + + if (!NT_SUCCESS(Status)) + return Status; + + PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor = NULL; + + Status = Subdevice->GetDescriptor(&SubDeviceDescriptor); + if (!NT_SUCCESS(Status)) + { + // failed to get descriptor + Subdevice->Release(); + return Status; + } + + /* set up subdevice descriptor */ + RtlZeroMemory(&m_Descriptor, sizeof(SUBDEVICE_DESCRIPTOR)); + m_Descriptor.FilterPropertySet = PinWaveCyclicPropertySet; + m_Descriptor.FilterPropertySetCount = sizeof(PinWaveCyclicPropertySet) / sizeof(KSPROPERTY_SET); + m_Descriptor.UnknownStream = (PUNKNOWN)m_Stream; + m_Descriptor.DeviceDescriptor = SubDeviceDescriptor->DeviceDescriptor; + m_Descriptor.UnknownMiniport = SubDeviceDescriptor->UnknownMiniport; + m_Descriptor.PortPin = (PVOID)this; + + DPRINT("CPortPinWaveCyclic::Init Status %x\n", Status); + + // release subdevice descriptor + Subdevice->Release(); Status = m_ServiceGroup->AddMember(PSERVICESINK(this)); if (!NT_SUCCESS(Status)) @@ -955,7 +1081,7 @@ return Status; } - m_Format = (PKSDATAFORMAT)ExAllocatePoolWithTag(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); + m_Format = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); if (!m_Format) return STATUS_INSUFFICIENT_RESOURCES; @@ -972,7 +1098,6 @@ DPRINT1("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE)); m_State = KSSTATE_PAUSE; - //m_ServiceGroup->RequestDelayedService(m_Delay); return STATUS_SUCCESS; } Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp?rev=43414&r1=43413&r2=43414&view=diff ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp [iso-8859-1] Mon Oct 12 21:20:33 2009 @@ -751,7 +751,7 @@ DPRINT("IPortPinWavePci_fnInit entered\n"); - m_Format = (PKSDATAFORMAT)ExAllocatePoolWithTag(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); + m_Format = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); if (!m_Format) return STATUS_INSUFFICIENT_RESOURCES; Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/private.hpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/private.hpp?rev=43414&r1=43413&r2=43414&view=diff ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/private.hpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/private.hpp [iso-8859-1] Mon Oct 12 21:20:33 2009 @@ -313,6 +313,31 @@ IN ULONG PropertySetCount, IN PKSPROPERTY_SET PropertySet, IN PSUBDEVICE_DESCRIPTOR Descriptor); + +#define DEFINE_KSPROPERTY_CONNECTIONSET(PinSet,\ + PropStateHandler, PropDataFormatHandler)\ +DEFINE_KSPROPERTY_TABLE(PinSet) {\ + DEFINE_KSPROPERTY_ITEM_CONNECTION_STATE(PropStateHandler, PropStateHandler),\ + DEFINE_KSPROPERTY_ITEM_CONNECTION_DATAFORMAT(PropDataFormatHandler, PropDataFormatHandler)\ +} + +#define DEFINE_KSPROPERTY_ITEM_AUDIO_POSITION(GetHandler, SetHandler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_AUDIO_POSITION,\ + (GetHandler),\ + sizeof(KSPROPERTY),\ + sizeof(KSAUDIO_POSITION),\ + (SetHandler),\ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_AUDIOSET(PinSet,\ + PropPositionHandler)\ +DEFINE_KSPROPERTY_TABLE(PinSet) {\ + DEFINE_KSPROPERTY_ITEM_AUDIO_POSITION(PropPositionHandler, PropPositionHandler)\ +} + + + #define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet,\ PropGeneral, PropInstances, PropIntersection)\ Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp?rev=43414&r1=43413&r2=43414&view=diff ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp [iso-8859-1] Mon Oct 12 21:20:33 2009 @@ -101,29 +101,50 @@ PC_ASSERT(Node->AutomationTable->PropertyCount); PC_ASSERT(Node->AutomationTable->PropertyItemSize); - Irp->IoStatus.Information = sizeof(GUID) * Node->AutomationTable->PropertyCount; - if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GUID) * Node->AutomationTable->PropertyCount) - { - // buffer too small - return STATUS_MORE_ENTRIES; - } - + Buffer = (LPGUID)AllocateItem(NonPagedPool, sizeof (GUID) * Node->AutomationTable->PropertyCount, TAG_PORTCLASS); + if (!Buffer) + return STATUS_INSUFFICIENT_RESOURCES; + + + ULONG Count = 0, SubIndex; PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties; - Buffer = (LPGUID)Irp->UserBuffer; - - for(Index = 0; Index < Node->AutomationTable->PropertyCount; Index++) - { - RtlMoveMemory(Buffer, PropertyItem->Set, sizeof(GUID)); - Buffer++; - + for (Index = 0; Index < Node->AutomationTable->PropertyCount; Index++) + { + BOOL Found = FALSE; + for (SubIndex = 0; SubIndex < Count; Index++) + { + if (IsEqualGUIDAligned(Buffer[SubIndex], *PropertyItem->Set)) + { + Found = TRUE; + break; + } + } + if (!Found) + { + RtlMoveMemory(&Buffer[Count], PropertyItem->Set, sizeof (GUID)); + Count++; + } PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize); } + + Irp->IoStatus.Information = sizeof (GUID) * Count; + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GUID) * Count) + { + // buffer too small + FreeItem(Buffer, TAG_PORTCLASS); + return STATUS_MORE_ENTRIES; + } + + RtlMoveMemory(Irp->UserBuffer, Buffer, sizeof (GUID) * Count); + FreeItem(Buffer, TAG_PORTCLASS); return STATUS_SUCCESS; } else /*if (Property->Property.Flags == (KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_TOPOLOGY) || Property->Property.Flags == (KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY) || Property->Property.Flags == (KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY)) */ { + //UNICODE_STRING GuidString; + if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount) { // request is out of bounds @@ -137,7 +158,7 @@ { // request is out of bounds Irp->IoStatus.Information = 0; - return STATUS_INVALID_PARAMETER; + return STATUS_NOT_FOUND; } PC_ASSERT(Node->AutomationTable); @@ -145,19 +166,56 @@ PC_ASSERT(Node->AutomationTable->PropertyItemSize); PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties; - //Flags = (PULONG)Irp->UserBuffer; for(Index = 0; Index < Node->AutomationTable->PropertyCount; Index++) { if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Property.Set) && PropertyItem->Id == Property->Property.Id) { + if (Property->Property.Flags & KSPROPERTY_TYPE_BASICSUPPORT) + { + if (!(PropertyItem->Flags & KSPROPERTY_TYPE_BASICSUPPORT)) + { + PC_ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(ULONG)); + PULONG Flags = (PULONG)Irp->UserBuffer; + + /* reset flags */ + *Flags = 0; + + if (PropertyItem->Flags & KSPROPERTY_TYPE_SET) + *Flags |= KSPROPERTY_TYPE_SET; + + if (PropertyItem->Flags & KSPROPERTY_TYPE_GET) + *Flags |= KSPROPERTY_TYPE_GET; + + Irp->IoStatus.Information = sizeof(ULONG); + + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION)) + { + /* get output buffer */ + PKSPROPERTY_DESCRIPTION Description = (PKSPROPERTY_DESCRIPTION)Irp->UserBuffer; + + /* store result */ + Description->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION); + Description->PropTypeSet.Set = KSPROPTYPESETID_General; + Description->PropTypeSet.Id = 0; + Description->PropTypeSet.Flags = 0; + Description->MembersListCount = 0; + Description->Reserved = 0; + + Irp->IoStatus.Information = sizeof(KSPROPERTY_DESCRIPTION); + } + return STATUS_SUCCESS; + } + } + + PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS); if (!PropertyRequest) return STATUS_INSUFFICIENT_RESOURCES; PC_ASSERT(SubDeviceDescriptor->UnknownMiniport); PropertyRequest->MajorTarget = SubDeviceDescriptor->UnknownMiniport; - //PropertyRequest->MinorTarget = (PUNKNOWN)0xABADCAFE; + PropertyRequest->MinorTarget = SubDeviceDescriptor->UnknownStream; PropertyRequest->Irp = Irp; PropertyRequest->Node = Property->NodeId; PropertyRequest->PropertyItem = PropertyItem; @@ -176,20 +234,21 @@ Irp->IoStatus.Information = PropertyRequest->ValueSize; ExFreePool(PropertyRequest); } +#if 0 + RtlStringFromGUID(Property->Property.Set, &GuidString); + DPRINT1("Id %u Flags %x Set %S FlagsItem %x Status %x\n", Property->Property.Id, Property->Property.Flags, GuidString.Buffer, PropertyItem->Flags, Status); + RtlFreeUnicodeString(&GuidString); +#endif return Status; } PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize); } +#if 0 + RtlStringFromGUID(Property->Property.Set, &GuidString); + DPRINT1("Id %u Flags %x Set %S Status %x\n", Property->Property.Id, Property->Property.Flags, GuidString.Buffer, Status); + RtlFreeUnicodeString(&GuidString); +#endif } -#if 0 - else - { - UNICODE_STRING GuidString; - RtlStringFromGUID(Property->Property.Set, &GuidString); - DPRINT1("Id %u Flags %x Set %S\n", Property->Property.Id, Property->Property.Flags, GuidString.Buffer); - DbgBreakPoint(); - } -#endif } return Status; }