diff --git a/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c b/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c index b040ed082c9..ec93086a565 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c @@ -106,7 +106,7 @@ HandleDataIntersection( } /* Access parameters */ - MultipleItem = (PKSMULTIPLE_ITEM)(Request + 1); + MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1); DataRange = (PKSDATARANGE)(MultipleItem + 1); /* Get current stack location */ @@ -115,7 +115,9 @@ HandleDataIntersection( 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) diff --git a/reactos/drivers/wdm/audio/sysaudio/control.c b/reactos/drivers/wdm/audio/sysaudio/control.c index bc9969d5148..613304dc84d 100644 --- a/reactos/drivers/wdm/audio/sysaudio/control.c +++ b/reactos/drivers/wdm/audio/sysaudio/control.c @@ -17,6 +17,15 @@ const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, 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( IN PIRP Irp, @@ -187,17 +196,14 @@ CreatePinWorkerRoutine( IN PVOID Context) { NTSTATUS Status; - PSYSAUDIO_CLIENT AudioClient; - HANDLE RealPinHandle, VirtualPinHandle; - HANDLE Filter; ULONG NumHandels; - PFILE_OBJECT FileObject; + HANDLE RealPinHandle = NULL, VirtualPinHandle = NULL, Filter; + PFILE_OBJECT RealFileObject = NULL, VirtualFileObject = NULL; + PSYSAUDIO_CLIENT AudioClient; 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 @@ CreatePinWorkerRoutine( ASSERT(WorkerContext->Entry->Pins); ASSERT(WorkerContext->Entry->NumberOfPins > WorkerContext->PinConnect->PinId); - PinConnect = WorkerContext->PinConnect; - ClientFormat = (PKSDATAFORMAT)(PinConnect + 1); + /* Let's try to create the audio irp pin */ + Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle); - if (WorkerContext->CreateMixerPin) + if (!NT_SUCCESS(Status)) { - PinConnect = ExAllocatePool(NonPagedPool, sizeof(KSPIN_CONNECT) + WorkerContext->MixerFormat->DataFormat.FormatSize); - if (!PinConnect) + /* 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) { - /* no memory */ - SetIrpIoStatus(WorkerContext->Irp, STATUS_NO_MEMORY, 0); + SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0); ExFreePool(WorkerContext->DispatchContext); - ExFreePool(WorkerContext->MixerFormat); return; } - RtlMoveMemory(PinConnect, WorkerContext->PinConnect, sizeof(KSPIN_CONNECT)); - RtlMoveMemory((PinConnect + 1), WorkerContext->MixerFormat, WorkerContext->MixerFormat->DataFormat.FormatSize); + /* Copy initial connect details */ + RtlMoveMemory(MixerPinConnect, WorkerContext->PinConnect, sizeof(KSPIN_CONNECT)); - Status = CreateMixerPinAndSetFormat(WorkerContext->DeviceExtension->KMixerHandle, - PinConnect, - (PKSDATAFORMAT)(WorkerContext->PinConnect + 1), - (PKSDATAFORMAT)WorkerContext->MixerFormat, + + 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); - ExFreePool(WorkerContext->MixerFormat); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to create Mixer Pin with %x\n", Status); - SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0); - ExFreePool(WorkerContext->DispatchContext); - return; + goto cleanup; } - } - 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); - 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); } @@ -362,37 +314,21 @@ CreatePinWorkerRoutine( 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; + goto cleanup; } - ASSERT(WorkerContext->DispatchContext); - ASSERT(WorkerContext->DispatchContext->AudioEntry != NULL); - ASSERT(WorkerContext->DispatchContext->FileObject != NULL); - ASSERT(WorkerContext->DispatchContext->Handle != NULL); ASSERT(WorkerContext->AudioClient); ASSERT(WorkerContext->AudioClient->NumDevices > 0); ASSERT(WorkerContext->AudioClient->Devs != NULL); @@ -439,15 +375,39 @@ CreatePinWorkerRoutine( 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 @@ HandleSysAudioFilterPinProperties( } } -BOOL + +NTSTATUS ComputeCompatibleFormat( IN PKSAUDIO_DEVICE_ENTRY Entry, IN ULONG PinId, @@ -552,41 +513,63 @@ ComputeCompatibleFormat( { BOOL bFound; ULONG BytesReturned; - KSP_PIN PinRequest; - PKSDATARANGE_AUDIO AudioRange; + PKSP_PIN PinRequest; NTSTATUS Status; - ULONG Index; PKSMULTIPLE_ITEM MultipleItem; + ULONG Length; + PKSDATARANGE_AUDIO AudioRange; + ULONG Index; - 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_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; } - PinRequest.PinId = PinId; - PinRequest.Property.Set = KSPROPSETID_Pin; - PinRequest.Property.Flags = KSPROPERTY_TYPE_GET; - PinRequest.Property.Id = KSPROPERTY_PIN_DATARANGES; + /* 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); - 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 @@ ComputeCompatibleFormat( 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 @@ ComputeCompatibleFormat( 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,16 +603,19 @@ ComputeCompatibleFormat( 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); + 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); + ExFreePool(PinRequest); + if (bFound) return STATUS_SUCCESS; else @@ -678,10 +665,18 @@ CloseExistingPin( 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 @@ HandleSysAudioFilterPinCreation( 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 @@ HandleSysAudioFilterPinCreation( 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 @@ HandleSysAudioFilterPinCreation( { /* 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 @@ HandleSysAudioFilterPinCreation( 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 @@ HandleSysAudioFilterPinCreation( 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 */ diff --git a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c index 67c0a8e0fd4..fb7700a683c 100644 --- a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c +++ b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c @@ -116,9 +116,16 @@ Dispatch_fnClose( 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 @@ DispatchCreateSysAudio( 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;