- Rewrite registering physical connection handling to support KSPROPERTY_PIN_PHYSICALCONNECTION

svn path=/trunk/; revision=43175
This commit is contained in:
Johannes Anderwald 2009-09-27 00:50:06 +00:00
parent 307f8beca8
commit efc1228ec6
10 changed files with 179 additions and 238 deletions

View file

@ -135,10 +135,6 @@ PcAddAdapterDevice(
portcls_ext->PhysicalDeviceObject = PhysicalDeviceObject;
// set up the start device function
portcls_ext->StartDevice = StartDevice;
// prepare the subdevice list
InitializeListHead(&portcls_ext->SubDeviceList);
// prepare the physical connection list
InitializeListHead(&portcls_ext->PhysicalConnectionList);
// initialize timer lock
KeInitializeSpinLock(&portcls_ext->TimerListLock);
// initialize timer list
@ -214,10 +210,9 @@ PcRegisterSubdevice(
NTSTATUS Status;
ISubdevice *SubDevice;
UNICODE_STRING SymbolicLinkName;
SUBDEVICE_DESCRIPTOR * SubDeviceDescriptor;
PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
ULONG Index;
UNICODE_STRING RefName;
PSUBDEVICE_ENTRY Entry;
PSYMBOLICLINK_ENTRY SymEntry;
DPRINT1("PcRegisterSubdevice DeviceObject %p Name %S Unknown %p\n", DeviceObject, Name, Unknown);
@ -259,36 +254,19 @@ PcRegisterSubdevice(
return STATUS_UNSUCCESSFUL;
}
// allocate subdevice entry
Entry = (PSUBDEVICE_ENTRY)AllocateItem(NonPagedPool, sizeof(SUBDEVICE_ENTRY), TAG_PORTCLASS);
if (!Entry)
{
// Insufficient memory
SubDevice->Release();
return STATUS_INSUFFICIENT_RESOURCES;
}
// add an create item to the device header
Status = KsAddObjectCreateItemToDeviceHeader(DeviceExt->KsDeviceHeader, PcCreateItemDispatch, (PVOID)SubDevice, Name, NULL);
if (!NT_SUCCESS(Status))
{
// failed to attach
SubDevice->Release();
FreeItem(Entry, TAG_PORTCLASS);
DPRINT1("KsAddObjectCreateItemToDeviceHeader failed with %x\n", Status);
return Status;
}
// initialize reference string
RtlInitUnicodeString(&RefName, Name);
// initialize subdevice entry
Entry->SubDevice = SubDevice;
RtlInitUnicodeString(&Entry->Name, Name);
InitializeListHead(&Entry->SymbolicLinkList);
// store subdevice entry
InsertTailList(&DeviceExt->SubDeviceList, &Entry->Entry);
RtlInitUnicodeString(&SubDeviceDescriptor->RefString, Name);
for(Index = 0; Index < SubDeviceDescriptor->InterfaceCount; Index++)
{
@ -311,7 +289,7 @@ PcRegisterSubdevice(
// initialize symbolic link item
RtlInitUnicodeString(&SymEntry->SymbolicLink, SymbolicLinkName.Buffer);
// store item
InsertTailList(&Entry->SymbolicLinkList, &SymEntry->Entry);
InsertTailList(&SubDeviceDescriptor->SymbolicLinkList, &SymEntry->Entry);
}
else
{

View file

@ -81,107 +81,8 @@ UnRegisterConnection(
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->QueryInterface(IID_ISubdevice, (PVOID*)&FromSubDevice);
if (!NT_SUCCESS(Status))
return STATUS_INVALID_PARAMETER;
}
if (ToUnknown)
{
Status = ToUnknown->QueryInterface(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->Release();
if (Connection->ToSubDevice)
Connection->ToSubDevice->Release();
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->Release();
if (ToSubDevice)
ToSubDevice->Release();
return Status;
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
@ -255,67 +156,100 @@ RegisterConnection(
IN PUNICODE_STRING ToString,
IN ULONG ToPin)
{
PHYSICAL_CONNECTION *NewConnection;
PPCLASS_DEVICE_EXTENSION DeviceExt;
PSUBDEVICE_DESCRIPTOR FromSubDeviceDescriptor, ToSubDeviceDescriptor;
PSYMBOLICLINK_ENTRY SymEntry;
ISubdevice * FromSubDevice = NULL, *ToSubDevice = NULL;
NTSTATUS Status;
DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
NewConnection = (PPHYSICAL_CONNECTION)AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION), TAG_PORTCLASS);
if (!NewConnection)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
PPHYSICAL_CONNECTION_ENTRY FromEntry = NULL, ToEntry = NULL;
if (FromUnknown)
{
Status = FromUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&NewConnection->FromSubDevice);
Status = FromUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&FromSubDevice);
if (!NT_SUCCESS(Status))
goto cleanup;
}
else
{
if (!RtlCreateUnicodeString(&NewConnection->FromUnicodeString, (PCWSTR)FromString))
Status = FromSubDevice->GetDescriptor(&FromSubDeviceDescriptor);
if (!NT_SUCCESS(Status))
goto cleanup;
if (IsListEmpty(&FromSubDeviceDescriptor->SymbolicLinkList))
{
Status = STATUS_INSUFFICIENT_RESOURCES;
Status = STATUS_UNSUCCESSFUL;
goto cleanup;
}
SymEntry = (PSYMBOLICLINK_ENTRY)CONTAINING_RECORD(FromSubDeviceDescriptor->SymbolicLinkList.Flink, SYMBOLICLINK_ENTRY, Entry);
FromString = &SymEntry->SymbolicLink;
}
if (ToUnknown)
{
Status = ToUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&NewConnection->ToSubDevice);
Status = ToUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&ToSubDevice);
if (!NT_SUCCESS(Status))
goto cleanup;
}
else
{
if (!RtlCreateUnicodeString(&NewConnection->ToUnicodeString, (PCWSTR)ToString))
Status = ToSubDevice->GetDescriptor(&ToSubDeviceDescriptor);
if (!NT_SUCCESS(Status))
goto cleanup;
if (IsListEmpty(&ToSubDeviceDescriptor->SymbolicLinkList))
{
Status = STATUS_INSUFFICIENT_RESOURCES;
Status = STATUS_UNSUCCESSFUL;
goto cleanup;
}
SymEntry = (PSYMBOLICLINK_ENTRY)CONTAINING_RECORD(ToSubDeviceDescriptor->SymbolicLinkList.Flink, SYMBOLICLINK_ENTRY, Entry);
ToString = &SymEntry->SymbolicLink;
}
InsertTailList(&DeviceExt->PhysicalConnectionList, &NewConnection->Entry);
FromEntry = (PPHYSICAL_CONNECTION_ENTRY)AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION_ENTRY) + ToString->MaximumLength, TAG_PORTCLASS);
if (!FromEntry)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto cleanup;
}
ToEntry = (PPHYSICAL_CONNECTION_ENTRY)AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION_ENTRY) + FromString->MaximumLength, TAG_PORTCLASS);
if (!ToEntry)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto cleanup;
}
FromEntry->FromPin = FromPin;
FromEntry->Connection.Pin = ToPin;
FromEntry->Connection.Size = sizeof(KSPIN_PHYSICALCONNECTION) + ToString->MaximumLength;
RtlMoveMemory(&FromEntry->Connection.SymbolicLinkName, ToString->Buffer, ToString->MaximumLength);
FromEntry->Connection.SymbolicLinkName[ToString->Length / sizeof(WCHAR)] = L'\0';
ToEntry->FromPin = ToPin;
ToEntry->Connection.Pin = FromPin;
ToEntry->Connection.Size = sizeof(KSPIN_PHYSICALCONNECTION) + FromString->MaximumLength;
RtlMoveMemory(&ToEntry->Connection.SymbolicLinkName, FromString->Buffer, FromString->MaximumLength);
ToEntry->Connection.SymbolicLinkName[FromString->Length / sizeof(WCHAR)] = L'\0';
InsertTailList(&FromSubDeviceDescriptor->PhysicalConnectionList, &FromEntry->Entry);
InsertTailList(&ToSubDeviceDescriptor->PhysicalConnectionList, &ToEntry->Entry);
return STATUS_SUCCESS;
cleanup:
if (NewConnection->FromSubDevice)
NewConnection->FromSubDevice->Release();
if (FromSubDevice)
FromSubDevice->Release();
if (NewConnection->ToSubDevice)
NewConnection->ToSubDevice->Release();
if (ToSubDevice)
ToSubDevice->Release();
if (NewConnection->FromUnicodeString.Buffer)
RtlFreeUnicodeString(&NewConnection->FromUnicodeString);
if (FromEntry)
FreeItem(FromEntry, TAG_PORTCLASS);
if (NewConnection->ToUnicodeString.Buffer)
RtlFreeUnicodeString(&NewConnection->ToUnicodeString);
FreeItem(NewConnection, TAG_PORTCLASS);
if (ToEntry)
FreeItem(ToEntry, TAG_PORTCLASS);
return Status;
}

View file

@ -91,6 +91,17 @@ CPortFilterTopology::DeviceIoControl(
PIO_STACK_LOCATION IoStack;
IoStack = IoGetCurrentIrpStackLocation(Irp);
if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY)
{
DPRINT1("Unhandled function %lx Length %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength);
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
PC_ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY);
return PcPropertyHandler(Irp, m_Descriptor);

View file

@ -168,6 +168,19 @@ DECLARE_INTERFACE_(IIrpTarget, IUnknown)
struct IIrpTargetFactory;
typedef struct
{
LIST_ENTRY Entry;
UNICODE_STRING SymbolicLink;
}SYMBOLICLINK_ENTRY, *PSYMBOLICLINK_ENTRY;
typedef struct
{
LIST_ENTRY Entry;
ULONG FromPin;
KSPIN_PHYSICALCONNECTION Connection;
}PHYSICAL_CONNECTION_ENTRY, *PPHYSICAL_CONNECTION_ENTRY;
typedef struct
{
ULONG MaxGlobalInstanceCount;
@ -202,6 +215,9 @@ typedef struct
PPCFILTER_DESCRIPTOR DeviceDescriptor;
KSTOPOLOGY* Topology;
LIST_ENTRY SymbolicLinkList;
LIST_ENTRY PhysicalConnectionList;
UNICODE_STRING RefString;
}SUBDEVICE_DESCRIPTOR, *PSUBDEVICE_DESCRIPTOR;
#undef INTERFACE

View file

@ -174,33 +174,11 @@ PortClsShutdown(
IN PIRP Irp)
{
PPCLASS_DEVICE_EXTENSION DeviceExtension;
PLIST_ENTRY Entry;
PPHYSICAL_CONNECTION Connection;
DPRINT("PortClsShutdown called\n");
// get device extension
DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
while(!IsListEmpty(&DeviceExtension->PhysicalConnectionList))
{
// get connection entry
Entry = RemoveHeadList(&DeviceExtension->PhysicalConnectionList);
Connection = (PPHYSICAL_CONNECTION)CONTAINING_RECORD(Entry, PHYSICAL_CONNECTION, Entry);
if (Connection->FromSubDevice)
{
// release subdevice
Connection->FromSubDevice->Release();
}
if (Connection->ToSubDevice)
{
// release subdevice
Connection->ToSubDevice->Release();
}
FreeItem(Connection, TAG_PORTCLASS);
}
if (DeviceExtension->AdapterPowerManagement)
{
// release adapter power management

View file

@ -25,7 +25,6 @@ public:
STDMETHODIMP_(ULONG) Release()
{
InterlockedDecrement(&m_Ref);
DPRINT1("Release %u\n", m_Ref);
if (!m_Ref)
{
//delete this;

View file

@ -346,32 +346,6 @@ DEFINE_KSPROPERTY_TABLE(PinSet) {\
DEFINE_KSPROPERTY_ITEM_PIN_PROPOSEDATAFORMAT(PropGeneral)\
}
typedef struct
{
LIST_ENTRY Entry;
UNICODE_STRING SymbolicLink;
}SYMBOLICLINK_ENTRY, *PSYMBOLICLINK_ENTRY;
typedef struct
{
LIST_ENTRY Entry;
ISubdevice *SubDevice;
UNICODE_STRING Name;
LIST_ENTRY SymbolicLinkList;
}SUBDEVICE_ENTRY, *PSUBDEVICE_ENTRY;
typedef struct
{
LIST_ENTRY Entry;
ISubdevice * FromSubDevice;
UNICODE_STRING FromUnicodeString;
ULONG FromPin;
ISubdevice * ToSubDevice;
UNICODE_STRING ToUnicodeString;
ULONG ToPin;
}PHYSICAL_CONNECTION, *PPHYSICAL_CONNECTION;
typedef struct
{
KSDEVICE_HEADER KsDeviceHeader;
@ -384,8 +358,6 @@ typedef struct
KSOBJECT_CREATE_ITEM * CreateItems;
IResourceList* resources;
LIST_ENTRY SubDeviceList;
LIST_ENTRY PhysicalConnectionList;
LIST_ENTRY TimerList;
KSPIN_LOCK TimerListLock;

View file

@ -114,6 +114,71 @@ HandleDataIntersection(
return Status;
}
NTSTATUS
HandlePhysicalConnection(
IN PIO_STATUS_BLOCK IoStatus,
IN PKSIDENTIFIER Request,
IN ULONG RequestLength,
IN OUT PVOID Data,
IN ULONG DataLength,
IN PSUBDEVICE_DESCRIPTOR Descriptor)
{
PKSP_PIN Pin;
PLIST_ENTRY Entry;
PKSPIN_PHYSICALCONNECTION Connection;
PPHYSICAL_CONNECTION_ENTRY ConEntry;
// get pin
Pin = (PKSP_PIN)Request;
if (RequestLength < sizeof(KSP_PIN))
{
// input buffer must be at least sizeof KSP_PIN
DPRINT1("input length too small\n");
return STATUS_INVALID_PARAMETER;
}
if (IsListEmpty(&Descriptor->PhysicalConnectionList))
{
DPRINT1("no connection\n");
return STATUS_NOT_FOUND;
}
// get first item
Entry = Descriptor->PhysicalConnectionList.Flink;
do
{
ConEntry = (PPHYSICAL_CONNECTION_ENTRY)CONTAINING_RECORD(Entry, PHYSICAL_CONNECTION_ENTRY, Entry);
if (ConEntry->FromPin == Pin->PinId)
{
Connection = (PKSPIN_PHYSICALCONNECTION)Data;
DPRINT("FoundEntry %S Size %u\n", ConEntry->Connection.SymbolicLinkName, ConEntry->Connection.Size);
IoStatus->Information = ConEntry->Connection.Size;
if (!DataLength)
{
IoStatus->Information = ConEntry->Connection.Size;
return STATUS_MORE_ENTRIES;
}
if (DataLength < ConEntry->Connection.Size)
{
return STATUS_BUFFER_TOO_SMALL;
}
RtlMoveMemory(Data, &ConEntry->Connection, ConEntry->Connection.Size);
return STATUS_SUCCESS;
}
// move to next item
Entry = Entry->Flink;
}while(Entry != &Descriptor->PhysicalConnectionList);
IoStatus->Information = 0;
return STATUS_NOT_FOUND;
}
NTSTATUS
NTAPI
@ -188,6 +253,8 @@ PinPropertyHandler(
Status = HandleDataIntersection(&Irp->IoStatus, Request, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Descriptor, SubDevice);
break;
case KSPROPERTY_PIN_PHYSICALCONNECTION:
Status = HandlePhysicalConnection(&Irp->IoStatus, Request, IoStack->Parameters.DeviceIoControl.InputBufferLength, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Descriptor);
break;
case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
UNIMPLEMENTED
Status = STATUS_NOT_IMPLEMENTED;

View file

@ -165,6 +165,10 @@ PcCreateSubdeviceDescriptor(
if (!Descriptor)
return STATUS_INSUFFICIENT_RESOURCES;
// initialize physical / symbolic link connection list
InitializeListHead(&Descriptor->SymbolicLinkList);
InitializeListHead(&Descriptor->PhysicalConnectionList);
Descriptor->Interfaces = (GUID*)AllocateItem(NonPagedPool, sizeof(GUID) * InterfaceCount, TAG_PORTCLASS);
if (!Descriptor->Interfaces)
goto cleanup;

View file

@ -66,10 +66,9 @@ CUnregisterSubdevice::UnregisterSubdevice(
{
PPCLASS_DEVICE_EXTENSION DeviceExtension;
PLIST_ENTRY Entry;
PSUBDEVICE_ENTRY SubDeviceEntry;
PSYMBOLICLINK_ENTRY SymLinkEntry;
PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
ISubdevice *SubDevice;
ULONG Found;
ULONG Index;
NTSTATUS Status;
@ -93,32 +92,18 @@ CUnregisterSubdevice::UnregisterSubdevice(
return STATUS_INVALID_PARAMETER;
}
Entry = DeviceExtension->SubDeviceList.Flink;
Found = FALSE;
// loop subdevice entry list and search for the subdevice
while(Entry != &DeviceExtension->SubDeviceList)
Status = SubDevice->GetDescriptor(&SubDeviceDescriptor);
if (!NT_SUCCESS(Status))
{
SubDeviceEntry = (PSUBDEVICE_ENTRY)CONTAINING_RECORD(Entry, SUBDEVICE_ENTRY, Entry);
if (SubDeviceEntry->SubDevice == SubDevice)
{
Found = TRUE;
break;
}
Entry = Entry->Flink;
DPRINT1("Failed to retrieve subdevice descriptor %x\n", Status);
// the provided port driver doesnt support ISubdevice
return STATUS_INVALID_PARAMETER;
}
// release the subdevice
SubDevice->Release();
if (!Found)
return STATUS_NOT_FOUND;
// remove subdevice entry
RemoveEntryList(&SubDeviceEntry->Entry);
// loop our create items and disable the create handler
for(Index = 0; Index < DeviceExtension->MaxSubDevices; Index++)
{
if (!RtlCompareUnicodeString(&SubDeviceEntry->Name, &DeviceExtension->CreateItems[Index].ObjectClass, TRUE))
if (!RtlCompareUnicodeString(&SubDeviceDescriptor->RefString, &DeviceExtension->CreateItems[Index].ObjectClass, TRUE))
{
DeviceExtension->CreateItems[Index].Create = NULL;
RtlInitUnicodeString(&DeviceExtension->CreateItems[Index].ObjectClass, NULL);
@ -127,10 +112,10 @@ CUnregisterSubdevice::UnregisterSubdevice(
}
// now unregister device interfaces
while(!IsListEmpty(&SubDeviceEntry->SymbolicLinkList))
while(!IsListEmpty(&SubDeviceDescriptor->SymbolicLinkList))
{
// remove entry
Entry = RemoveHeadList(&SubDeviceEntry->SymbolicLinkList);
Entry = RemoveHeadList(&SubDeviceDescriptor->SymbolicLinkList);
// get symlink entry
SymLinkEntry = (PSYMBOLICLINK_ENTRY)CONTAINING_RECORD(Entry, SYMBOLICLINK_ENTRY, Entry);
@ -142,9 +127,6 @@ CUnregisterSubdevice::UnregisterSubdevice(
FreeItem(SymLinkEntry, TAG_PORTCLASS);
}
// free subdevice entry
ExFreePool(SubDeviceEntry);
return STATUS_SUCCESS;
}