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
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);
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++)
{
// initialize symbolic link item
RtlInitUnicodeString(&SymEntry->SymbolicLink, SymbolicLinkName.Buffer);
// store item
- InsertTailList(&Entry->SymbolicLinkList, &SymEntry->Entry);
+ InsertTailList(&SubDeviceDescriptor->SymbolicLinkList, &SymEntry->Entry);
}
else
{
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
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;
+
+ }
+
+ 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;
}
- InsertTailList(&DeviceExt->PhysicalConnectionList, &NewConnection->Entry);
+ 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 (NewConnection->ToSubDevice)
- NewConnection->ToSubDevice->Release();
+ if (FromSubDevice)
+ FromSubDevice->Release();
- if (NewConnection->FromUnicodeString.Buffer)
- RtlFreeUnicodeString(&NewConnection->FromUnicodeString);
+ if (ToSubDevice)
+ ToSubDevice->Release();
- if (NewConnection->ToUnicodeString.Buffer)
- RtlFreeUnicodeString(&NewConnection->ToUnicodeString);
+ if (FromEntry)
+ FreeItem(FromEntry, TAG_PORTCLASS);
- FreeItem(NewConnection, TAG_PORTCLASS);
+ if (ToEntry)
+ FreeItem(ToEntry, TAG_PORTCLASS);
return Status;
}
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);
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;
PPCFILTER_DESCRIPTOR DeviceDescriptor;
KSTOPOLOGY* Topology;
+ LIST_ENTRY SymbolicLinkList;
+ LIST_ENTRY PhysicalConnectionList;
+ UNICODE_STRING RefString;
}SUBDEVICE_DESCRIPTOR, *PSUBDEVICE_DESCRIPTOR;
#undef INTERFACE
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
STDMETHODIMP_(ULONG) Release()
{
InterlockedDecrement(&m_Ref);
- DPRINT1("Release %u\n", m_Ref);
if (!m_Ref)
{
//delete this;
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;
KSOBJECT_CREATE_ITEM * CreateItems;
IResourceList* resources;
- LIST_ENTRY SubDeviceList;
- LIST_ENTRY PhysicalConnectionList;
LIST_ENTRY TimerList;
KSPIN_LOCK TimerListLock;
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
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;
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;
{
PPCLASS_DEVICE_EXTENSION DeviceExtension;
PLIST_ENTRY Entry;
- PSUBDEVICE_ENTRY SubDeviceEntry;
PSYMBOLICLINK_ENTRY SymLinkEntry;
+ PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
ISubdevice *SubDevice;
- ULONG Found;
ULONG Index;
NTSTATUS Status;
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);
}
// 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);
FreeItem(SymLinkEntry, TAG_PORTCLASS);
}
- // free subdevice entry
- ExFreePool(SubDeviceEntry);
-
return STATUS_SUCCESS;
}