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\n",
279 PropertyRequest
->Node
, PropertyRequest
->MajorTarget
, PropertyRequest
->MinorTarget
, GuidBuffer
.Buffer
, Property
->Id
, Property
->Flags
, PropertyRequest
->InstanceSize
, PropertyRequest
->ValueSize
,
280 PropertyRequest
->PropertyItem
->Handler
, PropertyRequest
);
282 Status
= PropertyRequest
->PropertyItem
->Handler(PropertyRequest
);
284 Status
= STATUS_NOT_FOUND
;
286 Irp
->IoStatus
.Information
= PropertyRequest
->ValueSize
;
288 if (Status
!= STATUS_PENDING
)
290 // free property request
291 FreeItem(PropertyRequest
, TAG_PORTCLASS
);
296 FreeItem(PropertyRequest
, TAG_PORTCLASS
);
297 Status
= STATUS_NOT_FOUND
;
305 PcAddToPropertyTable(
306 IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor
,
307 IN PPCPROPERTY_ITEM PropertyItem
,
310 ULONG bFound
= FALSE
;
311 ULONG Index
, PropertySetIndex
, PropertySetItemIndex
;
312 PKSPROPERTY_SET NewPropertySet
;
313 PKSPROPERTY_ITEM FilterPropertyItem
, NewFilterPropertyItem
;
315 //UNICODE_STRING GuidBuffer;
317 ASSERT(PropertyItem
->Set
);
318 // RtlStringFromGUID(*PropertyItem->Set, &GuidBuffer);
319 // DPRINT1("PcAddToPropertyTable Adding Item Set %S Id %lu Flags %lx\n", GuidBuffer.Buffer, PropertyItem->Id, PropertyItem->Flags);
323 //DPRINT1("FilterPropertySetCount %lu\n", SubDeviceDescriptor->FilterPropertySetCount);
324 // first step check if the property set is present already
325 for(Index
= 0; Index
< SubDeviceDescriptor
->FilterPropertySetCount
; Index
++)
328 //RtlStringFromGUID(*SubDeviceDescriptor->FilterPropertySet[Index].Set, &GuidBuffer);
329 //DPRINT1("FilterProperty Set %S PropertyCount %lu\n", GuidBuffer.Buffer, SubDeviceDescriptor->FilterPropertySet[Index].PropertiesCount);
330 if (IsEqualGUIDAligned(*SubDeviceDescriptor
->FilterPropertySet
[Index
].Set
, *PropertyItem
->Set
))
332 // property set is already present
334 PropertySetIndex
= Index
;
341 // is the property set present
344 // need to allocate a property set
345 NewPropertySet
= (PKSPROPERTY_SET
)AllocateItem(NonPagedPool
, (SubDeviceDescriptor
->FilterPropertySetCount
+ 1) * sizeof(KSPROPERTY_SET
), TAG_PORTCLASS
);
349 return STATUS_INSUFFICIENT_RESOURCES
;
352 // need to allocate property set guid
353 Guid
= (LPGUID
)AllocateItem(NonPagedPool
, sizeof(GUID
), TAG_PORTCLASS
);
357 FreeItem(NewPropertySet
, TAG_PORTCLASS
);
358 return STATUS_INSUFFICIENT_RESOURCES
;
361 // are any existing property sets
362 if (SubDeviceDescriptor
->FilterPropertySetCount
)
364 // copy property sets
365 RtlMoveMemory(NewPropertySet
, SubDeviceDescriptor
->FilterPropertySet
, SubDeviceDescriptor
->FilterPropertySetCount
* sizeof(KSPROPERTY_SET
));
368 FreeItem(SubDeviceDescriptor
->FilterPropertySet
, TAG_PORTCLASS
);
371 // store new property set descriptors
372 SubDeviceDescriptor
->FilterPropertySet
= NewPropertySet
;
375 PropertySetIndex
= SubDeviceDescriptor
->FilterPropertySetCount
;
377 // increment property set count
378 SubDeviceDescriptor
->FilterPropertySetCount
++;
380 // copy property guid
381 RtlMoveMemory(Guid
, PropertyItem
->Set
, sizeof(GUID
));
383 // initialize property set
384 SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].Set
= Guid
;
385 SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
= 0;
388 // as the property set has been indentified, now search for duplicate property set item entries
389 FilterPropertyItem
= (PKSPROPERTY_ITEM
)SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
;
392 for(Index
= 0; Index
< SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
; Index
++)
394 // now search for an equal property set item
395 if (FilterPropertyItem
->PropertyId
== PropertyItem
->Id
)
397 // found existing property set item
399 PropertySetItemIndex
= Index
;
403 // move to next entry
404 FilterPropertyItem
++;
409 // need to allocate memory for new property set item
410 NewFilterPropertyItem
= (PKSPROPERTY_ITEM
)AllocateItem(NonPagedPool
, (SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
+ 1) * sizeof(KSPROPERTY_ITEM
), TAG_PORTCLASS
);
411 if (!NewFilterPropertyItem
)
414 return STATUS_INSUFFICIENT_RESOURCES
;
417 // are any existing property set items
418 if (SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
)
420 // copy property item sets
421 RtlMoveMemory(NewFilterPropertyItem
,
422 (PVOID
)SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
,
423 SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
* sizeof(KSPROPERTY_ITEM
));
425 // release old descriptors
426 FreeItem((PVOID
)SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
, TAG_PORTCLASS
);
429 // store new descriptor
430 SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
= NewFilterPropertyItem
;
433 PropertySetItemIndex
= SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
;
435 // increment property item set count
436 SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
++;
438 // now initialize property item
439 FilterPropertyItem
= (PKSPROPERTY_ITEM
)&SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
[PropertySetItemIndex
];
440 FilterPropertyItem
->PropertyId
= PropertyItem
->Id
;
441 FilterPropertyItem
->MinProperty
= sizeof(KSPROPERTY
);
442 FilterPropertyItem
->MinData
= 0;
444 // are any set operations supported
445 if (PropertyItem
->Flags
& PCPROPERTY_ITEM_FLAG_SET
)
448 FilterPropertyItem
->SetPropertyHandler
= PropertyItemDispatch
;
451 // are set operation supported
452 if (PropertyItem
->Flags
& PCPROPERTY_ITEM_FLAG_GET
)
455 FilterPropertyItem
->GetPropertyHandler
= PropertyItemDispatch
;
458 // are get operations supported
459 if (PropertyItem
->Flags
& PCPROPERTY_ITEM_FLAG_GET
)
462 FilterPropertyItem
->GetPropertyHandler
= PropertyItemDispatch
;
465 // are basic support operations supported
466 if (PropertyItem
->Flags
& PCPROPERTY_ITEM_FLAG_BASICSUPPORT
)
469 FilterPropertyItem
->SupportHandler
= PropertyItemDispatch
;
474 // store property item in relations
475 // only store property item of filter properties / pin properties
476 // because filter & pin properties do not require a specific context
477 // on the other hand node properties are specifically bound to a node
479 FilterPropertyItem
->Relations
= (const KSPROPERTY
*)PropertyItem
;
484 // property set item handler already present
488 // filter & pin properties should not be exposed on a node
489 ASSERT(SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
[PropertySetItemIndex
].Relations
== NULL
);
493 // node properties should not be exposed on a filter & pin
494 ASSERT(SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
[PropertySetItemIndex
].Relations
!= NULL
);
499 return STATUS_SUCCESS
;
510 return STATUS_NOT_IMPLEMENTED
;
514 DumpFilterDescriptor(
515 IN PPCFILTER_DESCRIPTOR FilterDescription
)
517 ULONG Index
, SubIndex
;
518 PPCPROPERTY_ITEM PropertyItem
;
519 PPCEVENT_ITEM EventItem
;
520 PPCNODE_DESCRIPTOR NodeDescriptor
;
521 UNICODE_STRING GuidString
;
525 DPRINT("======================\n");
526 DPRINT("Descriptor Automation Table %p\n",FilterDescription
->AutomationTable
);
528 if (FilterDescription
->AutomationTable
)
530 DPRINT("FilterPropertiesCount %u FilterPropertySize %u Expected %u Events %u EventItemSize %u expected %u\n", FilterDescription
->AutomationTable
->PropertyCount
, FilterDescription
->AutomationTable
->PropertyItemSize
, sizeof(PCPROPERTY_ITEM
),
531 FilterDescription
->AutomationTable
->EventCount
, FilterDescription
->AutomationTable
->EventItemSize
, sizeof(PCEVENT_ITEM
));
532 if (FilterDescription
->AutomationTable
->PropertyCount
)
534 PropertyItem
= (PPCPROPERTY_ITEM
)FilterDescription
->AutomationTable
->Properties
;
536 for(Index
= 0; Index
< FilterDescription
->AutomationTable
->PropertyCount
; Index
++)
538 RtlStringFromGUID(*PropertyItem
->Set
, &GuidString
);
539 DPRINT("Property Index %u GUID %S Id %u Flags %x\n", Index
, GuidString
.Buffer
, PropertyItem
->Id
, PropertyItem
->Flags
);
541 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ FilterDescription
->AutomationTable
->PropertyItemSize
);
544 EventItem
= (PPCEVENT_ITEM
)FilterDescription
->AutomationTable
->Events
;
545 for(Index
= 0; Index
< FilterDescription
->AutomationTable
->EventCount
; Index
++)
547 RtlStringFromGUID(*EventItem
->Set
, &GuidString
);
548 DPRINT("EventIndex %u GUID %S Id %u Flags %x\n", Index
, GuidString
.Buffer
, EventItem
->Id
, EventItem
->Flags
);
550 EventItem
= (PPCEVENT_ITEM
)((ULONG_PTR
)EventItem
+ FilterDescription
->AutomationTable
->EventItemSize
);
556 if (FilterDescription
->Nodes
)
558 DPRINT("NodeCount %u NodeSize %u expected %u\n", FilterDescription
->NodeCount
, FilterDescription
->NodeSize
, sizeof(PCNODE_DESCRIPTOR
));
559 NodeDescriptor
= (PPCNODE_DESCRIPTOR
)FilterDescription
->Nodes
;
560 for(Index
= 0; Index
< FilterDescription
->NodeCount
; Index
++)
562 DPRINT("Index %u AutomationTable %p\n", Index
, NodeDescriptor
->AutomationTable
);
564 if (NodeDescriptor
->AutomationTable
)
566 DPRINT(" Index %u EventCount %u\n", Index
, NodeDescriptor
->AutomationTable
->EventCount
);
567 EventItem
= (PPCEVENT_ITEM
)NodeDescriptor
->AutomationTable
->Events
;
568 for(SubIndex
= 0; SubIndex
< NodeDescriptor
->AutomationTable
->EventCount
; SubIndex
++)
570 RtlStringFromGUID(*EventItem
->Set
, &GuidString
);
571 DPRINT(" EventIndex %u GUID %S Id %u Flags %x\n", SubIndex
, GuidString
.Buffer
, EventItem
->Id
, EventItem
->Flags
);
573 EventItem
= (PPCEVENT_ITEM
)((ULONG_PTR
)EventItem
+ NodeDescriptor
->AutomationTable
->EventItemSize
);
576 DPRINT1(" Index %u PropertyCount %u\n", Index
, NodeDescriptor
->AutomationTable
->PropertyCount
);
577 PropertyItem
= (PPCPROPERTY_ITEM
)NodeDescriptor
->AutomationTable
->Properties
;
578 for(SubIndex
= 0; SubIndex
< NodeDescriptor
->AutomationTable
->PropertyCount
; SubIndex
++)
580 RtlStringFromGUID(*PropertyItem
->Set
, &GuidString
);
581 DPRINT1(" PropertyIndex %u GUID %S Id %u Flags %x\n", SubIndex
, GuidString
.Buffer
, PropertyItem
->Id
, PropertyItem
->Flags
);
583 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ NodeDescriptor
->AutomationTable
->PropertyItemSize
);
588 NodeDescriptor
= (PPCNODE_DESCRIPTOR
)((ULONG_PTR
)NodeDescriptor
+ FilterDescription
->NodeSize
);
595 DPRINT("ConnectionCount: %lu\n", FilterDescription
->ConnectionCount
);
597 if (FilterDescription
->ConnectionCount
)
599 DPRINT("------ Start of Nodes Connections ----------------\n");
600 for(Index
= 0; Index
< FilterDescription
->ConnectionCount
; Index
++)
602 DPRINT1("Index %ld FromPin %ld FromNode %ld -> ToPin %ld ToNode %ld\n", Index
,
603 FilterDescription
->Connections
[Index
].FromNodePin
,
604 FilterDescription
->Connections
[Index
].FromNode
,
605 FilterDescription
->Connections
[Index
].ToNodePin
,
606 FilterDescription
->Connections
[Index
].ToNode
);
608 DPRINT("------ End of Nodes Connections----------------\n");
611 DPRINT1("======================\n");
616 PcCreateSubdeviceDescriptor(
617 OUT SUBDEVICE_DESCRIPTOR
** OutSubdeviceDescriptor
,
618 IN ULONG InterfaceCount
,
619 IN GUID
* InterfaceGuids
,
620 IN ULONG IdentifierCount
,
621 IN KSIDENTIFIER
*Identifier
,
622 IN ULONG FilterPropertiesCount
,
623 IN KSPROPERTY_SET
* FilterProperties
,
626 IN ULONG PinPropertiesCount
,
627 IN KSPROPERTY_SET
* PinProperties
,
628 IN ULONG EventSetCount
,
629 IN KSEVENT_SET
* EventSet
,
630 IN PPCFILTER_DESCRIPTOR FilterDescription
)
632 SUBDEVICE_DESCRIPTOR
* Descriptor
;
633 ULONG Index
, SubIndex
;
634 NTSTATUS Status
= STATUS_INSUFFICIENT_RESOURCES
;
635 PPCPIN_DESCRIPTOR SrcDescriptor
;
636 PPCNODE_DESCRIPTOR NodeDescriptor
;
637 PPCPROPERTY_ITEM PropertyItem
;
639 // allocate subdevice descriptor
640 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)AllocateItem(NonPagedPool
, sizeof(SUBDEVICE_DESCRIPTOR
), TAG_PORTCLASS
);
642 return STATUS_INSUFFICIENT_RESOURCES
;
644 // initialize physical / symbolic link connection list
645 InitializeListHead(&Descriptor
->SymbolicLinkList
);
646 InitializeListHead(&Descriptor
->PhysicalConnectionList
);
648 //FIXME add driver category guids
649 Descriptor
->Interfaces
= (GUID
*)AllocateItem(NonPagedPool
, sizeof(GUID
) * InterfaceCount
, TAG_PORTCLASS
);
650 if (!Descriptor
->Interfaces
)
653 // copy interface guids
654 RtlCopyMemory(Descriptor
->Interfaces
, InterfaceGuids
, sizeof(GUID
) * InterfaceCount
);
655 Descriptor
->InterfaceCount
= InterfaceCount
;
657 //DumpFilterDescriptor(FilterDescription);
659 // are any property sets supported by the portcls
660 if (FilterPropertiesCount
)
662 // first allocate filter properties set
663 Descriptor
->FilterPropertySet
= (PKSPROPERTY_SET
)AllocateItem(NonPagedPool
, sizeof(KSPROPERTY_SET
) * FilterPropertiesCount
, TAG_PORTCLASS
);
664 if (! Descriptor
->FilterPropertySet
)
667 // now copy all filter property sets
668 Descriptor
->FilterPropertySetCount
= FilterPropertiesCount
;
669 for(Index
= 0; Index
< FilterPropertiesCount
; Index
++)
672 RtlMoveMemory(&Descriptor
->FilterPropertySet
[Index
], &FilterProperties
[Index
], sizeof(KSPROPERTY_SET
));
674 if (Descriptor
->FilterPropertySet
[Index
].PropertiesCount
)
676 // copy property items to make sure they are dynamically allocated
677 Descriptor
->FilterPropertySet
[Index
].PropertyItem
= (PKSPROPERTY_ITEM
)AllocateItem(NonPagedPool
, FilterProperties
[Index
].PropertiesCount
* sizeof(KSPROPERTY_ITEM
), TAG_PORTCLASS
);
678 if (!Descriptor
->FilterPropertySet
[Index
].PropertyItem
)
684 // copy filter property items
685 RtlMoveMemory((PVOID
)Descriptor
->FilterPropertySet
[Index
].PropertyItem
, FilterProperties
[Index
].PropertyItem
, FilterProperties
[Index
].PropertiesCount
* sizeof(KSPROPERTY_ITEM
));
690 // now check if the filter descriptor supports filter properties
691 if (FilterDescription
->AutomationTable
)
694 PropertyItem
= (PPCPROPERTY_ITEM
)FilterDescription
->AutomationTable
->Properties
;
696 // copy driver filter property sets
697 for(Index
= 0; Index
< FilterDescription
->AutomationTable
->PropertyCount
; Index
++)
699 // add the property item
700 Status
= PcAddToPropertyTable(Descriptor
, PropertyItem
, FALSE
);
703 if (Status
!= STATUS_SUCCESS
)
709 // move to next entry
710 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ FilterDescription
->AutomationTable
->PropertyItemSize
);
714 // check if the filter has pins
715 if (FilterDescription
->PinCount
)
717 // allocate pin factory descriptors
718 Descriptor
->Factory
.KsPinDescriptor
= (PKSPIN_DESCRIPTOR
)AllocateItem(NonPagedPool
, sizeof(KSPIN_DESCRIPTOR
) * FilterDescription
->PinCount
, TAG_PORTCLASS
);
719 if (!Descriptor
->Factory
.KsPinDescriptor
)
722 // allocate pin instance info
723 Descriptor
->Factory
.Instances
= (PPIN_INSTANCE_INFO
)AllocateItem(NonPagedPool
, FilterDescription
->PinCount
* sizeof(PIN_INSTANCE_INFO
), TAG_PORTCLASS
);
724 if (!Descriptor
->Factory
.Instances
)
727 // initialize pin factory descriptor
728 Descriptor
->Factory
.PinDescriptorCount
= FilterDescription
->PinCount
;
729 Descriptor
->Factory
.PinDescriptorSize
= sizeof(KSPIN_DESCRIPTOR
);
732 SrcDescriptor
= (PPCPIN_DESCRIPTOR
)FilterDescription
->Pins
;
734 // copy pin factories
735 for(Index
= 0; Index
< FilterDescription
->PinCount
; Index
++)
737 // copy pin descriptor
738 RtlMoveMemory(&Descriptor
->Factory
.KsPinDescriptor
[Index
], &SrcDescriptor
->KsPinDescriptor
, sizeof(KSPIN_DESCRIPTOR
));
740 // initialize pin factory instance data
741 Descriptor
->Factory
.Instances
[Index
].CurrentPinInstanceCount
= 0;
742 Descriptor
->Factory
.Instances
[Index
].MaxFilterInstanceCount
= SrcDescriptor
->MaxFilterInstanceCount
;
743 Descriptor
->Factory
.Instances
[Index
].MaxGlobalInstanceCount
= SrcDescriptor
->MaxGlobalInstanceCount
;
744 Descriptor
->Factory
.Instances
[Index
].MinFilterInstanceCount
= SrcDescriptor
->MinFilterInstanceCount
;
746 // check if the descriptor has an automation table
747 if (SrcDescriptor
->AutomationTable
)
749 // it has, grab first entry
750 PropertyItem
= (PPCPROPERTY_ITEM
)SrcDescriptor
->AutomationTable
->Properties
;
752 // now add all supported property items
753 for(SubIndex
= 0; SubIndex
< SrcDescriptor
->AutomationTable
->PropertyCount
; SubIndex
++)
755 // add the property item to the table
756 Status
= PcAddToPropertyTable(Descriptor
, PropertyItem
, FALSE
);
759 if (Status
!= STATUS_SUCCESS
)
765 // move to next entry
766 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ SrcDescriptor
->AutomationTable
->PropertyItemSize
);
770 // move to next entry
771 SrcDescriptor
= (PPCPIN_DESCRIPTOR
)((ULONG_PTR
)SrcDescriptor
+ FilterDescription
->PinSize
);
775 // allocate topology descriptor
776 Descriptor
->Topology
= (PKSTOPOLOGY
)AllocateItem(NonPagedPool
, sizeof(KSTOPOLOGY
), TAG_PORTCLASS
);
777 if (!Descriptor
->Topology
)
780 // are there any connections
781 if (FilterDescription
->ConnectionCount
)
783 // allocate connection descriptor
784 Descriptor
->Topology
->TopologyConnections
= (PKSTOPOLOGY_CONNECTION
)AllocateItem(NonPagedPool
, sizeof(KSTOPOLOGY_CONNECTION
) * FilterDescription
->ConnectionCount
, TAG_PORTCLASS
);
785 if (!Descriptor
->Topology
->TopologyConnections
)
788 // copy connection descriptor
789 RtlMoveMemory((PVOID
)Descriptor
->Topology
->TopologyConnections
, FilterDescription
->Connections
, FilterDescription
->ConnectionCount
* sizeof(PCCONNECTION_DESCRIPTOR
));
791 // store connection count
792 Descriptor
->Topology
->TopologyConnectionsCount
= FilterDescription
->ConnectionCount
;
795 // does the filter have nodes
796 if (FilterDescription
->NodeCount
)
798 // allocate topology node types array
799 Descriptor
->Topology
->TopologyNodes
= (const GUID
*)AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescription
->NodeCount
, TAG_PORTCLASS
);
800 if (!Descriptor
->Topology
->TopologyNodes
)
803 // allocate topology node names array
804 Descriptor
->Topology
->TopologyNodesNames
= (const GUID
*)AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescription
->NodeCount
, TAG_PORTCLASS
);
805 if (!Descriptor
->Topology
->TopologyNodesNames
)
809 NodeDescriptor
= (PPCNODE_DESCRIPTOR
)FilterDescription
->Nodes
;
811 // iterate all nodes and copy node types / names and node properties
812 for(Index
= 0; Index
< FilterDescription
->NodeCount
; Index
++)
814 // does it have a type
815 if (NodeDescriptor
->Type
)
818 RtlMoveMemory((PVOID
)&Descriptor
->Topology
->TopologyNodes
[Index
], NodeDescriptor
->Type
, sizeof(GUID
));
821 // does it have a node name
822 if (NodeDescriptor
->Name
)
825 RtlMoveMemory((PVOID
)&Descriptor
->Topology
->TopologyNodesNames
[Index
], NodeDescriptor
->Name
, sizeof(GUID
));
828 // check if has an automation table
829 if (NodeDescriptor
->AutomationTable
)
832 PropertyItem
= (PPCPROPERTY_ITEM
)NodeDescriptor
->AutomationTable
->Properties
;
834 // copy all node properties into the global property set
835 for(SubIndex
= 0; SubIndex
< NodeDescriptor
->AutomationTable
->PropertyCount
; SubIndex
++)
837 // add to property set
838 Status
= PcAddToPropertyTable(Descriptor
, PropertyItem
, TRUE
);
841 if (Status
!= STATUS_SUCCESS
)
847 // move to next property item
848 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ NodeDescriptor
->AutomationTable
->PropertyItemSize
);
852 // move to next descriptor
853 NodeDescriptor
= (PPCNODE_DESCRIPTOR
)((ULONG_PTR
)NodeDescriptor
+ FilterDescription
->NodeSize
);
856 // now store the topology node count
857 Descriptor
->Topology
->TopologyNodesCount
= FilterDescription
->NodeCount
;
861 Descriptor
->DeviceDescriptor
= FilterDescription
;
864 *OutSubdeviceDescriptor
= Descriptor
;
866 return STATUS_SUCCESS
;
871 if (Descriptor
->Interfaces
)
872 FreeItem(Descriptor
->Interfaces
, TAG_PORTCLASS
);
874 if (Descriptor
->Factory
.KsPinDescriptor
)
875 FreeItem(Descriptor
->Factory
.KsPinDescriptor
, TAG_PORTCLASS
);
877 FreeItem(Descriptor
, TAG_PORTCLASS
);
884 PcValidateConnectRequest(
886 IN KSPIN_FACTORY
* Factory
,
887 OUT PKSPIN_CONNECT
* Connect
)
889 return KsValidateConnectRequest(Irp
, Factory
->PinDescriptorCount
, Factory
->KsPinDescriptor
, Connect
);