ReactOS 0.4.17-dev-683-g0dafdc5
undoc.cpp
Go to the documentation of this file.
1/*
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
7 */
8
9#include "private.hpp"
10
11#define NDEBUG
12#include <debug.h>
13
18 PIRP Irp)
19{
22}
23
24IIrpTarget *
28{
30
31 // IrpTarget is stored in FsContext
32 return (IIrpTarget*)FileObject->FsContext;
33}
34
35IIrpTarget *
38 PIRP Irp)
39{
40 PIO_STACK_LOCATION IoStack;
41
42 // get current irp stack location
44
45 // IIrpTarget is stored in Context member
46 return (IIrpTarget*)IoStack->FileObject->FsContext;
47}
48
52 IN PIRP Irp,
54{
55 // store descriptor
56 KSEVENT_ITEM_IRP_STORAGE(Irp) = (PKSEVENT_ITEM)Descriptor;
57
58 // FIXME seh probing
59 return KsEnableEvent(Irp, Descriptor->EventSetCount, Descriptor->EventSet, NULL, KSEVENTS_NONE, NULL);
60}
61
65 IN PIRP Irp,
67{
68 // store descriptor
69 KSEVENT_ITEM_IRP_STORAGE(Irp) = (PKSEVENT_ITEM)Descriptor;
70
71 // FIXME seh probing
72
73 return KsDisableEvent(Irp, Descriptor->EventList, KSEVENTS_SPINLOCK, (PVOID)Descriptor->EventListLock);
74}
75
79 IN PIRP Irp,
80 IN ULONG PropertySetCount,
81 IN PKSPROPERTY_SET PropertySet,
82 IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)
83{
84 PIO_STACK_LOCATION IoStack;
85
86 // get current irp stack location
88
89 if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY))
90 {
91 // certainly an invalid request
93 }
94
95 // store device descriptor
96 KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor;
97
98 // then try KsPropertyHandler
99 return KsPropertyHandler(Irp, PropertySetCount, PropertySet);
100}
101
102VOID
103NTAPI
106 LONG Unknown2,
109{
111}
112
115 PVOID Ptr,
116 LONG Unknown2,
122 LONG Unknown7)
123{
126}
127
129NTAPI
131 IN PIRP Irp,
134{
135 PPCPROPERTY_REQUEST PropertyRequest;
139 PKSNODEPROPERTY NodeProperty;
140 PKSPROPERTY_SET PropertySet;
142 PPCAUTOMATION_TABLE NodeAutomation;
143 PIO_STACK_LOCATION IoStack;
144 ULONG InstanceSize, ValueSize, Index;
147
148 // allocate a property request
150 if (!PropertyRequest)
152
153 // grab device descriptor
154 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
155
156 // get current irp stack
158
159 // get input property request
161
162 // get property set
163 PropertySet = (PKSPROPERTY_SET)KSPROPERTY_SET_IRP_STORAGE(Irp);
164
165 // sanity check
167 PC_ASSERT(Descriptor->UnknownMiniport);
168
169 // get instance / value size
170 InstanceSize = IoStack->Parameters.DeviceIoControl.InputBufferLength;
172 ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
173
174 // initialize property request
175 PropertyRequest->MajorTarget = Descriptor->UnknownMiniport;
176 PropertyRequest->MinorTarget = Descriptor->UnknownStream;
177 PropertyRequest->Irp = Irp;
178 PropertyRequest->Verb = Property->Flags;
179
180 // check if this is filter / pin property request
181 if (!(Property->Flags & KSPROPERTY_TYPE_TOPOLOGY))
182 {
183 // adjust input buffer size
184 InstanceSize -= sizeof(KSPROPERTY);
186
187 // filter / pin property request dont use node field
188 PropertyRequest->Node = MAXULONG;
189 }
190 else if (InstanceSize >= sizeof(KSNODEPROPERTY))
191 {
192 // request is for a node
193 InstanceSize -= sizeof(KSNODEPROPERTY);
195
196 // cast node property request
197 NodeProperty = (PKSNODEPROPERTY)Request;
198
199 // store node id
200 PropertyRequest->Node = NodeProperty->NodeId;
201 }
202 else
203 {
204 // invalid buffer size
205 FreeItem(PropertyRequest, TAG_PORTCLASS);
207 }
208
209 // store instance size
210 PropertyRequest->InstanceSize = InstanceSize;
211 PropertyRequest->Instance = (InstanceSize != 0 ? Instance : NULL);
212
213 // store value size
214 PropertyRequest->ValueSize = ValueSize;
215 PropertyRequest->Value = Data;
216
217 // now scan the property set for the attached property set item stored in Relations member
218 if (PropertySet)
219 {
220 // sanity check
221 PC_ASSERT(IsEqualGUIDAligned(Property->Set, *PropertySet->Set));
222
223 for(Index = 0; Index < PropertySet->PropertiesCount; Index++)
224 {
225 // check if they got the same property id
226 if (PropertySet->PropertyItem[Index].PropertyId == Property->Id)
227 {
228 // found item
229 PropertyRequest->PropertyItem = (const PCPROPERTY_ITEM*)PropertySet->PropertyItem[Index].Relations;
230
231 // done
232 break;
233 }
234 }
235 }
236
237 // check if there has been a property set item attached
238 if (!PropertyRequest->PropertyItem)
239 {
240 // is topology node id valid
241 if (PropertyRequest->Node < Descriptor->DeviceDescriptor->NodeCount)
242 {
243 // get node descriptor
244 NodeDescriptor = (PPCNODE_DESCRIPTOR) ((ULONG_PTR)Descriptor->DeviceDescriptor->Nodes + PropertyRequest->Node * Descriptor->DeviceDescriptor->NodeSize);
245
246 // get node automation table
247 NodeAutomation = (PPCAUTOMATION_TABLE)NodeDescriptor->AutomationTable;
248
249 // has it got a automation table
250 if (NodeAutomation)
251 {
252 // now scan the properties and check if it supports this request
253 PropertyItem = (PPCPROPERTY_ITEM)NodeAutomation->Properties;
254 for(Index = 0; Index < NodeAutomation->PropertyCount; Index++)
255 {
256 // are they same property
258 {
259 if (PropertyItem->Id == Property->Id)
260 {
261 // found match
262 PropertyRequest->PropertyItem = PropertyItem;
263 DPRINT("Using property item %p\n", PropertyItem);
264 // done
265 break;
266 }
267 }
268
269 // move to next property item
271 }
272 }
273 }
274 }
275
276 if (PropertyRequest->PropertyItem && PropertyRequest->PropertyItem->Handler)
277 {
278 // now call the handler
279 UNICODE_STRING GuidBuffer;
280 RtlStringFromGUID(Property->Set, &GuidBuffer);
281 DPRINT("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",
282 PropertyRequest->Node, PropertyRequest->MajorTarget, PropertyRequest->MinorTarget, GuidBuffer.Buffer, Property->Id, Property->Flags, PropertyRequest->InstanceSize, PropertyRequest->ValueSize,
283 PropertyRequest->PropertyItem->Handler, PropertyRequest, PropertyRequest->PropertyItem->Flags, PropertyRequest->PropertyItem->Id);
284 RtlFreeUnicodeString(&GuidBuffer);
285 Status = PropertyRequest->PropertyItem->Handler(PropertyRequest);
286 DPRINT("Status %lx ValueSize %lu Information %lu\n", Status, PropertyRequest->ValueSize, Irp->IoStatus.Information);
287 Irp->IoStatus.Information = PropertyRequest->ValueSize;
288
289 if (Status != STATUS_PENDING)
290 {
291 // free property request
292 FreeItem(PropertyRequest, TAG_PORTCLASS);
293 }
294 }
295 else
296 {
297 FreeItem(PropertyRequest, TAG_PORTCLASS);
299 }
300
301 /* done */
302 return Status;
303}
304
307 IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor,
309 IN ULONG bNode)
310{
311 ULONG bFound = FALSE;
312 ULONG Index, PropertySetIndex, PropertySetItemIndex;
313 PKSPROPERTY_SET NewPropertySet;
314 PKSPROPERTY_ITEM FilterPropertyItem, NewFilterPropertyItem;
315 LPGUID Guid;
316 //UNICODE_STRING GuidBuffer;
317
318ASSERT(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);
321
322 //DPRINT1("FilterPropertySetCount %lu\n", SubDeviceDescriptor->FilterPropertySetCount);
323 // first step check if the property set is present already
324 for(Index = 0; Index < SubDeviceDescriptor->FilterPropertySetCount; Index++)
325 {
326
327 //RtlStringFromGUID(*SubDeviceDescriptor->FilterPropertySet[Index].Set, &GuidBuffer);
328 //DPRINT1("FilterProperty Set %S PropertyCount %lu\n", GuidBuffer.Buffer, SubDeviceDescriptor->FilterPropertySet[Index].PropertiesCount);
329 if (IsEqualGUIDAligned(*SubDeviceDescriptor->FilterPropertySet[Index].Set, *PropertyItem->Set))
330 {
331 // property set is already present
332 bFound = TRUE;
333 PropertySetIndex = Index;
334
335 // break out
336 break;
337 }
338 }
339
340 // is the property set present
341 if (!bFound)
342 {
343 // need to allocate a property set
344 NewPropertySet = (PKSPROPERTY_SET)AllocateItem(NonPagedPool, (SubDeviceDescriptor->FilterPropertySetCount + 1) * sizeof(KSPROPERTY_SET), TAG_PORTCLASS);
345 if (!NewPropertySet)
346 {
347 // out of memory
349 }
350
351 // need to allocate property set guid
353 if (!Guid)
354 {
355 // out of memory
356 FreeItem(NewPropertySet, TAG_PORTCLASS);
358 }
359
360 // are any existing property sets
361 if (SubDeviceDescriptor->FilterPropertySetCount)
362 {
363 // copy property sets
364 RtlMoveMemory(NewPropertySet, SubDeviceDescriptor->FilterPropertySet, SubDeviceDescriptor->FilterPropertySetCount * sizeof(KSPROPERTY_SET));
365
366 // release memory
367 FreeItem(SubDeviceDescriptor->FilterPropertySet, TAG_PORTCLASS);
368 }
369
370 // store new property set descriptors
371 SubDeviceDescriptor->FilterPropertySet = NewPropertySet;
372
373 // store index
374 PropertySetIndex = SubDeviceDescriptor->FilterPropertySetCount;
375
376 // increment property set count
377 SubDeviceDescriptor->FilterPropertySetCount++;
378
379 // copy property guid
380 RtlMoveMemory(Guid, PropertyItem->Set, sizeof(GUID));
381
382 // initialize property set
383 SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].Set = Guid;
384 SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount = 0;
385 }
386
387 // as the property set has been identified, now search for duplicate property set item entries
388 FilterPropertyItem = (PKSPROPERTY_ITEM)SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem;
389 bFound = FALSE;
390
391 for(Index = 0; Index < SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount; Index++)
392 {
393 // now search for an equal property set item
394 if (FilterPropertyItem->PropertyId == PropertyItem->Id)
395 {
396 // found existing property set item
397 bFound = TRUE;
398 PropertySetItemIndex = Index;
399 break;
400 }
401
402 // move to next entry
404 }
405
406 if (!bFound)
407 {
408 // need to allocate memory for new property set item
409 NewFilterPropertyItem = (PKSPROPERTY_ITEM)AllocateItem(NonPagedPool, (SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount + 1) * sizeof(KSPROPERTY_ITEM), TAG_PORTCLASS);
410 if (!NewFilterPropertyItem)
411 {
412 // out of memory
414 }
415
416 // are any existing property set items
417 if (SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount)
418 {
419 // copy property item sets
420 RtlMoveMemory(NewFilterPropertyItem,
421 (PVOID)SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem,
422 SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount * sizeof(KSPROPERTY_ITEM));
423
424 // release old descriptors
425 FreeItem((PVOID)SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem, TAG_PORTCLASS);
426 }
427
428 // store new descriptor
429 SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem = NewFilterPropertyItem;
430
431 // store index
432 PropertySetItemIndex = SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount;
433
434 // increment property item set count
435 SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount++;
436
437 // now initialize property item
438 FilterPropertyItem = (PKSPROPERTY_ITEM)&SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem[PropertySetItemIndex];
439 FilterPropertyItem->PropertyId = PropertyItem->Id;
440 FilterPropertyItem->MinProperty = sizeof(KSPROPERTY);
441 FilterPropertyItem->MinData = 0;
442
443 // are any set operations supported
445 {
446 // setup handler
447 FilterPropertyItem->SetPropertyHandler = PropertyItemDispatch;
448 }
449
450 // are set operation supported
452 {
453 // setup handler
454 FilterPropertyItem->GetPropertyHandler = PropertyItemDispatch;
455 }
456
457 // are get operations supported
459 {
460 // setup handler
461 FilterPropertyItem->GetPropertyHandler = PropertyItemDispatch;
462 }
463
464 // are basic support operations supported
466 {
467 // setup handler
469 }
470
471 if (!bNode)
472 {
473 // store property item in relations
474 // only store property item of filter properties / pin properties
475 // because filter & pin properties do not require a specific context
476 // on the other hand node properties are specifically bound to a node
477
478 FilterPropertyItem->Relations = (const KSPROPERTY*)PropertyItem;
479 }
480 }
481 else
482 {
483 // property set item handler already present
484
485 if (bNode)
486 {
487 // filter & pin properties should not be exposed on a node
488 ASSERT(SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem[PropertySetItemIndex].Relations == NULL);
489 }
490 else
491 {
492 // node properties should not be exposed on a filter & pin
493 ASSERT(SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem[PropertySetItemIndex].Relations != NULL);
494 }
495 }
496
497 // done
498 return STATUS_SUCCESS;
499}
500
504 LONG Unknown2,
507{
510}
511
512#if DBG
513VOID
514DumpAutomationTable(
515 IN PPCAUTOMATION_TABLE AutomationTable,
516 IN LPCWSTR DebugPrefix,
517 IN LPCWSTR DebugIndentation)
518{
520 PPCEVENT_ITEM EventItem;
521 PPCMETHOD_ITEM MethodItem;
522 ULONG Index;
524
525 if (!AutomationTable)
526 {
527 // no table
528 return;
529 }
530
531 DPRINT("=====================================================================\n");
532 DPRINT("%S%S AutomationTable %p\n", DebugIndentation, DebugPrefix, AutomationTable);
533 DPRINT("%S%S PropertyCount %lu\n", DebugIndentation, DebugPrefix, AutomationTable->PropertyCount);
534 DPRINT("%S%S EventCount %lu\n", DebugIndentation, DebugPrefix, AutomationTable->EventCount);
535 DPRINT("%S%S MethodCount %lu\n", DebugIndentation, DebugPrefix, AutomationTable->MethodCount);
536
537 // print properties
538 if (AutomationTable->PropertyCount)
539 {
540 if (AutomationTable->PropertyItemSize >= sizeof(PCPROPERTY_ITEM))
541 {
542 // get property item
543 PropertyItem = (PPCPROPERTY_ITEM)AutomationTable->Properties;
544
545 // sanity check
547
548 // display all properties associated
549 for (Index = 0; Index < AutomationTable->PropertyCount; Index++)
550 {
551 // convert to printable string
553 DPRINT("%SPropertyItemIndex %lu %p GUID %S Id %u Flags %x\n", DebugIndentation, Index, PropertyItem, GuidString.Buffer, PropertyItem->Id, PropertyItem->Flags);
555 // move to next item
556 PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + AutomationTable->PropertyItemSize);
557 }
558
559 }
560 else
561 {
562 DPRINT1("DRIVER BUG: property item must be at least %lu but got %lu\n", sizeof(PCPROPERTY_ITEM), AutomationTable->PropertyItemSize);
563 }
564 }
565
566 // print events
567 if (AutomationTable->EventCount)
568 {
569 if (AutomationTable->EventItemSize >= sizeof(PCEVENT_ITEM))
570 {
571 // get first event item
572 EventItem = (PPCEVENT_ITEM)AutomationTable->Events;
573
574 // sanity check
575 ASSERT(EventItem);
576
577 for (Index = 0; Index < AutomationTable->EventCount; Index++)
578 {
579 // convert to printable string
580 RtlStringFromGUID(*EventItem->Set, &GuidString);
581 DPRINT("%SEventItemIndex %lu %p GUID %S Id %u Flags %x\n", DebugIndentation, Index, EventItem, GuidString.Buffer, EventItem->Id, EventItem->Flags);
583
584 // move to next item
585 EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + AutomationTable->EventItemSize);
586 }
587 }
588 else
589 {
590 DPRINT1("DRIVER BUG: event item must be at least %lu but got %lu\n", sizeof(PCEVENT_ITEM), AutomationTable->EventItemSize);
591 }
592 }
593
594 // print methods
595 if (AutomationTable->MethodCount)
596 {
597 if (AutomationTable->MethodItemSize >= sizeof(PCMETHOD_ITEM))
598 {
599 // get first event item
600 MethodItem = (PPCMETHOD_ITEM)AutomationTable->Methods;
601
602 // sanity check
603 ASSERT(MethodItem);
604
605 for (Index = 0; Index < AutomationTable->MethodCount; Index++)
606 {
607 // convert to printable string
608 RtlStringFromGUID(*MethodItem->Set, &GuidString);
609 DPRINT("%SMethodItemIndex %lu %p GUID %S Id %u Flags %x\n", DebugIndentation, Index, MethodItem, GuidString.Buffer, MethodItem->Id, MethodItem->Flags);
611
612 // move to next item
613 MethodItem = (PPCMETHOD_ITEM)((ULONG_PTR)MethodItem + AutomationTable->MethodItemSize);
614 }
615
616 }
617 else
618 {
619 DPRINT1("DRIVER BUG: method item must be at least %lu but got %lu\n", sizeof(PCEVENT_ITEM), AutomationTable->MethodItemSize);
620 }
621 }
622 DPRINT("=====================================================================\n");
623}
624
625VOID
626DumpFilterDescriptor(
627 IN PPCFILTER_DESCRIPTOR FilterDescription)
628{
629 ULONG Index;
630 WCHAR Buffer[30];
632 PPCPIN_DESCRIPTOR PinDescriptor;
634
635 DPRINT("======================\n");
636 DPRINT("Descriptor Automation Table %p\n",FilterDescription->AutomationTable);
637 DPRINT("PinCount %lu PinSize %lu StandardSize %lu\n", FilterDescription->PinCount, FilterDescription->PinSize, sizeof(PCPIN_DESCRIPTOR));
638 DPRINT("NodeCount %lu NodeSize %lu StandardSize %lu\n", FilterDescription->NodeCount, FilterDescription->NodeSize, sizeof(PCNODE_DESCRIPTOR));
639
640 // dump filter description table
641 DumpAutomationTable((PPCAUTOMATION_TABLE)FilterDescription->AutomationTable, L"Filter", L"");
642
643 if (FilterDescription->PinCount)
644 {
645 if (FilterDescription->PinSize >= sizeof(PCPIN_DESCRIPTOR))
646 {
647 // get first pin
648 PinDescriptor = (PPCPIN_DESCRIPTOR)FilterDescription->Pins;
649
650 // sanity check
651 ASSERT(PinDescriptor);
652
653 for (Index = 0; Index < FilterDescription->PinCount; Index++)
654 {
655 // print prefix
656 _swprintf(Buffer, L"PinIndex %lu", Index);
657
658 DPRINT("PinIndex %lu\n", Index);
659 DPRINT("DataFlow %lu, Communication %lu\n",
660 PinDescriptor->KsPinDescriptor.DataFlow, PinDescriptor->KsPinDescriptor.Communication);
661 if (PinDescriptor->KsPinDescriptor.Category)
662 {
663 RtlStringFromGUID(*PinDescriptor->KsPinDescriptor.Category, &GuidString);
664 DPRINT("Category %S\n", GuidString.Buffer);
666 }
667 if (PinDescriptor->KsPinDescriptor.Name)
668 {
669 RtlStringFromGUID(*PinDescriptor->KsPinDescriptor.Name, &GuidString);
670 DPRINT("Name %S\n", GuidString.Buffer);
672 }
673
674 // dump automation table
675 DumpAutomationTable((PPCAUTOMATION_TABLE)PinDescriptor->AutomationTable, Buffer, L" ");
676
677 // move to next pin descriptor
678 PinDescriptor = (PPCPIN_DESCRIPTOR)((ULONG_PTR)PinDescriptor + FilterDescription->PinSize);
679 }
680 }
681 else
682 {
683 DPRINT1("DRIVER BUG: pin size smaller than minimum size\n");
684 }
685 }
686
687 DPRINT("=====================================================================\n");
688
689 if (FilterDescription->Nodes)
690 {
691 if (FilterDescription->NodeSize >= sizeof(PCNODE_DESCRIPTOR))
692 {
693 // get first descriptor
694 NodeDescriptor = (PPCNODE_DESCRIPTOR)FilterDescription->Nodes;
695
696 // sanity check
698
699 for (Index = 0; Index < FilterDescription->NodeCount; Index++)
700 {
701 // print prefix
702 _swprintf(Buffer, L"NodeIndex %lu", Index);
703
704 DPRINT("NodeIndex %lu\n", Index);
705 if (NodeDescriptor->Type)
706 {
708 DPRINT("Type %S\n", GuidString.Buffer);
710 }
711 if (NodeDescriptor->Name)
712 {
714 DPRINT("Name %S\n", GuidString.Buffer);
716 }
717
718 // dump automation table
719 DumpAutomationTable((PPCAUTOMATION_TABLE)NodeDescriptor->AutomationTable, Buffer, L" ");
720
721 // move to next node descriptor
722 NodeDescriptor = (PPCNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescription->NodeSize);
723 }
724 }
725 else
726 {
727 DPRINT1("DRIVER BUG: node size smaller than standard descriptor size\n");
728 }
729 }
730
731 DPRINT("ConnectionCount: %lu\n", FilterDescription->ConnectionCount);
732
733 if (FilterDescription->ConnectionCount)
734 {
735 DPRINT("------ Start of Nodes Connections ----------------\n");
736 for (Index = 0; Index < FilterDescription->ConnectionCount; Index++)
737 {
738 DPRINT("Index %lu FromNode %ld FromPin %ld -> ToNode %ld ToPin %ld\n", Index,
739 FilterDescription->Connections[Index].FromNode,
740 FilterDescription->Connections[Index].FromNodePin,
741 FilterDescription->Connections[Index].ToNode,
742 FilterDescription->Connections[Index].ToNodePin);
743 }
744 DPRINT("------ End of Nodes Connections ----------------\n");
745 }
746 DPRINT("======================\n");
747}
748#endif // DBG
749
751NTAPI
753 OUT SUBDEVICE_DESCRIPTOR ** OutSubdeviceDescriptor,
754 IN ULONG InterfaceCount,
756 IN ULONG IdentifierCount,
758 IN ULONG FilterPropertiesCount,
759 IN KSPROPERTY_SET * FilterProperties,
760 IN ULONG Unknown1,
761 IN ULONG Unknown2,
762 IN ULONG PinPropertiesCount,
763 IN KSPROPERTY_SET * PinProperties,
764 IN ULONG EventSetCount,
765 IN KSEVENT_SET * EventSet,
766 IN PPCFILTER_DESCRIPTOR FilterDescription)
767{
769 ULONG Index, SubIndex;
771 PPCPIN_DESCRIPTOR SrcDescriptor;
774
775 // allocate subdevice descriptor
777 if (!Descriptor)
779
780 // initialize physical / symbolic link connection list
781 InitializeListHead(&Descriptor->SymbolicLinkList);
782 InitializeListHead(&Descriptor->PhysicalConnectionList);
783
784 //FIXME add driver category guids
785 Descriptor->Interfaces = (GUID*)AllocateItem(NonPagedPool, sizeof(GUID) * InterfaceCount, TAG_PORTCLASS);
786 if (!Descriptor->Interfaces)
787 goto cleanup;
788
789 // copy interface guids
790 RtlCopyMemory(Descriptor->Interfaces, InterfaceGuids, sizeof(GUID) * InterfaceCount);
791 Descriptor->InterfaceCount = InterfaceCount;
792
793#if DBG
794 DumpFilterDescriptor(FilterDescription);
795#endif
796
797 // are any property sets supported by the portcls
798 if (FilterPropertiesCount)
799 {
800 // first allocate filter properties set
801 Descriptor->FilterPropertySet = (PKSPROPERTY_SET)AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * FilterPropertiesCount, TAG_PORTCLASS);
802 if (! Descriptor->FilterPropertySet)
803 goto cleanup;
804
805 // now copy all filter property sets
806 Descriptor->FilterPropertySetCount = FilterPropertiesCount;
807 for(Index = 0; Index < FilterPropertiesCount; Index++)
808 {
809 // copy property set
810 RtlMoveMemory(&Descriptor->FilterPropertySet[Index], &FilterProperties[Index], sizeof(KSPROPERTY_SET));
811
812 if (Descriptor->FilterPropertySet[Index].PropertiesCount)
813 {
814 // copy property items to make sure they are dynamically allocated
815 Descriptor->FilterPropertySet[Index].PropertyItem = (PKSPROPERTY_ITEM)AllocateItem(NonPagedPool, FilterProperties[Index].PropertiesCount * sizeof(KSPROPERTY_ITEM), TAG_PORTCLASS);
816 if (!Descriptor->FilterPropertySet[Index].PropertyItem)
817 {
818 // no memory
819 goto cleanup;
820 }
821
822 // copy filter property items
823 RtlMoveMemory((PVOID)Descriptor->FilterPropertySet[Index].PropertyItem, FilterProperties[Index].PropertyItem, FilterProperties[Index].PropertiesCount * sizeof(KSPROPERTY_ITEM));
824 }
825 }
826 }
827
828 // now check if the filter descriptor supports filter properties
829 if (FilterDescription->AutomationTable)
830 {
831 // get first entry
832 PropertyItem = (PPCPROPERTY_ITEM)FilterDescription->AutomationTable->Properties;
833
834 // copy driver filter property sets
835 for(Index = 0; Index < FilterDescription->AutomationTable->PropertyCount; Index++)
836 {
837 // add the property item
839
840 // check for success
841 if (Status != STATUS_SUCCESS)
842 {
843 // goto cleanup
844 goto cleanup;
845 }
846
847 // move to next entry
848 PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + FilterDescription->AutomationTable->PropertyItemSize);
849 }
850 }
851
852 // check if the filter has pins
853 if (FilterDescription->PinCount)
854 {
855 // allocate pin factory descriptors
856 Descriptor->Factory.KsPinDescriptor = (PKSPIN_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR) * FilterDescription->PinCount, TAG_PORTCLASS);
857 if (!Descriptor->Factory.KsPinDescriptor)
858 goto cleanup;
859
860 // allocate pin instance info
861 Descriptor->Factory.Instances = (PPIN_INSTANCE_INFO)AllocateItem(NonPagedPool, FilterDescription->PinCount * sizeof(PIN_INSTANCE_INFO), TAG_PORTCLASS);
862 if (!Descriptor->Factory.Instances)
863 goto cleanup;
864
865 // initialize pin factory descriptor
866 Descriptor->Factory.PinDescriptorCount = FilterDescription->PinCount;
867 Descriptor->Factory.PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR);
868
869 // grab first entry
870 SrcDescriptor = (PPCPIN_DESCRIPTOR)FilterDescription->Pins;
871
872 // copy pin factories
873 for(Index = 0; Index < FilterDescription->PinCount; Index++)
874 {
875 // copy pin descriptor
876 RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &SrcDescriptor->KsPinDescriptor, sizeof(KSPIN_DESCRIPTOR));
877
878 // initialize pin factory instance data
879 Descriptor->Factory.Instances[Index].CurrentPinInstanceCount = 0;
880 Descriptor->Factory.Instances[Index].MaxFilterInstanceCount = SrcDescriptor->MaxFilterInstanceCount;
881 Descriptor->Factory.Instances[Index].MaxGlobalInstanceCount = SrcDescriptor->MaxGlobalInstanceCount;
882 Descriptor->Factory.Instances[Index].MinFilterInstanceCount = SrcDescriptor->MinFilterInstanceCount;
883
884 // check if the descriptor has an automation table
885 if (SrcDescriptor->AutomationTable)
886 {
887 // it has, grab first entry
889
890 // now add all supported property items
891 for(SubIndex = 0; SubIndex < SrcDescriptor->AutomationTable->PropertyCount; SubIndex++)
892 {
893 // add the property item to the table
895
896 // check for success
897 if (Status != STATUS_SUCCESS)
898 {
899 // goto cleanup
900 goto cleanup;
901 }
902
903 // move to next entry
905 }
906 }
907
908 // move to next entry
909 SrcDescriptor = (PPCPIN_DESCRIPTOR)((ULONG_PTR)SrcDescriptor + FilterDescription->PinSize);
910 }
911 }
912
913 // allocate topology descriptor
915 if (!Descriptor->Topology)
916 goto cleanup;
917
918 // are there any connections
919 if (FilterDescription->ConnectionCount)
920 {
921 // allocate connection descriptor
922 Descriptor->Topology->TopologyConnections = (PKSTOPOLOGY_CONNECTION)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY_CONNECTION) * FilterDescription->ConnectionCount, TAG_PORTCLASS);
923 if (!Descriptor->Topology->TopologyConnections)
924 goto cleanup;
925
926 // copy connection descriptor
927 RtlMoveMemory((PVOID)Descriptor->Topology->TopologyConnections, FilterDescription->Connections, FilterDescription->ConnectionCount * sizeof(PCCONNECTION_DESCRIPTOR));
928
929 // store connection count
930 Descriptor->Topology->TopologyConnectionsCount = FilterDescription->ConnectionCount;
931 }
932
933 // does the filter have nodes
934 if (FilterDescription->NodeCount)
935 {
936 // allocate topology node types array
937 Descriptor->Topology->TopologyNodes = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS);
938 if (!Descriptor->Topology->TopologyNodes)
939 goto cleanup;
940
941 // allocate topology node names array
942 Descriptor->Topology->TopologyNodesNames = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS);
943 if (!Descriptor->Topology->TopologyNodesNames)
944 goto cleanup;
945
946 // grab first entry
947 NodeDescriptor = (PPCNODE_DESCRIPTOR)FilterDescription->Nodes;
948
949 // iterate all nodes and copy node types / names and node properties
950 for(Index = 0; Index < FilterDescription->NodeCount; Index++)
951 {
952 // does it have a type
953 if (NodeDescriptor->Type)
954 {
955 // copy node type
956 RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodes[Index], NodeDescriptor->Type, sizeof(GUID));
957 }
958
959 // does it have a node name
960 if (NodeDescriptor->Name)
961 {
962 // copy node name
963 RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodesNames[Index], NodeDescriptor->Name, sizeof(GUID));
964 }
965
966 // check if has an automation table
967 if (NodeDescriptor->AutomationTable)
968 {
969 // grab first entry
970 PropertyItem = (PPCPROPERTY_ITEM)NodeDescriptor->AutomationTable->Properties;
971
972 // copy all node properties into the global property set
973 for(SubIndex = 0; SubIndex < NodeDescriptor->AutomationTable->PropertyCount; SubIndex++)
974 {
975 // add to property set
977
978 // check for success
979 if (Status != STATUS_SUCCESS)
980 {
981 // failed
982 goto cleanup;
983 }
984
985 // move to next property item
986 PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + NodeDescriptor->AutomationTable->PropertyItemSize);
987 }
988 }
989
990 // move to next descriptor
991 NodeDescriptor = (PPCNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescription->NodeSize);
992 }
993
994 // now store the topology node count
995 Descriptor->Topology->TopologyNodesCount = FilterDescription->NodeCount;
996 }
997
998 // store descriptor
999 Descriptor->DeviceDescriptor = FilterDescription;
1000
1001 // store result
1002 *OutSubdeviceDescriptor = Descriptor;
1003 // done
1004 return STATUS_SUCCESS;
1005
1006cleanup:
1007 if (Descriptor)
1008 {
1009 if (Descriptor->Interfaces)
1010 FreeItem(Descriptor->Interfaces, TAG_PORTCLASS);
1011
1012 if (Descriptor->Factory.KsPinDescriptor)
1013 FreeItem(Descriptor->Factory.KsPinDescriptor, TAG_PORTCLASS);
1014
1016 }
1017 return Status;
1018}
1019
1021NTAPI
1023 IN PIRP Irp,
1026{
1027 return KsValidateConnectRequest(Irp, Factory->PinDescriptorCount, Factory->KsPinDescriptor, Connect);
1028}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
PRTL_UNICODE_STRING_BUFFER PULONG PULONG Unknown4
@ Identifier
Definition: asmpp.cpp:95
struct SUBDEVICE_DESCRIPTOR * PSUBDEVICE_DESCRIPTOR
struct PIN_INSTANCE_INFO * PPIN_INSTANCE_INFO
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
KSPROPERTY_ITEM FilterPropertyItem[]
Definition: bdasup.c:17
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
Definition: bufpool.h:45
KSDDKAPI NTSTATUS NTAPI KsValidateConnectRequest(IN PIRP Irp, IN ULONG DescriptorsCount, IN KSPIN_DESCRIPTOR *Descriptor, OUT PKSPIN_CONNECT *Connect)
Definition: connectivity.c:222
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD IN DWORD IN DWORD IN DWORD Unknown6
Definition: conport.c:40
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD IN DWORD IN DWORD Unknown5
Definition: conport.c:39
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD Unknown3
Definition: conport.c:37
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static void cleanup(void)
Definition: main.c:1335
#define L(x)
Definition: resources.c:13
KSDDKAPI NTSTATUS NTAPI KsEnableEvent(IN PIRP Irp, IN ULONG EventSetsCount, IN KSEVENT_SET *EventSet, IN OUT PLIST_ENTRY EventsList OPTIONAL, IN KSEVENTS_LOCKTYPE EventsFlags OPTIONAL, IN PVOID EventsLock OPTIONAL)
Definition: event.c:387
KSDDKAPI NTSTATUS NTAPI KsDisableEvent(IN PIRP Irp, IN OUT PLIST_ENTRY EventsList, IN KSEVENTS_LOCKTYPE EventsFlags, IN PVOID EventsLock)
Definition: event.c:469
KSPROPERTY_SET FilterPropertySet[]
Definition: filter.c:63
KSDDKAPI NTSTATUS NTAPI KsPropertyHandler(IN PIRP Irp, IN ULONG PropertySetsCount, IN const KSPROPERTY_SET *PropertySet)
Definition: property.c:358
#define KSPROPERTY_TYPE_TOPOLOGY
Definition: dmksctrl.h:53
struct KSIDENTIFIER KSPROPERTY
struct KSIDENTIFIER * PKSPROPERTY
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
Status
Definition: gdiplustypes.h:24
@ Unknown
Definition: i8042prt.h:114
struct KSTOPOLOGY * PKSTOPOLOGY
@ KSEVENTS_SPINLOCK
Definition: ks.h:1233
@ KSEVENTS_NONE
Definition: ks.h:1232
_In_ PKSPIN_CONNECT Connect
Definition: ks.h:4536
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:29
VOID FreeItem(IN PVOID Item)
Definition: misc.c:37
struct KSNODEPROPERTY * PKSNODEPROPERTY
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
static PWSTR GuidString
Definition: apphelp.c:93
#define _swprintf(buf, format,...)
Definition: sprintf.c:56
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:772
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
static GUID InterfaceGuids[3]
Definition: port_dmus.cpp:42
struct _PCPROPERTY_REQUEST * PPCPROPERTY_REQUEST
Definition: portcls.h:230
#define PCPROPERTY_ITEM_FLAG_SET
Definition: portcls.h:241
struct PCPROPERTY_ITEM * PPCPROPERTY_ITEM
struct _PCMETHOD_ITEM * PPCMETHOD_ITEM
#define PCPROPERTY_ITEM_FLAG_GET
Definition: portcls.h:240
struct PCAUTOMATION_TABLE * PPCAUTOMATION_TABLE
struct _PCEVENT_ITEM * PPCEVENT_ITEM
struct PCNODE_DESCRIPTOR * PPCNODE_DESCRIPTOR
struct PCPIN_DESCRIPTOR * PPCPIN_DESCRIPTOR
#define PCPROPERTY_ITEM_FLAG_BASICSUPPORT
Definition: portcls.h:242
#define TAG_PORTCLASS
Definition: private.hpp:24
#define PC_ASSERT(exp)
Definition: private.hpp:26
GUID * LPGUID
Definition: guiddef.h:81
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define DPRINT
Definition: sndvol32.h:73
const KSNODE_DESCRIPTOR NodeDescriptor[]
Definition: splitter.c:217
_In_ const GUID _In_ ULONG PinCount
Definition: strmini.h:505
ULONG NodeId
Definition: ksmedia.h:1234
const PCPROPERTY_ITEM * Properties
Definition: portcls.h:321
ULONG PropertyItemSize
Definition: portcls.h:319
ULONG MaxGlobalInstanceCount
Definition: portcls.h:339
ULONG MinFilterInstanceCount
Definition: portcls.h:341
KSPIN_DESCRIPTOR KsPinDescriptor
Definition: portcls.h:343
const PCAUTOMATION_TABLE * AutomationTable
Definition: portcls.h:342
ULONG MaxFilterInstanceCount
Definition: portcls.h:340
PCPFNPROPERTY_HANDLER Handler
Definition: portcls.h:253
union _IO_STACK_LOCATION::@1708 Parameters
PFILE_OBJECT FileObject
Definition: iotypes.h:3171
struct _IO_STACK_LOCATION::@1708::@1709 DeviceIoControl
ULONG Flags
Definition: portcls.h:279
ULONG Id
Definition: portcls.h:278
const GUID * Set
Definition: portcls.h:277
const GUID * Set
Definition: portcls.h:300
ULONG Flags
Definition: portcls.h:302
PUNKNOWN MinorTarget
Definition: portcls.h:259
const PCPROPERTY_ITEM * PropertyItem
Definition: portcls.h:261
PUNKNOWN MajorTarget
Definition: portcls.h:258
#define STATUS_PENDING
Definition: telnetd.h:14
#define MAXULONG
Definition: typedefs.h:251
const uint16_t * LPCWSTR
Definition: typedefs.h:57
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS PcCaptureFormat(LONG Unknown, LONG Unknown2, LONG Unknown3, LONG Unknown4)
Definition: undoc.cpp:502
NTSTATUS NTAPI PcValidateConnectRequest(IN PIRP Irp, IN KSPIN_FACTORY *Factory, OUT PKSPIN_CONNECT *Connect)
Definition: undoc.cpp:1022
IIrpTarget *NTAPI KsoGetIrpTargetFromFileObject(PFILE_OBJECT FileObject)
Definition: undoc.cpp:26
NTSTATUS NTAPI PcHandlePropertyWithTable(IN PIRP Irp, IN ULONG PropertySetCount, IN PKSPROPERTY_SET PropertySet, IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)
Definition: undoc.cpp:78
NTSTATUS NTAPI KsoDispatchCreateWithGenericFactory(LONG Unknown, PIRP Irp)
Definition: undoc.cpp:16
NTSTATUS NTAPI PropertyItemDispatch(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data)
Definition: undoc.cpp:130
NTSTATUS NTAPI PcCreateSubdeviceDescriptor(OUT SUBDEVICE_DESCRIPTOR **OutSubdeviceDescriptor, IN ULONG InterfaceCount, IN GUID *InterfaceGuids, IN ULONG IdentifierCount, IN KSIDENTIFIER *Identifier, IN ULONG FilterPropertiesCount, IN KSPROPERTY_SET *FilterProperties, IN ULONG Unknown1, IN ULONG Unknown2, IN ULONG PinPropertiesCount, IN KSPROPERTY_SET *PinProperties, IN ULONG EventSetCount, IN KSEVENT_SET *EventSet, IN PPCFILTER_DESCRIPTOR FilterDescription)
Definition: undoc.cpp:752
IIrpTarget *NTAPI KsoGetIrpTargetFromIrp(PIRP Irp)
Definition: undoc.cpp:37
NTSTATUS NTAPI PcHandleDisableEventWithTable(IN PIRP Irp, IN PSUBDEVICE_DESCRIPTOR Descriptor)
Definition: undoc.cpp:64
NTSTATUS PcAddToPropertyTable(IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor, IN PPCPROPERTY_ITEM PropertyItem, IN ULONG bNode)
Definition: undoc.cpp:306
NTSTATUS PcAddToEventTable(PVOID Ptr, LONG Unknown2, ULONG Length, LONG Unknown3, LONG Unknown4, LONG Unknown5, LONG Unknown6, LONG Unknown7)
Definition: undoc.cpp:114
NTSTATUS NTAPI PcHandleEnableEventWithTable(IN PIRP Irp, IN PSUBDEVICE_DESCRIPTOR Descriptor)
Definition: undoc.cpp:51
VOID NTAPI PcAcquireFormatResources(LONG Unknown, LONG Unknown2, LONG Unknown3, LONG Unknown4)
Definition: undoc.cpp:104
struct KSTOPOLOGY_CONNECTION * PKSTOPOLOGY_CONNECTION
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
_Must_inspect_result_ _In_ WDFOBJECT _In_ CONST GUID * Guid
Definition: wdfobject.h:762
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_WMI_INSTANCE_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_opt_ WDFWMIINSTANCE * Instance
Definition: wdfwmi.h:481
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:235
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
* PFILE_OBJECT
Definition: iotypes.h:1998