From 9e975473238ffee52d13dbddaf85a50cf378749a Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sat, 11 Jul 2009 19:01:18 +0000 Subject: [PATCH] - Implement dynamic unregistration of physical connections - Implement IUnregisterPhysicalConnection interface for all port drivers svn path=/trunk/; revision=41891 --- .../wdm/audio/backpln/portcls/connection.c | 332 +++++++++++++++--- .../wdm/audio/backpln/portcls/port_dmus.c | 4 + .../wdm/audio/backpln/portcls/port_topology.c | 4 + .../audio/backpln/portcls/port_wavecyclic.c | 4 + .../wdm/audio/backpln/portcls/port_wavepci.c | 4 + .../wdm/audio/backpln/portcls/port_wavert.c | 4 + .../wdm/audio/backpln/portcls/private.h | 10 +- 7 files changed, 309 insertions(+), 53 deletions(-) diff --git a/reactos/drivers/wdm/audio/backpln/portcls/connection.c b/reactos/drivers/wdm/audio/backpln/portcls/connection.c index 0e20e706a36..79855baac61 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/connection.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/connection.c @@ -9,6 +9,247 @@ #include "private.h" +typedef struct +{ + IUnregisterPhysicalConnectionVtbl *lpVtbl; + LONG ref; + +}IUnregisterPhysicalConnectionImpl; + +NTSTATUS +NTAPI +IUnregisterPhysicalConnection_fnQueryInterface( + IUnregisterPhysicalConnection* iface, + IN REFIID refiid, + OUT PVOID* Output) +{ + IUnregisterPhysicalConnectionImpl * This = (IUnregisterPhysicalConnectionImpl*)iface; + + if (IsEqualGUIDAligned(refiid, &IID_IUnregisterPhysicalConnection) || + IsEqualGUIDAligned(refiid, &IID_IUnknown)) + { + *Output = &This->lpVtbl; + InterlockedIncrement(&This->ref); + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +} + +ULONG +NTAPI +IUnregisterPhysicalConnection_fnAddRef( + IUnregisterPhysicalConnection* iface) +{ + IUnregisterPhysicalConnectionImpl * This = (IUnregisterPhysicalConnectionImpl*)iface; + + return InterlockedIncrement(&This->ref); +} + +ULONG +NTAPI +IUnregisterPhysicalConnection_fnRelease( + IUnregisterPhysicalConnection* iface) +{ + IUnregisterPhysicalConnectionImpl * This = (IUnregisterPhysicalConnectionImpl*)iface; + + InterlockedDecrement(&This->ref); + + if (This->ref == 0) + { + FreeItem(This, TAG_PORTCLASS); + return 0; + } + return This->ref; +} + +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) + { + /* get our private interface */ + Status = FromUnknown->lpVtbl->QueryInterface(FromUnknown, &IID_ISubdevice, (PVOID*)&FromSubDevice); + if (!NT_SUCCESS(Status)) + return STATUS_INVALID_PARAMETER; + } + + if (ToUnknown) + { + Status = ToUnknown->lpVtbl->QueryInterface(ToUnknown, &IID_ISubdevice, (PVOID*)&ToSubDevice); + if (!NT_SUCCESS(Status)) + goto cleanup; + } + + + Entry = DeviceExt->PhysicalConnectionList.Flink; + bFound = FALSE; + /* loop physical connection list */ + while(Entry != &DeviceExt->PhysicalConnectionList) + { + Connection = (PPHYSICAL_CONNECTION)CONTAINING_RECORD(Entry, PHYSICAL_CONNECTION, Entry); + /* compare current entry */ + if (Connection->FromPin == FromPin && Connection->ToPin == ToPin && + Connection->FromSubDevice == FromSubDevice && Connection->ToSubDevice == ToSubDevice) + { + if (FromString && Connection->FromUnicodeString.Buffer) + { + if (!RtlCompareUnicodeString(FromString, &Connection->FromUnicodeString, TRUE)) + { + /* UnregisterPhysicalConnectionFromExternal */ + bFound = TRUE; + break; + } + } + else if (ToString && Connection->ToUnicodeString.Buffer) + { + if (!RtlCompareUnicodeString(ToString, &Connection->ToUnicodeString, TRUE)) + { + /* UnregisterPhysicalConnectionToExternal */ + bFound = TRUE; + break; + } + } + else + { + /* UnregisterPhysicalConnection */ + bFound = TRUE; + break; + } + } + Entry = Entry->Flink; + } + + if (!bFound) + { + /* not found */ + Status = STATUS_NOT_FOUND; + goto cleanup; + } + + /* remove list entry */ + RemoveEntryList(&Connection->Entry); + + /* release resources */ + if (Connection->FromSubDevice) + Connection->FromSubDevice->lpVtbl->Release(Connection->FromSubDevice); + + + if (Connection->ToSubDevice) + Connection->ToSubDevice->lpVtbl->Release(Connection->ToSubDevice); + + if (Connection->FromUnicodeString.Buffer) + RtlFreeUnicodeString(&Connection->FromUnicodeString); + + if (Connection->ToUnicodeString.Buffer) + RtlFreeUnicodeString(&Connection->ToUnicodeString); + + FreeItem(Connection, TAG_PORTCLASS); + Status = STATUS_SUCCESS; + +cleanup: + + if (FromSubDevice) + FromSubDevice->lpVtbl->Release(FromSubDevice); + + if (ToSubDevice) + ToSubDevice->lpVtbl->Release(ToSubDevice); + + return Status; + +} + +NTSTATUS +NTAPI +IUnregisterPhysicalConnection_fnUnregisterPhysicalConnection( + IN IUnregisterPhysicalConnection* iface, + 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 +IUnregisterPhysicalConnection_fnUnregisterPhysicalConnectionToExternal( + IN IUnregisterPhysicalConnection* iface, + 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 +IUnregisterPhysicalConnection_fnUnregisterPhysicalConnectionFromExternal( + IN IUnregisterPhysicalConnection* iface, + 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); +} + +static IUnregisterPhysicalConnectionVtbl vt_IUnregisterPhysicalConnection = +{ + IUnregisterPhysicalConnection_fnQueryInterface, + IUnregisterPhysicalConnection_fnAddRef, + IUnregisterPhysicalConnection_fnRelease, + IUnregisterPhysicalConnection_fnUnregisterPhysicalConnection, + IUnregisterPhysicalConnection_fnUnregisterPhysicalConnectionToExternal, + IUnregisterPhysicalConnection_fnUnregisterPhysicalConnectionFromExternal +}; + +NTSTATUS +NTAPI +NewIUnregisterPhysicalConnection( + OUT PUNREGISTERPHYSICALCONNECTION *OutConnection) +{ + IUnregisterPhysicalConnectionImpl * This = (IUnregisterPhysicalConnectionImpl*)AllocateItem(NonPagedPool, sizeof(IUnregisterPhysicalConnectionImpl), TAG_PORTCLASS); + + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + This->lpVtbl = &vt_IUnregisterPhysicalConnection; + This->ref = 1; + *OutConnection = (PUNREGISTERPHYSICALCONNECTION)&This->lpVtbl; + return STATUS_SUCCESS; +} NTSYSAPI BOOLEAN @@ -30,75 +271,66 @@ RegisterConnection( IN ULONG ToPin) { PHYSICAL_CONNECTION *NewConnection; - UNICODE_STRING FromUnicodeString = {0, 0, 0}; - UNICODE_STRING ToUnicodeString = {0, 0, 0}; - ISubdevice * FromSubDevice = NULL; - ISubdevice * ToSubDevice = NULL; PPCLASS_DEVICE_EXTENSION DeviceExt; + NTSTATUS Status; DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - NTSTATUS Status = STATUS_SUCCESS; - - if (FromUnknown) - { - Status = FromUnknown->lpVtbl->QueryInterface(FromUnknown, &IID_ISubdevice, (PVOID*)&FromSubDevice); - if (!NT_SUCCESS(Status)) - return STATUS_INVALID_PARAMETER; - } - else - { - if (!RtlCreateUnicodeString(&FromUnicodeString, (PCWSTR)FromString)) - return STATUS_INSUFFICIENT_RESOURCES; - } - - if (ToUnknown) - { - Status = ToUnknown->lpVtbl->QueryInterface(ToUnknown, &IID_ISubdevice, (PVOID*)&ToSubDevice); - } - else - { - if (!RtlCreateUnicodeString(&ToUnicodeString, (PCWSTR)ToString)) - Status = STATUS_INSUFFICIENT_RESOURCES; - } - - if (!NT_SUCCESS(Status)) - { - goto cleanup; - } - NewConnection = AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION), TAG_PORTCLASS); if (!NewConnection) { - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; + return STATUS_INSUFFICIENT_RESOURCES; } - NewConnection->FromPin = FromPin; - NewConnection->FromSubDevice = FromSubDevice; - NewConnection->FromUnicodeString = FromUnicodeString.Buffer; - NewConnection->ToPin = ToPin; - NewConnection->ToSubDevice = ToSubDevice; - NewConnection->ToUnicodeString = ToUnicodeString.Buffer; + if (FromUnknown) + { + Status = FromUnknown->lpVtbl->QueryInterface(FromUnknown, &IID_ISubdevice, (PVOID*)&NewConnection->FromSubDevice); + if (!NT_SUCCESS(Status)) + goto cleanup; + } + else + { + if (!RtlCreateUnicodeString(&NewConnection->FromUnicodeString, (PCWSTR)FromString)) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + } + + if (ToUnknown) + { + Status = ToUnknown->lpVtbl->QueryInterface(ToUnknown, &IID_ISubdevice, (PVOID*)&NewConnection->ToSubDevice); + if (!NT_SUCCESS(Status)) + goto cleanup; + } + else + { + if (!RtlCreateUnicodeString(&NewConnection->ToUnicodeString, (PCWSTR)ToString)) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + } InsertTailList(&DeviceExt->PhysicalConnectionList, &NewConnection->Entry); return STATUS_SUCCESS; cleanup: - if (FromSubDevice) - FromSubDevice->lpVtbl->Release(FromSubDevice); + if (NewConnection->FromSubDevice) + NewConnection->FromSubDevice->lpVtbl->Release(NewConnection->FromSubDevice); - if (ToSubDevice) - ToSubDevice->lpVtbl->Release(ToSubDevice); + if (NewConnection->ToSubDevice) + NewConnection->ToSubDevice->lpVtbl->Release(NewConnection->ToSubDevice); - if (FromUnicodeString.Buffer) - RtlFreeUnicodeString(&FromUnicodeString); + if (NewConnection->FromUnicodeString.Buffer) + RtlFreeUnicodeString(&NewConnection->FromUnicodeString); - if (ToUnicodeString.Buffer) - RtlFreeUnicodeString(&ToUnicodeString); + if (NewConnection->ToUnicodeString.Buffer) + RtlFreeUnicodeString(&NewConnection->ToUnicodeString); + + FreeItem(NewConnection, TAG_PORTCLASS); return Status; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c b/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c index 7e8c18132c9..c9910f81eb4 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c @@ -87,6 +87,10 @@ IPortDMus_fnQueryInterface( { return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); } + else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterPhysicalConnection)) + { + return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); + } if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) { diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c b/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c index 40974caac9c..a0e9f69d648 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c @@ -105,6 +105,10 @@ IPortTopology_fnQueryInterface( { return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); } + else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterPhysicalConnection)) + { + return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); + } if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) { diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c b/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c index 32f6767462f..eef0193c301 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c @@ -230,6 +230,10 @@ IPortWaveCyclic_fnQueryInterface( { return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); } + else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterPhysicalConnection)) + { + return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); + } if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) { diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c b/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c index 65bf15c3105..c6d59d7d020 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c @@ -290,6 +290,10 @@ IPortWavePci_fnQueryInterface( { return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); } + else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterPhysicalConnection)) + { + return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); + } if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) { diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c b/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c index 4670367a5c4..14a6a113f5d 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c @@ -226,6 +226,10 @@ IPortWaveRT_fnQueryInterface( { return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); } + else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterPhysicalConnection)) + { + return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); + } if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS) { diff --git a/reactos/drivers/wdm/audio/backpln/portcls/private.h b/reactos/drivers/wdm/audio/backpln/portcls/private.h index 21744945b82..445e5bc3b7d 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/private.h +++ b/reactos/drivers/wdm/audio/backpln/portcls/private.h @@ -300,6 +300,10 @@ NTAPI NewIUnregisterSubdevice( OUT PUNREGISTERSUBDEVICE *OutDevice); +NTSTATUS +NTAPI +NewIUnregisterPhysicalConnection( + OUT PUNREGISTERPHYSICALCONNECTION *OutConnection); #define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet,\ PropGeneral, PropInstances, PropIntersection)\ @@ -337,12 +341,12 @@ typedef struct { LIST_ENTRY Entry; ISubdevice * FromSubDevice; - LPWSTR FromUnicodeString; + UNICODE_STRING FromUnicodeString; ULONG FromPin; ISubdevice * ToSubDevice; - LPWSTR ToUnicodeString; + UNICODE_STRING ToUnicodeString; ULONG ToPin; -}PHYSICAL_CONNECTION; +}PHYSICAL_CONNECTION, *PPHYSICAL_CONNECTION; typedef struct {