ReactOS  0.4.14-dev-55-g2da92ac
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 
18 NTAPI
20  LONG Unknown,
21  PIRP Irp)
22 {
25 }
26 
27 IIrpTarget *
28 NTAPI
31 {
33 
34  // IrpTarget is stored in FsContext
35  return (IIrpTarget*)FileObject->FsContext;
36 }
37 
38 IIrpTarget *
39 NTAPI
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 
53 NTAPI
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 
66 NTAPI
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 
80 NTAPI
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 
106 VOID
107 NTAPI
109  LONG Unknown,
110  LONG Unknown2,
111  LONG Unknown3,
112  LONG Unknown4)
113 {
115 }
116 
117 NTSTATUS
119  PVOID Ptr,
120  LONG Unknown2,
121  ULONG Length,
122  LONG Unknown3,
123  LONG Unknown4,
124  LONG Unknown5,
125  LONG Unknown6,
126  LONG Unknown7)
127 {
129  return STATUS_NOT_IMPLEMENTED;
130 }
131 
132 NTSTATUS
133 NTAPI
135  IN PIRP Irp,
137  IN OUT PVOID Data)
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;
149  PVOID Instance;
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;
175  Instance = Request;
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);
190  Instance = (PVOID)((ULONG_PTR)Instance + 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
262  if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Set))
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 
310 NTSTATUS
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 
323 ASSERT(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
475  FilterPropertyItem->SupportHandler = PropertyItemDispatch;
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 
508 NTSTATUS
510  LONG Unknown,
511  LONG Unknown2,
512  LONG Unknown3,
513  LONG Unknown4)
514 {
516  return STATUS_NOT_IMPLEMENTED;
517 }
518 
519 
520 
521 
522 VOID
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 
635 VOID
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 
728 NTSTATUS
729 NTAPI
731  OUT SUBDEVICE_DESCRIPTOR ** OutSubdeviceDescriptor,
732  IN ULONG InterfaceCount,
734  IN ULONG IdentifierCount,
735  IN KSIDENTIFIER *Identifier,
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 
982 cleanup:
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 
996 NTSTATUS
997 NTAPI
999  IN PIRP Irp,
1002 {
1003  return KsValidateConnectRequest(Irp, Factory->PinDescriptorCount, Factory->KsPinDescriptor, Connect);
1004 }
1005 
struct KSIDENTIFIER KSPROPERTY
static PWSTR GuidString
Definition: apphelp.c:91
#define IN
Definition: typedefs.h:38
ULONG MaxGlobalInstanceCount
Definition: portcls.h:339
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD Unknown3
Definition: conport.c:35
#define PC_ASSERT(exp)
Definition: usbehci.h:17
_In_ PKSPIN_CONNECT Connect
Definition: ks.h:4536
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
ULONG Flags
Definition: portcls.h:279
_In_ PIRP Irp
Definition: csq.h:116
const PCPROPERTY_ITEM * Properties
Definition: portcls.h:321
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define TAG_PORTCLASS
Definition: private.hpp:24
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
LONG NTSTATUS
Definition: precomp.h:26
VOID DumpFilterDescriptor(IN PPCFILTER_DESCRIPTOR FilterDescription)
Definition: undoc.cpp:636
struct _PCPROPERTY_REQUEST * PPCPROPERTY_REQUEST
Definition: portcls.h:230
struct KSTOPOLOGY_CONNECTION * PKSTOPOLOGY_CONNECTION
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD IN DWORD IN DWORD IN DWORD Unknown6
Definition: conport.c:35
PUNKNOWN MinorTarget
Definition: portcls.h:259
static GUID InterfaceGuids[3]
Definition: port_dmus.cpp:64
NTSTATUS NTAPI PcValidateConnectRequest(IN PIRP Irp, IN KSPIN_FACTORY *Factory, OUT PKSPIN_CONNECT *Connect)
Definition: undoc.cpp:998
#define PCPROPERTY_ITEM_FLAG_GET
Definition: portcls.h:240
NTSTATUS NTAPI KsoDispatchCreateWithGenericFactory(LONG Unknown, PIRP Irp)
Definition: undoc.cpp:19
struct PCNODE_DESCRIPTOR * PPCNODE_DESCRIPTOR
NTSTATUS NTAPI PcHandleDisableEventWithTable(IN PIRP Irp, IN PSUBDEVICE_DESCRIPTOR Descriptor)
Definition: undoc.cpp:67
KSPIN_DESCRIPTOR KsPinDescriptor
Definition: portcls.h:343
_In_ const GUID _In_ ULONG PinCount
Definition: strmini.h:504
ULONG Id
Definition: portcls.h:278
KSDDKAPI NTSTATUS NTAPI KsDisableEvent(IN PIRP Irp, IN OUT PLIST_ENTRY EventsList, IN KSEVENTS_LOCKTYPE EventsFlags, IN PVOID EventsLock)
Definition: event.c:469
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
const GUID * Set
Definition: portcls.h:300
KSDDKAPI NTSTATUS NTAPI KsPropertyHandler(IN PIRP Irp, IN ULONG PropertySetsCount, IN const KSPROPERTY_SET *PropertySet)
Definition: property.c:358
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:233
uint32_t ULONG_PTR
Definition: typedefs.h:63
NTSTATUS NTAPI PcHandleEnableEventWithTable(IN PIRP Irp, IN PSUBDEVICE_DESCRIPTOR Descriptor)
Definition: undoc.cpp:54
struct PCPIN_DESCRIPTOR * PPCPIN_DESCRIPTOR
_In_ NDIS_HANDLE _In_ PNDIS_REQUEST Request
Definition: ndis.h:5173
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
long LONG
Definition: pedump.c:60
ULONG NodeId
Definition: ksmedia.h:1134
#define PCPROPERTY_ITEM_FLAG_BASICSUPPORT
Definition: portcls.h:242
PRTL_UNICODE_STRING_BUFFER PULONG PULONG Unknown4
struct _PCEVENT_ITEM * PPCEVENT_ITEM
KSPROPERTY_ITEM FilterPropertyItem[]
Definition: bdasup.c:15
static GUID * Guid
Definition: apphelp.c:93
smooth NULL
Definition: ftsmooth.c:416
struct PCAUTOMATION_TABLE * PPCAUTOMATION_TABLE
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
PCPFNPROPERTY_HANDLER Handler
Definition: portcls.h:253
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
ULONG Flags
Definition: portcls.h:302
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
VOID DumpAutomationTable(IN PPCAUTOMATION_TABLE AutomationTable, IN LPCWSTR DebugPrefix, IN LPCWSTR DebugIndentation)
Definition: undoc.cpp:523
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:636
const PCPROPERTY_ITEM * PropertyItem
Definition: portcls.h:261
#define STATUS_NOT_FOUND
Definition: shellext.h:67
VOID NTAPI PcAcquireFormatResources(LONG Unknown, LONG Unknown2, LONG Unknown3, LONG Unknown4)
Definition: undoc.cpp:108
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
struct _PCMETHOD_ITEM * PPCMETHOD_ITEM
#define STATUS_PENDING
Definition: ntstatus.h:82
ULONG PropertyItemSize
Definition: portcls.h:319
#define swprintf(buf, format,...)
Definition: sprintf.c:56
static const UCHAR Index[8]
Definition: usbohci.c:18
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
KSPROPERTY_SET FilterPropertySet[]
Definition: filter.c:63
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
* PFILE_OBJECT
Definition: iotypes.h:1955
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
const KSNODE_DESCRIPTOR NodeDescriptor[]
Definition: splitter.c:217
struct KSTOPOLOGY * PKSTOPOLOGY
struct KSNODEPROPERTY * PKSNODEPROPERTY
static const WCHAR L[]
Definition: oid.c:1250
struct PropertyItem PropertyItem
PUNKNOWN MajorTarget
Definition: portcls.h:258
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
IIrpTarget *NTAPI KsoGetIrpTargetFromFileObject(PFILE_OBJECT FileObject)
Definition: undoc.cpp:29
NTSTATUS PcCaptureFormat(LONG Unknown, LONG Unknown2, LONG Unknown3, LONG Unknown4)
Definition: undoc.cpp:509
NTSTATUS PcAddToEventTable(PVOID Ptr, LONG Unknown2, ULONG Length, LONG Unknown3, LONG Unknown4, LONG Unknown5, LONG Unknown6, LONG Unknown7)
Definition: undoc.cpp:118
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI PropertyItemDispatch(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data)
Definition: undoc.cpp:134
#define MAXULONG
Definition: typedefs.h:250
_In_ DWORD Property
Definition: setupapi.h:1545
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
NTSTATUS NTAPI PcHandlePropertyWithTable(IN PIRP Irp, IN ULONG PropertySetCount, IN PKSPROPERTY_SET PropertySet, IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)
Definition: undoc.cpp:81
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define PCPROPERTY_ITEM_FLAG_SET
Definition: portcls.h:241
ULONG MaxFilterInstanceCount
Definition: portcls.h:340
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
IIrpTarget *NTAPI KsoGetIrpTargetFromIrp(PIRP Irp)
Definition: undoc.cpp:40
IN PVOID Instance
Definition: pci.h:359
#define DPRINT1
Definition: precomp.h:8
ULONG MinFilterInstanceCount
Definition: portcls.h:341
const GUID * Set
Definition: portcls.h:277
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:114
char * cleanup(char *str)
Definition: wpickclick.c:99
NTSTATUS PcAddToPropertyTable(IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor, IN PPCPROPERTY_ITEM PropertyItem, IN ULONG bNode)
Definition: undoc.cpp:311
struct KSIDENTIFIER * PKSPROPERTY
#define KSPROPERTY_TYPE_TOPOLOGY
Definition: dmksctrl.h:53
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD IN DWORD IN DWORD Unknown5
Definition: conport.c:35
const PCAUTOMATION_TABLE * AutomationTable
Definition: portcls.h:342
return STATUS_SUCCESS
Definition: btrfs.c:2966
struct SUBDEVICE_DESCRIPTOR * PSUBDEVICE_DESCRIPTOR
KSDDKAPI NTSTATUS NTAPI KsValidateConnectRequest(IN PIRP Irp, IN ULONG DescriptorsCount, IN KSPIN_DESCRIPTOR *Descriptor, OUT PKSPIN_CONNECT *Connect)
Definition: connectivity.c:222
struct PIN_INSTANCE_INFO * PPIN_INSTANCE_INFO
GUID * LPGUID
Definition: guiddef.h:81
struct PCPROPERTY_ITEM * PPCPROPERTY_ITEM
_In_ PSTORAGE_PROPERTY_ID _Outptr_ PSTORAGE_DESCRIPTOR_HEADER * Descriptor
Definition: classpnp.h:966