Author: janderwald Date: Sat Jul 11 23:01:18 2009 New Revision: 41891
URL: http://svn.reactos.org/svn/reactos?rev=41891&view=rev Log: - Implement dynamic unregistration of physical connections - Implement IUnregisterPhysicalConnection interface for all port drivers
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/connection.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/connection.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/connection.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/connection.c [iso-8859-1] Sat Jul 11 23:01:18 2009 @@ -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 @@ 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; - } - - NewConnection->FromPin = FromPin; - NewConnection->FromSubDevice = FromSubDevice; - NewConnection->FromUnicodeString = FromUnicodeString.Buffer; - NewConnection->ToPin = ToPin; - NewConnection->ToSubDevice = ToSubDevice; - NewConnection->ToUnicodeString = ToUnicodeString.Buffer; - + return STATUS_INSUFFICIENT_RESOURCES; + } + + + 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 (ToSubDevice) - ToSubDevice->lpVtbl->Release(ToSubDevice); - - if (FromUnicodeString.Buffer) - RtlFreeUnicodeString(&FromUnicodeString); - - if (ToUnicodeString.Buffer) - RtlFreeUnicodeString(&ToUnicodeString); + if (NewConnection->FromSubDevice) + NewConnection->FromSubDevice->lpVtbl->Release(NewConnection->FromSubDevice); + + if (NewConnection->ToSubDevice) + NewConnection->ToSubDevice->lpVtbl->Release(NewConnection->ToSubDevice); + + if (NewConnection->FromUnicodeString.Buffer) + RtlFreeUnicodeString(&NewConnection->FromUnicodeString); + + if (NewConnection->ToUnicodeString.Buffer) + RtlFreeUnicodeString(&NewConnection->ToUnicodeString); + + FreeItem(NewConnection, TAG_PORTCLASS);
return Status; }
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c [iso-8859-1] Sat Jul 11 23:01:18 2009 @@ -86,6 +86,10 @@ else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice)) { return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); + } + else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterPhysicalConnection)) + { + return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); }
if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c [iso-8859-1] Sat Jul 11 23:01:18 2009 @@ -104,6 +104,10 @@ else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice)) { return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); + } + else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterPhysicalConnection)) + { + return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); }
if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c [iso-8859-1] Sat Jul 11 23:01:18 2009 @@ -229,6 +229,10 @@ else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice)) { return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); + } + else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterPhysicalConnection)) + { + return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); }
if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c [iso-8859-1] Sat Jul 11 23:01:18 2009 @@ -289,6 +289,10 @@ else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice)) { return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); + } + else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterPhysicalConnection)) + { + return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); }
if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c [iso-8859-1] Sat Jul 11 23:01:18 2009 @@ -225,6 +225,10 @@ else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice)) { return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); + } + else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterPhysicalConnection)) + { + return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output); }
if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] Sat Jul 11 23:01:18 2009 @@ -300,6 +300,10 @@ NewIUnregisterSubdevice( OUT PUNREGISTERSUBDEVICE *OutDevice);
+NTSTATUS +NTAPI +NewIUnregisterPhysicalConnection( + OUT PUNREGISTERPHYSICALCONNECTION *OutConnection);
#define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet,\ PropGeneral, PropInstances, PropIntersection)\ @@ -337,12 +341,12 @@ { 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 {