Hopefully fail to break anything in the process of syncing with trunk (r47786)
[reactos.git] / drivers / wdm / audio / backpln / portcls / undoc.cpp
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
12 KSPIN_INTERFACE PinInterfaces[] =
13 {
14 {
15 {STATIC_KSINTERFACESETID_Standard},
16 KSINTERFACE_STANDARD_STREAMING,
17 0
18 },
19 {
20 {STATIC_KSINTERFACESETID_Standard},
21 KSINTERFACE_STANDARD_LOOPED_STREAMING,
22 0
23 }
24 };
25
26
27 NTSTATUS
28 NTAPI
29 KsoDispatchCreateWithGenericFactory(
30 LONG Unknown,
31 PIRP Irp)
32 {
33 UNIMPLEMENTED;
34 return STATUS_NOT_IMPLEMENTED;
35 }
36
37 IIrpTarget *
38 NTAPI
39 KsoGetIrpTargetFromFileObject(
40 PFILE_OBJECT FileObject)
41 {
42 PC_ASSERT(FileObject);
43
44 // IrpTarget is stored in FsContext
45 return (IIrpTarget*)FileObject->FsContext;
46 }
47
48 IIrpTarget *
49 NTAPI
50 KsoGetIrpTargetFromIrp(
51 PIRP Irp)
52 {
53 PIO_STACK_LOCATION IoStack;
54
55 // get current irp stack location
56 IoStack = IoGetCurrentIrpStackLocation(Irp);
57
58 // IIrpTarget is stored in Context member
59 return (IIrpTarget*)IoStack->FileObject->FsContext;
60 }
61
62 NTSTATUS
63 NTAPI
64 PcHandleEnableEventWithTable(
65 IN PIRP Irp,
66 IN PSUBDEVICE_DESCRIPTOR Descriptor)
67 {
68 // store descriptor
69 KSEVENT_ITEM_IRP_STORAGE(Irp) = (PKSEVENT_ITEM)Descriptor;
70
71 // FIXME seh probing
72 return KsEnableEvent(Irp, Descriptor->EventSetCount, Descriptor->EventSet, NULL, KSEVENTS_NONE, NULL);
73 }
74
75 NTSTATUS
76 NTAPI
77 PcHandleDisableEventWithTable(
78 IN PIRP Irp,
79 IN PSUBDEVICE_DESCRIPTOR Descriptor)
80 {
81 // store descriptor
82 KSEVENT_ITEM_IRP_STORAGE(Irp) = (PKSEVENT_ITEM)Descriptor;
83
84 // FIXME seh probing
85
86 return KsDisableEvent(Irp, Descriptor->EventList, KSEVENTS_SPINLOCK, (PVOID)Descriptor->EventListLock);
87 }
88
89 NTSTATUS
90 PcHandleGuidNullRequest(
91 IN OUT PIRP Irp,
92 IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)
93 {
94 PPCNODE_DESCRIPTOR Node;
95 PPCPROPERTY_ITEM PropertyItem;
96 PIO_STACK_LOCATION IoStack;
97 PKSP_NODE Property;
98 LPGUID Buffer;
99 ULONG Count = 0, SubIndex, Index;
100
101 // get current irp stack location
102 IoStack = IoGetCurrentIrpStackLocation(Irp);
103
104
105 // access property
106 Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
107
108 if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount)
109 {
110 // request is out of bounds
111 Irp->IoStatus.Information = 0;
112 return STATUS_INVALID_PARAMETER;
113 }
114
115 Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize));
116
117 if (!Node->AutomationTable)
118 {
119 // request is out of bounds
120 Irp->IoStatus.Information = 0;
121 return STATUS_INVALID_PARAMETER;
122 }
123
124 PC_ASSERT(Node->AutomationTable);
125 PC_ASSERT(Node->AutomationTable->PropertyCount);
126 PC_ASSERT(Node->AutomationTable->PropertyItemSize);
127
128 Buffer = (LPGUID)AllocateItem(NonPagedPool, sizeof (GUID) * Node->AutomationTable->PropertyCount, TAG_PORTCLASS);
129 if (!Buffer)
130 return STATUS_INSUFFICIENT_RESOURCES;
131
132 PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties;
133 for (Index = 0; Index < Node->AutomationTable->PropertyCount; Index++)
134 {
135 BOOL Found = FALSE;
136 for (SubIndex = 0; SubIndex < Count; SubIndex++)
137 {
138 if (IsEqualGUIDAligned(Buffer[SubIndex], *PropertyItem->Set))
139 {
140 Found = TRUE;
141 break;
142 }
143 }
144 if (!Found)
145 {
146 RtlMoveMemory(&Buffer[Count], PropertyItem->Set, sizeof (GUID));
147 Count++;
148 }
149 PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize);
150 }
151
152 // store result length
153 Irp->IoStatus.Information = sizeof (GUID) * Count;
154 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GUID) * Count)
155 {
156 // buffer too small
157 FreeItem(Buffer, TAG_PORTCLASS);
158 return STATUS_MORE_ENTRIES;
159 }
160
161 RtlMoveMemory(Irp->UserBuffer, Buffer, sizeof (GUID) * Count);
162 FreeItem(Buffer, TAG_PORTCLASS);
163 return STATUS_SUCCESS;
164 }
165
166 NTSTATUS
167 PcFindNodePropertyHandler(
168 PIRP Irp,
169 PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor,
170 OUT PPCPROPERTY_ITEM * OutPropertyItem)
171 {
172 PPCNODE_DESCRIPTOR Node;
173 PPCPROPERTY_ITEM PropertyItem;
174 PIO_STACK_LOCATION IoStack;
175 PKSP_NODE Property;
176 ULONG Index;
177
178 // get current irp stack location
179 IoStack = IoGetCurrentIrpStackLocation(Irp);
180
181 // access property
182 Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
183
184 if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount)
185 {
186 // request is out of bounds
187 DPRINT("InvalidIndex %u %u\n", Property->NodeId, SubDeviceDescriptor->DeviceDescriptor->NodeCount);
188 return STATUS_INVALID_PARAMETER;
189 }
190
191 Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize));
192
193 if (!Node->AutomationTable)
194 {
195 // request is out of bounds
196 Irp->IoStatus.Information = 0;
197 return STATUS_NOT_FOUND;
198 }
199
200 // sanity checks
201 PC_ASSERT(Node->AutomationTable);
202 PC_ASSERT(Node->AutomationTable->PropertyCount);
203 PC_ASSERT(Node->AutomationTable->PropertyItemSize);
204
205 PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties;
206
207 DPRINT("NodeId %u PropertyCount %u\n", Property->NodeId, Node->AutomationTable->PropertyCount);
208 for(Index = 0; Index < Node->AutomationTable->PropertyCount; Index++)
209 {
210 if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Property.Set) && PropertyItem->Id == Property->Property.Id)
211 {
212 //found property handler
213 *OutPropertyItem = PropertyItem;
214 return STATUS_SUCCESS;
215 }
216 PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize);
217 }
218
219 // no handler yet found
220 DPRINT("NotFound\n");
221 return STATUS_NOT_FOUND;
222 }
223
224 NTSTATUS
225 PcNodeBasicSupportHandler(
226 PIRP Irp,
227 PPCPROPERTY_ITEM PropertyItem)
228 {
229 PULONG Flags;
230 PIO_STACK_LOCATION IoStack;
231 PKSPROPERTY_DESCRIPTION Description;
232 PKSP_NODE Property;
233
234 // get current irp stack location
235 IoStack = IoGetCurrentIrpStackLocation(Irp);
236
237 // access property
238 Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
239
240 PC_ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(ULONG));
241 Flags= (PULONG)Irp->UserBuffer;
242
243 // reset flags
244 *Flags = 0;
245
246 if (PropertyItem->Flags & KSPROPERTY_TYPE_SET)
247 *Flags |= KSPROPERTY_TYPE_SET;
248
249 if (PropertyItem->Flags & KSPROPERTY_TYPE_GET)
250 *Flags |= KSPROPERTY_TYPE_GET;
251
252 // store result length
253 Irp->IoStatus.Information = sizeof(ULONG);
254
255 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION))
256 {
257 // get output buffer
258 Description = (PKSPROPERTY_DESCRIPTION)Irp->UserBuffer;
259
260 // store result
261 Description->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION);
262 Description->PropTypeSet.Set = KSPROPTYPESETID_General;
263 Description->PropTypeSet.Id = 0;
264 Description->PropTypeSet.Flags = 0;
265 Description->MembersListCount = 0;
266 Description->Reserved = 0;
267
268 Irp->IoStatus.Information = sizeof(KSPROPERTY_DESCRIPTION);
269 }
270 return STATUS_SUCCESS;
271 }
272
273
274 NTSTATUS
275 PcHandleNodePropertyRequest(
276 PIRP Irp,
277 IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)
278 {
279 PIO_STACK_LOCATION IoStack;
280 PPCPROPERTY_ITEM PropertyItem;
281 PPCPROPERTY_REQUEST PropertyRequest;
282 PKSP_NODE Property;
283 NTSTATUS Status;
284
285 // get current irp stack location
286 IoStack = IoGetCurrentIrpStackLocation(Irp);
287
288 if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_NODE))
289 {
290 // certainly not a node property request
291 return STATUS_NOT_FOUND;
292 }
293
294 // access property
295 Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
296
297 if (IsEqualGUIDAligned(Property->Property.Set, GUID_NULL) && Property->Property.Id == 0 && Property->Property.Flags == (KSPROPERTY_TYPE_SETSUPPORT | KSPROPERTY_TYPE_TOPOLOGY))
298 {
299 return PcHandleGuidNullRequest(Irp, SubDeviceDescriptor);
300 }
301
302 // find property handler
303 Status = PcFindNodePropertyHandler(Irp, SubDeviceDescriptor, &PropertyItem);
304
305 // check for success
306 if (!NT_SUCCESS(Status))
307 {
308 // might not be a node property request
309 DPRINT("NotFound\n");
310 return STATUS_NOT_FOUND;
311 }
312
313 if (Property->Property.Flags & KSPROPERTY_TYPE_BASICSUPPORT)
314 {
315 // caller issued a basic property request
316 if (!(PropertyItem->Flags & KSPROPERTY_TYPE_BASICSUPPORT))
317 {
318 // driver does not have a basic support handler
319 return PcNodeBasicSupportHandler(Irp, PropertyItem);
320 }
321 }
322
323 // sanity check
324 PC_ASSERT(SubDeviceDescriptor->UnknownMiniport);
325
326 // allocate a property request
327 PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS);
328 if (!PropertyRequest)
329 return STATUS_INSUFFICIENT_RESOURCES;
330
331 // initialize property request
332 PropertyRequest->MajorTarget = SubDeviceDescriptor->UnknownMiniport;
333 PropertyRequest->MinorTarget = SubDeviceDescriptor->UnknownStream;
334 PropertyRequest->Irp = Irp;
335 PropertyRequest->Node = Property->NodeId;
336 PropertyRequest->PropertyItem = PropertyItem;
337 PropertyRequest->Verb = Property->Property.Flags;
338 PropertyRequest->InstanceSize = IoStack->Parameters.DeviceIoControl.InputBufferLength - sizeof(KSNODEPROPERTY);
339 PropertyRequest->Instance = (PVOID)((ULONG_PTR)IoStack->Parameters.DeviceIoControl.Type3InputBuffer + sizeof(KSNODEPROPERTY));
340 PropertyRequest->ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
341 PropertyRequest->Value = Irp->UserBuffer;
342
343 Status = PropertyItem->Handler(PropertyRequest);
344
345 if (Status != STATUS_PENDING)
346 {
347 //request completed
348 Irp->IoStatus.Information = PropertyRequest->ValueSize;
349 FreeItem(PropertyRequest, TAG_PORTCLASS);
350 }
351
352 // done
353 DPRINT("Status %x\n", Status);
354 return Status;
355 }
356
357 NTSTATUS
358 NTAPI
359 PcHandlePropertyWithTable(
360 IN PIRP Irp,
361 IN ULONG PropertySetCount,
362 IN PKSPROPERTY_SET PropertySet,
363 IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)
364 {
365 NTSTATUS Status;
366
367 // try handle it as node property request
368 Status = PcHandleNodePropertyRequest(Irp, SubDeviceDescriptor);
369
370 if (Status == STATUS_NOT_FOUND)
371 {
372 // store device descriptor
373 KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor;
374
375 /* then try KsPropertyHandler */
376 Status = KsPropertyHandler(Irp, PropertySetCount, PropertySet);
377 }
378
379 return Status;
380 }
381
382 VOID
383 NTAPI
384 PcAcquireFormatResources(
385 LONG Unknown,
386 LONG Unknown2,
387 LONG Unknown3,
388 LONG Unknown4)
389 {
390 UNIMPLEMENTED;
391 }
392
393 NTSTATUS
394 PcAddToEventTable(
395 PVOID Ptr,
396 LONG Unknown2,
397 ULONG Length,
398 LONG Unknown3,
399 LONG Unknown4,
400 LONG Unknown5,
401 LONG Unknown6,
402 LONG Unknown7)
403 {
404 UNIMPLEMENTED;
405 return STATUS_NOT_IMPLEMENTED;
406 }
407
408 NTSTATUS
409 PcAddToPropertyTable(
410 PVOID Ptr,
411 LONG Unknown,
412 LONG Unknown2,
413 LONG Unknown3,
414 CHAR Unknown4)
415 {
416 UNIMPLEMENTED;
417 return STATUS_NOT_IMPLEMENTED;
418 }
419
420 NTSTATUS
421 PcCaptureFormat(
422 LONG Unknown,
423 LONG Unknown2,
424 LONG Unknown3,
425 LONG Unknown4)
426 {
427 UNIMPLEMENTED;
428 return STATUS_NOT_IMPLEMENTED;
429 }
430
431 VOID
432 DumpFilterDescriptor(
433 IN PPCFILTER_DESCRIPTOR FilterDescription)
434 {
435 ULONG Index, SubIndex;
436 PPCPROPERTY_ITEM PropertyItem;
437 PPCEVENT_ITEM EventItem;
438 PPCNODE_DESCRIPTOR NodeDescriptor;
439 UNICODE_STRING GuidString;
440
441
442
443 DPRINT("======================\n");
444 DPRINT("Descriptor Automation Table %p\n",FilterDescription->AutomationTable);
445
446 if (FilterDescription->AutomationTable)
447 {
448 DPRINT("FilterPropertiesCount %u FilterPropertySize %u Expected %u Events %u EventItemSize %u expected %u\n", FilterDescription->AutomationTable->PropertyCount, FilterDescription->AutomationTable->PropertyItemSize, sizeof(PCPROPERTY_ITEM),
449 FilterDescription->AutomationTable->EventCount, FilterDescription->AutomationTable->EventItemSize, sizeof(PCEVENT_ITEM));
450 if (FilterDescription->AutomationTable->PropertyCount)
451 {
452 PropertyItem = (PPCPROPERTY_ITEM)FilterDescription->AutomationTable->Properties;
453
454 for(Index = 0; Index < FilterDescription->AutomationTable->PropertyCount; Index++)
455 {
456 RtlStringFromGUID(*PropertyItem->Set, &GuidString);
457 DPRINT("Property Index %u GUID %S Id %u Flags %x\n", Index, GuidString.Buffer, PropertyItem->Id, PropertyItem->Flags);
458
459 PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + FilterDescription->AutomationTable->PropertyItemSize);
460 }
461
462 EventItem = (PPCEVENT_ITEM)FilterDescription->AutomationTable->Events;
463 for(Index = 0; Index < FilterDescription->AutomationTable->EventCount; Index++)
464 {
465 RtlStringFromGUID(*EventItem->Set, &GuidString);
466 DPRINT("EventIndex %u GUID %S Id %u Flags %x\n", Index, GuidString.Buffer, EventItem->Id, EventItem->Flags);
467
468 EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + FilterDescription->AutomationTable->EventItemSize);
469 }
470
471 }
472 }
473
474 if (FilterDescription->Nodes)
475 {
476 DPRINT("NodeCount %u NodeSize %u expected %u\n", FilterDescription->NodeCount, FilterDescription->NodeSize, sizeof(PCNODE_DESCRIPTOR));
477 NodeDescriptor = (PPCNODE_DESCRIPTOR)FilterDescription->Nodes;
478 for(Index = 0; Index < FilterDescription->NodeCount; Index++)
479 {
480 DPRINT("Index %u AutomationTable %p\n", Index, NodeDescriptor->AutomationTable);
481
482 if (NodeDescriptor->AutomationTable)
483 {
484 DPRINT(" Index %u EventCount %u\n", Index, NodeDescriptor->AutomationTable->EventCount);
485 EventItem = (PPCEVENT_ITEM)NodeDescriptor->AutomationTable->Events;
486 for(SubIndex = 0; SubIndex < NodeDescriptor->AutomationTable->EventCount; SubIndex++)
487 {
488 RtlStringFromGUID(*EventItem->Set, &GuidString);
489 DPRINT(" EventIndex %u GUID %S Id %u Flags %x\n", SubIndex, GuidString.Buffer, EventItem->Id, EventItem->Flags);
490
491 EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + NodeDescriptor->AutomationTable->EventItemSize);
492 }
493
494 }
495
496
497 NodeDescriptor = (PPCNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescription->NodeSize);
498 }
499
500
501
502 }
503
504 DPRINT("ConnectionCount: %lu\n", FilterDescription->ConnectionCount);
505
506 if (FilterDescription->ConnectionCount)
507 {
508 DPRINT("------ Start of Nodes Connections ----------------\n");
509 for(Index = 0; Index < FilterDescription->ConnectionCount; Index++)
510 {
511 DPRINT1("Index %ld FromPin %ld FromNode %ld -> ToPin %ld ToNode %ld\n", Index,
512 FilterDescription->Connections[Index].FromNodePin,
513 FilterDescription->Connections[Index].FromNode,
514 FilterDescription->Connections[Index].ToNodePin,
515 FilterDescription->Connections[Index].ToNode);
516 }
517 DPRINT("------ End of Nodes Connections----------------\n");
518 }
519
520 DPRINT1("======================\n");
521 }
522
523 NTSTATUS
524 NTAPI
525 PcCreateSubdeviceDescriptor(
526 OUT SUBDEVICE_DESCRIPTOR ** OutSubdeviceDescriptor,
527 IN ULONG InterfaceCount,
528 IN GUID * InterfaceGuids,
529 IN ULONG IdentifierCount,
530 IN KSIDENTIFIER *Identifier,
531 IN ULONG FilterPropertiesCount,
532 IN KSPROPERTY_SET * FilterProperties,
533 IN ULONG Unknown1,
534 IN ULONG Unknown2,
535 IN ULONG PinPropertiesCount,
536 IN KSPROPERTY_SET * PinProperties,
537 IN ULONG EventSetCount,
538 IN KSEVENT_SET * EventSet,
539 IN PPCFILTER_DESCRIPTOR FilterDescription)
540 {
541 SUBDEVICE_DESCRIPTOR * Descriptor;
542 ULONG Index;
543 NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
544 PPCPIN_DESCRIPTOR SrcDescriptor;
545
546 Descriptor = (PSUBDEVICE_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(SUBDEVICE_DESCRIPTOR), TAG_PORTCLASS);
547 if (!Descriptor)
548 return STATUS_INSUFFICIENT_RESOURCES;
549
550 // initialize physical / symbolic link connection list
551 InitializeListHead(&Descriptor->SymbolicLinkList);
552 InitializeListHead(&Descriptor->PhysicalConnectionList);
553
554 Descriptor->Interfaces = (GUID*)AllocateItem(NonPagedPool, sizeof(GUID) * InterfaceCount, TAG_PORTCLASS);
555 if (!Descriptor->Interfaces)
556 goto cleanup;
557
558 // copy interface guids
559 RtlCopyMemory(Descriptor->Interfaces, InterfaceGuids, sizeof(GUID) * InterfaceCount);
560 Descriptor->InterfaceCount = InterfaceCount;
561
562 if (FilterPropertiesCount)
563 {
564 /// FIXME
565 /// handle driver properties
566
567 DumpFilterDescriptor(FilterDescription);
568
569 Descriptor->FilterPropertySet = (PKSPROPERTY_SET)AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * FilterPropertiesCount, TAG_PORTCLASS);
570 if (! Descriptor->FilterPropertySet)
571 goto cleanup;
572
573 Descriptor->FilterPropertySetCount = FilterPropertiesCount;
574 for(Index = 0; Index < FilterPropertiesCount; Index++)
575 {
576 RtlMoveMemory(&Descriptor->FilterPropertySet[Index], &FilterProperties[Index], sizeof(KSPROPERTY_SET));
577 }
578 }
579
580 Descriptor->Topology = (PKSTOPOLOGY)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY), TAG_PORTCLASS);
581 if (!Descriptor->Topology)
582 goto cleanup;
583
584 if (FilterDescription->ConnectionCount)
585 {
586 Descriptor->Topology->TopologyConnections = (PKSTOPOLOGY_CONNECTION)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY_CONNECTION) * FilterDescription->ConnectionCount, TAG_PORTCLASS);
587 if (!Descriptor->Topology->TopologyConnections)
588 goto cleanup;
589
590 RtlMoveMemory((PVOID)Descriptor->Topology->TopologyConnections, FilterDescription->Connections, FilterDescription->ConnectionCount * sizeof(PCCONNECTION_DESCRIPTOR));
591 Descriptor->Topology->TopologyConnectionsCount = FilterDescription->ConnectionCount;
592 }
593
594 if (FilterDescription->NodeCount)
595 {
596 Descriptor->Topology->TopologyNodes = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS);
597 if (!Descriptor->Topology->TopologyNodes)
598 goto cleanup;
599
600 Descriptor->Topology->TopologyNodesNames = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS);
601 if (!Descriptor->Topology->TopologyNodesNames)
602 goto cleanup;
603
604 for(Index = 0; Index < FilterDescription->NodeCount; Index++)
605 {
606 if (FilterDescription->Nodes[Index].Type)
607 {
608 RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodes[Index], FilterDescription->Nodes[Index].Type, sizeof(GUID));
609 }
610 if (FilterDescription->Nodes[Index].Name)
611 {
612 RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodesNames[Index], FilterDescription->Nodes[Index].Name, sizeof(GUID));
613 }
614 }
615 Descriptor->Topology->TopologyNodesCount = FilterDescription->NodeCount;
616 }
617
618 if (FilterDescription->PinCount)
619 {
620 Descriptor->Factory.KsPinDescriptor = (PKSPIN_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR) * FilterDescription->PinCount, TAG_PORTCLASS);
621 if (!Descriptor->Factory.KsPinDescriptor)
622 goto cleanup;
623
624 Descriptor->Factory.Instances = (PPIN_INSTANCE_INFO)AllocateItem(NonPagedPool, FilterDescription->PinCount * sizeof(PIN_INSTANCE_INFO), TAG_PORTCLASS);
625 if (!Descriptor->Factory.Instances)
626 goto cleanup;
627
628 Descriptor->Factory.PinDescriptorCount = FilterDescription->PinCount;
629 Descriptor->Factory.PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR);
630
631 SrcDescriptor = (PPCPIN_DESCRIPTOR)FilterDescription->Pins;
632 DPRINT("Size %u Expected %u\n", FilterDescription->PinSize, sizeof(PCPIN_DESCRIPTOR));
633
634 // copy pin factories
635 for(Index = 0; Index < FilterDescription->PinCount; Index++)
636 {
637 RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &SrcDescriptor->KsPinDescriptor, sizeof(KSPIN_DESCRIPTOR));
638
639 Descriptor->Factory.KsPinDescriptor[Index].Interfaces = PinInterfaces;
640 Descriptor->Factory.KsPinDescriptor[Index].InterfacesCount = sizeof(PinInterfaces) / sizeof(KSPIN_INTERFACE);
641
642 DPRINT("Index %u DataRangeCount %u\n", Index, SrcDescriptor->KsPinDescriptor.DataRangesCount);
643
644 Descriptor->Factory.Instances[Index].CurrentPinInstanceCount = 0;
645 Descriptor->Factory.Instances[Index].MaxFilterInstanceCount = SrcDescriptor->MaxFilterInstanceCount;
646 Descriptor->Factory.Instances[Index].MaxGlobalInstanceCount = SrcDescriptor->MaxGlobalInstanceCount;
647 Descriptor->Factory.Instances[Index].MinFilterInstanceCount = SrcDescriptor->MinFilterInstanceCount;
648 SrcDescriptor = (PPCPIN_DESCRIPTOR)((ULONG_PTR)SrcDescriptor + FilterDescription->PinSize);
649 }
650 }
651
652 Descriptor->DeviceDescriptor = FilterDescription;
653 *OutSubdeviceDescriptor = Descriptor;
654 return STATUS_SUCCESS;
655
656 cleanup:
657 if (Descriptor)
658 {
659 if (Descriptor->Interfaces)
660 FreeItem(Descriptor->Interfaces, TAG_PORTCLASS);
661
662 if (Descriptor->Factory.KsPinDescriptor)
663 FreeItem(Descriptor->Factory.KsPinDescriptor, TAG_PORTCLASS);
664
665 FreeItem(Descriptor, TAG_PORTCLASS);
666 }
667 return Status;
668 }
669
670 NTSTATUS
671 NTAPI
672 PcValidateConnectRequest(
673 IN PIRP Irp,
674 IN KSPIN_FACTORY * Factory,
675 OUT PKSPIN_CONNECT * Connect)
676 {
677 return KsValidateConnectRequest(Irp, Factory->PinDescriptorCount, Factory->KsPinDescriptor, Connect);
678 }
679