1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS Kernel Streaming
4  * FILE:            drivers/wdm/audio/backpln/portcls/filter_topology.c
5  * PURPOSE:         portcls topology filter
6  * PROGRAMMER:      Johannes Anderwald
7  */
8 
9 #include "private.hpp"
10 
11 #define NDEBUG
12 #include <debug.h>
13 
14 class CPortFilterTopology : public CUnknownImpl<IPortFilterTopology>
15 {
16 public:
17     STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
18 
19     IMP_IPortFilterTopology;
CPortFilterTopology(IUnknown * OuterUnknown)20     CPortFilterTopology(IUnknown *OuterUnknown){}
~CPortFilterTopology()21     virtual ~CPortFilterTopology(){}
22 
23 protected:
24     IPortTopology * m_Port;
25     SUBDEVICE_DESCRIPTOR * m_Descriptor;
26     ISubdevice * m_SubDevice;
27 };
28 
29 NTSTATUS
30 NTAPI
QueryInterface(IN REFIID refiid,OUT PVOID * Output)31 CPortFilterTopology::QueryInterface(
32     IN  REFIID refiid,
33     OUT PVOID* Output)
34 {
35 
36     if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) ||
37         IsEqualGUIDAligned(refiid, IID_IUnknown))
38     {
39         *Output = PVOID(PUNKNOWN(this));
40         PUNKNOWN(*Output)->AddRef();
41         return STATUS_SUCCESS;
42     }
43     else if (IsEqualGUIDAligned(refiid, IID_IPort))
44     {
45         *Output = PVOID(PUNKNOWN(m_Port));
46         PUNKNOWN(*Output)->AddRef();
47         return STATUS_SUCCESS;
48     }
49 
50     return STATUS_UNSUCCESSFUL;
51 }
52 
53 NTSTATUS
54 NTAPI
NewIrpTarget(OUT struct IIrpTarget ** OutTarget,IN PCWSTR Name,IN PUNKNOWN Unknown,IN POOL_TYPE PoolType,IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN KSOBJECT_CREATE * CreateObject)55 CPortFilterTopology::NewIrpTarget(
56     OUT struct IIrpTarget **OutTarget,
57     IN PCWSTR Name,
58     IN PUNKNOWN Unknown,
59     IN POOL_TYPE PoolType,
60     IN PDEVICE_OBJECT DeviceObject,
61     IN PIRP Irp,
62     IN KSOBJECT_CREATE *CreateObject)
63 {
64     DPRINT("CPortFilterTopology::NewIrpTarget entered\n");
65 
66     return STATUS_NOT_SUPPORTED;
67 }
68 
69 NTSTATUS
70 NTAPI
DeviceIoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)71 CPortFilterTopology::DeviceIoControl(
72     IN PDEVICE_OBJECT DeviceObject,
73     IN PIRP Irp)
74 {
75     PIO_STACK_LOCATION IoStack;
76     NTSTATUS Status;
77 
78     IoStack = IoGetCurrentIrpStackLocation(Irp);
79 
80     if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY)
81     {
82         DPRINT("Unhandled function %lx Length %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength);
83 
84         Irp->IoStatus.Status = STATUS_SUCCESS;
85 
86         IoCompleteRequest(Irp, IO_NO_INCREMENT);
87         return STATUS_SUCCESS;
88     }
89 
90     Status = PcHandlePropertyWithTable(Irp, m_Descriptor->FilterPropertySetCount, m_Descriptor->FilterPropertySet, m_Descriptor);
91     if (Status != STATUS_PENDING)
92     {
93         Irp->IoStatus.Status = Status;
94         DPRINT("Result %x Length %u\n", Status, Irp->IoStatus.Information);
95         IoCompleteRequest(Irp, IO_NO_INCREMENT);
96     }
97     return Status;
98 
99 }
100 
101 NTSTATUS
102 NTAPI
Read(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)103 CPortFilterTopology::Read(
104     IN PDEVICE_OBJECT DeviceObject,
105     IN PIRP Irp)
106 {
107     return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
108 }
109 
110 NTSTATUS
111 NTAPI
Write(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)112 CPortFilterTopology::Write(
113     IN PDEVICE_OBJECT DeviceObject,
114     IN PIRP Irp)
115 {
116     return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
117 }
118 
119 NTSTATUS
120 NTAPI
Flush(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)121 CPortFilterTopology::Flush(
122     IN PDEVICE_OBJECT DeviceObject,
123     IN PIRP Irp)
124 {
125     return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
126 }
127 
128 NTSTATUS
129 NTAPI
Close(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)130 CPortFilterTopology::Close(
131     IN PDEVICE_OBJECT DeviceObject,
132     IN PIRP Irp)
133 {
134     NTSTATUS Status = STATUS_SUCCESS;
135 
136     // FIXME handle DirectSound
137 
138 #if 0
139 //FIXME
140     if (m_ref == 1)
141     {
142         // release reference to port
143         This->SubDevice->lpVtbl->Release(This->SubDevice);
144 
145         // time to shutdown the audio system
146         Status = This->SubDevice->lpVtbl->ReleaseChildren(This->SubDevice);
147     }
148 #endif
149 
150     Irp->IoStatus.Status = Status;
151     Irp->IoStatus.Information = 0;
152     IoCompleteRequest(Irp, IO_NO_INCREMENT);
153 
154     return STATUS_SUCCESS;
155 }
156 
157 NTSTATUS
158 NTAPI
QuerySecurity(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)159 CPortFilterTopology::QuerySecurity(
160     IN PDEVICE_OBJECT DeviceObject,
161     IN PIRP Irp)
162 {
163     return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
164 }
165 
166 NTSTATUS
167 NTAPI
SetSecurity(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)168 CPortFilterTopology::SetSecurity(
169     IN PDEVICE_OBJECT DeviceObject,
170     IN PIRP Irp)
171 {
172     return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
173 }
174 
175 BOOLEAN
176 NTAPI
FastDeviceIoControl(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)177 CPortFilterTopology::FastDeviceIoControl(
178     IN PFILE_OBJECT FileObject,
179     IN BOOLEAN Wait,
180     IN PVOID InputBuffer,
181     IN ULONG InputBufferLength,
182     OUT PVOID OutputBuffer,
183     IN ULONG OutputBufferLength,
184     IN ULONG IoControlCode,
185     OUT PIO_STATUS_BLOCK StatusBlock,
186     IN PDEVICE_OBJECT DeviceObject)
187 {
188     return FALSE;
189 }
190 
191 BOOLEAN
192 NTAPI
FastRead(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)193 CPortFilterTopology::FastRead(
194     IN PFILE_OBJECT FileObject,
195     IN PLARGE_INTEGER FileOffset,
196     IN ULONG Length,
197     IN BOOLEAN Wait,
198     IN ULONG LockKey,
199     IN PVOID Buffer,
200     OUT PIO_STATUS_BLOCK StatusBlock,
201     IN PDEVICE_OBJECT DeviceObject)
202 {
203     return FALSE;
204 }
205 
206 BOOLEAN
207 NTAPI
FastWrite(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)208 CPortFilterTopology::FastWrite(
209     IN PFILE_OBJECT FileObject,
210     IN PLARGE_INTEGER FileOffset,
211     IN ULONG Length,
212     IN BOOLEAN Wait,
213     IN ULONG LockKey,
214     IN PVOID Buffer,
215     OUT PIO_STATUS_BLOCK StatusBlock,
216     IN PDEVICE_OBJECT DeviceObject)
217 {
218     return FALSE;
219 }
220 
221 NTSTATUS
222 NTAPI
Init(IN IPortTopology * Port)223 CPortFilterTopology::Init(
224     IN IPortTopology* Port)
225 {
226     ISubdevice * ISubDevice;
227     SUBDEVICE_DESCRIPTOR * Descriptor;
228     NTSTATUS Status;
229 
230     // get our private interface
231     Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&ISubDevice);
232     if (!NT_SUCCESS(Status))
233         return STATUS_UNSUCCESSFUL;
234 
235     // get the subdevice descriptor
236     Status = ISubDevice->GetDescriptor(&Descriptor);
237 
238     // store subdevice interface
239     m_SubDevice = ISubDevice;
240 
241     if (!NT_SUCCESS(Status))
242         return STATUS_UNSUCCESSFUL;
243 
244     // save descriptor
245     m_Descriptor = Descriptor;
246 
247     // store port object
248     m_Port = Port;
249 
250     return STATUS_SUCCESS;
251 }
252 
253 NTSTATUS
NewPortFilterTopology(OUT IPortFilterTopology ** OutFilter)254 NewPortFilterTopology(
255     OUT IPortFilterTopology ** OutFilter)
256 {
257     CPortFilterTopology * This;
258 
259     This = new(NonPagedPool, TAG_PORTCLASS)CPortFilterTopology(NULL);
260     if (!This)
261         return STATUS_INSUFFICIENT_RESOURCES;
262 
263     This->AddRef();
264 
265     // return result
266     *OutFilter = (CPortFilterTopology*)This;
267 
268     return STATUS_SUCCESS;
269 }
270