diff --git a/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c index bd85b964d47..eaa64ce9365 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c @@ -133,7 +133,7 @@ IPortFilterWaveCyclic_fnNewIrpTarget( } /* - * @unimplemented + * @implemented */ NTSTATUS NTAPI @@ -142,8 +142,23 @@ IPortFilterWaveCyclic_fnDeviceIoControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { + PIO_STACK_LOCATION IoStack; + ISubdevice *SubDevice = NULL; + SUBDEVICE_DESCRIPTOR * Descriptor; - return STATUS_UNSUCCESSFUL; + IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl *)iface; + + IoStack = IoGetCurrentIrpStackLocation(Irp); + ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY); + ASSERT(This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&SubDevice) == STATUS_SUCCESS); + ASSERT(SubDevice != NULL); + + ASSERT(SubDevice->lpVtbl->GetDescriptor(SubDevice, &Descriptor) == STATUS_SUCCESS); + ASSERT(Descriptor != NULL); + + SubDevice->lpVtbl->Release(SubDevice); + + return PcPropertyHandler(Irp, Descriptor); } /* diff --git a/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h b/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h index a5634f34486..43fdf227cd3 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h +++ b/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h @@ -97,11 +97,22 @@ DECLARE_INTERFACE_(IIrpTarget, IUnknown) struct IIrpTargetFactory; +typedef struct +{ + ULONG MaxGlobalInstanceCount; + ULONG MaxFilterInstanceCount; + ULONG MinFilterInstanceCount; + ULONG CurrentFilterInstanceCount; + +}PIN_INSTANCE_INFO, *PPIN_INSTANCE_INFO; + + typedef struct { ULONG PinDescriptorCount; ULONG PinDescriptorSize; KSPIN_DESCRIPTOR * KsPinDescriptor; + PIN_INSTANCE_INFO * Instances; }KSPIN_FACTORY; typedef struct diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c b/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c index 8de27c2c2c4..4ba0ae9d78b 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c @@ -486,8 +486,10 @@ PcCreateItemDispatch( ISubdevice * SubDevice; PPCLASS_DEVICE_EXTENSION DeviceExt; SUBDEVICE_ENTRY * Entry; - IIrpTarget *Filter, *Pin; + IIrpTarget *Filter; PKSOBJECT_CREATE_ITEM CreateItem; + PPIN_WORKER_CONTEXT Context; + PIO_WORKITEM WorkItem; DPRINT1("PcCreateItemDispatch called DeviceObject %p\n", DeviceObject); @@ -567,7 +569,6 @@ PcCreateItemDispatch( } else { - KSOBJECT_CREATE Create; LPWSTR Buffer = IoStack->FileObject->FileName.Buffer; static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}"; @@ -576,51 +577,33 @@ PcCreateItemDispatch( if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN))) { /* try to create new pin */ - - if (KeGetCurrentIrql() >= APC_LEVEL) - { - PPIN_WORKER_CONTEXT Context = AllocateItem(NonPagedPool, sizeof(PIN_WORKER_CONTEXT), TAG_PORTCLASS); - if (!Context) - { - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - return STATUS_INSUFFICIENT_RESOURCES; - } - Context->Filter = Filter; - Context->Irp = Irp; - - PIO_WORKITEM WorkItem = IoAllocateWorkItem(DeviceObject); - if (!WorkItem) - { - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - return STATUS_INSUFFICIENT_RESOURCES; - } - - IoQueueWorkItem(WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context); - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_PENDING; - IoMarkIrpPending(Irp); - return STATUS_PENDING; - } - - Create.CreateItemsCount = 1; - Create.CreateItemsList = (PKSOBJECT_CREATE_ITEM)(IoStack->FileObject->FileName.Buffer + (wcslen(KS_NAME_PIN) + 1)); - - Status = Filter->lpVtbl->NewIrpTarget(Filter, - &Pin, - KS_NAME_PIN, - NULL, - NonPagedPool, - DeviceObject, - Irp, - &Create); - if (NT_SUCCESS(Status)) + Context = AllocateItem(NonPagedPool, sizeof(PIN_WORKER_CONTEXT), TAG_PORTCLASS); + if (!Context) { - /* create the dispatch object */ - Status = NewDispatchObject(Irp, Pin); - DPRINT1("Pin %p\n", Pin); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; } + Context->Filter = Filter; + Context->Irp = Irp; + + WorkItem = IoAllocateWorkItem(DeviceObject); + if (!WorkItem) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + FreeItem(Context, TAG_PORTCLASS); + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + DPRINT1("Queueing IRP %p\n", Irp); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_PENDING; + IoMarkIrpPending(Irp); + IoQueueWorkItem(WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context); + + return STATUS_PENDING; } } Irp->IoStatus.Information = 0; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/private.h b/reactos/drivers/wdm/audio/backpln/portcls/private.h index 1e09b88ba49..a858390e73b 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/private.h +++ b/reactos/drivers/wdm/audio/backpln/portcls/private.h @@ -220,5 +220,11 @@ PcCreateItemDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); +NTSTATUS +NTAPI +PcPropertyHandler( + IN PIRP Irp, + IN PSUBDEVICE_DESCRIPTOR Descriptor); + #endif diff --git a/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c b/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c index 6d936d1d8c3..3650a3f48a9 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c @@ -1,5 +1,63 @@ #include "private.h" +NTSTATUS +HandlePropertyInstances( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data, + IN PSUBDEVICE_DESCRIPTOR Descriptor, + IN BOOL Global) +{ + KSPIN_CINSTANCES * Instances; + KSP_PIN * Pin = (KSP_PIN*)Request; + + if (Pin->PinId >= Descriptor->Factory.PinDescriptorCount) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + return STATUS_INVALID_PARAMETER; + } + + Instances = (KSPIN_CINSTANCES*)Data; + + if (Global) + Instances->PossibleCount = Descriptor->Factory.Instances[Pin->PinId].MaxGlobalInstanceCount; + else + Instances->PossibleCount = Descriptor->Factory.Instances[Pin->PinId].MaxFilterInstanceCount; + + Instances->CurrentCount = Descriptor->Factory.Instances[Pin->PinId].CurrentFilterInstanceCount; + + Irp->IoStatus.Information = sizeof(KSPIN_CINSTANCES); + Irp->IoStatus.Status = STATUS_SUCCESS; + return STATUS_SUCCESS; +} + +NTSTATUS +HandleNecessaryPropertyInstances( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data, + IN PSUBDEVICE_DESCRIPTOR Descriptor) +{ + PULONG Result; + KSP_PIN * Pin = (KSP_PIN*)Request; + + if (Pin->PinId >= Descriptor->Factory.PinDescriptorCount) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + return STATUS_INVALID_PARAMETER; + } + + Result = (PULONG)Data; + *Result = Descriptor->Factory.Instances[Pin->PinId].MinFilterInstanceCount; + + Irp->IoStatus.Information = sizeof(ULONG); + Irp->IoStatus.Status = STATUS_SUCCESS; + return STATUS_SUCCESS; +} + + NTSTATUS NTAPI PinPropertyHandler( @@ -7,8 +65,12 @@ PinPropertyHandler( IN PKSIDENTIFIER Request, IN OUT PVOID Data) { + PSUBDEVICE_DESCRIPTOR Descriptor; NTSTATUS Status = STATUS_UNSUCCESSFUL; + Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); + ASSERT(Descriptor); + switch(Request->Id) { case KSPROPERTY_PIN_CTYPES: @@ -19,12 +81,19 @@ PinPropertyHandler( case KSPROPERTY_PIN_COMMUNICATION: case KSPROPERTY_PIN_CATEGORY: case KSPROPERTY_PIN_NAME: - // KsPinPropertyHandler + Status = KsPinPropertyHandler(Irp, Request, Data, Descriptor->Factory.PinDescriptorCount, Descriptor->Factory.KsPinDescriptor); break; - case KSPROPERTY_PIN_DATAINTERSECTION: - case KSPROPERTY_PIN_CINSTANCES: case KSPROPERTY_PIN_GLOBALCINSTANCES: + Status = HandlePropertyInstances(Irp, Request, Data, Descriptor, TRUE); + break; + case KSPROPERTY_PIN_CINSTANCES: + Status = HandlePropertyInstances(Irp, Request, Data, Descriptor, FALSE); + break; case KSPROPERTY_PIN_NECESSARYINSTANCES: + Status = HandleNecessaryPropertyInstances(Irp, Request, Data, Descriptor); + break; + + case KSPROPERTY_PIN_DATAINTERSECTION: case KSPROPERTY_PIN_PHYSICALCONNECTION: case KSPROPERTY_PIN_CONSTRAINEDDATARANGES: DPRINT1("Unhandled %x\n", Request->Id); @@ -52,3 +121,85 @@ TopologyPropertyHandler( NULL /* FIXME */); } +NTSTATUS +NTAPI +PcPropertyHandler( + IN PIRP Irp, + IN PSUBDEVICE_DESCRIPTOR Descriptor) +{ + ULONG Index, ItemIndex; + PIO_STACK_LOCATION IoStack; + PKSPROPERTY Property; + PFNKSHANDLER PropertyHandler = NULL; + UNICODE_STRING GuidString; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + + IoStack = IoGetCurrentIrpStackLocation(Irp); + + Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + ASSERT(Property); + + DPRINT1("Num of Property Sets %u\n", Descriptor->FilterPropertySet.FreeKsPropertySetOffset); + for(Index = 0; Index < Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++) + { + RtlStringFromGUID ((GUID*)Descriptor->FilterPropertySet.Properties[Index].Set, &GuidString); + DPRINT1("Current GUID %S\n", GuidString.Buffer); + RtlFreeUnicodeString(&GuidString); + + if (IsEqualGUIDAligned(&Property->Set, Descriptor->FilterPropertySet.Properties[Index].Set)) + { + DPRINT1("Found Property Set Properties %u\n", Descriptor->FilterPropertySet.Properties[Index].PropertiesCount); + for(ItemIndex = 0; ItemIndex < Descriptor->FilterPropertySet.Properties[Index].PropertiesCount; ItemIndex++) + { + if (Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].PropertyId == Property->Id) + { + DPRINT1("Found property set identifier %u\n", Property->Id); + if (Property->Flags & KSPROPERTY_TYPE_SET) + PropertyHandler = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].SetPropertyHandler; + + if (Property->Flags & KSPROPERTY_TYPE_GET) + PropertyHandler = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].GetPropertyHandler; + + if (Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinProperty > IoStack->Parameters.DeviceIoControl.InputBufferLength) + { + /* too small input buffer */ + Irp->IoStatus.Information = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinProperty; + Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + return STATUS_BUFFER_TOO_SMALL; + } + + if (Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinData > IoStack->Parameters.DeviceIoControl.OutputBufferLength) + { + /* too small output buffer */ + Irp->IoStatus.Information = Descriptor->FilterPropertySet.Properties[Index].PropertyItem[ItemIndex].MinData; + Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + return STATUS_BUFFER_TOO_SMALL; + } + + if (PropertyHandler) + { + KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PVOID)Descriptor; + DPRINT1("Calling property handler %p\n", PropertyHandler); + Status = PropertyHandler(Irp, Property, Irp->UserBuffer); + } + + /* the information member is set by the handler */ + Irp->IoStatus.Status = Status; + DPRINT1("Result %x\n", Status); + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + } + } + } + + RtlStringFromGUID(&Property->Set, &GuidString); + DPRINT1("Unhandeled property: Set %S Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); + DbgBreakPoint(); + RtlFreeUnicodeString(&GuidString); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + + diff --git a/reactos/drivers/wdm/audio/backpln/portcls/undoc.c b/reactos/drivers/wdm/audio/backpln/portcls/undoc.c index 54948526270..61b6de72c56 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/undoc.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/undoc.c @@ -108,7 +108,17 @@ AddToPropertyTable( RtlMoveMemory((PVOID)Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].PropertyItem, FilterProperty->PropertyItem, sizeof(KSPROPERTY_ITEM) * FilterProperty->PropertiesCount); + } + Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].Set = AllocateItem(NonPagedPool, sizeof(GUID), TAG_PORTCLASS); + if (!Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].Set) + return STATUS_INSUFFICIENT_RESOURCES; + + RtlCopyMemory((PVOID)Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].Set, FilterProperty->Set, sizeof(GUID)); + + /* ignore fast io table for now */ + Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].FastIoCount = 0; + Descriptor->FilterPropertySet.Properties[Descriptor->FilterPropertySet.FreeKsPropertySetOffset].FastIoTable = NULL; Descriptor->FilterPropertySet.FreeKsPropertySetOffset++; @@ -177,12 +187,22 @@ PcCreateSubdeviceDescriptor( if (!Descriptor->Factory.KsPinDescriptor) goto cleanup; + Descriptor->Factory.Instances = AllocateItem(NonPagedPool, FilterDescription->PinCount * sizeof(PIN_INSTANCE_INFO), TAG_PORTCLASS); + if (!Descriptor->Factory.Instances) + goto cleanup; + Descriptor->Factory.PinDescriptorCount = FilterDescription->PinCount; Descriptor->Factory.PinDescriptorSize = FilterDescription->PinSize; /* copy pin factories */ for(Index = 0; Index < FilterDescription->PinCount; Index++) + { RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &FilterDescription->Pins[Index].KsPinDescriptor, FilterDescription->PinSize); + Descriptor->Factory.Instances[Index].CurrentFilterInstanceCount = 0; + Descriptor->Factory.Instances[Index].MaxFilterInstanceCount = FilterDescription->Pins[Index].MaxFilterInstanceCount; + Descriptor->Factory.Instances[Index].MaxGlobalInstanceCount = FilterDescription->Pins[Index].MaxGlobalInstanceCount; + Descriptor->Factory.Instances[Index].MinFilterInstanceCount = FilterDescription->Pins[Index].MinFilterInstanceCount; + } } *OutSubdeviceDescriptor = Descriptor; diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c index b16cd8ef653..2328a6a9f39 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -44,6 +44,7 @@ WdmAudControlOpen( ACCESS_MASK DesiredAccess = 0; HANDLE PinHandle; KSPIN_CONNECT * PinConnect; + ULONG Length; KSDATAFORMAT_WAVEFORMATEX * DataFormat; if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE) @@ -52,7 +53,8 @@ WdmAudControlOpen( return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); } - InstanceInfo = ExAllocatePool(NonPagedPool, sizeof(KSDATAFORMAT_WAVEFORMATEX) + sizeof(KSPIN_CONNECT)); + Length = sizeof(KSDATAFORMAT_WAVEFORMATEX) + sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO); + InstanceInfo = ExAllocatePool(NonPagedPool, Length); if (!InstanceInfo) { /* no memory */ @@ -90,7 +92,7 @@ WdmAudControlOpen( DesiredAccess |= GENERIC_WRITE; } - PinConnect = (KSPIN_CONNECT*)InstanceInfo; + PinConnect = (KSPIN_CONNECT*)(InstanceInfo + 1); PinConnect->Interface.Set = KSINTERFACESETID_Standard; @@ -100,7 +102,7 @@ WdmAudControlOpen( PinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE; PinConnect->Medium.Flags = 0; PinConnect->PinId = 0; //FIXME - PinConnect->PinToHandle = NULL; + PinConnect->PinToHandle = ClientInfo->hSysAudio; PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; PinConnect->Priority.PrioritySubClass = 1; @@ -125,16 +127,25 @@ WdmAudControlOpen( DataFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX; DataFormat->DataFormat.SampleSize = 4; - - Status = KsCreatePin(ClientInfo->hSysAudio, PinConnect, DesiredAccess, &PinHandle); - DPRINT1("KsCreatePin Status %x\n", Status); - - - /* free buffer */ - ExFreePool(InstanceInfo); - + /* ros specific pin creation request */ + InstanceInfo->Property.Id = (ULONG)-1; + Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, Length, &PinHandle, sizeof(HANDLE), &BytesReturned); if (NT_SUCCESS(Status)) { + PHANDLE Handels = ExAllocatePool(NonPagedPool, sizeof(HANDLE) * (ClientInfo->NumPins+1)); + + if (Handels) + { + if (ClientInfo->NumPins) + { + RtlMoveMemory(Handels, ClientInfo->hPins, sizeof(HANDLE) * ClientInfo->NumPins); + ExFreePool(ClientInfo->hPins); + } + + ClientInfo->hPins = Handels; + ClientInfo->hPins[ClientInfo->NumPins] = PinHandle; + ClientInfo->NumPins++; + } DeviceInfo->hDevice = PinHandle; } else @@ -338,7 +349,6 @@ WdmAudDeviceControl( IoStack = IoGetCurrentIrpStackLocation(Irp); DPRINT1("WdmAudDeviceControl entered\n"); - DbgBreakPoint(); if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(WDMAUD_DEVICE_INFO)) { diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c b/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c index 7a5dc0915ca..017e0ecb944 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c @@ -167,8 +167,6 @@ WdmAudClose( { NTSTATUS Status = STATUS_SUCCESS; PWDMAUD_DEVICE_EXTENSION DeviceExtension; - PIO_STACK_LOCATION IoStack; - WDMAUD_CLIENT *pClient; DPRINT1("WdmAudClose\n"); @@ -184,17 +182,6 @@ WdmAudClose( } #endif - IoStack = IoGetCurrentIrpStackLocation(Irp); - - pClient = (WDMAUD_CLIENT*)IoStack->FileObject->FsContext; - if (pClient) - { - ObDereferenceObject(pClient->FileObject); - ZwClose(pClient->hSysAudio); - ExFreePool(pClient); - IoStack->FileObject->FsContext = NULL; - } - Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -208,12 +195,36 @@ WdmAudCleanup( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - UNIMPLEMENTED + PIO_STACK_LOCATION IoStack; + WDMAUD_CLIENT *pClient; + ULONG Index; + + DPRINT1("WdmAudCleanup\n"); + + IoStack = IoGetCurrentIrpStackLocation(Irp); + + pClient = (WDMAUD_CLIENT*)IoStack->FileObject->FsContext; + + if (pClient) + { + for (Index = 0; Index < pClient->NumPins; Index++) + ZwClose(pClient->hPins[Index]); + + if (pClient->hPins) + { + ExFreePool(pClient->hPins); + } + + ObDereferenceObject(pClient->FileObject); + ZwClose(pClient->hSysAudio); + ExFreePool(pClient); + IoStack->FileObject->FsContext = NULL; + } Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); - + DPRINT1("WdmAudCleanup complete\n"); return STATUS_SUCCESS; } diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h index 9f23545d3e3..b3c59a2c418 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h @@ -65,6 +65,8 @@ typedef struct HANDLE hProcess; HANDLE hSysAudio; PFILE_OBJECT FileObject; + ULONG NumPins; + HANDLE * hPins; }WDMAUD_CLIENT, *PWDMAUD_CLIENT; diff --git a/reactos/drivers/wdm/audio/sysaudio/control.c b/reactos/drivers/wdm/audio/sysaudio/control.c index eaa3dd2bd67..235be97ecb2 100644 --- a/reactos/drivers/wdm/audio/sysaudio/control.c +++ b/reactos/drivers/wdm/audio/sysaudio/control.c @@ -19,6 +19,8 @@ const GUID KSPROPSETID_Sysaudio = {0xCBE3FAA0L, 0xCC75, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}}; const GUID KSPROPSETID_Sysaudio_Pin = {0xA3A53220L, 0xC6E4, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}}; const GUID KSPROPSETID_General = {0x1464EDA5L, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}}; +const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; NTSTATUS @@ -57,6 +59,7 @@ SysAudioOpenVirtualDevice( PSYSAUDIODEVEXT DeviceExtension) { PULONG Index; + PHANDLE Handle; ULONG Count; PSYSAUDIO_CLIENT ClientInfo; PKSAUDIO_DEVICE_ENTRY Entry; @@ -88,8 +91,17 @@ SysAudioOpenVirtualDevice( /* no memory */ return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); } + + ClientInfo->Handels = ExAllocatePool(NonPagedPool, sizeof(HANDLE)); + if (!ClientInfo->Devices) + { + /* no memory */ + return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); + } + ClientInfo->NumDevices = 1; ClientInfo->Devices[0] = DeviceNumber; + ClientInfo->Handels[0] = NULL; /* increase usage count */ Entry->NumberOfClients++; return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0); @@ -111,18 +123,157 @@ SysAudioOpenVirtualDevice( /* no memory */ return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); } + + Handle = ExAllocatePool(NonPagedPool, sizeof(HANDLE) * (ClientInfo->NumDevices + 1)); + if (!Handle) + { + /* no memory */ + ExFreePool(Index); + return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); + } + /* increase usage count */ Entry->NumberOfClients++; /* copy device count array */ - RtlMoveMemory(Index, ClientInfo->Devices, ClientInfo->NumDevices * sizeof(ULONG)); + if (ClientInfo->NumDevices) + { + RtlMoveMemory(Index, ClientInfo->Devices, ClientInfo->NumDevices * sizeof(ULONG)); + RtlMoveMemory(Handle, ClientInfo->Handels, ClientInfo->NumDevices * sizeof(HANDLE)); + } + Index[ClientInfo->NumDevices] = DeviceNumber; + Handle[ClientInfo->NumDevices] = NULL; + ExFreePool(ClientInfo->Handels); ExFreePool(ClientInfo->Devices); ClientInfo->NumDevices++; ClientInfo->Devices = Index; + ClientInfo->Handels = Handle; return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0); +} +VOID +NTAPI +CreatePinWorkerRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + NTSTATUS Status; + HANDLE PinHandle; + HANDLE Filter; + PFILE_OBJECT FileObject; + PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context; + Filter = WorkerContext->PinConnect->PinToHandle; + + WorkerContext->PinConnect->PinToHandle = NULL; + + + if (WorkerContext->CreateRealPin) + { + /* create the real pin */ + Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create Pin with %x\n", Status); + SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0); + ExFreePool(WorkerContext); + return; + } + + /* get pin file object */ + Status = ObReferenceObjectByHandle(PinHandle, + GENERIC_READ | GENERIC_WRITE, + IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); + + WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle = PinHandle; + WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 1; + WorkerContext->DispatchContext->Handle = PinHandle; + WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId; + WorkerContext->DispatchContext->AudioEntry = WorkerContext->Entry; + + if (NT_SUCCESS(Status)) + WorkerContext->DispatchContext->FileObject = FileObject; + else + WorkerContext->DispatchContext->FileObject = NULL; + } + 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(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); + return; + } + WorkerContext->DispatchContext->FileObject = FileObject; + } + + 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, &PinHandle); + + 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); + return; + } + + /* get pin file object */ + 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); + if (WorkerContext->CreateRealPin) + { + /* mark pin as free to use */ + WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 0; + } + + ZwClose(PinHandle); + SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0); + ExFreePool(WorkerContext); + return; + } + + ASSERT(WorkerContext->DispatchContext); + ASSERT(WorkerContext->DispatchContext->AudioEntry != NULL); + ASSERT(WorkerContext->DispatchContext->FileObject != NULL); + ASSERT(WorkerContext->DispatchContext->Handle != NULL); + ASSERT(WorkerContext->AudioClient); + ASSERT(WorkerContext->AudioClient->Handels); + ASSERT(WorkerContext->AudioClient->Handels[WorkerContext->AudioClient->NumDevices -1] == NULL); + + /* store pin context */ + FileObject->FsContext2 = (PVOID)WorkerContext->DispatchContext; + + /* store pin handle in client specific struct */ + WorkerContext->AudioClient->Handels[WorkerContext->AudioClient->NumDevices-1] = PinHandle; + + DPRINT1("Successfully created Pin %p\n", WorkerContext->Irp); + *((PHANDLE)WorkerContext->Irp->UserBuffer) = PinHandle; + + SetIrpIoStatus(WorkerContext->Irp, STATUS_SUCCESS, sizeof(HANDLE)); } @@ -144,6 +295,14 @@ SysAudioHandleProperty( ULONG Count, BytesReturned; PKSOBJECT_CREATE_ITEM CreateItem; UNICODE_STRING GuidString; + ULONG Length; + KSPIN_CONNECT * PinConnect; + KSP_PIN PinRequest; + KSPIN_CINSTANCES PinInstances; + PPIN_WORKER_CONTEXT WorkerContext; + PDISPATCH_CONTEXT DispatchContext; + PIO_WORKITEM WorkItem; + PFILE_OBJECT FileObject; /* access the create item */ CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); @@ -279,6 +438,194 @@ SysAudioHandleProperty( return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); } } + else if (Property->Id == (ULONG)-1) + { + /* ros specific pin creation request */ + DPRINT1("Initiating create request\n"); + + 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); + } + + /* get input parameter */ + InstanceInfo = (PSYSAUDIO_INSTANCE_INFO)Property; + if (DeviceExtension->NumberOfKsAudioDevices <= InstanceInfo->DeviceNumber) + { + /* invalid parameters */ + return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0); + } + + /* get client context */ + ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context; + ASSERT(ClientInfo); + ASSERT(ClientInfo->NumDevices >= 1); + ASSERT(ClientInfo->Devices != NULL); + ASSERT(ClientInfo->Devices[ClientInfo->NumDevices-1] == InstanceInfo->DeviceNumber); + + /* get sysaudio entry */ + Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, InstanceInfo->DeviceNumber); + ASSERT(Entry != NULL); + + if (!Entry->Pins) + { + PropertyRequest.Set = KSPROPSETID_Pin; + PropertyRequest.Flags = KSPROPERTY_TYPE_GET; + PropertyRequest.Id = KSPROPERTY_PIN_CTYPES; + + /* query for num of pins */ + Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PropertyRequest, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned); + if (!NT_SUCCESS(Status)) + { + DPRINT("Property Request KSPROPERTY_PIN_CTYPES failed with %x\n", Status); + return SetIrpIoStatus(Irp, Status, 0); + } + DPRINT("KSPROPERTY_TYPE_GET num pins %d\n", Count); + + Entry->Pins = ExAllocatePool(NonPagedPool, Count * sizeof(PIN_INFO)); + if (!Entry->Pins) + { + /* invalid parameters */ + return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); + } + /* clear array */ + RtlZeroMemory(Entry->Pins, sizeof(PIN_INFO) * Count); + Entry->NumberOfPins = Count; + + } + + /* 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); + } + + PinRequest.PinId = PinConnect->PinId; + PinRequest.Property.Set = KSPROPSETID_Pin; + PinRequest.Property.Flags = KSPROPERTY_TYPE_GET; + PinRequest.Property.Id = KSPROPERTY_PIN_CINSTANCES; + + //RtlZeroMemory(&PinInstances, sizeof(KSPIN_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); + } + DPRINT1("PinInstances Current %u Max %u\n", PinInstances.CurrentCount, PinInstances.PossibleCount); + + WorkItem = IoAllocateWorkItem(DeviceObject); + if (!WorkItem) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* create worker context */ + WorkerContext = ExAllocatePool(NonPagedPool, sizeof(PIN_WORKER_CONTEXT)); + if (!WorkerContext) + { + /* invalid parameters */ + IoFreeWorkItem(WorkItem); + return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); + } + + /* create worker context */ + DispatchContext = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT)); + if (!DispatchContext) + { + /* invalid parameters */ + IoFreeWorkItem(WorkItem); + ExFreePool(WorkerContext); + return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); + } + /* prepare context */ + RtlZeroMemory(WorkerContext, sizeof(PIN_WORKER_CONTEXT)); + RtlZeroMemory(DispatchContext, sizeof(DISPATCH_CONTEXT)); + + if (PinInstances.CurrentCount == PinInstances.PossibleCount) + { + /* pin already exists */ + DPRINT1("Pins %p\n", Entry->Pins); + DbgBreakPoint(); + ASSERT(Entry->Pins[PinConnect->PinId].PinHandle != NULL); + + if (Entry->Pins[PinConnect->PinId].References != 0) + { + /* FIXME need ksmixer */ + DPRINT1("Device %u Pin %u is already occupied, try later\n", InstanceInfo->DeviceNumber, PinConnect->PinId); + IoFreeWorkItem(WorkItem); + ExFreePool(WorkerContext); + ExFreePool(DispatchContext); + return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); + } + /* re-using pin */ + PropertyRequest.Set = KSPROPSETID_Connection; + PropertyRequest.Flags = KSPROPERTY_TYPE_SET; + PropertyRequest.Id = KSPROPERTY_CONNECTION_DATAFORMAT; + + /* 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); + IoFreeWorkItem(WorkItem); + ExFreePool(WorkerContext); + ExFreePool(DispatchContext); + return SetIrpIoStatus(Irp, Status, 0); + } + + Length -= sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO); + Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PropertyRequest, sizeof(KSPROPERTY), + (PVOID)(PinConnect + 1), Length, &BytesReturned); + + ObDereferenceObject(FileObject); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to set format with Status %x\n", Status); + IoFreeWorkItem(WorkItem); + ExFreePool(WorkerContext); + ExFreePool(DispatchContext); + return SetIrpIoStatus(Irp, Status, 0); + } + + } + else + { + /* create the real pin */ + WorkerContext->CreateRealPin = TRUE; + } + + /* set up context */ + + WorkerContext->DispatchContext = DispatchContext; + WorkerContext->Entry = Entry; + WorkerContext->Irp = Irp; + WorkerContext->PinConnect = PinConnect; + WorkerContext->AudioClient = ClientInfo; + + 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; + } } RtlStringFromGUID(&Property->Set, &GuidString); @@ -288,5 +635,3 @@ SysAudioHandleProperty( return Status; } - - diff --git a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c index 969cb10f710..1fccaaaaed4 100644 --- a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c +++ b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c @@ -66,7 +66,11 @@ Dispatch_fnFlush( PIRP Irp) { DPRINT1("Dispatch_fnFlush called DeviceObject %p Irp %p\n", DeviceObject); - + //FIXME + // cleanup resources + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } @@ -76,9 +80,39 @@ Dispatch_fnClose( PDEVICE_OBJECT DeviceObject, PIRP Irp) { + PSYSAUDIO_CLIENT Client; + PIO_STACK_LOCATION IoStatus; + ULONG Index; + + DPRINT1("Dispatch_fnClose called DeviceObject %p Irp %p\n", DeviceObject); + IoStatus = IoGetCurrentIrpStackLocation(Irp); + Client = (PSYSAUDIO_CLIENT)IoStatus->FileObject->FsContext2; + + DPRINT1("Client %p NumDevices %u\n", Client, Client->NumDevices); + for(Index = 0; Index < Client->NumDevices; Index++) + { + if (Client->Handels[Index]) + { + ZwClose(Client->Handels[Index]); + } + } + + if (Client->Handels) + ExFreePool(Client->Handels); + + if (Client->Devices) + ExFreePool(Client->Devices); + + ExFreePool(Client); + + //FIXME + // cleanup resources + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } @@ -175,61 +209,6 @@ static KSDISPATCH_TABLE DispatchTable = Dispatch_fnFastWrite, }; -VOID -NTAPI -CreatePinWorkerRoutine( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context) -{ - NTSTATUS Status; - HANDLE PinHandle; - HANDLE * Handels; - PFILE_OBJECT FileObject; - PIRP Irp; - PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context; - - Handels = ExAllocatePool(NonPagedPool, (WorkerContext->Entry->NumberOfPins + 1) * sizeof(HANDLE)); - if (!Handels) - { - DPRINT1("No Memory \n"); - WorkerContext->Irp->IoStatus.Status = STATUS_NO_MEMORY; - WorkerContext->Irp->IoStatus.Information = 0; - IoCompleteRequest(WorkerContext->Irp, IO_SOUND_INCREMENT); - return; - } - - - Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle); - DPRINT1("KsCreatePin status %x\n", Status); - - if (NT_SUCCESS(Status)) - { - Status = ObReferenceObjectByHandle(PinHandle, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); - if (NT_SUCCESS(Status)) - { - Status = CreateDispatcher(WorkerContext->Irp, PinHandle, FileObject); - DPRINT1("Pins %x\n", WorkerContext->Entry->NumberOfPins); - if (WorkerContext->Entry->NumberOfPins) - { - RtlMoveMemory(Handels, WorkerContext->Entry->Pins, WorkerContext->Entry->NumberOfPins * sizeof(HANDLE)); - ExFreePool(WorkerContext->Entry->Pins); - } - Handels[WorkerContext->Entry->NumberOfPins-1] = PinHandle; - WorkerContext->Entry->Pins = Handels; - WorkerContext->Entry->NumberOfPins++; - } - } - - DPRINT1("CreatePinWorkerRoutine completing irp\n"); - WorkerContext->Irp->IoStatus.Status = Status; - WorkerContext->Irp->IoStatus.Information = 0; - - Irp = WorkerContext->Irp; - ExFreePool(Context); - - IoCompleteRequest(Irp, IO_SOUND_INCREMENT); -} - NTSTATUS NTAPI DispatchCreateSysAudio( @@ -242,12 +221,7 @@ DispatchCreateSysAudio( PKSOBJECT_CREATE_ITEM CreateItem; PIO_STACK_LOCATION IoStatus; LPWSTR Buffer; - ULONG Length, DeviceIndex; - PSYSAUDIODEVEXT DeviceExtension; - PKSAUDIO_DEVICE_ENTRY Entry; - KSPIN_CONNECT * PinConnect; - PIO_WORKITEM WorkItem; - PPIN_WORKER_CONTEXT Context; + static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}"; IoStatus = IoGetCurrentIrpStackLocation(Irp); @@ -260,57 +234,12 @@ DispatchCreateSysAudio( /* is the request for a new pin */ if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN))) { - Client = (PSYSAUDIO_CLIENT)Irp->Tail.Overlay.OriginalFileObject->FsContext2; - DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension; - if (Client) - { - ASSERT(Client->NumDevices >= 1); - DeviceIndex = Client->Devices[Client->NumDevices-1]; - } - else - { - DPRINT1("Warning: using HACK\n"); - DeviceIndex = 0; - } - ASSERT(DeviceIndex < DeviceExtension->NumberOfKsAudioDevices); - Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, DeviceIndex); - ASSERT(Entry); - - Length = (IoStatus->FileObject->FileName.Length - ((wcslen(KS_NAME_PIN)+1) * sizeof(WCHAR))); - PinConnect = ExAllocatePool(NonPagedPool, Length); - if (!PinConnect) - { - Irp->IoStatus.Status = STATUS_NO_MEMORY; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_NO_MEMORY; - } - RtlMoveMemory(PinConnect, IoStatus->FileObject->FileName.Buffer + (wcslen(KS_NAME_PIN)+1), Length); - Context = ExAllocatePool(NonPagedPool, sizeof(PIN_WORKER_CONTEXT)); - if (!Context) - { - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_INSUFFICIENT_RESOURCES; - } - Context->PinConnect = PinConnect; - Context->Entry = Entry; - Context->Irp = Irp; - - WorkItem = IoAllocateWorkItem(DeviceObject); - if (!WorkItem) - { - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_INSUFFICIENT_RESOURCES; - } - IoQueueWorkItem(WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context); + Status = CreateDispatcher(Irp); + DPRINT1("Virtual pin Status %x\n", Status); Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_PENDING; - IoMarkIrpPending(Irp); - return STATUS_PENDING; + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; } } @@ -341,6 +270,10 @@ DispatchCreateSysAudio( Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable); DPRINT1("KsAllocateObjectHeader result %x\n", Status); + /* complete the irp */ + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } diff --git a/reactos/drivers/wdm/audio/sysaudio/pin.c b/reactos/drivers/wdm/audio/sysaudio/pin.c index 2f9654c79b5..977733ff70c 100644 --- a/reactos/drivers/wdm/audio/sysaudio/pin.c +++ b/reactos/drivers/wdm/audio/sysaudio/pin.c @@ -23,19 +23,17 @@ Pin_fnDeviceIoControl( PIRP Irp) { PDISPATCH_CONTEXT Context; - PKSOBJECT_CREATE_ITEM CreateItem; NTSTATUS Status; ULONG BytesReturned; PIO_STACK_LOCATION IoStack; DPRINT1("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject); - /* access the create item */ - CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); - Context = (PDISPATCH_CONTEXT)CreateItem->Context; - IoStack = IoGetCurrentIrpStackLocation(Irp); + Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext2; + ASSERT(Context); + Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.Type3InputBuffer, IoStack->Parameters.DeviceIoControl.InputBufferLength, @@ -84,19 +82,17 @@ Pin_fnWrite( PIRP Irp) { PDISPATCH_CONTEXT Context; - PKSOBJECT_CREATE_ITEM CreateItem; PIO_STACK_LOCATION IoStack; ULONG BytesReturned; NTSTATUS Status; DPRINT1("Pin_fnWrite called DeviceObject %p Irp %p\n", DeviceObject); - /* access the create item */ - CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); - Context = (PDISPATCH_CONTEXT)CreateItem->Context; - IoStack = IoGetCurrentIrpStackLocation(Irp); + Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext2; + ASSERT(Context); + Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IOCTL_KS_WRITE_STREAM, IoStack->Parameters.DeviceIoControl.Type3InputBuffer, IoStack->Parameters.DeviceIoControl.InputBufferLength, @@ -228,34 +224,12 @@ static KSDISPATCH_TABLE PinTable = NTSTATUS CreateDispatcher( - IN PIRP Irp, - IN HANDLE Handle, - IN PFILE_OBJECT FileObject) + IN PIRP Irp) { - PKSOBJECT_CREATE_ITEM CreateItem; NTSTATUS Status; KSOBJECT_HEADER ObjectHeader; - PDISPATCH_CONTEXT Context; - - /* allocate create item */ - CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM)); - if (!CreateItem) - return STATUS_INSUFFICIENT_RESOURCES; - - Context = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT)); - if (!Context) - { - ExFreePool(CreateItem); - return STATUS_INSUFFICIENT_RESOURCES; - } - - Context->Handle = Handle; - Context->FileObject = FileObject; - - - CreateItem->Context = (PVOID)Context; /* allocate object header */ - Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &PinTable); + Status = KsAllocateObjectHeader(&ObjectHeader, 0, NULL, Irp, &PinTable); return Status; } diff --git a/reactos/drivers/wdm/audio/sysaudio/sysaudio.h b/reactos/drivers/wdm/audio/sysaudio/sysaudio.h index 3b933378330..f81d7332f43 100644 --- a/reactos/drivers/wdm/audio/sysaudio/sysaudio.h +++ b/reactos/drivers/wdm/audio/sysaudio/sysaudio.h @@ -5,9 +5,16 @@ typedef struct { ULONG NumDevices; PULONG Devices; + PHANDLE Handels; }SYSAUDIO_CLIENT, *PSYSAUDIO_CLIENT; +typedef struct +{ + HANDLE PinHandle; + ULONG References; +}PIN_INFO; + typedef struct { @@ -18,7 +25,7 @@ typedef struct ULONG NumberOfClients; ULONG NumberOfPins; - HANDLE * Pins; + PIN_INFO * Pins; }KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY; @@ -38,17 +45,22 @@ typedef struct typedef struct { - PIRP Irp; - PKSAUDIO_DEVICE_ENTRY Entry; - KSPIN_CONNECT * PinConnect; + HANDLE Handle; + PFILE_OBJECT FileObject; + ULONG PinId; + PKSAUDIO_DEVICE_ENTRY AudioEntry; -}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT; +}DISPATCH_CONTEXT, *PDISPATCH_CONTEXT; typedef struct { - HANDLE Handle; - PFILE_OBJECT FileObject; -}DISPATCH_CONTEXT, *PDISPATCH_CONTEXT; + PIRP Irp; + BOOL CreateRealPin; + PKSAUDIO_DEVICE_ENTRY Entry; + KSPIN_CONNECT * PinConnect; + PDISPATCH_CONTEXT DispatchContext; + PSYSAUDIO_CLIENT AudioClient; +}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT; NTSTATUS SysAudioAllocateDeviceHeader( @@ -75,8 +87,6 @@ GetListEntry( NTSTATUS CreateDispatcher( - IN PIRP Irp, - IN HANDLE Handle, - IN PFILE_OBJECT FileObject); + IN PIRP Irp); #endif