ReactOS 0.4.15-dev-5865-g640e228
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#ifndef YDEBUG
12#define NDEBUG
13#endif
14
15#include <debug.h>
16
17class CPortPinDMus : public CUnknownImpl<IPortPinDMus>
18{
19public:
21
26
27 CPortPinDMus(IUnknown * OuterUnknown){}
28 virtual ~CPortPinDMus(){}
29
30protected:
33
34 IPortDMus * m_Port;
35 IPortFilterDMus * m_Filter;
36 KSPIN_DESCRIPTOR * m_KsPinDescriptor;
38
40
45
48
49
53
56 IIrpQueue * m_IrpQueue;
57
61
63};
64
65typedef struct
66{
70
71typedef struct
72{
77
78//==================================================================================================================================
81CPortPinDMus::GetTime(OUT REFERENCE_TIME *prtTime)
82{
84 return STATUS_SUCCESS;
85}
86
87//==================================================================================================================================
90CPortPinDMus::GetMessage(
91 OUT PDMUS_KERNEL_EVENT * ppDMKEvt)
92{
94
95 Buffer = ExAllocateFromNPagedLookasideList(&m_LookAsideEvent);
96 if (!Buffer)
98
99 *ppDMKEvt = (PDMUS_KERNEL_EVENT)Buffer;
101 return STATUS_SUCCESS;
102}
103
104USHORT
105NTAPI
106CPortPinDMus::GetBufferSize()
107{
108 return PAGE_SIZE;
109}
110
112NTAPI
113CPortPinDMus::GetBuffer(
114 OUT PBYTE * ppBuffer)
115{
117
118 Buffer = ExAllocateFromNPagedLookasideList(&m_LookAsideBuffer);
119 if (!Buffer)
121
122 *ppBuffer = (PBYTE)Buffer;
124 return STATUS_SUCCESS;
125}
126
127
129NTAPI
130CPortPinDMus::PutBuffer(
132{
134
135 m_IrpQueue->ReleaseMappingWithTag(Event->Tag);
136
137 ExFreeToNPagedLookasideList(&m_LookAsideBuffer, pBuffer);
138 return STATUS_SUCCESS;
139}
140
142NTAPI
143CPortPinDMus::SetState(
145{
148}
149
150
152NTAPI
153CPortPinDMus::PutMessage(
154 IN PDMUS_KERNEL_EVENT pDMKEvt)
155{
156 ExFreeToNPagedLookasideList(&m_LookAsideEvent, pDMKEvt);
157 return STATUS_SUCCESS;
158}
159
160
162NTAPI
163CPortPinDMus::ConnectOutput(
164 IN PMXF sinkMXF)
165{
168}
169
170
172NTAPI
173CPortPinDMus::DisconnectOutput(
174 IN PMXF sinkMXF)
175{
178}
179
180//==================================================================================================================================
181
182VOID
184{
189
190 do
191 {
192 Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize);
193 if (!NT_SUCCESS(Status))
194 {
195 return;
196 }
197
198 if (m_Capture)
199 {
201 if (!NT_SUCCESS(Status))
202 {
203 DPRINT("Read failed with %x\n", Status);
204 return;
205 }
206 }
207 else
208 {
210 if (!NT_SUCCESS(Status))
211 {
212 DPRINT("Write failed with %x\n", Status);
213 return;
214 }
215 }
216
217 if (!BytesWritten)
218 {
219 DPRINT("Device is busy retry later\n");
220 return;
221 }
222
223 m_IrpQueue->UpdateMapping(BytesWritten);
224
225 }while(TRUE);
226
227}
228
229VOID
231{
237
238 do
239 {
240 m_LastTag++;
242 if (!NT_SUCCESS(Status))
243 {
244 break;
245 }
246
248 if (!NT_SUCCESS(Status))
249 break;
250
251 //FIXME
252 //set up struct
253 //Event->Event.usFlags = DMUS_KEF_EVENT_COMPLETE;
254 Event->Event.cbStruct = sizeof(DMUS_KERNEL_EVENT);
255 Event->Event.cbEvent = (USHORT)BufferSize;
256 Event->Event.uData.pbData = (PBYTE)Buffer;
257
258
259 if (!Root)
260 Root = Event;
261 else
262 LastEvent->Event.pNextEvt = (struct _DMUS_KERNEL_EVENT *)Event;
263
264 LastEvent = Event;
265 LastEvent->Event.pNextEvt = NULL;
266 LastEvent->Tag = UlongToPtr(m_LastTag);
267
268 }while(TRUE);
269
270 if (!Root)
271 {
272 return;
273 }
274
275 Status = m_Mxf->PutMessage((PDMUS_KERNEL_EVENT)Root);
276 DPRINT("Status %x\n", Status);
277}
278
279
280
281VOID
282NTAPI
283CPortPinDMus::RequestService()
284{
286
287 if (m_MidiStream)
288 {
290 }
291 else if (m_Mxf)
292 {
294 }
295}
296
297//==================================================================================================================================
299NTAPI
301 IN REFIID refiid,
303{
304
305 if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) ||
307 {
308 *Output = PVOID(PUNKNOWN(this));
309 PUNKNOWN(*Output)->AddRef();
310 return STATUS_SUCCESS;
311 }
312
313 return STATUS_UNSUCCESSFUL;
314}
315
317NTAPI
318CPortPinDMus::NewIrpTarget(
319 OUT struct IIrpTarget **OutTarget,
320 IN PCWSTR Name,
324 IN PIRP Irp,
325 IN KSOBJECT_CREATE *CreateObject)
326{
328
329 Irp->IoStatus.Information = 0;
330 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
332
333 return STATUS_UNSUCCESSFUL;
334}
335
337NTAPI
338CPortPinDMus::DeviceIoControl(
340 IN PIRP Irp)
341{
343
344 Irp->IoStatus.Information = 0;
345 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
347
348 return STATUS_UNSUCCESSFUL;
349}
350
352NTAPI
353CPortPinDMus::Read(
355 IN PIRP Irp)
356{
358}
359
361NTAPI
362CPortPinDMus::Write(
364 IN PIRP Irp)
365{
367}
368
370NTAPI
371CPortPinDMus::Flush(
373 IN PIRP Irp)
374{
376}
377
379NTAPI
380CPortPinDMus::Close(
382 IN PIRP Irp)
383{
385 ISubdevice * SubDevice;
387
388 if (m_ServiceGroup)
389 {
390 m_ServiceGroup->RemoveMember(PSERVICESINK(this));
391 }
392
393 if (m_MidiStream)
394 {
395 if (m_State != KSSTATE_STOP)
396 {
397 m_MidiStream->SetState(KSSTATE_STOP);
399 }
400 DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql());
401 m_MidiStream->Release();
402 }
403
404 Status = m_Port->QueryInterface(IID_ISubdevice, (PVOID*)&SubDevice);
405 if (NT_SUCCESS(Status))
406 {
407 Status = SubDevice->GetDescriptor(&Descriptor);
408 if (NT_SUCCESS(Status))
409 {
410 // release reference count
411 Descriptor->Factory.Instances[m_ConnectDetails->PinId].CurrentPinInstanceCount--;
412 }
413 SubDevice->Release();
414 }
415
416 if (m_Format)
417 {
419 m_Format = NULL;
420 }
421
422 // complete the irp
423 Irp->IoStatus.Information = 0;
424 Irp->IoStatus.Status = STATUS_SUCCESS;
426
427 // destroy DMus pin
428 m_Filter->FreePin(PPORTPINDMUS(this));
429
430 return STATUS_SUCCESS;
431}
432
434NTAPI
435CPortPinDMus::QuerySecurity(
437 IN PIRP Irp)
438{
440}
441
443NTAPI
444CPortPinDMus::SetSecurity(
446 IN PIRP Irp)
447{
449}
450
452NTAPI
453CPortPinDMus::FastDeviceIoControl(
461 OUT PIO_STATUS_BLOCK StatusBlock,
463{
464 return FALSE;
465}
466
468NTAPI
469CPortPinDMus::FastRead(
476 OUT PIO_STATUS_BLOCK StatusBlock,
478{
479 return FALSE;
480}
481
483NTAPI
484CPortPinDMus::FastWrite(
491 OUT PIO_STATUS_BLOCK StatusBlock,
493{
494 return FALSE;
495}
496
498NTAPI
499CPortPinDMus::Init(
502 IN KSPIN_CONNECT * ConnectDetails,
503 IN KSPIN_DESCRIPTOR * KsPinDescriptor,
505{
509
510 Port->AddRef();
511 Filter->AddRef();
512
513 m_Port = Port;
515 m_KsPinDescriptor = KsPinDescriptor;
516 m_ConnectDetails = ConnectDetails;
518
520
521 DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1);
522
523 DPRINT("CPortPinDMus::Init entered\n");
524
526 if (!m_Format)
528
530
531 if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN)
532 {
534 }
535 else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT)
536 {
538 }
539 else
540 {
541 DPRINT("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor->Communication, KsPinDescriptor->DataFlow);
543 while(TRUE);
544 }
545
547 if (!NT_SUCCESS(Status))
548 {
549 DPRINT("Failed to allocate IrpQueue with %x\n", Status);
550 return Status;
551 }
552
553 if (m_MidiMiniport)
554 {
555 Status = m_MidiMiniport->NewStream(&m_MidiStream, NULL, NonPagedPool, ConnectDetails->PinId, Type, m_Format, &m_ServiceGroup);
556
557 DPRINT("CPortPinDMus::Init Status %x\n", Status);
558
559 if (!NT_SUCCESS(Status))
560 return Status;
561 }
562 else
563 {
564 Status = m_Miniport->NewStream(&m_Mxf, NULL, NonPagedPool, ConnectDetails->PinId, Type, m_Format, &m_ServiceGroup, PAllocatorMXF(this), PMASTERCLOCK(this),&m_SchedulePreFetch);
565
566 DPRINT("CPortPinDMus::Init Status %x\n", Status);
567
568 if (!NT_SUCCESS(Status))
569 return Status;
570
572 {
573 Status = m_Mxf->ConnectOutput(PMXF(this));
574 if (!NT_SUCCESS(Status))
575 {
576 DPRINT("IMXF_ConnectOutput failed with Status %x\n", Status);
577 return Status;
578 }
579 }
580
583 }
584
585 if (m_ServiceGroup)
586 {
587 Status = m_ServiceGroup->AddMember(PSERVICESINK(this));
588 if (!NT_SUCCESS(Status))
589 {
590 DPRINT("Failed to add pin to service group\n");
591 return Status;
592 }
593 }
594
595 Status = m_IrpQueue->Init(ConnectDetails, KsPinDescriptor, 0, 0, FALSE);
596 if (!NT_SUCCESS(Status))
597 {
598 DPRINT("IrpQueue_Init failed with %x\n", Status);
599 return Status;
600 }
601
603 m_Capture = Type;
604
605 return STATUS_SUCCESS;
606}
607
608VOID
609NTAPI
610CPortPinDMus::Notify()
611{
612 m_ServiceGroup->RequestService();
613}
614
617 OUT IPortPinDMus ** OutPin)
618{
620
622 if (!This)
624
625 This->AddRef();
626
627 // store result
628 *OutPin = (IPortPinDMus*)This;
629
630 return STATUS_SUCCESS;
631}
632
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:37
virtual ~CPortPinDMus()
Definition: pin_dmus.cpp:28
NPAGED_LOOKASIDE_LIST m_LookAsideEvent
Definition: pin_dmus.cpp:43
IPortDMus * m_Port
Definition: pin_dmus.cpp:34
PKSDATAFORMAT m_Format
Definition: pin_dmus.cpp:51
PSERVICEGROUP m_ServiceGroup
Definition: pin_dmus.cpp:39
IIrpQueue * m_IrpQueue
Definition: pin_dmus.cpp:56
VOID TransferMidiData()
Definition: pin_dmus.cpp:183
ULONG m_LastTag
Definition: pin_dmus.cpp:62
STDMETHODIMP QueryInterface(REFIID InterfaceId, PVOID *Interface)
Definition: pin_dmus.cpp:300
PMINIPORTMIDISTREAM m_MidiStream
Definition: pin_dmus.cpp:47
DMUS_STREAM_TYPE m_Capture
Definition: pin_dmus.cpp:54
PDEVICE_OBJECT m_DeviceObject
Definition: pin_dmus.cpp:55
ULONG m_PreCompleted
Definition: pin_dmus.cpp:59
ULONG m_TotalPackets
Definition: pin_dmus.cpp:58
VOID TransferMidiDataToDMus()
Definition: pin_dmus.cpp:230
IPortFilterDMus * m_Filter
Definition: pin_dmus.cpp:35
CPortPinDMus(IUnknown *OuterUnknown)
Definition: pin_dmus.cpp:27
KSSTATE m_State
Definition: pin_dmus.cpp:50
NPAGED_LOOKASIDE_LIST m_LookAsideBuffer
Definition: pin_dmus.cpp:44
KSPIN_DESCRIPTOR * m_KsPinDescriptor
Definition: pin_dmus.cpp:36
PMINIPORTMIDI m_MidiMiniport
Definition: pin_dmus.cpp:46
KSPIN_CONNECT * m_ConnectDetails
Definition: pin_dmus.cpp:52
ULONG m_PostCompleted
Definition: pin_dmus.cpp:60
ULONGLONG m_SchedulePreFetch
Definition: pin_dmus.cpp:42
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:1168
#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:869
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:30
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
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:616
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:514
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:67
ULONG PinId
Definition: ks.h:2603
root entry for file system trees
Definition: entries.h:148
CPortPinDMus * Pin
Definition: pin_dmus.cpp:73
PIO_WORKITEM WorkItem
Definition: pin_dmus.cpp:74
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:5780
_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