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
14 KSPIN_INTERFACE StandardPinInterface
=
16 {STATIC_KSINTERFACESETID_Standard
},
17 KSINTERFACE_STANDARD_STREAMING
,
21 KSPIN_MEDIUM StandardPinMedium
=
23 {STATIC_KSMEDIUMSETID_Standard
},
24 KSMEDIUM_TYPE_ANYINSTANCE
,
28 const GUID KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT
= {0xf4aeb342, 0x0329, 0x4fdd, {0xa8, 0xfd, 0x4a, 0xff, 0x49, 0x26, 0xc9, 0x78}};
37 IN HANDLE FilterHandle
,
38 IN PKSPIN_CONNECT Connect
,
39 IN ACCESS_MASK DesiredAccess
,
40 OUT PHANDLE ConnectionHandle
)
42 UINT ConnectSize
= sizeof(KSPIN_CONNECT
);
44 PKSDATAFORMAT_WAVEFORMATEX Format
= (PKSDATAFORMAT_WAVEFORMATEX
)(Connect
+ 1);
45 if (Format
->DataFormat
.FormatSize
== sizeof(KSDATAFORMAT
) ||
46 Format
->DataFormat
.FormatSize
== sizeof(KSDATAFORMAT
) + sizeof(WAVEFORMATEX
))
48 ConnectSize
+= Format
->DataFormat
.FormatSize
;
51 return KspCreateObjectType(FilterHandle
,
60 KspValidateConnectRequest(
62 IN ULONG DescriptorsCount
,
64 IN ULONG DescriptorSize
,
65 OUT PKSPIN_CONNECT
* Connect
)
67 PKSPIN_CONNECT ConnectDetails
;
68 PKSPIN_INTERFACE Interface
;
75 PKSPIN_DESCRIPTOR Descriptor
;
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 if (DescriptorSize
== sizeof(KSPIN_DESCRIPTOR
))
100 /* standard pin descriptor */
101 Descriptor
= (PKSPIN_DESCRIPTOR
)((ULONG_PTR
)Descriptors
+ sizeof(KSPIN_DESCRIPTOR
) * ConnectDetails
->PinId
);
105 /* extended / variable pin descriptor */
106 Descriptor
= &((PKSPIN_DESCRIPTOR_EX
)((ULONG_PTR
)Descriptors
+ DescriptorSize
* ConnectDetails
->PinId
))->PinDescriptor
;
110 /* does the pin have interface details filled in */
111 if (Descriptor
->InterfacesCount
&& Descriptor
->Interfaces
)
113 /* use provided pin interface count */
114 Count
= Descriptor
->InterfacesCount
;
115 Interface
= (PKSPIN_INTERFACE
)Descriptor
->Interfaces
;
119 /* use standard pin interface */
121 Interface
= &StandardPinInterface
;
124 /* now check the interface */
129 UNICODE_STRING GuidString
, GuidString2
;
130 RtlStringFromGUID(&Interface
[Index
].Set
, &GuidString
);
131 RtlStringFromGUID(&ConnectDetails
->Interface
.Set
, &GuidString2
);
133 DPRINT("Driver Interface %S Id %u\n", GuidString
.Buffer
, Interface
[Index
].Id
);
134 DPRINT("Connect Interface %S Id %u\n", GuidString2
.Buffer
, ConnectDetails
->Interface
.Id
);
136 if (IsEqualGUIDAligned(&Interface
[Index
].Set
, &ConnectDetails
->Interface
.Set
) &&
137 Interface
[Index
].Id
== ConnectDetails
->Interface
.Id
)
139 /* found a matching interface */
143 /* iterate to next interface */
145 }while(Index
< Count
);
149 /* pin doesnt support this interface */
150 return STATUS_NO_MATCH
;
153 /* does the pin have medium details filled in */
154 if (Descriptor
->MediumsCount
&& Descriptor
->Mediums
)
156 /* use provided pin interface count */
157 Count
= Descriptor
->MediumsCount
;
158 Medium
= (PKSPIN_MEDIUM
)Descriptor
->Mediums
;
162 /* use standard pin interface */
164 Medium
= &StandardPinMedium
;
167 /* now check the interface */
172 UNICODE_STRING GuidString
, GuidString2
;
173 RtlStringFromGUID(&Medium
[Index
].Set
, &GuidString
);
174 RtlStringFromGUID(&ConnectDetails
->Medium
.Set
, &GuidString2
);
176 DPRINT("Driver Medium %S Id %u\n", GuidString
.Buffer
, Medium
[Index
].Id
);
177 DPRINT("Connect Medium %S Id %u\n", GuidString2
.Buffer
, ConnectDetails
->Medium
.Id
);
180 if (IsEqualGUIDAligned(&Medium
[Index
].Set
, &ConnectDetails
->Medium
.Set
) &&
181 Medium
[Index
].Id
== ConnectDetails
->Medium
.Id
)
183 /* found a matching interface */
190 /* iterate to next medium */
192 }while(Index
< Count
);
196 /* pin doesnt support this medium */
197 return STATUS_NO_MATCH
;
201 /// implement format checking
203 *Connect
= ConnectDetails
;
204 return STATUS_SUCCESS
;
213 KsValidateConnectRequest(
215 IN ULONG DescriptorsCount
,
216 IN KSPIN_DESCRIPTOR
* Descriptor
,
217 OUT PKSPIN_CONNECT
* Connect
)
219 return KspValidateConnectRequest(Irp
, DescriptorsCount
, Descriptor
, sizeof(KSPIN_DESCRIPTOR
), Connect
);
223 KspReadMediaCategory(
225 PKEY_VALUE_PARTIAL_INFORMATION
*OutInformation
)
227 UNICODE_STRING MediaPath
= RTL_CONSTANT_STRING(L
"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control\\MediaCategories\\");
228 UNICODE_STRING Name
= RTL_CONSTANT_STRING(L
"Name");
229 UNICODE_STRING GuidString
, Path
;
231 OBJECT_ATTRIBUTES ObjectAttributes
;
234 PKEY_VALUE_PARTIAL_INFORMATION KeyInfo
;
236 /* convert the guid to string */
237 Status
= RtlStringFromGUID(Category
, &GuidString
);
238 if (!NT_SUCCESS(Status
))
241 /* allocate buffer for the registry key */
243 Path
.MaximumLength
= MediaPath
.MaximumLength
+ GuidString
.MaximumLength
;
244 Path
.Buffer
= AllocateItem(NonPagedPool
, Path
.MaximumLength
);
247 /* not enough memory */
248 RtlFreeUnicodeString(&GuidString
);
249 return STATUS_INSUFFICIENT_RESOURCES
;
252 RtlAppendUnicodeStringToString(&Path
, &MediaPath
);
253 RtlAppendUnicodeStringToString(&Path
, &GuidString
);
255 /* free guid string */
256 RtlFreeUnicodeString(&GuidString
);
258 /* initialize object attributes */
259 InitializeObjectAttributes(&ObjectAttributes
, &Path
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
262 Status
= ZwOpenKey(&hKey
, GENERIC_READ
, &ObjectAttributes
);
264 DPRINT("ZwOpenKey() status 0x%08lx %wZ\n", Status
, &Path
);
266 /* free path buffer */
267 FreeItem(Path
.Buffer
);
269 /* check for success */
270 if (!NT_SUCCESS(Status
))
272 DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status
);
276 /* query the name size */
277 Status
= ZwQueryValueKey(hKey
, &Name
, KeyValuePartialInformation
, NULL
, 0, &Size
);
278 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_TOO_SMALL
)
280 /* failed to query for name key */
285 /* allocate buffer to read key info */
286 KeyInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
) AllocateItem(NonPagedPool
, Size
);
289 /* not enough memory */
291 return STATUS_INSUFFICIENT_RESOURCES
;
294 /* now read the info */
295 Status
= ZwQueryValueKey(hKey
, &Name
, KeyValuePartialInformation
, (PVOID
)KeyInfo
, Size
, &Size
);
300 if (!NT_SUCCESS(Status
))
302 /* failed to read key */
307 /* store key information */
308 *OutInformation
= KeyInfo
;
315 KspPinPropertyHandler(
317 IN PKSPROPERTY Property
,
319 IN ULONG DescriptorsCount
,
320 IN
const KSPIN_DESCRIPTOR
* Descriptors
,
321 IN ULONG DescriptorSize
)
324 KSMULTIPLE_ITEM
* Item
;
325 PIO_STACK_LOCATION IoStack
;
328 PKSDATARANGE_AUDIO
*WaveFormatOut
;
329 PKSDATAFORMAT_WAVEFORMATEX WaveFormatIn
;
330 PKEY_VALUE_PARTIAL_INFORMATION KeyInfo
;
331 const KSPIN_DESCRIPTOR
*Descriptor
;
332 NTSTATUS Status
= STATUS_NOT_SUPPORTED
;
334 const PKSDATARANGE
* DataRanges
;
337 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
340 //DPRINT("KsPinPropertyHandler Irp %p Property %p Data %p DescriptorsCount %u Descriptor %p OutputLength %u Id %u\n", Irp, Property, Data, DescriptorsCount, Descriptor, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Property->Id);
342 /* convert to PKSP_PIN */
343 Pin
= (KSP_PIN
*)Property
;
345 if (Property
->Id
!= KSPROPERTY_PIN_CTYPES
)
347 if (Pin
->PinId
>= DescriptorsCount
)
349 /* invalid parameter */
350 return STATUS_INVALID_PARAMETER
;
354 if (DescriptorSize
== sizeof(KSPIN_DESCRIPTOR
))
356 /* it is simple pin descriptor */
357 Descriptor
= &Descriptors
[Pin
->PinId
];
361 /* get offset to pin descriptor */
362 Descriptor
= &(((PKSPIN_DESCRIPTOR_EX
)((ULONG_PTR
)Descriptors
+ Pin
->PinId
* DescriptorSize
))->PinDescriptor
);
367 case KSPROPERTY_PIN_CTYPES
:
368 (*(PULONG
)Buffer
) = DescriptorsCount
;
369 Irp
->IoStatus
.Information
= sizeof(ULONG
);
370 Status
= STATUS_SUCCESS
;
372 case KSPROPERTY_PIN_DATAFLOW
:
374 Size
= sizeof(KSPIN_DATAFLOW
);
375 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
377 Irp
->IoStatus
.Information
= Size
;
378 Status
= STATUS_BUFFER_TOO_SMALL
;
382 *((KSPIN_DATAFLOW
*)Buffer
) = Descriptor
->DataFlow
;
383 Irp
->IoStatus
.Information
= sizeof(KSPIN_DATAFLOW
);
384 Status
= STATUS_SUCCESS
;
387 case KSPROPERTY_PIN_DATARANGES
:
388 case KSPROPERTY_PIN_CONSTRAINEDDATARANGES
:
390 Size
= sizeof(KSMULTIPLE_ITEM
);
391 DPRINT("Id %lu PinId %lu DataRangesCount %lu ConstrainedDataRangesCount %lu\n", Property
->Id
, Pin
->PinId
, Descriptor
->DataRangesCount
, Descriptor
->ConstrainedDataRangesCount
);
393 if (Property
->Id
== KSPROPERTY_PIN_DATARANGES
|| Descriptor
->ConstrainedDataRangesCount
== 0)
395 DataRanges
= Descriptor
->DataRanges
;
396 Count
= Descriptor
->DataRangesCount
;
400 DataRanges
= Descriptor
->ConstrainedDataRanges
;
401 Count
= Descriptor
->ConstrainedDataRangesCount
;
404 for (Index
= 0; Index
< Count
; Index
++)
406 Size
+= ((DataRanges
[Index
]->FormatSize
+ 0x7) & ~0x7);
409 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== 0)
411 /* buffer too small */
412 Irp
->IoStatus
.Information
= Size
;
413 Status
= STATUS_BUFFER_OVERFLOW
;
417 Item
= (KSMULTIPLE_ITEM
*)Buffer
;
419 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== sizeof(ULONG
))
421 /* store the result size */
423 Irp
->IoStatus
.Information
= sizeof(ULONG
);
424 Status
= STATUS_SUCCESS
;
428 /* store descriptor size */
432 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== sizeof(KSMULTIPLE_ITEM
))
434 Irp
->IoStatus
.Information
= sizeof(KSMULTIPLE_ITEM
);
435 Status
= STATUS_SUCCESS
;
439 /* now copy all dataranges */
440 Data
= (PUCHAR
)(Item
+1);
442 /* alignment assert */
443 ASSERT(((ULONG_PTR
)Data
& 0x7) == 0);
445 for (Index
= 0; Index
< Count
; Index
++)
447 UNICODE_STRING GuidString
;
448 /* convert the guid to string */
449 RtlStringFromGUID(&DataRanges
[Index
]->MajorFormat
, &GuidString
);
450 DPRINT("Index %lu MajorFormat %S\n", Index
, GuidString
.Buffer
);
451 RtlStringFromGUID(&DataRanges
[Index
]->SubFormat
, &GuidString
);
452 DPRINT("Index %lu SubFormat %S\n", Index
, GuidString
.Buffer
);
453 RtlStringFromGUID(&DataRanges
[Index
]->Specifier
, &GuidString
);
454 DPRINT("Index %lu Specifier %S\n", Index
, GuidString
.Buffer
);
455 RtlStringFromGUID(&DataRanges
[Index
]->Specifier
, &GuidString
);
456 DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved %lu KSDATAFORMAT %lu\n", Index
,
457 DataRanges
[Index
]->FormatSize
, DataRanges
[Index
]->Flags
, DataRanges
[Index
]->SampleSize
, DataRanges
[Index
]->Reserved
, sizeof(KSDATAFORMAT
));
459 RtlMoveMemory(Data
, DataRanges
[Index
], DataRanges
[Index
]->FormatSize
);
460 Data
= ((PUCHAR
)Data
+ DataRanges
[Index
]->FormatSize
);
461 /* alignment assert */
462 ASSERT(((ULONG_PTR
)Data
& 0x7) == 0);
463 Data
= (PVOID
)(((ULONG_PTR
)Data
+ 0x7) & ~0x7);
466 Status
= STATUS_SUCCESS
;
467 Irp
->IoStatus
.Information
= Size
;
469 case KSPROPERTY_PIN_INTERFACES
:
471 if (Descriptor
->Interfaces
)
473 /* use mediums provided by driver */
474 return KsHandleSizedListQuery(Irp
, Descriptor
->InterfacesCount
, sizeof(KSPIN_MEDIUM
), Descriptor
->Interfaces
);
478 /* use standard medium */
479 return KsHandleSizedListQuery(Irp
, 1, sizeof(KSPIN_INTERFACE
), &StandardPinInterface
);
483 case KSPROPERTY_PIN_MEDIUMS
:
485 if (Descriptor
->MediumsCount
)
487 /* use mediums provided by driver */
488 return KsHandleSizedListQuery(Irp
, Descriptor
->MediumsCount
, sizeof(KSPIN_MEDIUM
), Descriptor
->Mediums
);
492 /* use standard medium */
493 return KsHandleSizedListQuery(Irp
, 1, sizeof(KSPIN_MEDIUM
), &StandardPinMedium
);
497 case KSPROPERTY_PIN_COMMUNICATION
:
499 Size
= sizeof(KSPIN_COMMUNICATION
);
500 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
502 Irp
->IoStatus
.Information
= Size
;
503 Status
= STATUS_BUFFER_TOO_SMALL
;
507 *((KSPIN_COMMUNICATION
*)Buffer
) = Descriptor
->Communication
;
509 Status
= STATUS_SUCCESS
;
510 Irp
->IoStatus
.Information
= Size
;
513 case KSPROPERTY_PIN_CATEGORY
:
515 if (!Descriptor
->Category
)
517 /* no pin category */
518 return STATUS_NOT_FOUND
;
523 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
525 /* buffer too small */
526 Irp
->IoStatus
.Information
= Size
;
527 Status
= STATUS_BUFFER_TOO_SMALL
;
531 /* copy category guid */
532 RtlMoveMemory(Buffer
, Descriptor
->Category
, sizeof(GUID
));
535 Status
= STATUS_SUCCESS
;
536 Irp
->IoStatus
.Information
= Size
;
539 case KSPROPERTY_PIN_NAME
:
541 if (Descriptor
->Name
)
544 Guid
= (LPGUID
)Descriptor
->Name
;
548 /* use pin category as fallback */
549 Guid
= (LPGUID
)Descriptor
->Category
;
554 /* no friendly name available */
555 return STATUS_NOT_FOUND
;
558 /* read friendly name category name */
559 Status
= KspReadMediaCategory(Guid
, &KeyInfo
);
560 if (!NT_SUCCESS(Status
))
562 /* failed to read category */
563 Irp
->IoStatus
.Information
= 0;
567 /* store required length */
568 Irp
->IoStatus
.Information
= KeyInfo
->DataLength
+ sizeof(WCHAR
);
570 /* check if buffer is too small */
571 if (KeyInfo
->DataLength
+ sizeof(WCHAR
) > IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
)
573 /* buffer too small */
574 Status
= STATUS_BUFFER_OVERFLOW
;
580 RtlMoveMemory(Irp
->UserBuffer
, &KeyInfo
->Data
, KeyInfo
->DataLength
);
582 /* null terminate name */
583 ((LPWSTR
)Irp
->UserBuffer
)[KeyInfo
->DataLength
/ sizeof(WCHAR
)] = L
'\0';
588 case KSPROPERTY_PIN_PROPOSEDATAFORMAT
:
589 Size
= sizeof(KSDATAFORMAT
);
590 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
592 Irp
->IoStatus
.Information
= Size
;
593 Status
= STATUS_BUFFER_TOO_SMALL
;
596 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
!= sizeof(KSDATAFORMAT_WAVEFORMATEX
))
599 Status
= STATUS_NOT_IMPLEMENTED
;
600 Irp
->IoStatus
.Information
= 0;
604 WaveFormatIn
= (PKSDATAFORMAT_WAVEFORMATEX
)Buffer
;
605 if (!Descriptor
->DataRanges
|| !Descriptor
->DataRangesCount
)
607 Status
= STATUS_UNSUCCESSFUL
;
608 Irp
->IoStatus
.Information
= 0;
611 WaveFormatOut
= (PKSDATARANGE_AUDIO
*)Descriptor
->DataRanges
;
612 for(Index
= 0; Index
< Descriptor
->DataRangesCount
; Index
++)
614 if (WaveFormatOut
[Index
]->DataRange
.FormatSize
!= sizeof(KSDATARANGE_AUDIO
))
620 if (WaveFormatOut
[Index
]->MinimumSampleFrequency
> WaveFormatIn
->WaveFormatEx
.nSamplesPerSec
||
621 WaveFormatOut
[Index
]->MaximumSampleFrequency
< WaveFormatIn
->WaveFormatEx
.nSamplesPerSec
||
622 WaveFormatOut
[Index
]->MinimumBitsPerSample
> WaveFormatIn
->WaveFormatEx
.wBitsPerSample
||
623 WaveFormatOut
[Index
]->MaximumBitsPerSample
< WaveFormatIn
->WaveFormatEx
.wBitsPerSample
||
624 WaveFormatOut
[Index
]->MaximumChannels
< WaveFormatIn
->WaveFormatEx
.nChannels
)
626 Irp
->IoStatus
.Status
= STATUS_NO_MATCH
;
627 Irp
->IoStatus
.Information
= 0;
628 return STATUS_NO_MATCH
;
632 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
633 Irp
->IoStatus
.Information
= 0;
634 return STATUS_SUCCESS
;
637 Status
= STATUS_NO_MATCH
;
638 Irp
->IoStatus
.Information
= 0;
641 DPRINT1("Unhandled property request %x\n", Property
->Id
);
642 Status
= STATUS_NOT_IMPLEMENTED
;
643 Irp
->IoStatus
.Information
= 0;
655 KsPinPropertyHandler(
657 IN PKSPROPERTY Property
,
659 IN ULONG DescriptorsCount
,
660 IN
const KSPIN_DESCRIPTOR
* Descriptor
)
662 return KspPinPropertyHandler(Irp
, Property
, Data
, DescriptorsCount
, Descriptor
, sizeof(KSPIN_DESCRIPTOR
));
668 KSDDKAPI NTSTATUS NTAPI
669 KsPinDataIntersectionEx(
673 IN ULONG DescriptorsCount
,
674 IN
const KSPIN_DESCRIPTOR
* Descriptor
,
675 IN ULONG DescriptorSize
,
676 IN PFNKSINTERSECTHANDLEREX IntersectHandler OPTIONAL
,
677 IN PVOID HandlerContext OPTIONAL
)
680 return STATUS_UNSUCCESSFUL
;
689 KsPinDataIntersection(
693 IN ULONG DescriptorsCount
,
694 IN
const KSPIN_DESCRIPTOR
* Descriptor
,
695 IN PFNKSINTERSECTHANDLER IntersectHandler
)
697 KSMULTIPLE_ITEM
* Item
;
698 KSDATARANGE
* DataRange
;
699 PIO_STACK_LOCATION IoStack
;
704 /* get current irp stack location */
705 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
707 /* calculate minimum data size */
708 Size
= sizeof(KSP_PIN
) + sizeof(KSMULTIPLE_ITEM
) + sizeof(KSDATARANGE
);
709 if (IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
< Size
)
711 /* buffer too small */
712 Irp
->IoStatus
.Information
= Size
;
713 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
714 return STATUS_BUFFER_TOO_SMALL
;
716 /* is pin id out of bounds */
717 if (Pin
->PinId
>= DescriptorsCount
)
720 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
721 Irp
->IoStatus
.Information
= 0;
722 return STATUS_INVALID_PARAMETER
;
726 Item
= (KSMULTIPLE_ITEM
*)(Pin
+ 1);
727 /* get first data range */
728 DataRange
= (KSDATARANGE
*)(Item
+ 1);
729 /* iterate through all data ranges */
730 for(Index
= 0; Index
< Item
->Count
; Index
++, DataRange
++)
732 /* call intersect handler */
733 Status
= IntersectHandler(Irp
, Pin
, DataRange
, Data
);
734 if (NT_SUCCESS(Status
))
736 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< DataRange
->FormatSize
)
738 /* buffer is too small */
739 Irp
->IoStatus
.Information
= DataRange
->FormatSize
;
740 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
741 return STATUS_BUFFER_TOO_SMALL
;
743 RtlMoveMemory(Irp
->UserBuffer
, DataRange
, sizeof(KSDATARANGE
));
744 Irp
->IoStatus
.Information
= sizeof(KSDATARANGE
);
745 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
746 return STATUS_SUCCESS
;
751 Irp
->IoStatus
.Information
= 0;
752 Irp
->IoStatus
.Status
= STATUS_NO_MATCH
;
753 return STATUS_NO_MATCH
;
763 KsHandleSizedListQuery(
765 IN ULONG DataItemsCount
,
766 IN ULONG DataItemSize
,
767 IN
const VOID
* DataItems
)
770 PIO_STACK_LOCATION IoStack
;
771 PKSMULTIPLE_ITEM Item
;
773 /* get current irp stack location */
774 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
777 Size
= DataItemSize
* DataItemsCount
+ sizeof(KSMULTIPLE_ITEM
);
779 /* get multiple item */
780 Item
= (PKSMULTIPLE_ITEM
)Irp
->AssociatedIrp
.SystemBuffer
;
782 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== 0)
784 /* buffer too small */
785 Irp
->IoStatus
.Information
= Size
;
787 return STATUS_BUFFER_OVERFLOW
;
790 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== sizeof(ULONG
))
792 /* store just the size */
794 Irp
->IoStatus
.Information
= sizeof(ULONG
);
796 return STATUS_SUCCESS
;
800 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< sizeof(KSMULTIPLE_ITEM
))
802 /* buffer too small */
803 return STATUS_BUFFER_TOO_SMALL
;
806 Item
->Count
= DataItemsCount
;
807 Item
->Size
= DataItemSize
;
809 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== sizeof(KSMULTIPLE_ITEM
))
811 /* buffer can only hold the length descriptor */
812 Irp
->IoStatus
.Information
= sizeof(KSMULTIPLE_ITEM
);
813 return STATUS_SUCCESS
;
816 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
>= Size
)
819 RtlMoveMemory((PVOID
)(Item
+ 1), DataItems
, DataItemSize
* DataItemsCount
);
821 Irp
->IoStatus
.Information
= Size
;
823 return STATUS_SUCCESS
;
827 /* buffer too small */
828 return STATUS_BUFFER_TOO_SMALL
;