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;
 }


Reply via email to