2009-04-03 17:06:16 +00:00
|
|
|
/*
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS Kernel Streaming
|
|
|
|
* FILE: drivers/wdm/audio/backpln/portcls/connection.c
|
|
|
|
* PURPOSE: portcls physical connection registration
|
|
|
|
* PROGRAMMER: Johannes Anderwald
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2009-09-11 06:33:55 +00:00
|
|
|
#include "private.hpp"
|
2009-01-12 18:40:08 +00:00
|
|
|
|
2009-09-11 06:33:55 +00:00
|
|
|
extern
|
|
|
|
"C"
|
|
|
|
NTSYSAPI
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
RtlCreateUnicodeString(
|
|
|
|
PUNICODE_STRING DestinationString,
|
|
|
|
PCWSTR SourceString
|
|
|
|
);
|
2009-07-11 19:01:18 +00:00
|
|
|
|
|
|
|
|
2009-09-11 06:33:55 +00:00
|
|
|
class CUnregisterPhysicalConnection : public IUnregisterPhysicalConnection
|
2009-07-11 19:01:18 +00:00
|
|
|
{
|
2009-09-11 06:33:55 +00:00
|
|
|
public:
|
|
|
|
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
|
2009-07-11 19:01:18 +00:00
|
|
|
|
2009-09-11 06:33:55 +00:00
|
|
|
STDMETHODIMP_(ULONG) AddRef()
|
2009-07-11 19:01:18 +00:00
|
|
|
{
|
2009-09-11 06:33:55 +00:00
|
|
|
InterlockedIncrement(&m_Ref);
|
|
|
|
return m_Ref;
|
2009-07-11 19:01:18 +00:00
|
|
|
}
|
2009-09-11 06:33:55 +00:00
|
|
|
STDMETHODIMP_(ULONG) Release()
|
|
|
|
{
|
|
|
|
InterlockedDecrement(&m_Ref);
|
2009-07-11 19:01:18 +00:00
|
|
|
|
2009-09-11 06:33:55 +00:00
|
|
|
if (!m_Ref)
|
|
|
|
{
|
|
|
|
delete this;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return m_Ref;
|
|
|
|
}
|
|
|
|
IMP_IUnregisterPhysicalConnection;
|
2009-07-11 19:01:18 +00:00
|
|
|
|
2009-09-11 06:33:55 +00:00
|
|
|
CUnregisterPhysicalConnection(IUnknown *OuterUnknown){}
|
2009-07-11 19:01:18 +00:00
|
|
|
|
2009-09-11 06:33:55 +00:00
|
|
|
virtual ~CUnregisterPhysicalConnection(){}
|
2009-07-11 19:01:18 +00:00
|
|
|
|
2009-09-11 06:33:55 +00:00
|
|
|
protected:
|
|
|
|
LONG m_Ref;
|
2009-07-11 19:01:18 +00:00
|
|
|
|
2009-09-11 06:33:55 +00:00
|
|
|
};
|
2009-07-11 19:01:18 +00:00
|
|
|
|
2009-09-11 06:33:55 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
CUnregisterPhysicalConnection::QueryInterface(
|
|
|
|
IN REFIID refiid,
|
|
|
|
OUT PVOID* Output)
|
|
|
|
{
|
|
|
|
if (IsEqualGUIDAligned(refiid, IID_IUnregisterPhysicalConnection) ||
|
|
|
|
IsEqualGUIDAligned(refiid, IID_IUnknown))
|
2009-07-11 19:01:18 +00:00
|
|
|
{
|
2009-09-11 06:33:55 +00:00
|
|
|
*Output = PVOID(PUNKNOWN(this));
|
|
|
|
|
|
|
|
PUNKNOWN(*Output)->AddRef();
|
|
|
|
return STATUS_SUCCESS;
|
2009-07-11 19:01:18 +00:00
|
|
|
}
|
2009-09-11 06:33:55 +00:00
|
|
|
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
2009-07-11 19:01:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
PLIST_ENTRY Entry;
|
|
|
|
PPHYSICAL_CONNECTION Connection;
|
|
|
|
PPCLASS_DEVICE_EXTENSION DeviceExt;
|
|
|
|
NTSTATUS Status;
|
|
|
|
ISubdevice * FromSubDevice = NULL;
|
|
|
|
ISubdevice * ToSubDevice = NULL;
|
|
|
|
ULONG bFound;
|
|
|
|
|
|
|
|
DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
|
|
|
|
|
|
if (FromUnknown)
|
|
|
|
{
|
2009-09-11 06:33:55 +00:00
|
|
|
// get our private interface
|
|
|
|
Status = FromUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&FromSubDevice);
|
2009-07-11 19:01:18 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ToUnknown)
|
|
|
|
{
|
2009-09-11 06:33:55 +00:00
|
|
|
Status = ToUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&ToSubDevice);
|
2009-07-11 19:01:18 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Entry = DeviceExt->PhysicalConnectionList.Flink;
|
|
|
|
bFound = FALSE;
|
2009-09-11 06:33:55 +00:00
|
|
|
// loop physical connection list
|
2009-07-11 19:01:18 +00:00
|
|
|
while(Entry != &DeviceExt->PhysicalConnectionList)
|
|
|
|
{
|
|
|
|
Connection = (PPHYSICAL_CONNECTION)CONTAINING_RECORD(Entry, PHYSICAL_CONNECTION, Entry);
|
2009-09-11 06:33:55 +00:00
|
|
|
// compare current entry
|
2009-07-11 19:01:18 +00:00
|
|
|
if (Connection->FromPin == FromPin && Connection->ToPin == ToPin &&
|
|
|
|
Connection->FromSubDevice == FromSubDevice && Connection->ToSubDevice == ToSubDevice)
|
|
|
|
{
|
|
|
|
if (FromString && Connection->FromUnicodeString.Buffer)
|
|
|
|
{
|
|
|
|
if (!RtlCompareUnicodeString(FromString, &Connection->FromUnicodeString, TRUE))
|
|
|
|
{
|
2009-09-11 06:33:55 +00:00
|
|
|
// UnregisterPhysicalConnectionFromExternal
|
2009-07-11 19:01:18 +00:00
|
|
|
bFound = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ToString && Connection->ToUnicodeString.Buffer)
|
|
|
|
{
|
|
|
|
if (!RtlCompareUnicodeString(ToString, &Connection->ToUnicodeString, TRUE))
|
|
|
|
{
|
2009-09-11 06:33:55 +00:00
|
|
|
// UnregisterPhysicalConnectionToExternal
|
2009-07-11 19:01:18 +00:00
|
|
|
bFound = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-09-11 06:33:55 +00:00
|
|
|
// UnregisterPhysicalConnection
|
2009-07-11 19:01:18 +00:00
|
|
|
bFound = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Entry = Entry->Flink;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!bFound)
|
|
|
|
{
|
2009-09-11 06:33:55 +00:00
|
|
|
// not found
|
2009-07-11 19:01:18 +00:00
|
|
|
Status = STATUS_NOT_FOUND;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2009-09-11 06:33:55 +00:00
|
|
|
// remove list entry
|
2009-07-11 19:01:18 +00:00
|
|
|
RemoveEntryList(&Connection->Entry);
|
|
|
|
|
2009-09-11 06:33:55 +00:00
|
|
|
// release resources
|
2009-07-11 19:01:18 +00:00
|
|
|
if (Connection->FromSubDevice)
|
2009-09-11 06:33:55 +00:00
|
|
|
Connection->FromSubDevice->Release();
|
2009-07-11 19:01:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
if (Connection->ToSubDevice)
|
2009-09-11 06:33:55 +00:00
|
|
|
Connection->ToSubDevice->Release();
|
2009-07-11 19:01:18 +00:00
|
|
|
|
|
|
|
if (Connection->FromUnicodeString.Buffer)
|
|
|
|
RtlFreeUnicodeString(&Connection->FromUnicodeString);
|
|
|
|
|
|
|
|
if (Connection->ToUnicodeString.Buffer)
|
|
|
|
RtlFreeUnicodeString(&Connection->ToUnicodeString);
|
|
|
|
|
|
|
|
FreeItem(Connection, TAG_PORTCLASS);
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
|
|
|
|
if (FromSubDevice)
|
2009-09-11 06:33:55 +00:00
|
|
|
FromSubDevice->Release();
|
2009-07-11 19:01:18 +00:00
|
|
|
|
|
|
|
if (ToSubDevice)
|
2009-09-11 06:33:55 +00:00
|
|
|
ToSubDevice->Release();
|
2009-07-11 19:01:18 +00:00
|
|
|
|
|
|
|
return Status;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2009-09-11 06:33:55 +00:00
|
|
|
CUnregisterPhysicalConnection::UnregisterPhysicalConnection(
|
2009-07-11 19:01:18 +00:00
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PUNKNOWN FromUnknown,
|
|
|
|
IN ULONG FromPin,
|
|
|
|
IN PUNKNOWN ToUnknown,
|
|
|
|
IN ULONG ToPin)
|
|
|
|
{
|
|
|
|
if (!DeviceObject || !FromUnknown || !ToUnknown)
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
return UnRegisterConnection(DeviceObject, FromUnknown, NULL, FromPin, ToUnknown, NULL, ToPin);
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2009-09-11 06:33:55 +00:00
|
|
|
CUnregisterPhysicalConnection::UnregisterPhysicalConnectionToExternal(
|
2009-07-11 19:01:18 +00:00
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PUNKNOWN FromUnknown,
|
|
|
|
IN ULONG FromPin,
|
|
|
|
IN PUNICODE_STRING ToString,
|
|
|
|
IN ULONG ToPin)
|
|
|
|
{
|
|
|
|
if (!DeviceObject || !FromUnknown || !ToString)
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
return UnRegisterConnection(DeviceObject, FromUnknown, NULL, FromPin, NULL, ToString, ToPin);
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2009-09-11 06:33:55 +00:00
|
|
|
CUnregisterPhysicalConnection::UnregisterPhysicalConnectionFromExternal(
|
2009-07-11 19:01:18 +00:00
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PUNICODE_STRING FromString,
|
|
|
|
IN ULONG FromPin,
|
|
|
|
IN PUNKNOWN ToUnknown,
|
|
|
|
IN ULONG ToPin)
|
|
|
|
{
|
|
|
|
if (!DeviceObject || !FromString || !ToUnknown)
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
return UnRegisterConnection(DeviceObject, NULL, FromString, FromPin, ToUnknown, NULL, ToPin);
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
NewIUnregisterPhysicalConnection(
|
|
|
|
OUT PUNREGISTERPHYSICALCONNECTION *OutConnection)
|
|
|
|
{
|
|
|
|
|
2009-09-11 06:33:55 +00:00
|
|
|
CUnregisterPhysicalConnection *new_ptr = new(NonPagedPool, TAG_PORTCLASS) CUnregisterPhysicalConnection(NULL);
|
|
|
|
|
|
|
|
if (!new_ptr)
|
2009-07-11 19:01:18 +00:00
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
|
2009-09-11 06:33:55 +00:00
|
|
|
new_ptr->AddRef();
|
|
|
|
*OutConnection = (PUNREGISTERPHYSICALCONNECTION)new_ptr;
|
2009-07-11 19:01:18 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
2009-01-12 18:40:08 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
PHYSICAL_CONNECTION *NewConnection;
|
2009-01-27 12:43:33 +00:00
|
|
|
PPCLASS_DEVICE_EXTENSION DeviceExt;
|
2009-07-11 19:01:18 +00:00
|
|
|
NTSTATUS Status;
|
2009-01-12 18:40:08 +00:00
|
|
|
|
2009-01-27 12:43:33 +00:00
|
|
|
DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
2009-01-12 18:40:08 +00:00
|
|
|
|
2009-09-11 06:33:55 +00:00
|
|
|
NewConnection = (PPHYSICAL_CONNECTION)AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION), TAG_PORTCLASS);
|
2009-07-11 19:01:18 +00:00
|
|
|
if (!NewConnection)
|
|
|
|
{
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
}
|
2009-01-12 18:40:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
if (FromUnknown)
|
|
|
|
{
|
2009-09-11 06:33:55 +00:00
|
|
|
Status = FromUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&NewConnection->FromSubDevice);
|
2009-01-12 18:40:08 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2009-07-11 19:01:18 +00:00
|
|
|
goto cleanup;
|
2009-01-12 18:40:08 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-07-11 19:01:18 +00:00
|
|
|
if (!RtlCreateUnicodeString(&NewConnection->FromUnicodeString, (PCWSTR)FromString))
|
|
|
|
{
|
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-01-12 18:40:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ToUnknown)
|
|
|
|
{
|
2009-09-11 06:33:55 +00:00
|
|
|
Status = ToUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&NewConnection->ToSubDevice);
|
2009-07-11 19:01:18 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
goto cleanup;
|
2009-01-12 18:40:08 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-07-11 19:01:18 +00:00
|
|
|
if (!RtlCreateUnicodeString(&NewConnection->ToUnicodeString, (PCWSTR)ToString))
|
|
|
|
{
|
2009-01-12 18:40:08 +00:00
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
2009-07-11 19:01:18 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-01-12 18:40:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
InsertTailList(&DeviceExt->PhysicalConnectionList, &NewConnection->Entry);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
|
2009-07-11 19:01:18 +00:00
|
|
|
if (NewConnection->FromSubDevice)
|
2009-09-11 06:33:55 +00:00
|
|
|
NewConnection->FromSubDevice->Release();
|
2009-01-12 18:40:08 +00:00
|
|
|
|
2009-07-11 19:01:18 +00:00
|
|
|
if (NewConnection->ToSubDevice)
|
2009-09-11 06:33:55 +00:00
|
|
|
NewConnection->ToSubDevice->Release();
|
2009-07-11 19:01:18 +00:00
|
|
|
|
|
|
|
if (NewConnection->FromUnicodeString.Buffer)
|
|
|
|
RtlFreeUnicodeString(&NewConnection->FromUnicodeString);
|
2009-01-12 18:40:08 +00:00
|
|
|
|
2009-07-11 19:01:18 +00:00
|
|
|
if (NewConnection->ToUnicodeString.Buffer)
|
|
|
|
RtlFreeUnicodeString(&NewConnection->ToUnicodeString);
|
2009-01-12 18:40:08 +00:00
|
|
|
|
2009-07-11 19:01:18 +00:00
|
|
|
FreeItem(NewConnection, TAG_PORTCLASS);
|
2009-01-12 18:40:08 +00:00
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2009-09-11 06:33:55 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2009-01-12 18:40:08 +00:00
|
|
|
PcRegisterPhysicalConnection(
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PUNKNOWN FromUnknown,
|
|
|
|
IN ULONG FromPin,
|
|
|
|
IN PUNKNOWN ToUnknown,
|
|
|
|
IN ULONG ToPin)
|
|
|
|
{
|
2009-04-03 17:06:16 +00:00
|
|
|
DPRINT("PcRegisterPhysicalConnection\n");
|
2009-09-11 06:33:55 +00:00
|
|
|
PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
|
2009-01-17 11:19:27 +00:00
|
|
|
|
2009-01-12 18:40:08 +00:00
|
|
|
if (!DeviceObject || !FromUnknown || !ToUnknown)
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
return RegisterConnection(DeviceObject, FromUnknown, NULL, FromPin, ToUnknown, NULL, ToPin);
|
|
|
|
}
|
|
|
|
|
2009-09-11 06:33:55 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2009-01-12 18:40:08 +00:00
|
|
|
PcRegisterPhysicalConnectionFromExternal(
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PUNICODE_STRING FromString,
|
|
|
|
IN ULONG FromPin,
|
|
|
|
IN PUNKNOWN ToUnknown,
|
|
|
|
IN ULONG ToPin)
|
|
|
|
{
|
2009-09-11 06:33:55 +00:00
|
|
|
PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
|
2009-04-23 19:06:36 +00:00
|
|
|
|
2009-01-12 18:40:08 +00:00
|
|
|
if (!DeviceObject || !FromString || !ToUnknown)
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
return RegisterConnection(DeviceObject, NULL, FromString, FromPin, ToUnknown, NULL, ToPin);
|
|
|
|
}
|
|
|
|
|
2009-09-11 06:33:55 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2009-01-12 18:40:08 +00:00
|
|
|
PcRegisterPhysicalConnectionToExternal(
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PUNKNOWN FromUnknown,
|
|
|
|
IN ULONG FromPin,
|
|
|
|
IN PUNICODE_STRING ToString,
|
|
|
|
IN ULONG ToPin)
|
|
|
|
{
|
2009-09-11 06:33:55 +00:00
|
|
|
PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
|
2009-04-23 19:06:36 +00:00
|
|
|
|
2009-01-12 18:40:08 +00:00
|
|
|
if (!DeviceObject || !FromUnknown || !ToString)
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
return RegisterConnection(DeviceObject, FromUnknown, NULL, FromPin, NULL, ToString, ToPin);
|
|
|
|
}
|