Author: janderwald
Date: Tue Apr 14 18:59:51 2009
New Revision: 40500
URL:
http://svn.reactos.org/svn/reactos?rev=40500&view=rev
Log:
- Fix a bug in the KSPROPERTY_PIN_DATAINTERSECTION handler
- Verify format in the pin creation routine
- Only create a pin when there is work to be done
- Improve error checking
Modified:
trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c
trunk/reactos/drivers/wdm/audio/sysaudio/control.c
trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c [iso-8859-1]
(original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c [iso-8859-1] Tue Apr
14 18:59:51 2009
@@ -106,7 +106,7 @@
}
/* Access parameters */
- MultipleItem = (PKSMULTIPLE_ITEM)(Request + 1);
+ MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1);
DataRange = (PKSDATARANGE)(MultipleItem + 1);
/* Get current stack location */
@@ -115,7 +115,9 @@
for(Index = 0; Index < MultipleItem->Count; Index++)
{
/* Call miniport's properitary handler */
- Status = SubDevice->lpVtbl->DataRangeIntersection(SubDevice, Pin->PinId,
DataRange,
(PKSDATARANGE)&Descriptor->Factory.KsPinDescriptor[Pin->PinId].DataRanges[0],
+ ASSERT(Descriptor->Factory.KsPinDescriptor[Pin->PinId].DataRangesCount);
+ ASSERT(Descriptor->Factory.KsPinDescriptor[Pin->PinId].DataRanges[0]);
+ Status = SubDevice->lpVtbl->DataRangeIntersection(SubDevice, Pin->PinId,
DataRange,
(PKSDATARANGE)Descriptor->Factory.KsPinDescriptor[Pin->PinId].DataRanges[0],
IoStack->Parameters.DeviceIoControl.OutputBufferLength, Data, &Length);
if (Status == STATUS_SUCCESS)
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] Tue Apr 14 18:59:51
2009
@@ -16,6 +16,15 @@
const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, {0x80,
0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
const GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001L, 0x0000, 0x0010, {0x80,
0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, {0xbf,
0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
+
+NTSTATUS
+ComputeCompatibleFormat(
+ IN PKSAUDIO_DEVICE_ENTRY Entry,
+ IN ULONG PinId,
+ IN PSYSAUDIODEVEXT DeviceExtension,
+ IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat,
+ OUT PKSDATAFORMAT_WAVEFORMATEX MixerFormat);
+
NTSTATUS
SetIrpIoStatus(
@@ -187,17 +196,14 @@
IN PVOID Context)
{
NTSTATUS Status;
+ ULONG NumHandels;
+ HANDLE RealPinHandle = NULL, VirtualPinHandle = NULL, Filter;
+ PFILE_OBJECT RealFileObject = NULL, VirtualFileObject = NULL;
PSYSAUDIO_CLIENT AudioClient;
- HANDLE RealPinHandle, VirtualPinHandle;
- HANDLE Filter;
- ULONG NumHandels;
- PFILE_OBJECT FileObject;
PSYSAUDIO_PIN_HANDLE ClientPinHandle;
+ PKSDATAFORMAT_WAVEFORMATEX OutputFormat = NULL;
+ PKSPIN_CONNECT MixerPinConnect = NULL;
PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context;
- PKSPIN_CONNECT PinConnect = NULL;
- PKSDATAFORMAT ClientFormat;
- KSP_PIN PinRequest;
- ULONG BytesReturned;
Filter = WorkerContext->PinConnect->PinToHandle;
@@ -210,149 +216,95 @@
ASSERT(WorkerContext->Entry->Pins);
ASSERT(WorkerContext->Entry->NumberOfPins >
WorkerContext->PinConnect->PinId);
- PinConnect = WorkerContext->PinConnect;
- ClientFormat = (PKSDATAFORMAT)(PinConnect + 1);
-
- if (WorkerContext->CreateMixerPin)
- {
- PinConnect = ExAllocatePool(NonPagedPool, sizeof(KSPIN_CONNECT) +
WorkerContext->MixerFormat->DataFormat.FormatSize);
- if (!PinConnect)
- {
- /* no memory */
- SetIrpIoStatus(WorkerContext->Irp, STATUS_NO_MEMORY, 0);
- ExFreePool(WorkerContext->DispatchContext);
- ExFreePool(WorkerContext->MixerFormat);
- return;
- }
-
- RtlMoveMemory(PinConnect, WorkerContext->PinConnect, sizeof(KSPIN_CONNECT));
- RtlMoveMemory((PinConnect + 1), WorkerContext->MixerFormat,
WorkerContext->MixerFormat->DataFormat.FormatSize);
-
- 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))
- {
- DPRINT1("Failed to create Mixer Pin with %x\n", Status);
+ /* Let's try to create the audio irp pin */
+ Status = KsCreatePin(WorkerContext->Entry->Handle,
WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle);
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* the audio irp pin didnt accept the input format
+ * let's compute a compatible format
+ */
+
+ MixerPinConnect = ExAllocatePool(NonPagedPool, sizeof(KSPIN_CONNECT) +
sizeof(KSDATAFORMAT_WAVEFORMATEX));
+ if (!MixerPinConnect)
+ {
SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
ExFreePool(WorkerContext->DispatchContext);
return;
}
- }
- else
- {
- Status =
CreateMixerPinAndSetFormat(WorkerContext->DeviceExtension->KMixerHandle,
- WorkerContext->PinConnect,
- (PKSDATAFORMAT)(WorkerContext->PinConnect
+ 1),
- (PKSDATAFORMAT)(WorkerContext->PinConnect
+ 1),
+
+ /* Copy initial connect details */
+ RtlMoveMemory(MixerPinConnect, WorkerContext->PinConnect,
sizeof(KSPIN_CONNECT));
+
+
+ OutputFormat = (PKSDATAFORMAT_WAVEFORMATEX)(MixerPinConnect + 1);
+
+ Status = ComputeCompatibleFormat(WorkerContext->Entry,
WorkerContext->PinConnect->PinId, WorkerContext->DeviceExtension,
(PKSDATAFORMAT_WAVEFORMATEX)(WorkerContext->PinConnect + 1), OutputFormat);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ComputeCompatibleFormat failed with %x\n", Status);
+ SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
+ ExFreePool(WorkerContext->DispatchContext);
+ ExFreePool(MixerPinConnect);
+ return;
+ }
+
+ /* Retry with Mixer format */
+ Status = KsCreatePin(WorkerContext->Entry->Handle, MixerPinConnect,
GENERIC_READ | GENERIC_WRITE, &RealPinHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("KsCreatePin failed with %x\n", Status);
+ /* This should not fail */
+ KeBugCheck(0);
+ return;
+ }
+ }
+
+ /* get pin file object */
+ Status = ObReferenceObjectByHandle(RealPinHandle,
+ GENERIC_READ | GENERIC_WRITE,
+ IoFileObjectType, KernelMode,
(PVOID*)&RealFileObject, NULL);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to get file object with %x\n", Status);
+ goto cleanup;
+ }
+
+ if
(WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].MaxPinInstanceCount
== 1)
+ {
+ /* store the pin handle there if 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 = RealFileObject;
+
+ /* Do we need to transform the audio stream */
+ if (OutputFormat != NULL)
+ {
+ PKSDATAFORMAT InputFormat;
+
+ /* Fetch input format */
+ InputFormat = (PKSDATAFORMAT)(WorkerContext->PinConnect + 1);
+
+ /* Now create the mixer pin */
+ Status =
CreateMixerPinAndSetFormat(WorkerContext->DeviceExtension->KMixerHandle,
+ MixerPinConnect,
+ InputFormat,
+ (PKSDATAFORMAT)OutputFormat,
&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);
- 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);
-
- DPRINT("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);
- KeBugCheck(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*)&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);
- return;
- }
-
- if
(WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].MaxPinInstanceCount
== 1)
- {
- /* store the pin handle there if 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 get file object with %x %p\n", Status,
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle);
- SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
- ExFreePool(WorkerContext->DispatchContext);
- return;
- }
- WorkerContext->DispatchContext->FileObject = FileObject;
-
-
- /* 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);
+ goto cleanup;
+ }
}
@@ -362,37 +314,21 @@
if (!NT_SUCCESS(Status))
{
- DPRINT1("Failed to create virtual pin with %x\n", Status);
- if (WorkerContext->CreateRealPin)
- {
- /* mark pin as free to use */
-
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 0;
- }
-
- SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
- ExFreePool(WorkerContext->DispatchContext);
- return;
+ DPRINT1("Failed to create virtual pin %x\n", Status);
+ goto cleanup;
}
/* get pin file object */
Status = ObReferenceObjectByHandle(VirtualPinHandle,
GENERIC_READ | GENERIC_WRITE,
- IoFileObjectType, KernelMode,
(PVOID*)&FileObject, NULL);
+ IoFileObjectType, KernelMode,
(PVOID*)&VirtualFileObject, NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to get file object with %x\n", Status);
-
- ZwClose(VirtualPinHandle);
- SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
- ExFreePool(WorkerContext->DispatchContext);
- return;
- }
-
- ASSERT(WorkerContext->DispatchContext);
- ASSERT(WorkerContext->DispatchContext->AudioEntry != NULL);
- ASSERT(WorkerContext->DispatchContext->FileObject != NULL);
- ASSERT(WorkerContext->DispatchContext->Handle != NULL);
+ goto cleanup;
+ }
+
ASSERT(WorkerContext->AudioClient);
ASSERT(WorkerContext->AudioClient->NumDevices > 0);
ASSERT(WorkerContext->AudioClient->Devs != NULL);
@@ -439,15 +375,39 @@
AudioClient->Devs[AudioClient->NumDevices -1].ClientHandlesCount++;
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References++;
}
-
+ else
+ {
+ /* no memory */
+ goto cleanup;
+ }
/* store pin context */
- FileObject->FsContext2 = (PVOID)WorkerContext->DispatchContext;
+ VirtualFileObject->FsContext2 = (PVOID)WorkerContext->DispatchContext;
DPRINT("Successfully created virtual pin %p\n", VirtualPinHandle);
*((PHANDLE)WorkerContext->Irp->UserBuffer) = VirtualPinHandle;
SetIrpIoStatus(WorkerContext->Irp, STATUS_SUCCESS, sizeof(HANDLE));
+ return;
+
+
+cleanup:
+ if (RealFileObject)
+ ObDereferenceObject(RealFileObject);
+
+ if (RealPinHandle)
+ ZwClose(RealPinHandle);
+
+ if (WorkerContext->DispatchContext->MixerFileObject)
+ ObDereferenceObject(WorkerContext->DispatchContext->MixerFileObject);
+
+ if (WorkerContext->DispatchContext->hMixerPin)
+ ZwClose(WorkerContext->DispatchContext->hMixerPin);
+
+
+ ExFreePool(WorkerContext->DispatchContext);
+ SetIrpIoStatus(WorkerContext->Irp, Status, 0);
+
}
NTSTATUS
@@ -542,7 +502,8 @@
}
}
-BOOL
+
+NTSTATUS
ComputeCompatibleFormat(
IN PKSAUDIO_DEVICE_ENTRY Entry,
IN ULONG PinId,
@@ -552,41 +513,63 @@
{
BOOL bFound;
ULONG BytesReturned;
- KSP_PIN PinRequest;
+ PKSP_PIN PinRequest;
+ NTSTATUS Status;
+ PKSMULTIPLE_ITEM MultipleItem;
+ ULONG Length;
PKSDATARANGE_AUDIO AudioRange;
- NTSTATUS Status;
ULONG Index;
- PKSMULTIPLE_ITEM MultipleItem;
-
- if (!DeviceExtension->KMixerHandle || !DeviceExtension->KMixerFileObject)
- {
- DPRINT1("KMixer is not available\n");
+
+ Length = sizeof(KSP_PIN) + sizeof(KSMULTIPLE_ITEM) +
ClientFormat->DataFormat.FormatSize;
+ PinRequest = ExAllocatePool(NonPagedPool, Length);
+ if (!PinRequest)
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);
+
+ PinRequest->PinId = PinId;
+ PinRequest->Property.Set = KSPROPSETID_Pin;
+ PinRequest->Property.Flags = KSPROPERTY_TYPE_GET;
+ PinRequest->Property.Id = KSPROPERTY_PIN_DATAINTERSECTION;
+
+ MultipleItem = (PKSMULTIPLE_ITEM)(PinRequest + 1);
+ MultipleItem->Count = 1;
+ MultipleItem->Size = sizeof(KSMULTIPLE_ITEM) +
ClientFormat->DataFormat.FormatSize;
+
+ RtlMoveMemory(MultipleItem + 1, ClientFormat,
ClientFormat->DataFormat.FormatSize);
+ /* Query the miniport data intersection handler */
+ Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)PinRequest, Length, (PVOID)MixerFormat,
sizeof(KSDATAFORMAT_WAVEFORMATEX), &BytesReturned);
+
+ DPRINT("Status %x\n", Status);
+
+ if (NT_SUCCESS(Status))
+ {
+ ExFreePool(PinRequest);
+ return Status;
+ }
+
+ /* Setup request block */
+ PinRequest->Property.Id = KSPROPERTY_PIN_DATARANGES;
+ /* Query pin data ranges */
+ 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;
+ /* Failed to data ranges */
+ return Status;
}
MultipleItem = ExAllocatePool(NonPagedPool, BytesReturned);
if (!MultipleItem)
{
+ ExFreePool(PinRequest);
return STATUS_NO_MEMORY;
}
- Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)MultipleItem,
BytesReturned, &BytesReturned);
+ 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);
+ ExFreePool(PinRequest);
return STATUS_UNSUCCESSFUL;
}
@@ -599,6 +582,7 @@
UNIMPLEMENTED
AudioRange = (PKSDATARANGE_AUDIO)((PUCHAR)AudioRange +
AudioRange->DataRange.FormatSize);
}
+ /* Select best quality available */
MixerFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) +
sizeof(WAVEFORMATEX);
MixerFormat->DataFormat.Flags = 0;
MixerFormat->DataFormat.Reserved = 0;
@@ -607,9 +591,9 @@
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.nChannels = min(2, AudioRange->MaximumChannels);
/* AC97 does not support mono render / record */
+ MixerFormat->WaveFormatEx.nSamplesPerSec =
AudioRange->MaximumSampleFrequency;
+ MixerFormat->WaveFormatEx.wBitsPerSample =
AudioRange->MaximumBitsPerSample;
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);
@@ -619,15 +603,18 @@
AudioRange = (PKSDATARANGE_AUDIO)((PUCHAR)AudioRange +
AudioRange->DataRange.FormatSize);
}
+
+#if 0
+ DPRINT1("\nNum Max Channels %u Channels %u Old Channels %u\n Max SampleRate %u
SampleRate %u Old SampleRate %u\n Max BitsPerSample %u BitsPerSample %u Old BitsPerSample
%u\n",
+ AudioRange->MaximumChannels, MixerFormat->WaveFormatEx.nChannels,
ClientFormat->WaveFormatEx.nChannels,
+ AudioRange->MaximumSampleFrequency,
MixerFormat->WaveFormatEx.nSamplesPerSec,
ClientFormat->WaveFormatEx.nSamplesPerSec,
+ AudioRange->MaximumBitsPerSample,
MixerFormat->WaveFormatEx.wBitsPerSample,
ClientFormat->WaveFormatEx.wBitsPerSample);
+
+
+#endif
+
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
+ ExFreePool(PinRequest);
if (bFound)
return STATUS_SUCCESS;
@@ -678,10 +665,18 @@
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);
+
+ if (DispatchContext->MixerFileObject)
+ ObDereferenceObject(DispatchContext->MixerFileObject);
+
+ if (DispatchContext->hMixerPin)
+ ZwClose(DispatchContext->hMixerPin);
+
+ if (DispatchContext->FileObject)
+ ObDereferenceObject(DispatchContext->FileObject);
+
+ if (DispatchContext->Handle)
+ ZwClose(DispatchContext->Handle);
ClientInfo->Devs[Index].ClientHandles[SubIndex].PinId =
(ULONG)-1;
}
}
@@ -698,20 +693,18 @@
PSYSAUDIODEVEXT DeviceExtension,
PDEVICE_OBJECT DeviceObject)
{
- ULONG Length, BytesReturned;
+ ULONG Length;
PKSAUDIO_DEVICE_ENTRY Entry;
KSPIN_CONNECT * PinConnect;
PIO_STACK_LOCATION IoStack;
PSYSAUDIO_INSTANCE_INFO InstanceInfo;
PSYSAUDIO_CLIENT ClientInfo;
PKSOBJECT_CREATE_ITEM CreateItem;
- KSP_PIN PinRequest;
NTSTATUS Status;
KSPIN_CINSTANCES PinInstances;
PPIN_WORKER_CONTEXT WorkerContext;
PDISPATCH_CONTEXT DispatchContext;
- BOOL CreateMixerPin;
- PKSDATAFORMAT_WAVEFORMATEX MixerFormat = NULL, ClientFormat;
+
IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -783,43 +776,6 @@
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
}
- /* check the format */
- PinRequest.PinId = PinConnect->PinId;
- PinRequest.Property.Set = KSPROPSETID_Pin;
- PinRequest.Property.Flags = KSPROPERTY_TYPE_SET;
- PinRequest.Property.Id = KSPROPERTY_PIN_PROPOSEDATAFORMAT;
-
- CreateMixerPin = FALSE;
- BytesReturned = IoStack->Parameters.DeviceIoControl.InputBufferLength -
sizeof(KSPIN_CONNECT) - sizeof(SYSAUDIO_INSTANCE_INFO);
- ClientFormat = (PKSDATAFORMAT_WAVEFORMATEX)(PinConnect + 1);
-
- Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)ClientFormat,
BytesReturned, &BytesReturned);
- if (!NT_SUCCESS(Status))
- {
- //DPRINT("Property Request KSPROPERTY_PIN_PROPOSEDATAFORMAT failed with
%x\n", Status);
-
- if (!DeviceExtension->KMixerHandle || !DeviceExtension->KMixerFileObject)
- {
- DPRINT1("KMixer is not available\n");
- DbgBreakPoint();
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
- }
-
- MixerFormat = ExAllocatePool(NonPagedPool, sizeof(KSDATAFORMAT_WAVEFORMATEX));
- if (!MixerFormat)
- {
- return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
- }
-
- Status = ComputeCompatibleFormat(Entry, PinConnect->PinId, DeviceExtension,
ClientFormat, MixerFormat);
- if (!NT_SUCCESS(Status))
- {
- ExFreePool(MixerFormat);
- return SetIrpIoStatus(Irp, Status, 0);
- }
- CreateMixerPin = TRUE;
- }
-
if (PinInstances.CurrentCount == PinInstances.PossibleCount)
{
/* pin already exists */
@@ -828,8 +784,6 @@
{
/* 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);
- if (MixerFormat)
- ExFreePool(MixerFormat);
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
}
}
@@ -841,10 +795,7 @@
DispatchContext = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT));
if (!DispatchContext)
{
- if (MixerFormat)
- {
- ExFreePool(MixerFormat);
- }
+ /* no memory */
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
}
@@ -871,9 +822,7 @@
WorkerContext->Irp = Irp;
WorkerContext->PinConnect = PinConnect;
WorkerContext->AudioClient = ClientInfo;
- WorkerContext->CreateMixerPin = CreateMixerPin;
WorkerContext->DeviceExtension = DeviceExtension;
- WorkerContext->MixerFormat = MixerFormat;
DPRINT("Queing Irp %p\n", Irp);
/* queue the work item */
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] Tue Apr 14 18:59:51
2009
@@ -116,9 +116,16 @@
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);
+
+ if (DispatchContext->MixerFileObject)
+ ObDereferenceObject(DispatchContext->MixerFileObject);
+
+ if (DispatchContext->hMixerPin)
+ ZwClose(DispatchContext->hMixerPin);
+
+ if (DispatchContext->FileObject)
+ ObDereferenceObject(DispatchContext->FileObject);
+
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);
@@ -272,7 +279,7 @@
if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN)))
{
Status = CreateDispatcher(Irp);
- DPRINT1("Virtual pin Status %x FileObject %p\n", Status,
IoStatus->FileObject);
+ DPRINT("Virtual pin Status %x FileObject %p\n", Status,
IoStatus->FileObject);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = Status;