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