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