- Add KSPROPSETID_Audio guid

- Allocate data format after successful initialization of IPinWaveCyclic
- Store Miniport Adapter in subdevice descriptor
- Implement GUID_NULL handler for topology nodes 
- Implement setting / retrieving properties for topology nodes

svn path=/trunk/; revision=43258
This commit is contained in:
Johannes Anderwald
2009-10-02 21:55:53 +00:00
parent 58df56f2c5
commit f187acf5ef
6 changed files with 184 additions and 9 deletions
@@ -82,6 +82,7 @@ const GUID KSPROPTYPESETID_General = {0x97E99BA0L, 0xBDEA, 0x11CF, {
const GUID IID_IAllocatorMXF = {0xa5f0d62cL, 0xb30f, 0x11d2, {0xb7, 0xa3, 0x00, 0x60, 0x08, 0x33, 0x16, 0xc1}};
const GUID KSPROPSETID_Audio = {0x45FFAAA0L, 0x6E1B, 0x11D0, {0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}};
///
/// undocumented guids
@@ -161,6 +161,8 @@ DECLARE_INTERFACE_(IIrpTarget, IUnknown)
DEFINE_ABSTRACT_IRPTARGET()
};
typedef IIrpTarget *PIRPTARGET;
/*****************************************************************************
* ISubdevice
*****************************************************************************
@@ -212,6 +214,7 @@ typedef struct
LIST_ENTRY SymbolicLinkList;
LIST_ENTRY PhysicalConnectionList;
UNICODE_STRING RefString;
PUNKNOWN UnknownMiniport;
}SUBDEVICE_DESCRIPTOR, *PSUBDEVICE_DESCRIPTOR;
#undef INTERFACE
@@ -913,12 +913,6 @@ CPortPinWaveCyclic::Init(
DPRINT("CPortPinWaveCyclic::Init entered Size %u\n", DataFormat->FormatSize);
m_Format = (PKSDATAFORMAT)ExAllocatePoolWithTag(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS);
if (!m_Format)
return STATUS_INSUFFICIENT_RESOURCES;
RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize);
Status = NewIrpQueue(&m_IrpQueue);
if (!NT_SUCCESS(Status))
return Status;
@@ -943,7 +937,7 @@ CPortPinWaveCyclic::Init(
NonPagedPool,
ConnectDetails->PinId,
Capture,
m_Format,
DataFormat,
&m_DmaChannel,
&m_ServiceGroup);
#if 0
@@ -999,6 +993,13 @@ CPortPinWaveCyclic::Init(
return Status;
}
m_Format = (PKSDATAFORMAT)ExAllocatePoolWithTag(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS);
if (!m_Format)
return STATUS_INSUFFICIENT_RESOURCES;
RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize);
Port->AddRef();
Filter->AddRef();
@@ -273,6 +273,12 @@ CPortTopology::Init(
DPRINT("IPortTopology_fnInit success\n");
if (NT_SUCCESS(Status))
{
// store for node property requests
m_SubDeviceDescriptor->UnknownMiniport = UnknownMiniport;
}
return STATUS_SUCCESS;
}
@@ -455,7 +461,7 @@ CreatePinWorkerRoutine(
DPRINT("CreatePinWorkerRoutine called\n");
// create the pin
Status = WorkerContext->Filter->NewIrpTarget(&Pin,
NULL,
KSSTRING_Pin,
NULL,
NonPagedPool,
DeviceObject,
@@ -298,6 +298,9 @@ CPortWaveCyclic::Init(
return Status;
}
// store for node property requests
m_SubDeviceDescriptor->UnknownMiniport = UnknownMiniport;
// check if it supports IPinCount interface
Status = UnknownMiniport->QueryInterface(IID_IPinCount, (PVOID*)&PinCount);
if (NT_SUCCESS(Status))
@@ -51,8 +51,133 @@ PcHandlePropertyWithTable(
IN PKSPROPERTY_SET PropertySet,
IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)
{
NTSTATUS Status;
PIO_STACK_LOCATION IoStack;
PKSP_NODE Property;
PPCNODE_DESCRIPTOR Node;
PPCPROPERTY_ITEM PropertyItem;
ULONG Index;
LPGUID Buffer;
//PULONG Flags;
PPCPROPERTY_REQUEST PropertyRequest;
KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor;
return KsPropertyHandler(Irp, PropertySetCount, PropertySet);
/* try first KsPropertyHandler */
Status = KsPropertyHandler(Irp, PropertySetCount, PropertySet);
// get current irp stack location
IoStack = IoGetCurrentIrpStackLocation(Irp);
// access property
Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
// check if this a GUID_NULL request
if (Status == STATUS_NOT_FOUND)
{
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_NODE))
return Status;
// check if its a request for a topology node
if (IsEqualGUIDAligned(Property->Property.Set, GUID_NULL) && Property->Property.Id == 0 && Property->Property.Flags == (KSPROPERTY_TYPE_SETSUPPORT | KSPROPERTY_TYPE_TOPOLOGY))
{
if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount)
{
// request is out of bounds
Irp->IoStatus.Information = 0;
return STATUS_INVALID_PARAMETER;
}
Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize));
PC_ASSERT(Node->AutomationTable);
PC_ASSERT(Node->AutomationTable->PropertyCount);
PC_ASSERT(Node->AutomationTable->PropertyItemSize);
Irp->IoStatus.Information = sizeof(GUID) * Node->AutomationTable->PropertyCount;
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GUID) * Node->AutomationTable->PropertyCount)
{
// buffer too small
return STATUS_MORE_ENTRIES;
}
PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties;
Buffer = (LPGUID)Irp->UserBuffer;
for(Index = 0; Index < Node->AutomationTable->PropertyCount; Index++)
{
RtlMoveMemory(Buffer, PropertyItem->Set, sizeof(GUID));
Buffer++;
PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize);
}
return STATUS_SUCCESS;
}
else /*if (Property->Property.Flags == (KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_TOPOLOGY) ||
Property->Property.Flags == (KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY) ||
Property->Property.Flags == (KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY)) */
{
if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount)
{
// request is out of bounds
Irp->IoStatus.Information = 0;
return STATUS_INVALID_PARAMETER;
}
Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize));
PC_ASSERT(Node->AutomationTable);
PC_ASSERT(Node->AutomationTable->PropertyCount);
PC_ASSERT(Node->AutomationTable->PropertyItemSize);
PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties;
//Flags = (PULONG)Irp->UserBuffer;
for(Index = 0; Index < Node->AutomationTable->PropertyCount; Index++)
{
if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Property.Set) && PropertyItem->Id == Property->Property.Id)
{
PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS);
if (!PropertyRequest)
return STATUS_INSUFFICIENT_RESOURCES;
PC_ASSERT(SubDeviceDescriptor->UnknownMiniport);
PropertyRequest->MajorTarget = SubDeviceDescriptor->UnknownMiniport;
//PropertyRequest->MinorTarget = (PUNKNOWN)0xABADCAFE;
PropertyRequest->Irp = Irp;
PropertyRequest->Node = Property->NodeId;
PropertyRequest->PropertyItem = PropertyItem;
PropertyRequest->Verb = Property->Property.Flags;
PropertyRequest->InstanceSize = IoStack->Parameters.DeviceIoControl.InputBufferLength - sizeof(KSNODEPROPERTY);
PropertyRequest->Instance = (PVOID)((ULONG_PTR)IoStack->Parameters.DeviceIoControl.Type3InputBuffer + sizeof(KSNODEPROPERTY));
PropertyRequest->ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
PropertyRequest->Value = Irp->UserBuffer;
Status = PropertyItem->Handler(PropertyRequest);
if (Status != STATUS_PENDING)
{
//DPRINT1("Status %x ValueSize %u
Irp->IoStatus.Information = PropertyRequest->ValueSize;
ExFreePool(PropertyRequest);
}
return Status;
}
PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize);
}
}
#if 0
else
{
UNICODE_STRING GuidString;
RtlStringFromGUID(Property->Property.Set, &GuidString);
DPRINT1("Id %u Flags %x Set %S\n", Property->Property.Id, Property->Property.Flags, GuidString.Buffer);
DbgBreakPoint();
}
#endif
}
return Status;
}
VOID
@@ -104,6 +229,39 @@ PcCaptureFormat(
return STATUS_NOT_IMPLEMENTED;
}
VOID
DumpFilterDescriptor(
IN PPCFILTER_DESCRIPTOR FilterDescription)
{
ULONG Index;
PPCPROPERTY_ITEM PropertyItem;
UNICODE_STRING GuidString;
DPRINT1("======================\n");
DPRINT1("Descriptor Automation Table%p\n",FilterDescription->AutomationTable);
if (FilterDescription->AutomationTable)
{
DPRINT1("FilterPropertiesCount %u FilterPropertySize %u Expected %u\n", FilterDescription->AutomationTable->PropertyCount, FilterDescription->AutomationTable->PropertyItemSize, sizeof(PCPROPERTY_ITEM));
if (FilterDescription->AutomationTable->PropertyCount)
{
PropertyItem = (PPCPROPERTY_ITEM)FilterDescription->AutomationTable->Properties;
for(Index = 0; Index < FilterDescription->AutomationTable->PropertyCount; Index++)
{
RtlStringFromGUID(*PropertyItem->Set, &GuidString);
DPRINT1("Index %u GUID %S Id %u Flags %x\n", Index, GuidString.Buffer, PropertyItem->Id, PropertyItem->Flags);
PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + FilterDescription->AutomationTable->PropertyItemSize);
}
}
}
DPRINT1("======================\n");
DbgBreakPoint();
}
NTSTATUS
NTAPI
PcCreateSubdeviceDescriptor(
@@ -147,6 +305,9 @@ PcCreateSubdeviceDescriptor(
{
/// FIXME
/// handle driver properties
//DumpFilterDescriptor(FilterDescription);
Descriptor->FilterPropertySet = (PKSPROPERTY_SET)AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * FilterPropertiesCount, TAG_PORTCLASS);
if (! Descriptor->FilterPropertySet)
goto cleanup;