45edf1cd6607bedf1d51b27747a719156ba08be2
[reactos.git] / reactos / drivers / wdm / audio / backpln / portcls / port_topology.c
1 #include "private.h"
2
3 typedef struct
4 {
5 IPortTopologyVtbl *lpVtbl;
6
7 LONG ref;
8 BOOL bInitialized;
9
10 PMINIPORTTOPOLOGY Miniport;
11 PDEVICE_OBJECT pDeviceObject;
12 PRESOURCELIST pResourceList;
13
14 }IPortTopologyImpl;
15
16 const GUID IID_IMiniportTopology;
17 const GUID IID_IPortTopology;
18 #if 0
19 static
20 KSPROPERTY_SET PinPropertySet =
21 {
22 &KSPROPSETID_Pin,
23 0,
24 NULL,
25 0,
26 NULL
27 };
28
29 static
30 KSPROPERTY_SET TopologyPropertySet =
31 {
32 &KSPROPSETID_Topology,
33 4,
34 NULL,
35 0,
36 NULL
37 };
38 #endif
39
40
41 //---------------------------------------------------------------
42 // IUnknown interface functions
43 //
44
45 NTSTATUS
46 NTAPI
47 IPortTopology_fnQueryInterface(
48 IPortTopology* iface,
49 IN REFIID refiid,
50 OUT PVOID* Output)
51 {
52 IPortTopologyImpl * This = (IPortTopologyImpl*)iface;
53
54 if (IsEqualGUIDAligned(refiid, &IID_IPortTopology) ||
55 IsEqualGUIDAligned(refiid, &IID_IUnknown))
56 {
57 *Output = &This->lpVtbl;
58 _InterlockedIncrement(&This->ref);
59 return STATUS_SUCCESS;
60 }
61 else if (IsEqualGUIDAligned(refiid, &IID_IPortClsVersion))
62 {
63 return NewPortClsVersion((PPORTCLSVERSION*)Output);
64 }
65
66 return STATUS_UNSUCCESSFUL;
67 }
68
69 ULONG
70 NTAPI
71 IPortTopology_fnAddRef(
72 IPortTopology* iface)
73 {
74 IPortTopologyImpl * This = (IPortTopologyImpl*)iface;
75
76 return InterlockedIncrement(&This->ref);
77 }
78
79 ULONG
80 NTAPI
81 IPortTopology_fnRelease(
82 IPortTopology* iface)
83 {
84 IPortTopologyImpl * This = (IPortTopologyImpl*)iface;
85
86 InterlockedDecrement(&This->ref);
87
88 if (This->ref == 0)
89 {
90 ExFreePoolWithTag(This, TAG_PORTCLASS);
91 return 0;
92 }
93 /* Return new reference count */
94 return This->ref;
95 }
96
97
98 //---------------------------------------------------------------
99 // IPort interface functions
100 //
101
102 NTSTATUS
103 NTAPI
104 IPortTopology_fnGetDeviceProperty(
105 IN IPortTopology * iface,
106 IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty,
107 IN ULONG BufferLength,
108 OUT PVOID PropertyBuffer,
109 OUT PULONG ReturnLength)
110 {
111 IPortTopologyImpl * This = (IPortTopologyImpl*)iface;
112
113 if (!This->bInitialized)
114 {
115 DPRINT("IPortWaveCyclic_fnNewRegistryKey called w/o initiazed\n");
116 return STATUS_UNSUCCESSFUL;
117 }
118
119 return IoGetDeviceProperty(This->pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength);
120 }
121
122 NTSTATUS
123 NTAPI
124 IPortTopology_fnInit(
125 IN IPortTopology * iface,
126 IN PDEVICE_OBJECT DeviceObject,
127 IN PIRP Irp,
128 IN PUNKNOWN UnknownMiniport,
129 IN PUNKNOWN UnknownAdapter OPTIONAL,
130 IN PRESOURCELIST ResourceList)
131 {
132 IMiniportTopology * Miniport;
133 NTSTATUS Status;
134 IPortTopologyImpl * This = (IPortTopologyImpl*)iface;
135
136 if (This->bInitialized)
137 {
138 DPRINT("IPortWaveCyclic_Init called again\n");
139 return STATUS_SUCCESS;
140 }
141
142 Status = UnknownMiniport->lpVtbl->QueryInterface(UnknownMiniport, &IID_IMiniportTopology, (PVOID*)&Miniport);
143 if (!NT_SUCCESS(Status))
144 {
145 DPRINT("IPortWaveCyclic_Init called with invalid IMiniport adapter\n");
146 return STATUS_INVALID_PARAMETER;
147 }
148
149 Status = Miniport->lpVtbl->Init(Miniport, UnknownAdapter, ResourceList, iface);
150 if (!NT_SUCCESS(Status))
151 {
152 DPRINT("IMiniportWaveCyclic_Init failed with %x\n", Status);
153 return Status;
154 }
155
156 /* Initialize port object */
157 This->Miniport = Miniport;
158 This->pDeviceObject = DeviceObject;
159 This->bInitialized = TRUE;
160 This->pResourceList = ResourceList;
161
162 /* increment reference on miniport adapter */
163 Miniport->lpVtbl->AddRef(Miniport);
164 /* increment reference on resource list */
165 ResourceList->lpVtbl->AddRef(ResourceList);
166
167 return STATUS_SUCCESS;
168 }
169
170
171 NTSTATUS
172 NTAPI
173 IPortTopology_fnNewRegistryKey(
174 IN IPortTopology * iface,
175 OUT PREGISTRYKEY *OutRegistryKey,
176 IN PUNKNOWN OuterUnknown OPTIONAL,
177 IN ULONG RegistryKeyType,
178 IN ACCESS_MASK DesiredAccess,
179 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
180 IN ULONG CreateOptions OPTIONAL,
181 OUT PULONG Disposition OPTIONAL)
182 {
183 IPortTopologyImpl * This = (IPortTopologyImpl*)iface;
184
185 if (!This->bInitialized)
186 {
187 DPRINT("IPortWaveCyclic_fnNewRegistryKey called w/o initialized\n");
188 return STATUS_UNSUCCESSFUL;
189 }
190 return PcNewRegistryKey(OutRegistryKey,
191 OuterUnknown,
192 RegistryKeyType,
193 DesiredAccess,
194 This->pDeviceObject,
195 NULL,//FIXME
196 ObjectAttributes,
197 CreateOptions,
198 Disposition);
199 }
200
201 static IPortTopologyVtbl vt_IPortTopology =
202 {
203 /* IUnknown methods */
204 IPortTopology_fnQueryInterface,
205 IPortTopology_fnAddRef,
206 IPortTopology_fnRelease,
207 /* IPort methods */
208 IPortTopology_fnInit,
209 IPortTopology_fnGetDeviceProperty,
210 IPortTopology_fnNewRegistryKey
211 };
212
213 NTSTATUS
214 NewPortTopology(
215 OUT PPORT* OutPort)
216 {
217 IPortTopologyImpl * This;
218
219 This = ExAllocatePoolWithTag(NonPagedPool, sizeof(IPortTopologyImpl), TAG_PORTCLASS);
220 if (!This)
221 return STATUS_INSUFFICIENT_RESOURCES;
222
223 RtlZeroMemory(This, sizeof(IPortTopologyImpl));
224 This->lpVtbl = &vt_IPortTopology;
225 This->ref = 1;
226 *OutPort = (PPORT)(&This->lpVtbl);
227
228 return STATUS_SUCCESS;
229 }