2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/api.cpp
5 * PURPOSE: Port api functions
6 * PROGRAMMER: Johannes Anderwald
13 KsoDispatchCreateWithGenericFactory(
18 return STATUS_NOT_IMPLEMENTED
;
23 KsoGetIrpTargetFromFileObject(
24 PFILE_OBJECT FileObject
)
26 PC_ASSERT(FileObject
);
28 // IrpTarget is stored in FsContext
29 return (IIrpTarget
*)FileObject
->FsContext
;
34 KsoGetIrpTargetFromIrp(
37 PIO_STACK_LOCATION IoStack
;
39 // get current irp stack location
40 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
42 // IIrpTarget is stored in Context member
43 return (IIrpTarget
*)IoStack
->FileObject
->FsContext
;
48 PcHandleEnableEventWithTable(
50 IN PSUBDEVICE_DESCRIPTOR Descriptor
)
53 KSEVENT_ITEM_IRP_STORAGE(Irp
) = (PKSEVENT_ITEM
)Descriptor
;
56 return KsEnableEvent(Irp
, Descriptor
->EventSetCount
, Descriptor
->EventSet
, NULL
, KSEVENTS_NONE
, NULL
);
61 PcHandleDisableEventWithTable(
63 IN PSUBDEVICE_DESCRIPTOR Descriptor
)
66 KSEVENT_ITEM_IRP_STORAGE(Irp
) = (PKSEVENT_ITEM
)Descriptor
;
70 return KsDisableEvent(Irp
, Descriptor
->EventList
, KSEVENTS_SPINLOCK
, (PVOID
)Descriptor
->EventListLock
);
75 PcHandlePropertyWithTable(
77 IN ULONG PropertySetCount
,
78 IN PKSPROPERTY_SET PropertySet
,
79 IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor
)
81 PIO_STACK_LOCATION IoStack
;
83 // get current irp stack location
84 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
86 if (IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(KSPROPERTY
))
88 // certainly an invalid request
89 return STATUS_INVALID_PARAMETER
;
92 // store device descriptor
93 KSPROPERTY_ITEM_IRP_STORAGE(Irp
) = (PKSPROPERTY_ITEM
)SubDeviceDescriptor
;
95 // then try KsPropertyHandler
96 return KsPropertyHandler(Irp
, PropertySetCount
, PropertySet
);
101 PcAcquireFormatResources(
122 return STATUS_NOT_IMPLEMENTED
;
127 PropertyItemDispatch(
129 IN PKSIDENTIFIER Request
,
132 PPCPROPERTY_REQUEST PropertyRequest
;
133 PSUBDEVICE_DESCRIPTOR Descriptor
;
134 PKSPROPERTY Property
;
135 PPCNODE_DESCRIPTOR NodeDescriptor
;
136 PKSNODEPROPERTY NodeProperty
;
137 PKSPROPERTY_SET PropertySet
;
138 PPCPROPERTY_ITEM PropertyItem
;
139 PPCAUTOMATION_TABLE NodeAutomation
;
140 PIO_STACK_LOCATION IoStack
;
141 ULONG InstanceSize
, ValueSize
, Index
;
145 // allocate a property request
146 PropertyRequest
= (PPCPROPERTY_REQUEST
)AllocateItem(NonPagedPool
, sizeof(PCPROPERTY_REQUEST
), TAG_PORTCLASS
);
147 if (!PropertyRequest
)
148 return STATUS_INSUFFICIENT_RESOURCES
;
150 // grab device descriptor
151 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
153 // get current irp stack
154 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
156 // get input property request
157 Property
= (PKSPROPERTY
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
160 PropertySet
= (PKSPROPERTY_SET
)KSPROPERTY_SET_IRP_STORAGE(Irp
);
163 PC_ASSERT(Descriptor
);
164 PC_ASSERT(Descriptor
->UnknownMiniport
);
166 // get instance / value size
167 InstanceSize
= IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
;
169 ValueSize
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
171 // initialize property request
172 PropertyRequest
->MajorTarget
= Descriptor
->UnknownMiniport
;
173 PropertyRequest
->MinorTarget
= Descriptor
->UnknownStream
;
174 PropertyRequest
->Irp
= Irp
;
175 PropertyRequest
->Verb
= Property
->Flags
;
178 // check if this is filter / pin property request
179 if (!(Property
->Flags
& KSPROPERTY_TYPE_TOPOLOGY
))
181 // adjust input buffer size
182 InstanceSize
-= sizeof(KSPROPERTY
);
183 Instance
= (PVOID
)((ULONG_PTR
)Instance
+ sizeof(KSPROPERTY
));
185 // filter / pin property request dont use node field
186 PropertyRequest
->Node
= MAXULONG
;
188 else if (InstanceSize
>= sizeof(KSNODEPROPERTY
))
190 // request is for a node
191 InstanceSize
-= sizeof(KSNODEPROPERTY
);
192 Instance
= (PVOID
)((ULONG_PTR
)Instance
+ sizeof(KSNODEPROPERTY
));
194 // cast node property request
195 NodeProperty
= (PKSNODEPROPERTY
)Request
;
198 PropertyRequest
->Node
= NodeProperty
->NodeId
;
202 // invalid buffer size
203 return STATUS_INVALID_BUFFER_SIZE
;
206 // store instance size
207 PropertyRequest
->InstanceSize
= InstanceSize
;
208 PropertyRequest
->Instance
= (InstanceSize
!= 0 ? Instance
: NULL
);
211 PropertyRequest
->ValueSize
= ValueSize
;
212 PropertyRequest
->Value
= (ValueSize
!= 0 ? Irp
->UserBuffer
: NULL
);
214 // now scan the property set for the attached property set item stored in Relations member
218 PC_ASSERT(IsEqualGUIDAligned(Property
->Set
, *PropertySet
->Set
));
220 for(Index
= 0; Index
< PropertySet
->PropertiesCount
; Index
++)
222 // check if they got the same property id
223 if (PropertySet
->PropertyItem
[Index
].PropertyId
== Property
->Id
)
226 PropertyRequest
->PropertyItem
= (const PCPROPERTY_ITEM
*)PropertySet
->PropertyItem
[Index
].Relations
;
234 // check if there has been a property set item attached
235 if (!PropertyRequest
->PropertyItem
)
237 // is topology node id valid
238 if (PropertyRequest
->Node
< Descriptor
->DeviceDescriptor
->NodeCount
)
240 // get node descriptor
241 NodeDescriptor
= (PPCNODE_DESCRIPTOR
) ((ULONG_PTR
)Descriptor
->DeviceDescriptor
->Nodes
+ PropertyRequest
->Node
* Descriptor
->DeviceDescriptor
->NodeSize
);
243 // get node automation table
244 NodeAutomation
= (PPCAUTOMATION_TABLE
)NodeDescriptor
->AutomationTable
;
246 // has it got a automation table
249 // now scan the properties and check if it supports this request
250 PropertyItem
= (PPCPROPERTY_ITEM
)NodeAutomation
->Properties
;
251 for(Index
= 0; Index
< NodeAutomation
->PropertyCount
; Index
++)
253 // are they same property
254 if (IsEqualGUIDAligned(*PropertyItem
->Set
, Property
->Set
))
256 if (PropertyItem
->Id
== Property
->Id
)
259 PropertyRequest
->PropertyItem
= PropertyItem
;
266 // move to next property item
267 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ NodeAutomation
->PropertyItemSize
);
273 if (PropertyRequest
->PropertyItem
&& PropertyRequest
->PropertyItem
->Handler
)
275 // now call the handler
276 UNICODE_STRING GuidBuffer
;
277 RtlStringFromGUID(Property
->Set
, &GuidBuffer
);
278 DPRINT1("Calling Node %lu MajorTarget %p MinorTarget %p PropertySet %S PropertyId %lu PropertyFlags %lx InstanceSize %lu ValueSize %lu Handler %p PropertyRequest %p PropertyItemFlags %lx PropertyItemId %lu\n",
279 PropertyRequest
->Node
, PropertyRequest
->MajorTarget
, PropertyRequest
->MinorTarget
, GuidBuffer
.Buffer
, Property
->Id
, Property
->Flags
, PropertyRequest
->InstanceSize
, PropertyRequest
->ValueSize
,
280 PropertyRequest
->PropertyItem
->Handler
, PropertyRequest
, PropertyRequest
->PropertyItem
->Flags
, PropertyRequest
->PropertyItem
->Id
);
282 Status
= PropertyRequest
->PropertyItem
->Handler(PropertyRequest
);
283 DPRINT1("Status %lx ValueSize %lu Information %lu\n", Status
, PropertyRequest
->ValueSize
, Irp
->IoStatus
.Information
);
285 Status
= STATUS_NOT_FOUND
;
287 Irp
->IoStatus
.Information
= PropertyRequest
->ValueSize
;
289 if (Status
!= STATUS_PENDING
)
291 // free property request
292 FreeItem(PropertyRequest
, TAG_PORTCLASS
);
297 FreeItem(PropertyRequest
, TAG_PORTCLASS
);
298 Status
= STATUS_NOT_FOUND
;
306 PcAddToPropertyTable(
307 IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor
,
308 IN PPCPROPERTY_ITEM PropertyItem
,
311 ULONG bFound
= FALSE
;
312 ULONG Index
, PropertySetIndex
, PropertySetItemIndex
;
313 PKSPROPERTY_SET NewPropertySet
;
314 PKSPROPERTY_ITEM FilterPropertyItem
, NewFilterPropertyItem
;
316 //UNICODE_STRING GuidBuffer;
318 ASSERT(PropertyItem
->Set
);
319 // RtlStringFromGUID(*PropertyItem->Set, &GuidBuffer);
320 // DPRINT1("PcAddToPropertyTable Adding Item Set %S Id %lu Flags %lx\n", GuidBuffer.Buffer, PropertyItem->Id, PropertyItem->Flags);
324 //DPRINT1("FilterPropertySetCount %lu\n", SubDeviceDescriptor->FilterPropertySetCount);
325 // first step check if the property set is present already
326 for(Index
= 0; Index
< SubDeviceDescriptor
->FilterPropertySetCount
; Index
++)
329 //RtlStringFromGUID(*SubDeviceDescriptor->FilterPropertySet[Index].Set, &GuidBuffer);
330 //DPRINT1("FilterProperty Set %S PropertyCount %lu\n", GuidBuffer.Buffer, SubDeviceDescriptor->FilterPropertySet[Index].PropertiesCount);
331 if (IsEqualGUIDAligned(*SubDeviceDescriptor
->FilterPropertySet
[Index
].Set
, *PropertyItem
->Set
))
333 // property set is already present
335 PropertySetIndex
= Index
;
342 // is the property set present
345 // need to allocate a property set
346 NewPropertySet
= (PKSPROPERTY_SET
)AllocateItem(NonPagedPool
, (SubDeviceDescriptor
->FilterPropertySetCount
+ 1) * sizeof(KSPROPERTY_SET
), TAG_PORTCLASS
);
350 return STATUS_INSUFFICIENT_RESOURCES
;
353 // need to allocate property set guid
354 Guid
= (LPGUID
)AllocateItem(NonPagedPool
, sizeof(GUID
), TAG_PORTCLASS
);
358 FreeItem(NewPropertySet
, TAG_PORTCLASS
);
359 return STATUS_INSUFFICIENT_RESOURCES
;
362 // are any existing property sets
363 if (SubDeviceDescriptor
->FilterPropertySetCount
)
365 // copy property sets
366 RtlMoveMemory(NewPropertySet
, SubDeviceDescriptor
->FilterPropertySet
, SubDeviceDescriptor
->FilterPropertySetCount
* sizeof(KSPROPERTY_SET
));
369 FreeItem(SubDeviceDescriptor
->FilterPropertySet
, TAG_PORTCLASS
);
372 // store new property set descriptors
373 SubDeviceDescriptor
->FilterPropertySet
= NewPropertySet
;
376 PropertySetIndex
= SubDeviceDescriptor
->FilterPropertySetCount
;
378 // increment property set count
379 SubDeviceDescriptor
->FilterPropertySetCount
++;
381 // copy property guid
382 RtlMoveMemory(Guid
, PropertyItem
->Set
, sizeof(GUID
));
384 // initialize property set
385 SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].Set
= Guid
;
386 SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
= 0;
389 // as the property set has been indentified, now search for duplicate property set item entries
390 FilterPropertyItem
= (PKSPROPERTY_ITEM
)SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
;
393 for(Index
= 0; Index
< SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
; Index
++)
395 // now search for an equal property set item
396 if (FilterPropertyItem
->PropertyId
== PropertyItem
->Id
)
398 // found existing property set item
400 PropertySetItemIndex
= Index
;
404 // move to next entry
405 FilterPropertyItem
++;
410 // need to allocate memory for new property set item
411 NewFilterPropertyItem
= (PKSPROPERTY_ITEM
)AllocateItem(NonPagedPool
, (SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
+ 1) * sizeof(KSPROPERTY_ITEM
), TAG_PORTCLASS
);
412 if (!NewFilterPropertyItem
)
415 return STATUS_INSUFFICIENT_RESOURCES
;
418 // are any existing property set items
419 if (SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
)
421 // copy property item sets
422 RtlMoveMemory(NewFilterPropertyItem
,
423 (PVOID
)SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
,
424 SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
* sizeof(KSPROPERTY_ITEM
));
426 // release old descriptors
427 FreeItem((PVOID
)SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
, TAG_PORTCLASS
);
430 // store new descriptor
431 SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
= NewFilterPropertyItem
;
434 PropertySetItemIndex
= SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
;
436 // increment property item set count
437 SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
++;
439 // now initialize property item
440 FilterPropertyItem
= (PKSPROPERTY_ITEM
)&SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
[PropertySetItemIndex
];
441 FilterPropertyItem
->PropertyId
= PropertyItem
->Id
;
442 FilterPropertyItem
->MinProperty
= sizeof(KSPROPERTY
);
443 FilterPropertyItem
->MinData
= 0;
445 // are any set operations supported
446 if (PropertyItem
->Flags
& PCPROPERTY_ITEM_FLAG_SET
)
449 FilterPropertyItem
->SetPropertyHandler
= PropertyItemDispatch
;
452 // are set operation supported
453 if (PropertyItem
->Flags
& PCPROPERTY_ITEM_FLAG_GET
)
456 FilterPropertyItem
->GetPropertyHandler
= PropertyItemDispatch
;
459 // are get operations supported
460 if (PropertyItem
->Flags
& PCPROPERTY_ITEM_FLAG_GET
)
463 FilterPropertyItem
->GetPropertyHandler
= PropertyItemDispatch
;
466 // are basic support operations supported
467 if (PropertyItem
->Flags
& PCPROPERTY_ITEM_FLAG_BASICSUPPORT
)
470 FilterPropertyItem
->SupportHandler
= PropertyItemDispatch
;
475 // store property item in relations
476 // only store property item of filter properties / pin properties
477 // because filter & pin properties do not require a specific context
478 // on the other hand node properties are specifically bound to a node
480 FilterPropertyItem
->Relations
= (const KSPROPERTY
*)PropertyItem
;
485 // property set item handler already present
489 // filter & pin properties should not be exposed on a node
490 ASSERT(SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
[PropertySetItemIndex
].Relations
== NULL
);
494 // node properties should not be exposed on a filter & pin
495 ASSERT(SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
[PropertySetItemIndex
].Relations
!= NULL
);
500 return STATUS_SUCCESS
;
511 return STATUS_NOT_IMPLEMENTED
;
515 DumpFilterDescriptor(
516 IN PPCFILTER_DESCRIPTOR FilterDescription
)
518 ULONG Index
, SubIndex
;
519 PPCPROPERTY_ITEM PropertyItem
;
520 PPCEVENT_ITEM EventItem
;
521 PPCNODE_DESCRIPTOR NodeDescriptor
;
522 UNICODE_STRING GuidString
;
526 DPRINT("======================\n");
527 DPRINT("Descriptor Automation Table %p\n",FilterDescription
->AutomationTable
);
529 if (FilterDescription
->AutomationTable
)
531 DPRINT("FilterPropertiesCount %u FilterPropertySize %u Expected %u Events %u EventItemSize %u expected %u\n", FilterDescription
->AutomationTable
->PropertyCount
, FilterDescription
->AutomationTable
->PropertyItemSize
, sizeof(PCPROPERTY_ITEM
),
532 FilterDescription
->AutomationTable
->EventCount
, FilterDescription
->AutomationTable
->EventItemSize
, sizeof(PCEVENT_ITEM
));
533 if (FilterDescription
->AutomationTable
->PropertyCount
)
535 PropertyItem
= (PPCPROPERTY_ITEM
)FilterDescription
->AutomationTable
->Properties
;
537 for(Index
= 0; Index
< FilterDescription
->AutomationTable
->PropertyCount
; Index
++)
539 RtlStringFromGUID(*PropertyItem
->Set
, &GuidString
);
540 DPRINT("Property Index %u GUID %S Id %u Flags %x\n", Index
, GuidString
.Buffer
, PropertyItem
->Id
, PropertyItem
->Flags
);
542 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ FilterDescription
->AutomationTable
->PropertyItemSize
);
545 EventItem
= (PPCEVENT_ITEM
)FilterDescription
->AutomationTable
->Events
;
546 for(Index
= 0; Index
< FilterDescription
->AutomationTable
->EventCount
; Index
++)
548 RtlStringFromGUID(*EventItem
->Set
, &GuidString
);
549 DPRINT("EventIndex %u GUID %S Id %u Flags %x\n", Index
, GuidString
.Buffer
, EventItem
->Id
, EventItem
->Flags
);
551 EventItem
= (PPCEVENT_ITEM
)((ULONG_PTR
)EventItem
+ FilterDescription
->AutomationTable
->EventItemSize
);
557 if (FilterDescription
->Nodes
)
559 DPRINT("NodeCount %u NodeSize %u expected %u\n", FilterDescription
->NodeCount
, FilterDescription
->NodeSize
, sizeof(PCNODE_DESCRIPTOR
));
560 NodeDescriptor
= (PPCNODE_DESCRIPTOR
)FilterDescription
->Nodes
;
561 for(Index
= 0; Index
< FilterDescription
->NodeCount
; Index
++)
563 DPRINT("Index %u AutomationTable %p\n", Index
, NodeDescriptor
->AutomationTable
);
565 if (NodeDescriptor
->AutomationTable
)
567 DPRINT(" Index %u EventCount %u\n", Index
, NodeDescriptor
->AutomationTable
->EventCount
);
568 EventItem
= (PPCEVENT_ITEM
)NodeDescriptor
->AutomationTable
->Events
;
569 for(SubIndex
= 0; SubIndex
< NodeDescriptor
->AutomationTable
->EventCount
; SubIndex
++)
571 RtlStringFromGUID(*EventItem
->Set
, &GuidString
);
572 DPRINT(" EventIndex %u GUID %S Id %u Flags %x\n", SubIndex
, GuidString
.Buffer
, EventItem
->Id
, EventItem
->Flags
);
574 EventItem
= (PPCEVENT_ITEM
)((ULONG_PTR
)EventItem
+ NodeDescriptor
->AutomationTable
->EventItemSize
);
577 DPRINT1(" Index %u PropertyCount %u\n", Index
, NodeDescriptor
->AutomationTable
->PropertyCount
);
578 PropertyItem
= (PPCPROPERTY_ITEM
)NodeDescriptor
->AutomationTable
->Properties
;
579 for(SubIndex
= 0; SubIndex
< NodeDescriptor
->AutomationTable
->PropertyCount
; SubIndex
++)
581 RtlStringFromGUID(*PropertyItem
->Set
, &GuidString
);
582 DPRINT1(" PropertyIndex %u GUID %S Id %u Flags %x\n", SubIndex
, GuidString
.Buffer
, PropertyItem
->Id
, PropertyItem
->Flags
);
584 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ NodeDescriptor
->AutomationTable
->PropertyItemSize
);
589 NodeDescriptor
= (PPCNODE_DESCRIPTOR
)((ULONG_PTR
)NodeDescriptor
+ FilterDescription
->NodeSize
);
596 DPRINT("ConnectionCount: %lu\n", FilterDescription
->ConnectionCount
);
598 if (FilterDescription
->ConnectionCount
)
600 DPRINT("------ Start of Nodes Connections ----------------\n");
601 for(Index
= 0; Index
< FilterDescription
->ConnectionCount
; Index
++)
603 DPRINT1("Index %ld FromPin %ld FromNode %ld -> ToPin %ld ToNode %ld\n", Index
,
604 FilterDescription
->Connections
[Index
].FromNodePin
,
605 FilterDescription
->Connections
[Index
].FromNode
,
606 FilterDescription
->Connections
[Index
].ToNodePin
,
607 FilterDescription
->Connections
[Index
].ToNode
);
609 DPRINT("------ End of Nodes Connections----------------\n");
612 DPRINT1("======================\n");
617 PcCreateSubdeviceDescriptor(
618 OUT SUBDEVICE_DESCRIPTOR
** OutSubdeviceDescriptor
,
619 IN ULONG InterfaceCount
,
620 IN GUID
* InterfaceGuids
,
621 IN ULONG IdentifierCount
,
622 IN KSIDENTIFIER
*Identifier
,
623 IN ULONG FilterPropertiesCount
,
624 IN KSPROPERTY_SET
* FilterProperties
,
627 IN ULONG PinPropertiesCount
,
628 IN KSPROPERTY_SET
* PinProperties
,
629 IN ULONG EventSetCount
,
630 IN KSEVENT_SET
* EventSet
,
631 IN PPCFILTER_DESCRIPTOR FilterDescription
)
633 SUBDEVICE_DESCRIPTOR
* Descriptor
;
634 ULONG Index
, SubIndex
;
635 NTSTATUS Status
= STATUS_INSUFFICIENT_RESOURCES
;
636 PPCPIN_DESCRIPTOR SrcDescriptor
;
637 PPCNODE_DESCRIPTOR NodeDescriptor
;
638 PPCPROPERTY_ITEM PropertyItem
;
640 // allocate subdevice descriptor
641 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)AllocateItem(NonPagedPool
, sizeof(SUBDEVICE_DESCRIPTOR
), TAG_PORTCLASS
);
643 return STATUS_INSUFFICIENT_RESOURCES
;
645 // initialize physical / symbolic link connection list
646 InitializeListHead(&Descriptor
->SymbolicLinkList
);
647 InitializeListHead(&Descriptor
->PhysicalConnectionList
);
649 //FIXME add driver category guids
650 Descriptor
->Interfaces
= (GUID
*)AllocateItem(NonPagedPool
, sizeof(GUID
) * InterfaceCount
, TAG_PORTCLASS
);
651 if (!Descriptor
->Interfaces
)
654 // copy interface guids
655 RtlCopyMemory(Descriptor
->Interfaces
, InterfaceGuids
, sizeof(GUID
) * InterfaceCount
);
656 Descriptor
->InterfaceCount
= InterfaceCount
;
658 //DumpFilterDescriptor(FilterDescription);
660 // are any property sets supported by the portcls
661 if (FilterPropertiesCount
)
663 // first allocate filter properties set
664 Descriptor
->FilterPropertySet
= (PKSPROPERTY_SET
)AllocateItem(NonPagedPool
, sizeof(KSPROPERTY_SET
) * FilterPropertiesCount
, TAG_PORTCLASS
);
665 if (! Descriptor
->FilterPropertySet
)
668 // now copy all filter property sets
669 Descriptor
->FilterPropertySetCount
= FilterPropertiesCount
;
670 for(Index
= 0; Index
< FilterPropertiesCount
; Index
++)
673 RtlMoveMemory(&Descriptor
->FilterPropertySet
[Index
], &FilterProperties
[Index
], sizeof(KSPROPERTY_SET
));
675 if (Descriptor
->FilterPropertySet
[Index
].PropertiesCount
)
677 // copy property items to make sure they are dynamically allocated
678 Descriptor
->FilterPropertySet
[Index
].PropertyItem
= (PKSPROPERTY_ITEM
)AllocateItem(NonPagedPool
, FilterProperties
[Index
].PropertiesCount
* sizeof(KSPROPERTY_ITEM
), TAG_PORTCLASS
);
679 if (!Descriptor
->FilterPropertySet
[Index
].PropertyItem
)
685 // copy filter property items
686 RtlMoveMemory((PVOID
)Descriptor
->FilterPropertySet
[Index
].PropertyItem
, FilterProperties
[Index
].PropertyItem
, FilterProperties
[Index
].PropertiesCount
* sizeof(KSPROPERTY_ITEM
));
691 // now check if the filter descriptor supports filter properties
692 if (FilterDescription
->AutomationTable
)
695 PropertyItem
= (PPCPROPERTY_ITEM
)FilterDescription
->AutomationTable
->Properties
;
697 // copy driver filter property sets
698 for(Index
= 0; Index
< FilterDescription
->AutomationTable
->PropertyCount
; Index
++)
700 // add the property item
701 Status
= PcAddToPropertyTable(Descriptor
, PropertyItem
, FALSE
);
704 if (Status
!= STATUS_SUCCESS
)
710 // move to next entry
711 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ FilterDescription
->AutomationTable
->PropertyItemSize
);
715 // check if the filter has pins
716 if (FilterDescription
->PinCount
)
718 // allocate pin factory descriptors
719 Descriptor
->Factory
.KsPinDescriptor
= (PKSPIN_DESCRIPTOR
)AllocateItem(NonPagedPool
, sizeof(KSPIN_DESCRIPTOR
) * FilterDescription
->PinCount
, TAG_PORTCLASS
);
720 if (!Descriptor
->Factory
.KsPinDescriptor
)
723 // allocate pin instance info
724 Descriptor
->Factory
.Instances
= (PPIN_INSTANCE_INFO
)AllocateItem(NonPagedPool
, FilterDescription
->PinCount
* sizeof(PIN_INSTANCE_INFO
), TAG_PORTCLASS
);
725 if (!Descriptor
->Factory
.Instances
)
728 // initialize pin factory descriptor
729 Descriptor
->Factory
.PinDescriptorCount
= FilterDescription
->PinCount
;
730 Descriptor
->Factory
.PinDescriptorSize
= sizeof(KSPIN_DESCRIPTOR
);
733 SrcDescriptor
= (PPCPIN_DESCRIPTOR
)FilterDescription
->Pins
;
735 // copy pin factories
736 for(Index
= 0; Index
< FilterDescription
->PinCount
; Index
++)
738 // copy pin descriptor
739 RtlMoveMemory(&Descriptor
->Factory
.KsPinDescriptor
[Index
], &SrcDescriptor
->KsPinDescriptor
, sizeof(KSPIN_DESCRIPTOR
));
741 // initialize pin factory instance data
742 Descriptor
->Factory
.Instances
[Index
].CurrentPinInstanceCount
= 0;
743 Descriptor
->Factory
.Instances
[Index
].MaxFilterInstanceCount
= SrcDescriptor
->MaxFilterInstanceCount
;
744 Descriptor
->Factory
.Instances
[Index
].MaxGlobalInstanceCount
= SrcDescriptor
->MaxGlobalInstanceCount
;
745 Descriptor
->Factory
.Instances
[Index
].MinFilterInstanceCount
= SrcDescriptor
->MinFilterInstanceCount
;
747 // check if the descriptor has an automation table
748 if (SrcDescriptor
->AutomationTable
)
750 // it has, grab first entry
751 PropertyItem
= (PPCPROPERTY_ITEM
)SrcDescriptor
->AutomationTable
->Properties
;
753 // now add all supported property items
754 for(SubIndex
= 0; SubIndex
< SrcDescriptor
->AutomationTable
->PropertyCount
; SubIndex
++)
756 // add the property item to the table
757 Status
= PcAddToPropertyTable(Descriptor
, PropertyItem
, FALSE
);
760 if (Status
!= STATUS_SUCCESS
)
766 // move to next entry
767 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ SrcDescriptor
->AutomationTable
->PropertyItemSize
);
771 // move to next entry
772 SrcDescriptor
= (PPCPIN_DESCRIPTOR
)((ULONG_PTR
)SrcDescriptor
+ FilterDescription
->PinSize
);
776 // allocate topology descriptor
777 Descriptor
->Topology
= (PKSTOPOLOGY
)AllocateItem(NonPagedPool
, sizeof(KSTOPOLOGY
), TAG_PORTCLASS
);
778 if (!Descriptor
->Topology
)
781 // are there any connections
782 if (FilterDescription
->ConnectionCount
)
784 // allocate connection descriptor
785 Descriptor
->Topology
->TopologyConnections
= (PKSTOPOLOGY_CONNECTION
)AllocateItem(NonPagedPool
, sizeof(KSTOPOLOGY_CONNECTION
) * FilterDescription
->ConnectionCount
, TAG_PORTCLASS
);
786 if (!Descriptor
->Topology
->TopologyConnections
)
789 // copy connection descriptor
790 RtlMoveMemory((PVOID
)Descriptor
->Topology
->TopologyConnections
, FilterDescription
->Connections
, FilterDescription
->ConnectionCount
* sizeof(PCCONNECTION_DESCRIPTOR
));
792 // store connection count
793 Descriptor
->Topology
->TopologyConnectionsCount
= FilterDescription
->ConnectionCount
;
796 // does the filter have nodes
797 if (FilterDescription
->NodeCount
)
799 // allocate topology node types array
800 Descriptor
->Topology
->TopologyNodes
= (const GUID
*)AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescription
->NodeCount
, TAG_PORTCLASS
);
801 if (!Descriptor
->Topology
->TopologyNodes
)
804 // allocate topology node names array
805 Descriptor
->Topology
->TopologyNodesNames
= (const GUID
*)AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescription
->NodeCount
, TAG_PORTCLASS
);
806 if (!Descriptor
->Topology
->TopologyNodesNames
)
810 NodeDescriptor
= (PPCNODE_DESCRIPTOR
)FilterDescription
->Nodes
;
812 // iterate all nodes and copy node types / names and node properties
813 for(Index
= 0; Index
< FilterDescription
->NodeCount
; Index
++)
815 // does it have a type
816 if (NodeDescriptor
->Type
)
819 RtlMoveMemory((PVOID
)&Descriptor
->Topology
->TopologyNodes
[Index
], NodeDescriptor
->Type
, sizeof(GUID
));
822 // does it have a node name
823 if (NodeDescriptor
->Name
)
826 RtlMoveMemory((PVOID
)&Descriptor
->Topology
->TopologyNodesNames
[Index
], NodeDescriptor
->Name
, sizeof(GUID
));
829 // check if has an automation table
830 if (NodeDescriptor
->AutomationTable
)
833 PropertyItem
= (PPCPROPERTY_ITEM
)NodeDescriptor
->AutomationTable
->Properties
;
835 // copy all node properties into the global property set
836 for(SubIndex
= 0; SubIndex
< NodeDescriptor
->AutomationTable
->PropertyCount
; SubIndex
++)
838 // add to property set
839 Status
= PcAddToPropertyTable(Descriptor
, PropertyItem
, TRUE
);
842 if (Status
!= STATUS_SUCCESS
)
848 // move to next property item
849 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ NodeDescriptor
->AutomationTable
->PropertyItemSize
);
853 // move to next descriptor
854 NodeDescriptor
= (PPCNODE_DESCRIPTOR
)((ULONG_PTR
)NodeDescriptor
+ FilterDescription
->NodeSize
);
857 // now store the topology node count
858 Descriptor
->Topology
->TopologyNodesCount
= FilterDescription
->NodeCount
;
862 Descriptor
->DeviceDescriptor
= FilterDescription
;
865 *OutSubdeviceDescriptor
= Descriptor
;
867 return STATUS_SUCCESS
;
872 if (Descriptor
->Interfaces
)
873 FreeItem(Descriptor
->Interfaces
, TAG_PORTCLASS
);
875 if (Descriptor
->Factory
.KsPinDescriptor
)
876 FreeItem(Descriptor
->Factory
.KsPinDescriptor
, TAG_PORTCLASS
);
878 FreeItem(Descriptor
, TAG_PORTCLASS
);
885 PcValidateConnectRequest(
887 IN KSPIN_FACTORY
* Factory
,
888 OUT PKSPIN_CONNECT
* Connect
)
890 return KsValidateConnectRequest(Irp
, Factory
->PinDescriptorCount
, Factory
->KsPinDescriptor
, Connect
);