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
);
281 Status
= PropertyRequest
->PropertyItem
->Handler(PropertyRequest
);
283 Irp
->IoStatus
.Information
= PropertyRequest
->ValueSize
;
285 if (Status
!= STATUS_PENDING
)
287 // free property request
288 FreeItem(PropertyRequest
, TAG_PORTCLASS
);
293 FreeItem(PropertyRequest
, TAG_PORTCLASS
);
294 Status
= STATUS_NOT_FOUND
;
302 PcAddToPropertyTable(
303 IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor
,
304 IN PPCPROPERTY_ITEM PropertyItem
,
307 ULONG bFound
= FALSE
;
308 ULONG Index
, PropertySetIndex
, PropertySetItemIndex
;
309 PKSPROPERTY_SET NewPropertySet
;
310 PKSPROPERTY_ITEM FilterPropertyItem
, NewFilterPropertyItem
;
312 //UNICODE_STRING GuidBuffer;
314 ASSERT(PropertyItem
->Set
);
315 // RtlStringFromGUID(*PropertyItem->Set, &GuidBuffer);
316 // DPRINT1("PcAddToPropertyTable Adding Item Set %S Id %lu Flags %lx\n", GuidBuffer.Buffer, PropertyItem->Id, PropertyItem->Flags);
320 //DPRINT1("FilterPropertySetCount %lu\n", SubDeviceDescriptor->FilterPropertySetCount);
321 // first step check if the property set is present already
322 for(Index
= 0; Index
< SubDeviceDescriptor
->FilterPropertySetCount
; Index
++)
325 //RtlStringFromGUID(*SubDeviceDescriptor->FilterPropertySet[Index].Set, &GuidBuffer);
326 //DPRINT1("FilterProperty Set %S PropertyCount %lu\n", GuidBuffer.Buffer, SubDeviceDescriptor->FilterPropertySet[Index].PropertiesCount);
327 if (IsEqualGUIDAligned(*SubDeviceDescriptor
->FilterPropertySet
[Index
].Set
, *PropertyItem
->Set
))
329 // property set is already present
331 PropertySetIndex
= Index
;
338 // is the property set present
341 // need to allocate a property set
342 NewPropertySet
= (PKSPROPERTY_SET
)AllocateItem(NonPagedPool
, (SubDeviceDescriptor
->FilterPropertySetCount
+ 1) * sizeof(KSPROPERTY_SET
), TAG_PORTCLASS
);
346 return STATUS_INSUFFICIENT_RESOURCES
;
349 // need to allocate property set guid
350 Guid
= (LPGUID
)AllocateItem(NonPagedPool
, sizeof(GUID
), TAG_PORTCLASS
);
354 FreeItem(NewPropertySet
, TAG_PORTCLASS
);
355 return STATUS_INSUFFICIENT_RESOURCES
;
358 // are any existing property sets
359 if (SubDeviceDescriptor
->FilterPropertySetCount
)
361 // copy property sets
362 RtlMoveMemory(NewPropertySet
, SubDeviceDescriptor
->FilterPropertySet
, SubDeviceDescriptor
->FilterPropertySetCount
* sizeof(KSPROPERTY_SET
));
365 FreeItem(SubDeviceDescriptor
->FilterPropertySet
, TAG_PORTCLASS
);
368 // store new property set descriptors
369 SubDeviceDescriptor
->FilterPropertySet
= NewPropertySet
;
372 PropertySetIndex
= SubDeviceDescriptor
->FilterPropertySetCount
;
374 // increment property set count
375 SubDeviceDescriptor
->FilterPropertySetCount
++;
377 // copy property guid
378 RtlMoveMemory(Guid
, PropertyItem
->Set
, sizeof(GUID
));
380 // initialize property set
381 SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].Set
= Guid
;
382 SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
= 0;
385 // as the property set has been indentified, now search for duplicate property set item entries
386 FilterPropertyItem
= (PKSPROPERTY_ITEM
)SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
;
389 for(Index
= 0; Index
< SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
; Index
++)
391 // now search for an equal property set item
392 if (FilterPropertyItem
->PropertyId
== PropertyItem
->Id
)
394 // found existing property set item
396 PropertySetItemIndex
= Index
;
400 // move to next entry
401 FilterPropertyItem
++;
406 // need to allocate memory for new property set item
407 NewFilterPropertyItem
= (PKSPROPERTY_ITEM
)AllocateItem(NonPagedPool
, (SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
+ 1) * sizeof(KSPROPERTY_ITEM
), TAG_PORTCLASS
);
408 if (!NewFilterPropertyItem
)
411 return STATUS_INSUFFICIENT_RESOURCES
;
414 // are any existing property set items
415 if (SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
)
417 // copy property item sets
418 RtlMoveMemory(NewFilterPropertyItem
,
419 (PVOID
)SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
,
420 SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
* sizeof(KSPROPERTY_ITEM
));
422 // release old descriptors
423 FreeItem((PVOID
)SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
, TAG_PORTCLASS
);
426 // store new descriptor
427 SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
= NewFilterPropertyItem
;
430 PropertySetItemIndex
= SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
;
432 // increment property item set count
433 SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertiesCount
++;
435 // now initialize property item
436 FilterPropertyItem
= (PKSPROPERTY_ITEM
)&SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
[PropertySetItemIndex
];
437 FilterPropertyItem
->PropertyId
= PropertyItem
->Id
;
438 FilterPropertyItem
->MinProperty
= sizeof(KSPROPERTY
);
439 FilterPropertyItem
->MinData
= 0;
441 // are any set operations supported
442 if (PropertyItem
->Flags
& PCPROPERTY_ITEM_FLAG_SET
)
445 FilterPropertyItem
->SetPropertyHandler
= PropertyItemDispatch
;
448 // are set operation supported
449 if (PropertyItem
->Flags
& PCPROPERTY_ITEM_FLAG_GET
)
452 FilterPropertyItem
->GetPropertyHandler
= PropertyItemDispatch
;
455 // are get operations supported
456 if (PropertyItem
->Flags
& PCPROPERTY_ITEM_FLAG_GET
)
459 FilterPropertyItem
->GetPropertyHandler
= PropertyItemDispatch
;
462 // are basic support operations supported
463 if (PropertyItem
->Flags
& PCPROPERTY_ITEM_FLAG_BASICSUPPORT
)
466 FilterPropertyItem
->SupportHandler
= PropertyItemDispatch
;
471 // store property item in relations
472 // only store property item of filter properties / pin properties
473 // because filter & pin properties do not require a specific context
474 // on the other hand node properties are specifically bound to a node
476 FilterPropertyItem
->Relations
= (const KSPROPERTY
*)PropertyItem
;
481 // property set item handler already present
485 // filter & pin properties should not be exposed on a node
486 ASSERT(SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
[PropertySetItemIndex
].Relations
== NULL
);
490 // node properties should not be exposed on a filter & pin
491 ASSERT(SubDeviceDescriptor
->FilterPropertySet
[PropertySetIndex
].PropertyItem
[PropertySetItemIndex
].Relations
!= NULL
);
496 return STATUS_SUCCESS
;
507 return STATUS_NOT_IMPLEMENTED
;
511 DumpFilterDescriptor(
512 IN PPCFILTER_DESCRIPTOR FilterDescription
)
514 ULONG Index
, SubIndex
;
515 PPCPROPERTY_ITEM PropertyItem
;
516 PPCEVENT_ITEM EventItem
;
517 PPCNODE_DESCRIPTOR NodeDescriptor
;
518 UNICODE_STRING GuidString
;
522 DPRINT("======================\n");
523 DPRINT("Descriptor Automation Table %p\n",FilterDescription
->AutomationTable
);
525 if (FilterDescription
->AutomationTable
)
527 DPRINT("FilterPropertiesCount %u FilterPropertySize %u Expected %u Events %u EventItemSize %u expected %u\n", FilterDescription
->AutomationTable
->PropertyCount
, FilterDescription
->AutomationTable
->PropertyItemSize
, sizeof(PCPROPERTY_ITEM
),
528 FilterDescription
->AutomationTable
->EventCount
, FilterDescription
->AutomationTable
->EventItemSize
, sizeof(PCEVENT_ITEM
));
529 if (FilterDescription
->AutomationTable
->PropertyCount
)
531 PropertyItem
= (PPCPROPERTY_ITEM
)FilterDescription
->AutomationTable
->Properties
;
533 for(Index
= 0; Index
< FilterDescription
->AutomationTable
->PropertyCount
; Index
++)
535 RtlStringFromGUID(*PropertyItem
->Set
, &GuidString
);
536 DPRINT("Property Index %u GUID %S Id %u Flags %x\n", Index
, GuidString
.Buffer
, PropertyItem
->Id
, PropertyItem
->Flags
);
538 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ FilterDescription
->AutomationTable
->PropertyItemSize
);
541 EventItem
= (PPCEVENT_ITEM
)FilterDescription
->AutomationTable
->Events
;
542 for(Index
= 0; Index
< FilterDescription
->AutomationTable
->EventCount
; Index
++)
544 RtlStringFromGUID(*EventItem
->Set
, &GuidString
);
545 DPRINT("EventIndex %u GUID %S Id %u Flags %x\n", Index
, GuidString
.Buffer
, EventItem
->Id
, EventItem
->Flags
);
547 EventItem
= (PPCEVENT_ITEM
)((ULONG_PTR
)EventItem
+ FilterDescription
->AutomationTable
->EventItemSize
);
553 if (FilterDescription
->Nodes
)
555 DPRINT("NodeCount %u NodeSize %u expected %u\n", FilterDescription
->NodeCount
, FilterDescription
->NodeSize
, sizeof(PCNODE_DESCRIPTOR
));
556 NodeDescriptor
= (PPCNODE_DESCRIPTOR
)FilterDescription
->Nodes
;
557 for(Index
= 0; Index
< FilterDescription
->NodeCount
; Index
++)
559 DPRINT("Index %u AutomationTable %p\n", Index
, NodeDescriptor
->AutomationTable
);
561 if (NodeDescriptor
->AutomationTable
)
563 DPRINT(" Index %u EventCount %u\n", Index
, NodeDescriptor
->AutomationTable
->EventCount
);
564 EventItem
= (PPCEVENT_ITEM
)NodeDescriptor
->AutomationTable
->Events
;
565 for(SubIndex
= 0; SubIndex
< NodeDescriptor
->AutomationTable
->EventCount
; SubIndex
++)
567 RtlStringFromGUID(*EventItem
->Set
, &GuidString
);
568 DPRINT(" EventIndex %u GUID %S Id %u Flags %x\n", SubIndex
, GuidString
.Buffer
, EventItem
->Id
, EventItem
->Flags
);
570 EventItem
= (PPCEVENT_ITEM
)((ULONG_PTR
)EventItem
+ NodeDescriptor
->AutomationTable
->EventItemSize
);
573 DPRINT1(" Index %u PropertyCount %u\n", Index
, NodeDescriptor
->AutomationTable
->PropertyCount
);
574 PropertyItem
= (PPCPROPERTY_ITEM
)NodeDescriptor
->AutomationTable
->Properties
;
575 for(SubIndex
= 0; SubIndex
< NodeDescriptor
->AutomationTable
->PropertyCount
; SubIndex
++)
577 RtlStringFromGUID(*PropertyItem
->Set
, &GuidString
);
578 DPRINT1(" PropertyIndex %u GUID %S Id %u Flags %x\n", SubIndex
, GuidString
.Buffer
, PropertyItem
->Id
, PropertyItem
->Flags
);
580 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ NodeDescriptor
->AutomationTable
->PropertyItemSize
);
585 NodeDescriptor
= (PPCNODE_DESCRIPTOR
)((ULONG_PTR
)NodeDescriptor
+ FilterDescription
->NodeSize
);
592 DPRINT("ConnectionCount: %lu\n", FilterDescription
->ConnectionCount
);
594 if (FilterDescription
->ConnectionCount
)
596 DPRINT("------ Start of Nodes Connections ----------------\n");
597 for(Index
= 0; Index
< FilterDescription
->ConnectionCount
; Index
++)
599 DPRINT1("Index %ld FromPin %ld FromNode %ld -> ToPin %ld ToNode %ld\n", Index
,
600 FilterDescription
->Connections
[Index
].FromNodePin
,
601 FilterDescription
->Connections
[Index
].FromNode
,
602 FilterDescription
->Connections
[Index
].ToNodePin
,
603 FilterDescription
->Connections
[Index
].ToNode
);
605 DPRINT("------ End of Nodes Connections----------------\n");
608 DPRINT1("======================\n");
613 PcCreateSubdeviceDescriptor(
614 OUT SUBDEVICE_DESCRIPTOR
** OutSubdeviceDescriptor
,
615 IN ULONG InterfaceCount
,
616 IN GUID
* InterfaceGuids
,
617 IN ULONG IdentifierCount
,
618 IN KSIDENTIFIER
*Identifier
,
619 IN ULONG FilterPropertiesCount
,
620 IN KSPROPERTY_SET
* FilterProperties
,
623 IN ULONG PinPropertiesCount
,
624 IN KSPROPERTY_SET
* PinProperties
,
625 IN ULONG EventSetCount
,
626 IN KSEVENT_SET
* EventSet
,
627 IN PPCFILTER_DESCRIPTOR FilterDescription
)
629 SUBDEVICE_DESCRIPTOR
* Descriptor
;
630 ULONG Index
, SubIndex
;
631 NTSTATUS Status
= STATUS_INSUFFICIENT_RESOURCES
;
632 PPCPIN_DESCRIPTOR SrcDescriptor
;
633 PPCNODE_DESCRIPTOR NodeDescriptor
;
634 PPCPROPERTY_ITEM PropertyItem
;
636 // allocate subdevice descriptor
637 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)AllocateItem(NonPagedPool
, sizeof(SUBDEVICE_DESCRIPTOR
), TAG_PORTCLASS
);
639 return STATUS_INSUFFICIENT_RESOURCES
;
641 // initialize physical / symbolic link connection list
642 InitializeListHead(&Descriptor
->SymbolicLinkList
);
643 InitializeListHead(&Descriptor
->PhysicalConnectionList
);
645 //FIXME add driver category guids
646 Descriptor
->Interfaces
= (GUID
*)AllocateItem(NonPagedPool
, sizeof(GUID
) * InterfaceCount
, TAG_PORTCLASS
);
647 if (!Descriptor
->Interfaces
)
650 // copy interface guids
651 RtlCopyMemory(Descriptor
->Interfaces
, InterfaceGuids
, sizeof(GUID
) * InterfaceCount
);
652 Descriptor
->InterfaceCount
= InterfaceCount
;
654 //DumpFilterDescriptor(FilterDescription);
656 // are any property sets supported by the portcls
657 if (FilterPropertiesCount
)
659 // first allocate filter properties set
660 Descriptor
->FilterPropertySet
= (PKSPROPERTY_SET
)AllocateItem(NonPagedPool
, sizeof(KSPROPERTY_SET
) * FilterPropertiesCount
, TAG_PORTCLASS
);
661 if (! Descriptor
->FilterPropertySet
)
664 // now copy all filter property sets
665 Descriptor
->FilterPropertySetCount
= FilterPropertiesCount
;
666 for(Index
= 0; Index
< FilterPropertiesCount
; Index
++)
669 RtlMoveMemory(&Descriptor
->FilterPropertySet
[Index
], &FilterProperties
[Index
], sizeof(KSPROPERTY_SET
));
671 if (Descriptor
->FilterPropertySet
[Index
].PropertiesCount
)
673 // copy property items to make sure they are dynamically allocated
674 Descriptor
->FilterPropertySet
[Index
].PropertyItem
= (PKSPROPERTY_ITEM
)AllocateItem(NonPagedPool
, FilterProperties
[Index
].PropertiesCount
* sizeof(KSPROPERTY_ITEM
), TAG_PORTCLASS
);
675 if (!Descriptor
->FilterPropertySet
[Index
].PropertyItem
)
681 // copy filter property items
682 RtlMoveMemory((PVOID
)Descriptor
->FilterPropertySet
[Index
].PropertyItem
, FilterProperties
[Index
].PropertyItem
, FilterProperties
[Index
].PropertiesCount
* sizeof(KSPROPERTY_ITEM
));
687 // now check if the filter descriptor supports filter properties
688 if (FilterDescription
->AutomationTable
)
691 PropertyItem
= (PPCPROPERTY_ITEM
)FilterDescription
->AutomationTable
->Properties
;
693 // copy driver filter property sets
694 for(Index
= 0; Index
< FilterDescription
->AutomationTable
->PropertyCount
; Index
++)
696 // add the property item
697 Status
= PcAddToPropertyTable(Descriptor
, PropertyItem
, FALSE
);
700 if (Status
!= STATUS_SUCCESS
)
706 // move to next entry
707 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ FilterDescription
->AutomationTable
->PropertyItemSize
);
711 // check if the filter has pins
712 if (FilterDescription
->PinCount
)
714 // allocate pin factory descriptors
715 Descriptor
->Factory
.KsPinDescriptor
= (PKSPIN_DESCRIPTOR
)AllocateItem(NonPagedPool
, sizeof(KSPIN_DESCRIPTOR
) * FilterDescription
->PinCount
, TAG_PORTCLASS
);
716 if (!Descriptor
->Factory
.KsPinDescriptor
)
719 // allocate pin instance info
720 Descriptor
->Factory
.Instances
= (PPIN_INSTANCE_INFO
)AllocateItem(NonPagedPool
, FilterDescription
->PinCount
* sizeof(PIN_INSTANCE_INFO
), TAG_PORTCLASS
);
721 if (!Descriptor
->Factory
.Instances
)
724 // initialize pin factory descriptor
725 Descriptor
->Factory
.PinDescriptorCount
= FilterDescription
->PinCount
;
726 Descriptor
->Factory
.PinDescriptorSize
= sizeof(KSPIN_DESCRIPTOR
);
729 SrcDescriptor
= (PPCPIN_DESCRIPTOR
)FilterDescription
->Pins
;
731 // copy pin factories
732 for(Index
= 0; Index
< FilterDescription
->PinCount
; Index
++)
734 // copy pin descriptor
735 RtlMoveMemory(&Descriptor
->Factory
.KsPinDescriptor
[Index
], &SrcDescriptor
->KsPinDescriptor
, sizeof(KSPIN_DESCRIPTOR
));
737 // initialize pin factory instance data
738 Descriptor
->Factory
.Instances
[Index
].CurrentPinInstanceCount
= 0;
739 Descriptor
->Factory
.Instances
[Index
].MaxFilterInstanceCount
= SrcDescriptor
->MaxFilterInstanceCount
;
740 Descriptor
->Factory
.Instances
[Index
].MaxGlobalInstanceCount
= SrcDescriptor
->MaxGlobalInstanceCount
;
741 Descriptor
->Factory
.Instances
[Index
].MinFilterInstanceCount
= SrcDescriptor
->MinFilterInstanceCount
;
743 // check if the descriptor has an automation table
744 if (SrcDescriptor
->AutomationTable
)
746 // it has, grab first entry
747 PropertyItem
= (PPCPROPERTY_ITEM
)SrcDescriptor
->AutomationTable
->Properties
;
749 // now add all supported property items
750 for(SubIndex
= 0; SubIndex
< SrcDescriptor
->AutomationTable
->PropertyCount
; SubIndex
++)
752 // add the property item to the table
753 Status
= PcAddToPropertyTable(Descriptor
, PropertyItem
, FALSE
);
756 if (Status
!= STATUS_SUCCESS
)
762 // move to next entry
763 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ SrcDescriptor
->AutomationTable
->PropertyItemSize
);
767 // move to next entry
768 SrcDescriptor
= (PPCPIN_DESCRIPTOR
)((ULONG_PTR
)SrcDescriptor
+ FilterDescription
->PinSize
);
772 // allocate topology descriptor
773 Descriptor
->Topology
= (PKSTOPOLOGY
)AllocateItem(NonPagedPool
, sizeof(KSTOPOLOGY
), TAG_PORTCLASS
);
774 if (!Descriptor
->Topology
)
777 // are there any connections
778 if (FilterDescription
->ConnectionCount
)
780 // allocate connection descriptor
781 Descriptor
->Topology
->TopologyConnections
= (PKSTOPOLOGY_CONNECTION
)AllocateItem(NonPagedPool
, sizeof(KSTOPOLOGY_CONNECTION
) * FilterDescription
->ConnectionCount
, TAG_PORTCLASS
);
782 if (!Descriptor
->Topology
->TopologyConnections
)
785 // copy connection descriptor
786 RtlMoveMemory((PVOID
)Descriptor
->Topology
->TopologyConnections
, FilterDescription
->Connections
, FilterDescription
->ConnectionCount
* sizeof(PCCONNECTION_DESCRIPTOR
));
788 // store connection count
789 Descriptor
->Topology
->TopologyConnectionsCount
= FilterDescription
->ConnectionCount
;
792 // does the filter have nodes
793 if (FilterDescription
->NodeCount
)
795 // allocate topology node types array
796 Descriptor
->Topology
->TopologyNodes
= (const GUID
*)AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescription
->NodeCount
, TAG_PORTCLASS
);
797 if (!Descriptor
->Topology
->TopologyNodes
)
800 // allocate topology node names array
801 Descriptor
->Topology
->TopologyNodesNames
= (const GUID
*)AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescription
->NodeCount
, TAG_PORTCLASS
);
802 if (!Descriptor
->Topology
->TopologyNodesNames
)
806 NodeDescriptor
= (PPCNODE_DESCRIPTOR
)FilterDescription
->Nodes
;
808 // iterate all nodes and copy node types / names and node properties
809 for(Index
= 0; Index
< FilterDescription
->NodeCount
; Index
++)
811 // does it have a type
812 if (NodeDescriptor
->Type
)
815 RtlMoveMemory((PVOID
)&Descriptor
->Topology
->TopologyNodes
[Index
], NodeDescriptor
->Type
, sizeof(GUID
));
818 // does it have a node name
819 if (NodeDescriptor
->Name
)
822 RtlMoveMemory((PVOID
)&Descriptor
->Topology
->TopologyNodesNames
[Index
], NodeDescriptor
->Name
, sizeof(GUID
));
825 // check if has an automation table
826 if (NodeDescriptor
->AutomationTable
)
829 PropertyItem
= (PPCPROPERTY_ITEM
)NodeDescriptor
->AutomationTable
->Properties
;
831 // copy all node properties into the global property set
832 for(SubIndex
= 0; SubIndex
< NodeDescriptor
->AutomationTable
->PropertyCount
; SubIndex
++)
834 // add to property set
835 Status
= PcAddToPropertyTable(Descriptor
, PropertyItem
, TRUE
);
838 if (Status
!= STATUS_SUCCESS
)
844 // move to next property item
845 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ NodeDescriptor
->AutomationTable
->PropertyItemSize
);
849 // move to next descriptor
850 NodeDescriptor
= (PPCNODE_DESCRIPTOR
)((ULONG_PTR
)NodeDescriptor
+ FilterDescription
->NodeSize
);
853 // now store the topology node count
854 Descriptor
->Topology
->TopologyNodesCount
= FilterDescription
->NodeCount
;
858 Descriptor
->DeviceDescriptor
= FilterDescription
;
861 *OutSubdeviceDescriptor
= Descriptor
;
863 return STATUS_SUCCESS
;
868 if (Descriptor
->Interfaces
)
869 FreeItem(Descriptor
->Interfaces
, TAG_PORTCLASS
);
871 if (Descriptor
->Factory
.KsPinDescriptor
)
872 FreeItem(Descriptor
->Factory
.KsPinDescriptor
, TAG_PORTCLASS
);
874 FreeItem(Descriptor
, TAG_PORTCLASS
);
881 PcValidateConnectRequest(
883 IN KSPIN_FACTORY
* Factory
,
884 OUT PKSPIN_CONNECT
* Connect
)
886 return KsValidateConnectRequest(Irp
, Factory
->PinDescriptorCount
, Factory
->KsPinDescriptor
, Connect
);