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