[ros-diffs] [janderwald] 39992: - Disable some debug prints - Close the real pin on exit / when a new wave stream is played. This should fix stuttering when changing the sample rate - Always create the mixer pin

janderwald at svn.reactos.org janderwald at svn.reactos.org
Thu Mar 12 23:11:54 CET 2009


Author: janderwald
Date: Fri Mar 13 01:11:53 2009
New Revision: 39992

URL: http://svn.reactos.org/svn/reactos?rev=39992&view=rev
Log:
- Disable some debug prints
- Close the real pin on exit / when a new wave stream is played. This should fix stuttering when changing the sample rate
- Always create the mixer pin

Modified:
    trunk/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c
    trunk/reactos/drivers/wdm/audio/filters/kmixer/pin.c
    trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c
    trunk/reactos/drivers/wdm/audio/sysaudio/control.c
    trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c
    trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c?rev=39992&r1=39991&r2=39992&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c [iso-8859-1] Fri Mar 13 01:11:53 2009
@@ -10,7 +10,7 @@
     IIrpTarget * IrpTarget;
     PKSOBJECT_CREATE_ITEM CreateItem;
 
-    DPRINT1("Dispatch_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
+    //DPRINT1("Dispatch_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
 
     /* access the create item */
     CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
@@ -114,7 +114,7 @@
 
     IrpTarget = (IIrpTarget*)CreateItem->Context;
 
-    DPRINT1("IrpTarget %p\n", IrpTarget);
+    //DPRINT1("IrpTarget %p\n", IrpTarget);
 
     return IrpTarget->lpVtbl->Close(IrpTarget, DeviceObject, Irp);
 }

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c?rev=39992&r1=39991&r2=39992&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1] Fri Mar 13 01:11:53 2009
@@ -15,6 +15,7 @@
     PMINIPORTWAVECYCLICSTREAM Stream;
     KSSTATE State;
     PKSDATAFORMAT Format;
+    KSPIN_CONNECT * ConnectDetails;
 
     PVOID CommonBuffer;
     ULONG CommonBufferSize;
@@ -184,8 +185,8 @@
         }
         DPRINT1("Stopping %u\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue));
 
-        This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_PAUSE);
-        This->State = KSSTATE_PAUSE;
+        This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP);
+        This->State = KSSTATE_STOP;
         return;
     }
 
@@ -306,7 +307,7 @@
 
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
-    DPRINT1("IPortPinWave_HandleKsProperty entered\n");
+    //DPRINT1("IPortPinWave_HandleKsProperty entered\n");
 
     if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY))
     {
@@ -365,7 +366,16 @@
             PKSDATAFORMAT DataFormat = (PKSDATAFORMAT)Irp->UserBuffer;
             if (Property->Flags & KSPROPERTY_TYPE_SET)
             {
-                PKSDATAFORMAT NewDataFormat = AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS);
+                PKSDATAFORMAT NewDataFormat;
+                if (!RtlCompareMemory(DataFormat, This->Format, DataFormat->FormatSize))
+                {
+                    Irp->IoStatus.Information = DataFormat->FormatSize;
+                    Irp->IoStatus.Status = STATUS_SUCCESS;
+                    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                    return STATUS_SUCCESS;
+                }
+
+                NewDataFormat = AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS);
                 if (!NewDataFormat)
                 {
                     Irp->IoStatus.Information = 0;
@@ -377,11 +387,18 @@
 
                 if (This->Stream)
                 {
+                    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
+                    ASSERT(NewDataFormat->FormatSize == sizeof(KSDATAFORMAT_WAVEFORMATEX));
+                    ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.MajorFormat, &KSDATAFORMAT_TYPE_AUDIO));
+                    ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM));
+                    ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX));
+
                     Status = This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP);
+                    ASSERT(Status == STATUS_SUCCESS);
                     This->State = KSSTATE_STOP;
-                    DPRINT1("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)DataFormat)->WaveFormatEx.nChannels,
-                                                                                 ((PKSDATAFORMAT_WAVEFORMATEX)DataFormat)->WaveFormatEx.wBitsPerSample,
-                                                                                 ((PKSDATAFORMAT_WAVEFORMATEX)DataFormat)->WaveFormatEx.nSamplesPerSec);
+                    DPRINT1("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nChannels,
+                                                                                 ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.wBitsPerSample,
+                                                                                 ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nSamplesPerSec);
 
                     Status = This->Stream->lpVtbl->SetFormat(This->Stream, NewDataFormat);
                     if (NT_SUCCESS(Status))
@@ -399,7 +416,6 @@
 
                 }
                 DPRINT1("Failed to set format\n");
-DbgBreakPoint();
                 Irp->IoStatus.Information = 0;
                 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
                 IoCompleteRequest(Irp, IO_NO_INCREMENT);
@@ -549,8 +565,20 @@
     return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
 }
 
-/*
- * @unimplemented
+VOID
+NTAPI
+CloseStreamRoutine(
+    IN PDEVICE_OBJECT  DeviceObject,
+    IN PVOID  Context)
+{
+    PMINIPORTWAVECYCLICSTREAM Stream = (PMINIPORTWAVECYCLICSTREAM)Context;
+
+    DPRINT("CloseStreamRoutine %p\n", Stream);
+    Stream->lpVtbl->Release(Stream);
+}
+
+/*
+ * @implemented
  */
 NTSTATUS
 NTAPI
@@ -559,9 +587,50 @@
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp)
 {
+    ISubdevice *ISubDevice;
+    NTSTATUS Status;
+    SUBDEVICE_DESCRIPTOR * Descriptor;
+    PIO_WORKITEM WorkItem;
+
+    IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
     DPRINT1("IPortPinWaveCyclic_fnClose\n");
 
-    //FIXME
+    Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&ISubDevice);
+    if (NT_SUCCESS(Status))
+    {
+        Status = ISubDevice->lpVtbl->GetDescriptor(ISubDevice, &Descriptor);
+        if (NT_SUCCESS(Status))
+        {
+            ISubDevice->lpVtbl->Release(ISubDevice);
+            Descriptor->Factory.Instances[This->ConnectDetails->PinId].CurrentPinInstanceCount--;
+            DPRINT1("InstanceCount %u\n", Descriptor->Factory.Instances[This->ConnectDetails->PinId].CurrentPinInstanceCount);
+        }
+    }
+
+
+    if (This->Stream)
+    {
+        This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP);
+    }
+
+    This->ServiceGroup->lpVtbl->RemoveMember(This->ServiceGroup, (PSERVICESINK)&This->lpVtblServiceSink);
+    This->ServiceGroup->lpVtbl->Release(This->ServiceGroup);
+    This->DmaChannel->lpVtbl->Release(This->DmaChannel);
+
+    if (This->Format)
+        ExFreePool(This->Format);
+
+    This->IrpQueue->lpVtbl->Release(This->IrpQueue);
+
+
+    if (This->Stream)
+    {
+        WorkItem = IoAllocateWorkItem(DeviceObject);
+        if (WorkItem)
+        {
+            IoQueueWorkItem(WorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)This->Stream);
+        }
+    }
 
     Irp->IoStatus.Information = 0;
     Irp->IoStatus.Status = STATUS_SUCCESS;
@@ -716,6 +785,7 @@
     This->Port = Port;
     This->Filter = Filter;
     This->KsPinDescriptor = KsPinDescriptor;
+    This->ConnectDetails = ConnectDetails;
     This->Miniport = GetWaveCyclicMiniport(Port);
 
     DeviceObject = GetDeviceObject(Port);

Modified: trunk/reactos/drivers/wdm/audio/filters/kmixer/pin.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/filters/kmixer/pin.c?rev=39992&r1=39991&r2=39992&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/filters/kmixer/pin.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/filters/kmixer/pin.c [iso-8859-1] Fri Mar 13 01:11:53 2009
@@ -163,42 +163,32 @@
     PIRP Irp)
 {
     PIO_STACK_LOCATION IoStack;
-    PKSPROPERTY Property;
-    DPRINT1("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
+    PKSP_PIN Property;
+    //DPRINT1("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
 
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
-    if (IoStack->Parameters.DeviceIoControl.InputBufferLength == sizeof(KSPROPERTY) && IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(KSDATAFORMAT_WAVEFORMATEX))
-    {
-        Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
-
-        if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Connection))
+    if (IoStack->Parameters.DeviceIoControl.InputBufferLength == sizeof(KSP_PIN) && IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(KSDATAFORMAT_WAVEFORMATEX))
+    {
+        Property = (PKSP_PIN)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
+
+        if (IsEqualGUIDAligned(&Property->Property.Set, &KSPROPSETID_Connection))
         {
-            if (Property->Id == KSPROPERTY_CONNECTION_DATAFORMAT && Property->Flags == KSPROPERTY_TYPE_SET)
+            if (Property->Property.Id == KSPROPERTY_CONNECTION_DATAFORMAT && Property->Property.Flags == KSPROPERTY_TYPE_SET)
             {
-                PKSDATAFORMAT_WAVEFORMATEX WaveFormat2;
-                PKSDATAFORMAT_WAVEFORMATEX WaveFormat = ExAllocatePool(NonPagedPool, sizeof(KSDATAFORMAT_WAVEFORMATEX));
-
-                if (!WaveFormat)
-                {
-                    Irp->IoStatus.Information = 0;
-                    Irp->IoStatus.Status = STATUS_NO_MEMORY;
-                    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-                    return STATUS_NO_MEMORY;
-                }
-
-                if (IoStack->FileObject->FsContext2)
-                {
-                    ExFreePool(IoStack->FileObject->FsContext2);
-                }
-
-                WaveFormat2 = (PKSDATAFORMAT_WAVEFORMATEX)Irp->UserBuffer;
-                WaveFormat->WaveFormatEx.nChannels = WaveFormat2->WaveFormatEx.nChannels;
-                WaveFormat->WaveFormatEx.nSamplesPerSec = WaveFormat2->WaveFormatEx.nSamplesPerSec;
-                WaveFormat->WaveFormatEx.wBitsPerSample = WaveFormat2->WaveFormatEx.wBitsPerSample;
-
-                IoStack->FileObject->FsContext2 = (PVOID)WaveFormat;
-
+                PKSDATAFORMAT_WAVEFORMATEX Formats;
+                PKSDATAFORMAT_WAVEFORMATEX WaveFormat;
+
+                Formats = (PKSDATAFORMAT_WAVEFORMATEX)IoStack->FileObject->FsContext2;
+                WaveFormat = (PKSDATAFORMAT_WAVEFORMATEX)Irp->UserBuffer;
+
+                ASSERT(Property->PinId == 0 || Property->PinId == 1);
+                ASSERT(Formats);
+                ASSERT(WaveFormat);
+
+                Formats[Property->PinId].WaveFormatEx.nChannels = WaveFormat->WaveFormatEx.nChannels;
+                Formats[Property->PinId].WaveFormatEx.wBitsPerSample = WaveFormat->WaveFormatEx.wBitsPerSample;
+                Formats[Property->PinId].WaveFormatEx.nSamplesPerSec = WaveFormat->WaveFormatEx.nSamplesPerSec;
 
                 Irp->IoStatus.Information = 0;
                 Irp->IoStatus.Status = STATUS_SUCCESS;
@@ -207,7 +197,7 @@
             }
         }
     }
-
+    DPRINT1("Size %u Expected %u\n",IoStack->Parameters.DeviceIoControl.OutputBufferLength,  sizeof(KSDATAFORMAT_WAVEFORMATEX));
     Irp->IoStatus.Information = 0;
     Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
@@ -365,54 +355,34 @@
     PIO_STATUS_BLOCK IoStatus,
     PDEVICE_OBJECT DeviceObject)
 {
-    PKSPIN_CONNECT ConnectDetails;
     PKSSTREAM_HEADER StreamHeader;
     PVOID BufferOut;
     ULONG BufferLength;
     NTSTATUS Status = STATUS_SUCCESS;
-    LPWSTR PinName = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}\\";
-
-    PKSDATAFORMAT_WAVEFORMATEX BaseFormat, TransformedFormat;
+    PKSDATAFORMAT_WAVEFORMATEX Formats;
+    PKSDATAFORMAT_WAVEFORMATEX InputFormat, OutputFormat;
 
     //DPRINT1("Pin_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject);
 
-
-    BaseFormat = (PKSDATAFORMAT_WAVEFORMATEX)FileObject->FsContext2;
-    if (!BaseFormat)
-    {
-        DPRINT1("Expected DataFormat\n");
-        DbgBreakPoint();
-        IoStatus->Status = STATUS_UNSUCCESSFUL;
-        IoStatus->Information = 0;
-        return FALSE;
-    }
-
-    if (FileObject->FileName.Length < wcslen(PinName) + sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT))
-    {
-        DPRINT1("Expected DataFormat\n");
-        DbgBreakPoint();
-        IoStatus->Status = STATUS_INVALID_PARAMETER;
-        IoStatus->Information = 0;
-        return FALSE;
-    }
-
-    ConnectDetails = (PKSPIN_CONNECT)(FileObject->FileName.Buffer + wcslen(PinName));
-    TransformedFormat = (PKSDATAFORMAT_WAVEFORMATEX)(ConnectDetails + 1);
+    Formats = (PKSDATAFORMAT_WAVEFORMATEX)FileObject->FsContext2;
+
+    InputFormat = Formats;
+    OutputFormat = (Formats + 1);
     StreamHeader = (PKSSTREAM_HEADER)Buffer;
 
 #if 0
     DPRINT1("Num Channels %u Old Channels %u\n SampleRate %u Old SampleRate %u\n BitsPerSample %u Old BitsPerSample %u\n",
-               BaseFormat->WaveFormatEx.nChannels, TransformedFormat->WaveFormatEx.nChannels,
-               BaseFormat->WaveFormatEx.nSamplesPerSec, TransformedFormat->WaveFormatEx.nSamplesPerSec,
-               BaseFormat->WaveFormatEx.wBitsPerSample, TransformedFormat->WaveFormatEx.wBitsPerSample);
-#endif
-
-    if (BaseFormat->WaveFormatEx.wBitsPerSample != TransformedFormat->WaveFormatEx.wBitsPerSample)
+               InputFormat->WaveFormatEx.nChannels, OutputFormat->WaveFormatEx.nChannels,
+               InputFormat->WaveFormatEx.nSamplesPerSec, OutputFormat->WaveFormatEx.nSamplesPerSec,
+               InputFormat->WaveFormatEx.wBitsPerSample, OutputFormat->WaveFormatEx.wBitsPerSample);
+#endif
+
+    if (InputFormat->WaveFormatEx.wBitsPerSample != OutputFormat->WaveFormatEx.wBitsPerSample)
     {
         Status = PerformQualityConversion(StreamHeader->Data,
                                           StreamHeader->DataUsed,
-                                          BaseFormat->WaveFormatEx.wBitsPerSample,
-                                          TransformedFormat->WaveFormatEx.wBitsPerSample,
+                                          InputFormat->WaveFormatEx.wBitsPerSample,
+                                          OutputFormat->WaveFormatEx.wBitsPerSample,
                                           &BufferOut,
                                           &BufferLength);
         if (NT_SUCCESS(Status))
@@ -424,10 +394,10 @@
         }
     }
 
-    if (BaseFormat->WaveFormatEx.nSamplesPerSec != TransformedFormat->WaveFormatEx.nSamplesPerSec)
+    if (InputFormat->WaveFormatEx.nSamplesPerSec != OutputFormat->WaveFormatEx.nSamplesPerSec)
     {
         /* sample format conversion must be done in a deferred routine */
-        DPRINT1("SampleRate conversion not available yet\n");
+        DPRINT1("SampleRate conversion not available yet %u %u\n", InputFormat->WaveFormatEx.nSamplesPerSec, OutputFormat->WaveFormatEx.nSamplesPerSec);
         return FALSE;
     }
 
@@ -457,6 +427,18 @@
 {
     NTSTATUS Status;
     KSOBJECT_HEADER ObjectHeader;
+    PKSDATAFORMAT DataFormat;
+    PIO_STACK_LOCATION IoStack;
+
+
+    DataFormat = ExAllocatePool(NonPagedPool, sizeof(KSDATAFORMAT_WAVEFORMATEX) * 2);
+    if (!DataFormat)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    RtlZeroMemory(DataFormat, sizeof(KSDATAFORMAT_WAVEFORMATEX) * 2);
+
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+    IoStack->FileObject->FsContext2 = (PVOID)DataFormat;
 
     /* allocate object header */
     Status = KsAllocateObjectHeader(&ObjectHeader, 0, NULL, Irp, &PinTable);

Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c?rev=39992&r1=39991&r2=39992&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] Fri Mar 13 01:11:53 2009
@@ -144,7 +144,7 @@
 
     if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE)
     {
-        DPRINT1("FIXME: only waveout devices are supported\n");
+        DPRINT1("FIXME: only waveout / wavein devices are supported\n");
         return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
     }
 
@@ -154,7 +154,6 @@
         DPRINT1("Invalid device index %u\n", DeviceInfo->DeviceIndex);
         return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
     }
-
 
     Length = sizeof(KSDATAFORMAT_WAVEFORMATEX) + sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO);
     InstanceInfo = ExAllocatePool(NonPagedPool, Length);
@@ -343,8 +342,6 @@
                 }
             }
         }
-        else
-            DPRINT1("KSPROPERTY_PIN_CTYPES index %u failed with %x\n", Index, Status);
     }
 
 
@@ -370,7 +367,7 @@
     ULONG BytesReturned;
     PFILE_OBJECT FileObject;
 
-    DPRINT1("WdmAudControlDeviceState\n");
+    //DPRINT1("WdmAudControlDeviceState\n");
 
     Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
     if (!NT_SUCCESS(Status))
@@ -389,7 +386,7 @@
 
     ObDereferenceObject(FileObject);
 
-    DPRINT1("WdmAudControlDeviceState Status %x\n", Status);
+    //DPRINT1("WdmAudControlDeviceState Status %x\n", Status);
     return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
 }
 
@@ -468,7 +465,6 @@
 
     DPRINT("WdmAudCapabilities entered\n");
 
-
     Status = GetFilterIdAndPinId(DeviceObject, DeviceInfo, ClientInfo, &FilterId, &PinId);
     if (!NT_SUCCESS(Status))
     {
@@ -595,7 +591,7 @@
 
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
-    DPRINT1("WdmAudDeviceControl entered\n");
+    DPRINT("WdmAudDeviceControl entered\n");
 
     if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(WDMAUD_DEVICE_INFO))
     {
@@ -621,7 +617,7 @@
     }
     ClientInfo = (PWDMAUD_CLIENT)IoStack->FileObject->FsContext;
 
-    DPRINT1("WdmAudDeviceControl entered\n");
+    DPRINT("WdmAudDeviceControl entered\n");
 
     switch(IoStack->Parameters.DeviceIoControl.IoControlCode)
     {

Modified: trunk/reactos/drivers/wdm/audio/sysaudio/control.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/control.c?rev=39992&r1=39991&r2=39992&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/control.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/control.c [iso-8859-1] Fri Mar 13 01:11:53 2009
@@ -33,7 +33,14 @@
 {
     Irp->IoStatus.Information = Length;
     Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    if (Status != STATUS_PENDING)
+    {
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    }
+    else
+    {
+        IoMarkIrpPending(Irp);
+    }
     return Status;
 
 }
@@ -139,6 +146,90 @@
     return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
 }
 
+NTSTATUS
+SetMixerInputOutputFormat(
+    IN PFILE_OBJECT FileObject,
+    IN PKSDATAFORMAT InputFormat,
+    IN PKSDATAFORMAT OutputFormat)
+{
+    KSP_PIN PinRequest;
+    ULONG BytesReturned;
+    NTSTATUS Status;
+
+    /* re-using pin */
+    PinRequest.Property.Set = KSPROPSETID_Connection;
+    PinRequest.Property.Flags = KSPROPERTY_TYPE_SET;
+    PinRequest.Property.Id = KSPROPERTY_CONNECTION_DATAFORMAT;
+
+    /* set the input format */
+    PinRequest.PinId = 0;
+    //DPRINT1("InputFormat %p Size %u WaveFormatSize %u DataFormat %u WaveEx %u\n", InputFormat, InputFormat->FormatSize, sizeof(KSDATAFORMAT_WAVEFORMATEX), sizeof(KSDATAFORMAT), sizeof(WAVEFORMATEX));
+    Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY,
+                                          (PVOID)&PinRequest,
+                                           sizeof(KSP_PIN),
+                                          (PVOID)InputFormat,
+                                           InputFormat->FormatSize,
+                                          &BytesReturned);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    /* set the the output format */
+    PinRequest.PinId = 1;
+    //DPRINT1("OutputFormat %p Size %u WaveFormatSize %u DataFormat %u WaveEx %u\n", OutputFormat, OutputFormat->FormatSize, sizeof(KSDATAFORMAT_WAVEFORMATEX), sizeof(KSDATAFORMAT), sizeof(WAVEFORMATEX));
+    Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY,
+                                          (PVOID)&PinRequest,
+                                           sizeof(KSP_PIN),
+                                          (PVOID)OutputFormat,
+                                           OutputFormat->FormatSize,
+                                          &BytesReturned);
+    return Status;
+}
+
+
+NTSTATUS
+CreateMixerPinAndSetFormat(
+    IN HANDLE KMixerHandle,
+    IN KSPIN_CONNECT *PinConnect,
+    IN PKSDATAFORMAT InputFormat,
+    IN PKSDATAFORMAT OutputFormat,
+    OUT PHANDLE MixerPinHandle,
+    OUT PFILE_OBJECT *MixerFileObject)
+{
+    NTSTATUS Status;
+    HANDLE PinHandle;
+    PFILE_OBJECT FileObject;
+
+    Status = KsCreatePin(KMixerHandle, PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to create Mixer Pin with %x\n", Status);
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    Status = ObReferenceObjectByHandle(PinHandle,
+                                       GENERIC_READ | GENERIC_WRITE, 
+                                       IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to get file object with %x\n", Status);
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    Status = SetMixerInputOutputFormat(FileObject, InputFormat, OutputFormat);
+    if (!NT_SUCCESS(Status))
+    {
+        ObDereferenceObject(FileObject);
+        ZwClose(PinHandle);
+    }
+
+    *MixerPinHandle = PinHandle;
+    *MixerFileObject = FileObject;
+     return Status;
+}
+
+
 VOID
 NTAPI
 CreatePinWorkerRoutine(
@@ -147,22 +238,22 @@
 {
     NTSTATUS Status;
     PSYSAUDIO_CLIENT AudioClient;
-    HANDLE RealPinHandle, VirtualPinHandle, MixerPinHandle = NULL;
+    HANDLE RealPinHandle, VirtualPinHandle;
     HANDLE Filter;
-    ULONG NumHandels, BytesReturned;
-    PFILE_OBJECT FileObject, MixerFileObject = NULL;
+    ULONG NumHandels;
+    PFILE_OBJECT FileObject;
     PSYSAUDIO_PIN_HANDLE ClientPinHandle;
     PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context;
     PKSPIN_CONNECT PinConnect = NULL;
-    KSPROPERTY PinRequest;
-    PKSDATAFORMAT_WAVEFORMATEX ClientFormat;
+    PKSDATAFORMAT ClientFormat;
+    KSP_PIN PinRequest;
+    ULONG BytesReturned;
 
     Filter = WorkerContext->PinConnect->PinToHandle;
 
-
     WorkerContext->PinConnect->PinToHandle = NULL;
 
-    DPRINT1("CreatePinWorkerRoutine entered\n");
+    DPRINT("CreatePinWorkerRoutine entered\n");
 
     ASSERT(WorkerContext->Entry);
     ASSERT(WorkerContext->PinConnect);
@@ -170,7 +261,7 @@
     ASSERT(WorkerContext->Entry->NumberOfPins > WorkerContext->PinConnect->PinId);
 
     PinConnect = WorkerContext->PinConnect;
-    ClientFormat = (PKSDATAFORMAT_WAVEFORMATEX)(PinConnect + 1);
+    ClientFormat = (PKSDATAFORMAT)(PinConnect + 1);
 
     if (WorkerContext->CreateMixerPin)
     {
@@ -188,8 +279,14 @@
         RtlMoveMemory(PinConnect, WorkerContext->PinConnect, sizeof(KSPIN_CONNECT));
         RtlMoveMemory((PinConnect + 1), WorkerContext->MixerFormat, WorkerContext->MixerFormat->DataFormat.FormatSize);
 
-
-        Status = KsCreatePin(WorkerContext->DeviceExtension->KMixerHandle, PinConnect, GENERIC_READ | GENERIC_WRITE, &MixerPinHandle);
+        Status = CreateMixerPinAndSetFormat(WorkerContext->DeviceExtension->KMixerHandle, 
+                                            PinConnect,
+                                            (PKSDATAFORMAT)(WorkerContext->PinConnect + 1),
+                                            (PKSDATAFORMAT)WorkerContext->MixerFormat,
+                                            &WorkerContext->DispatchContext->hMixerPin,
+                                            &WorkerContext->DispatchContext->MixerFileObject);
+
+        ExFreePool(WorkerContext->MixerFormat);
 
         if (!NT_SUCCESS(Status))
         {
@@ -199,10 +296,60 @@
             ExFreePool(WorkerContext);
             return;
         }
-
-        Status = ObReferenceObjectByHandle(MixerPinHandle,
+    }
+    else
+    {
+        Status = CreateMixerPinAndSetFormat(WorkerContext->DeviceExtension->KMixerHandle, 
+                                            WorkerContext->PinConnect,
+                                            (PKSDATAFORMAT)(WorkerContext->PinConnect + 1),
+                                            (PKSDATAFORMAT)(WorkerContext->PinConnect + 1),
+                                            &WorkerContext->DispatchContext->hMixerPin,
+                                            &WorkerContext->DispatchContext->MixerFileObject);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Failed to create Mixer Pin with %x\n", Status);
+            SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
+            ExFreePool(WorkerContext->DispatchContext);
+            ExFreePool(WorkerContext);
+            return;
+        }
+    }
+
+    if (WorkerContext->CreateRealPin)
+    {
+        /* create the real pin */
+        DPRINT("Creating real pin\n");
+
+        if (WorkerContext->CreateMixerPin)
+            Status = KsCreatePin(WorkerContext->Entry->Handle, PinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle);
+        else
+            Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle);
+
+        DPRINT1("Status %x\n", Status);
+        if (!NT_SUCCESS(Status))
+        {
+            PKSDATAFORMAT_WAVEFORMATEX RequestedFormat = (PKSDATAFORMAT_WAVEFORMATEX)(WorkerContext->PinConnect + 1);
+            DPRINT1("Failed to create Pin with %x\nNumChannels: %u BitsPerSample %u SampleRate %u\n", Status,
+            RequestedFormat->WaveFormatEx.nChannels, RequestedFormat->WaveFormatEx.wBitsPerSample, RequestedFormat->WaveFormatEx.nSamplesPerSec);
+
+            if (WorkerContext->CreateMixerPin)
+            {
+                /* The mixer pin format should have been accepted */
+                ObDereferenceObject(WorkerContext->DispatchContext->MixerFileObject);
+                ZwClose(WorkerContext->DispatchContext->hMixerPin);
+                ASSERT(0);
+            }
+
+            SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
+            ExFreePool(WorkerContext->DispatchContext);
+            ExFreePool(WorkerContext);
+            return;
+        }
+
+        /* get pin file object */
+        Status = ObReferenceObjectByHandle(RealPinHandle,
                                            GENERIC_READ | GENERIC_WRITE, 
-                                           IoFileObjectType, KernelMode, (PVOID*)&MixerFileObject, NULL);
+                                           IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
 
         if (!NT_SUCCESS(Status))
         {
@@ -213,94 +360,58 @@
             return;
         }
 
-        WorkerContext->DispatchContext->hMixerPin = MixerPinHandle;
-        WorkerContext->DispatchContext->MixerFileObject = MixerFileObject;
-
-        PinRequest.Set = KSPROPSETID_Connection;
-        PinRequest.Flags = KSPROPERTY_TYPE_SET;
-        PinRequest.Id = KSPROPERTY_CONNECTION_DATAFORMAT;
-
-        DPRINT1("ClientFormat %p Channels %u Samples %u Bits %u\n", ClientFormat, ClientFormat->WaveFormatEx.nChannels, ClientFormat->WaveFormatEx.nSamplesPerSec, ClientFormat->WaveFormatEx.wBitsPerSample);
-
-        Status = KsSynchronousIoControlDevice(MixerFileObject, KernelMode, IOCTL_KS_PROPERTY,
-                                             (PVOID)&PinRequest,
-                                             sizeof(KSPROPERTY),
-                                             (PVOID)ClientFormat,
-                                             sizeof(KSDATAFORMAT_WAVEFORMATEX),
-                                             &BytesReturned);
-
-    }
-
-    if (WorkerContext->CreateRealPin)
-    {
-        /* create the real pin */
-        DPRINT("Creating real pin\n");
-
-        if (WorkerContext->CreateMixerPin)
-            Status = KsCreatePin(WorkerContext->Entry->Handle, PinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle);
-        else
-            Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle);
-
-        DPRINT1("Status %x\n", Status);
+        if (WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].MaxPinInstanceCount == 1)
+        {
+            /* store the pin handle there is the pin can only be instantiated once*/
+            WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle = RealPinHandle;
+        }
+
+        WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 0;
+        WorkerContext->DispatchContext->Handle = RealPinHandle;
+        WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId;
+        WorkerContext->DispatchContext->AudioEntry = WorkerContext->Entry;
+        WorkerContext->DispatchContext->FileObject = FileObject;
+    }
+    else
+    {
+        WorkerContext->DispatchContext->AudioEntry = WorkerContext->Entry;
+        WorkerContext->DispatchContext->Handle = WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle;
+        WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId;
+
+        /* get pin file object */
+        Status = ObReferenceObjectByHandle(WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle,
+                                           GENERIC_READ | GENERIC_WRITE, 
+                                           IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+
         if (!NT_SUCCESS(Status))
         {
-            DPRINT1("Failed to create Pin with %x\n", Status);
+            DPRINT1("Failed to get file object with %x %p\n", Status, WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle);
             SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
             ExFreePool(WorkerContext->DispatchContext);
             ExFreePool(WorkerContext);
             return;
         }
-
-        /* get pin file object */
-        Status = ObReferenceObjectByHandle(RealPinHandle,
-                                           GENERIC_READ | GENERIC_WRITE, 
-                                           IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
-
-        DPRINT1("Status %x\n", Status);
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT1("Failed to get file object with %x\n", Status);
-            SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
-            ExFreePool(WorkerContext->DispatchContext);
-            ExFreePool(WorkerContext);
-            return;
-        }
-
-        if (WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].MaxPinInstanceCount == 1)
-        {
-            /* store the pin handle there is the pin can only be instantiated once*/
-            WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle = RealPinHandle;
-        }
-
-        WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 1;
-        WorkerContext->DispatchContext->Handle = RealPinHandle;
-        WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId;
-        WorkerContext->DispatchContext->AudioEntry = WorkerContext->Entry;
         WorkerContext->DispatchContext->FileObject = FileObject;
-    }
-    else
-    {
-        WorkerContext->DispatchContext->AudioEntry = WorkerContext->Entry;
-        WorkerContext->DispatchContext->Handle = WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle;
-        WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId;
-
-        /* get pin file object */
-        Status = ObReferenceObjectByHandle(WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle,
-                                           GENERIC_READ | GENERIC_WRITE, 
-                                           IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
-
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT1("Failed to get file object with %x\n", Status);
-            SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
-            ExFreePool(WorkerContext->DispatchContext);
-            ExFreePool(WorkerContext);
-            return;
-        }
-        WorkerContext->DispatchContext->FileObject = FileObject;
-    }
-
-    DPRINT1("creating virtual pin\n");
+
+
+        /* re-using pin */
+        PinRequest.Property.Set = KSPROPSETID_Connection;
+        PinRequest.Property.Flags = KSPROPERTY_TYPE_SET;
+        PinRequest.Property.Id = KSPROPERTY_CONNECTION_DATAFORMAT;
+        PinRequest.PinId = PinConnect->PinId;
+
+        if (WorkerContext->MixerFormat)
+            ClientFormat = (PKSDATAFORMAT)WorkerContext->MixerFormat;
+        else
+            ClientFormat = (PKSDATAFORMAT)(WorkerContext->PinConnect + 1);
+
+        /* set the format on the real pin */
+        Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSPROPERTY),
+                                             (PVOID)ClientFormat, ClientFormat->FormatSize, &BytesReturned);
+
+    }
+
+    DPRINT("creating virtual pin\n");
     /* now create the virtual audio pin which is exposed to wdmaud */
     Status = KsCreatePin(Filter, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &VirtualPinHandle);
 
@@ -369,27 +480,28 @@
             AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].bHandle = TRUE;
             AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].hPin = RealPinHandle;
             AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].PinId = WorkerContext->PinConnect->PinId;
-            AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].hMixer = MixerPinHandle;
-
+            AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].hMixer = WorkerContext->DispatchContext->hMixerPin;
+            AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].DispatchContext = WorkerContext->DispatchContext;
         }
         else
         {
             AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].bHandle = FALSE;
             AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].hPin = VirtualPinHandle;
             AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].PinId = WorkerContext->PinConnect->PinId;
-            AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].hMixer = MixerPinHandle;
+            AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].hMixer = WorkerContext->DispatchContext->hMixerPin;
+            AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].DispatchContext = WorkerContext->DispatchContext;
         }
 
         /// increase reference count
+        AudioClient->Devs[AudioClient->NumDevices -1].ClientHandlesCount++;
         WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References++;
-        AudioClient->Devs[AudioClient->NumDevices -1].ClientHandlesCount++;
     }
 
 
     /* store pin context */
     FileObject->FsContext2 = (PVOID)WorkerContext->DispatchContext;
 
-    DPRINT1("Successfully created virtual pin %p\n", VirtualPinHandle);
+    DPRINT("Successfully created virtual pin %p\n", VirtualPinHandle);
     *((PHANDLE)WorkerContext->Irp->UserBuffer) = VirtualPinHandle;
 
     SetIrpIoStatus(WorkerContext->Irp, STATUS_SUCCESS, sizeof(HANDLE));
@@ -488,48 +600,97 @@
     }
 }
 
-NTSTATUS
-SetPinFormat(
-    PKSAUDIO_DEVICE_ENTRY Entry,
-    KSPIN_CONNECT * PinConnect,
-    ULONG Length)
+BOOL
+ComputeCompatibleFormat(
+    IN PKSAUDIO_DEVICE_ENTRY Entry,
+    IN ULONG PinId,
+    IN PSYSAUDIODEVEXT DeviceExtension,
+    IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat,
+    OUT PKSDATAFORMAT_WAVEFORMATEX MixerFormat)
 {
+    BOOL bFound;
+    ULONG BytesReturned;
     KSP_PIN PinRequest;
-    PFILE_OBJECT FileObject;
-    ULONG BytesReturned;
+    PKSDATARANGE_AUDIO AudioRange;
     NTSTATUS Status;
-
-    /* re-using pin */
-    PinRequest.Property.Set = KSPROPSETID_Connection;
-    PinRequest.Property.Flags = KSPROPERTY_TYPE_SET;
-    PinRequest.Property.Id = KSPROPERTY_CONNECTION_DATAFORMAT;
-    PinRequest.PinId = PinConnect->PinId;
-
-
-    /* get pin file object */
-    Status = ObReferenceObjectByHandle(Entry->Pins[PinConnect->PinId].PinHandle,
-                                       GENERIC_READ | GENERIC_WRITE, 
-                                       IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
-
-   if (!NT_SUCCESS(Status))
-   {
-       DPRINT1("Failed to get pin file object with %x\n", Status);
-       return Status;
-   }
-
-   Length -= sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO);
-   Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSPROPERTY),
-                                         (PVOID)(PinConnect + 1), Length, &BytesReturned);
-   ObDereferenceObject(FileObject);
-
-   if (!NT_SUCCESS(Status))
-   {
-       /* set the format on the mixer pin */
-       UNIMPLEMENTED
-       return STATUS_SUCCESS;
-   }
-
-   return Status;
+    ULONG Index;
+    PKSMULTIPLE_ITEM MultipleItem;
+
+    if (!DeviceExtension->KMixerHandle || !DeviceExtension->KMixerFileObject)
+    {
+        DPRINT1("KMixer is not available\n");
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    PinRequest.PinId = PinId;
+    PinRequest.Property.Set = KSPROPSETID_Pin;
+    PinRequest.Property.Flags = KSPROPERTY_TYPE_GET;
+    PinRequest.Property.Id = KSPROPERTY_PIN_DATARANGES;
+
+    Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), NULL, 0, &BytesReturned);
+    if (Status != STATUS_BUFFER_TOO_SMALL)
+    {
+        DPRINT1("Property Request KSPROPERTY_PIN_DATARANGES failed with %x\n", Status);
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    MultipleItem = ExAllocatePool(NonPagedPool, BytesReturned);
+    if (!MultipleItem)
+    {
+        return STATUS_NO_MEMORY;
+    }
+
+    Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)MultipleItem, BytesReturned, &BytesReturned);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT("Property Request KSPROPERTY_PIN_DATARANGES failed with %x\n", Status);
+        ExFreePool(MultipleItem);
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    AudioRange = (PKSDATARANGE_AUDIO)(MultipleItem + 1);
+    bFound = FALSE;
+    for(Index = 0; Index < MultipleItem->Count; Index++)
+    {
+        if (AudioRange->DataRange.FormatSize != sizeof(KSDATARANGE_AUDIO))
+        {
+            UNIMPLEMENTED
+            AudioRange = (PKSDATARANGE_AUDIO)((PUCHAR)AudioRange + AudioRange->DataRange.FormatSize);
+        }
+        MixerFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX);
+        MixerFormat->DataFormat.Flags = 0;
+        MixerFormat->DataFormat.Reserved = 0;
+        MixerFormat->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
+        MixerFormat->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+        MixerFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
+        MixerFormat->DataFormat.SampleSize = 4;
+        MixerFormat->WaveFormatEx.wFormatTag = ClientFormat->WaveFormatEx.wFormatTag;
+        MixerFormat->WaveFormatEx.nChannels = min(AudioRange->MaximumChannels, ClientFormat->WaveFormatEx.nChannels);
+        MixerFormat->WaveFormatEx.nSamplesPerSec = max(AudioRange->MinimumSampleFrequency, min(AudioRange->MaximumSampleFrequency, ClientFormat->WaveFormatEx.nSamplesPerSec));
+        MixerFormat->WaveFormatEx.wBitsPerSample = max(AudioRange->MinimumBitsPerSample, min(AudioRange->MaximumBitsPerSample, ClientFormat->WaveFormatEx.wBitsPerSample));
+        MixerFormat->WaveFormatEx.cbSize = 0;
+        MixerFormat->WaveFormatEx.nBlockAlign = (MixerFormat->WaveFormatEx.nChannels * MixerFormat->WaveFormatEx.wBitsPerSample) / 8;
+        MixerFormat->WaveFormatEx.nAvgBytesPerSec = MixerFormat->WaveFormatEx.nChannels * MixerFormat->WaveFormatEx.nSamplesPerSec * (MixerFormat->WaveFormatEx.wBitsPerSample / 8);
+
+        bFound = TRUE;
+        break;
+
+        AudioRange = (PKSDATARANGE_AUDIO)((PUCHAR)AudioRange + AudioRange->DataRange.FormatSize);
+    }
+    ExFreePool(MultipleItem);
+
+
+#if 0
+    DPRINT1("\nNum Channels %u Old Channels %u\n SampleRate %u Old SampleRate %u\n BitsPerSample %u Old BitsPerSample %u\n ClientFormat %p",
+           MixerFormat->WaveFormatEx.nChannels, ClientFormat->WaveFormatEx.nChannels,
+           MixerFormat->WaveFormatEx.nSamplesPerSec, ClientFormat->WaveFormatEx.nSamplesPerSec,
+           MixerFormat->WaveFormatEx.wBitsPerSample, ClientFormat->WaveFormatEx.wBitsPerSample, ClientFormat);
+#endif
+
+    if (bFound)
+        return STATUS_SUCCESS;
+    else
+        return STATUS_NOT_IMPLEMENTED;
 }
 
 
@@ -555,10 +716,9 @@
     PDISPATCH_CONTEXT DispatchContext;
     ULONG Index, SubIndex;
     BOOL CreateMixerPin;
-    PKSDATARANGE_AUDIO AudioRange;
+    ULONG DeviceId;
     PKSDATAFORMAT_WAVEFORMATEX MixerFormat = NULL, ClientFormat;
 
-    PKSMULTIPLE_ITEM MultipleItem;
 
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
@@ -611,6 +771,27 @@
         DPRINT("Invalid PinId %x\n", PinConnect->PinId);
         return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
     }
+
+Retry:
+    /* get the instances count */
+    PinRequest.PinId = PinConnect->PinId;
+    PinRequest.Property.Set = KSPROPSETID_Pin;
+    PinRequest.Property.Flags = KSPROPERTY_TYPE_GET;
+    PinRequest.Property.Id = KSPROPERTY_PIN_CINSTANCES;
+
+    Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&PinInstances, sizeof(KSPIN_CINSTANCES), &BytesReturned);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT("Property Request KSPROPERTY_PIN_GLOBALCINSTANCES failed with %x\n", Status);
+        return SetIrpIoStatus(Irp, Status, 0);
+    }
+
+    if (PinInstances.PossibleCount == 0)
+    {
+        /* caller wanted to open an instance-less pin */
+        return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+    }
+
 
     /* check the format */
     PinRequest.PinId = PinConnect->PinId;
@@ -620,12 +801,6 @@
 
     CreateMixerPin = FALSE;
     BytesReturned = IoStack->Parameters.DeviceIoControl.InputBufferLength - sizeof(KSPIN_CONNECT) - sizeof(SYSAUDIO_INSTANCE_INFO);
-    if (BytesReturned != sizeof(KSDATAFORMAT_WAVEFORMATEX))
-    {
-        UNIMPLEMENTED
-        return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
-    }
-
     ClientFormat = (PKSDATAFORMAT_WAVEFORMATEX)(PinConnect + 1);
 
     Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)ClientFormat, BytesReturned, &BytesReturned);
@@ -640,136 +815,58 @@
             return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
         }
 
-        PinRequest.PinId = PinConnect->PinId;
-        PinRequest.Property.Set = KSPROPSETID_Pin;
-        PinRequest.Property.Flags = KSPROPERTY_TYPE_GET;
-        PinRequest.Property.Id = KSPROPERTY_PIN_DATARANGES;
-
-        Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), NULL, 0, &BytesReturned);
-        if (Status != STATUS_BUFFER_TOO_SMALL)
-        {
-            DPRINT1("Property Request KSPROPERTY_PIN_DATARANGES failed with %x\n", Status);
-            return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
-        }
-
-        MultipleItem = ExAllocatePool(NonPagedPool, BytesReturned);
-        if (!MultipleItem)
-        {
-            return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
-        }
-
         MixerFormat = ExAllocatePool(NonPagedPool, sizeof(KSDATAFORMAT_WAVEFORMATEX));
         if (!MixerFormat)
         {
-            ExFreePool(MultipleItem);
-            return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
-        }
-
-        Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)MultipleItem, BytesReturned, &BytesReturned);
+            return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
+        }
+
+        Status = ComputeCompatibleFormat(Entry, PinConnect->PinId, DeviceExtension, ClientFormat, MixerFormat);
         if (!NT_SUCCESS(Status))
         {
-            DPRINT("Property Request KSPROPERTY_PIN_DATARANGES failed with %x\n", Status);
             ExFreePool(MixerFormat);
-            ExFreePool(MultipleItem);
-            return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
-        }
-
-        CreateMixerPin = FALSE;
-        AudioRange = (PKSDATARANGE_AUDIO)(MultipleItem + 1);
-        for(Index = 0; Index < MultipleItem->Count; Index++)
-        {
-            if (AudioRange->DataRange.FormatSize != sizeof(KSDATARANGE_AUDIO))
-            {
-                UNIMPLEMENTED
-                AudioRange = (PKSDATARANGE_AUDIO)((PUCHAR)AudioRange + AudioRange->DataRange.FormatSize);
-            }
-            MixerFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX);
-            MixerFormat->DataFormat.Flags = 0;
-            MixerFormat->DataFormat.Reserved = 0;
-            MixerFormat->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
-            MixerFormat->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
-            MixerFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
-            MixerFormat->DataFormat.SampleSize = 4;
-            MixerFormat->WaveFormatEx.wFormatTag = ClientFormat->WaveFormatEx.wFormatTag;
-            MixerFormat->WaveFormatEx.nChannels = min(AudioRange->MaximumChannels, ClientFormat->WaveFormatEx.nChannels);
-            MixerFormat->WaveFormatEx.nSamplesPerSec = max(AudioRange->MinimumSampleFrequency, min(AudioRange->MaximumSampleFrequency, ClientFormat->WaveFormatEx.nSamplesPerSec));
-            MixerFormat->WaveFormatEx.wBitsPerSample = max(AudioRange->MinimumBitsPerSample, min(AudioRange->MaximumBitsPerSample, ClientFormat->WaveFormatEx.wBitsPerSample));
-            MixerFormat->WaveFormatEx.cbSize = 0;
-            MixerFormat->WaveFormatEx.nBlockAlign = (MixerFormat->WaveFormatEx.nChannels * MixerFormat->WaveFormatEx.wBitsPerSample) / 8;
-            MixerFormat->WaveFormatEx.nAvgBytesPerSec = MixerFormat->WaveFormatEx.nChannels * MixerFormat->WaveFormatEx.nSamplesPerSec * (MixerFormat->WaveFormatEx.wBitsPerSample / 8);
-
-            CreateMixerPin = TRUE;
-            break;
-
-            AudioRange = (PKSDATARANGE_AUDIO)((PUCHAR)AudioRange + AudioRange->DataRange.FormatSize);
-        }
-        ExFreePool(MultipleItem);
-        if (!CreateMixerPin)
-        {
-            ExFreePool(MixerFormat);
-            DPRINT1("No Format found :(\n");
-            return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
-        }
-#if 0
-        DPRINT1("\nNum Channels %u Old Channels %u\n SampleRate %u Old SampleRate %u\n BitsPerSample %u Old BitsPerSample %u\n ClientFormat %p",
-               MixerFormat->WaveFormatEx.nChannels, ClientFormat->WaveFormatEx.nChannels,
-               MixerFormat->WaveFormatEx.nSamplesPerSec, ClientFormat->WaveFormatEx.nSamplesPerSec,
-               MixerFormat->WaveFormatEx.wBitsPerSample, ClientFormat->WaveFormatEx.wBitsPerSample, ClientFormat);
-#endif
-    }
-
-    /* get the instances count */
-    PinRequest.PinId = PinConnect->PinId;
-    PinRequest.Property.Set = KSPROPSETID_Pin;
-    PinRequest.Property.Flags = KSPROPERTY_TYPE_GET;
-    PinRequest.Property.Id = KSPROPERTY_PIN_CINSTANCES;
-
-    Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&PinInstances, sizeof(KSPIN_CINSTANCES), &BytesReturned);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT("Property Request KSPROPERTY_PIN_GLOBALCINSTANCES failed with %x\n", Status);
-        if (MixerFormat)
-            ExFreePool(MixerFormat);
-        return SetIrpIoStatus(Irp, Status, 0);
-    }
-
-    if (PinInstances.PossibleCount == 0)
-    {
-        /* caller wanted to open an instance-less pin */
-        if (MixerFormat)
-            ExFreePool(MixerFormat);
-        return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
-    }
-
-    if (PinInstances.CurrentCount == PinInstances.PossibleCount)
-    {
-        for (Index = 0; Index < ClientInfo->NumDevices; Index++)
-        {
-            if (ClientInfo->Devs[Index].DeviceId == InstanceInfo->DeviceNumber)
-            {
-                if (ClientInfo->Devs[Index].ClientHandlesCount)
+            return SetIrpIoStatus(Irp, Status, 0);
+        }
+        CreateMixerPin = TRUE;
+    }
+
+    DeviceId = (ULONG)-1;
+
+    /* scan the clientinfo if the client has already opened device with the specified pin */
+    for (Index = 0; Index < ClientInfo->NumDevices; Index++)
+    {
+        if (ClientInfo->Devs[Index].DeviceId == InstanceInfo->DeviceNumber)
+        {
+            DeviceId = Index;
+            if (ClientInfo->Devs[Index].ClientHandlesCount)
+            {
+                for(SubIndex = 0; SubIndex < ClientInfo->Devs[Index].ClientHandlesCount; SubIndex++)
                 {
-                    for(SubIndex = 0; SubIndex < ClientInfo->Devs[Index].ClientHandlesCount; SubIndex++)
+                    if (ClientInfo->Devs[Index].ClientHandles[SubIndex].PinId == PinConnect->PinId)
                     {
-                        if (ClientInfo->Devs[Index].ClientHandles[SubIndex].PinId == PinConnect->PinId)
-                        {
-                            /* reuse opened pin */
-                            Length = IoStack->Parameters.DeviceIoControl.InputBufferLength - sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO);
-                            Status = SetPinFormat(Entry, PinConnect, Length);
-                            DPRINT1("Reusing instance handle Status %x\n", Status);
-                            ASSERT(ClientInfo->Devs[Index].ClientHandles[SubIndex].bHandle == FALSE);
-                            *((PHANDLE)Irp->UserBuffer) = ClientInfo->Devs[Index].ClientHandles[SubIndex].hPin;
-                            return SetIrpIoStatus(Irp, Status, sizeof(HANDLE));
-                        }
+                        /* the pin has been already opened by the client, re-use it */
+                        ASSERT(ClientInfo->Devs[Index].ClientHandles[SubIndex].bHandle == FALSE);
+
+                        DispatchContext = ClientInfo->Devs[Index].ClientHandles[SubIndex].DispatchContext;
+                        ObDereferenceObject(DispatchContext->MixerFileObject);
+                        ObDereferenceObject(DispatchContext->FileObject);
+                        ZwClose(DispatchContext->hMixerPin);
+                        ZwClose(DispatchContext->Handle);
+                        ClientInfo->Devs[Index].ClientHandles[SubIndex].PinId = (ULONG)-1;
+                        goto Retry;
                     }
                 }
-
-            }
-        }
-
+            }
+        }
+    }
+
+    ASSERT(DeviceId != (ULONG)-1);
+
+    if (PinInstances.CurrentCount == PinInstances.PossibleCount)
+    {
         /* pin already exists */
         ASSERT(Entry->Pins[PinConnect->PinId].PinHandle != NULL);
-        if (Entry->Pins[PinConnect->PinId].References > 1)
+        if (Entry->Pins[PinConnect->PinId].References)
         {
             /* FIXME need ksmixer */
             DPRINT1("Device %u Pin %u References %u is already occupied, try later\n", InstanceInfo->DeviceNumber, PinConnect->PinId, Entry->Pins[PinConnect->PinId].References);
@@ -816,28 +913,14 @@
     RtlZeroMemory(WorkerContext, sizeof(PIN_WORKER_CONTEXT));
     RtlZeroMemory(DispatchContext, sizeof(DISPATCH_CONTEXT));
 
-    if (PinInstances.CurrentCount == PinInstances.PossibleCount)
-    {
-        /* re-using pin */
-        Status = SetPinFormat(Entry, PinConnect, Length);
-        if (!NT_SUCCESS(Status))
-        {
-            if (MixerFormat)
-                ExFreePool(MixerFormat);
-            IoFreeWorkItem(WorkItem);
-            ExFreePool(WorkerContext);
-            ExFreePool(DispatchContext);
-            return SetIrpIoStatus(Irp, Status, 0);
-        }
-    }
-    else
-    {
-        /* create the real pin */
+    DPRINT1("PinInstances.CurrentCount %u\n", PinInstances.CurrentCount);
+
+    if (PinInstances.CurrentCount < PinInstances.PossibleCount)
+    {
         WorkerContext->CreateRealPin = TRUE;
     }
 
     /* set up context */
-
     WorkerContext->DispatchContext = DispatchContext;
     WorkerContext->Entry = Entry;
     WorkerContext->Irp = Irp;

Modified: trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c?rev=39992&r1=39991&r2=39992&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c [iso-8859-1] Fri Mar 13 01:11:53 2009
@@ -24,7 +24,7 @@
 {
     PIO_STACK_LOCATION IoStack;
 
-    DPRINT("Dispatch_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
+    //DPRINT("Dispatch_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
 
     IoStack = IoGetCurrentIrpStackLocation(Irp);
     if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
@@ -95,6 +95,8 @@
     PIO_STACK_LOCATION IoStatus;
     ULONG Index, SubIndex;
     PSYSAUDIODEVEXT DeviceExtension;
+    PDISPATCH_CONTEXT DispatchContext;
+
 
     IoStatus = IoGetCurrentIrpStackLocation(Irp);
 
@@ -105,6 +107,7 @@
     DPRINT1("Client %p NumDevices %u\n", Client, Client->NumDevices);
     for(Index = 0; Index < Client->NumDevices; Index++)
     {
+        DPRINT1("Index %u Device %u Handels Count %u\n", Index, Client->Devs[Index].DeviceId, Client->Devs[Index].ClientHandlesCount);
         if (Client->Devs[Index].ClientHandlesCount)
         {
             Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, Client->Devs[Index].DeviceId);
@@ -112,7 +115,9 @@
 
             for(SubIndex = 0; SubIndex < Client->Devs[Index].ClientHandlesCount; SubIndex++)
             {
-                ASSERT(Entry->NumberOfPins > Client->Devs[Index].ClientHandles[SubIndex].PinId);
+                if (Client->Devs[Index].ClientHandles[SubIndex].PinId == (ULONG)-1)
+                    continue;
+
                 if (Client->Devs[Index].ClientHandles[SubIndex].bHandle)
                 {
                     DPRINT1("Closing handle %p\n", Client->Devs[Index].ClientHandles[SubIndex].hPin);
@@ -125,6 +130,21 @@
                     /* this is pin which can only be instantiated once
                      * so we just need to release the reference count on that pin */
                     Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].References--;
+
+                    DispatchContext = (PDISPATCH_CONTEXT)Client->Devs[Index].ClientHandles[SubIndex].DispatchContext;
+                    ObDereferenceObject(DispatchContext->MixerFileObject);
+                    ObDereferenceObject(DispatchContext->FileObject);
+                    ZwClose(DispatchContext->hMixerPin);
+                    ExFreePool(DispatchContext);
+
+                    //DPRINT1("Index %u DeviceIndex %u Pin %u References %u\n", Index, Client->Devs[Index].DeviceId, SubIndex, Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].References);
+                    if (!Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].References)
+                    {
+                        DPRINT1("Closing pin %p\n", Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].PinHandle);
+
+                        ZwClose(Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].PinHandle);
+                        Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].PinHandle = NULL;
+                    }
                 }
             }
             ExFreePool(Client->Devs[Index].ClientHandles);

Modified: trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h?rev=39992&r1=39991&r2=39992&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] Fri Mar 13 01:11:53 2009
@@ -7,6 +7,7 @@
     ULONG PinId;
     HANDLE hPin;
     HANDLE hMixer;
+    PVOID DispatchContext;
 }SYSAUDIO_PIN_HANDLE, *PSYSAUDIO_PIN_HANDLE;
 
 



More information about the Ros-diffs mailing list