ReactOS 0.4.15-dev-7834-g00c4b3d
pin_dmus.cpp
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/pin_dmus.cpp
5 * PURPOSE: DMus IRP Audio Pin
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9#include "private.hpp"
10
11#define NDEBUG
12#include <debug.h>
13
14class CPortPinDMus : public CUnknownImpl<IPortPinDMus>
15{
16public:
18
23
24 CPortPinDMus(IUnknown * OuterUnknown){}
25 virtual ~CPortPinDMus(){}
26
27protected:
30
31 IPortDMus * m_Port;
32 IPortFilterDMus * m_Filter;
33 KSPIN_DESCRIPTOR * m_KsPinDescriptor;
35
37
42
45
49
52 IIrpQueue * m_IrpQueue;
53
57
59};
60
61typedef struct
62{
66
67typedef struct
68{
73
74//==================================================================================================================================
77CPortPinDMus::GetTime(OUT REFERENCE_TIME *prtTime)
78{
80 return STATUS_SUCCESS;
81}
82
83//==================================================================================================================================
86CPortPinDMus::GetMessage(
87 OUT PDMUS_KERNEL_EVENT * ppDMKEvt)
88{
90
91 Buffer = ExAllocateFromNPagedLookasideList(&m_LookAsideEvent);
92 if (!Buffer)
94
95 *ppDMKEvt = (PDMUS_KERNEL_EVENT)Buffer;
97 return STATUS_SUCCESS;
98}
99
100USHORT
101NTAPI
102CPortPinDMus::GetBufferSize()
103{
104 return PAGE_SIZE;
105}
106
108NTAPI
109CPortPinDMus::GetBuffer(
110 OUT PBYTE * ppBuffer)
111{
113
114 Buffer = ExAllocateFromNPagedLookasideList(&m_LookAsideBuffer);
115 if (!Buffer)
117
118 *ppBuffer = (PBYTE)Buffer;
120 return STATUS_SUCCESS;
121}
122
124NTAPI
125CPortPinDMus::PutBuffer(
127{
129
130 m_IrpQueue->ReleaseMappingWithTag(Event->Tag);
131
132 ExFreeToNPagedLookasideList(&m_LookAsideBuffer, pBuffer);
133 return STATUS_SUCCESS;
134}
135
137NTAPI
138CPortPinDMus::SetState(
140{
143}
144
146NTAPI
147CPortPinDMus::PutMessage(
148 IN PDMUS_KERNEL_EVENT pDMKEvt)
149{
150 ExFreeToNPagedLookasideList(&m_LookAsideEvent, pDMKEvt);
151 return STATUS_SUCCESS;
152}
153
155NTAPI
156CPortPinDMus::ConnectOutput(
157 IN PMXF sinkMXF)
158{
161}
162
164NTAPI
165CPortPinDMus::DisconnectOutput(
166 IN PMXF sinkMXF)
167{
170}
171
172//==================================================================================================================================
173
174VOID
176{
181
182 do
183 {
184 Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize);
185 if (!NT_SUCCESS(Status))
186 {
187 return;
188 }
189
190 if (m_Capture)
191 {
193 if (!NT_SUCCESS(Status))
194 {
195 DPRINT("Read failed with %x\n", Status);
196 return;
197 }
198 }
199 else
200 {
202 if (!NT_SUCCESS(Status))
203 {
204 DPRINT("Write failed with %x\n", Status);
205 return;
206 }
207 }
208
209 if (!BytesWritten)
210 {
211 DPRINT("Device is busy retry later\n");
212 return;
213 }
214
215 m_IrpQueue->UpdateMapping(BytesWritten);
216
217 }while(TRUE);
218
219}
220
221VOID
223{
229
230 do
231 {
232 m_LastTag++;
234 if (!NT_SUCCESS(Status))
235 {
236 break;
237 }
238
240 if (!NT_SUCCESS(Status))
241 break;
242
243 //FIXME
244 //set up struct
245 //Event->Event.usFlags = DMUS_KEF_EVENT_COMPLETE;
246 Event->Event.cbStruct = sizeof(DMUS_KERNEL_EVENT);
247 Event->Event.cbEvent = (USHORT)BufferSize;
248 Event->Event.uData.pbData = (PBYTE)Buffer;
249
250 if (!Root)
251 Root = Event;
252 else
253 LastEvent->Event.pNextEvt = (struct _DMUS_KERNEL_EVENT *)Event;
254
255 LastEvent = Event;
256 LastEvent->Event.pNextEvt = NULL;
257 LastEvent->Tag = UlongToPtr(m_LastTag);
258
259 }while(TRUE);
260
261 if (!Root)
262 {
263 return;
264 }
265
266 Status = m_Mxf->PutMessage((PDMUS_KERNEL_EVENT)Root);
267 DPRINT("Status %x\n", Status);
268}
269
270VOID
271NTAPI
272CPortPinDMus::RequestService()
273{
275
276 if (m_MidiStream)
277 {
279 }
280 else if (m_Mxf)
281 {
283 }
284}
285
286//==================================================================================================================================
287
289NTAPI
291 IN REFIID refiid,
293{
294
295 if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) ||
297 {
298 *Output = PVOID(PUNKNOWN(this));
299 PUNKNOWN(*Output)->AddRef();
300 return STATUS_SUCCESS;
301 }
302
303 return STATUS_UNSUCCESSFUL;
304}
305
307NTAPI
308CPortPinDMus::NewIrpTarget(
309 OUT struct IIrpTarget **OutTarget,
310 IN PCWSTR Name,
314 IN PIRP Irp,
315 IN KSOBJECT_CREATE *CreateObject)
316{
318
319 Irp->IoStatus.Information = 0;
320 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
322
323 return STATUS_UNSUCCESSFUL;
324}
325
327NTAPI
328CPortPinDMus::DeviceIoControl(
330 IN PIRP Irp)
331{
333
334 Irp->IoStatus.Information = 0;
335 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
337
338 return STATUS_UNSUCCESSFUL;
339}
340
342NTAPI
343CPortPinDMus::Read(
345 IN PIRP Irp)
346{
348}
349
351NTAPI
352CPortPinDMus::Write(
354 IN PIRP Irp)
355{
357}
358
360NTAPI
361CPortPinDMus::Flush(
363 IN PIRP Irp)
364{
366}
367
369NTAPI
370CPortPinDMus::Close(
372 IN PIRP Irp)
373{
375 ISubdevice * SubDevice;
377
378 if (m_ServiceGroup)
379 {
380 m_ServiceGroup->RemoveMember(PSERVICESINK(this));
381 }
382
383 if (m_MidiStream)
384 {
385 if (m_State != KSSTATE_STOP)
386 {
387 m_MidiStream->SetState(KSSTATE_STOP);
389 }
390 DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql());
391 m_MidiStream->Release();
392 }
393
394 Status = m_Port->QueryInterface(IID_ISubdevice, (PVOID*)&SubDevice);
395 if (NT_SUCCESS(Status))
396 {
397 Status = SubDevice->GetDescriptor(&Descriptor);
398 if (NT_SUCCESS(Status))
399 {
400 // release reference count
401 Descriptor->Factory.Instances[m_ConnectDetails->PinId].CurrentPinInstanceCount--;
402 }
403 SubDevice->Release();
404 }
405
406 if (m_Format)
407 {
409 m_Format = NULL;
410 }
411
412 // complete the irp
413 Irp->IoStatus.Information = 0;
414 Irp->IoStatus.Status = STATUS_SUCCESS;
416
417 // destroy DMus pin
418 m_Filter->FreePin(PPORTPINDMUS(this));
419
420 return STATUS_SUCCESS;
421}
422
424NTAPI
425CPortPinDMus::QuerySecurity(
427 IN PIRP Irp)
428{
430}
431
433NTAPI
434CPortPinDMus::SetSecurity(
436 IN PIRP Irp)
437{
439}
440
442NTAPI
443CPortPinDMus::FastDeviceIoControl(
451 OUT PIO_STATUS_BLOCK StatusBlock,
453{
454 return FALSE;
455}
456
458NTAPI
459CPortPinDMus::FastRead(
466 OUT PIO_STATUS_BLOCK StatusBlock,
468{
469 return FALSE;
470}
471
473NTAPI
474CPortPinDMus::FastWrite(
481 OUT PIO_STATUS_BLOCK StatusBlock,
483{
484 return FALSE;
485}
486
488NTAPI
489CPortPinDMus::Init(
492 IN KSPIN_CONNECT * ConnectDetails,
493 IN KSPIN_DESCRIPTOR * KsPinDescriptor,
495{
499
500 Port->AddRef();
501 Filter->AddRef();
502
503 m_Port = Port;
505 m_KsPinDescriptor = KsPinDescriptor;
506 m_ConnectDetails = ConnectDetails;
508
510
511 DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1);
512
513 DPRINT("CPortPinDMus::Init entered\n");
514
516 if (!m_Format)
518
520
521 if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN)
522 {
524 }
525 else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT)
526 {
528 }
529 else
530 {
531 DPRINT("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor->Communication, KsPinDescriptor->DataFlow);
533 while(TRUE);
534 }
535
537 if (!NT_SUCCESS(Status))
538 {
539 DPRINT("Failed to allocate IrpQueue with %x\n", Status);
540 return Status;
541 }
542
543 if (m_MidiMiniport)
544 {
545 Status = m_MidiMiniport->NewStream(&m_MidiStream, NULL, NonPagedPool, ConnectDetails->PinId, Type, m_Format, &m_ServiceGroup);
546
547 DPRINT("CPortPinDMus::Init Status %x\n", Status);
548
549 if (!NT_SUCCESS(Status))
550 return Status;
551 }
552 else
553 {
554 Status = m_Miniport->NewStream(&m_Mxf, NULL, NonPagedPool, ConnectDetails->PinId, Type, m_Format, &m_ServiceGroup, PAllocatorMXF(this), PMASTERCLOCK(this),&m_SchedulePreFetch);
555
556 DPRINT("CPortPinDMus::Init Status %x\n", Status);
557
558 if (!NT_SUCCESS(Status))
559 return Status;
560
562 {
563 Status = m_Mxf->ConnectOutput(PMXF(this));
564 if (!NT_SUCCESS(Status))
565 {
566 DPRINT("IMXF_ConnectOutput failed with Status %x\n", Status);
567 return Status;
568 }
569 }
570
573 }
574
575 if (m_ServiceGroup)
576 {
577 Status = m_ServiceGroup->AddMember(PSERVICESINK(this));
578 if (!NT_SUCCESS(Status))
579 {
580 DPRINT("Failed to add pin to service group\n");
581 return Status;
582 }
583 }
584
585 Status = m_IrpQueue->Init(ConnectDetails, KsPinDescriptor, 0, 0, FALSE);
586 if (!NT_SUCCESS(Status))
587 {
588 DPRINT("IrpQueue_Init failed with %x\n", Status);
589 return Status;
590 }
591
593 m_Capture = Type;
594
595 return STATUS_SUCCESS;
596}
597
598VOID
599NTAPI
600CPortPinDMus::Notify()
601{
602 m_ServiceGroup->RequestService();
603}
604
607 OUT IPortPinDMus ** OutPin)
608{
610
612 if (!This)
614
615 This->AddRef();
616
617 // store result
618 *OutPin = (IPortPinDMus*)This;
619
620 return STATUS_SUCCESS;
621}
unsigned char BOOLEAN
Type
Definition: Type.h:7
IPortFilterDMus * PPORTFILTERDMUS
Definition: interfaces.hpp:839
IPortPinDMus * PPORTPINDMUS
Definition: interfaces.hpp:883
LONG NTSTATUS
Definition: precomp.h:26
#define STDMETHODIMP
Definition: basetyps.h:43
const GUID IID_IUnknown
#define UNIMPLEMENTED
Definition: debug.h:115
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
Definition: bufpool.h:45
PMINIPORTDMUS m_Miniport
Definition: pin_dmus.cpp:34
virtual ~CPortPinDMus()
Definition: pin_dmus.cpp:25
NPAGED_LOOKASIDE_LIST m_LookAsideEvent
Definition: pin_dmus.cpp:40
IPortDMus * m_Port
Definition: pin_dmus.cpp:31
PKSDATAFORMAT m_Format
Definition: pin_dmus.cpp:47
PSERVICEGROUP m_ServiceGroup
Definition: pin_dmus.cpp:36
IIrpQueue * m_IrpQueue
Definition: pin_dmus.cpp:52
VOID TransferMidiData()
Definition: pin_dmus.cpp:175
ULONG m_LastTag
Definition: pin_dmus.cpp:58
STDMETHODIMP QueryInterface(REFIID InterfaceId, PVOID *Interface)
Definition: pin_dmus.cpp:290
PMINIPORTMIDISTREAM m_MidiStream
Definition: pin_dmus.cpp:44
DMUS_STREAM_TYPE m_Capture
Definition: pin_dmus.cpp:50
PDEVICE_OBJECT m_DeviceObject
Definition: pin_dmus.cpp:51
ULONG m_PreCompleted
Definition: pin_dmus.cpp:55
ULONG m_TotalPackets
Definition: pin_dmus.cpp:54
VOID TransferMidiDataToDMus()
Definition: pin_dmus.cpp:222
IPortFilterDMus * m_Filter
Definition: pin_dmus.cpp:32
CPortPinDMus(IUnknown *OuterUnknown)
Definition: pin_dmus.cpp:24
KSSTATE m_State
Definition: pin_dmus.cpp:46
NPAGED_LOOKASIDE_LIST m_LookAsideBuffer
Definition: pin_dmus.cpp:41
KSPIN_DESCRIPTOR * m_KsPinDescriptor
Definition: pin_dmus.cpp:33
PMINIPORTMIDI m_MidiMiniport
Definition: pin_dmus.cpp:43
KSPIN_CONNECT * m_ConnectDetails
Definition: pin_dmus.cpp:48
ULONG m_PostCompleted
Definition: pin_dmus.cpp:56
ULONGLONG m_SchedulePreFetch
Definition: pin_dmus.cpp:39
IUnknown * PUNKNOWN
Definition: com_apitest.h:45
_In_ PIRP Irp
Definition: csq.h:116
#define BufferSize
Definition: mmc.h:75
KSDATAFORMAT * PKSDATAFORMAT
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
IPortDMus * PPORTDMUS
Definition: dmusicks.h:168
struct _DMUS_KERNEL_EVENT * PDMUS_KERNEL_EVENT
struct IAllocatorMXF * PAllocatorMXF
Definition: dmusicks.h:107
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
struct IMXF * PMXF
Definition: dmusicks.h:68
IMiniportDMus * PMINIPORTDMUS
Definition: dmusicks.h:211
struct _DMUS_KERNEL_EVENT DMUS_KERNEL_EVENT
IMasterClock * PMASTERCLOCK
Definition: dmusicks.h:53
DMUS_STREAM_TYPE
Definition: dmusicks.h:28
@ DMUS_STREAM_MIDI_RENDER
Definition: dmusicks.h:30
@ DMUS_STREAM_MIDI_CAPTURE
Definition: dmusicks.h:31
KSDDKAPI NTSTATUS NTAPI KsDispatchInvalidDeviceRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1189
#define UlongToPtr(u)
Definition: config.h:106
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define NonPagedPool
Definition: env_spec_w32.h:307
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG LockKey
Definition: fatprocs.h:2665
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1801
Status
Definition: gdiplustypes.h:25
CPPORT Port[4]
Definition: headless.c:35
@ Unknown
Definition: i8042prt.h:114
NTSYSAPI void WINAPI DbgBreakPoint(void)
ULONG AddRef()
nsrefcnt Release()
NTSTATUS NTAPI NewIrpQueue(IN IIrpQueue **Queue)
Definition: irpstream.cpp:864
KSSTATE
Definition: ks.h:1214
@ KSSTATE_STOP
Definition: ks.h:1215
@ KSPIN_DATAFLOW_IN
Definition: ks.h:1249
@ KSPIN_DATAFLOW_OUT
Definition: ks.h:1250
@ KSPIN_COMMUNICATION_SINK
Definition: ks.h:1255
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:29
VOID FreeItem(IN PVOID Item)
Definition: misc.c:37
VOID NTAPI ExInitializeNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth)
Definition: lookas.c:218
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
BYTE * PBYTE
Definition: pedump.c:66
unsigned short USHORT
Definition: pedump.c:61
NTSTATUS NewPortPinDMus(OUT IPortPinDMus **OutPin)
Definition: pin_dmus.cpp:606
struct DMUS_KERNEL_EVENT_WITH_TAG * PDMUS_KERNEL_EVENT_WITH_TAG
struct SETSTREAM_CONTEXT * PSETSTREAM_CONTEXT
VOID GetDMusMiniport(IN IPortDMus *iface, IN PMINIPORTDMUS *Miniport, IN PMINIPORTMIDI *MidiMiniport)
Definition: port_dmus.cpp:503
IMiniportMidiStream * PMINIPORTMIDISTREAM
Definition: portcls.h:1342
IServiceSink * PSERVICESINK
Definition: portcls.h:569
IServiceGroup * PSERVICEGROUP
Definition: portcls.h:614
IMiniportMidi * PMINIPORTMIDI
Definition: portcls.h:1378
#define PC_ASSERT_IRQL(x)
Definition: private.hpp:30
#define TAG_PORTCLASS
Definition: private.hpp:24
#define REFIID
Definition: guiddef.h:118
PVOID pBuffer
@ Output
Definition: arc.h:85
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
DMUS_KERNEL_EVENT Event
Definition: pin_dmus.cpp:63
ULONG PinId
Definition: ks.h:2603
root entry for file system trees
Definition: entries.h:148
CPortPinDMus * Pin
Definition: pin_dmus.cpp:69
PIO_WORKITEM WorkItem
Definition: pin_dmus.cpp:70
struct _DMUS_KERNEL_EVENT * pNextEvt
Definition: dmusicks.h:20
const uint16_t * PCWSTR
Definition: typedefs.h:57
INT POOL_TYPE
Definition: typedefs.h:78
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3815
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE Interface
Definition: wdffdo.h:465
_In_ WDFREQUEST _In_ size_t _In_ size_t _In_ ULONG IoControlCode
Definition: wdfio.h:325
_In_ WDFREQUEST _In_ size_t OutputBufferLength
Definition: wdfio.h:320
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
Definition: wdfio.h:322
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesWritten
Definition: wdfiotarget.h:960
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:235
#define GetMessage
Definition: winuser.h:5790
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
struct LOOKASIDE_ALIGN _NPAGED_LOOKASIDE_LIST NPAGED_LOOKASIDE_LIST
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1098
#define IO_NO_INCREMENT
Definition: iotypes.h:598
* PFILE_OBJECT
Definition: iotypes.h:1998