diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c index 1a4fc915677..4f82903e306 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -135,7 +135,7 @@ WdmAudControlOpen( IN PWDMAUD_DEVICE_INFO DeviceInfo, IN PWDMAUD_CLIENT ClientInfo) { - PSYSAUDIO_INSTANCE_INFO InstanceInfo; + SYSAUDIO_INSTANCE_INFO InstanceInfo; PWDMAUD_DEVICE_EXTENSION DeviceExtension; ULONG BytesReturned; NTSTATUS Status; @@ -185,21 +185,16 @@ WdmAudControlOpen( } - Length = sizeof(KSDATAFORMAT_WAVEFORMATEX) + sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO); - InstanceInfo = ExAllocatePool(NonPagedPool, Length); - if (!InstanceInfo) + Length = sizeof(KSDATAFORMAT_WAVEFORMATEX) + sizeof(KSPIN_CONNECT); + PinConnect = ExAllocatePool(NonPagedPool, Length); + if (!PinConnect) { /* no memory */ return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); } - InstanceInfo->Property.Set = KSPROPSETID_Sysaudio; - InstanceInfo->Property.Id = KSPROPERTY_SYSAUDIO_INSTANCE_INFO; - InstanceInfo->Property.Flags = KSPROPERTY_TYPE_SET; - InstanceInfo->Flags = 0; - InstanceInfo->DeviceNumber = FilterId; - DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE || DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE || DeviceInfo->DeviceType == MIXER_DEVICE_TYPE) @@ -215,17 +210,14 @@ WdmAudControlOpen( DesiredAccess |= GENERIC_WRITE; } - PinConnect = (KSPIN_CONNECT*)(InstanceInfo + 1); - - PinConnect->Interface.Set = KSINTERFACESETID_Standard; PinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING; PinConnect->Interface.Flags = 0; PinConnect->Medium.Set = KSMEDIUMSETID_Standard; PinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE; PinConnect->Medium.Flags = 0; + PinConnect->PinToHandle = NULL; PinConnect->PinId = PinId; - PinConnect->PinToHandle = DeviceExtension->hSysAudio; PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; PinConnect->Priority.PrioritySubClass = 1; @@ -247,9 +239,29 @@ WdmAudControlOpen( DataFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX; DataFormat->DataFormat.SampleSize = 4; - /* ros specific pin creation request */ - InstanceInfo->Property.Id = (ULONG)-1; - Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, Length, &PinHandle, sizeof(HANDLE), &BytesReturned); + /* setup property request */ + InstanceInfo.Property.Set = KSPROPSETID_Sysaudio; + InstanceInfo.Property.Id = KSPROPERTY_SYSAUDIO_INSTANCE_INFO; + InstanceInfo.Property.Flags = KSPROPERTY_TYPE_SET; + InstanceInfo.Flags = 0; + InstanceInfo.DeviceNumber = FilterId; + + /* first open the virtual device */ + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&InstanceInfo, sizeof(SYSAUDIO_INSTANCE_INFO), NULL, 0, &BytesReturned); + + if (!NT_SUCCESS(Status)) + { + /* failed */ + ExFreePool(PinConnect); + return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO)); + } + + /* now create the pin */ + Status = KsCreatePin(DeviceExtension->hSysAudio, PinConnect, DesiredAccess, &PinHandle); + + /* free create info */ + ExFreePool(PinConnect); + if (NT_SUCCESS(Status)) { PWDMAUD_HANDLE Handels; diff --git a/reactos/drivers/wdm/audio/sysaudio/control.c b/reactos/drivers/wdm/audio/sysaudio/control.c index e3966d5b85c..857662b81be 100644 --- a/reactos/drivers/wdm/audio/sysaudio/control.c +++ b/reactos/drivers/wdm/audio/sysaudio/control.c @@ -18,15 +18,6 @@ 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, @@ -70,11 +61,13 @@ SysAudioOpenVirtualDevice( PSYSAUDIODEVEXT DeviceExtension) { PKSAUDIO_DEVICE_ENTRY Entry; - PKSOBJECT_CREATE_ITEM CreateItem; + PIO_STACK_LOCATION IoStack; - /* access the create item */ - CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); - ASSERT(CreateItem); + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* sanity check */ + ASSERT(IoStack->FileObject); if (DeviceNumber >= DeviceExtension->NumberOfKsAudioDevices) { @@ -86,264 +79,14 @@ SysAudioOpenVirtualDevice( Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, DeviceNumber); ASSERT(Entry != NULL); + /* store device entry in FsContext2 + * see pin.c DispatchCreateSysAudioPin for details + */ + IoStack->FileObject->FsContext2 = (PVOID)Entry; + 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; - DPRINT("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; - DPRINT("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) -{ - 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); - } - - ObDereferenceObject(FileObject); - - *MixerPinHandle = PinHandle; - return Status; -} - - -VOID -NTAPI -CreatePinWorkerRoutine( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context) -{ - NTSTATUS Status; - HANDLE RealPinHandle = NULL, VirtualPinHandle = NULL, Filter; - PFILE_OBJECT VirtualFileObject = NULL; - PKSDATAFORMAT_WAVEFORMATEX InputFormat; - PKSDATAFORMAT_WAVEFORMATEX OutputFormat = NULL; - PKSPIN_CONNECT MixerPinConnect = NULL; - PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context; - - Filter = WorkerContext->PinConnect->PinToHandle; - - WorkerContext->PinConnect->PinToHandle = NULL; - - DPRINT("CreatePinWorkerRoutine entered\n"); - - ASSERT(WorkerContext->Entry); - ASSERT(WorkerContext->PinConnect); - ASSERT(WorkerContext->Entry->Pins); - ASSERT(WorkerContext->Entry->NumberOfPins > WorkerContext->PinConnect->PinId); - - /* Fetch input format */ - InputFormat = (PKSDATAFORMAT_WAVEFORMATEX)(WorkerContext->PinConnect + 1); - - - /* 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); - IoFreeWorkItem(WorkerContext->WorkItem); - ExFreePool(WorkerContext); - return; - } - - /* Zero pin connect */ - RtlZeroMemory(MixerPinConnect, sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX)); - - /* 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, InputFormat, OutputFormat); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ComputeCompatibleFormat failed with %x\n", Status); - SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0); - ExFreePool(WorkerContext->DispatchContext); - ExFreePool(MixerPinConnect); - IoFreeWorkItem(WorkerContext->WorkItem); - ExFreePool(WorkerContext); - return; - } - - /* Retry with Mixer format */ - Status = KsCreatePin(WorkerContext->Entry->Handle, MixerPinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle); //, WorkerContext->Entry->ObjectClass); - if (!NT_SUCCESS(Status)) - { - /* This should not fail */ - DPRINT1("KsCreatePin failed with %x\n", Status); - DPRINT1(" InputFormat: SampleRate %u Bits %u Channels %u\n", InputFormat->WaveFormatEx.nSamplesPerSec, InputFormat->WaveFormatEx.wBitsPerSample, InputFormat->WaveFormatEx.nChannels); - DPRINT1("OutputFormat: SampleRate %u Bits %u Channels %u\n", OutputFormat->WaveFormatEx.nSamplesPerSec, OutputFormat->WaveFormatEx.wBitsPerSample, OutputFormat->WaveFormatEx.nChannels); - - SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0); - ExFreePool(WorkerContext->DispatchContext); - ExFreePool(MixerPinConnect); - IoFreeWorkItem(WorkerContext->WorkItem); - ExFreePool(WorkerContext); - return; - } - } - - ASSERT(WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].MaxPinInstanceCount); - - WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 0; - WorkerContext->DispatchContext->Handle = RealPinHandle; - WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId; - WorkerContext->DispatchContext->AudioEntry = WorkerContext->Entry; - - /* Do we need to transform the audio stream */ - if (OutputFormat != NULL) - { - /* Now create the mixer pin */ - Status = CreateMixerPinAndSetFormat(WorkerContext->DeviceExtension->KMixerHandle, - MixerPinConnect, - (PKSDATAFORMAT)InputFormat, - (PKSDATAFORMAT)OutputFormat, - &WorkerContext->DispatchContext->hMixerPin); - - - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to create Mixer Pin with %x\n", Status); - goto cleanup; - } - - } - - DPRINT1("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); //, L"SysAudio"); - - if (!NT_SUCCESS(Status)) - { - 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*)&VirtualFileObject, NULL); - - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to get file object with %x\n", Status); - goto cleanup; - } - - ASSERT(WorkerContext->Entry->Pins != NULL); - ASSERT(WorkerContext->Entry->NumberOfPins > WorkerContext->PinConnect->PinId); - - /* increment reference count */ - WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References++; - - /* store the pin handle there if the pin can only be instantiated once*/ - WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle = VirtualPinHandle; - - /* store pin context */ - VirtualFileObject->FsContext2 = (PVOID)WorkerContext->DispatchContext; - - /* release virtual file object */ - ObDereferenceObject(VirtualFileObject); - - DPRINT("Successfully created virtual pin %p\n", VirtualPinHandle); - *((PHANDLE)WorkerContext->Irp->UserBuffer) = VirtualPinHandle; - - SetIrpIoStatus(WorkerContext->Irp, STATUS_SUCCESS, sizeof(HANDLE)); - IoFreeWorkItem(WorkerContext->WorkItem); - ExFreePool(WorkerContext); - return; - -cleanup: - if (RealPinHandle) - ZwClose(RealPinHandle); - - if (WorkerContext->DispatchContext->hMixerPin) - ZwClose(WorkerContext->DispatchContext->hMixerPin); - - - ExFreePool(WorkerContext->DispatchContext); - SetIrpIoStatus(WorkerContext->Irp, Status, 0); - IoFreeWorkItem(WorkerContext->WorkItem); - ExFreePool(WorkerContext); -} - NTSTATUS HandleSysAudioFilterPinProperties( PIRP Irp, @@ -382,7 +125,7 @@ HandleSysAudioFilterPinProperties( return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); } - if (Entry->NumberOfPins <= Pin->PinId) + if (Entry->PinDescriptorsCount <= Pin->PinId) { /* invalid pin id */ return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0); @@ -396,7 +139,7 @@ HandleSysAudioFilterPinProperties( return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(ULONG)); } /* store result */ - *((PULONG)Irp->UserBuffer) = Entry->NumberOfPins; + *((PULONG)Irp->UserBuffer) = Entry->PinDescriptorsCount; return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(ULONG)); } else if (Property->Id == KSPROPERTY_PIN_COMMUNICATION) @@ -407,7 +150,7 @@ HandleSysAudioFilterPinProperties( return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPIN_COMMUNICATION)); } /* store result */ - *((KSPIN_COMMUNICATION*)Irp->UserBuffer) = Entry->Pins[Pin->PinId].Communication; + *((KSPIN_COMMUNICATION*)Irp->UserBuffer) = Entry->PinDescriptors[Pin->PinId].Communication; return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(KSPIN_COMMUNICATION)); } @@ -419,7 +162,7 @@ HandleSysAudioFilterPinProperties( return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPIN_DATAFLOW)); } /* store result */ - *((KSPIN_DATAFLOW*)Irp->UserBuffer) = Entry->Pins[Pin->PinId].DataFlow; + *((KSPIN_DATAFLOW*)Irp->UserBuffer) = Entry->PinDescriptors[Pin->PinId].DataFlow; return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(KSPIN_DATAFLOW)); } else @@ -441,7 +184,6 @@ NTSTATUS ComputeCompatibleFormat( IN PKSAUDIO_DEVICE_ENTRY Entry, IN ULONG PinId, - IN PSYSAUDIODEVEXT DeviceExtension, IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat, OUT PKSDATAFORMAT_WAVEFORMATEX MixerFormat) { @@ -591,149 +333,6 @@ GetPinInstanceCount( } -NTSTATUS -HandleSysAudioFilterPinCreation( - PIRP Irp, - PKSPROPERTY Property, - PSYSAUDIODEVEXT DeviceExtension, - PDEVICE_OBJECT DeviceObject) -{ - ULONG Length; - PKSAUDIO_DEVICE_ENTRY Entry; - KSPIN_CONNECT * PinConnect; - PIO_STACK_LOCATION IoStack; - PSYSAUDIO_INSTANCE_INFO InstanceInfo; - PKSOBJECT_CREATE_ITEM CreateItem; - NTSTATUS Status; - KSPIN_CINSTANCES PinInstances; - PPIN_WORKER_CONTEXT WorkerContext; - PDISPATCH_CONTEXT DispatchContext; - PIO_WORKITEM WorkItem; - - IoStack = IoGetCurrentIrpStackLocation(Irp); - - Length = sizeof(KSDATAFORMAT) + sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO); - if (IoStack->Parameters.DeviceIoControl.InputBufferLength < Length || - IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(HANDLE)) - { - /* invalid parameters */ - return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0); - } - - /* access the create item */ - CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); - - /* get input parameter */ - InstanceInfo = (PSYSAUDIO_INSTANCE_INFO)Property; - if (DeviceExtension->NumberOfKsAudioDevices <= InstanceInfo->DeviceNumber) - { - /* invalid parameters */ - return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0); - } - - /* get sysaudio entry */ - Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, InstanceInfo->DeviceNumber); - if (!Entry) - { - /* invalid device index */ - return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0); - } - - if (!Entry->Pins) - { - /* should not happen */ - return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); - } - - /* get connect details */ - PinConnect = (KSPIN_CONNECT*)(InstanceInfo + 1); - - if (Entry->NumberOfPins <= PinConnect->PinId) - { - DPRINT("Invalid PinId %x\n", PinConnect->PinId); - return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0); - } - - /* query instance count */ - Status = GetPinInstanceCount(Entry, &PinInstances, PinConnect); - 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); - } - - if (PinInstances.CurrentCount == PinInstances.PossibleCount) - { - /* pin already exists */ - ASSERT(Entry->Pins[PinConnect->PinId].PinHandle != NULL); - ASSERT(Entry->Pins[PinConnect->PinId].References); - - DPRINT1("Device %u Pin %u References %u is already occupied, try later\n", InstanceInfo->DeviceNumber, PinConnect->PinId, Entry->Pins[PinConnect->PinId].References); - return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); - } - /* create dispatch pin context */ - DispatchContext = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT)); - if (!DispatchContext) - { - /* no memory */ - return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); - } - - /* allocate worker context */ - WorkerContext = ExAllocatePool(NonPagedPool, sizeof(PIN_WORKER_CONTEXT)); - if (!WorkerContext) - { - /* no memory */ - ExFreePool(DispatchContext); - return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); - } - - /* allocate work item */ - WorkItem = IoAllocateWorkItem(DeviceObject); - if (!WorkerContext) - { - /* no memory */ - ExFreePool(DispatchContext); - ExFreePool(WorkerContext); - return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); - } - - /* prepare context */ - RtlZeroMemory(WorkerContext, sizeof(PIN_WORKER_CONTEXT)); - RtlZeroMemory(DispatchContext, sizeof(DISPATCH_CONTEXT)); - - DPRINT("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; - WorkerContext->PinConnect = PinConnect; - WorkerContext->DeviceExtension = DeviceExtension; - WorkerContext->WorkItem = WorkItem; - - DPRINT("Queing Irp %p\n", Irp); - /* queue the work item */ - IoMarkIrpPending(Irp); - Irp->IoStatus.Status = STATUS_PENDING; - Irp->IoStatus.Information = 0; - IoQueueWorkItem(WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)WorkerContext); - - /* mark irp as pending */ - return STATUS_PENDING; -} - NTSTATUS SysAudioHandleProperty( PDEVICE_OBJECT DeviceObject, @@ -874,12 +473,6 @@ SysAudioHandleProperty( return SysAudioOpenVirtualDevice(Irp, InstanceInfo->DeviceNumber, DeviceExtension); } } - else if (Property->Id == (ULONG)-1) - { - /* ros specific pin creation request */ - DPRINT("Initiating create request\n"); - return HandleSysAudioFilterPinCreation(Irp, Property, DeviceExtension, DeviceObject); - } } RtlStringFromGUID(&Property->Set, &GuidString); diff --git a/reactos/drivers/wdm/audio/sysaudio/deviface.c b/reactos/drivers/wdm/audio/sysaudio/deviface.c index d9a85676221..cee9acbdfdd 100644 --- a/reactos/drivers/wdm/audio/sysaudio/deviface.c +++ b/reactos/drivers/wdm/audio/sysaudio/deviface.c @@ -16,19 +16,65 @@ const GUID DMOCATEGORY_ACOUSTIC_ECHO_CANCEL = {0xBF963D80L, 0xC559, 0x11D0, { #define IOCTL_KS_OBJECT_CLASS CTL_CODE(FILE_DEVICE_KS, 0x7, METHOD_NEITHER, FILE_ANY_ACCESS) +NTSTATUS +BuildPinDescriptor( + IN PKSAUDIO_DEVICE_ENTRY DeviceEntry, + IN ULONG Count) +{ + ULONG Index; + KSP_PIN PinRequest; + KSPIN_DATAFLOW DataFlow; + KSPIN_COMMUNICATION Communication; + ULONG NumWaveOutPin, NumWaveInPin; + NTSTATUS Status; + ULONG BytesReturned; + + NumWaveInPin = 0; + NumWaveOutPin = 0; + for(Index = 0; Index < Count; Index++) + { + /* retrieve data flow */ + PinRequest.PinId = Index; + PinRequest.Property.Set = KSPROPSETID_Pin; + PinRequest.Property.Flags = KSPROPERTY_TYPE_GET; + + /* get dataflow direction */ + PinRequest.Property.Id = KSPROPERTY_PIN_DATAFLOW; + Status = KsSynchronousIoControlDevice(DeviceEntry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned); + if (NT_SUCCESS(Status)) + { + DeviceEntry->PinDescriptors[Index].DataFlow = DataFlow; + } + + /* get irp flow direction */ + PinRequest.Property.Id = KSPROPERTY_PIN_COMMUNICATION; + Status = KsSynchronousIoControlDevice(DeviceEntry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned); + if (NT_SUCCESS(Status)) + { + DeviceEntry->PinDescriptors[Index].Communication = Communication; + } + + if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_IN) + NumWaveOutPin++; + + if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_OUT) + NumWaveInPin++; + + /* FIXME query for interface, dataformat etc */ + } + + DPRINT("Num Pins %u Num WaveIn Pins %u Name WaveOut Pins %u\n", DeviceEntry->PinDescriptorsCount, NumWaveInPin, NumWaveOutPin); + return STATUS_SUCCESS; +} + VOID QueryFilterRoutine( IN PKSAUDIO_DEVICE_ENTRY DeviceEntry) { KSPROPERTY PropertyRequest; - KSP_PIN PinRequest; - KSPIN_DATAFLOW DataFlow; - KSPIN_COMMUNICATION Communication; - KSPIN_CINSTANCES PinInstances; - ULONG Count, Index; + ULONG Count; NTSTATUS Status; ULONG BytesReturned; - ULONG NumWaveOutPin, NumWaveInPin; DPRINT("Querying filter...\n"); @@ -50,6 +96,23 @@ QueryFilterRoutine( return; } + /* allocate pin descriptor array */ + DeviceEntry->PinDescriptors = ExAllocatePool(NonPagedPool, Count * sizeof(KSPIN_DESCRIPTOR)); + if (!DeviceEntry->PinDescriptors) + { + /* no memory */ + return; + } + + /* zero array pin descriptor array */ + RtlZeroMemory(DeviceEntry->PinDescriptors, Count * sizeof(KSPIN_DESCRIPTOR)); + + /* build the device descriptor */ + Status = BuildPinDescriptor(DeviceEntry, Count); + if (!NT_SUCCESS(Status)) + return; + + /* allocate pin array */ DeviceEntry->Pins = ExAllocatePool(NonPagedPool, Count * sizeof(PIN_INFO)); if (!DeviceEntry->Pins) @@ -58,51 +121,11 @@ QueryFilterRoutine( DPRINT1("Failed to allocate memory Pins %u Block %x\n", Count, Count * sizeof(PIN_INFO)); return; } + /* clear array */ RtlZeroMemory(DeviceEntry->Pins, sizeof(PIN_INFO) * Count); - DeviceEntry->NumberOfPins = Count; + DeviceEntry->PinDescriptorsCount = Count; - NumWaveInPin = 0; - NumWaveOutPin = 0; - for(Index = 0; Index < Count; Index++) - { - /* get max instance count */ - PinRequest.PinId = Index; - PinRequest.Property.Set = KSPROPSETID_Pin; - PinRequest.Property.Flags = KSPROPERTY_TYPE_GET; - PinRequest.Property.Id = KSPROPERTY_PIN_CINSTANCES; - - Status = KsSynchronousIoControlDevice(DeviceEntry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&PinInstances, sizeof(KSPIN_CINSTANCES), &BytesReturned); - if (NT_SUCCESS(Status)) - { - DeviceEntry->Pins[Index].MaxPinInstanceCount = PinInstances.PossibleCount; - } - - /* get dataflow direction */ - PinRequest.Property.Id = KSPROPERTY_PIN_DATAFLOW; - Status = KsSynchronousIoControlDevice(DeviceEntry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned); - if (NT_SUCCESS(Status)) - { - DeviceEntry->Pins[Index].DataFlow = DataFlow; - } - - /* get irp flow direction */ - PinRequest.Property.Id = KSPROPERTY_PIN_COMMUNICATION; - Status = KsSynchronousIoControlDevice(DeviceEntry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned); - if (NT_SUCCESS(Status)) - { - DeviceEntry->Pins[Index].Communication = Communication; - } - - if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_IN) - NumWaveOutPin++; - - if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_OUT) - NumWaveInPin++; - - } - - DPRINT("Num Pins %u Num WaveIn Pins %u Name WaveOut Pins %u\n", DeviceEntry->NumberOfPins, NumWaveInPin, NumWaveOutPin); } VOID diff --git a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c index f3731433e3d..d2ee704aee2 100644 --- a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c +++ b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c @@ -29,44 +29,6 @@ Dispatch_fnDeviceIoControl( return STATUS_UNSUCCESSFUL; } -NTSTATUS -NTAPI -Dispatch_fnRead( - PDEVICE_OBJECT DeviceObject, - PIRP Irp) -{ - /* unsupported request */ - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; -} - -NTSTATUS -NTAPI -Dispatch_fnWrite( - PDEVICE_OBJECT DeviceObject, - PIRP Irp) -{ - /* unsupported request */ - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; -} - -NTSTATUS -NTAPI -Dispatch_fnFlush( - PDEVICE_OBJECT DeviceObject, - PIRP Irp) -{ - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; -} - NTSTATUS NTAPI Dispatch_fnClose( @@ -81,123 +43,20 @@ Dispatch_fnClose( return STATUS_SUCCESS; } -NTSTATUS -NTAPI -Dispatch_fnQuerySecurity( - PDEVICE_OBJECT DeviceObject, - PIRP Irp) -{ - DPRINT("Dispatch_fnQuerySecurity called DeviceObject %p Irp %p\n", DeviceObject); - - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; -} - -NTSTATUS -NTAPI -Dispatch_fnSetSecurity( - PDEVICE_OBJECT DeviceObject, - PIRP Irp) -{ - - DPRINT("Dispatch_fnSetSecurity called DeviceObject %p Irp %p\n", DeviceObject); - - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; -} - -BOOLEAN -NTAPI -Dispatch_fnFastDeviceIoControl( - PFILE_OBJECT FileObject, - BOOLEAN Wait, - PVOID InputBuffer, - ULONG InputBufferLength, - PVOID OutputBuffer, - ULONG OutputBufferLength, - ULONG IoControlCode, - PIO_STATUS_BLOCK IoStatus, - PDEVICE_OBJECT DeviceObject) -{ - DPRINT("Dispatch_fnFastDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject); - - - return FALSE; -} - - -BOOLEAN -NTAPI -Dispatch_fnFastRead( - PFILE_OBJECT FileObject, - PLARGE_INTEGER FileOffset, - ULONG Length, - BOOLEAN Wait, - ULONG LockKey, - PVOID Buffer, - PIO_STATUS_BLOCK IoStatus, - PDEVICE_OBJECT DeviceObject) -{ - DPRINT("Dispatch_fnFastRead called DeviceObject %p Irp %p\n", DeviceObject); - - return FALSE; - -} - -BOOLEAN -NTAPI -Dispatch_fnFastWrite( - PFILE_OBJECT FileObject, - PLARGE_INTEGER FileOffset, - ULONG Length, - BOOLEAN Wait, - ULONG LockKey, - PVOID Buffer, - PIO_STATUS_BLOCK IoStatus, - PDEVICE_OBJECT DeviceObject) -{ - DPRINT("Dispatch_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject); - - return FALSE; -} - static KSDISPATCH_TABLE DispatchTable = { Dispatch_fnDeviceIoControl, - Dispatch_fnRead, - Dispatch_fnWrite, - Dispatch_fnFlush, + KsDispatchInvalidDeviceRequest, + KsDispatchInvalidDeviceRequest, + KsDispatchInvalidDeviceRequest, Dispatch_fnClose, - Dispatch_fnQuerySecurity, - Dispatch_fnSetSecurity, - Dispatch_fnFastDeviceIoControl, - Dispatch_fnFastRead, - Dispatch_fnFastWrite, + KsDispatchInvalidDeviceRequest, + KsDispatchInvalidDeviceRequest, + KsDispatchFastIoDeviceControlFailure, + KsDispatchFastReadFailure, + KsDispatchFastWriteFailure, }; -NTSTATUS -NTAPI -DispatchCreateSysAudioPin( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - NTSTATUS Status; - - DPRINT("DispatchCreateSysAudio entered\n"); - /* create the virtual pin */ - Status = CreateSysAudioPin(Irp); - - /* store result */ - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return Status; -} - NTSTATUS NTAPI DispatchCreateSysAudio( @@ -208,9 +67,7 @@ DispatchCreateSysAudio( KSOBJECT_HEADER ObjectHeader; PKSOBJECT_CREATE_ITEM CreateItem; - static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}"; - - DPRINT("DispatchCreateSysAudio entered\n"); + DPRINT1("DispatchCreateSysAudio entered\n"); /* allocate create item */ CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM)); @@ -227,12 +84,12 @@ DispatchCreateSysAudio( /* setup create context */ CreateItem->Create = DispatchCreateSysAudioPin; - RtlInitUnicodeString(&CreateItem->ObjectClass, KS_NAME_PIN); + RtlInitUnicodeString(&CreateItem->ObjectClass, KSSTRING_Pin); /* allocate object header */ Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable); - DPRINT("KsAllocateObjectHeader result %x\n", Status); + DPRINT1("KsAllocateObjectHeader result %x\n", Status); /* complete the irp */ Irp->IoStatus.Information = 0; Irp->IoStatus.Status = Status; diff --git a/reactos/drivers/wdm/audio/sysaudio/pin.c b/reactos/drivers/wdm/audio/sysaudio/pin.c index 2ed463b96f6..fd321ea9c54 100644 --- a/reactos/drivers/wdm/audio/sysaudio/pin.c +++ b/reactos/drivers/wdm/audio/sysaudio/pin.c @@ -420,13 +420,287 @@ static KSDISPATCH_TABLE PinTable = }; NTSTATUS -CreateSysAudioPin( - IN PIRP Irp) +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; + DPRINT("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; + DPRINT("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) { 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); + } + + ObDereferenceObject(FileObject); + + *MixerPinHandle = PinHandle; + return Status; +} + + +NTSTATUS +NTAPI +InstantiatePins( + IN PKSAUDIO_DEVICE_ENTRY DeviceEntry, + IN PKSPIN_CONNECT Connect, + IN PDISPATCH_CONTEXT DispatchContext, + IN PSYSAUDIODEVEXT DeviceExtension) +{ + NTSTATUS Status; + HANDLE RealPinHandle; + PKSDATAFORMAT_WAVEFORMATEX InputFormat; + PKSDATAFORMAT_WAVEFORMATEX OutputFormat = NULL; + PKSPIN_CONNECT MixerPinConnect = NULL; + KSPIN_CINSTANCES PinInstances; + + DPRINT("InstantiatePins entered\n"); + + /* query instance count */ + Status = GetPinInstanceCount(DeviceEntry, &PinInstances, Connect); + if (!NT_SUCCESS(Status)) + { + /* failed to query instance count */ + return Status; + } + + /* can be the pin be instantiated */ + if (PinInstances.PossibleCount == 0) + { + /* caller wanted to open an instance-less pin */ + return STATUS_UNSUCCESSFUL; + } + + /* has the maximum instance count been exceeded */ + if (PinInstances.CurrentCount == PinInstances.PossibleCount) + { + /* FIXME pin already exists + * and kmixer infrastructure is not implemented + */ + return STATUS_UNSUCCESSFUL; + } + + /* Fetch input format */ + InputFormat = (PKSDATAFORMAT_WAVEFORMATEX)(Connect + 1); + + /* Let's try to create the audio irp pin */ + Status = KsCreatePin(DeviceEntry->Handle, Connect, 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) + { + /* not enough memory */ + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Zero pin connect */ + RtlZeroMemory(MixerPinConnect, sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX)); + + /* Copy initial connect details */ + RtlMoveMemory(MixerPinConnect, Connect, sizeof(KSPIN_CONNECT)); + + + OutputFormat = (PKSDATAFORMAT_WAVEFORMATEX)(MixerPinConnect + 1); + + Status = ComputeCompatibleFormat(DeviceEntry, Connect->PinId, InputFormat, OutputFormat); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ComputeCompatibleFormat failed with %x\n", Status); + ExFreePool(MixerPinConnect); + return Status; + } + + /* Retry with Mixer format */ + Status = KsCreatePin(DeviceEntry->Handle, MixerPinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle); + if (!NT_SUCCESS(Status)) + { + /* This should not fail */ + DPRINT1("KsCreatePin failed with %x\n", Status); + DPRINT1(" InputFormat: SampleRate %u Bits %u Channels %u\n", InputFormat->WaveFormatEx.nSamplesPerSec, InputFormat->WaveFormatEx.wBitsPerSample, InputFormat->WaveFormatEx.nChannels); + DPRINT1("OutputFormat: SampleRate %u Bits %u Channels %u\n", OutputFormat->WaveFormatEx.nSamplesPerSec, OutputFormat->WaveFormatEx.wBitsPerSample, OutputFormat->WaveFormatEx.nChannels); + + ExFreePool(MixerPinConnect); + return Status; + } + } + + DeviceEntry->Pins[Connect->PinId].References = 0; + + /* initialize dispatch context */ + DispatchContext->Handle = RealPinHandle; + DispatchContext->PinId = Connect->PinId; + DispatchContext->AudioEntry = DeviceEntry; + + + /* Do we need to transform the audio stream */ + if (OutputFormat != NULL) + { + /* Now create the mixer pin */ + Status = CreateMixerPinAndSetFormat(DeviceExtension->KMixerHandle, + MixerPinConnect, + (PKSDATAFORMAT)InputFormat, + (PKSDATAFORMAT)OutputFormat, + &DispatchContext->hMixerPin); + + /* check for success */ + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create Mixer Pin with %x\n", Status); + ExFreePool(MixerPinConnect); + } + } + /* done */ + return Status; +} + +NTSTATUS +NTAPI +DispatchCreateSysAudioPin( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + NTSTATUS Status = STATUS_SUCCESS; KSOBJECT_HEADER ObjectHeader; + PIO_STACK_LOCATION IoStack; + PKSAUDIO_DEVICE_ENTRY DeviceEntry; + PKSPIN_CONNECT Connect = NULL; + PDISPATCH_CONTEXT DispatchContext; + + DPRINT("DispatchCreateSysAudioPin entered\n"); + + /* get current stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* sanity checks */ + ASSERT(IoStack->FileObject); + ASSERT(IoStack->FileObject->RelatedFileObject); + ASSERT(IoStack->FileObject->RelatedFileObject->FsContext2); + + /* get current attached virtual device */ + DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)IoStack->FileObject->RelatedFileObject->FsContext2; + + /* now validate pin connect request */ + Status = KsValidateConnectRequest(Irp, DeviceEntry->PinDescriptorsCount, DeviceEntry->PinDescriptors, &Connect); + + /* check for success */ + if (!NT_SUCCESS(Status)) + { + /* failed */ + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + + /* allocate dispatch context */ + DispatchContext = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT)); + if (!DispatchContext) + { + /* failed */ + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* zero dispatch context */ + RtlZeroMemory(DispatchContext, sizeof(DISPATCH_CONTEXT)); /* allocate object header */ Status = KsAllocateObjectHeader(&ObjectHeader, 0, NULL, Irp, &PinTable); + if (!NT_SUCCESS(Status)) + { + /* failed */ + ExFreePool(DispatchContext); + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + + /* now instantiate the pins */ + Status = InstantiatePins(DeviceEntry, Connect, DispatchContext, (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension); + if (!NT_SUCCESS(Status)) + { + /* failed */ + KsFreeObjectHeader(ObjectHeader); + ExFreePool(DispatchContext); + } + else + { + /* store dispatch context */ + IoStack->FileObject->FsContext2 = (PVOID)DispatchContext; + } + + + /* FIXME create items for clocks / allocators */ + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } diff --git a/reactos/drivers/wdm/audio/sysaudio/sysaudio.h b/reactos/drivers/wdm/audio/sysaudio/sysaudio.h index cf1bb01fb63..0cf0ec17f4f 100644 --- a/reactos/drivers/wdm/audio/sysaudio/sysaudio.h +++ b/reactos/drivers/wdm/audio/sysaudio/sysaudio.h @@ -13,11 +13,8 @@ typedef struct { - ULONG MaxPinInstanceCount; // maximum times a audio irp pin can be instantiated HANDLE PinHandle; // handle to audio irp pin ULONG References; // number of clients having a reference to this audio irp pin - KSPIN_DATAFLOW DataFlow; // specifies data flow - KSPIN_COMMUNICATION Communication; // pin type }PIN_INFO; typedef struct @@ -28,9 +25,9 @@ typedef struct HANDLE Handle; // handle to audio sub device PFILE_OBJECT FileObject; // file objecto to audio sub device - ULONG NumberOfPins; // number of pins of audio device PIN_INFO * Pins; // array of PIN_INFO - + ULONG PinDescriptorsCount; // number of pin descriptors + KSPIN_DESCRIPTOR *PinDescriptors; // pin descriptors array }KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY; typedef struct @@ -65,24 +62,6 @@ typedef struct HANDLE hMixerPin; // handle to mixer pin }DISPATCH_CONTEXT, *PDISPATCH_CONTEXT; -// struct PIN_WORKER_CONTEXT -// -// This structure holds all information required -// to create audio irp pin, mixer pin and virtual sysaudio pin -// -typedef struct -{ - PIRP Irp; - BOOL CreateRealPin; - BOOL CreateMixerPin; - PKSAUDIO_DEVICE_ENTRY Entry; - KSPIN_CONNECT * PinConnect; - PDISPATCH_CONTEXT DispatchContext; - PSYSAUDIODEVEXT DeviceExtension; - PKSDATAFORMAT_WAVEFORMATEX MixerFormat; - PIO_WORKITEM WorkItem; -}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT; - typedef struct { PIO_WORKITEM WorkItem; @@ -131,12 +110,28 @@ GetListEntry( IN ULONG Index); NTSTATUS -CreateSysAudioPin( - IN PIRP Irp); +NTAPI +DispatchCreateSysAudioPin( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); ULONG GetDeviceCount( PSYSAUDIODEVEXT DeviceExtension, BOOL WaveIn); +NTSTATUS +GetPinInstanceCount( + PKSAUDIO_DEVICE_ENTRY Entry, + PKSPIN_CINSTANCES PinInstances, + PKSPIN_CONNECT PinConnect); + +NTSTATUS +ComputeCompatibleFormat( + IN PKSAUDIO_DEVICE_ENTRY Entry, + IN ULONG PinId, + IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat, + OUT PKSDATAFORMAT_WAVEFORMATEX MixerFormat); + + #endif