- Implement IPortMidi, IPortFilterDMus, IPortPinDMus

- Implement reading / writing midi stream data using IMiniportMidiStream interface
- Delete old IPortMidi implementation

svn path=/trunk/; revision=40835
This commit is contained in:
Johannes Anderwald 2009-05-08 09:36:02 +00:00
parent 0cddd07a48
commit a5731d82f9
9 changed files with 1894 additions and 500 deletions

View file

@ -0,0 +1,503 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Kernel Streaming
* FILE: drivers/wdm/audio/backpln/portcls/filter_dmus.c
* PURPOSE: portcls wave pci filter
* PROGRAMMER: Johannes Anderwald
*/
#include "private.h"
typedef struct
{
IPortFilterDMusVtbl *lpVtbl;
LONG ref;
IPortDMus* Port;
IPortPinDMus ** Pins;
SUBDEVICE_DESCRIPTOR * Descriptor;
}IPortFilterDMusImpl;
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortFilterDMus_fnQueryInterface(
IPortFilterDMus* iface,
IN REFIID refiid,
OUT PVOID* Output)
{
IPortFilterDMusImpl * This = (IPortFilterDMusImpl*)iface;
if (IsEqualGUIDAligned(refiid, &IID_IIrpTarget) ||
IsEqualGUIDAligned(refiid, &IID_IUnknown))
{
*Output = &This->lpVtbl;
InterlockedIncrement(&This->ref);
return STATUS_SUCCESS;
}
else if (IsEqualGUIDAligned(refiid, &IID_IPort))
{
*Output = This->Port;
This->Port->lpVtbl->AddRef(This->Port);
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
}
/*
* @implemented
*/
ULONG
NTAPI
IPortFilterDMus_fnAddRef(
IPortFilterDMus* iface)
{
IPortFilterDMusImpl * This = (IPortFilterDMusImpl*)iface;
return InterlockedIncrement(&This->ref);
}
/*
* @implemented
*/
ULONG
NTAPI
IPortFilterDMus_fnRelease(
IPortFilterDMus* iface)
{
IPortFilterDMusImpl * This = (IPortFilterDMusImpl*)iface;
InterlockedDecrement(&This->ref);
if (This->ref == 0)
{
FreeItem(This, TAG_PORTCLASS);
return 0;
}
return This->ref;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortFilterDMus_fnNewIrpTarget(
IN IPortFilterDMus* iface,
OUT struct IIrpTarget **OutTarget,
IN WCHAR * Name,
IN PUNKNOWN Unknown,
IN POOL_TYPE PoolType,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN KSOBJECT_CREATE *CreateObject)
{
NTSTATUS Status;
IPortPinDMus * Pin;
PKSPIN_CONNECT ConnectDetails;
IPortFilterDMusImpl * This = (IPortFilterDMusImpl *)iface;
ASSERT(This->Port);
ASSERT(This->Descriptor);
ASSERT(This->Pins);
DPRINT("IPortFilterDMus_fnNewIrpTarget entered\n");
/* let's verify the connection request */
Status = PcValidateConnectRequest(Irp, &This->Descriptor->Factory, &ConnectDetails);
if (!NT_SUCCESS(Status))
{
return STATUS_UNSUCCESSFUL;
}
if (This->Pins[ConnectDetails->PinId] && This->Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount)
{
/* release existing instance */
ASSERT(0);
}
/* now create the pin */
Status = NewPortPinDMus(&Pin);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* initialize the pin */
Status = Pin->lpVtbl->Init(Pin, This->Port, iface, ConnectDetails, &This->Descriptor->Factory.KsPinDescriptor[ConnectDetails->PinId], DeviceObject);
if (!NT_SUCCESS(Status))
{
Pin->lpVtbl->Release(Pin);
return Status;
}
/* release existing pin */
if (This->Pins[ConnectDetails->PinId])
{
This->Pins[ConnectDetails->PinId]->lpVtbl->Release(This->Pins[ConnectDetails->PinId]);
}
/* store pin */
This->Pins[ConnectDetails->PinId] = Pin;
/* store result */
*OutTarget = (IIrpTarget*)Pin;
/* increment current instance count */
This->Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount++;
return Status;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortFilterDMus_fnDeviceIoControl(
IN IPortFilterDMus* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
ISubdevice *SubDevice = NULL;
SUBDEVICE_DESCRIPTOR * Descriptor;
NTSTATUS Status;
IPortFilterDMusImpl * This = (IPortFilterDMusImpl *)iface;
IoStack = IoGetCurrentIrpStackLocation(Irp);
ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY);
Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&SubDevice);
ASSERT(Status == STATUS_SUCCESS);
ASSERT(SubDevice != NULL);
Status = SubDevice->lpVtbl->GetDescriptor(SubDevice, &Descriptor);
ASSERT(Status == STATUS_SUCCESS);
ASSERT(Descriptor != NULL);
SubDevice->lpVtbl->Release(SubDevice);
return PcPropertyHandler(Irp, Descriptor);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortFilterDMus_fnRead(
IN IPortFilterDMus* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortFilterDMus_fnWrite(
IN IPortFilterDMus* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortFilterDMus_fnFlush(
IN IPortFilterDMus* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortFilterDMus_fnClose(
IN IPortFilterDMus* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
ULONG Index;
IPortFilterDMusImpl * This = (IPortFilterDMusImpl *)iface;
for(Index = 0; Index < This->Descriptor->Factory.PinDescriptorCount; Index++)
{
if (This->Pins[Index])
{
This->Pins[Index]->lpVtbl->Close(This->Pins[Index], DeviceObject, NULL);
}
}
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortFilterDMus_fnQuerySecurity(
IN IPortFilterDMus* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortFilterDMus_fnSetSecurity(
IN IPortFilterDMus* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
/*
* @implemented
*/
BOOLEAN
NTAPI
IPortFilterDMus_fnFastDeviceIoControl(
IN IPortFilterDMus* iface,
IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
IN PVOID InputBuffer,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer,
IN ULONG OutputBufferLength,
IN ULONG IoControlCode,
OUT PIO_STATUS_BLOCK StatusBlock,
IN PDEVICE_OBJECT DeviceObject)
{
ULONG Index;
PKSPROPERTY Property;
NTSTATUS Status;
ISubdevice * SubDevice = NULL;
PSUBDEVICE_DESCRIPTOR Descriptor = NULL;
IPortFilterDMusImpl * This = (IPortFilterDMusImpl *)iface;
Property = (PKSPROPERTY)InputBuffer;
if (InputBufferLength < sizeof(KSPROPERTY))
return FALSE;
/* get private interface */
Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&SubDevice);
if (!NT_SUCCESS(Status))
return FALSE;
/* get descriptor */
Status = SubDevice->lpVtbl->GetDescriptor(SubDevice, &Descriptor);
if (!NT_SUCCESS(Status))
{
SubDevice->lpVtbl->Release(SubDevice);
return FALSE;
}
for(Index = 0; Index < Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++)
{
if (IsEqualGUIDAligned(&Property->Set, Descriptor->FilterPropertySet.Properties[Index].Set))
{
FastPropertyHandler(FileObject, (PKSPROPERTY)InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, StatusBlock,
1,
&Descriptor->FilterPropertySet.Properties[Index],
Descriptor, SubDevice);
}
}
return TRUE;
}
/*
* @implemented
*/
BOOLEAN
NTAPI
IPortFilterDMus_fnFastRead(
IN IPortFilterDMus* iface,
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN BOOLEAN Wait,
IN ULONG LockKey,
IN PVOID Buffer,
OUT PIO_STATUS_BLOCK StatusBlock,
IN PDEVICE_OBJECT DeviceObject)
{
UNIMPLEMENTED
return FALSE;
}
/*
* @implemented
*/
BOOLEAN
NTAPI
IPortFilterDMus_fnFastWrite(
IN IPortFilterDMus* iface,
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN BOOLEAN Wait,
IN ULONG LockKey,
IN PVOID Buffer,
OUT PIO_STATUS_BLOCK StatusBlock,
IN PDEVICE_OBJECT DeviceObject)
{
UNIMPLEMENTED
return FALSE;
}
/*
* @implemented
*/
static
NTSTATUS
NTAPI
IPortFilterDMus_fnInit(
IN IPortFilterDMus* iface,
IN IPortDMus* Port)
{
ISubdevice * ISubDevice;
SUBDEVICE_DESCRIPTOR * Descriptor;
NTSTATUS Status;
IPortFilterDMusImpl * This = (IPortFilterDMusImpl*)iface;
This->Port = Port;
/* get our private interface */
Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&ISubDevice);
if (!NT_SUCCESS(Status))
return STATUS_UNSUCCESSFUL;
/* get the subdevice descriptor */
Status = ISubDevice->lpVtbl->GetDescriptor(ISubDevice, &Descriptor);
/* release subdevice interface */
ISubDevice->lpVtbl->Release(ISubDevice);
if (!NT_SUCCESS(Status))
return STATUS_UNSUCCESSFUL;
/* save descriptor */
This->Descriptor = Descriptor;
/* allocate pin array */
This->Pins = AllocateItem(NonPagedPool, Descriptor->Factory.PinDescriptorCount * sizeof(IPortPinDMus*), TAG_PORTCLASS);
if (!This->Pins)
return STATUS_UNSUCCESSFUL;
/* increment reference count */
Port->lpVtbl->AddRef(Port);
return STATUS_SUCCESS;
}
static
NTSTATUS
NTAPI
IPortFilterDMus_fnFreePin(
IN IPortFilterDMus* iface,
IN struct IPortPinDMus* Pin)
{
ULONG Index;
IPortFilterDMusImpl * This = (IPortFilterDMusImpl*)iface;
for(Index = 0; Index < This->Descriptor->Factory.PinDescriptorCount; Index++)
{
if (This->Pins[Index] == Pin)
{
This->Pins[Index]->lpVtbl->Release(This->Pins[Index]);
This->Pins[Index] = NULL;
return STATUS_SUCCESS;
}
}
return STATUS_UNSUCCESSFUL;
}
static
VOID
NTAPI
IPortFilterDMus_fnNotifyPins(
IN IPortFilterDMus* iface)
{
ULONG Index;
IPortFilterDMusImpl * This = (IPortFilterDMusImpl*)iface;
DPRINT("Notifying %u pins\n", This->Descriptor->Factory.PinDescriptorCount);
for(Index = 0; Index < This->Descriptor->Factory.PinDescriptorCount; Index++)
{
This->Pins[Index]->lpVtbl->Notify(This->Pins[Index]);
}
}
static IPortFilterDMusVtbl vt_IPortFilterDMus =
{
IPortFilterDMus_fnQueryInterface,
IPortFilterDMus_fnAddRef,
IPortFilterDMus_fnRelease,
IPortFilterDMus_fnNewIrpTarget,
IPortFilterDMus_fnDeviceIoControl,
IPortFilterDMus_fnRead,
IPortFilterDMus_fnWrite,
IPortFilterDMus_fnFlush,
IPortFilterDMus_fnClose,
IPortFilterDMus_fnQuerySecurity,
IPortFilterDMus_fnSetSecurity,
IPortFilterDMus_fnFastDeviceIoControl,
IPortFilterDMus_fnFastRead,
IPortFilterDMus_fnFastWrite,
IPortFilterDMus_fnInit,
IPortFilterDMus_fnFreePin,
IPortFilterDMus_fnNotifyPins
};
NTSTATUS
NewPortFilterDMus(
OUT PPORTFILTERDMUS * OutFilter)
{
IPortFilterDMusImpl * This;
This = AllocateItem(NonPagedPool, sizeof(IPortFilterDMusImpl), TAG_PORTCLASS);
if (!This)
return STATUS_INSUFFICIENT_RESOURCES;
/* initialize IPortFilterDMus */
This->ref = 1;
This->lpVtbl = &vt_IPortFilterDMus;
/* return result */
*OutFilter = (IPortFilterDMus*)&This->lpVtbl;
return STATUS_SUCCESS;
}

View file

@ -13,10 +13,14 @@ const GUID CLSID_PortTopology = {0xb4c90a32L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00,
const GUID CLSID_PortMidi = {0xb4c90a43L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
const GUID CLSID_PortWaveCyclic = {0xb4c90a2aL, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
const GUID CLSID_PortWavePci = {0xb4c90a54L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
const GUID CLSID_PortDMus;
const GUID IID_IMiniportDMus;
const GUID CLSID_PortDMus = {0xb7902fe9L, 0xfb0a, 0x11d1, {0x81, 0xb0, 0x00, 0x60, 0x08, 0x33, 0x16, 0xc1}};
const GUID IID_IMiniportDMus = {0xc096df9dL, 0xfb09, 0x11d1, {0x81, 0xb0, 0x00, 0x60, 0x08, 0x33, 0x16, 0xc1}};
const GUID IID_IMiniportTopology = {0xb4c90a31L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
const GUID IID_IMiniportMidi = {0xb4c90a41L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
const GUID IID_IMiniportWavePci = {0xb4c90a52L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
const GUID IID_IPortTopology = {0xb4c90a30L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
const GUID CLSID_MiniportDriverDMusUART;
@ -32,8 +36,7 @@ const GUID IID_IInterruptSync = {0x22C6AC63L, 0x851B, 0x11D0, {0x9A, 0x7F, 0x00,
const GUID IID_IPortWavePci = {0xb4c90a50L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
const GUID IID_IPortWavePciStream = {0xb4c90a51L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
const GUID IID_IPortMidi = {0xb4c90a40L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
const GUID IID_IMiniportMidi = {0xb4c90a41L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
const GUID IID_IMiniportWavePci = {0xb4c90a52L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
const GUID IID_IPortDMus = {0xc096df9cL, 0xfb09, 0x11d1, {0x81, 0xb0, 0x00, 0x60, 0x08, 0x33, 0x16, 0xc1}};
const GUID IID_IAdapterPowerManagement = {0x793417D0L, 0x35FE, 0x11D1, {0xAD, 0x08, 0x00, 0xA0, 0xC9, 0x0A, 0xB1, 0xB0}};
const GUID IID_IMiniportWaveCyclic = {0xb4c90a27L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};

View file

@ -497,7 +497,7 @@ DECLARE_INTERFACE_(IPortFilterWaveRT, IIrpTarget)
typedef IPortFilterWaveRT *PPORTFILTERWAVERT;
/*****************************************************************************
* IPortPinWavePci
* IPortPinWaveRT
*****************************************************************************
*/
@ -569,6 +569,59 @@ DECLARE_INTERFACE_(IPortPinWaveCyclic, IIrpTarget)
STDMETHOD_(PMINIPORT, GetMiniport)(THIS);
};
/*****************************************************************************
* IPortFilterDMus
*****************************************************************************
*/
#undef INTERFACE
#define INTERFACE IPortFilterDMus
struct IPortPinDMus;
DECLARE_INTERFACE_(IPortFilterDMus, IIrpTarget)
{
DEFINE_ABSTRACT_UNKNOWN()
DEFINE_ABSTRACT_IRPTARGET()
STDMETHOD_(NTSTATUS, Init)(THIS_
IN PPORTDMUS Port)PURE;
STDMETHOD_(NTSTATUS, FreePin)(THIS_
IN struct IPortPinDMus* Pin)PURE;
STDMETHOD_(VOID, NotifyPins)(THIS);
};
typedef IPortFilterDMus *PPORTFILTERDMUS;
/*****************************************************************************
* IPortPinDMus
*****************************************************************************
*/
#undef INTERFACE
#define INTERFACE IPortPinDMus
DECLARE_INTERFACE_(IPortPinDMus, IIrpTarget)
{
DEFINE_ABSTRACT_UNKNOWN()
DEFINE_ABSTRACT_IRPTARGET()
STDMETHOD_(NTSTATUS, Init)(THIS_
IN PPORTDMUS Port,
IN PPORTFILTERDMUS Filter,
IN KSPIN_CONNECT * ConnectDetails,
IN KSPIN_DESCRIPTOR * PinDescriptor,
IN PDEVICE_OBJECT DeviceObject) PURE;
STDMETHOD_(VOID, Notify)(THIS);
};
typedef IPortPinDMus *PPORTPINDMUS;
/*****************************************************************************
* IDmaChannelInit
*****************************************************************************

View file

@ -0,0 +1,844 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Kernel Streaming
* FILE: drivers/wdm/audio/backpln/portcls/pin_dmus.c
* PURPOSE: DMus IRP Audio Pin
* PROGRAMMER: Johannes Anderwald
*/
#include "private.h"
#include "private.h"
typedef struct
{
IPortPinDMusVtbl *lpVtbl;
IServiceSinkVtbl *lpVtblServiceSink;
LONG ref;
IPortDMus * Port;
IPortFilterDMus * Filter;
KSPIN_DESCRIPTOR * KsPinDescriptor;
PMINIPORTDMUS Miniport;
PSERVICEGROUP ServiceGroup;
PMINIPORTMIDI MidiMiniport;
PMINIPORTMIDISTREAM MidiStream;
KSSTATE State;
PKSDATAFORMAT Format;
KSPIN_CONNECT * ConnectDetails;
BOOL Capture;
PDEVICE_OBJECT DeviceObject;
IIrpQueue * IrpQueue;
ULONG TotalPackets;
ULONG PreCompleted;
ULONG PostCompleted;
}IPortPinDMusImpl;
typedef struct
{
IPortPinDMusImpl *Pin;
PIO_WORKITEM WorkItem;
KSSTATE State;
}SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT;
NTSTATUS
NTAPI
IPortDMus_fnProcessNewIrp(
IPortPinDMusImpl * This);
//==================================================================================================================================
static
NTSTATUS
NTAPI
IServiceSink_fnQueryInterface(
IServiceSink* iface,
IN REFIID refiid,
OUT PVOID* Output)
{
IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblServiceSink);
DPRINT("IServiceSink_fnQueryInterface entered\n");
if (IsEqualGUIDAligned(refiid, &IID_IServiceSink) ||
IsEqualGUIDAligned(refiid, &IID_IUnknown))
{
*Output = &This->lpVtblServiceSink;
InterlockedIncrement(&This->ref);
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
}
static
ULONG
NTAPI
IServiceSink_fnAddRef(
IServiceSink* iface)
{
IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblServiceSink);
DPRINT("IServiceSink_fnAddRef entered\n");
return InterlockedIncrement(&This->ref);
}
static
ULONG
NTAPI
IServiceSink_fnRelease(
IServiceSink* iface)
{
IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblServiceSink);
InterlockedDecrement(&This->ref);
DPRINT("IServiceSink_fnRelease entered %u\n", This->ref);
if (This->ref == 0)
{
FreeItem(This, TAG_PORTCLASS);
return 0;
}
/* Return new reference count */
return This->ref;
}
static
VOID
NTAPI
SetStreamWorkerRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context)
{
IPortPinDMusImpl * This;
PSETSTREAM_CONTEXT Ctx = (PSETSTREAM_CONTEXT)Context;
KSSTATE State;
This = Ctx->Pin;
State = Ctx->State;
IoFreeWorkItem(Ctx->WorkItem);
FreeItem(Ctx, TAG_PORTCLASS);
/* Has the audio stream resumed? */
if (This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue) && State == KSSTATE_STOP)
return;
/* Set the state */
if (NT_SUCCESS(This->MidiStream->lpVtbl->SetState(This->MidiStream, State)))
{
/* Set internal state to stop */
This->State = State;
if (This->State == KSSTATE_STOP)
{
/* reset start stream */
This->IrpQueue->lpVtbl->CancelBuffers(This->IrpQueue); //FIX function name
DPRINT1("Stopping PreCompleted %u PostCompleted %u\n", This->PreCompleted, This->PostCompleted);
}
}
}
static
VOID
NTAPI
SetStreamState(
IN IPortPinDMusImpl * This,
IN KSSTATE State)
{
PIO_WORKITEM WorkItem;
PSETSTREAM_CONTEXT Context;
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
/* Has the audio stream resumed? */
if (This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue) && State == KSSTATE_STOP)
return;
/* Has the audio state already been set? */
if (This->State == State)
return;
/* allocate set state context */
Context = AllocateItem(NonPagedPool, sizeof(SETSTREAM_CONTEXT), TAG_PORTCLASS);
if (!Context)
return;
/* allocate work item */
WorkItem = IoAllocateWorkItem(This->DeviceObject);
if (!WorkItem)
{
ExFreePool(Context);
return;
}
Context->Pin = (PVOID)This;
Context->WorkItem = WorkItem;
Context->State = State;
/* queue the work item */
IoQueueWorkItem(WorkItem, SetStreamWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
}
VOID
TransferMidiData(
IPortPinDMusImpl * This)
{
NTSTATUS Status;
PUCHAR Buffer;
ULONG BufferSize;
ULONG BytesWritten;
do
{
Status = This->IrpQueue->lpVtbl->GetMapping(This->IrpQueue, &Buffer, &BufferSize);
if (!NT_SUCCESS(Status))
{
SetStreamState(This, KSSTATE_STOP);
return;
}
if (This->Capture)
{
Status = This->MidiStream->lpVtbl->Read(This->MidiStream, Buffer, BufferSize, &BytesWritten);
if (!NT_SUCCESS(Status))
{
DPRINT("Read failed with %x\n", Status);
return;
}
}
else
{
Status = This->MidiStream->lpVtbl->Write(This->MidiStream, Buffer, BufferSize, &BytesWritten);
if (!NT_SUCCESS(Status))
{
DPRINT("Write failed with %x\n", Status);
return;
}
}
if (!BytesWritten)
{
DPRINT("Device is busy retry later\n");
return;
}
This->IrpQueue->lpVtbl->UpdateMapping(This->IrpQueue, BytesWritten);
}while(TRUE);
}
static
VOID
NTAPI
IServiceSink_fnRequestService(
IServiceSink* iface)
{
IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblServiceSink);
ASSERT_IRQL(DISPATCH_LEVEL);
if (This->MidiStream)
{
TransferMidiData(This);
}
}
static IServiceSinkVtbl vt_IServiceSink =
{
IServiceSink_fnQueryInterface,
IServiceSink_fnAddRef,
IServiceSink_fnRelease,
IServiceSink_fnRequestService
};
//==================================================================================================================================
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortPinDMus_fnQueryInterface(
IPortPinDMus* iface,
IN REFIID refiid,
OUT PVOID* Output)
{
IPortPinDMusImpl * This = (IPortPinDMusImpl*)iface;
if (IsEqualGUIDAligned(refiid, &IID_IIrpTarget) ||
IsEqualGUIDAligned(refiid, &IID_IUnknown))
{
*Output = &This->lpVtbl;
InterlockedIncrement(&This->ref);
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
}
/*
* @implemented
*/
ULONG
NTAPI
IPortPinDMus_fnAddRef(
IPortPinDMus* iface)
{
IPortPinDMusImpl * This = (IPortPinDMusImpl*)iface;
return InterlockedIncrement(&This->ref);
}
/*
* @implemented
*/
ULONG
NTAPI
IPortPinDMus_fnRelease(
IPortPinDMus* iface)
{
IPortPinDMusImpl * This = (IPortPinDMusImpl*)iface;
InterlockedDecrement(&This->ref);
if (This->ref == 0)
{
FreeItem(This, TAG_PORTCLASS);
return 0;
}
return This->ref;
}
/*
* @unimplemented
*/
NTSTATUS
NTAPI
IPortPinDMus_fnNewIrpTarget(
IN IPortPinDMus* iface,
OUT struct IIrpTarget **OutTarget,
IN WCHAR * Name,
IN PUNKNOWN Unknown,
IN POOL_TYPE PoolType,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN KSOBJECT_CREATE *CreateObject)
{
UNIMPLEMENTED
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
/*
* @unimplemented
*/
NTSTATUS
NTAPI
IPortPinDMus_fnDeviceIoControl(
IN IPortPinDMus* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
UNIMPLEMENTED
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortPinDMus_fnRead(
IN IPortPinDMus* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortPinDMus_fnWrite(
IN IPortPinDMus* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortPinDMus_fnFlush(
IN IPortPinDMus* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
static
VOID
NTAPI
CloseStreamRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context)
{
PMINIPORTMIDISTREAM Stream = NULL;
NTSTATUS Status;
ISubdevice *ISubDevice;
PSUBDEVICE_DESCRIPTOR Descriptor;
IPortPinDMusImpl * This;
PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context;
This = (IPortPinDMusImpl*)Ctx->Pin;
if (This->MidiStream)
{
if (This->State != KSSTATE_STOP)
{
This->MidiStream->lpVtbl->SetState(This->MidiStream, KSSTATE_STOP);
KeStallExecutionProcessor(10);
}
Stream = This->MidiStream;
This->MidiStream = NULL;
}
if (This->ServiceGroup)
{
This->ServiceGroup->lpVtbl->RemoveMember(This->ServiceGroup, (PSERVICESINK)&This->lpVtblServiceSink);
This->ServiceGroup->lpVtbl->Release(This->ServiceGroup);
}
Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&ISubDevice);
if (NT_SUCCESS(Status))
{
Status = ISubDevice->lpVtbl->GetDescriptor(ISubDevice, &Descriptor);
if (NT_SUCCESS(Status))
{
ISubDevice->lpVtbl->Release(ISubDevice);
Descriptor->Factory.Instances[This->ConnectDetails->PinId].CurrentPinInstanceCount--;
}
}
if (This->Format)
{
ExFreePool(This->Format);
This->Format = NULL;
}
/* complete the irp */
Ctx->Irp->IoStatus.Information = 0;
Ctx->Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Ctx->Irp, IO_NO_INCREMENT);
/* free the work item */
IoFreeWorkItem(Ctx->WorkItem);
/* free work item ctx */
FreeItem(Ctx, TAG_PORTCLASS);
/* destroy DMus pin */
This->Filter->lpVtbl->FreePin(This->Filter, (PPORTPINDMUS)This);
if (Stream)
{
DPRINT1("Closing stream at Irql %u\n", KeGetCurrentIrql());
Stream->lpVtbl->Release(Stream);
}
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortPinDMus_fnClose(
IN IPortPinDMus* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PCLOSESTREAM_CONTEXT Ctx;
IPortPinDMusImpl * This = (IPortPinDMusImpl*)iface;
if (This->MidiStream)
{
Ctx = AllocateItem(NonPagedPool, sizeof(CLOSESTREAM_CONTEXT), TAG_PORTCLASS);
if (!Ctx)
{
DPRINT1("Failed to allocate stream context\n");
goto cleanup;
}
Ctx->WorkItem = IoAllocateWorkItem(DeviceObject);
if (!Ctx->WorkItem)
{
DPRINT1("Failed to allocate work item\n");
goto cleanup;
}
Ctx->Irp = Irp;
Ctx->Pin = (PVOID)This;
IoMarkIrpPending(Irp);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_PENDING;
/* defer work item */
IoQueueWorkItem(Ctx->WorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)Ctx);
/* Return result */
return STATUS_PENDING;
}
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
cleanup:
if (Ctx)
FreeItem(Ctx, TAG_PORTCLASS);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortPinDMus_fnQuerySecurity(
IN IPortPinDMus* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortPinDMus_fnSetSecurity(
IN IPortPinDMus* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
/*
* @implemented
*/
BOOLEAN
NTAPI
IPortPinDMus_fnFastDeviceIoControl(
IN IPortPinDMus* iface,
IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
IN PVOID InputBuffer,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer,
IN ULONG OutputBufferLength,
IN ULONG IoControlCode,
OUT PIO_STATUS_BLOCK StatusBlock,
IN PDEVICE_OBJECT DeviceObject)
{
UNIMPLEMENTED
return FALSE;
}
/*
* @implemented
*/
BOOLEAN
NTAPI
IPortPinDMus_fnFastRead(
IN IPortPinDMus* iface,
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN BOOLEAN Wait,
IN ULONG LockKey,
IN PVOID Buffer,
OUT PIO_STATUS_BLOCK StatusBlock,
IN PDEVICE_OBJECT DeviceObject)
{
NTSTATUS Status;
PCONTEXT_WRITE Packet;
PIRP Irp;
IPortPinDMusImpl * This = (IPortPinDMusImpl*)iface;
DPRINT("IPortPinDMus_fnFastRead entered\n");
Packet = (PCONTEXT_WRITE)Buffer;
Irp = Packet->Irp;
StatusBlock->Status = STATUS_PENDING;
Status = This->IrpQueue->lpVtbl->AddMapping(This->IrpQueue, Buffer, Length, Irp);
if (!NT_SUCCESS(Status))
return FALSE;
if (This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue) == TRUE && This->State != KSSTATE_RUN)
{
/* some should initiate a state request but didnt do it */
DPRINT1("Starting stream with %lu mappings\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue));
SetStreamState(This, KSSTATE_RUN);
}
return TRUE;
}
/*
* @implemented
*/
BOOLEAN
NTAPI
IPortPinDMus_fnFastWrite(
IN IPortPinDMus* iface,
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN BOOLEAN Wait,
IN ULONG LockKey,
IN PVOID Buffer,
OUT PIO_STATUS_BLOCK StatusBlock,
IN PDEVICE_OBJECT DeviceObject)
{
NTSTATUS Status;
PCONTEXT_WRITE Packet;
PIRP Irp;
IPortPinDMusImpl * This = (IPortPinDMusImpl*)iface;
InterlockedIncrement((PLONG)&This->TotalPackets);
DPRINT("IPortPinDMus_fnFastWrite entered Total %u Pre %u Post %u\n", This->TotalPackets, This->PreCompleted, This->PostCompleted);
Packet = (PCONTEXT_WRITE)Buffer;
if (This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue))
{
Irp = Packet->Irp;
StatusBlock->Status = STATUS_PENDING;
InterlockedIncrement((PLONG)&This->PostCompleted);
}
else
{
Irp = NULL;
Packet->Irp->IoStatus.Status = STATUS_SUCCESS;
Packet->Irp->IoStatus.Information = Packet->Header.FrameExtent;
IoCompleteRequest(Packet->Irp, IO_SOUND_INCREMENT);
StatusBlock->Status = STATUS_SUCCESS;
InterlockedIncrement((PLONG)&This->PreCompleted);
}
Status = This->IrpQueue->lpVtbl->AddMapping(This->IrpQueue, Buffer, Length, Irp);
if (!NT_SUCCESS(Status))
return FALSE;
if (This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue) == TRUE && This->State != KSSTATE_RUN)
{
SetStreamState(This, KSSTATE_RUN);
/* some should initiate a state request but didnt do it */
DPRINT1("Starting stream with %lu mappings Status %x\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue), Status);
}
return TRUE;
}
/*
* @unimplemented
*/
NTSTATUS
NTAPI
IPortPinDMus_fnInit(
IN IPortPinDMus* iface,
IN PPORTDMUS Port,
IN PPORTFILTERDMUS Filter,
IN KSPIN_CONNECT * ConnectDetails,
IN KSPIN_DESCRIPTOR * KsPinDescriptor,
IN PDEVICE_OBJECT DeviceObject)
{
NTSTATUS Status;
PKSDATAFORMAT DataFormat;
BOOL Capture;
IPortPinDMusImpl * This = (IPortPinDMusImpl*)iface;
Port->lpVtbl->AddRef(Port);
Filter->lpVtbl->AddRef(Filter);
This->Port = Port;
This->Filter = Filter;
This->KsPinDescriptor = KsPinDescriptor;
This->ConnectDetails = ConnectDetails;
This->DeviceObject = DeviceObject;
GetDMusMiniport(Port, &This->Miniport, &This->MidiMiniport);
DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1);
DPRINT("IPortPinDMus_fnInit entered\n");
This->Format = ExAllocatePoolWithTag(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS);
if (!This->Format)
return STATUS_INSUFFICIENT_RESOURCES;
RtlMoveMemory(This->Format, DataFormat, DataFormat->FormatSize);
if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN)
{
Capture = FALSE;
}
else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT)
{
Capture = TRUE;
}
else
{
DPRINT1("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor->Communication, KsPinDescriptor->DataFlow);
KeBugCheck(0);
}
Status = NewIrpQueue(&This->IrpQueue);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to allocate IrpQueue with %x\n", Status);
return Status;
}
if (This->MidiMiniport)
{
Status = This->MidiMiniport->lpVtbl->NewStream(This->MidiMiniport,
&This->MidiStream,
NULL,
NonPagedPool,
ConnectDetails->PinId,
Capture,
This->Format,
&This->ServiceGroup);
DPRINT("IPortPinDMus_fnInit Status %x\n", Status);
if (!NT_SUCCESS(Status))
return Status;
}
if (This->ServiceGroup)
{
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->ServiceGroup->lpVtbl->SupportDelayedService(This->ServiceGroup);
}
Status = This->IrpQueue->lpVtbl->Init(This->IrpQueue, ConnectDetails, This->Format, DeviceObject, 0);
if (!NT_SUCCESS(Status))
{
DPRINT1("IrpQueue_Init failed with %x\n", Status);
return Status;
}
This->State = KSSTATE_STOP;
This->Capture = Capture;
return STATUS_SUCCESS;
}
/*
* @implemented
*/
VOID
NTAPI
IPortPinDMus_fnNotify(
IN IPortPinDMus* iface)
{
IPortPinDMusImpl * This = (IPortPinDMusImpl*)iface;
This->ServiceGroup->lpVtbl->RequestService(This->ServiceGroup);
}
static IPortPinDMusVtbl vt_IPortPinDMus =
{
IPortPinDMus_fnQueryInterface,
IPortPinDMus_fnAddRef,
IPortPinDMus_fnRelease,
IPortPinDMus_fnNewIrpTarget,
IPortPinDMus_fnDeviceIoControl,
IPortPinDMus_fnRead,
IPortPinDMus_fnWrite,
IPortPinDMus_fnFlush,
IPortPinDMus_fnClose,
IPortPinDMus_fnQuerySecurity,
IPortPinDMus_fnSetSecurity,
IPortPinDMus_fnFastDeviceIoControl,
IPortPinDMus_fnFastRead,
IPortPinDMus_fnFastWrite,
IPortPinDMus_fnInit,
IPortPinDMus_fnNotify
};
NTSTATUS NewPortPinDMus(
OUT IPortPinDMus ** OutPin)
{
IPortPinDMusImpl * This;
This = AllocateItem(NonPagedPool, sizeof(IPortPinDMusImpl), TAG_PORTCLASS);
if (!This)
return STATUS_INSUFFICIENT_RESOURCES;
/* initialize IPortPinDMus */
This->ref = 1;
This->lpVtbl = &vt_IPortPinDMus;
This->lpVtblServiceSink = &vt_IServiceSink;
/* store result */
*OutPin = (IPortPinDMus*)&This->lpVtbl;
return STATUS_SUCCESS;
}

View file

@ -31,7 +31,7 @@ PcNewPort(
}
if (IsEqualGUIDAligned(ClassId, &CLSID_PortMidi))
Status = NewPortMidi(OutPort);
Status = NewPortDMus(OutPort);
else if (IsEqualGUIDAligned(ClassId, &CLSID_PortDMus))
Status = NewPortDMus(OutPort);
else if (IsEqualGUIDAligned(ClassId, &CLSID_PortTopology))

View file

@ -11,16 +11,39 @@
typedef struct
{
IPortDMusVtbl *lpVtbl;
IServiceSinkVtbl *lpVtblServiceSink;
ISubdeviceVtbl *lpVtblSubDevice;
LONG ref;
BOOL bInitialized;
IMiniportDMus *pMiniport;
IMiniportMidi *pMiniportMidi;
DEVICE_OBJECT *pDeviceObject;
PSERVICEGROUP ServiceGroup;
PPINCOUNT pPinCount;
PPOWERNOTIFY pPowerNotify;
PPORTFILTERDMUS Filter;
PPCFILTER_DESCRIPTOR pDescriptor;
PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
}IPortDMusImpl;
const GUID IID_IPortDMus;
static GUID InterfaceGuids[3] =
{
{
/// KS_CATEGORY_AUDIO
0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
},
{
/// KS_CATEGORY_RENDER
0x65E8773E, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
},
{
/// KS_CATEGORY_CAPTURE
0x65E8773D, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
}
};
//---------------------------------------------------------------
// IUnknown interface functions
@ -33,19 +56,39 @@ IPortDMus_fnQueryInterface(
IN REFIID refiid,
OUT PVOID* Output)
{
UNICODE_STRING GuidString;
IPortDMusImpl * This = (IPortDMusImpl*)iface;
if (IsEqualGUIDAligned(refiid, &IID_IPortDMus) ||
IsEqualGUIDAligned(refiid, &IID_IPortMidi) ||
IsEqualGUIDAligned(refiid, &IID_IUnknown))
{
*Output = &This->lpVtbl;
_InterlockedIncrement(&This->ref);
InterlockedIncrement(&This->ref);
return STATUS_SUCCESS;
}
else if (IsEqualGUIDAligned(refiid, &IID_ISubdevice))
{
*Output = &This->lpVtblSubDevice;
InterlockedIncrement(&This->ref);
return STATUS_SUCCESS;
}
else if (IsEqualGUIDAligned(refiid, &IID_IDrmPort) ||
IsEqualGUIDAligned(refiid, &IID_IDrmPort2))
{
return NewIDrmPort((PDRMPORT2*)Output);
}
else if (IsEqualGUIDAligned(refiid, &IID_IPortClsVersion))
{
return NewPortClsVersion((PPORTCLSVERSION*)Output);
}
if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
{
DPRINT1("IPortMidi_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer);
RtlFreeUnicodeString(&GuidString);
}
return STATUS_UNSUCCESSFUL;
}
@ -118,8 +161,12 @@ IPortDMus_fnInit(
IN PUNKNOWN UnknownAdapter OPTIONAL,
IN PRESOURCELIST ResourceList)
{
IMiniportDMus * Miniport;
IMiniportDMus * Miniport = NULL;
IMiniportMidi * MidiMiniport = NULL;
NTSTATUS Status;
PSERVICEGROUP ServiceGroup;
PPINCOUNT PinCount;
PPOWERNOTIFY PowerNotify;
IPortDMusImpl * This = (IPortDMusImpl*)iface;
ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
@ -133,25 +180,111 @@ IPortDMus_fnInit(
Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IMiniportDMus, (PVOID*)&Miniport);
if (!NT_SUCCESS(Status))
{
DPRINT("IPortDMus_Init called with invalid IMiniport adapter\n");
return STATUS_INVALID_PARAMETER;
/* check for legacy interface */
Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IMiniportMidi, (PVOID*)&MidiMiniport);
if (!NT_SUCCESS(Status))
{
DPRINT("IPortDMus_Init called with invalid IMiniport adapter\n");
return STATUS_INVALID_PARAMETER;
}
}
Status = Miniport->lpVtbl->Init(Miniport, UnknownAdapter, ResourceList, iface, &This->ServiceGroup);
if (Miniport)
{
/* initialize IMiniportDMus */
Status = Miniport->lpVtbl->Init(Miniport, UnknownAdapter, ResourceList, iface, &ServiceGroup);
if (!NT_SUCCESS(Status))
{
DPRINT("IMiniportDMus_Init failed with %x\n", Status);
return Status;
}
/* get the miniport device descriptor */
Status = Miniport->lpVtbl->GetDescription(Miniport, &This->pDescriptor);
if (!NT_SUCCESS(Status))
{
DPRINT1("failed to get description\n");
Miniport->lpVtbl->Release(Miniport);
return Status;
}
}
else
{
/* initialize IMiniportMidi */
Status = MidiMiniport->lpVtbl->Init(MidiMiniport, UnknownAdapter, ResourceList, (IPortMidi*)iface, &ServiceGroup);
if (!NT_SUCCESS(Status))
{
DPRINT("IMiniportMidi_Init failed with %x\n", Status);
return Status;
}
/* get the miniport device descriptor */
Status = MidiMiniport->lpVtbl->GetDescription(MidiMiniport, &This->pDescriptor);
if (!NT_SUCCESS(Status))
{
DPRINT1("failed to get description\n");
MidiMiniport->lpVtbl->Release(MidiMiniport);
return Status;
}
}
/* create the subdevice descriptor */
Status = PcCreateSubdeviceDescriptor(&This->SubDeviceDescriptor,
3,
InterfaceGuids,
0,
NULL,
0,
NULL,
0,
0,
0,
NULL,
0,
NULL,
This->pDescriptor);
if (!NT_SUCCESS(Status))
{
DPRINT("IMinIPortDMus_Init failed with %x\n", Status);
DPRINT1("Failed to create descriptior\n");
if (Miniport)
Miniport->lpVtbl->Release(Miniport);
else
MidiMiniport->lpVtbl->Release(MidiMiniport);
return Status;
}
ASSERT(This->ServiceGroup);
ASSERT(ServiceGroup == This->ServiceGroup);
/* Initialize port object */
This->pMiniport = Miniport;
This->pMiniportMidi = MidiMiniport;
This->pDeviceObject = DeviceObject;
This->bInitialized = TRUE;
/* increment reference on miniport adapter */
Miniport->lpVtbl->AddRef(Miniport);
/* check if it supports IPinCount interface */
Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IPinCount, (PVOID*)&PinCount);
if (NT_SUCCESS(Status))
{
/* store IPinCount interface */
This->pPinCount = PinCount;
}
/* does the Miniport adapter support IPowerNotify interface*/
Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IPowerNotify, (PVOID*)&PowerNotify);
if (NT_SUCCESS(Status))
{
/* store reference */
This->pPowerNotify = PowerNotify;
}
return STATUS_SUCCESS;
}
@ -180,11 +313,339 @@ IPortDMus_fnNewRegistryKey(
return STATUS_UNSUCCESSFUL;
}
VOID
NTAPI
IPortDMus_fnNotify(
IN IPortDMus * iface,
IN PSERVICEGROUP ServiceGroup OPTIONAL)
{
IPortDMusImpl * This = (IPortDMusImpl*)iface;
if (ServiceGroup)
{
ServiceGroup->lpVtbl->RequestService (ServiceGroup);
return;
}
ASSERT(This->ServiceGroup);
/* notify miniport service group */
This->ServiceGroup->lpVtbl->RequestService(This->ServiceGroup);
/* notify stream miniport service group */
if (This->Filter)
{
This->Filter->lpVtbl->NotifyPins(This->Filter);
}
}
VOID
NTAPI
IPortDMus_fnRegisterServiceGroup(
IN IPortDMus * iface,
IN PSERVICEGROUP ServiceGroup)
{
IPortDMusImpl * This = (IPortDMusImpl*)iface;
ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
This->ServiceGroup = ServiceGroup;
ServiceGroup->lpVtbl->AddRef(ServiceGroup);
ServiceGroup->lpVtbl->AddMember(ServiceGroup, (PSERVICESINK)&This->lpVtblServiceSink);
}
static IPortDMusVtbl vt_IPortDMus =
{
/* IUnknown methods */
IPortDMus_fnQueryInterface,
IPortDMus_fnAddRef,
IPortDMus_fnRelease,
/* IPort methods */
IPortDMus_fnInit,
IPortDMus_fnGetDeviceProperty,
IPortDMus_fnNewRegistryKey,
IPortDMus_fnNotify,
IPortDMus_fnRegisterServiceGroup
};
//---------------------------------------------------------------
// ISubdevice interface
//
static
NTSTATUS
NTAPI
ISubDevice_fnQueryInterface(
IN ISubdevice *iface,
IN REFIID InterfaceId,
IN PVOID* Interface)
{
IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblSubDevice);
return IPortDMus_fnQueryInterface((IPortDMus*)This, InterfaceId, Interface);
}
static
ULONG
NTAPI
ISubDevice_fnAddRef(
IN ISubdevice *iface)
{
IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblSubDevice);
return IPortDMus_fnAddRef((IPortDMus*)This);
}
static
ULONG
NTAPI
ISubDevice_fnRelease(
IN ISubdevice *iface)
{
IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblSubDevice);
return IPortDMus_fnRelease((IPortDMus*)This);
}
static
NTSTATUS
NTAPI
ISubDevice_fnNewIrpTarget(
IN ISubdevice *iface,
OUT struct IIrpTarget **OutTarget,
IN WCHAR * Name,
IN PUNKNOWN Unknown,
IN POOL_TYPE PoolType,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN KSOBJECT_CREATE *CreateObject)
{
NTSTATUS Status;
PPORTFILTERDMUS Filter;
IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblSubDevice);
DPRINT("ISubDevice_NewIrpTarget this %p\n", This);
if (This->Filter)
{
*OutTarget = (IIrpTarget*)This->Filter;
return STATUS_SUCCESS;
}
Status = NewPortFilterDMus(&Filter);
if (!NT_SUCCESS(Status))
{
return Status;
}
Status = Filter->lpVtbl->Init(Filter, (PPORTDMUS)This);
if (!NT_SUCCESS(Status))
{
Filter->lpVtbl->Release(Filter);
return Status;
}
*OutTarget = (IIrpTarget*)Filter;
return Status;
}
static
NTSTATUS
NTAPI
ISubDevice_fnReleaseChildren(
IN ISubdevice *iface)
{
//IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblSubDevice);
UNIMPLEMENTED
return STATUS_UNSUCCESSFUL;
}
static
NTSTATUS
NTAPI
ISubDevice_fnGetDescriptor(
IN ISubdevice *iface,
IN SUBDEVICE_DESCRIPTOR ** Descriptor)
{
IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblSubDevice);
DPRINT("ISubDevice_GetDescriptor this %p\n", This);
*Descriptor = This->SubDeviceDescriptor;
return STATUS_SUCCESS;
}
static
NTSTATUS
NTAPI
ISubDevice_fnDataRangeIntersection(
IN ISubdevice *iface,
IN ULONG PinId,
IN PKSDATARANGE DataRange,
IN PKSDATARANGE MatchingDataRange,
IN ULONG OutputBufferLength,
OUT PVOID ResultantFormat OPTIONAL,
OUT PULONG ResultantFormatLength)
{
IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblSubDevice);
DPRINT("ISubDevice_DataRangeIntersection this %p\n", This);
if (This->pMiniport)
{
return This->pMiniport->lpVtbl->DataRangeIntersection (This->pMiniport, PinId, DataRange, MatchingDataRange, OutputBufferLength, ResultantFormat, ResultantFormatLength);
}
return STATUS_UNSUCCESSFUL;
}
static
NTSTATUS
NTAPI
ISubDevice_fnPowerChangeNotify(
IN ISubdevice *iface,
IN POWER_STATE PowerState)
{
IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblSubDevice);
if (This->pPowerNotify)
{
This->pPowerNotify->lpVtbl->PowerChangeNotify(This->pPowerNotify, PowerState);
}
return STATUS_SUCCESS;
}
static
NTSTATUS
NTAPI
ISubDevice_fnPinCount(
IN ISubdevice *iface,
IN ULONG PinId,
IN OUT PULONG FilterNecessary,
IN OUT PULONG FilterCurrent,
IN OUT PULONG FilterPossible,
IN OUT PULONG GlobalCurrent,
IN OUT PULONG GlobalPossible)
{
IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblSubDevice);
if (This->pPinCount)
{
This->pPinCount->lpVtbl->PinCount(This->pPinCount, PinId, FilterNecessary, FilterCurrent, FilterPossible, GlobalCurrent, GlobalPossible);
return STATUS_SUCCESS;
}
/* FIXME
* scan filter descriptor
*/
return STATUS_UNSUCCESSFUL;
}
static ISubdeviceVtbl vt_ISubdevice =
{
ISubDevice_fnQueryInterface,
ISubDevice_fnAddRef,
ISubDevice_fnRelease,
ISubDevice_fnNewIrpTarget,
ISubDevice_fnReleaseChildren,
ISubDevice_fnGetDescriptor,
ISubDevice_fnDataRangeIntersection,
ISubDevice_fnPowerChangeNotify,
ISubDevice_fnPinCount
};
static
NTSTATUS
NTAPI
IServiceSink_fnQueryInterface(
IServiceSink* iface,
IN REFIID refiid,
OUT PVOID* Output)
{
IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblServiceSink);
if (IsEqualGUIDAligned(refiid, &IID_IServiceSink) ||
IsEqualGUIDAligned(refiid, &IID_IUnknown))
{
*Output = &This->lpVtblServiceSink;
InterlockedIncrement(&This->ref);
return STATUS_SUCCESS;
}
DPRINT("Unknown interface requested\n");
return STATUS_UNSUCCESSFUL;
}
static
ULONG
NTAPI
IServiceSink_fnAddRef(
IServiceSink* iface)
{
IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblServiceSink);
return IPortDMus_fnAddRef((IPortDMus*)This);
}
static
ULONG
NTAPI
IServiceSink_fnRelease(
IServiceSink* iface)
{
IPortDMusImpl * This = (IPortDMusImpl*)CONTAINING_RECORD(iface, IPortDMusImpl, lpVtblServiceSink);
return IPortDMus_fnRelease((IPortDMus*)This);
}
static
VOID
NTAPI
IServiceSink_fnRequestService(
IServiceSink* iface)
{
UNIMPLEMENTED
}
static IServiceSinkVtbl vt_IServiceSink =
{
IServiceSink_fnQueryInterface,
IServiceSink_fnAddRef,
IServiceSink_fnRelease,
IServiceSink_fnRequestService
};
NTSTATUS
NewPortDMus(
OUT PPORT* OutPort)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
IPortDMusImpl * This = AllocateItem(NonPagedPool, sizeof(IPortDMusImpl), TAG_PORTCLASS);
if (!This)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
This->ref = 1;
This->lpVtbl = &vt_IPortDMus;
This->lpVtblServiceSink = &vt_IServiceSink;
This->lpVtblSubDevice = &vt_ISubdevice;
*OutPort = (PPORT)&This->lpVtbl;
return STATUS_SUCCESS;
}
VOID
GetDMusMiniport(
IN IPortDMus * iface,
IN PMINIPORTDMUS * Miniport,
IN PMINIPORTMIDI * MidiMiniport)
{
IPortDMusImpl * This = (IPortDMusImpl*)iface;
*Miniport = This->pMiniport;
*MidiMiniport = This->pMiniportMidi;
}

View file

@ -1,481 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Kernel Streaming
* FILE: drivers/wdm/audio/backpln/portcls/port_midi.c
* PURPOSE: Midi Port driver
* PROGRAMMER: Johannes Anderwald
*/
#include "private.h"
typedef struct
{
IPortMidiVtbl *lpVtbl;
ISubdeviceVtbl *lpVtblSubDevice;
LONG ref;
BOOL bInitialized;
PMINIPORTMIDI pMiniport;
PDEVICE_OBJECT pDeviceObject;
PPINCOUNT pPinCount;
PPOWERNOTIFY pPowerNotify;
PSERVICEGROUP pServiceGroup;
PPCFILTER_DESCRIPTOR pDescriptor;
PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
}IPortMidiImpl;
static GUID InterfaceGuids[3] =
{
{
/// KS_CATEGORY_AUDIO
0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
},
{
/// KS_CATEGORY_RENDER
0x65E8773E, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
},
{
/// KS_CATEGORY_CAPTURE
0x65E8773D, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
}
};
//---------------------------------------------------------------
// IUnknown interface functions
//
NTSTATUS
NTAPI
IPortMidi_fnQueryInterface(
IPortMidi* iface,
IN REFIID refiid,
OUT PVOID* Output)
{
UNICODE_STRING GuidString;
IPortMidiImpl * This = (IPortMidiImpl*)iface;
DPRINT("IPortMidi_fnQueryInterface\n");
if (IsEqualGUIDAligned(refiid, &IID_IPortMidi) ||
IsEqualGUIDAligned(refiid, &IID_IPort) ||
IsEqualGUIDAligned(refiid, &IID_IUnknown))
{
*Output = &This->lpVtbl;
InterlockedIncrement(&This->ref);
return STATUS_SUCCESS;
}
else if (IsEqualGUIDAligned(refiid, &IID_ISubdevice))
{
*Output = &This->lpVtblSubDevice;
InterlockedIncrement(&This->ref);
return STATUS_SUCCESS;
}
else if (IsEqualGUIDAligned(refiid, &IID_IPortClsVersion))
{
return NewPortClsVersion((PPORTCLSVERSION*)Output);
}
else if (IsEqualGUIDAligned(refiid, &IID_IDrmPort) ||
IsEqualGUIDAligned(refiid, &IID_IDrmPort2))
{
return NewIDrmPort((PDRMPORT2*)Output);
}
if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
{
DPRINT1("IPortMidi_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer);
RtlFreeUnicodeString(&GuidString);
}
return STATUS_UNSUCCESSFUL;
}
ULONG
NTAPI
IPortMidi_fnAddRef(
IPortMidi* iface)
{
IPortMidiImpl * This = (IPortMidiImpl*)iface;
return InterlockedIncrement(&This->ref);
}
ULONG
NTAPI
IPortMidi_fnRelease(
IPortMidi* iface)
{
IPortMidiImpl * This = (IPortMidiImpl*)iface;
InterlockedDecrement(&This->ref);
if (This->ref == 0)
{
FreeItem(This, TAG_PORTCLASS);
return 0;
}
/* Return new reference count */
return This->ref;
}
//---------------------------------------------------------------
// IPort interface functions
//
NTSTATUS
NTAPI
IPortMidi_fnGetDeviceProperty(
IN IPortMidi * iface,
IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty,
IN ULONG BufferLength,
OUT PVOID PropertyBuffer,
OUT PULONG ReturnLength)
{
IPortMidiImpl * This = (IPortMidiImpl*)iface;
ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
if (!This->bInitialized)
{
DPRINT("IPortMidi_fnNewRegistryKey called w/o initiazed\n");
return STATUS_UNSUCCESSFUL;
}
return IoGetDeviceProperty(This->pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength);
}
NTSTATUS
NTAPI
IPortMidi_fnInit(
IN IPortMidi * iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PUNKNOWN UnknownMiniport,
IN PUNKNOWN UnknownAdapter OPTIONAL,
IN PRESOURCELIST ResourceList)
{
IMiniportMidi * Miniport;
IServiceGroup * ServiceGroup = NULL;
NTSTATUS Status;
IPortMidiImpl * This = (IPortMidiImpl*)iface;
DPRINT("IPortMidi_fnInit entered This %p DeviceObject %p Irp %p UnknownMiniport %p UnknownAdapter %p ResourceList %p\n",
This, DeviceObject, Irp, UnknownMiniport, UnknownAdapter, ResourceList);
ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
if (This->bInitialized)
{
DPRINT1("IPortMidi_Init called again\n");
return STATUS_SUCCESS;
}
Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IMiniportMidi, (PVOID*)&Miniport);
if (!NT_SUCCESS(Status))
{
DPRINT1("IPortMidi_Init called with invalid IMiniport adapter\n");
return STATUS_INVALID_PARAMETER;
}
/* Initialize port object */
This->pMiniport = Miniport;
This->pDeviceObject = DeviceObject;
This->bInitialized = TRUE;
/* increment reference on miniport adapter */
Miniport->lpVtbl->AddRef(Miniport);
Status = Miniport->lpVtbl->Init(Miniport, UnknownAdapter, ResourceList, iface, &ServiceGroup);
if (!NT_SUCCESS(Status))
{
DPRINT1("IPortMidi_Init failed with %x\n", Status);
This->bInitialized = FALSE;
Miniport->lpVtbl->Release(Miniport);
return Status;
}
/* get the miniport device descriptor */
Status = Miniport->lpVtbl->GetDescription(Miniport, &This->pDescriptor);
if (!NT_SUCCESS(Status))
{
DPRINT1("failed to get description\n");
Miniport->lpVtbl->Release(Miniport);
This->bInitialized = FALSE;
return Status;
}
This->pServiceGroup = ServiceGroup;
/* create the subdevice descriptor */
Status = PcCreateSubdeviceDescriptor(&This->SubDeviceDescriptor,
3,
InterfaceGuids,
0,
NULL,
0,
NULL,
0,
0,
0,
NULL,
0,
NULL,
This->pDescriptor);
DPRINT("IPortMidi_fnInit success\n");
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
IPortMidi_fnNewRegistryKey(
IN IPortMidi * iface,
OUT PREGISTRYKEY *OutRegistryKey,
IN PUNKNOWN OuterUnknown OPTIONAL,
IN ULONG RegistryKeyType,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN ULONG CreateOptions OPTIONAL,
OUT PULONG Disposition OPTIONAL)
{
IPortMidiImpl * This = (IPortMidiImpl*)iface;
ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
if (!This->bInitialized)
{
DPRINT("IPortMidi_fnNewRegistryKey called w/o initialized\n");
return STATUS_UNSUCCESSFUL;
}
return PcNewRegistryKey(OutRegistryKey,
OuterUnknown,
RegistryKeyType,
DesiredAccess,
This->pDeviceObject,
NULL,//FIXME
ObjectAttributes,
CreateOptions,
Disposition);
}
VOID
NTAPI
IPortMidi_fnNotify(
IN IPortMidi * iface,
IN PSERVICEGROUP ServiceGroup OPTIONAL)
{
UNIMPLEMENTED
}
NTSTATUS
NTAPI
IPortMidi_fnRegisterServiceGroup(
IN IPortMidi * iface,
IN PSERVICEGROUP ServiceGroup)
{
UNIMPLEMENTED
ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
return STATUS_SUCCESS;
}
static IPortMidiVtbl vt_IPortMidi =
{
/* IUnknown methods */
IPortMidi_fnQueryInterface,
IPortMidi_fnAddRef,
IPortMidi_fnRelease,
/* IPort methods */
IPortMidi_fnInit,
IPortMidi_fnGetDeviceProperty,
IPortMidi_fnNewRegistryKey,
IPortMidi_fnNotify,
IPortMidi_fnRegisterServiceGroup
};
//---------------------------------------------------------------
// ISubdevice interface
//
static
NTSTATUS
NTAPI
ISubDevice_fnQueryInterface(
IN ISubdevice *iface,
IN REFIID InterfaceId,
IN PVOID* Interface)
{
IPortMidiImpl * This = (IPortMidiImpl*)CONTAINING_RECORD(iface, IPortMidiImpl, lpVtblSubDevice);
return IPortMidi_fnQueryInterface((IPortMidi*)This, InterfaceId, Interface);
}
static
ULONG
NTAPI
ISubDevice_fnAddRef(
IN ISubdevice *iface)
{
IPortMidiImpl * This = (IPortMidiImpl*)CONTAINING_RECORD(iface, IPortMidiImpl, lpVtblSubDevice);
return IPortMidi_fnAddRef((IPortMidi*)This);
}
static
ULONG
NTAPI
ISubDevice_fnRelease(
IN ISubdevice *iface)
{
IPortMidiImpl * This = (IPortMidiImpl*)CONTAINING_RECORD(iface, IPortMidiImpl, lpVtblSubDevice);
return IPortMidi_fnRelease((IPortMidi*)This);
}
static
NTSTATUS
NTAPI
ISubDevice_fnNewIrpTarget(
IN ISubdevice *iface,
OUT struct IIrpTarget **OutTarget,
IN WCHAR * Name,
IN PUNKNOWN Unknown,
IN POOL_TYPE PoolType,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN KSOBJECT_CREATE *CreateObject)
{
//IPortMidiImpl * This = (IPortMidiImpl*)CONTAINING_RECORD(iface, IPortMidiImpl, lpVtblSubDevice);
UNIMPLEMENTED
return STATUS_UNSUCCESSFUL;
}
static
NTSTATUS
NTAPI
ISubDevice_fnReleaseChildren(
IN ISubdevice *iface)
{
//IPortMidiImpl * This = (IPortMidiImpl*)CONTAINING_RECORD(iface, IPortMidiImpl, lpVtblSubDevice);
UNIMPLEMENTED
return STATUS_UNSUCCESSFUL;
}
static
NTSTATUS
NTAPI
ISubDevice_fnGetDescriptor(
IN ISubdevice *iface,
IN SUBDEVICE_DESCRIPTOR ** Descriptor)
{
IPortMidiImpl * This = (IPortMidiImpl*)CONTAINING_RECORD(iface, IPortMidiImpl, lpVtblSubDevice);
DPRINT("ISubDevice_GetDescriptor this %p\n", This);
*Descriptor = This->SubDeviceDescriptor;
return STATUS_SUCCESS;
}
static
NTSTATUS
NTAPI
ISubDevice_fnDataRangeIntersection(
IN ISubdevice *iface,
IN ULONG PinId,
IN PKSDATARANGE DataRange,
IN PKSDATARANGE MatchingDataRange,
IN ULONG OutputBufferLength,
OUT PVOID ResultantFormat OPTIONAL,
OUT PULONG ResultantFormatLength)
{
IPortMidiImpl * This = (IPortMidiImpl*)CONTAINING_RECORD(iface, IPortMidiImpl, lpVtblSubDevice);
DPRINT("ISubDevice_DataRangeIntersection this %p\n", This);
if (This->pMiniport)
{
return This->pMiniport->lpVtbl->DataRangeIntersection (This->pMiniport, PinId, DataRange, MatchingDataRange, OutputBufferLength, ResultantFormat, ResultantFormatLength);
}
return STATUS_UNSUCCESSFUL;
}
static
NTSTATUS
NTAPI
ISubDevice_fnPowerChangeNotify(
IN ISubdevice *iface,
IN POWER_STATE PowerState)
{
IPortMidiImpl * This = (IPortMidiImpl*)CONTAINING_RECORD(iface, IPortMidiImpl, lpVtblSubDevice);
if (This->pPowerNotify)
{
This->pPowerNotify->lpVtbl->PowerChangeNotify(This->pPowerNotify, PowerState);
}
return STATUS_SUCCESS;
}
static
NTSTATUS
NTAPI
ISubDevice_fnPinCount(
IN ISubdevice *iface,
IN ULONG PinId,
IN OUT PULONG FilterNecessary,
IN OUT PULONG FilterCurrent,
IN OUT PULONG FilterPossible,
IN OUT PULONG GlobalCurrent,
IN OUT PULONG GlobalPossible)
{
IPortMidiImpl * This = (IPortMidiImpl*)CONTAINING_RECORD(iface, IPortMidiImpl, lpVtblSubDevice);
if (This->pPinCount)
{
This->pPinCount->lpVtbl->PinCount(This->pPinCount, PinId, FilterNecessary, FilterCurrent, FilterPossible, GlobalCurrent, GlobalPossible);
return STATUS_SUCCESS;
}
/* FIXME
* scan filter descriptor
*/
return STATUS_UNSUCCESSFUL;
}
static ISubdeviceVtbl vt_ISubdeviceVtbl =
{
ISubDevice_fnQueryInterface,
ISubDevice_fnAddRef,
ISubDevice_fnRelease,
ISubDevice_fnNewIrpTarget,
ISubDevice_fnReleaseChildren,
ISubDevice_fnGetDescriptor,
ISubDevice_fnDataRangeIntersection,
ISubDevice_fnPowerChangeNotify,
ISubDevice_fnPinCount
};
NTSTATUS
NewPortMidi(
OUT PPORT* OutPort)
{
IPortMidiImpl * This;
This = AllocateItem(NonPagedPool, sizeof(IPortMidiImpl), TAG_PORTCLASS);
if (!This)
return STATUS_INSUFFICIENT_RESOURCES;
This->lpVtbl = &vt_IPortMidi;
This->lpVtblSubDevice = &vt_ISubdeviceVtbl;
This->ref = 1;
*OutPort = (PPORT)(&This->lpVtbl);
DPRINT("NewPortMidi result %p\n", *OutPort);
return STATUS_SUCCESS;
}

View file

@ -19,6 +19,7 @@
<file>dma_slave.c</file>
<file>drm.c</file>
<file>drm_port.c</file>
<file>filter_dmus.c</file>
<file>filter_wavecyclic.c</file>
<file>filter_wavepci.c</file>
<file>filter_wavert.c</file>
@ -29,13 +30,13 @@
<file>miniport.c</file>
<file>miniport_dmus.c</file>
<file>miniport_fmsynth.c</file>
<file>pin_dmus.c</file>
<file>pin_wavecyclic.c</file>
<file>pin_wavepci.c</file>
<file>pin_wavert.c</file>
<file>pool.c</file>
<file>port.c</file>
<file>port_dmus.c</file>
<file>port_midi.c</file>
<file>port_topology.c</file>
<file>port_wavecyclic.c</file>
<file>port_wavepci.c</file>

View file

@ -63,9 +63,6 @@ NTSTATUS NewMiniportFmSynth(
OUT PMINIPORT* OutMiniport,
IN REFCLSID ClassId);
NTSTATUS NewPortMidi(
OUT PPORT* OutPort);
NTSTATUS NewPortDMus(
OUT PPORT* OutPort);
@ -109,6 +106,19 @@ PMINIPORTWAVEPCI
GetWavePciMiniport(
PPORTWAVEPCI Port);
NTSTATUS
NewPortFilterDMus(
OUT PPORTFILTERDMUS * OutFilter);
NTSTATUS NewPortPinDMus(
OUT PPORTPINDMUS * OutPin);
VOID
GetDMusMiniport(
IN IPortDMus * iface,
IN PMINIPORTDMUS * Miniport,
IN PMINIPORTMIDI * MidiMiniport);
#if (NTDDI_VERSION >= NTDDI_VISTA)
NTSTATUS