mirror of
https://github.com/reactos/reactos.git
synced 2025-04-25 16:10:29 +00:00
- Experimental IPortPinWavePci implementation
- Refactor IPortWavePciStream initilization - Add test code for IDrmAudioStream svn path=/trunk/; revision=40712
This commit is contained in:
parent
dc97dbb867
commit
86b82cf4d6
9 changed files with 907 additions and 43 deletions
|
@ -131,7 +131,7 @@ IPortFilterWavePci_fnNewIrpTarget(
|
|||
}
|
||||
|
||||
/* initialize the pin */
|
||||
Status = Pin->lpVtbl->Init(Pin, This->Port, iface, ConnectDetails, &This->Descriptor->Factory.KsPinDescriptor[ConnectDetails->PinId], GetDeviceObjectFromWaveCyclic(This->Port));
|
||||
Status = Pin->lpVtbl->Init(Pin, This->Port, iface, ConnectDetails, &This->Descriptor->Factory.KsPinDescriptor[ConnectDetails->PinId], GetDeviceObjectFromPortWavePci(This->Port));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Pin->lpVtbl->Release(Pin);
|
||||
|
|
|
@ -51,7 +51,7 @@ const GUID IID_IUnknown = {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0xC0, 0x00,
|
|||
const GUID IID_IPortEvents = {0xA80F29C4L, 0x5498, 0x11D2, {0x95, 0xD9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}};
|
||||
|
||||
const GUID KSNAME_PIN = {0x146F1A80, 0x4791, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
|
||||
|
||||
const GUID IID_IDrmAudioStream = {0x1915c967, 0x3299, 0x48cb, {0xa3, 0xe4, 0x69, 0xfd, 0x1d, 0x1b, 0x30, 0x6e}};
|
||||
|
||||
//FIXME
|
||||
//
|
||||
|
|
|
@ -230,6 +230,7 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown)
|
|||
STDMETHOD_(VOID, ReleaseMappingWithTag)(THIS_
|
||||
IN PVOID Tag);
|
||||
|
||||
STDMETHOD_(BOOL, HasLastMappingFailed)(THIS);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ typedef struct
|
|||
BOOL OutOfMapping;
|
||||
ULONG MaxFrameSize;
|
||||
|
||||
BOOL LastMappingFailed;
|
||||
|
||||
}IIrpQueueImpl;
|
||||
|
||||
VOID
|
||||
|
@ -189,11 +191,14 @@ IIrpQueue_fnGetMapping(
|
|||
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
|
||||
|
||||
if (!This->FirstMap)
|
||||
{
|
||||
This->LastMappingFailed = TRUE;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
*Buffer = (PUCHAR)This->FirstMap->Header->Data + This->CurrentOffset;
|
||||
*BufferSize = This->FirstMap->Header->DataUsed - This->CurrentOffset;
|
||||
|
||||
This->LastMappingFailed = FALSE;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -365,13 +370,17 @@ IIrpQueue_fnGetMappingWithTag(
|
|||
|
||||
KeReleaseSpinLock(&This->Lock, OldIrql);
|
||||
if (!Result)
|
||||
{
|
||||
This->LastMappingFailed = TRUE;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
Result->Tag = Tag;
|
||||
*PhysicalAddress = MmGetPhysicalAddress(Result->Header->Data);
|
||||
*VirtualAddress = Result->Header->Data;
|
||||
*ByteCount = Result->Header->DataUsed;
|
||||
This->LastTag = Tag;
|
||||
This->LastMappingFailed = FALSE;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -421,6 +430,15 @@ IIrpQueue_fnReleaseMappingWithTag(
|
|||
KeReleaseSpinLock(&This->Lock, OldIrql);
|
||||
}
|
||||
|
||||
BOOL
|
||||
NTAPI
|
||||
IIrpQueue_fnHasLastMappingFailed(
|
||||
IN IIrpQueue *iface)
|
||||
{
|
||||
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
|
||||
return This->LastMappingFailed;
|
||||
}
|
||||
|
||||
static IIrpQueueVtbl vt_IIrpQueue =
|
||||
{
|
||||
IIrpQueue_fnQueryInterface,
|
||||
|
@ -436,7 +454,9 @@ static IIrpQueueVtbl vt_IIrpQueue =
|
|||
IIrpQueue_fnCancelBuffers,
|
||||
IIrpQueue_fnUpdateFormat,
|
||||
IIrpQueue_fnGetMappingWithTag,
|
||||
IIrpQueue_fnReleaseMappingWithTag
|
||||
IIrpQueue_fnReleaseMappingWithTag,
|
||||
IIrpQueue_fnHasLastMappingFailed
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -37,6 +37,10 @@ typedef struct
|
|||
ULONG FrameSize;
|
||||
BOOL Capture;
|
||||
|
||||
ULONG TotalPackets;
|
||||
ULONG PreCompleted;
|
||||
ULONG PostCompleted;
|
||||
|
||||
}IPortPinWaveCyclicImpl;
|
||||
|
||||
|
||||
|
@ -120,6 +124,8 @@ UpdateCommonBuffer(
|
|||
ULONG BufferSize;
|
||||
PUCHAR Buffer;
|
||||
NTSTATUS Status;
|
||||
PUSHORT Data;
|
||||
ULONG Index;
|
||||
|
||||
BufferLength = Position - This->CommonBufferOffset;
|
||||
while(BufferLength)
|
||||
|
@ -140,6 +146,10 @@ UpdateCommonBuffer(
|
|||
}
|
||||
else
|
||||
{
|
||||
Data = (PUSHORT)Buffer;
|
||||
for(Index = 0; Index < BytesToCopy / sizeof(USHORT); Index++)
|
||||
Data[Index] = Data[Index] + 32768;
|
||||
|
||||
This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
|
||||
(PUCHAR)This->CommonBuffer + This->CommonBufferOffset,
|
||||
Buffer,
|
||||
|
@ -164,6 +174,8 @@ UpdateCommonBufferOverlap(
|
|||
ULONG BufferSize;
|
||||
PUCHAR Buffer;
|
||||
NTSTATUS Status;
|
||||
PUSHORT Data;
|
||||
ULONG Index;
|
||||
|
||||
BufferLength = This->CommonBufferSize - This->CommonBufferOffset;
|
||||
while(BufferLength)
|
||||
|
@ -183,6 +195,10 @@ UpdateCommonBufferOverlap(
|
|||
}
|
||||
else
|
||||
{
|
||||
Data = (PUSHORT)Buffer;
|
||||
for(Index = 0; Index < BytesToCopy / sizeof(USHORT); Index++)
|
||||
Data[Index] = Data[Index] + 32768;
|
||||
|
||||
This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
|
||||
(PUCHAR)This->CommonBuffer + This->CommonBufferOffset,
|
||||
Buffer,
|
||||
|
@ -228,7 +244,7 @@ SetStreamWorkerRoutine(
|
|||
{
|
||||
/* reset start stream */
|
||||
This->IrpQueue->lpVtbl->CancelBuffers(This->IrpQueue); //FIX function name
|
||||
DPRINT1("Stopping %u Irql %u\n", This, This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue), KeGetCurrentIrql());
|
||||
DPRINT1("Stopping PreCompleted %u PostCompleted %u\n", This->PreCompleted, This->PostCompleted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -908,7 +924,9 @@ IPortPinWaveCyclic_fnFastWrite(
|
|||
PIRP Irp;
|
||||
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
|
||||
|
||||
DPRINT("IPortPinWaveCyclic_fnFastWrite entered\n");
|
||||
InterlockedIncrement((PLONG)&This->TotalPackets);
|
||||
|
||||
DPRINT("IPortPinWaveCyclic_fnFastWrite entered Total %u Pre %u Post %u\n", This->TotalPackets, This->PreCompleted, This->PostCompleted);
|
||||
|
||||
Packet = (PCONTEXT_WRITE)Buffer;
|
||||
|
||||
|
@ -917,6 +935,7 @@ IPortPinWaveCyclic_fnFastWrite(
|
|||
{
|
||||
Irp = Packet->Irp;
|
||||
StatusBlock->Status = STATUS_PENDING;
|
||||
InterlockedIncrement((PLONG)&This->PostCompleted);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -925,6 +944,7 @@ IPortPinWaveCyclic_fnFastWrite(
|
|||
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);
|
||||
|
@ -958,6 +978,7 @@ IPortPinWaveCyclic_fnInit(
|
|||
PKSDATAFORMAT DataFormat;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
BOOL Capture;
|
||||
//IDrmAudioStream * DrmAudio = NULL;
|
||||
|
||||
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
|
||||
|
||||
|
@ -1016,6 +1037,21 @@ IPortPinWaveCyclic_fnInit(
|
|||
This->Format,
|
||||
&This->DmaChannel,
|
||||
&This->ServiceGroup);
|
||||
#if 0
|
||||
Status = This->Stream->lpVtbl->QueryInterface(This->Stream, &IID_IDrmAudioStream, (PVOID*)&DrmAudio);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
DRMRIGHTS DrmRights;
|
||||
DPRINT1("Got IID_IDrmAudioStream interface %p\n", DrmAudio);
|
||||
|
||||
DrmRights.CopyProtect = FALSE;
|
||||
DrmRights.Reserved = 0;
|
||||
DrmRights.DigitalOutputDisable = FALSE;
|
||||
|
||||
Status = DrmAudio->lpVtbl->SetContentId(DrmAudio, 1, &DrmRights);
|
||||
DPRINT("Status %x\n", Status);
|
||||
}
|
||||
#endif
|
||||
|
||||
DPRINT("IPortPinWaveCyclic_fnInit Status %x\n", Status);
|
||||
|
||||
|
@ -1033,7 +1069,7 @@ IPortPinWaveCyclic_fnInit(
|
|||
This->ServiceGroup->lpVtbl->SupportDelayedService(This->ServiceGroup);
|
||||
//This->DmaChannel->lpVtbl->AddRef(This->DmaChannel);
|
||||
|
||||
|
||||
This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP);
|
||||
This->State = KSSTATE_STOP;
|
||||
This->CommonBufferOffset = 0;
|
||||
This->CommonBufferSize = This->DmaChannel->lpVtbl->AllocatedBufferSize(This->DmaChannel);
|
||||
|
|
|
@ -1,16 +1,829 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Kernel Streaming
|
||||
* FILE: drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c
|
||||
* PURPOSE: WaveCyclic IRP Audio Pin
|
||||
* FILE: drivers/wdm/audio/backpln/portcls/pin_WavePci.c
|
||||
* PURPOSE: WavePci IRP Audio Pin
|
||||
* PROGRAMMER: Johannes Anderwald
|
||||
*/
|
||||
|
||||
#include "private.h"
|
||||
|
||||
NTSTATUS
|
||||
NewPortPinWavePci(
|
||||
OUT IPortPinWavePci ** OutPin)
|
||||
#include "private.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
IPortPinWavePciVtbl *lpVtbl;
|
||||
IServiceSinkVtbl *lpVtblServiceSink;
|
||||
|
||||
LONG ref;
|
||||
IPortWavePci * Port;
|
||||
IPortFilterWavePci * Filter;
|
||||
KSPIN_DESCRIPTOR * KsPinDescriptor;
|
||||
PMINIPORTWAVEPCI Miniport;
|
||||
PSERVICEGROUP ServiceGroup;
|
||||
PDMACHANNEL DmaChannel;
|
||||
PMINIPORTWAVEPCISTREAM Stream;
|
||||
KSSTATE State;
|
||||
PKSDATAFORMAT Format;
|
||||
KSPIN_CONNECT * ConnectDetails;
|
||||
|
||||
BOOL Capture;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PPORTWAVEPCISTREAM WaveStream;
|
||||
IIrpQueue * IrpQueue;
|
||||
|
||||
ULONG TotalPackets;
|
||||
ULONG PreCompleted;
|
||||
ULONG PostCompleted;
|
||||
|
||||
}IPortPinWavePciImpl;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
IPortPinWavePciImpl *Pin;
|
||||
PIO_WORKITEM WorkItem;
|
||||
KSSTATE State;
|
||||
}SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT;
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IPortWavePci_fnProcessNewIrp(
|
||||
IPortPinWavePciImpl * This);
|
||||
|
||||
//==================================================================================================================================
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IServiceSink_fnQueryInterface(
|
||||
IServiceSink* iface,
|
||||
IN REFIID refiid,
|
||||
OUT PVOID* Output)
|
||||
{
|
||||
IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface, IPortPinWavePciImpl, 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)
|
||||
{
|
||||
IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface, IPortPinWavePciImpl, lpVtblServiceSink);
|
||||
DPRINT("IServiceSink_fnAddRef entered\n");
|
||||
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static
|
||||
ULONG
|
||||
NTAPI
|
||||
IServiceSink_fnRelease(
|
||||
IServiceSink* iface)
|
||||
{
|
||||
IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface, IPortPinWavePciImpl, 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)
|
||||
{
|
||||
IPortPinWavePciImpl * 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->Stream->lpVtbl->SetState(This->Stream, 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 IPortPinWavePciImpl * This,
|
||||
IN KSSTATE State)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
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;
|
||||
|
||||
/* Get device object */
|
||||
DeviceObject = GetDeviceObjectFromPortWavePci(This->Port);
|
||||
|
||||
/* allocate set state context */
|
||||
Context = AllocateItem(NonPagedPool, sizeof(SETSTREAM_CONTEXT), TAG_PORTCLASS);
|
||||
|
||||
if (!Context)
|
||||
return;
|
||||
|
||||
/* allocate work item */
|
||||
WorkItem = IoAllocateWorkItem(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);
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
NTAPI
|
||||
IServiceSink_fnRequestService(
|
||||
IServiceSink* iface)
|
||||
{
|
||||
ULONGLONG Position;
|
||||
NTSTATUS Status;
|
||||
IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)CONTAINING_RECORD(iface, IPortPinWavePciImpl, lpVtblServiceSink);
|
||||
|
||||
ASSERT_IRQL(DISPATCH_LEVEL);
|
||||
|
||||
Status = This->Stream->lpVtbl->GetPosition(This->Stream, &Position);
|
||||
DPRINT("Position %llu Status %x\n", Position, Status);
|
||||
|
||||
This->Stream->lpVtbl->Service(This->Stream);
|
||||
}
|
||||
|
||||
static IServiceSinkVtbl vt_IServiceSink =
|
||||
{
|
||||
IServiceSink_fnQueryInterface,
|
||||
IServiceSink_fnAddRef,
|
||||
IServiceSink_fnRelease,
|
||||
IServiceSink_fnRequestService
|
||||
};
|
||||
|
||||
//==================================================================================================================================
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IPortPinWavePci_fnQueryInterface(
|
||||
IPortPinWavePci* iface,
|
||||
IN REFIID refiid,
|
||||
OUT PVOID* Output)
|
||||
{
|
||||
IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)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
|
||||
IPortPinWavePci_fnAddRef(
|
||||
IPortPinWavePci* iface)
|
||||
{
|
||||
IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
|
||||
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
ULONG
|
||||
NTAPI
|
||||
IPortPinWavePci_fnRelease(
|
||||
IPortPinWavePci* iface)
|
||||
{
|
||||
IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
|
||||
|
||||
InterlockedDecrement(&This->ref);
|
||||
|
||||
if (This->ref == 0)
|
||||
{
|
||||
FreeItem(This, TAG_PORTCLASS);
|
||||
return 0;
|
||||
}
|
||||
return This->ref;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IPortPinWavePci_fnNewIrpTarget(
|
||||
IN IPortPinWavePci* 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
|
||||
IPortPinWavePci_fnDeviceIoControl(
|
||||
IN IPortPinWavePci* 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
|
||||
IPortPinWavePci_fnRead(
|
||||
IN IPortPinWavePci* iface,
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IPortPinWavePci_fnWrite(
|
||||
IN IPortPinWavePci* iface,
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IPortPinWavePci_fnFlush(
|
||||
IN IPortPinWavePci* iface,
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
NTAPI
|
||||
CloseStreamRoutine(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PVOID Context)
|
||||
{
|
||||
PMINIPORTWAVEPCISTREAM Stream;
|
||||
NTSTATUS Status;
|
||||
ISubdevice *ISubDevice;
|
||||
PSUBDEVICE_DESCRIPTOR Descriptor;
|
||||
IPortPinWavePciImpl * This;
|
||||
PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context;
|
||||
|
||||
This = (IPortPinWavePciImpl*)Ctx->Pin;
|
||||
|
||||
if (This->Stream)
|
||||
{
|
||||
if (This->State != KSSTATE_STOP)
|
||||
{
|
||||
This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP);
|
||||
KeStallExecutionProcessor(10);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (This->WaveStream)
|
||||
{
|
||||
This->WaveStream->lpVtbl->Release(This->WaveStream);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
if (This->Stream)
|
||||
{
|
||||
Stream = This->Stream;
|
||||
This->Stream = NULL;
|
||||
DPRINT1("Closing stream at Irql %u\n", KeGetCurrentIrql());
|
||||
Stream->lpVtbl->Release(Stream);
|
||||
/* this line is never reached */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IPortPinWavePci_fnClose(
|
||||
IN IPortPinWavePci* iface,
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PCLOSESTREAM_CONTEXT Ctx;
|
||||
IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
|
||||
|
||||
if (This->Stream)
|
||||
{
|
||||
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
|
||||
IPortPinWavePci_fnQuerySecurity(
|
||||
IN IPortPinWavePci* iface,
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IPortPinWavePci_fnSetSecurity(
|
||||
IN IPortPinWavePci* iface,
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
IPortPinWavePci_fnFastDeviceIoControl(
|
||||
IN IPortPinWavePci* 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
|
||||
IPortPinWavePci_fnFastRead(
|
||||
IN IPortPinWavePci* 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;
|
||||
IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
|
||||
|
||||
DPRINT("IPortPinWavePci_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));
|
||||
|
||||
This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_RUN);
|
||||
This->State = KSSTATE_RUN;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
IPortPinWavePci_fnFastWrite(
|
||||
IN IPortPinWavePci* 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;
|
||||
IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
|
||||
|
||||
InterlockedIncrement((PLONG)&This->TotalPackets);
|
||||
|
||||
DPRINT("IPortPinWavePci_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);
|
||||
}
|
||||
|
||||
if (This->IrpQueue->lpVtbl->HasLastMappingFailed(This->IrpQueue))
|
||||
{
|
||||
/* notify port driver that new mapping is available */
|
||||
This->Stream->lpVtbl->MappingAvailable(This->Stream);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IPortPinWavePci_fnInit(
|
||||
IN IPortPinWavePci* iface,
|
||||
IN PPORTWAVEPCI Port,
|
||||
IN PPORTFILTERWAVEPCI Filter,
|
||||
IN KSPIN_CONNECT * ConnectDetails,
|
||||
IN KSPIN_DESCRIPTOR * KsPinDescriptor,
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PKSDATAFORMAT DataFormat;
|
||||
BOOL Capture;
|
||||
KSALLOCATOR_FRAMING AllocatorFraming;
|
||||
|
||||
IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
|
||||
|
||||
Port->lpVtbl->AddRef(Port);
|
||||
Filter->lpVtbl->AddRef(Filter);
|
||||
|
||||
This->Port = Port;
|
||||
This->Filter = Filter;
|
||||
This->KsPinDescriptor = KsPinDescriptor;
|
||||
This->ConnectDetails = ConnectDetails;
|
||||
This->Miniport = GetWavePciMiniport(Port);
|
||||
This->DeviceObject = DeviceObject;
|
||||
|
||||
DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1);
|
||||
|
||||
DPRINT("IPortPinWavePci_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 = NewIPortWavePciStream(&This->WaveStream);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(This->Format);
|
||||
This->Format = NULL;
|
||||
return Status;
|
||||
}
|
||||
|
||||
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 = This->Miniport->lpVtbl->NewStream(This->Miniport,
|
||||
&This->Stream,
|
||||
NULL,
|
||||
NonPagedPool,
|
||||
This->WaveStream,
|
||||
Capture,
|
||||
ConnectDetails->PinId,
|
||||
This->Format,
|
||||
&This->DmaChannel,
|
||||
&This->ServiceGroup);
|
||||
|
||||
DPRINT("IPortPinWavePci_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);
|
||||
}
|
||||
|
||||
This->IrpQueue = IPortWavePciStream_GetIrpQueue(This->WaveStream);
|
||||
|
||||
Status = This->Stream->lpVtbl->GetAllocatorFraming(This->Stream, &AllocatorFraming);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("GetAllocatorFraming failed with %x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = This->IrpQueue->lpVtbl->Init(This->IrpQueue, ConnectDetails, This->Format, DeviceObject, AllocatorFraming.FrameSize);
|
||||
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
|
||||
*/
|
||||
PVOID
|
||||
NTAPI
|
||||
IPortPinWavePci_fnGetIrpStream(
|
||||
IN IPortPinWavePci* iface)
|
||||
{
|
||||
IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
|
||||
|
||||
return (PVOID)This->IrpQueue;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
PMINIPORT
|
||||
NTAPI
|
||||
IPortPinWavePci_fnGetMiniport(
|
||||
IN IPortPinWavePci* iface)
|
||||
{
|
||||
IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
|
||||
|
||||
return (PMINIPORT)This->Miniport;
|
||||
}
|
||||
|
||||
static IPortPinWavePciVtbl vt_IPortPinWavePci =
|
||||
{
|
||||
IPortPinWavePci_fnQueryInterface,
|
||||
IPortPinWavePci_fnAddRef,
|
||||
IPortPinWavePci_fnRelease,
|
||||
IPortPinWavePci_fnNewIrpTarget,
|
||||
IPortPinWavePci_fnDeviceIoControl,
|
||||
IPortPinWavePci_fnRead,
|
||||
IPortPinWavePci_fnWrite,
|
||||
IPortPinWavePci_fnFlush,
|
||||
IPortPinWavePci_fnClose,
|
||||
IPortPinWavePci_fnQuerySecurity,
|
||||
IPortPinWavePci_fnSetSecurity,
|
||||
IPortPinWavePci_fnFastDeviceIoControl,
|
||||
IPortPinWavePci_fnFastRead,
|
||||
IPortPinWavePci_fnFastWrite,
|
||||
IPortPinWavePci_fnInit,
|
||||
IPortPinWavePci_fnGetIrpStream,
|
||||
IPortPinWavePci_fnGetMiniport
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
NTSTATUS NewPortPinWavePci(
|
||||
OUT IPortPinWavePci ** OutPin)
|
||||
{
|
||||
IPortPinWavePciImpl * This;
|
||||
|
||||
This = AllocateItem(NonPagedPool, sizeof(IPortPinWavePciImpl), TAG_PORTCLASS);
|
||||
if (!This)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
/* initialize IPortPinWavePci */
|
||||
This->ref = 1;
|
||||
This->lpVtbl = &vt_IPortPinWavePci;
|
||||
This->lpVtblServiceSink = &vt_IServiceSink;
|
||||
|
||||
|
||||
/* store result */
|
||||
*OutPin = (IPortPinWavePci*)&This->lpVtbl;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -813,10 +813,17 @@ NewPortWavePci(
|
|||
}
|
||||
|
||||
PDEVICE_OBJECT
|
||||
GetDeviceObjectFromWaveCyclic(
|
||||
GetDeviceObjectFromPortWavePci(
|
||||
IPortWavePci* iface)
|
||||
{
|
||||
IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
|
||||
return This->pDeviceObject;
|
||||
}
|
||||
|
||||
PMINIPORTWAVEPCI
|
||||
GetWavePciMiniport(
|
||||
PPORTWAVEPCI iface)
|
||||
{
|
||||
IPortWavePciImpl * This = (IPortWavePciImpl*)iface;
|
||||
return This->Miniport;
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@ IPortWavePciStream_fnRelease(
|
|||
|
||||
if (This->ref == 0)
|
||||
{
|
||||
This->Queue->lpVtbl->Release(This->Queue);
|
||||
FreeItem(This, TAG_PORTCLASS);
|
||||
return 0;
|
||||
}
|
||||
|
@ -131,11 +132,7 @@ static IPortWavePciStreamVtbl vt_PortWavePciStream =
|
|||
NTSTATUS
|
||||
NTAPI
|
||||
NewIPortWavePciStream(
|
||||
OUT PPORTWAVEPCISTREAM *Stream,
|
||||
IN KSPIN_CONNECT *ConnectDetails,
|
||||
IN PKSDATAFORMAT DataFormat,
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN ULONG FrameSize)
|
||||
OUT PPORTWAVEPCISTREAM *Stream)
|
||||
{
|
||||
IIrpQueue * Queue;
|
||||
IPortWavePciStreamImpl * This;
|
||||
|
@ -145,13 +142,6 @@ NewIPortWavePciStream(
|
|||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
Status = Queue->lpVtbl->Init(Queue, ConnectDetails, DataFormat, DeviceObject, FrameSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Queue->lpVtbl->Release(Queue);
|
||||
return Status;
|
||||
}
|
||||
|
||||
This = AllocateItem(NonPagedPool, sizeof(IPortWavePciStreamImpl), TAG_PORTCLASS);
|
||||
if (!This)
|
||||
{
|
||||
|
@ -167,15 +157,12 @@ NewIPortWavePciStream(
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
IIrpQueue*
|
||||
NTAPI
|
||||
IPortWavePciStream_AddMapping(
|
||||
IN IPortWavePciStream *iface,
|
||||
IN PUCHAR Buffer,
|
||||
IN ULONG BufferSize,
|
||||
IN PIRP Irp)
|
||||
IPortWavePciStream_GetIrpQueue(
|
||||
IN IPortWavePciStream *iface)
|
||||
{
|
||||
IPortWavePciStreamImpl * This = (IPortWavePciStreamImpl*)iface;
|
||||
return This->Queue->lpVtbl->AddMapping(This->Queue, Buffer, BufferSize, Irp);
|
||||
return This->Queue;
|
||||
}
|
||||
|
||||
|
|
|
@ -101,6 +101,13 @@ PDEVICE_OBJECT
|
|||
GetDeviceObjectFromWaveCyclic(
|
||||
IPortWavePci* iface);
|
||||
|
||||
PDEVICE_OBJECT
|
||||
GetDeviceObjectFromPortWavePci(
|
||||
IPortWavePci* iface);
|
||||
|
||||
PMINIPORTWAVEPCI
|
||||
GetWavePciMiniport(
|
||||
PPORTWAVEPCI Port);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
|
@ -272,22 +279,15 @@ PDEVICE_OBJECT
|
|||
GetDeviceObject(
|
||||
IPortWaveCyclic* iface);
|
||||
|
||||
NTSTATUS
|
||||
IIrpQueue*
|
||||
NTAPI
|
||||
IPortWavePciStream_AddMapping(
|
||||
IN IPortWavePciStream *iface,
|
||||
IN PUCHAR Buffer,
|
||||
IN ULONG BufferSize,
|
||||
IN PIRP Irp);
|
||||
IPortWavePciStream_GetIrpQueue(
|
||||
IN IPortWavePciStream *iface);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NewIPortWavePciStream(
|
||||
OUT PPORTWAVEPCISTREAM *Stream,
|
||||
IN KSPIN_CONNECT *ConnectDetails,
|
||||
IN PKSDATAFORMAT DataFormat,
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN ULONG FrameSize);
|
||||
OUT PPORTWAVEPCISTREAM *Stream);
|
||||
|
||||
#define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet,\
|
||||
PropGeneral, PropInstances, PropIntersection)\
|
||||
|
|
Loading…
Reference in a new issue