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
19 IN HANDLE FilterHandle
,
20 IN PKSPIN_CONNECT Connect
,
21 IN ACCESS_MASK DesiredAccess
,
22 OUT PHANDLE ConnectionHandle
)
24 UINT ConnectSize
= sizeof(KSPIN_CONNECT
);
26 PKSDATAFORMAT_WAVEFORMATEX Format
= (PKSDATAFORMAT_WAVEFORMATEX
)(Connect
+ 1);
27 if (Format
->DataFormat
.FormatSize
== sizeof(KSDATAFORMAT
) ||
28 Format
->DataFormat
.FormatSize
== sizeof(KSDATAFORMAT
) + sizeof(WAVEFORMATEX
))
30 ConnectSize
+= Format
->DataFormat
.FormatSize
;
33 return KspCreateObjectType(FilterHandle
,
47 KsValidateConnectRequest(
49 IN ULONG DescriptorsCount
,
50 IN KSPIN_DESCRIPTOR
* Descriptor
,
51 OUT PKSPIN_CONNECT
* Connect
)
53 PIO_STACK_LOCATION IoStack
;
54 PKSPIN_CONNECT ConnectDetails
;
55 LPWSTR PinName
= L
"{146F1A80-4791-11D0-A5D6-28DB04C10000}\\";
56 PKSDATAFORMAT DataFormat
;
59 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
60 if (!IoStack
->FileObject
->FileName
.Buffer
)
61 return STATUS_INVALID_PARAMETER
;
63 if (IoStack
->FileObject
->FileName
.Length
< wcslen(PinName
) + sizeof(KSPIN_CONNECT
) + sizeof(KSDATAFORMAT
))
64 return STATUS_INVALID_PARAMETER
;
66 Offset
= wcsstr(IoStack
->FileObject
->FileName
.Buffer
, PinName
);
69 /* request is not targeted for a pin */
70 return STATUS_INVALID_PARAMETER
;
73 ConnectDetails
= (PKSPIN_CONNECT
)(Offset
+ wcslen(PinName
));
75 if (ConnectDetails
->PinToHandle
!= NULL
)
78 return STATUS_NOT_IMPLEMENTED
;
81 if (ConnectDetails
->PinId
>= DescriptorsCount
)
82 return STATUS_INVALID_PARAMETER
;
85 if (!IsEqualGUIDAligned(&ConnectDetails
->Interface
.Set
, &KSINTERFACESETID_Standard
) &&
86 ConnectDetails
->Interface
.Id
!= KSINTERFACE_STANDARD_STREAMING
)
89 // validate provided interface set
93 if (!IsEqualGUIDAligned(&ConnectDetails
->Medium
.Set
, &KSMEDIUMSETID_Standard
) &&
94 ConnectDetails
->Medium
.Id
!= KSMEDIUM_TYPE_ANYINSTANCE
)
97 // validate provided medium set
103 /// implement format checking
105 DataFormat
= (PKSDATAFORMAT
) (ConnectDetails
+ 1);
106 *Connect
= ConnectDetails
;
108 return STATUS_SUCCESS
;
117 KsPinPropertyHandler(
119 IN PKSPROPERTY Property
,
121 IN ULONG DescriptorsCount
,
122 IN
const KSPIN_DESCRIPTOR
* Descriptor
)
125 KSMULTIPLE_ITEM
* Item
;
126 PIO_STACK_LOCATION IoStack
;
129 PKSDATARANGE_AUDIO
*WaveFormatOut
;
130 PKSDATAFORMAT_WAVEFORMATEX WaveFormatIn
;
132 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
133 Buffer
= Irp
->UserBuffer
;
137 case KSPROPERTY_PIN_CTYPES
:
138 (*(PULONG
)Buffer
) = DescriptorsCount
;
139 Irp
->IoStatus
.Information
= sizeof(ULONG
);
140 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
142 case KSPROPERTY_PIN_DATAFLOW
:
143 Pin
= (KSP_PIN
*)Property
;
144 if (Pin
->PinId
>= DescriptorsCount
)
146 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
147 Irp
->IoStatus
.Information
= 0;
150 Size
= sizeof(KSPIN_DATAFLOW
);
151 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
153 Irp
->IoStatus
.Information
= Size
;
154 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
158 *((KSPIN_DATAFLOW
*)Buffer
) = Descriptor
[Pin
->PinId
].DataFlow
;
159 Irp
->IoStatus
.Information
= sizeof(KSPIN_DATAFLOW
);
160 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
163 case KSPROPERTY_PIN_DATARANGES
:
164 Pin
= (KSP_PIN
*)Property
;
165 if (Pin
->PinId
>= DescriptorsCount
)
167 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
168 Irp
->IoStatus
.Information
= 0;
171 Size
= sizeof(KSMULTIPLE_ITEM
);
172 for (Index
= 0; Index
< Descriptor
[Pin
->PinId
].DataRangesCount
; Index
++)
174 Size
+= Descriptor
[Pin
->PinId
].DataRanges
[Index
]->FormatSize
;
177 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
179 Irp
->IoStatus
.Information
= Size
;
180 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
184 Item
= (KSMULTIPLE_ITEM
*)Buffer
;
186 Item
->Count
= Descriptor
[Pin
->PinId
].DataRangesCount
;
188 Data
= (PUCHAR
)(Item
+1);
189 for (Index
= 0; Index
< Descriptor
[Pin
->PinId
].DataRangesCount
; Index
++)
191 RtlMoveMemory(Data
, Descriptor
[Pin
->PinId
].DataRanges
[Index
], Descriptor
[Pin
->PinId
].DataRanges
[Index
]->FormatSize
);
192 Data
= ((PUCHAR
)Data
+ Descriptor
[Pin
->PinId
].DataRanges
[Index
]->FormatSize
);
195 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
196 Irp
->IoStatus
.Information
= Size
;
198 case KSPROPERTY_PIN_INTERFACES
:
199 Pin
= (KSP_PIN
*)Property
;
200 if (Pin
->PinId
>= DescriptorsCount
)
202 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
203 Irp
->IoStatus
.Information
= 0;
207 Size
= sizeof(KSMULTIPLE_ITEM
) + sizeof(KSPIN_INTERFACE
) * Descriptor
[Pin
->PinId
].InterfacesCount
;
209 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
211 Irp
->IoStatus
.Information
= Size
;
212 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
216 Item
= (KSMULTIPLE_ITEM
*)Buffer
;
218 Item
->Count
= Descriptor
[Pin
->PinId
].InterfacesCount
;
219 RtlMoveMemory((PVOID
)(Item
+ 1), Descriptor
[Pin
->PinId
].Interfaces
, Descriptor
[Pin
->PinId
].InterfacesCount
* sizeof(KSDATARANGE
));
221 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
222 Irp
->IoStatus
.Information
= Size
;
224 case KSPROPERTY_PIN_MEDIUMS
:
225 Pin
= (KSP_PIN
*)Property
;
226 if (Pin
->PinId
>= DescriptorsCount
)
228 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
229 Irp
->IoStatus
.Information
= 0;
233 Size
= sizeof(KSMULTIPLE_ITEM
) + sizeof(KSPIN_MEDIUM
) * Descriptor
[Pin
->PinId
].MediumsCount
;
234 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
236 Irp
->IoStatus
.Information
= Size
;
237 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
241 Item
= (KSMULTIPLE_ITEM
*)Buffer
;
243 Item
->Count
= Descriptor
[Pin
->PinId
].MediumsCount
;
244 RtlMoveMemory((PVOID
)(Item
+ 1), Descriptor
[Pin
->PinId
].Mediums
, Descriptor
[Pin
->PinId
].MediumsCount
* sizeof(KSDATARANGE
));
246 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
247 Irp
->IoStatus
.Information
= Size
;
250 case KSPROPERTY_PIN_COMMUNICATION
:
251 Pin
= (KSP_PIN
*)Property
;
252 if (Pin
->PinId
>= DescriptorsCount
)
254 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
255 Irp
->IoStatus
.Information
= 0;
259 Size
= sizeof(KSPIN_COMMUNICATION
);
260 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
262 Irp
->IoStatus
.Information
= Size
;
263 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
267 *((KSPIN_COMMUNICATION
*)Buffer
) = Descriptor
[Pin
->PinId
].Communication
;
268 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
269 Irp
->IoStatus
.Information
= Size
;
272 case KSPROPERTY_PIN_CATEGORY
:
273 Pin
= (KSP_PIN
*)Property
;
274 if (Pin
->PinId
>= DescriptorsCount
)
276 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
277 Irp
->IoStatus
.Information
= 0;
282 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
284 Irp
->IoStatus
.Information
= Size
;
285 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
289 RtlMoveMemory(Buffer
, &Descriptor
[Pin
->PinId
].Category
, sizeof(GUID
));
290 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
291 Irp
->IoStatus
.Information
= Size
;
294 case KSPROPERTY_PIN_NAME
:
295 Pin
= (KSP_PIN
*)Property
;
296 if (Pin
->PinId
>= DescriptorsCount
)
298 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
299 Irp
->IoStatus
.Information
= 0;
304 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
306 Irp
->IoStatus
.Information
= Size
;
307 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
312 RtlMoveMemory(Buffer
, &Descriptor
[Pin
->PinId
].Name
, sizeof(GUID
));
313 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
314 Irp
->IoStatus
.Information
= Size
;
316 case KSPROPERTY_PIN_PROPOSEDATAFORMAT
:
317 Pin
= (KSP_PIN
*)Property
;
318 if (Pin
->PinId
>= DescriptorsCount
)
320 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
321 Irp
->IoStatus
.Information
= 0;
324 Size
= sizeof(KSDATAFORMAT
);
325 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
327 Irp
->IoStatus
.Information
= Size
;
328 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
331 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
!= sizeof(KSDATAFORMAT_WAVEFORMATEX
))
334 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
335 Irp
->IoStatus
.Information
= 0;
336 return STATUS_NOT_IMPLEMENTED
;
339 WaveFormatIn
= (PKSDATAFORMAT_WAVEFORMATEX
)Buffer
;
340 if (!Descriptor
[Pin
->PinId
].DataRanges
|| !Descriptor
[Pin
->PinId
].DataRangesCount
)
342 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
343 Irp
->IoStatus
.Information
= 0;
344 return STATUS_UNSUCCESSFUL
;
346 WaveFormatOut
= (PKSDATARANGE_AUDIO
*)Descriptor
[Pin
->PinId
].DataRanges
;
347 for(Index
= 0; Index
< Descriptor
[Pin
->PinId
].DataRangesCount
; Index
++)
349 if (WaveFormatOut
[Index
]->DataRange
.FormatSize
!= sizeof(KSDATARANGE_AUDIO
))
355 if (WaveFormatOut
[Index
]->MinimumSampleFrequency
> WaveFormatIn
->WaveFormatEx
.nSamplesPerSec
||
356 WaveFormatOut
[Index
]->MaximumSampleFrequency
< WaveFormatIn
->WaveFormatEx
.nSamplesPerSec
||
357 WaveFormatOut
[Index
]->MinimumBitsPerSample
> WaveFormatIn
->WaveFormatEx
.wBitsPerSample
||
358 WaveFormatOut
[Index
]->MaximumBitsPerSample
< WaveFormatIn
->WaveFormatEx
.wBitsPerSample
||
359 WaveFormatOut
[Index
]->MaximumChannels
< WaveFormatIn
->WaveFormatEx
.nChannels
)
361 Irp
->IoStatus
.Status
= STATUS_NO_MATCH
;
362 Irp
->IoStatus
.Information
= 0;
363 return STATUS_NO_MATCH
;
367 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
368 Irp
->IoStatus
.Information
= 0;
369 return STATUS_SUCCESS
;
372 Irp
->IoStatus
.Status
= STATUS_NO_MATCH
;
373 Irp
->IoStatus
.Information
= 0;
374 return STATUS_NO_MATCH
;
376 DPRINT1("Unhandled property request %x\n", Property
->Id
);
377 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
378 Irp
->IoStatus
.Information
= 0;
381 return Irp
->IoStatus
.Status
;
390 KsPinDataIntersection(
394 IN ULONG DescriptorsCount
,
395 IN
const KSPIN_DESCRIPTOR
* Descriptor
,
396 IN PFNKSINTERSECTHANDLER IntersectHandler
)
398 KSMULTIPLE_ITEM
* Item
;
399 KSDATARANGE
* DataRange
;
400 PIO_STACK_LOCATION IoStack
;
405 /* get current irp stack location */
406 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
408 /* calculate minimum data size */
409 Size
= sizeof(KSP_PIN
) + sizeof(KSMULTIPLE_ITEM
) + sizeof(KSDATARANGE
);
410 if (IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
< Size
)
412 /* buffer too small */
413 Irp
->IoStatus
.Information
= Size
;
414 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
415 return STATUS_BUFFER_TOO_SMALL
;
417 /* is pin id out of bounds */
418 if (Pin
->PinId
>= DescriptorsCount
)
421 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
422 Irp
->IoStatus
.Information
= 0;
423 return STATUS_INVALID_PARAMETER
;
427 Item
= (KSMULTIPLE_ITEM
*)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
428 /* get first data range */
429 DataRange
= (KSDATARANGE
*)(Item
+ 1);
430 /* iterate through all data ranges */
431 for(Index
= 0; Index
< Item
->Count
; Index
++, DataRange
++)
433 /* call intersect handler */
434 Status
= IntersectHandler(Irp
, Pin
, DataRange
, Data
);
435 if (NT_SUCCESS(Status
))
437 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< DataRange
->FormatSize
)
439 /* buffer is too small */
440 Irp
->IoStatus
.Information
= DataRange
->FormatSize
;
441 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
442 return STATUS_BUFFER_TOO_SMALL
;
444 RtlMoveMemory(Irp
->UserBuffer
, DataRange
, sizeof(KSDATARANGE
));
445 Irp
->IoStatus
.Information
= sizeof(KSDATARANGE
);
446 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
447 return STATUS_SUCCESS
;
452 Irp
->IoStatus
.Information
= 0;
453 Irp
->IoStatus
.Status
= STATUS_NO_MATCH
;
454 return STATUS_NO_MATCH
;
464 KsHandleSizedListQuery(
466 IN ULONG DataItemsCount
,
467 IN ULONG DataItemSize
,
468 IN
const VOID
* DataItems
)
471 PIO_STACK_LOCATION IoStack
;
472 PKSMULTIPLE_ITEM Item
;
474 /* get current irp stack location */
475 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
477 Size
= DataItemSize
* DataItemsCount
+ sizeof(KSMULTIPLE_ITEM
);
480 if (IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
< Size
)
482 /* buffer too small */
483 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
484 Irp
->IoStatus
.Information
= Size
;
485 return STATUS_BUFFER_TOO_SMALL
;
488 /* get multiple item */
489 Item
= (PKSMULTIPLE_ITEM
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
491 Item
->Count
= DataItemsCount
;
492 Item
->Size
= DataItemSize
;
494 RtlMoveMemory((PVOID
)(Item
+ 1), DataItems
, DataItemSize
* DataItemsCount
);
496 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
497 Irp
->IoStatus
.Information
= Size
;
499 return STATUS_SUCCESS
;