[PORTCLS]
[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
90 NTSTATUS
91 NTAPI
92 PcHandlePropertyWithTable(
93 IN PIRP Irp,
94 IN ULONG PropertySetCount,
95 IN PKSPROPERTY_SET PropertySet,
96 IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)
97 {
98 NTSTATUS Status;
99 PIO_STACK_LOCATION IoStack;
100 PKSP_NODE Property;
101 PPCNODE_DESCRIPTOR Node;
102 PPCPROPERTY_ITEM PropertyItem;
103 ULONG Index;
104 LPGUID Buffer;
105 //PULONG Flags;
106 PPCPROPERTY_REQUEST PropertyRequest;
107
108 KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor;
109
110 /* try first KsPropertyHandler */
111 Status = KsPropertyHandler(Irp, PropertySetCount, PropertySet);
112
113 if (Status != STATUS_NOT_FOUND)
114 return Status;
115
116 // get current irp stack location
117 IoStack = IoGetCurrentIrpStackLocation(Irp);
118
119 // access property
120 Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
121
122 // check if this a GUID_NULL request
123 if (Status == STATUS_NOT_FOUND)
124 {
125 if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_NODE) || !(Property->Property.Flags & KSPROPERTY_TYPE_TOPOLOGY))
126 return Status;
127
128 // check if its a request for a topology node
129 if (IsEqualGUIDAligned(Property->Property.Set, GUID_NULL) && Property->Property.Id == 0 && Property->Property.Flags == (KSPROPERTY_TYPE_SETSUPPORT | KSPROPERTY_TYPE_TOPOLOGY))
130 {
131 if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount)
132 {
133 // request is out of bounds
134 Irp->IoStatus.Information = 0;
135 return STATUS_INVALID_PARAMETER;
136 }
137
138 Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize));
139
140 if (!Node->AutomationTable)
141 {
142 // request is out of bounds
143 Irp->IoStatus.Information = 0;
144 return STATUS_INVALID_PARAMETER;
145 }
146
147 PC_ASSERT(Node->AutomationTable);
148 PC_ASSERT(Node->AutomationTable->PropertyCount);
149 PC_ASSERT(Node->AutomationTable->PropertyItemSize);
150
151 Buffer = (LPGUID)AllocateItem(NonPagedPool, sizeof (GUID) * Node->AutomationTable->PropertyCount, TAG_PORTCLASS);
152 if (!Buffer)
153 return STATUS_INSUFFICIENT_RESOURCES;
154
155
156 ULONG Count = 0, SubIndex;
157 PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties;
158 for (Index = 0; Index < Node->AutomationTable->PropertyCount; Index++)
159 {
160 BOOL Found = FALSE;
161 for (SubIndex = 0; SubIndex < Count; Index++)
162 {
163 if (IsEqualGUIDAligned(Buffer[SubIndex], *PropertyItem->Set))
164 {
165 Found = TRUE;
166 break;
167 }
168 }
169 if (!Found)
170 {
171 RtlMoveMemory(&Buffer[Count], PropertyItem->Set, sizeof (GUID));
172 Count++;
173 }
174 PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize);
175 }
176
177 Irp->IoStatus.Information = sizeof (GUID) * Count;
178 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GUID) * Count)
179 {
180 // buffer too small
181 FreeItem(Buffer, TAG_PORTCLASS);
182 return STATUS_MORE_ENTRIES;
183 }
184
185 RtlMoveMemory(Irp->UserBuffer, Buffer, sizeof (GUID) * Count);
186 FreeItem(Buffer, TAG_PORTCLASS);
187 return STATUS_SUCCESS;
188 }
189 else /*if (Property->Property.Flags == (KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_TOPOLOGY) ||
190 Property->Property.Flags == (KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY) ||
191 Property->Property.Flags == (KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY)) */
192 {
193 //UNICODE_STRING GuidString;
194
195 if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount)
196 {
197 // request is out of bounds
198 Irp->IoStatus.Information = 0;
199 return STATUS_INVALID_PARAMETER;
200 }
201
202 Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize));
203
204 if (!Node->AutomationTable)
205 {
206 // request is out of bounds
207 Irp->IoStatus.Information = 0;
208 return STATUS_NOT_FOUND;
209 }
210
211 PC_ASSERT(Node->AutomationTable);
212 PC_ASSERT(Node->AutomationTable->PropertyCount);
213 PC_ASSERT(Node->AutomationTable->PropertyItemSize);
214
215 PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties;
216
217 for(Index = 0; Index < Node->AutomationTable->PropertyCount; Index++)
218 {
219 if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Property.Set) && PropertyItem->Id == Property->Property.Id)
220 {
221 if (Property->Property.Flags & KSPROPERTY_TYPE_BASICSUPPORT)
222 {
223 if (!(PropertyItem->Flags & KSPROPERTY_TYPE_BASICSUPPORT))
224 {
225 PC_ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(ULONG));
226 PULONG Flags = (PULONG)Irp->UserBuffer;
227
228 /* reset flags */
229 *Flags = 0;
230
231 if (PropertyItem->Flags & KSPROPERTY_TYPE_SET)
232 *Flags |= KSPROPERTY_TYPE_SET;
233
234 if (PropertyItem->Flags & KSPROPERTY_TYPE_GET)
235 *Flags |= KSPROPERTY_TYPE_GET;
236
237 Irp->IoStatus.Information = sizeof(ULONG);
238
239 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION))
240 {
241 /* get output buffer */
242 PKSPROPERTY_DESCRIPTION Description = (PKSPROPERTY_DESCRIPTION)Irp->UserBuffer;
243
244 /* store result */
245 Description->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION);
246 Description->PropTypeSet.Set = KSPROPTYPESETID_General;
247 Description->PropTypeSet.Id = 0;
248 Description->PropTypeSet.Flags = 0;
249 Description->MembersListCount = 0;
250 Description->Reserved = 0;
251
252 Irp->IoStatus.Information = sizeof(KSPROPERTY_DESCRIPTION);
253 }
254 return STATUS_SUCCESS;
255 }
256 }
257
258
259 PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS);
260 if (!PropertyRequest)
261 return STATUS_INSUFFICIENT_RESOURCES;
262
263 PC_ASSERT(SubDeviceDescriptor->UnknownMiniport);
264 PropertyRequest->MajorTarget = SubDeviceDescriptor->UnknownMiniport;
265 PropertyRequest->MinorTarget = SubDeviceDescriptor->UnknownStream;
266 PropertyRequest->Irp = Irp;
267 PropertyRequest->Node = Property->NodeId;
268 PropertyRequest->PropertyItem = PropertyItem;
269 PropertyRequest->Verb = Property->Property.Flags;
270 PropertyRequest->InstanceSize = IoStack->Parameters.DeviceIoControl.InputBufferLength - sizeof(KSNODEPROPERTY);
271 PropertyRequest->Instance = (PVOID)((ULONG_PTR)IoStack->Parameters.DeviceIoControl.Type3InputBuffer + sizeof(KSNODEPROPERTY));
272 PropertyRequest->ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
273 PropertyRequest->Value = Irp->UserBuffer;
274
275 Status = PropertyItem->Handler(PropertyRequest);
276
277 if (Status != STATUS_PENDING)
278 {
279 //DPRINT("Status %x ValueSize %u
280
281 Irp->IoStatus.Information = PropertyRequest->ValueSize;
282 ExFreePool(PropertyRequest);
283 }
284 #if 0
285 RtlStringFromGUID(Property->Property.Set, &GuidString);
286 DPRINT("Id %u Flags %x Set %S FlagsItem %x Status %x\n", Property->Property.Id, Property->Property.Flags, GuidString.Buffer, PropertyItem->Flags, Status);
287 RtlFreeUnicodeString(&GuidString);
288 #endif
289 return Status;
290 }
291 PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize);
292 }
293 #if 0
294 RtlStringFromGUID(Property->Property.Set, &GuidString);
295 DPRINT("Id %u Flags %x Set %S Status %x\n", Property->Property.Id, Property->Property.Flags, GuidString.Buffer, Status);
296 RtlFreeUnicodeString(&GuidString);
297 #endif
298 }
299 }
300 return Status;
301 }
302
303 VOID
304 NTAPI
305 PcAcquireFormatResources(
306 LONG Unknown,
307 LONG Unknown2,
308 LONG Unknown3,
309 LONG Unknown4)
310 {
311 UNIMPLEMENTED;
312 }
313
314 NTSTATUS
315 PcAddToEventTable(
316 PVOID Ptr,
317 LONG Unknown2,
318 ULONG Length,
319 LONG Unknown3,
320 LONG Unknown4,
321 LONG Unknown5,
322 LONG Unknown6,
323 LONG Unknown7)
324 {
325 UNIMPLEMENTED;
326 return STATUS_NOT_IMPLEMENTED;
327 }
328
329 NTSTATUS
330 PcAddToPropertyTable(
331 PVOID Ptr,
332 LONG Unknown,
333 LONG Unknown2,
334 LONG Unknown3,
335 CHAR Unknown4)
336 {
337 UNIMPLEMENTED;
338 return STATUS_NOT_IMPLEMENTED;
339 }
340
341 NTSTATUS
342 PcCaptureFormat(
343 LONG Unknown,
344 LONG Unknown2,
345 LONG Unknown3,
346 LONG Unknown4)
347 {
348 UNIMPLEMENTED;
349 return STATUS_NOT_IMPLEMENTED;
350 }
351
352 VOID
353 DumpFilterDescriptor(
354 IN PPCFILTER_DESCRIPTOR FilterDescription)
355 {
356 ULONG Index, SubIndex;
357 PPCPROPERTY_ITEM PropertyItem;
358 PPCEVENT_ITEM EventItem;
359 PPCNODE_DESCRIPTOR NodeDescriptor;
360 UNICODE_STRING GuidString;
361
362
363
364 DPRINT1("======================\n");
365 DPRINT1("Descriptor Automation Table%p\n",FilterDescription->AutomationTable);
366
367 if (FilterDescription->AutomationTable)
368 {
369 DPRINT1("FilterPropertiesCount %u FilterPropertySize %u Expected %u Events %u EventItemSize %u expected %u\n", FilterDescription->AutomationTable->PropertyCount, FilterDescription->AutomationTable->PropertyItemSize, sizeof(PCPROPERTY_ITEM),
370 FilterDescription->AutomationTable->EventCount, FilterDescription->AutomationTable->EventItemSize, sizeof(PCEVENT_ITEM));
371 if (FilterDescription->AutomationTable->PropertyCount)
372 {
373 PropertyItem = (PPCPROPERTY_ITEM)FilterDescription->AutomationTable->Properties;
374
375 for(Index = 0; Index < FilterDescription->AutomationTable->PropertyCount; Index++)
376 {
377 RtlStringFromGUID(*PropertyItem->Set, &GuidString);
378 DPRINT("Property Index %u GUID %S Id %u Flags %x\n", Index, GuidString.Buffer, PropertyItem->Id, PropertyItem->Flags);
379
380 PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + FilterDescription->AutomationTable->PropertyItemSize);
381 }
382
383 EventItem = (PPCEVENT_ITEM)FilterDescription->AutomationTable->Events;
384 for(Index = 0; Index < FilterDescription->AutomationTable->EventCount; Index++)
385 {
386 RtlStringFromGUID(*EventItem->Set, &GuidString);
387 DPRINT1("EventIndex %u GUID %S Id %u Flags %x\n", Index, GuidString.Buffer, EventItem->Id, EventItem->Flags);
388
389 EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + FilterDescription->AutomationTable->EventItemSize);
390 }
391
392 }
393 }
394
395 if (FilterDescription->Nodes)
396 {
397 DPRINT1("NodeCount %u NodeSize %u expected %u\n", FilterDescription->NodeCount, FilterDescription->NodeSize, sizeof(PCNODE_DESCRIPTOR));
398 NodeDescriptor = (PPCNODE_DESCRIPTOR)FilterDescription->Nodes;
399 for(Index = 0; Index < FilterDescription->NodeCount; Index++)
400 {
401 DPRINT("Index %u AutomationTable %p\n", Index, NodeDescriptor->AutomationTable);
402
403 if (NodeDescriptor->AutomationTable)
404 {
405 DPRINT1("Index %u EventCount %u\n", Index, NodeDescriptor->AutomationTable->EventCount);
406 EventItem = (PPCEVENT_ITEM)NodeDescriptor->AutomationTable->Events;
407 for(SubIndex = 0; SubIndex < NodeDescriptor->AutomationTable->EventCount; SubIndex++)
408 {
409 RtlStringFromGUID(*EventItem->Set, &GuidString);
410 DPRINT1("EventIndex %u GUID %S Id %u Flags %x\n", Index, GuidString.Buffer, EventItem->Id, EventItem->Flags);
411
412 EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + FilterDescription->AutomationTable->EventItemSize);
413 }
414
415 }
416
417
418 NodeDescriptor = (PPCNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescription->NodeSize);
419 }
420
421
422
423 }
424
425
426
427 DPRINT1("======================\n");
428 }
429
430 NTSTATUS
431 NTAPI
432 PcCreateSubdeviceDescriptor(
433 OUT SUBDEVICE_DESCRIPTOR ** OutSubdeviceDescriptor,
434 IN ULONG InterfaceCount,
435 IN GUID * InterfaceGuids,
436 IN ULONG IdentifierCount,
437 IN KSIDENTIFIER *Identifier,
438 IN ULONG FilterPropertiesCount,
439 IN KSPROPERTY_SET * FilterProperties,
440 IN ULONG Unknown1,
441 IN ULONG Unknown2,
442 IN ULONG PinPropertiesCount,
443 IN KSPROPERTY_SET * PinProperties,
444 IN ULONG EventSetCount,
445 IN KSEVENT_SET * EventSet,
446 IN PPCFILTER_DESCRIPTOR FilterDescription)
447 {
448 SUBDEVICE_DESCRIPTOR * Descriptor;
449 ULONG Index;
450 NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
451 PPCPIN_DESCRIPTOR SrcDescriptor;
452
453 Descriptor = (PSUBDEVICE_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(SUBDEVICE_DESCRIPTOR), TAG_PORTCLASS);
454 if (!Descriptor)
455 return STATUS_INSUFFICIENT_RESOURCES;
456
457 // initialize physical / symbolic link connection list
458 InitializeListHead(&Descriptor->SymbolicLinkList);
459 InitializeListHead(&Descriptor->PhysicalConnectionList);
460
461 Descriptor->Interfaces = (GUID*)AllocateItem(NonPagedPool, sizeof(GUID) * InterfaceCount, TAG_PORTCLASS);
462 if (!Descriptor->Interfaces)
463 goto cleanup;
464
465 // copy interface guids
466 RtlCopyMemory(Descriptor->Interfaces, InterfaceGuids, sizeof(GUID) * InterfaceCount);
467 Descriptor->InterfaceCount = InterfaceCount;
468
469 if (FilterPropertiesCount)
470 {
471 /// FIXME
472 /// handle driver properties
473
474 //DumpFilterDescriptor(FilterDescription);
475
476 Descriptor->FilterPropertySet = (PKSPROPERTY_SET)AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * FilterPropertiesCount, TAG_PORTCLASS);
477 if (! Descriptor->FilterPropertySet)
478 goto cleanup;
479
480 Descriptor->FilterPropertySetCount = FilterPropertiesCount;
481 for(Index = 0; Index < FilterPropertiesCount; Index++)
482 {
483 RtlMoveMemory(&Descriptor->FilterPropertySet[Index], &FilterProperties[Index], sizeof(KSPROPERTY_SET));
484 }
485 }
486
487 Descriptor->Topology = (PKSTOPOLOGY)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY), TAG_PORTCLASS);
488 if (!Descriptor->Topology)
489 goto cleanup;
490
491 if (FilterDescription->ConnectionCount)
492 {
493 Descriptor->Topology->TopologyConnections = (PKSTOPOLOGY_CONNECTION)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY_CONNECTION) * FilterDescription->ConnectionCount, TAG_PORTCLASS);
494 if (!Descriptor->Topology->TopologyConnections)
495 goto cleanup;
496
497 RtlMoveMemory((PVOID)Descriptor->Topology->TopologyConnections, FilterDescription->Connections, FilterDescription->ConnectionCount * sizeof(PCCONNECTION_DESCRIPTOR));
498 Descriptor->Topology->TopologyConnectionsCount = FilterDescription->ConnectionCount;
499 }
500
501 if (FilterDescription->NodeCount)
502 {
503 Descriptor->Topology->TopologyNodes = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS);
504 if (!Descriptor->Topology->TopologyNodes)
505 goto cleanup;
506
507 Descriptor->Topology->TopologyNodesNames = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS);
508 if (!Descriptor->Topology->TopologyNodesNames)
509 goto cleanup;
510
511 for(Index = 0; Index < FilterDescription->NodeCount; Index++)
512 {
513 if (FilterDescription->Nodes[Index].Type)
514 {
515 RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodes[Index], FilterDescription->Nodes[Index].Type, sizeof(GUID));
516 }
517 if (FilterDescription->Nodes[Index].Name)
518 {
519 RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodesNames[Index], FilterDescription->Nodes[Index].Name, sizeof(GUID));
520 }
521 }
522 Descriptor->Topology->TopologyNodesCount = FilterDescription->NodeCount;
523 }
524
525 if (FilterDescription->PinCount)
526 {
527 Descriptor->Factory.KsPinDescriptor = (PKSPIN_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR) * FilterDescription->PinCount, TAG_PORTCLASS);
528 if (!Descriptor->Factory.KsPinDescriptor)
529 goto cleanup;
530
531 Descriptor->Factory.Instances = (PPIN_INSTANCE_INFO)AllocateItem(NonPagedPool, FilterDescription->PinCount * sizeof(PIN_INSTANCE_INFO), TAG_PORTCLASS);
532 if (!Descriptor->Factory.Instances)
533 goto cleanup;
534
535 Descriptor->Factory.PinDescriptorCount = FilterDescription->PinCount;
536 Descriptor->Factory.PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR);
537
538 SrcDescriptor = (PPCPIN_DESCRIPTOR)FilterDescription->Pins;
539 DPRINT("Size %u Expected %u Ex Size %u\n", FilterDescription->PinSize, sizeof(KSPIN_DESCRIPTOR), sizeof(KSPIN_DESCRIPTOR_EX));
540
541 // copy pin factories
542 for(Index = 0; Index < FilterDescription->PinCount; Index++)
543 {
544 RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &SrcDescriptor->KsPinDescriptor, sizeof(KSPIN_DESCRIPTOR));
545
546 Descriptor->Factory.KsPinDescriptor[Index].Interfaces = PinInterfaces;
547 Descriptor->Factory.KsPinDescriptor[Index].InterfacesCount = sizeof(PinInterfaces) / sizeof(KSPIN_INTERFACE);
548
549 DPRINT("Index %u DataRangeCount %u\n", Index, SrcDescriptor->KsPinDescriptor.DataRangesCount);
550
551 Descriptor->Factory.Instances[Index].CurrentPinInstanceCount = 0;
552 Descriptor->Factory.Instances[Index].MaxFilterInstanceCount = SrcDescriptor->MaxFilterInstanceCount;
553 Descriptor->Factory.Instances[Index].MaxGlobalInstanceCount = SrcDescriptor->MaxGlobalInstanceCount;
554 Descriptor->Factory.Instances[Index].MinFilterInstanceCount = SrcDescriptor->MinFilterInstanceCount;
555 SrcDescriptor = (PPCPIN_DESCRIPTOR)((ULONG_PTR)SrcDescriptor + FilterDescription->PinSize);
556 }
557 }
558
559 Descriptor->DeviceDescriptor = FilterDescription;
560 *OutSubdeviceDescriptor = Descriptor;
561 return STATUS_SUCCESS;
562
563 cleanup:
564 if (Descriptor)
565 {
566 if (Descriptor->Interfaces)
567 FreeItem(Descriptor->Interfaces, TAG_PORTCLASS);
568
569 if (Descriptor->Factory.KsPinDescriptor)
570 FreeItem(Descriptor->Factory.KsPinDescriptor, TAG_PORTCLASS);
571
572 FreeItem(Descriptor, TAG_PORTCLASS);
573 }
574 return Status;
575 }
576
577 NTSTATUS
578 NTAPI
579 PcValidateConnectRequest(
580 IN PIRP Irp,
581 IN KSPIN_FACTORY * Factory,
582 OUT PKSPIN_CONNECT * Connect)
583 {
584 return KsValidateConnectRequest(Irp, Factory->PinDescriptorCount, Factory->KsPinDescriptor, Connect);
585 }
586