ReactOS 0.4.15-dev-7889-g76290a6
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,
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
512VOID
514 IN PPCAUTOMATION_TABLE AutomationTable,
515 IN LPCWSTR DebugPrefix,
516 IN LPCWSTR DebugIndentation)
517{
519 PPCEVENT_ITEM EventItem;
520 PPCMETHOD_ITEM MethodItem;
521 ULONG Index;
523
524 if (!AutomationTable)
525 {
526 // no table
527 return;
528 }
529
530 DPRINT("=====================================================================\n");
531 DPRINT("%S%S AutomationTable %p\n", DebugIndentation, DebugPrefix, AutomationTable);
532 DPRINT("%S%S PropertyCount %lu\n", DebugIndentation, DebugPrefix, AutomationTable->PropertyCount);
533 DPRINT("%S%S EventCount %lu\n", DebugIndentation, DebugPrefix, AutomationTable->EventCount);
534 DPRINT("%S%S MethodCount %lu\n", DebugIndentation, DebugPrefix, AutomationTable->MethodCount);
535
536 // print properties
537 if (AutomationTable->PropertyCount)
538 {
539 if (AutomationTable->PropertyItemSize >= sizeof(PCPROPERTY_ITEM))
540 {
541 // get property item
542 PropertyItem = (PPCPROPERTY_ITEM)AutomationTable->Properties;
543
544 // sanity check
546
547 // display all properties associated
548 for(Index = 0; Index < AutomationTable->PropertyCount; Index++)
549 {
550 // convert to printable string
552 DPRINT("%SPropertyItemIndex %lu %p GUID %S Id %u Flags %x\n", DebugIndentation, Index, PropertyItem, GuidString.Buffer, PropertyItem->Id, PropertyItem->Flags);
554 // move to next item
555 PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + AutomationTable->PropertyItemSize);
556 }
557
558 }
559 else
560 {
561 DPRINT1("DRIVER BUG: property item must be at least %lu but got %lu\n", sizeof(PCPROPERTY_ITEM), AutomationTable->PropertyItemSize);
562 }
563 }
564
565 // print events
566 if (AutomationTable->EventCount)
567 {
568 if (AutomationTable->EventItemSize >= sizeof(PCEVENT_ITEM))
569 {
570 // get first event item
571 EventItem = (PPCEVENT_ITEM)AutomationTable->Events;
572
573 // sanity check
574 ASSERT(EventItem);
575
576 for(Index = 0; Index < AutomationTable->EventCount; Index++)
577 {
578 // convert to printable string
579 RtlStringFromGUID(*EventItem->Set, &GuidString);
580 DPRINT("%SEventItemIndex %lu %p GUID %S Id %u Flags %x\n", DebugIndentation, Index, EventItem, GuidString.Buffer, EventItem->Id, EventItem->Flags);
582
583 // move to next item
584 EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + AutomationTable->EventItemSize);
585 }
586 }
587 else
588 {
589 DPRINT1("DRIVER BUG: event item must be at least %lu but got %lu\n", sizeof(PCEVENT_ITEM), AutomationTable->EventItemSize);
590 }
591 }
592
593 // print methods
594 if (AutomationTable->MethodCount)
595 {
596 if (AutomationTable->MethodItemSize >= sizeof(PCMETHOD_ITEM))
597 {
598 // get first event item
599 MethodItem = (PPCMETHOD_ITEM)AutomationTable->Methods;
600
601 // sanity check
602 ASSERT(MethodItem);
603
604 for(Index = 0; Index < AutomationTable->MethodCount; Index++)
605 {
606 // convert to printable string
607 RtlStringFromGUID(*MethodItem->Set, &GuidString);
608 DPRINT("%SMethodItemIndex %lu %p GUID %S Id %u Flags %x\n", DebugIndentation, Index, MethodItem, GuidString.Buffer, MethodItem->Id, MethodItem->Flags);
610
611 // move to next item
612 MethodItem = (PPCMETHOD_ITEM)((ULONG_PTR)MethodItem + AutomationTable->MethodItemSize);
613 }
614
615 }
616 else
617 {
618 DPRINT1("DRIVER BUG: method item must be at least %lu but got %lu\n", sizeof(PCEVENT_ITEM), AutomationTable->MethodItemSize);
619 }
620 }
621 DPRINT("=====================================================================\n");
622}
623
624VOID
626 IN PPCFILTER_DESCRIPTOR FilterDescription)
627{
628 ULONG Index;
629 WCHAR Buffer[30];
630 PPCPIN_DESCRIPTOR PinDescriptor;
632
633 DPRINT("======================\n");
634 DPRINT("Descriptor Automation Table %p\n",FilterDescription->AutomationTable);
635 DPRINT("PinCount %lu PinSize %lu StandardSize %lu\n", FilterDescription->PinCount, FilterDescription->PinSize, sizeof(PCPIN_DESCRIPTOR));
636 DPRINT("NodeCount %lu NodeSize %lu StandardSize %lu\n", FilterDescription->NodeCount, FilterDescription->NodeSize, sizeof(PCNODE_DESCRIPTOR));
637
638 // dump filter description table
639 DumpAutomationTable((PPCAUTOMATION_TABLE)FilterDescription->AutomationTable, L"Filter", L"");
640
641 if (FilterDescription->PinCount)
642 {
643 if (FilterDescription->PinSize >= sizeof(PCPIN_DESCRIPTOR))
644 {
645 // get first pin
646 PinDescriptor = (PPCPIN_DESCRIPTOR)FilterDescription->Pins;
647
648 // sanity check
649 ASSERT(PinDescriptor);
650
651 for(Index = 0; Index < FilterDescription->PinCount; Index++)
652 {
653 // print prefix
654 swprintf(Buffer, L"PinIndex %lu", Index);
655
656 // dump automation table
658
659 // move to next pin descriptor
660 PinDescriptor = (PPCPIN_DESCRIPTOR)((ULONG_PTR)PinDescriptor + FilterDescription->PinSize);
661 }
662 }
663 else
664 {
665 DPRINT1("DRIVER BUG: pin size smaller than minimum size\n");
666 }
667 }
668
669 if (FilterDescription->Nodes)
670 {
671 if (FilterDescription->NodeSize >= sizeof(PCNODE_DESCRIPTOR))
672 {
673 // get first descriptor
674 NodeDescriptor = (PPCNODE_DESCRIPTOR)FilterDescription->Nodes;
675
676 // sanity check
678
679 for(Index = 0; Index < FilterDescription->NodeCount; Index++)
680 {
681 // print prefix
682 swprintf(Buffer, L"NodeIndex %lu", Index);
683
684 // dump automation table
686
687 // move to next node descriptor
688 NodeDescriptor = (PPCNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescription->NodeSize);
689 }
690 }
691 else
692 {
693 DPRINT1("DRIVER BUG: node size smaller than standard descriptor size\n");
694 }
695 }
696
697 DPRINT("ConnectionCount: %lu\n", FilterDescription->ConnectionCount);
698
699 if (FilterDescription->ConnectionCount)
700 {
701 DPRINT("------ Start of Nodes Connections ----------------\n");
702 for(Index = 0; Index < FilterDescription->ConnectionCount; Index++)
703 {
704 DPRINT1("Index %ld FromPin %ld FromNode %ld -> ToPin %ld ToNode %ld\n", Index,
705 FilterDescription->Connections[Index].FromNodePin,
706 FilterDescription->Connections[Index].FromNode,
707 FilterDescription->Connections[Index].ToNodePin,
708 FilterDescription->Connections[Index].ToNode);
709 }
710 DPRINT("------ End of Nodes Connections----------------\n");
711 }
712 DPRINT1("======================\n");
713}
714
716NTAPI
718 OUT SUBDEVICE_DESCRIPTOR ** OutSubdeviceDescriptor,
719 IN ULONG InterfaceCount,
721 IN ULONG IdentifierCount,
723 IN ULONG FilterPropertiesCount,
724 IN KSPROPERTY_SET * FilterProperties,
725 IN ULONG Unknown1,
726 IN ULONG Unknown2,
727 IN ULONG PinPropertiesCount,
728 IN KSPROPERTY_SET * PinProperties,
729 IN ULONG EventSetCount,
730 IN KSEVENT_SET * EventSet,
731 IN PPCFILTER_DESCRIPTOR FilterDescription)
732{
734 ULONG Index, SubIndex;
736 PPCPIN_DESCRIPTOR SrcDescriptor;
739
740 // allocate subdevice descriptor
742 if (!Descriptor)
744
745 // initialize physical / symbolic link connection list
746 InitializeListHead(&Descriptor->SymbolicLinkList);
747 InitializeListHead(&Descriptor->PhysicalConnectionList);
748
749 //FIXME add driver category guids
750 Descriptor->Interfaces = (GUID*)AllocateItem(NonPagedPool, sizeof(GUID) * InterfaceCount, TAG_PORTCLASS);
751 if (!Descriptor->Interfaces)
752 goto cleanup;
753
754 // copy interface guids
755 RtlCopyMemory(Descriptor->Interfaces, InterfaceGuids, sizeof(GUID) * InterfaceCount);
756 Descriptor->InterfaceCount = InterfaceCount;
757
758 //DumpFilterDescriptor(FilterDescription);
759
760 // are any property sets supported by the portcls
761 if (FilterPropertiesCount)
762 {
763 // first allocate filter properties set
764 Descriptor->FilterPropertySet = (PKSPROPERTY_SET)AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * FilterPropertiesCount, TAG_PORTCLASS);
765 if (! Descriptor->FilterPropertySet)
766 goto cleanup;
767
768 // now copy all filter property sets
769 Descriptor->FilterPropertySetCount = FilterPropertiesCount;
770 for(Index = 0; Index < FilterPropertiesCount; Index++)
771 {
772 // copy property set
773 RtlMoveMemory(&Descriptor->FilterPropertySet[Index], &FilterProperties[Index], sizeof(KSPROPERTY_SET));
774
775 if (Descriptor->FilterPropertySet[Index].PropertiesCount)
776 {
777 // copy property items to make sure they are dynamically allocated
778 Descriptor->FilterPropertySet[Index].PropertyItem = (PKSPROPERTY_ITEM)AllocateItem(NonPagedPool, FilterProperties[Index].PropertiesCount * sizeof(KSPROPERTY_ITEM), TAG_PORTCLASS);
779 if (!Descriptor->FilterPropertySet[Index].PropertyItem)
780 {
781 // no memory
782 goto cleanup;
783 }
784
785 // copy filter property items
786 RtlMoveMemory((PVOID)Descriptor->FilterPropertySet[Index].PropertyItem, FilterProperties[Index].PropertyItem, FilterProperties[Index].PropertiesCount * sizeof(KSPROPERTY_ITEM));
787 }
788 }
789 }
790
791 // now check if the filter descriptor supports filter properties
792 if (FilterDescription->AutomationTable)
793 {
794 // get first entry
795 PropertyItem = (PPCPROPERTY_ITEM)FilterDescription->AutomationTable->Properties;
796
797 // copy driver filter property sets
798 for(Index = 0; Index < FilterDescription->AutomationTable->PropertyCount; Index++)
799 {
800 // add the property item
802
803 // check for success
804 if (Status != STATUS_SUCCESS)
805 {
806 // goto cleanup
807 goto cleanup;
808 }
809
810 // move to next entry
811 PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + FilterDescription->AutomationTable->PropertyItemSize);
812 }
813 }
814
815 // check if the filter has pins
816 if (FilterDescription->PinCount)
817 {
818 // allocate pin factory descriptors
819 Descriptor->Factory.KsPinDescriptor = (PKSPIN_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR) * FilterDescription->PinCount, TAG_PORTCLASS);
820 if (!Descriptor->Factory.KsPinDescriptor)
821 goto cleanup;
822
823 // allocate pin instance info
824 Descriptor->Factory.Instances = (PPIN_INSTANCE_INFO)AllocateItem(NonPagedPool, FilterDescription->PinCount * sizeof(PIN_INSTANCE_INFO), TAG_PORTCLASS);
825 if (!Descriptor->Factory.Instances)
826 goto cleanup;
827
828 // initialize pin factory descriptor
829 Descriptor->Factory.PinDescriptorCount = FilterDescription->PinCount;
830 Descriptor->Factory.PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR);
831
832 // grab first entry
833 SrcDescriptor = (PPCPIN_DESCRIPTOR)FilterDescription->Pins;
834
835 // copy pin factories
836 for(Index = 0; Index < FilterDescription->PinCount; Index++)
837 {
838 // copy pin descriptor
839 RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &SrcDescriptor->KsPinDescriptor, sizeof(KSPIN_DESCRIPTOR));
840
841 // initialize pin factory instance data
842 Descriptor->Factory.Instances[Index].CurrentPinInstanceCount = 0;
843 Descriptor->Factory.Instances[Index].MaxFilterInstanceCount = SrcDescriptor->MaxFilterInstanceCount;
844 Descriptor->Factory.Instances[Index].MaxGlobalInstanceCount = SrcDescriptor->MaxGlobalInstanceCount;
845 Descriptor->Factory.Instances[Index].MinFilterInstanceCount = SrcDescriptor->MinFilterInstanceCount;
846
847 // check if the descriptor has an automation table
848 if (SrcDescriptor->AutomationTable)
849 {
850 // it has, grab first entry
852
853 // now add all supported property items
854 for(SubIndex = 0; SubIndex < SrcDescriptor->AutomationTable->PropertyCount; SubIndex++)
855 {
856 // add the property item to the table
858
859 // check for success
860 if (Status != STATUS_SUCCESS)
861 {
862 // goto cleanup
863 goto cleanup;
864 }
865
866 // move to next entry
868 }
869 }
870
871 // move to next entry
872 SrcDescriptor = (PPCPIN_DESCRIPTOR)((ULONG_PTR)SrcDescriptor + FilterDescription->PinSize);
873 }
874 }
875
876 // allocate topology descriptor
878 if (!Descriptor->Topology)
879 goto cleanup;
880
881 // are there any connections
882 if (FilterDescription->ConnectionCount)
883 {
884 // allocate connection descriptor
885 Descriptor->Topology->TopologyConnections = (PKSTOPOLOGY_CONNECTION)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY_CONNECTION) * FilterDescription->ConnectionCount, TAG_PORTCLASS);
886 if (!Descriptor->Topology->TopologyConnections)
887 goto cleanup;
888
889 // copy connection descriptor
890 RtlMoveMemory((PVOID)Descriptor->Topology->TopologyConnections, FilterDescription->Connections, FilterDescription->ConnectionCount * sizeof(PCCONNECTION_DESCRIPTOR));
891
892 // store connection count
893 Descriptor->Topology->TopologyConnectionsCount = FilterDescription->ConnectionCount;
894 }
895
896 // does the filter have nodes
897 if (FilterDescription->NodeCount)
898 {
899 // allocate topology node types array
900 Descriptor->Topology->TopologyNodes = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS);
901 if (!Descriptor->Topology->TopologyNodes)
902 goto cleanup;
903
904 // allocate topology node names array
905 Descriptor->Topology->TopologyNodesNames = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS);
906 if (!Descriptor->Topology->TopologyNodesNames)
907 goto cleanup;
908
909 // grab first entry
910 NodeDescriptor = (PPCNODE_DESCRIPTOR)FilterDescription->Nodes;
911
912 // iterate all nodes and copy node types / names and node properties
913 for(Index = 0; Index < FilterDescription->NodeCount; Index++)
914 {
915 // does it have a type
916 if (NodeDescriptor->Type)
917 {
918 // copy node type
919 RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodes[Index], NodeDescriptor->Type, sizeof(GUID));
920 }
921
922 // does it have a node name
923 if (NodeDescriptor->Name)
924 {
925 // copy node name
926 RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodesNames[Index], NodeDescriptor->Name, sizeof(GUID));
927 }
928
929 // check if has an automation table
930 if (NodeDescriptor->AutomationTable)
931 {
932 // grab first entry
933 PropertyItem = (PPCPROPERTY_ITEM)NodeDescriptor->AutomationTable->Properties;
934
935 // copy all node properties into the global property set
936 for(SubIndex = 0; SubIndex < NodeDescriptor->AutomationTable->PropertyCount; SubIndex++)
937 {
938 // add to property set
940
941 // check for success
942 if (Status != STATUS_SUCCESS)
943 {
944 // failed
945 goto cleanup;
946 }
947
948 // move to next property item
949 PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + NodeDescriptor->AutomationTable->PropertyItemSize);
950 }
951 }
952
953 // move to next descriptor
954 NodeDescriptor = (PPCNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescription->NodeSize);
955 }
956
957 // now store the topology node count
958 Descriptor->Topology->TopologyNodesCount = FilterDescription->NodeCount;
959 }
960
961 // store descriptor
962 Descriptor->DeviceDescriptor = FilterDescription;
963
964 // store result
965 *OutSubdeviceDescriptor = Descriptor;
966 // done
967 return STATUS_SUCCESS;
968
969cleanup:
970 if (Descriptor)
971 {
972 if (Descriptor->Interfaces)
973 FreeItem(Descriptor->Interfaces, TAG_PORTCLASS);
974
975 if (Descriptor->Factory.KsPinDescriptor)
976 FreeItem(Descriptor->Factory.KsPinDescriptor, TAG_PORTCLASS);
977
979 }
980 return Status;
981}
982
984NTAPI
986 IN PIRP Irp,
989{
990 return KsValidateConnectRequest(Irp, Factory->PinDescriptorCount, Factory->KsPinDescriptor, Connect);
991}
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: 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: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
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: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: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
struct _IO_STACK_LOCATION::@1564::@1565 DeviceIoControl
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
union _IO_STACK_LOCATION::@1564 Parameters
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:502
NTSTATUS NTAPI PcValidateConnectRequest(IN PIRP Irp, IN KSPIN_FACTORY *Factory, OUT PKSPIN_CONNECT *Connect)
Definition: undoc.cpp:985
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:717
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
VOID DumpFilterDescriptor(IN PPCFILTER_DESCRIPTOR FilterDescription)
Definition: undoc.cpp:625
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 DumpAutomationTable(IN PPCAUTOMATION_TABLE AutomationTable, IN LPCWSTR DebugPrefix, IN LPCWSTR DebugIndentation)
Definition: undoc.cpp:513
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
* PFILE_OBJECT
Definition: iotypes.h:1998
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185