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 PcHandlePropertyWithTable(
66 IN ULONG PropertySetCount
,
67 IN PKSPROPERTY_SET PropertySet
,
68 IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor
)
71 PIO_STACK_LOCATION IoStack
;
73 PPCNODE_DESCRIPTOR Node
;
74 PPCPROPERTY_ITEM PropertyItem
;
78 PPCPROPERTY_REQUEST PropertyRequest
;
80 KSPROPERTY_ITEM_IRP_STORAGE(Irp
) = (PKSPROPERTY_ITEM
)SubDeviceDescriptor
;
82 /* try first KsPropertyHandler */
83 Status
= KsPropertyHandler(Irp
, PropertySetCount
, PropertySet
);
85 // get current irp stack location
86 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
89 Property
= (PKSP_NODE
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
91 // check if this a GUID_NULL request
92 if (Status
== STATUS_NOT_FOUND
)
94 if (IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(KSP_NODE
))
97 // check if its a request for a topology node
98 if (IsEqualGUIDAligned(Property
->Property
.Set
, GUID_NULL
) && Property
->Property
.Id
== 0 && Property
->Property
.Flags
== (KSPROPERTY_TYPE_SETSUPPORT
| KSPROPERTY_TYPE_TOPOLOGY
))
100 if (Property
->NodeId
>= SubDeviceDescriptor
->DeviceDescriptor
->NodeCount
)
102 // request is out of bounds
103 Irp
->IoStatus
.Information
= 0;
104 return STATUS_INVALID_PARAMETER
;
107 Node
= (PPCNODE_DESCRIPTOR
)((ULONG_PTR
)SubDeviceDescriptor
->DeviceDescriptor
->Nodes
+ (Property
->NodeId
* SubDeviceDescriptor
->DeviceDescriptor
->NodeSize
));
109 if (!Node
->AutomationTable
)
111 // request is out of bounds
112 Irp
->IoStatus
.Information
= 0;
113 return STATUS_INVALID_PARAMETER
;
116 PC_ASSERT(Node
->AutomationTable
);
117 PC_ASSERT(Node
->AutomationTable
->PropertyCount
);
118 PC_ASSERT(Node
->AutomationTable
->PropertyItemSize
);
120 Buffer
= (LPGUID
)AllocateItem(NonPagedPool
, sizeof (GUID
) * Node
->AutomationTable
->PropertyCount
, TAG_PORTCLASS
);
122 return STATUS_INSUFFICIENT_RESOURCES
;
125 ULONG Count
= 0, SubIndex
;
126 PropertyItem
= (PCPROPERTY_ITEM
*)Node
->AutomationTable
->Properties
;
127 for (Index
= 0; Index
< Node
->AutomationTable
->PropertyCount
; Index
++)
130 for (SubIndex
= 0; SubIndex
< Count
; Index
++)
132 if (IsEqualGUIDAligned(Buffer
[SubIndex
], *PropertyItem
->Set
))
140 RtlMoveMemory(&Buffer
[Count
], PropertyItem
->Set
, sizeof (GUID
));
143 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ Node
->AutomationTable
->PropertyItemSize
);
146 Irp
->IoStatus
.Information
= sizeof (GUID
) * Count
;
147 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< sizeof (GUID
) * Count
)
150 FreeItem(Buffer
, TAG_PORTCLASS
);
151 return STATUS_MORE_ENTRIES
;
154 RtlMoveMemory(Irp
->UserBuffer
, Buffer
, sizeof (GUID
) * Count
);
155 FreeItem(Buffer
, TAG_PORTCLASS
);
156 return STATUS_SUCCESS
;
158 else /*if (Property->Property.Flags == (KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_TOPOLOGY) ||
159 Property->Property.Flags == (KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY) ||
160 Property->Property.Flags == (KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY)) */
162 //UNICODE_STRING GuidString;
164 if (Property
->NodeId
>= SubDeviceDescriptor
->DeviceDescriptor
->NodeCount
)
166 // request is out of bounds
167 Irp
->IoStatus
.Information
= 0;
168 return STATUS_INVALID_PARAMETER
;
171 Node
= (PPCNODE_DESCRIPTOR
)((ULONG_PTR
)SubDeviceDescriptor
->DeviceDescriptor
->Nodes
+ (Property
->NodeId
* SubDeviceDescriptor
->DeviceDescriptor
->NodeSize
));
173 if (!Node
->AutomationTable
)
175 // request is out of bounds
176 Irp
->IoStatus
.Information
= 0;
177 return STATUS_NOT_FOUND
;
180 PC_ASSERT(Node
->AutomationTable
);
181 PC_ASSERT(Node
->AutomationTable
->PropertyCount
);
182 PC_ASSERT(Node
->AutomationTable
->PropertyItemSize
);
184 PropertyItem
= (PCPROPERTY_ITEM
*)Node
->AutomationTable
->Properties
;
186 for(Index
= 0; Index
< Node
->AutomationTable
->PropertyCount
; Index
++)
188 if (IsEqualGUIDAligned(*PropertyItem
->Set
, Property
->Property
.Set
) && PropertyItem
->Id
== Property
->Property
.Id
)
190 if (Property
->Property
.Flags
& KSPROPERTY_TYPE_BASICSUPPORT
)
192 if (!(PropertyItem
->Flags
& KSPROPERTY_TYPE_BASICSUPPORT
))
194 PC_ASSERT(IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
>= sizeof(ULONG
));
195 PULONG Flags
= (PULONG
)Irp
->UserBuffer
;
200 if (PropertyItem
->Flags
& KSPROPERTY_TYPE_SET
)
201 *Flags
|= KSPROPERTY_TYPE_SET
;
203 if (PropertyItem
->Flags
& KSPROPERTY_TYPE_GET
)
204 *Flags
|= KSPROPERTY_TYPE_GET
;
206 Irp
->IoStatus
.Information
= sizeof(ULONG
);
208 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
>= sizeof(KSPROPERTY_DESCRIPTION
))
210 /* get output buffer */
211 PKSPROPERTY_DESCRIPTION Description
= (PKSPROPERTY_DESCRIPTION
)Irp
->UserBuffer
;
214 Description
->DescriptionSize
= sizeof(KSPROPERTY_DESCRIPTION
);
215 Description
->PropTypeSet
.Set
= KSPROPTYPESETID_General
;
216 Description
->PropTypeSet
.Id
= 0;
217 Description
->PropTypeSet
.Flags
= 0;
218 Description
->MembersListCount
= 0;
219 Description
->Reserved
= 0;
221 Irp
->IoStatus
.Information
= sizeof(KSPROPERTY_DESCRIPTION
);
223 return STATUS_SUCCESS
;
228 PropertyRequest
= (PPCPROPERTY_REQUEST
)AllocateItem(NonPagedPool
, sizeof(PCPROPERTY_REQUEST
), TAG_PORTCLASS
);
229 if (!PropertyRequest
)
230 return STATUS_INSUFFICIENT_RESOURCES
;
232 PC_ASSERT(SubDeviceDescriptor
->UnknownMiniport
);
233 PropertyRequest
->MajorTarget
= SubDeviceDescriptor
->UnknownMiniport
;
234 PropertyRequest
->MinorTarget
= SubDeviceDescriptor
->UnknownStream
;
235 PropertyRequest
->Irp
= Irp
;
236 PropertyRequest
->Node
= Property
->NodeId
;
237 PropertyRequest
->PropertyItem
= PropertyItem
;
238 PropertyRequest
->Verb
= Property
->Property
.Flags
;
239 PropertyRequest
->InstanceSize
= IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
- sizeof(KSNODEPROPERTY
);
240 PropertyRequest
->Instance
= (PVOID
)((ULONG_PTR
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
+ sizeof(KSNODEPROPERTY
));
241 PropertyRequest
->ValueSize
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
242 PropertyRequest
->Value
= Irp
->UserBuffer
;
244 Status
= PropertyItem
->Handler(PropertyRequest
);
246 if (Status
!= STATUS_PENDING
)
248 //DPRINT("Status %x ValueSize %u
250 Irp
->IoStatus
.Information
= PropertyRequest
->ValueSize
;
251 ExFreePool(PropertyRequest
);
254 RtlStringFromGUID(Property
->Property
.Set
, &GuidString
);
255 DPRINT("Id %u Flags %x Set %S FlagsItem %x Status %x\n", Property
->Property
.Id
, Property
->Property
.Flags
, GuidString
.Buffer
, PropertyItem
->Flags
, Status
);
256 RtlFreeUnicodeString(&GuidString
);
260 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ Node
->AutomationTable
->PropertyItemSize
);
263 RtlStringFromGUID(Property
->Property
.Set
, &GuidString
);
264 DPRINT("Id %u Flags %x Set %S Status %x\n", Property
->Property
.Id
, Property
->Property
.Flags
, GuidString
.Buffer
, Status
);
265 RtlFreeUnicodeString(&GuidString
);
274 PcAcquireFormatResources(
295 return STATUS_NOT_IMPLEMENTED
;
299 PcAddToPropertyTable(
307 return STATUS_NOT_IMPLEMENTED
;
318 return STATUS_NOT_IMPLEMENTED
;
322 DumpFilterDescriptor(
323 IN PPCFILTER_DESCRIPTOR FilterDescription
)
326 PPCPROPERTY_ITEM PropertyItem
;
327 UNICODE_STRING GuidString
;
329 DPRINT("======================\n");
330 DPRINT("Descriptor Automation Table%p\n",FilterDescription
->AutomationTable
);
332 if (FilterDescription
->AutomationTable
)
334 DPRINT("FilterPropertiesCount %u FilterPropertySize %u Expected %u\n", FilterDescription
->AutomationTable
->PropertyCount
, FilterDescription
->AutomationTable
->PropertyItemSize
, sizeof(PCPROPERTY_ITEM
));
335 if (FilterDescription
->AutomationTable
->PropertyCount
)
337 PropertyItem
= (PPCPROPERTY_ITEM
)FilterDescription
->AutomationTable
->Properties
;
339 for(Index
= 0; Index
< FilterDescription
->AutomationTable
->PropertyCount
; Index
++)
341 RtlStringFromGUID(*PropertyItem
->Set
, &GuidString
);
342 DPRINT("Index %u GUID %S Id %u Flags %x\n", Index
, GuidString
.Buffer
, PropertyItem
->Id
, PropertyItem
->Flags
);
344 PropertyItem
= (PPCPROPERTY_ITEM
)((ULONG_PTR
)PropertyItem
+ FilterDescription
->AutomationTable
->PropertyItemSize
);
350 DPRINT("======================\n");
355 PcCreateSubdeviceDescriptor(
356 OUT SUBDEVICE_DESCRIPTOR
** OutSubdeviceDescriptor
,
357 IN ULONG InterfaceCount
,
358 IN GUID
* InterfaceGuids
,
359 IN ULONG IdentifierCount
,
360 IN KSIDENTIFIER
*Identifier
,
361 IN ULONG FilterPropertiesCount
,
362 IN KSPROPERTY_SET
* FilterProperties
,
365 IN ULONG PinPropertiesCount
,
366 IN KSPROPERTY_SET
* PinProperties
,
367 IN ULONG EventSetCount
,
368 IN KSEVENT_SET
* EventSet
,
369 IN PPCFILTER_DESCRIPTOR FilterDescription
)
371 SUBDEVICE_DESCRIPTOR
* Descriptor
;
373 NTSTATUS Status
= STATUS_INSUFFICIENT_RESOURCES
;
374 PPCPIN_DESCRIPTOR SrcDescriptor
;
376 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)AllocateItem(NonPagedPool
, sizeof(SUBDEVICE_DESCRIPTOR
), TAG_PORTCLASS
);
378 return STATUS_INSUFFICIENT_RESOURCES
;
380 // initialize physical / symbolic link connection list
381 InitializeListHead(&Descriptor
->SymbolicLinkList
);
382 InitializeListHead(&Descriptor
->PhysicalConnectionList
);
384 Descriptor
->Interfaces
= (GUID
*)AllocateItem(NonPagedPool
, sizeof(GUID
) * InterfaceCount
, TAG_PORTCLASS
);
385 if (!Descriptor
->Interfaces
)
388 // copy interface guids
389 RtlCopyMemory(Descriptor
->Interfaces
, InterfaceGuids
, sizeof(GUID
) * InterfaceCount
);
390 Descriptor
->InterfaceCount
= InterfaceCount
;
392 if (FilterPropertiesCount
)
395 /// handle driver properties
397 //DumpFilterDescriptor(FilterDescription);
399 Descriptor
->FilterPropertySet
= (PKSPROPERTY_SET
)AllocateItem(NonPagedPool
, sizeof(KSPROPERTY_SET
) * FilterPropertiesCount
, TAG_PORTCLASS
);
400 if (! Descriptor
->FilterPropertySet
)
403 Descriptor
->FilterPropertySetCount
= FilterPropertiesCount
;
404 for(Index
= 0; Index
< FilterPropertiesCount
; Index
++)
406 RtlMoveMemory(&Descriptor
->FilterPropertySet
[Index
], &FilterProperties
[Index
], sizeof(KSPROPERTY_SET
));
410 Descriptor
->Topology
= (PKSTOPOLOGY
)AllocateItem(NonPagedPool
, sizeof(KSTOPOLOGY
), TAG_PORTCLASS
);
411 if (!Descriptor
->Topology
)
414 if (FilterDescription
->ConnectionCount
)
416 Descriptor
->Topology
->TopologyConnections
= (PKSTOPOLOGY_CONNECTION
)AllocateItem(NonPagedPool
, sizeof(KSTOPOLOGY_CONNECTION
) * FilterDescription
->ConnectionCount
, TAG_PORTCLASS
);
417 if (!Descriptor
->Topology
->TopologyConnections
)
420 RtlMoveMemory((PVOID
)Descriptor
->Topology
->TopologyConnections
, FilterDescription
->Connections
, FilterDescription
->ConnectionCount
* sizeof(PCCONNECTION_DESCRIPTOR
));
421 Descriptor
->Topology
->TopologyConnectionsCount
= FilterDescription
->ConnectionCount
;
424 if (FilterDescription
->NodeCount
)
426 Descriptor
->Topology
->TopologyNodes
= (const GUID
*)AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescription
->NodeCount
, TAG_PORTCLASS
);
427 if (!Descriptor
->Topology
->TopologyNodes
)
430 Descriptor
->Topology
->TopologyNodesNames
= (const GUID
*)AllocateItem(NonPagedPool
, sizeof(GUID
) * FilterDescription
->NodeCount
, TAG_PORTCLASS
);
431 if (!Descriptor
->Topology
->TopologyNodesNames
)
434 for(Index
= 0; Index
< FilterDescription
->NodeCount
; Index
++)
436 if (FilterDescription
->Nodes
[Index
].Type
)
438 RtlMoveMemory((PVOID
)&Descriptor
->Topology
->TopologyNodes
[Index
], FilterDescription
->Nodes
[Index
].Type
, sizeof(GUID
));
440 if (FilterDescription
->Nodes
[Index
].Name
)
442 RtlMoveMemory((PVOID
)&Descriptor
->Topology
->TopologyNodesNames
[Index
], FilterDescription
->Nodes
[Index
].Name
, sizeof(GUID
));
445 Descriptor
->Topology
->TopologyNodesCount
= FilterDescription
->NodeCount
;
448 if (FilterDescription
->PinCount
)
450 Descriptor
->Factory
.KsPinDescriptor
= (PKSPIN_DESCRIPTOR
)AllocateItem(NonPagedPool
, sizeof(KSPIN_DESCRIPTOR
) * FilterDescription
->PinCount
, TAG_PORTCLASS
);
451 if (!Descriptor
->Factory
.KsPinDescriptor
)
454 Descriptor
->Factory
.Instances
= (PPIN_INSTANCE_INFO
)AllocateItem(NonPagedPool
, FilterDescription
->PinCount
* sizeof(PIN_INSTANCE_INFO
), TAG_PORTCLASS
);
455 if (!Descriptor
->Factory
.Instances
)
458 Descriptor
->Factory
.PinDescriptorCount
= FilterDescription
->PinCount
;
459 Descriptor
->Factory
.PinDescriptorSize
= sizeof(KSPIN_DESCRIPTOR
);
461 SrcDescriptor
= (PPCPIN_DESCRIPTOR
)FilterDescription
->Pins
;
462 DPRINT("Size %u Expected %u Ex Size %u\n", FilterDescription
->PinSize
, sizeof(KSPIN_DESCRIPTOR
), sizeof(KSPIN_DESCRIPTOR_EX
));
464 // copy pin factories
465 for(Index
= 0; Index
< FilterDescription
->PinCount
; Index
++)
467 RtlMoveMemory(&Descriptor
->Factory
.KsPinDescriptor
[Index
], &SrcDescriptor
->KsPinDescriptor
, sizeof(KSPIN_DESCRIPTOR
));
469 Descriptor
->Factory
.KsPinDescriptor
[Index
].Interfaces
= PinInterfaces
;
470 Descriptor
->Factory
.KsPinDescriptor
[Index
].InterfacesCount
= sizeof(PinInterfaces
) / sizeof(KSPIN_INTERFACE
);
472 DPRINT("Index %u DataRangeCount %u\n", Index
, SrcDescriptor
->KsPinDescriptor
.DataRangesCount
);
474 Descriptor
->Factory
.Instances
[Index
].CurrentPinInstanceCount
= 0;
475 Descriptor
->Factory
.Instances
[Index
].MaxFilterInstanceCount
= SrcDescriptor
->MaxFilterInstanceCount
;
476 Descriptor
->Factory
.Instances
[Index
].MaxGlobalInstanceCount
= SrcDescriptor
->MaxGlobalInstanceCount
;
477 Descriptor
->Factory
.Instances
[Index
].MinFilterInstanceCount
= SrcDescriptor
->MinFilterInstanceCount
;
478 SrcDescriptor
= (PPCPIN_DESCRIPTOR
)((ULONG_PTR
)SrcDescriptor
+ FilterDescription
->PinSize
);
482 Descriptor
->DeviceDescriptor
= FilterDescription
;
483 *OutSubdeviceDescriptor
= Descriptor
;
484 return STATUS_SUCCESS
;
489 if (Descriptor
->Interfaces
)
490 FreeItem(Descriptor
->Interfaces
, TAG_PORTCLASS
);
492 if (Descriptor
->Factory
.KsPinDescriptor
)
493 FreeItem(Descriptor
->Factory
.KsPinDescriptor
, TAG_PORTCLASS
);
495 FreeItem(Descriptor
, TAG_PORTCLASS
);
502 PcValidateConnectRequest(
504 IN KSPIN_FACTORY
* Factory
,
505 OUT PKSPIN_CONNECT
* Connect
)
507 return KsValidateConnectRequest(Irp
, Factory
->PinDescriptorCount
, Factory
->KsPinDescriptor
, Connect
);