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
12 KSPIN_INTERFACE PinInterfaces
[] =
15 {STATIC_KSINTERFACESETID_Standard
},
16 KSINTERFACE_STANDARD_STREAMING
,
20 {STATIC_KSINTERFACESETID_Standard
},
21 KSINTERFACE_STANDARD_LOOPED_STREAMING
,
29 KsoDispatchCreateWithGenericFactory(
34 return STATUS_NOT_IMPLEMENTED
;
39 KsoGetIrpTargetFromFileObject(
40 PFILE_OBJECT FileObject
)
42 PC_ASSERT(FileObject
);
44 // IrpTarget is stored in FsContext
45 return (IIrpTarget
*)FileObject
->FsContext
;
50 KsoGetIrpTargetFromIrp(
53 PKSOBJECT_CREATE_ITEM CreateItem
;
55 // access the create item
56 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
58 // IIrpTarget is stored in Context member
59 return (IIrpTarget
*)CreateItem
->Context
;
64 PcHandleEnableEventWithTable(
66 IN PSUBDEVICE_DESCRIPTOR Descriptor
)
69 KSEVENT_ITEM_IRP_STORAGE(Irp
) = (PKSEVENT_ITEM
)Descriptor
;
72 return KsEnableEvent(Irp
, Descriptor
->EventSetCount
, Descriptor
->EventSet
, NULL
, KSEVENTS_NONE
, NULL
);
77 PcHandleDisableEventWithTable(
79 IN PSUBDEVICE_DESCRIPTOR Descriptor
)
82 KSEVENT_ITEM_IRP_STORAGE(Irp
) = (PKSEVENT_ITEM
)Descriptor
;
86 return KsDisableEvent(Irp
, Descriptor
->EventList
, KSEVENTS_SPINLOCK
, (PVOID
)Descriptor
->EventListLock
);
92 PcHandlePropertyWithTable(
94 IN ULONG PropertySetCount
,
95 IN PKSPROPERTY_SET PropertySet
,
96 IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor
)
99 PIO_STACK_LOCATION IoStack
;
101 PPCNODE_DESCRIPTOR Node
;
102 PPCPROPERTY_ITEM PropertyItem
;
106 PPCPROPERTY_REQUEST PropertyRequest
;
108 KSPROPERTY_ITEM_IRP_STORAGE(Irp
) = (PKSPROPERTY_ITEM
)SubDeviceDescriptor
;
110 /* try first KsPropertyHandler */
111 Status
= KsPropertyHandler(Irp
, PropertySetCount
, PropertySet
);
113 // get current irp stack location
114 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
117 Property
= (PKSP_NODE
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
119 // check if this a GUID_NULL request
120 if (Status
== STATUS_NOT_FOUND
)
122 if (IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(KSP_NODE
))
125 // check if its a request for a topology node
126 if (IsEqualGUIDAligned(Property
->Property
.Set
, GUID_NULL
) && Property
->Property
.Id
== 0 && Property
->Property
.Flags
== (KSPROPERTY_TYPE_SETSUPPORT
| KSPROPERTY_TYPE_TOPOLOGY
))
128 if (Property
->NodeId
>= SubDeviceDescriptor
->DeviceDescriptor
->NodeCount
)
130 // request is out of bounds
131 Irp
->IoStatus
.Information
= 0;
132 return STATUS_INVALID_PARAMETER
;
135 Node
= (PPCNODE_DESCRIPTOR
)((ULONG_PTR
)SubDeviceDescriptor
->DeviceDescriptor
->Nodes
+ (Property
->NodeId
* SubDeviceDescriptor
->DeviceDescriptor
->NodeSize
));
137 if (!Node
->AutomationTable
)
139 // request is out of bounds
140 Irp
->IoStatus
.Information
= 0;
141 return STATUS_INVALID_PARAMETER
;
144 PC_ASSERT(Node
->AutomationTable
);
145 PC_ASSERT(Node
->AutomationTable
->PropertyCount
);
146 PC_ASSERT(Node
->AutomationTable
->PropertyItemSize
);
148 Buffer
= (LPGUID
)AllocateItem(NonPagedPool
, sizeof (GUID
) * Node
->AutomationTable
->PropertyCount
, TAG_PORTCLASS
);
150 return STATUS_INSUFFICIENT_RESOURCES
;
153 ULONG Count
= 0, SubIndex
;
154 PropertyItem
= (PCPROPERTY_ITEM
*)Node
->AutomationTable
->Properties
;
155 for (Index
= 0; Index
< Node
->AutomationTable
->PropertyCount
; Index
++)
158 for (SubIndex
= 0; SubIndex
< Count
; Index
++)
160 if (IsEqualGUIDAligned(Buffer
[SubIndex
], *PropertyItem
->Set
))
168 RtlMoveMemory(&Buffer
[Count
], PropertyItem
->Set
, sizeof (GUID
));
171 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ Node
->AutomationTable
->PropertyItemSize
);
174 Irp
->IoStatus
.Information
= sizeof (GUID
) * Count
;
175 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< sizeof (GUID
) * Count
)
178 FreeItem(Buffer
, TAG_PORTCLASS
);
179 return STATUS_MORE_ENTRIES
;
182 RtlMoveMemory(Irp
->UserBuffer
, Buffer
, sizeof (GUID
) * Count
);
183 FreeItem(Buffer
, TAG_PORTCLASS
);
184 return STATUS_SUCCESS
;
186 else /*if (Property->Property.Flags == (KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_TOPOLOGY) ||
187 Property->Property.Flags == (KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY) ||
188 Property->Property.Flags == (KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY)) */
190 //UNICODE_STRING GuidString;
192 if (Property
->NodeId
>= SubDeviceDescriptor
->DeviceDescriptor
->NodeCount
)
194 // request is out of bounds
195 Irp
->IoStatus
.Information
= 0;
196 return STATUS_INVALID_PARAMETER
;
199 Node
= (PPCNODE_DESCRIPTOR
)((ULONG_PTR
)SubDeviceDescriptor
->DeviceDescriptor
->Nodes
+ (Property
->NodeId
* SubDeviceDescriptor
->DeviceDescriptor
->NodeSize
));
201 if (!Node
->AutomationTable
)
203 // request is out of bounds
204 Irp
->IoStatus
.Information
= 0;
205 return STATUS_NOT_FOUND
;
208 PC_ASSERT(Node
->AutomationTable
);
209 PC_ASSERT(Node
->AutomationTable
->PropertyCount
);
210 PC_ASSERT(Node
->AutomationTable
->PropertyItemSize
);
212 PropertyItem
= (PCPROPERTY_ITEM
*)Node
->AutomationTable
->Properties
;
214 for(Index
= 0; Index
< Node
->AutomationTable
->PropertyCount
; Index
++)
216 if (IsEqualGUIDAligned(*PropertyItem
->Set
, Property
->Property
.Set
) && PropertyItem
->Id
== Property
->Property
.Id
)
218 if (Property
->Property
.Flags
& KSPROPERTY_TYPE_BASICSUPPORT
)
220 if (!(PropertyItem
->Flags
& KSPROPERTY_TYPE_BASICSUPPORT
))
222 PC_ASSERT(IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
>= sizeof(ULONG
));
223 PULONG Flags
= (PULONG
)Irp
->UserBuffer
;
228 if (PropertyItem
->Flags
& KSPROPERTY_TYPE_SET
)
229 *Flags
|= KSPROPERTY_TYPE_SET
;
231 if (PropertyItem
->Flags
& KSPROPERTY_TYPE_GET
)
232 *Flags
|= KSPROPERTY_TYPE_GET
;
234 Irp
->IoStatus
.Information
= sizeof(ULONG
);
236 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
>= sizeof(KSPROPERTY_DESCRIPTION
))
238 /* get output buffer */
239 PKSPROPERTY_DESCRIPTION Description
= (PKSPROPERTY_DESCRIPTION
)Irp
->UserBuffer
;
242 Description
->DescriptionSize
= sizeof(KSPROPERTY_DESCRIPTION
);
243 Description
->PropTypeSet
.Set
= KSPROPTYPESETID_General
;
244 Description
->PropTypeSet
.Id
= 0;
245 Description
->PropTypeSet
.Flags
= 0;
246 Description
->MembersListCount
= 0;
247 Description
->Reserved
= 0;
249 Irp
->IoStatus
.Information
= sizeof(KSPROPERTY_DESCRIPTION
);
251 return STATUS_SUCCESS
;
256 PropertyRequest
= (PPCPROPERTY_REQUEST
)AllocateItem(NonPagedPool
, sizeof(PCPROPERTY_REQUEST
), TAG_PORTCLASS
);
257 if (!PropertyRequest
)
258 return STATUS_INSUFFICIENT_RESOURCES
;
260 PC_ASSERT(SubDeviceDescriptor
->UnknownMiniport
);
261 PropertyRequest
->MajorTarget
= SubDeviceDescriptor
->UnknownMiniport
;
262 PropertyRequest
->MinorTarget
= SubDeviceDescriptor
->UnknownStream
;
263 PropertyRequest
->Irp
= Irp
;
264 PropertyRequest
->Node
= Property
->NodeId
;
265 PropertyRequest
->PropertyItem
= PropertyItem
;
266 PropertyRequest
->Verb
= Property
->Property
.Flags
;
267 PropertyRequest
->InstanceSize
= IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
- sizeof(KSNODEPROPERTY
);
268 PropertyRequest
->Instance
= (PVOID
)((ULONG_PTR
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
+ sizeof(KSNODEPROPERTY
));
269 PropertyRequest
->ValueSize
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
270 PropertyRequest
->Value
= Irp
->UserBuffer
;
272 Status
= PropertyItem
->Handler(PropertyRequest
);
274 if (Status
!= STATUS_PENDING
)
276 //DPRINT("Status %x ValueSize %u
278 Irp
->IoStatus
.Information
= PropertyRequest
->ValueSize
;
279 ExFreePool(PropertyRequest
);
282 RtlStringFromGUID(Property
->Property
.Set
, &GuidString
);
283 DPRINT("Id %u Flags %x Set %S FlagsItem %x Status %x\n", Property
->Property
.Id
, Property
->Property
.Flags
, GuidString
.Buffer
, PropertyItem
->Flags
, Status
);
284 RtlFreeUnicodeString(&GuidString
);
288 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ Node
->AutomationTable
->PropertyItemSize
);
291 RtlStringFromGUID(Property
->Property
.Set
, &GuidString
);
292 DPRINT("Id %u Flags %x Set %S Status %x\n", Property
->Property
.Id
, Property
->Property
.Flags
, GuidString
.Buffer
, Status
);
293 RtlFreeUnicodeString(&GuidString
);
302 PcAcquireFormatResources(
323 return STATUS_NOT_IMPLEMENTED
;
327 PcAddToPropertyTable(
335 return STATUS_NOT_IMPLEMENTED
;
346 return STATUS_NOT_IMPLEMENTED
;
350 DumpFilterDescriptor(
351 IN PPCFILTER_DESCRIPTOR FilterDescription
)
354 PPCPROPERTY_ITEM PropertyItem
;
355 UNICODE_STRING GuidString
;
357 DPRINT("======================\n");
358 DPRINT("Descriptor Automation Table%p\n",FilterDescription
->AutomationTable
);
360 if (FilterDescription
->AutomationTable
)
362 DPRINT("FilterPropertiesCount %u FilterPropertySize %u Expected %u\n", FilterDescription
->AutomationTable
->PropertyCount
, FilterDescription
->AutomationTable
->PropertyItemSize
, sizeof(PCPROPERTY_ITEM
));
363 if (FilterDescription
->AutomationTable
->PropertyCount
)
365 PropertyItem
= (PPCPROPERTY_ITEM
)FilterDescription
->AutomationTable
->Properties
;
367 for(Index
= 0; Index
< FilterDescription
->AutomationTable
->PropertyCount
; Index
++)
369 RtlStringFromGUID(*PropertyItem
->Set
, &GuidString
);
370 DPRINT("Index %u GUID %S Id %u Flags %x\n", Index
, GuidString
.Buffer
, PropertyItem
->Id
, PropertyItem
->Flags
);
372 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ FilterDescription
->AutomationTable
->PropertyItemSize
);
378 DPRINT("======================\n");
383 PcCreateSubdeviceDescriptor(
384 OUT SUBDEVICE_DESCRIPTOR
** OutSubdeviceDescriptor
,
385 IN ULONG InterfaceCount
,
386 IN GUID
* InterfaceGuids
,
387 IN ULONG IdentifierCount
,
388 IN KSIDENTIFIER
*Identifier
,
389 IN ULONG FilterPropertiesCount
,
390 IN KSPROPERTY_SET
* FilterProperties
,
393 IN ULONG PinPropertiesCount
,
394 IN KSPROPERTY_SET
* PinProperties
,
395 IN ULONG EventSetCount
,
396 IN KSEVENT_SET
* EventSet
,
397 IN PPCFILTER_DESCRIPTOR FilterDescription
)
399 SUBDEVICE_DESCRIPTOR
* Descriptor
;
401 NTSTATUS Status
= STATUS_INSUFFICIENT_RESOURCES
;
402 PPCPIN_DESCRIPTOR SrcDescriptor
;
404 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)AllocateItem(NonPagedPool
, sizeof(SUBDEVICE_DESCRIPTOR
), TAG_PORTCLASS
);
406 return STATUS_INSUFFICIENT_RESOURCES
;
408 // initialize physical / symbolic link connection list
409 InitializeListHead(&Descriptor
->SymbolicLinkList
);
410 InitializeListHead(&Descriptor
->PhysicalConnectionList
);
412 Descriptor
->Interfaces
= (GUID
*)AllocateItem(NonPagedPool
, sizeof(GUID
) * InterfaceCount
, TAG_PORTCLASS
);
413 if (!Descriptor
->Interfaces
)
416 // copy interface guids
417 RtlCopyMemory(Descriptor
->Interfaces
, InterfaceGuids
, sizeof(GUID
) * InterfaceCount
);
418 Descriptor
->InterfaceCount
= InterfaceCount
;
420 if (FilterPropertiesCount
)
423 /// handle driver properties
425 //DumpFilterDescriptor(FilterDescription);
427 Descriptor
->FilterPropertySet
= (PKSPROPERTY_SET
)AllocateItem(NonPagedPool
, sizeof(KSPROPERTY_SET
) * FilterPropertiesCount
, TAG_PORTCLASS
);
428 if (! Descriptor
->FilterPropertySet
)
431 Descriptor
->FilterPropertySetCount
= FilterPropertiesCount
;
432 for(Index
= 0; Index
< FilterPropertiesCount
; Index
++)
434 RtlMoveMemory(&Descriptor
->FilterPropertySet
[Index
], &FilterProperties
[Index
], sizeof(KSPROPERTY_SET
));
438 Descriptor
->Topology
= (PKSTOPOLOGY
)AllocateItem(NonPagedPool
, sizeof(KSTOPOLOGY
), TAG_PORTCLASS
);
439 if (!Descriptor
->Topology
)
442 if (FilterDescription
->ConnectionCount
)
444 Descriptor
->Topology
->TopologyConnections
= (PKSTOPOLOGY_CONNECTION
)AllocateItem(NonPagedPool
, sizeof(KSTOPOLOGY_CONNECTION
) * FilterDescription
->ConnectionCount
, TAG_PORTCLASS
);
445 if (!Descriptor
->Topology
->TopologyConnections
)
448 RtlMoveMemory((PVOID
)Descriptor
->Topology
->TopologyConnections
, FilterDescription
->Connections
, FilterDescription
->ConnectionCount
* sizeof(PCCONNECTION_DESCRIPTOR
));
449 Descriptor
->Topology
->TopologyConnectionsCount
= FilterDescription
->ConnectionCount
;
452 if (FilterDescription
->NodeCount
)
454 Descriptor
->Topology
->TopologyNodes
= (const GUID
*)AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescription
->NodeCount
, TAG_PORTCLASS
);
455 if (!Descriptor
->Topology
->TopologyNodes
)
458 Descriptor
->Topology
->TopologyNodesNames
= (const GUID
*)AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescription
->NodeCount
, TAG_PORTCLASS
);
459 if (!Descriptor
->Topology
->TopologyNodesNames
)
462 for(Index
= 0; Index
< FilterDescription
->NodeCount
; Index
++)
464 if (FilterDescription
->Nodes
[Index
].Type
)
466 RtlMoveMemory((PVOID
)&Descriptor
->Topology
->TopologyNodes
[Index
], FilterDescription
->Nodes
[Index
].Type
, sizeof(GUID
));
468 if (FilterDescription
->Nodes
[Index
].Name
)
470 RtlMoveMemory((PVOID
)&Descriptor
->Topology
->TopologyNodesNames
[Index
], FilterDescription
->Nodes
[Index
].Name
, sizeof(GUID
));
473 Descriptor
->Topology
->TopologyNodesCount
= FilterDescription
->NodeCount
;
476 if (FilterDescription
->PinCount
)
478 Descriptor
->Factory
.KsPinDescriptor
= (PKSPIN_DESCRIPTOR
)AllocateItem(NonPagedPool
, sizeof(KSPIN_DESCRIPTOR
) * FilterDescription
->PinCount
, TAG_PORTCLASS
);
479 if (!Descriptor
->Factory
.KsPinDescriptor
)
482 Descriptor
->Factory
.Instances
= (PPIN_INSTANCE_INFO
)AllocateItem(NonPagedPool
, FilterDescription
->PinCount
* sizeof(PIN_INSTANCE_INFO
), TAG_PORTCLASS
);
483 if (!Descriptor
->Factory
.Instances
)
486 Descriptor
->Factory
.PinDescriptorCount
= FilterDescription
->PinCount
;
487 Descriptor
->Factory
.PinDescriptorSize
= sizeof(KSPIN_DESCRIPTOR
);
489 SrcDescriptor
= (PPCPIN_DESCRIPTOR
)FilterDescription
->Pins
;
490 DPRINT("Size %u Expected %u Ex Size %u\n", FilterDescription
->PinSize
, sizeof(KSPIN_DESCRIPTOR
), sizeof(KSPIN_DESCRIPTOR_EX
));
492 // copy pin factories
493 for(Index
= 0; Index
< FilterDescription
->PinCount
; Index
++)
495 RtlMoveMemory(&Descriptor
->Factory
.KsPinDescriptor
[Index
], &SrcDescriptor
->KsPinDescriptor
, sizeof(KSPIN_DESCRIPTOR
));
497 Descriptor
->Factory
.KsPinDescriptor
[Index
].Interfaces
= PinInterfaces
;
498 Descriptor
->Factory
.KsPinDescriptor
[Index
].InterfacesCount
= sizeof(PinInterfaces
) / sizeof(KSPIN_INTERFACE
);
500 DPRINT("Index %u DataRangeCount %u\n", Index
, SrcDescriptor
->KsPinDescriptor
.DataRangesCount
);
502 Descriptor
->Factory
.Instances
[Index
].CurrentPinInstanceCount
= 0;
503 Descriptor
->Factory
.Instances
[Index
].MaxFilterInstanceCount
= SrcDescriptor
->MaxFilterInstanceCount
;
504 Descriptor
->Factory
.Instances
[Index
].MaxGlobalInstanceCount
= SrcDescriptor
->MaxGlobalInstanceCount
;
505 Descriptor
->Factory
.Instances
[Index
].MinFilterInstanceCount
= SrcDescriptor
->MinFilterInstanceCount
;
506 SrcDescriptor
= (PPCPIN_DESCRIPTOR
)((ULONG_PTR
)SrcDescriptor
+ FilterDescription
->PinSize
);
510 Descriptor
->DeviceDescriptor
= FilterDescription
;
511 *OutSubdeviceDescriptor
= Descriptor
;
512 return STATUS_SUCCESS
;
517 if (Descriptor
->Interfaces
)
518 FreeItem(Descriptor
->Interfaces
, TAG_PORTCLASS
);
520 if (Descriptor
->Factory
.KsPinDescriptor
)
521 FreeItem(Descriptor
->Factory
.KsPinDescriptor
, TAG_PORTCLASS
);
523 FreeItem(Descriptor
, TAG_PORTCLASS
);
530 PcValidateConnectRequest(
532 IN KSPIN_FACTORY
* Factory
,
533 OUT PKSPIN_CONNECT
* Connect
)
535 return KsValidateConnectRequest(Irp
, Factory
->PinDescriptorCount
, Factory
->KsPinDescriptor
, Connect
);