2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/connectivity.c
5 * PURPOSE: KS Pin functions
6 * PROGRAMMER: Johannes Anderwald
12 KSPIN_INTERFACE StandardPinInterface
=
14 {STATIC_KSINTERFACESETID_Standard
},
15 KSINTERFACE_STANDARD_STREAMING
,
19 KSPIN_MEDIUM StandardPinMedium
=
21 {STATIC_KSMEDIUMSETID_Standard
},
22 KSMEDIUM_TYPE_ANYINSTANCE
,
34 IN HANDLE FilterHandle
,
35 IN PKSPIN_CONNECT Connect
,
36 IN ACCESS_MASK DesiredAccess
,
37 OUT PHANDLE ConnectionHandle
)
39 UINT ConnectSize
= sizeof(KSPIN_CONNECT
);
41 PKSDATAFORMAT_WAVEFORMATEX Format
= (PKSDATAFORMAT_WAVEFORMATEX
)(Connect
+ 1);
42 if (Format
->DataFormat
.FormatSize
== sizeof(KSDATAFORMAT
) ||
43 Format
->DataFormat
.FormatSize
== sizeof(KSDATAFORMAT
) + sizeof(WAVEFORMATEX
))
45 ConnectSize
+= Format
->DataFormat
.FormatSize
;
48 return KspCreateObjectType(FilterHandle
,
62 KsValidateConnectRequest(
64 IN ULONG DescriptorsCount
,
65 IN KSPIN_DESCRIPTOR
* Descriptor
,
66 OUT PKSPIN_CONNECT
* Connect
)
68 PKSPIN_CONNECT ConnectDetails
;
69 PKSPIN_INTERFACE Interface
;
77 /* did the caller miss the connect parameter */
79 return STATUS_INVALID_PARAMETER
;
81 /* set create param size */
82 Size
= sizeof(KSPIN_CONNECT
);
84 /* fetch create parameters */
85 Status
= KspCopyCreateRequest(Irp
,
88 (PVOID
*)&ConnectDetails
);
90 /* check for success */
91 if (!NT_SUCCESS(Status
))
94 /* is pin id out of bounds */
95 if (ConnectDetails
->PinId
>= DescriptorsCount
)
96 return STATUS_INVALID_PARAMETER
;
98 /* does the pin have interface details filled in */
99 if (Descriptor
[ConnectDetails
->PinId
].InterfacesCount
&& Descriptor
[ConnectDetails
->PinId
].Interfaces
)
101 /* use provided pin interface count */
102 Count
= Descriptor
[ConnectDetails
->PinId
].InterfacesCount
;
103 Interface
= (PKSPIN_INTERFACE
)Descriptor
[ConnectDetails
->PinId
].Interfaces
;
107 /* use standard pin interface */
109 Interface
= &StandardPinInterface
;
112 /* now check the interface */
117 if (IsEqualGUIDAligned(&Interface
[Index
].Set
, &ConnectDetails
->Interface
.Set
) &&
118 Interface
[Index
].Id
== ConnectDetails
->Interface
.Id
)
120 /* found a matching interface */
124 /* iterate to next interface */
126 }while(Index
< Count
);
130 /* pin doesnt support this interface */
131 return STATUS_NO_MATCH
;
134 /* does the pin have medium details filled in */
135 if (Descriptor
[ConnectDetails
->PinId
].MediumsCount
&& Descriptor
[ConnectDetails
->PinId
].Mediums
)
137 /* use provided pin interface count */
138 Count
= Descriptor
[ConnectDetails
->PinId
].MediumsCount
;
139 Medium
= (PKSPIN_MEDIUM
)Descriptor
[ConnectDetails
->PinId
].Mediums
;
143 /* use standard pin interface */
145 Medium
= &StandardPinMedium
;
148 /* now check the interface */
153 if (IsEqualGUIDAligned(&Medium
[Index
].Set
, &ConnectDetails
->Medium
.Set
) &&
154 Medium
[Index
].Id
== ConnectDetails
->Medium
.Id
)
156 /* found a matching interface */
160 /* iterate to next medium */
162 }while(Index
< Count
);
166 /* pin doesnt support this medium */
167 return STATUS_NO_MATCH
;
171 /// implement format checking
173 *Connect
= ConnectDetails
;
174 return STATUS_SUCCESS
;
183 KsPinPropertyHandler(
185 IN PKSPROPERTY Property
,
187 IN ULONG DescriptorsCount
,
188 IN
const KSPIN_DESCRIPTOR
* Descriptor
)
191 KSMULTIPLE_ITEM
* Item
;
192 PIO_STACK_LOCATION IoStack
;
195 PKSDATARANGE_AUDIO
*WaveFormatOut
;
196 PKSDATAFORMAT_WAVEFORMATEX WaveFormatIn
;
198 static WCHAR Speaker
[] = {L
"PC-Speaker"};
200 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
201 Buffer
= Irp
->UserBuffer
;
203 DPRINT("KsPinPropertyHandler Irp %p Property %p Data %p DescriptorsCount %u Descriptor %p OutputLength %u Id %x\n", Irp
, Property
, Data
, DescriptorsCount
, Descriptor
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, Property
->Id
);
207 case KSPROPERTY_PIN_CTYPES
:
208 (*(PULONG
)Buffer
) = DescriptorsCount
;
209 Irp
->IoStatus
.Information
= sizeof(ULONG
);
210 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
212 case KSPROPERTY_PIN_DATAFLOW
:
213 Pin
= (KSP_PIN
*)Property
;
214 if (Pin
->PinId
>= DescriptorsCount
)
216 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
217 Irp
->IoStatus
.Information
= 0;
220 Size
= sizeof(KSPIN_DATAFLOW
);
221 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
223 Irp
->IoStatus
.Information
= Size
;
224 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
228 *((KSPIN_DATAFLOW
*)Buffer
) = Descriptor
[Pin
->PinId
].DataFlow
;
229 Irp
->IoStatus
.Information
= sizeof(KSPIN_DATAFLOW
);
230 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
233 case KSPROPERTY_PIN_DATARANGES
:
234 Pin
= (KSP_PIN
*)Property
;
235 if (Pin
->PinId
>= DescriptorsCount
)
237 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
238 Irp
->IoStatus
.Information
= 0;
241 Size
= sizeof(KSMULTIPLE_ITEM
);
242 for (Index
= 0; Index
< Descriptor
[Pin
->PinId
].DataRangesCount
; Index
++)
244 Size
+= Descriptor
[Pin
->PinId
].DataRanges
[Index
]->FormatSize
;
247 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
249 Irp
->IoStatus
.Information
= Size
;
250 Irp
->IoStatus
.Status
= STATUS_MORE_ENTRIES
;
254 Item
= (KSMULTIPLE_ITEM
*)Buffer
;
256 Item
->Count
= Descriptor
[Pin
->PinId
].DataRangesCount
;
258 Data
= (PUCHAR
)(Item
+1);
259 for (Index
= 0; Index
< Descriptor
[Pin
->PinId
].DataRangesCount
; Index
++)
261 RtlMoveMemory(Data
, Descriptor
[Pin
->PinId
].DataRanges
[Index
], Descriptor
[Pin
->PinId
].DataRanges
[Index
]->FormatSize
);
262 Data
= ((PUCHAR
)Data
+ Descriptor
[Pin
->PinId
].DataRanges
[Index
]->FormatSize
);
265 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
266 Irp
->IoStatus
.Information
= Size
;
268 case KSPROPERTY_PIN_INTERFACES
:
269 Pin
= (KSP_PIN
*)Property
;
270 if (Pin
->PinId
>= DescriptorsCount
)
272 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
273 Irp
->IoStatus
.Information
= 0;
278 Size
= sizeof(KSMULTIPLE_ITEM
);
279 Size
+= max(1, Descriptor
[Pin
->PinId
].InterfacesCount
) * sizeof(KSPIN_INTERFACE
);
281 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
283 Irp
->IoStatus
.Information
= Size
;
284 Irp
->IoStatus
.Status
= STATUS_MORE_ENTRIES
;
288 Item
= (KSMULTIPLE_ITEM
*)Buffer
;
291 if (Descriptor
[Pin
->PinId
].InterfacesCount
)
293 Item
->Count
= Descriptor
[Pin
->PinId
].InterfacesCount
;
294 RtlMoveMemory((PVOID
)(Item
+ 1), Descriptor
[Pin
->PinId
].Interfaces
, Descriptor
[Pin
->PinId
].InterfacesCount
* sizeof(KSPIN_INTERFACE
));
299 RtlMoveMemory((PVOID
)(Item
+ 1), &StandardPinInterface
, sizeof(KSPIN_INTERFACE
));
302 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
303 Irp
->IoStatus
.Information
= Size
;
305 case KSPROPERTY_PIN_MEDIUMS
:
306 Pin
= (KSP_PIN
*)Property
;
307 if (Pin
->PinId
>= DescriptorsCount
)
309 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
310 Irp
->IoStatus
.Information
= 0;
315 Size
= sizeof(KSMULTIPLE_ITEM
);
316 Size
+= max(1, Descriptor
[Pin
->PinId
].MediumsCount
) * sizeof(KSPIN_MEDIUM
);
318 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
320 Irp
->IoStatus
.Information
= Size
;
321 Irp
->IoStatus
.Status
= STATUS_MORE_ENTRIES
;
325 Item
= (KSMULTIPLE_ITEM
*)Buffer
;
328 if (Descriptor
[Pin
->PinId
].MediumsCount
)
330 Item
->Count
= Descriptor
[Pin
->PinId
].MediumsCount
;
331 RtlMoveMemory((PVOID
)(Item
+ 1), Descriptor
[Pin
->PinId
].Mediums
, Descriptor
[Pin
->PinId
].MediumsCount
* sizeof(KSPIN_MEDIUM
));
336 RtlMoveMemory((PVOID
)(Item
+ 1), &StandardPinMedium
, sizeof(KSPIN_MEDIUM
));
339 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
340 Irp
->IoStatus
.Information
= Size
;
343 case KSPROPERTY_PIN_COMMUNICATION
:
344 Pin
= (KSP_PIN
*)Property
;
345 if (Pin
->PinId
>= DescriptorsCount
)
347 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
348 Irp
->IoStatus
.Information
= 0;
352 Size
= sizeof(KSPIN_COMMUNICATION
);
353 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
355 Irp
->IoStatus
.Information
= Size
;
356 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
360 *((KSPIN_COMMUNICATION
*)Buffer
) = Descriptor
[Pin
->PinId
].Communication
;
361 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
362 Irp
->IoStatus
.Information
= Size
;
365 case KSPROPERTY_PIN_CATEGORY
:
366 Pin
= (KSP_PIN
*)Property
;
367 if (Pin
->PinId
>= DescriptorsCount
)
369 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
370 Irp
->IoStatus
.Information
= 0;
375 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
377 Irp
->IoStatus
.Information
= Size
;
378 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
382 RtlMoveMemory(Buffer
, &Descriptor
[Pin
->PinId
].Category
, sizeof(GUID
));
383 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
384 Irp
->IoStatus
.Information
= Size
;
387 case KSPROPERTY_PIN_NAME
:
388 Pin
= (KSP_PIN
*)Property
;
389 if (Pin
->PinId
>= DescriptorsCount
)
391 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
392 Irp
->IoStatus
.Information
= 0;
397 Size
= sizeof(Speaker
);
399 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
401 Irp
->IoStatus
.Information
= Size
;
402 Irp
->IoStatus
.Status
= STATUS_MORE_ENTRIES
;
406 RtlMoveMemory(GuidBuffer
, Speaker
, sizeof(Speaker
));
408 //RtlMoveMemory(Buffer, &Descriptor[Pin->PinId].Name, sizeof(GUID));
409 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
410 Irp
->IoStatus
.Information
= Size
;
412 case KSPROPERTY_PIN_PROPOSEDATAFORMAT
:
413 Pin
= (KSP_PIN
*)Property
;
414 if (Pin
->PinId
>= DescriptorsCount
)
416 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
417 Irp
->IoStatus
.Information
= 0;
420 Size
= sizeof(KSDATAFORMAT
);
421 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
423 Irp
->IoStatus
.Information
= Size
;
424 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
427 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
!= sizeof(KSDATAFORMAT_WAVEFORMATEX
))
430 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
431 Irp
->IoStatus
.Information
= 0;
432 return STATUS_NOT_IMPLEMENTED
;
435 WaveFormatIn
= (PKSDATAFORMAT_WAVEFORMATEX
)Buffer
;
436 if (!Descriptor
[Pin
->PinId
].DataRanges
|| !Descriptor
[Pin
->PinId
].DataRangesCount
)
438 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
439 Irp
->IoStatus
.Information
= 0;
440 return STATUS_UNSUCCESSFUL
;
442 WaveFormatOut
= (PKSDATARANGE_AUDIO
*)Descriptor
[Pin
->PinId
].DataRanges
;
443 for(Index
= 0; Index
< Descriptor
[Pin
->PinId
].DataRangesCount
; Index
++)
445 if (WaveFormatOut
[Index
]->DataRange
.FormatSize
!= sizeof(KSDATARANGE_AUDIO
))
451 if (WaveFormatOut
[Index
]->MinimumSampleFrequency
> WaveFormatIn
->WaveFormatEx
.nSamplesPerSec
||
452 WaveFormatOut
[Index
]->MaximumSampleFrequency
< WaveFormatIn
->WaveFormatEx
.nSamplesPerSec
||
453 WaveFormatOut
[Index
]->MinimumBitsPerSample
> WaveFormatIn
->WaveFormatEx
.wBitsPerSample
||
454 WaveFormatOut
[Index
]->MaximumBitsPerSample
< WaveFormatIn
->WaveFormatEx
.wBitsPerSample
||
455 WaveFormatOut
[Index
]->MaximumChannels
< WaveFormatIn
->WaveFormatEx
.nChannels
)
457 Irp
->IoStatus
.Status
= STATUS_NO_MATCH
;
458 Irp
->IoStatus
.Information
= 0;
459 return STATUS_NO_MATCH
;
463 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
464 Irp
->IoStatus
.Information
= 0;
465 return STATUS_SUCCESS
;
468 Irp
->IoStatus
.Status
= STATUS_NO_MATCH
;
469 Irp
->IoStatus
.Information
= 0;
470 return STATUS_NO_MATCH
;
472 DPRINT1("Unhandled property request %x\n", Property
->Id
);
473 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
474 Irp
->IoStatus
.Information
= 0;
477 return Irp
->IoStatus
.Status
;
486 KsPinDataIntersection(
490 IN ULONG DescriptorsCount
,
491 IN
const KSPIN_DESCRIPTOR
* Descriptor
,
492 IN PFNKSINTERSECTHANDLER IntersectHandler
)
494 KSMULTIPLE_ITEM
* Item
;
495 KSDATARANGE
* DataRange
;
496 PIO_STACK_LOCATION IoStack
;
501 /* get current irp stack location */
502 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
504 /* calculate minimum data size */
505 Size
= sizeof(KSP_PIN
) + sizeof(KSMULTIPLE_ITEM
) + sizeof(KSDATARANGE
);
506 if (IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
< Size
)
508 /* buffer too small */
509 Irp
->IoStatus
.Information
= Size
;
510 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
511 return STATUS_BUFFER_TOO_SMALL
;
513 /* is pin id out of bounds */
514 if (Pin
->PinId
>= DescriptorsCount
)
517 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
518 Irp
->IoStatus
.Information
= 0;
519 return STATUS_INVALID_PARAMETER
;
523 Item
= (KSMULTIPLE_ITEM
*)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
524 /* get first data range */
525 DataRange
= (KSDATARANGE
*)(Item
+ 1);
526 /* iterate through all data ranges */
527 for(Index
= 0; Index
< Item
->Count
; Index
++, DataRange
++)
529 /* call intersect handler */
530 Status
= IntersectHandler(Irp
, Pin
, DataRange
, Data
);
531 if (NT_SUCCESS(Status
))
533 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< DataRange
->FormatSize
)
535 /* buffer is too small */
536 Irp
->IoStatus
.Information
= DataRange
->FormatSize
;
537 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
538 return STATUS_BUFFER_TOO_SMALL
;
540 RtlMoveMemory(Irp
->UserBuffer
, DataRange
, sizeof(KSDATARANGE
));
541 Irp
->IoStatus
.Information
= sizeof(KSDATARANGE
);
542 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
543 return STATUS_SUCCESS
;
548 Irp
->IoStatus
.Information
= 0;
549 Irp
->IoStatus
.Status
= STATUS_NO_MATCH
;
550 return STATUS_NO_MATCH
;
560 KsHandleSizedListQuery(
562 IN ULONG DataItemsCount
,
563 IN ULONG DataItemSize
,
564 IN
const VOID
* DataItems
)
567 PIO_STACK_LOCATION IoStack
;
568 PKSMULTIPLE_ITEM Item
;
570 /* get current irp stack location */
571 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
573 Size
= DataItemSize
* DataItemsCount
+ sizeof(KSMULTIPLE_ITEM
);
576 if (IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
< Size
)
578 /* buffer too small */
579 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
580 Irp
->IoStatus
.Information
= Size
;
581 return STATUS_BUFFER_TOO_SMALL
;
584 /* get multiple item */
585 Item
= (PKSMULTIPLE_ITEM
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
587 Item
->Count
= DataItemsCount
;
588 Item
->Size
= DataItemSize
;
590 RtlMoveMemory((PVOID
)(Item
+ 1), DataItems
, DataItemSize
* DataItemsCount
);
592 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
593 Irp
->IoStatus
.Information
= Size
;
595 return STATUS_SUCCESS
;