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 31 CUnregisterPhysicalConnection(IUnknown *OuterUnknown){} 32 33 virtual ~CUnregisterPhysicalConnection(){} 34 }; 35 36 NTSTATUS 37 NTAPI 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 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 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 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 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 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 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 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 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 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