Sync to trunk (r44371)
[reactos.git] / reactos / 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; Index++)
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 // allocate a property request
324 PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS);
325 if (!PropertyRequest)
326 return STATUS_INSUFFICIENT_RESOURCES;
327
328 PropertyRequest->MajorTarget = SubDeviceDescriptor->UnknownMiniport;
329 PropertyRequest->MinorTarget = SubDeviceDescriptor->UnknownStream;
330 PropertyRequest->Irp = Irp;
331 PropertyRequest->Node = Property->NodeId;
332 PropertyRequest->PropertyItem = PropertyItem;
333 PropertyRequest->Verb = Property->Property.Flags;
334 PropertyRequest->InstanceSize = IoStack->Parameters.DeviceIoControl.InputBufferLength - sizeof(KSNODEPROPERTY);
335 PropertyRequest->Instance = (PVOID)((ULONG_PTR)IoStack->Parameters.DeviceIoControl.Type3InputBuffer + sizeof(KSNODEPROPERTY));
336 PropertyRequest->ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
337 PropertyRequest->Value = Irp->UserBuffer;
338
339 Status = PropertyItem->Handler(PropertyRequest);
340
341 if (Status != STATUS_PENDING)
342 {
343 //request completed
344 Irp->IoStatus.Information = PropertyRequest->ValueSize;
345 ExFreePool(PropertyRequest);
346 }
347
348 // done
349 DPRINT("Status %x\n", Status);
350 return Status;
351 }
352
353 NTSTATUS
354 NTAPI
355 PcHandlePropertyWithTable(
356 IN PIRP Irp,
357 IN ULONG PropertySetCount,
358 IN PKSPROPERTY_SET PropertySet,
359 IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)
360 {
361 NTSTATUS Status;
362
363 // try handle it as node property request
364 Status = PcHandleNodePropertyRequest(Irp, SubDeviceDescriptor);
365
366 if (Status == STATUS_NOT_FOUND)
367 {
368 // store device descriptor
369 KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor;
370
371 /* then try KsPropertyHandler */
372 Status = KsPropertyHandler(Irp, PropertySetCount, PropertySet);
373 }
374
375 return Status;
376 }
377
378 VOID
379 NTAPI
380 PcAcquireFormatResources(
381 LONG Unknown,
382 LONG Unknown2,
383 LONG Unknown3,
384 LONG Unknown4)
385 {
386 UNIMPLEMENTED;
387 }
388
389 NTSTATUS
390 PcAddToEventTable(
391 PVOID Ptr,
392 LONG Unknown2,
393 ULONG Length,
394 LONG Unknown3,
395 LONG Unknown4,
396 LONG Unknown5,
397 LONG Unknown6,
398 LONG Unknown7)
399 {
400 UNIMPLEMENTED;
401 return STATUS_NOT_IMPLEMENTED;
402 }
403
404 NTSTATUS
405 PcAddToPropertyTable(
406 PVOID Ptr,
407 LONG Unknown,
408 LONG Unknown2,
409 LONG Unknown3,
410 CHAR Unknown4)
411 {
412 UNIMPLEMENTED;
413 return STATUS_NOT_IMPLEMENTED;
414 }
415
416 NTSTATUS
417 PcCaptureFormat(
418 LONG Unknown,
419 LONG Unknown2,
420 LONG Unknown3,
421 LONG Unknown4)
422 {
423 UNIMPLEMENTED;
424 return STATUS_NOT_IMPLEMENTED;
425 }
426
427 VOID
428 DumpFilterDescriptor(
429 IN PPCFILTER_DESCRIPTOR FilterDescription)
430 {
431 ULONG Index, SubIndex;
432 PPCPROPERTY_ITEM PropertyItem;
433 PPCEVENT_ITEM EventItem;
434 PPCNODE_DESCRIPTOR NodeDescriptor;
435 UNICODE_STRING GuidString;
436
437
438
439 DPRINT1("======================\n");
440 DPRINT1("Descriptor Automation Table%p\n",FilterDescription->AutomationTable);
441
442 if (FilterDescription->AutomationTable)
443 {
444 DPRINT1("FilterPropertiesCount %u FilterPropertySize %u Expected %u Events %u EventItemSize %u expected %u\n", FilterDescription->AutomationTable->PropertyCount, FilterDescription->AutomationTable->PropertyItemSize, sizeof(PCPROPERTY_ITEM),
445 FilterDescription->AutomationTable->EventCount, FilterDescription->AutomationTable->EventItemSize, sizeof(PCEVENT_ITEM));
446 if (FilterDescription->AutomationTable->PropertyCount)
447 {
448 PropertyItem = (PPCPROPERTY_ITEM)FilterDescription->AutomationTable->Properties;
449
450 for(Index = 0; Index < FilterDescription->AutomationTable->PropertyCount; Index++)
451 {
452 RtlStringFromGUID(*PropertyItem->Set, &GuidString);
453 DPRINT("Property Index %u GUID %S Id %u Flags %x\n", Index, GuidString.Buffer, PropertyItem->Id, PropertyItem->Flags);
454
455 PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + FilterDescription->AutomationTable->PropertyItemSize);
456 }
457
458 EventItem = (PPCEVENT_ITEM)FilterDescription->AutomationTable->Events;
459 for(Index = 0; Index < FilterDescription->AutomationTable->EventCount; Index++)
460 {
461 RtlStringFromGUID(*EventItem->Set, &GuidString);
462 DPRINT1("EventIndex %u GUID %S Id %u Flags %x\n", Index, GuidString.Buffer, EventItem->Id, EventItem->Flags);
463
464 EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + FilterDescription->AutomationTable->EventItemSize);
465 }
466
467 }
468 }
469
470 if (FilterDescription->Nodes)
471 {
472 DPRINT1("NodeCount %u NodeSize %u expected %u\n", FilterDescription->NodeCount, FilterDescription->NodeSize, sizeof(PCNODE_DESCRIPTOR));
473 NodeDescriptor = (PPCNODE_DESCRIPTOR)FilterDescription->Nodes;
474 for(Index = 0; Index < FilterDescription->NodeCount; Index++)
475 {
476 DPRINT("Index %u AutomationTable %p\n", Index, NodeDescriptor->AutomationTable);
477
478 if (NodeDescriptor->AutomationTable)
479 {
480 DPRINT1("Index %u EventCount %u\n", Index, NodeDescriptor->AutomationTable->EventCount);
481 EventItem = (PPCEVENT_ITEM)NodeDescriptor->AutomationTable->Events;
482 for(SubIndex = 0; SubIndex < NodeDescriptor->AutomationTable->EventCount; SubIndex++)
483 {
484 RtlStringFromGUID(*EventItem->Set, &GuidString);
485 DPRINT1("EventIndex %u GUID %S Id %u Flags %x\n", Index, GuidString.Buffer, EventItem->Id, EventItem->Flags);
486
487 EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + FilterDescription->AutomationTable->EventItemSize);
488 }
489
490 }
491
492
493 NodeDescriptor = (PPCNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescription->NodeSize);
494 }
495
496
497
498 }
499
500
501
502 DPRINT1("======================\n");
503 }
504
505 NTSTATUS
506 NTAPI
507 PcCreateSubdeviceDescriptor(
508 OUT SUBDEVICE_DESCRIPTOR ** OutSubdeviceDescriptor,
509 IN ULONG InterfaceCount,
510 IN GUID * InterfaceGuids,
511 IN ULONG IdentifierCount,
512 IN KSIDENTIFIER *Identifier,
513 IN ULONG FilterPropertiesCount,
514 IN KSPROPERTY_SET * FilterProperties,
515 IN ULONG Unknown1,
516 IN ULONG Unknown2,
517 IN ULONG PinPropertiesCount,
518 IN KSPROPERTY_SET * PinProperties,
519 IN ULONG EventSetCount,
520 IN KSEVENT_SET * EventSet,
521 IN PPCFILTER_DESCRIPTOR FilterDescription)
522 {
523 SUBDEVICE_DESCRIPTOR * Descriptor;
524 ULONG Index;
525 NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
526 PPCPIN_DESCRIPTOR SrcDescriptor;
527
528 Descriptor = (PSUBDEVICE_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(SUBDEVICE_DESCRIPTOR), TAG_PORTCLASS);
529 if (!Descriptor)
530 return STATUS_INSUFFICIENT_RESOURCES;
531
532 // initialize physical / symbolic link connection list
533 InitializeListHead(&Descriptor->SymbolicLinkList);
534 InitializeListHead(&Descriptor->PhysicalConnectionList);
535
536 Descriptor->Interfaces = (GUID*)AllocateItem(NonPagedPool, sizeof(GUID) * InterfaceCount, TAG_PORTCLASS);
537 if (!Descriptor->Interfaces)
538 goto cleanup;
539
540 // copy interface guids
541 RtlCopyMemory(Descriptor->Interfaces, InterfaceGuids, sizeof(GUID) * InterfaceCount);
542 Descriptor->InterfaceCount = InterfaceCount;
543
544 if (FilterPropertiesCount)
545 {
546 /// FIXME
547 /// handle driver properties
548
549 //DumpFilterDescriptor(FilterDescription);
550
551 Descriptor->FilterPropertySet = (PKSPROPERTY_SET)AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * FilterPropertiesCount, TAG_PORTCLASS);
552 if (! Descriptor->FilterPropertySet)
553 goto cleanup;
554
555 Descriptor->FilterPropertySetCount = FilterPropertiesCount;
556 for(Index = 0; Index < FilterPropertiesCount; Index++)
557 {
558 RtlMoveMemory(&Descriptor->FilterPropertySet[Index], &FilterProperties[Index], sizeof(KSPROPERTY_SET));
559 }
560 }
561
562 Descriptor->Topology = (PKSTOPOLOGY)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY), TAG_PORTCLASS);
563 if (!Descriptor->Topology)
564 goto cleanup;
565
566 if (FilterDescription->ConnectionCount)
567 {
568 Descriptor->Topology->TopologyConnections = (PKSTOPOLOGY_CONNECTION)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY_CONNECTION) * FilterDescription->ConnectionCount, TAG_PORTCLASS);
569 if (!Descriptor->Topology->TopologyConnections)
570 goto cleanup;
571
572 RtlMoveMemory((PVOID)Descriptor->Topology->TopologyConnections, FilterDescription->Connections, FilterDescription->ConnectionCount * sizeof(PCCONNECTION_DESCRIPTOR));
573 Descriptor->Topology->TopologyConnectionsCount = FilterDescription->ConnectionCount;
574 }
575
576 if (FilterDescription->NodeCount)
577 {
578 Descriptor->Topology->TopologyNodes = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS);
579 if (!Descriptor->Topology->TopologyNodes)
580 goto cleanup;
581
582 Descriptor->Topology->TopologyNodesNames = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS);
583 if (!Descriptor->Topology->TopologyNodesNames)
584 goto cleanup;
585
586 for(Index = 0; Index < FilterDescription->NodeCount; Index++)
587 {
588 if (FilterDescription->Nodes[Index].Type)
589 {
590 RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodes[Index], FilterDescription->Nodes[Index].Type, sizeof(GUID));
591 }
592 if (FilterDescription->Nodes[Index].Name)
593 {
594 RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodesNames[Index], FilterDescription->Nodes[Index].Name, sizeof(GUID));
595 }
596 }
597 Descriptor->Topology->TopologyNodesCount = FilterDescription->NodeCount;
598 }
599
600 if (FilterDescription->PinCount)
601 {
602 Descriptor->Factory.KsPinDescriptor = (PKSPIN_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR) * FilterDescription->PinCount, TAG_PORTCLASS);
603 if (!Descriptor->Factory.KsPinDescriptor)
604 goto cleanup;
605
606 Descriptor->Factory.Instances = (PPIN_INSTANCE_INFO)AllocateItem(NonPagedPool, FilterDescription->PinCount * sizeof(PIN_INSTANCE_INFO), TAG_PORTCLASS);
607 if (!Descriptor->Factory.Instances)
608 goto cleanup;
609
610 Descriptor->Factory.PinDescriptorCount = FilterDescription->PinCount;
611 Descriptor->Factory.PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR);
612
613 SrcDescriptor = (PPCPIN_DESCRIPTOR)FilterDescription->Pins;
614 DPRINT("Size %u Expected %u Ex Size %u\n", FilterDescription->PinSize, sizeof(KSPIN_DESCRIPTOR), sizeof(KSPIN_DESCRIPTOR_EX));
615
616 // copy pin factories
617 for(Index = 0; Index < FilterDescription->PinCount; Index++)
618 {
619 RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &SrcDescriptor->KsPinDescriptor, sizeof(KSPIN_DESCRIPTOR));
620
621 Descriptor->Factory.KsPinDescriptor[Index].Interfaces = PinInterfaces;
622 Descriptor->Factory.KsPinDescriptor[Index].InterfacesCount = sizeof(PinInterfaces) / sizeof(KSPIN_INTERFACE);
623
624 DPRINT("Index %u DataRangeCount %u\n", Index, SrcDescriptor->KsPinDescriptor.DataRangesCount);
625
626 Descriptor->Factory.Instances[Index].CurrentPinInstanceCount = 0;
627 Descriptor->Factory.Instances[Index].MaxFilterInstanceCount = SrcDescriptor->MaxFilterInstanceCount;
628 Descriptor->Factory.Instances[Index].MaxGlobalInstanceCount = SrcDescriptor->MaxGlobalInstanceCount;
629 Descriptor->Factory.Instances[Index].MinFilterInstanceCount = SrcDescriptor->MinFilterInstanceCount;
630 SrcDescriptor = (PPCPIN_DESCRIPTOR)((ULONG_PTR)SrcDescriptor + FilterDescription->PinSize);
631 }
632 }
633
634 Descriptor->DeviceDescriptor = FilterDescription;
635 *OutSubdeviceDescriptor = Descriptor;
636 return STATUS_SUCCESS;
637
638 cleanup:
639 if (Descriptor)
640 {
641 if (Descriptor->Interfaces)
642 FreeItem(Descriptor->Interfaces, TAG_PORTCLASS);
643
644 if (Descriptor->Factory.KsPinDescriptor)
645 FreeItem(Descriptor->Factory.KsPinDescriptor, TAG_PORTCLASS);
646
647 FreeItem(Descriptor, TAG_PORTCLASS);
648 }
649 return Status;
650 }
651
652 NTSTATUS
653 NTAPI
654 PcValidateConnectRequest(
655 IN PIRP Irp,
656 IN KSPIN_FACTORY * Factory,
657 OUT PKSPIN_CONNECT * Connect)
658 {
659 return KsValidateConnectRequest(Irp, Factory->PinDescriptorCount, Factory->KsPinDescriptor, Connect);
660 }
661