1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/connection.c
5 * PURPOSE: portcls physical connection registration
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9 #include "private.hpp"
10
11 #define NDEBUG
12 #include <debug.h>
13
14 extern
15 "C"
16 NTSYSAPI
17 BOOLEAN
18 NTAPI
19 RtlCreateUnicodeString(
20 PUNICODE_STRING DestinationString,
21 PCWSTR SourceString
22 );
23
24 class CUnregisterPhysicalConnection : public CUnknownImpl<IUnregisterPhysicalConnection>
25 {
26 public:
27 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
28
29 IMP_IUnregisterPhysicalConnection;
30
CUnregisterPhysicalConnection(IUnknown * OuterUnknown)31 CUnregisterPhysicalConnection(IUnknown *OuterUnknown){}
32
~CUnregisterPhysicalConnection()33 virtual ~CUnregisterPhysicalConnection(){}
34 };
35
36 NTSTATUS
37 NTAPI
QueryInterface(IN REFIID refiid,OUT PVOID * Output)38 CUnregisterPhysicalConnection::QueryInterface(
39 IN REFIID refiid,
40 OUT PVOID* Output)
41 {
42 UNICODE_STRING GuidString;
43
44 if (IsEqualGUIDAligned(refiid, IID_IUnregisterPhysicalConnection) ||
45 IsEqualGUIDAligned(refiid, IID_IUnknown))
46 {
47 *Output = PVOID(PUNKNOWN(this));
48
49 PUNKNOWN(*Output)->AddRef();
50 return STATUS_SUCCESS;
51 }
52
53 if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
54 {
55 DPRINT1("CUnregisterPhysicalConnection::QueryInterface no interface!!! iface %S\n", GuidString.Buffer);
56 RtlFreeUnicodeString(&GuidString);
57 }
58
59 return STATUS_UNSUCCESSFUL;
60 }
61
62 static
63 NTSTATUS
UnRegisterConnection(IN OUT PDEVICE_OBJECT DeviceObject,IN PUNKNOWN FromUnknown,IN PUNICODE_STRING FromString,IN ULONG FromPin,IN PUNKNOWN ToUnknown,IN PUNICODE_STRING ToString,IN ULONG ToPin)64 UnRegisterConnection(
65 IN OUT PDEVICE_OBJECT DeviceObject,
66 IN PUNKNOWN FromUnknown,
67 IN PUNICODE_STRING FromString,
68 IN ULONG FromPin,
69 IN PUNKNOWN ToUnknown,
70 IN PUNICODE_STRING ToString,
71 IN ULONG ToPin)
72 {
73 UNIMPLEMENTED;
74 return STATUS_NOT_IMPLEMENTED;
75 }
76
77 NTSTATUS
78 NTAPI
UnregisterPhysicalConnection(IN PDEVICE_OBJECT DeviceObject,IN PUNKNOWN FromUnknown,IN ULONG FromPin,IN PUNKNOWN ToUnknown,IN ULONG ToPin)79 CUnregisterPhysicalConnection::UnregisterPhysicalConnection(
80 IN PDEVICE_OBJECT DeviceObject,
81 IN PUNKNOWN FromUnknown,
82 IN ULONG FromPin,
83 IN PUNKNOWN ToUnknown,
84 IN ULONG ToPin)
85 {
86 if (!DeviceObject || !FromUnknown || !ToUnknown)
87 return STATUS_INVALID_PARAMETER;
88
89 return UnRegisterConnection(DeviceObject, FromUnknown, NULL, FromPin, ToUnknown, NULL, ToPin);
90 }
91
92 NTSTATUS
93 NTAPI
UnregisterPhysicalConnectionToExternal(IN PDEVICE_OBJECT DeviceObject,IN PUNKNOWN FromUnknown,IN ULONG FromPin,IN PUNICODE_STRING ToString,IN ULONG ToPin)94 CUnregisterPhysicalConnection::UnregisterPhysicalConnectionToExternal(
95 IN PDEVICE_OBJECT DeviceObject,
96 IN PUNKNOWN FromUnknown,
97 IN ULONG FromPin,
98 IN PUNICODE_STRING ToString,
99 IN ULONG ToPin)
100 {
101 if (!DeviceObject || !FromUnknown || !ToString)
102 return STATUS_INVALID_PARAMETER;
103
104 return UnRegisterConnection(DeviceObject, FromUnknown, NULL, FromPin, NULL, ToString, ToPin);
105 }
106
107 NTSTATUS
108 NTAPI
UnregisterPhysicalConnectionFromExternal(IN PDEVICE_OBJECT DeviceObject,IN PUNICODE_STRING FromString,IN ULONG FromPin,IN PUNKNOWN ToUnknown,IN ULONG ToPin)109 CUnregisterPhysicalConnection::UnregisterPhysicalConnectionFromExternal(
110 IN PDEVICE_OBJECT DeviceObject,
111 IN PUNICODE_STRING FromString,
112 IN ULONG FromPin,
113 IN PUNKNOWN ToUnknown,
114 IN ULONG ToPin)
115 {
116 if (!DeviceObject || !FromString || !ToUnknown)
117 return STATUS_INVALID_PARAMETER;
118
119 return UnRegisterConnection(DeviceObject, NULL, FromString, FromPin, ToUnknown, NULL, ToPin);
120 }
121
122 NTSTATUS
123 NTAPI
NewIUnregisterPhysicalConnection(OUT PUNREGISTERPHYSICALCONNECTION * OutConnection)124 NewIUnregisterPhysicalConnection(
125 OUT PUNREGISTERPHYSICALCONNECTION *OutConnection)
126 {
127
128 CUnregisterPhysicalConnection *new_ptr = new(NonPagedPool, TAG_PORTCLASS) CUnregisterPhysicalConnection(NULL);
129
130 if (!new_ptr)
131 return STATUS_INSUFFICIENT_RESOURCES;
132
133 new_ptr->AddRef();
134 *OutConnection = (PUNREGISTERPHYSICALCONNECTION)new_ptr;
135 return STATUS_SUCCESS;
136 }
137
138 NTSTATUS
RegisterConnection(IN OUT PDEVICE_OBJECT DeviceObject,IN PUNKNOWN FromUnknown,IN PUNICODE_STRING FromString,IN ULONG FromPin,IN PUNKNOWN ToUnknown,IN PUNICODE_STRING ToString,IN ULONG ToPin)139 RegisterConnection(
140 IN OUT PDEVICE_OBJECT DeviceObject,
141 IN PUNKNOWN FromUnknown,
142 IN PUNICODE_STRING FromString,
143 IN ULONG FromPin,
144 IN PUNKNOWN ToUnknown,
145 IN PUNICODE_STRING ToString,
146 IN ULONG ToPin)
147 {
148 PSUBDEVICE_DESCRIPTOR FromSubDeviceDescriptor = NULL, ToSubDeviceDescriptor = NULL;
149 PSYMBOLICLINK_ENTRY SymEntry;
150 ISubdevice * FromSubDevice = NULL, *ToSubDevice = NULL;
151 NTSTATUS Status;
152 PPHYSICAL_CONNECTION_ENTRY FromEntry = NULL, ToEntry = NULL;
153
154 if (FromUnknown)
155 {
156 Status = FromUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&FromSubDevice);
157 if (!NT_SUCCESS(Status))
158 goto cleanup;
159
160 Status = FromSubDevice->GetDescriptor(&FromSubDeviceDescriptor);
161 if (!NT_SUCCESS(Status))
162 goto cleanup;
163
164 if (IsListEmpty(&FromSubDeviceDescriptor->SymbolicLinkList))
165 {
166 Status = STATUS_UNSUCCESSFUL;
167 goto cleanup;
168 }
169
170 SymEntry = (PSYMBOLICLINK_ENTRY)CONTAINING_RECORD(FromSubDeviceDescriptor->SymbolicLinkList.Flink, SYMBOLICLINK_ENTRY, Entry);
171 FromString = &SymEntry->SymbolicLink;
172 }
173
174 if (ToUnknown)
175 {
176 Status = ToUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&ToSubDevice);
177 if (!NT_SUCCESS(Status))
178 goto cleanup;
179
180 Status = ToSubDevice->GetDescriptor(&ToSubDeviceDescriptor);
181 if (!NT_SUCCESS(Status))
182 goto cleanup;
183
184 if (IsListEmpty(&ToSubDeviceDescriptor->SymbolicLinkList))
185 {
186 Status = STATUS_UNSUCCESSFUL;
187 goto cleanup;
188 }
189
190 SymEntry = (PSYMBOLICLINK_ENTRY)CONTAINING_RECORD(ToSubDeviceDescriptor->SymbolicLinkList.Flink, SYMBOLICLINK_ENTRY, Entry);
191 ToString = &SymEntry->SymbolicLink;
192
193 }
194
195 if (FromSubDeviceDescriptor)
196 {
197 FromEntry = (PPHYSICAL_CONNECTION_ENTRY)AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION_ENTRY) + ToString->MaximumLength + sizeof(WCHAR), TAG_PORTCLASS);
198 if (!FromEntry)
199 {
200 Status = STATUS_INSUFFICIENT_RESOURCES;
201 goto cleanup;
202 }
203 }
204
205 if (ToSubDeviceDescriptor)
206 {
207 ToEntry = (PPHYSICAL_CONNECTION_ENTRY)AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION_ENTRY) + FromString->MaximumLength + sizeof(WCHAR), TAG_PORTCLASS);
208 if (!ToEntry)
209 {
210 Status = STATUS_INSUFFICIENT_RESOURCES;
211 goto cleanup;
212 }
213 }
214
215 if (FromSubDeviceDescriptor)
216 {
217 FromEntry->FromPin = FromPin;
218 FromEntry->Connection.Pin = ToPin;
219 FromEntry->Connection.Size = sizeof(KSPIN_PHYSICALCONNECTION) + ToString->MaximumLength + sizeof(WCHAR);
220 RtlMoveMemory(&FromEntry->Connection.SymbolicLinkName, ToString->Buffer, ToString->MaximumLength);
221 FromEntry->Connection.SymbolicLinkName[ToString->Length / sizeof(WCHAR)] = UNICODE_NULL;
222
223 InsertTailList(&FromSubDeviceDescriptor->PhysicalConnectionList, &FromEntry->Entry);
224 }
225
226 if (ToSubDeviceDescriptor)
227 {
228 ToEntry->FromPin = ToPin;
229 ToEntry->Connection.Pin = FromPin;
230 ToEntry->Connection.Size = sizeof(KSPIN_PHYSICALCONNECTION) + FromString->MaximumLength + sizeof(WCHAR);
231 RtlMoveMemory(&ToEntry->Connection.SymbolicLinkName, FromString->Buffer, FromString->MaximumLength);
232 ToEntry->Connection.SymbolicLinkName[FromString->Length / sizeof(WCHAR)] = UNICODE_NULL;
233
234 InsertTailList(&ToSubDeviceDescriptor->PhysicalConnectionList, &ToEntry->Entry);
235
236 }
237
238 return STATUS_SUCCESS;
239
240 cleanup:
241
242 if (FromSubDevice)
243 FromSubDevice->Release();
244
245 if (ToSubDevice)
246 ToSubDevice->Release();
247
248 if (FromEntry)
249 FreeItem(FromEntry, TAG_PORTCLASS);
250
251 if (ToEntry)
252 FreeItem(ToEntry, TAG_PORTCLASS);
253
254 return Status;
255 }
256
257 NTSTATUS
258 NTAPI
PcRegisterPhysicalConnection(IN PDEVICE_OBJECT DeviceObject,IN PUNKNOWN FromUnknown,IN ULONG FromPin,IN PUNKNOWN ToUnknown,IN ULONG ToPin)259 PcRegisterPhysicalConnection(
260 IN PDEVICE_OBJECT DeviceObject,
261 IN PUNKNOWN FromUnknown,
262 IN ULONG FromPin,
263 IN PUNKNOWN ToUnknown,
264 IN ULONG ToPin)
265 {
266 DPRINT("PcRegisterPhysicalConnection\n");
267 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
268
269 if (!DeviceObject || !FromUnknown || !ToUnknown)
270 return STATUS_INVALID_PARAMETER;
271
272 return RegisterConnection(DeviceObject, FromUnknown, NULL, FromPin, ToUnknown, NULL, ToPin);
273 }
274
275 NTSTATUS
276 NTAPI
PcRegisterPhysicalConnectionFromExternal(IN PDEVICE_OBJECT DeviceObject,IN PUNICODE_STRING FromString,IN ULONG FromPin,IN PUNKNOWN ToUnknown,IN ULONG ToPin)277 PcRegisterPhysicalConnectionFromExternal(
278 IN PDEVICE_OBJECT DeviceObject,
279 IN PUNICODE_STRING FromString,
280 IN ULONG FromPin,
281 IN PUNKNOWN ToUnknown,
282 IN ULONG ToPin)
283 {
284 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
285
286 if (!DeviceObject || !FromString || !ToUnknown)
287 return STATUS_INVALID_PARAMETER;
288
289 return RegisterConnection(DeviceObject, NULL, FromString, FromPin, ToUnknown, NULL, ToPin);
290 }
291
292 NTSTATUS
293 NTAPI
PcRegisterPhysicalConnectionToExternal(IN PDEVICE_OBJECT DeviceObject,IN PUNKNOWN FromUnknown,IN ULONG FromPin,IN PUNICODE_STRING ToString,IN ULONG ToPin)294 PcRegisterPhysicalConnectionToExternal(
295 IN PDEVICE_OBJECT DeviceObject,
296 IN PUNKNOWN FromUnknown,
297 IN ULONG FromPin,
298 IN PUNICODE_STRING ToString,
299 IN ULONG ToPin)
300 {
301 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
302
303 if (!DeviceObject || !FromUnknown || !ToString)
304 return STATUS_INVALID_PARAMETER;
305
306 return RegisterConnection(DeviceObject, FromUnknown, NULL, FromPin, NULL, ToString, ToPin);
307 }
308