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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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;
}