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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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(