mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
- Implement dynamic unregistration of physical connections
- Implement IUnregisterPhysicalConnection interface for all port drivers svn path=/trunk/; revision=41891
This commit is contained in:
parent
9913f96067
commit
9e97547323
7 changed files with 309 additions and 53 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue