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