Author: janderwald Date: Wed Feb 18 17:27:10 2009 New Revision: 39671
URL: http://svn.reactos.org/svn/reactos?rev=39671&view=rev Log: - Implement KSPROPERTY_CONNECTION_STATE & KSPROPERTY_CONNECTION_FORMAT for property set KSPROPSETID_Connection - Queue a work item when Irql is above dispatch level - Open the input / output stream when initializing the pin
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_midi.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c [iso-8859-1] Wed Feb 18 17:27:10 2009 @@ -86,13 +86,13 @@ ISubdevice * ISubDevice; NTSTATUS Status; IPortPinWaveCyclic * Pin; - SUBDEVICE_DESCRIPTOR * Descriptor; PKSPIN_CONNECT ConnectDetails; - IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl *)iface;
ASSERT(This->Port); + + DPRINT("IPortFilterWaveCyclic_fnNewIrpTarget entered\n");
Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&ISubDevice); if (!NT_SUCCESS(Status))
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c [iso-8859-1] Wed Feb 18 17:27:10 2009 @@ -60,6 +60,7 @@
const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; 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}};
/// /// undocumented guids
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1] Wed Feb 18 17:27:10 2009 @@ -9,6 +9,12 @@ IPortWaveCyclic * Port; IPortFilterWaveCyclic * Filter; KSPIN_DESCRIPTOR * KsPinDescriptor; + PMINIPORTWAVECYCLIC Miniport; + PSERVICEGROUP ServiceGroup; + PDMACHANNEL DmaChannel; + PMINIPORTWAVECYCLICSTREAM Stream; + KSSTATE State; + PKSDATAFORMAT Format;
}IPortPinWaveCyclicImpl;
@@ -165,6 +171,139 @@ return STATUS_UNSUCCESSFUL; }
+NTSTATUS +NTAPI +IPortPinWaveCyclic_HandleKsProperty( + IN IPortPinWaveCyclic * iface, + IN PIRP Irp) +{ + PKSPROPERTY Property; + NTSTATUS Status; + UNICODE_STRING GuidString; + PIO_STACK_LOCATION IoStack; + IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface; + + IoStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT1("IPortPinWave_HandleKsProperty entered\n"); + + if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY)) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + return STATUS_INVALID_PARAMETER; + } + + Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + + if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Connection)) + { + if (Property->Id == KSPROPERTY_CONNECTION_STATE) + { + PKSSTATE State = (PKSSTATE)Irp->UserBuffer; + + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSSTATE)) + { + Irp->IoStatus.Information = sizeof(KSSTATE); + Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + return STATUS_BUFFER_TOO_SMALL; + } + + if (Property->Id & KSPROPERTY_TYPE_SET) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + if (This->Stream) + { + Status = This->Stream->lpVtbl->SetState(This->Stream, *State); + + DPRINT1("Setting state %x\n", Status); + if (NT_SUCCESS(Status)) + { + This->State = *State; + Irp->IoStatus.Information = sizeof(KSSTATE); + Irp->IoStatus.Status = Status; + return Status; + } + Irp->IoStatus.Status = Status; + } + return Irp->IoStatus.Status; + } + else if (Property->Id & KSPROPERTY_TYPE_GET) + { + *State = This->State; + Irp->IoStatus.Information = sizeof(KSSTATE); + Irp->IoStatus.Status = STATUS_SUCCESS; + return STATUS_SUCCESS; + } + } + else if (Property->Id == KSPROPERTY_CONNECTION_DATAFORMAT) + { + PKSDATAFORMAT DataFormat = (PKSDATAFORMAT)Irp->UserBuffer; + if (Property->Id & KSPROPERTY_TYPE_SET) + { + PKSDATAFORMAT NewDataFormat = AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); + if (!NewDataFormat) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_NO_MEMORY; + return STATUS_NO_MEMORY; + } + RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize); + + if (This->Stream) + { + Status = This->Stream->lpVtbl->SetFormat(This->Stream, DataFormat); + if (NT_SUCCESS(Status)) + { + if (This->Format) + ExFreePoolWithTag(This->Format, TAG_PORTCLASS); + This->Format = NewDataFormat; + Irp->IoStatus.Information = DataFormat->FormatSize; + Irp->IoStatus.Status = STATUS_SUCCESS; + return STATUS_SUCCESS; + } + } + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + return STATUS_UNSUCCESSFUL; + } + else if (Property->Id & KSPROPERTY_TYPE_GET) + { + PKSDATAFORMAT DataFormat = (PKSDATAFORMAT)Irp->UserBuffer; + if (!This->Format) + { + DPRINT1("No format\n"); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + return STATUS_UNSUCCESSFUL; + } + if (This->Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength) + { + Irp->IoStatus.Information = This->Format->FormatSize; + Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + return STATUS_BUFFER_TOO_SMALL; + } + + RtlMoveMemory(DataFormat, This->Format, This->Format->FormatSize); + Irp->IoStatus.Information = DataFormat->FormatSize; + Irp->IoStatus.Status = STATUS_SUCCESS; + return STATUS_SUCCESS; + } + } + } + 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.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + return STATUS_NOT_IMPLEMENTED; +} + + /* * @unimplemented */ @@ -181,11 +320,10 @@
IoStack = IoGetCurrentIrpStackLocation(Irp);
- DPRINT1("IPortPinWaveCyclic_fnDeviceIoControl\n"); + DPRINT1("IPortPinWaveCyclic_fnDeviceIoControl %x %x\n",IoStack->Parameters.DeviceIoControl.IoControlCode, IOCTL_KS_PROPERTY); if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) { - /// FIXME - /// handle property event + return IPortPinWaveCyclic_HandleKsProperty(iface, Irp); } else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT) { @@ -365,6 +503,8 @@ IN KSPIN_CONNECT * ConnectDetails, IN KSPIN_DESCRIPTOR * KsPinDescriptor) { + NTSTATUS Status; + PKSDATAFORMAT DataFormat; IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
Port->lpVtbl->AddRef(Port); @@ -373,6 +513,42 @@ This->Port = Port; This->Filter = Filter; This->KsPinDescriptor = KsPinDescriptor; + This->Miniport = GetWaveCyclicMiniport(Port); + + DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1); + + DPRINT("IPortPinWaveCyclic_fnInit entered\n"); + + This->Format = ExAllocatePoolWithTag(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); + if (!This->Format) + return STATUS_INSUFFICIENT_RESOURCES; + + RtlMoveMemory(This->Format, DataFormat, DataFormat->FormatSize); + + Status = This->Miniport->lpVtbl->NewStream(This->Miniport, + &This->Stream, + NULL, + NonPagedPool, + FALSE, //FIXME + ConnectDetails->PinId, + This->Format, + &This->DmaChannel, + &This->ServiceGroup); + + DPRINT("IPortPinWaveCyclic_fnInit Status %x\n", Status); + + if (!NT_SUCCESS(Status)) + return Status; + + Status = This->ServiceGroup->lpVtbl->AddMember(This->ServiceGroup, + (PSERVICESINK)&This->lpVtblServiceSink); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to add pin to service group\n"); + return Status; + } + + This->State = KSSTATE_STOP;
return STATUS_SUCCESS; }
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_midi.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_midi.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_midi.c [iso-8859-1] Wed Feb 18 17:27:10 2009 @@ -172,7 +172,6 @@ /* increment reference on miniport adapter */ Miniport->lpVtbl->AddRef(Miniport);
- DbgBreakPoint(); Status = Miniport->lpVtbl->Init(Miniport, UnknownAdapter, ResourceList, iface, &ServiceGroup); if (!NT_SUCCESS(Status)) { @@ -181,8 +180,6 @@ Miniport->lpVtbl->Release(Miniport); return Status; } - - DPRINT1("IMiniportMidi sucessfully init\n");
/* get the miniport device descriptor */ Status = Miniport->lpVtbl->GetDescription(Miniport, &This->pDescriptor);
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c [iso-8859-1] Wed Feb 18 17:27:10 2009 @@ -17,6 +17,12 @@ PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor; }IPortTopologyImpl;
+typedef struct +{ + PIRP Irp; + IIrpTarget *Filter; + +}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT;
static GUID InterfaceGuids[2] = { @@ -432,6 +438,43 @@ ISubDevice_fnPinCount };
+VOID +NTAPI +CreatePinWorkerRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + NTSTATUS Status; + IIrpTarget *Pin; + PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context; + + DPRINT("CreatePinWorkerRoutine called\n"); + + Status = WorkerContext->Filter->lpVtbl->NewIrpTarget(WorkerContext->Filter, + &Pin, + NULL, + NULL, + NonPagedPool, + DeviceObject, + WorkerContext->Irp, + NULL); + + DPRINT("CreatePinWorkerRoutine Status %x\n", Status); + + if (NT_SUCCESS(Status)) + { + /* create the dispatch object */ + Status = NewDispatchObject(WorkerContext->Irp, Pin); + DPRINT("Pin %p\n", Pin); + } + + DPRINT1("CreatePinWorkerRoutine completing irp\n"); + WorkerContext->Irp->IoStatus.Status = Status; + WorkerContext->Irp->IoStatus.Information = 0; + IoCompleteRequest(WorkerContext->Irp, IO_SOUND_INCREMENT); +} + + NTSTATUS NTAPI PcCreateItemDispatch( @@ -521,7 +564,6 @@ Status = NewDispatchObject(Irp, Filter);
DPRINT1("Filter %p\n", Filter); - DbgBreakPoint(); } else { @@ -534,6 +576,34 @@ 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));
@@ -553,7 +623,8 @@ } } } - + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = Status; return Status; }
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c [iso-8859-1] Wed Feb 18 17:27:10 2009 @@ -709,6 +709,14 @@ };
+///-------------------------------------------------------------- +PMINIPORTWAVECYCLIC +GetWaveCyclicMiniport( + IN IPortWaveCyclic* iface) +{ + IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl *)iface; + return This->pMiniport; +}
//--------------------------------------------------------------- // IPortWaveCyclic constructor
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] Wed Feb 18 17:27:10 2009 @@ -94,7 +94,15 @@ IN PIRP Irp, IN IIrpTarget * Target);
-PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag); +PMINIPORTWAVECYCLIC +GetWaveCyclicMiniport( + IN IPortWaveCyclic* iface); + +PVOID +AllocateItem( + IN POOL_TYPE PoolType, + IN SIZE_T NumberOfBytes, + IN ULONG Tag);
VOID FreeItem(