1 /*
2     PortCls FDO Extension
3 
4     by Andrew Greenwood
5 */
6 
7 #ifndef PORTCLS_PRIVATE_H
8 #define PORTCLS_PRIVATE_H
9 
10 #include <stdio.h>
11 
12 //#define _KS_NO_ANONYMOUS_STRUCTURES_
13 #define PC_IMPLEMENTATION
14 #define COM_STDMETHOD_CAN_THROW
15 #define PC_NO_IMPORTS
16 
17 #include <ntddk.h>
18 #include <portcls.h>
19 #include <dmusicks.h>
20 #include <kcom.h>
21 
22 #include "interfaces.hpp"
23 
24 #define TAG_PORTCLASS 'SLCP'
25 
26 #define PC_ASSERT(exp) \
27   (VOID)((!(exp)) ? \
28     RtlAssert((PVOID) #exp, (PVOID)__FILE__, __LINE__, NULL ), FALSE : TRUE)
29 
30 #define PC_ASSERT_IRQL(x) PC_ASSERT(KeGetCurrentIrql() <= (x))
31 #define PC_ASSERT_IRQL_EQUAL(x) PC_ASSERT(KeGetCurrentIrql()==(x))
32 
33 PVOID
34 __cdecl
35 operator new(
36     size_t Size,
37     POOL_TYPE PoolType,
38     ULONG Tag);
39 
40 extern
41 "C"
42 NTSTATUS
43 NTAPI
44 PortClsCreate(
45     IN  PDEVICE_OBJECT DeviceObject,
46     IN  PIRP Irp);
47 
48 extern
49 "C"
50 NTSTATUS
51 NTAPI
52 PortClsPnp(
53     IN  PDEVICE_OBJECT DeviceObject,
54     IN  PIRP Irp);
55 
56 extern
57 "C"
58 NTSTATUS
59 NTAPI
60 PortClsPower(
61     IN  PDEVICE_OBJECT DeviceObject,
62     IN  PIRP Irp);
63 
64 extern
65 "C"
66 NTSTATUS
67 NTAPI
68 PortClsSysControl(
69     IN  PDEVICE_OBJECT DeviceObject,
70     IN  PIRP Irp);
71 
72 NTSTATUS
73 NewMiniportDMusUART(
74     OUT PMINIPORT* OutMiniport,
75     IN  REFCLSID ClassId);
76 
77 NTSTATUS
78 NewMiniportFmSynth(
79     OUT PMINIPORT* OutMiniport,
80     IN  REFCLSID ClassId);
81 
82 NTSTATUS
83 NewPortDMus(
84     OUT PPORT* OutPort);
85 
86 NTSTATUS
87 NewPortTopology(
88     OUT PPORT* OutPort);
89 
90 NTSTATUS
91 NewPortWaveCyclic(
92     OUT PPORT* OutPort);
93 
94 NTSTATUS
95 NewPortWavePci(
96     OUT PPORT* OutPort);
97 
98 NTSTATUS
99 NewIDrmPort(
100     OUT PDRMPORT2 *OutPort);
101 
102 NTSTATUS
103 NewPortClsVersion(
104     OUT PPORTCLSVERSION * OutVersion);
105 
106 NTSTATUS
107 NewPortFilterWaveCyclic(
108     OUT IPortFilterWaveCyclic ** OutFilter);
109 
110 NTSTATUS
111 NewPortPinWaveCyclic(
112     OUT IPortPinWaveCyclic ** OutPin);
113 
114 NTSTATUS
115 NewPortFilterWavePci(
116     OUT IPortFilterWavePci ** OutFilter);
117 
118 NTSTATUS
119 NewPortPinWavePci(
120     OUT IPortPinWavePci ** OutPin);
121 
122 PDEVICE_OBJECT
123 GetDeviceObjectFromWaveCyclic(
124     IPortWavePci* iface);
125 
126 PDEVICE_OBJECT
127 GetDeviceObjectFromPortWavePci(
128     IPortWavePci* iface);
129 
130 PMINIPORTWAVEPCI
131 GetWavePciMiniport(
132     PPORTWAVEPCI Port);
133 
134 
135 NTSTATUS
136 NewPortFilterDMus(
137     OUT PPORTFILTERDMUS * OutFilter);
138 
139 
140 NTSTATUS
141 NewPortPinDMus(
142     OUT PPORTPINDMUS * OutPin);
143 
144 VOID
145 GetDMusMiniport(
146     IN IPortDMus * iface,
147     IN PMINIPORTDMUS * Miniport,
148     IN PMINIPORTMIDI * MidiMiniport);
149 
150 #if (NTDDI_VERSION >= NTDDI_VISTA)
151 
152 NTSTATUS
153 NewPortFilterWaveRT(
154     OUT IPortFilterWaveRT ** OutFilter);
155 
156 NTSTATUS
157 NewPortPinWaveRT(
158     OUT IPortPinWaveRT ** OutPin);
159 
160 PMINIPORTWAVERT
161 GetWaveRTMiniport(
162     IN IPortWaveRT* iface);
163 
164 PDEVICE_OBJECT
165 GetDeviceObjectFromPortWaveRT(
166     IPortWaveRT* iface);
167 
168 
169 NTSTATUS
170 NewPortWaveRTStream(
171     PPORTWAVERTSTREAM *OutStream);
172 
173 NTSTATUS
174 NewPortWaveRT(
175     OUT PPORT* OutPort);
176 
177 
178 #endif
179 
180 NTSTATUS
181 NewPortFilterTopology(
182     OUT IPortFilterTopology ** OutFilter);
183 
184 PMINIPORTTOPOLOGY
185 GetTopologyMiniport(
186     PPORTTOPOLOGY Port);
187 
188 NTSTATUS
189 NTAPI
190 NewDispatchObject(
191     IN PIRP Irp,
192     IN IIrpTarget * Target,
193     IN ULONG ObjectCreateItemCount,
194     IN PKSOBJECT_CREATE_ITEM ObjectCreateItem);
195 
196 PMINIPORTWAVECYCLIC
197 GetWaveCyclicMiniport(
198     IN IPortWaveCyclic* iface);
199 
200 PVOID
201 AllocateItem(
202     IN POOL_TYPE PoolType,
203     IN SIZE_T NumberOfBytes,
204     IN ULONG Tag);
205 
206 VOID
207 FreeItem(
208     IN PVOID Item,
209     IN ULONG Tag);
210 
211 NTSTATUS
212 NTAPI
213 NewIrpQueue(
214     IN IIrpQueue **Queue);
215 
216 NTSTATUS
217 NTAPI
218 TopologyPropertyHandler(
219     IN PIRP Irp,
220     IN PKSIDENTIFIER  Request,
221     IN OUT PVOID  Data);
222 
223 NTSTATUS
224 NTAPI
225 PinPropertyHandler(
226     IN PIRP Irp,
227     IN PKSIDENTIFIER  Request,
228     IN OUT PVOID  Data);
229 
230 extern
231 "C"
232 NTSTATUS
233 NTAPI
234 PcDmaMasterDescription(
235     IN PRESOURCELIST ResourceList OPTIONAL,
236     IN BOOLEAN ScatterGather,
237     IN BOOLEAN Dma32BitAddresses,
238     IN BOOLEAN IgnoreCount,
239     IN BOOLEAN Dma64BitAddresses,
240     IN DMA_WIDTH DmaWidth,
241     IN DMA_SPEED DmaSpeed,
242     IN ULONG MaximumLength,
243     IN ULONG DmaPort,
244     OUT PDEVICE_DESCRIPTION DeviceDescription);
245 
246 extern
247 "C"
248 NTSTATUS
249 NTAPI
250 PcDmaSlaveDescription(
251     IN PRESOURCELIST  ResourceList OPTIONAL,
252     IN ULONG DmaIndex,
253     IN BOOLEAN DemandMode,
254     IN BOOLEAN AutoInitialize,
255     IN DMA_SPEED DmaSpeed,
256     IN ULONG MaximumLength,
257     IN ULONG DmaPort,
258     OUT PDEVICE_DESCRIPTION DeviceDescription);
259 
260 extern
261 "C"
262 NTSTATUS
263 NTAPI
264 PcCreateSubdeviceDescriptor(
265     OUT SUBDEVICE_DESCRIPTOR ** OutSubdeviceDescriptor,
266     IN ULONG InterfaceCount,
267     IN GUID * InterfaceGuids,
268     IN ULONG IdentifierCount,
269     IN KSIDENTIFIER *Identifier,
270     IN ULONG FilterPropertiesCount,
271     IN KSPROPERTY_SET * FilterProperties,
272     IN ULONG Unknown1,
273     IN ULONG Unknown2,
274     IN ULONG PinPropertiesCount,
275     IN KSPROPERTY_SET * PinProperties,
276     IN ULONG EventSetCount,
277     IN KSEVENT_SET * EventSet,
278     IN PPCFILTER_DESCRIPTOR FilterDescription);
279 
280 extern
281 "C"
282 NTSTATUS
283 NTAPI
284 PcValidateConnectRequest(
285     IN PIRP Irp,
286     IN KSPIN_FACTORY * Descriptor,
287     OUT PKSPIN_CONNECT* Connect);
288 
289 NTSTATUS
290 NTAPI
291 PcCreateItemDispatch(
292     IN  PDEVICE_OBJECT DeviceObject,
293     IN  PIRP Irp);
294 
295 PDEVICE_OBJECT
296 GetDeviceObject(
297     IPortWaveCyclic* iface);
298 
299 VOID
300 NTAPI
301 PcIoTimerRoutine(
302     IN PDEVICE_OBJECT  DeviceObject,
303     IN PVOID  Context);
304 
305 NTSTATUS
306 NTAPI
307 NewIUnregisterSubdevice(
308     OUT PUNREGISTERSUBDEVICE *OutDevice);
309 
310 NTSTATUS
311 NTAPI
312 NewIUnregisterPhysicalConnection(
313     OUT PUNREGISTERPHYSICALCONNECTION *OutConnection);
314 
315 NTSTATUS
316 NTAPI
317 PcHandlePropertyWithTable(
318     IN PIRP Irp,
319     IN ULONG PropertySetCount,
320     IN PKSPROPERTY_SET PropertySet,
321     IN PSUBDEVICE_DESCRIPTOR Descriptor);
322 
323 NTSTATUS
324 NTAPI
325 PcHandleEnableEventWithTable(
326     IN PIRP Irp,
327     IN PSUBDEVICE_DESCRIPTOR Descriptor);
328 
329 NTSTATUS
330 NTAPI
331 PcHandleDisableEventWithTable(
332     IN PIRP Irp,
333     IN PSUBDEVICE_DESCRIPTOR Descriptor);
334 
335 IIrpTarget *
336 NTAPI
337 KsoGetIrpTargetFromIrp(
338     PIRP Irp);
339 
340 #define DEFINE_KSPROPERTY_CONNECTIONSET(PinSet,\
341     PropStateHandler, PropDataFormatHandler, PropAllocatorFraming)\
342 DEFINE_KSPROPERTY_TABLE(PinSet) {\
343     DEFINE_KSPROPERTY_ITEM_CONNECTION_STATE(PropStateHandler, PropStateHandler),\
344     DEFINE_KSPROPERTY_ITEM_CONNECTION_DATAFORMAT(PropDataFormatHandler, PropDataFormatHandler),\
345     DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING(PropAllocatorFraming)\
346 }
347 
348 #define DEFINE_KSPROPERTY_ITEM_AUDIO_POSITION(GetHandler, SetHandler)\
349     DEFINE_KSPROPERTY_ITEM(\
350         KSPROPERTY_AUDIO_POSITION,\
351         (GetHandler),\
352         sizeof(KSPROPERTY),\
353         sizeof(KSAUDIO_POSITION),\
354         (SetHandler),\
355         NULL, 0, NULL, NULL, 0)
356 
357 #define DEFINE_KSPROPERTY_AUDIOSET(PinSet,\
358     PropPositionHandler)\
359 DEFINE_KSPROPERTY_TABLE(PinSet) {\
360     DEFINE_KSPROPERTY_ITEM_AUDIO_POSITION(PropPositionHandler, PropPositionHandler)\
361 }
362 
363 
364 #define DEFINE_KSPROPERTY_ITEM_DRMAUDIOSTREAM_CONTENTID(SetHandler)\
365     DEFINE_KSPROPERTY_ITEM(\
366         KSPROPERTY_DRMAUDIOSTREAM_CONTENTID,\
367         NULL,\
368         sizeof(KSPROPERTY),\
369         sizeof(ULONG),\
370         (SetHandler),\
371         NULL, 0, NULL, NULL, 0)
372 
373 #define DEFINE_KSPROPERTY_DRMSET(PinSet,\
374     PropPositionHandler)\
375 DEFINE_KSPROPERTY_TABLE(PinSet) {\
376     DEFINE_KSPROPERTY_ITEM_DRMAUDIOSTREAM_CONTENTID(PropPositionHandler)\
377 }
378 
379 #define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet,\
380     PropGeneral, PropInstances, PropIntersection)\
381 DEFINE_KSPROPERTY_TABLE(PinSet) {\
382     DEFINE_KSPROPERTY_ITEM_PIN_CINSTANCES(PropInstances),\
383     DEFINE_KSPROPERTY_ITEM_PIN_CTYPES(PropGeneral),\
384     DEFINE_KSPROPERTY_ITEM_PIN_DATAFLOW(PropGeneral),\
385     DEFINE_KSPROPERTY_ITEM_PIN_DATARANGES(PropGeneral),\
386     DEFINE_KSPROPERTY_ITEM_PIN_DATAINTERSECTION(PropIntersection),\
387     DEFINE_KSPROPERTY_ITEM_PIN_INTERFACES(PropGeneral),\
388     DEFINE_KSPROPERTY_ITEM_PIN_MEDIUMS(PropGeneral),\
389     DEFINE_KSPROPERTY_ITEM_PIN_COMMUNICATION(PropGeneral),\
390     DEFINE_KSPROPERTY_ITEM_PIN_GLOBALCINSTANCES(PropGeneral),\
391     DEFINE_KSPROPERTY_ITEM_PIN_NECESSARYINSTANCES(PropGeneral),\
392     DEFINE_KSPROPERTY_ITEM_PIN_PHYSICALCONNECTION(PropGeneral),\
393     DEFINE_KSPROPERTY_ITEM_PIN_CATEGORY(PropGeneral),\
394     DEFINE_KSPROPERTY_ITEM_PIN_NAME(PropGeneral),\
395     DEFINE_KSPROPERTY_ITEM_PIN_CONSTRAINEDDATARANGES(PropGeneral),\
396     DEFINE_KSPROPERTY_ITEM_PIN_PROPOSEDATAFORMAT(PropGeneral)\
397 }
398 
399 typedef struct
400 {
401     KSDEVICE_HEADER KsDeviceHeader;
402     PDEVICE_OBJECT PhysicalDeviceObject;
403     PDEVICE_OBJECT PrevDeviceObject;
404     PCPFNSTARTDEVICE StartDevice;
405     ULONG_PTR Unused[4];
406     IAdapterPowerManagement * AdapterPowerManagement;
407     ULONG MaxSubDevices;
408     KSOBJECT_CREATE_ITEM * CreateItems;
409 
410     IResourceList* resources;
411 
412     LIST_ENTRY TimerList;
413     KSPIN_LOCK TimerListLock;
414 
415     DEVICE_POWER_STATE DevicePowerState;
416     SYSTEM_POWER_STATE  SystemPowerState;
417 
418 } PCLASS_DEVICE_EXTENSION, *PPCLASS_DEVICE_EXTENSION;
419 
420 
421 typedef struct
422 {
423     PVOID Pin;
424     PIO_WORKITEM WorkItem;
425     PIRP Irp;
426 }CLOSESTREAM_CONTEXT, *PCLOSESTREAM_CONTEXT;
427 
428 typedef struct
429 {
430     LIST_ENTRY Entry;
431     PIO_TIMER_ROUTINE pTimerRoutine;
432     PVOID Context;
433 }TIMER_CONTEXT, *PTIMER_CONTEXT;
434 
435 typedef struct
436 {
437     KSOBJECT_HEADER ObjectHeader;
438     IIrpTarget * Target;
439     PKSOBJECT_CREATE_ITEM CreateItem;
440 }DISPATCH_CONTEXT, *PDISPATCH_CONTEXT;
441 
442 template<typename... Interfaces>
443 class CUnknownImpl : public Interfaces...
444 {
445 private:
446     volatile LONG m_Ref;
447 protected:
448     CUnknownImpl() :
449         m_Ref(0)
450     {
451     }
452     virtual ~CUnknownImpl()
453     {
454     }
455 public:
456     STDMETHODIMP_(ULONG) AddRef()
457     {
458         ULONG Ref = InterlockedIncrement(&m_Ref);
459         ASSERT(Ref < 0x10000);
460         return Ref;
461     }
462     STDMETHODIMP_(ULONG) Release()
463     {
464         ULONG Ref = InterlockedDecrement(&m_Ref);
465         ASSERT(Ref < 0x10000);
466         if (!Ref)
467         {
468             delete this;
469             return 0;
470         }
471         return Ref;
472     }
473 };
474 
475 #endif /* PORTCLS_PRIVATE_H */
476