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
,
26 const GUID KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT
= {0xf4aeb342, 0x0329, 0x4fdd, {0xa8, 0xfd, 0x4a, 0xff, 0x49, 0x26, 0xc9, 0x78}};
35 IN HANDLE FilterHandle
,
36 IN PKSPIN_CONNECT Connect
,
37 IN ACCESS_MASK DesiredAccess
,
38 OUT PHANDLE ConnectionHandle
)
40 UINT ConnectSize
= sizeof(KSPIN_CONNECT
);
42 PKSDATAFORMAT_WAVEFORMATEX Format
= (PKSDATAFORMAT_WAVEFORMATEX
)(Connect
+ 1);
43 if (Format
->DataFormat
.FormatSize
== sizeof(KSDATAFORMAT
) ||
44 Format
->DataFormat
.FormatSize
== sizeof(KSDATAFORMAT
) + sizeof(WAVEFORMATEX
))
46 ConnectSize
+= Format
->DataFormat
.FormatSize
;
49 return KspCreateObjectType(FilterHandle
,
58 KspValidateConnectRequest(
60 IN ULONG DescriptorsCount
,
62 IN ULONG DescriptorSize
,
63 OUT PKSPIN_CONNECT
* Connect
)
65 PKSPIN_CONNECT ConnectDetails
;
66 PKSPIN_INTERFACE Interface
;
73 PKSPIN_DESCRIPTOR Descriptor
;
75 /* did the caller miss the connect parameter */
77 return STATUS_INVALID_PARAMETER
;
79 /* set create param size */
80 Size
= sizeof(KSPIN_CONNECT
);
82 /* fetch create parameters */
83 Status
= KspCopyCreateRequest(Irp
,
86 (PVOID
*)&ConnectDetails
);
88 /* check for success */
89 if (!NT_SUCCESS(Status
))
92 /* is pin id out of bounds */
93 if (ConnectDetails
->PinId
>= DescriptorsCount
)
94 return STATUS_INVALID_PARAMETER
;
96 if (DescriptorSize
== sizeof(KSPIN_DESCRIPTOR
))
98 /* standard pin descriptor */
99 Descriptor
= (PKSPIN_DESCRIPTOR
)((ULONG_PTR
)Descriptors
+ sizeof(KSPIN_DESCRIPTOR
) * ConnectDetails
->PinId
);
103 /* extended / variable pin descriptor */
104 Descriptor
= &((PKSPIN_DESCRIPTOR_EX
)((ULONG_PTR
)Descriptors
+ DescriptorSize
* ConnectDetails
->PinId
))->PinDescriptor
;
108 /* does the pin have interface details filled in */
109 if (Descriptor
->InterfacesCount
&& Descriptor
->Interfaces
)
111 /* use provided pin interface count */
112 Count
= Descriptor
->InterfacesCount
;
113 Interface
= (PKSPIN_INTERFACE
)Descriptor
->Interfaces
;
117 /* use standard pin interface */
119 Interface
= &StandardPinInterface
;
122 /* now check the interface */
127 UNICODE_STRING GuidString
, GuidString2
;
128 RtlStringFromGUID(&Interface
[Index
].Set
, &GuidString
);
129 RtlStringFromGUID(&ConnectDetails
->Interface
.Set
, &GuidString2
);
131 DPRINT("Driver Interface %S Id %u\n", GuidString
.Buffer
, Interface
[Index
].Id
);
132 DPRINT("Connect Interface %S Id %u\n", GuidString2
.Buffer
, ConnectDetails
->Interface
.Id
);
134 if (IsEqualGUIDAligned(&Interface
[Index
].Set
, &ConnectDetails
->Interface
.Set
) &&
135 Interface
[Index
].Id
== ConnectDetails
->Interface
.Id
)
137 /* found a matching interface */
141 /* iterate to next interface */
143 }while(Index
< Count
);
147 /* pin doesnt support this interface */
148 return STATUS_NO_MATCH
;
151 /* does the pin have medium details filled in */
152 if (Descriptor
->MediumsCount
&& Descriptor
->Mediums
)
154 /* use provided pin interface count */
155 Count
= Descriptor
->MediumsCount
;
156 Medium
= (PKSPIN_MEDIUM
)Descriptor
->Mediums
;
160 /* use standard pin interface */
162 Medium
= &StandardPinMedium
;
165 /* now check the interface */
170 UNICODE_STRING GuidString
, GuidString2
;
171 RtlStringFromGUID(&Medium
[Index
].Set
, &GuidString
);
172 RtlStringFromGUID(&ConnectDetails
->Medium
.Set
, &GuidString2
);
174 DPRINT("Driver Medium %S Id %u\n", GuidString
.Buffer
, Medium
[Index
].Id
);
175 DPRINT("Connect Medium %S Id %u\n", GuidString2
.Buffer
, ConnectDetails
->Medium
.Id
);
178 if (IsEqualGUIDAligned(&Medium
[Index
].Set
, &ConnectDetails
->Medium
.Set
) &&
179 Medium
[Index
].Id
== ConnectDetails
->Medium
.Id
)
181 /* found a matching interface */
188 /* iterate to next medium */
190 }while(Index
< Count
);
194 /* pin doesnt support this medium */
195 return STATUS_NO_MATCH
;
199 /// implement format checking
201 *Connect
= ConnectDetails
;
202 return STATUS_SUCCESS
;
211 KsValidateConnectRequest(
213 IN ULONG DescriptorsCount
,
214 IN KSPIN_DESCRIPTOR
* Descriptor
,
215 OUT PKSPIN_CONNECT
* Connect
)
217 return KspValidateConnectRequest(Irp
, DescriptorsCount
, Descriptor
, sizeof(KSPIN_DESCRIPTOR
), Connect
);
221 KspReadMediaCategory(
223 PKEY_VALUE_PARTIAL_INFORMATION
*OutInformation
)
225 UNICODE_STRING MediaPath
= RTL_CONSTANT_STRING(L
"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control\\MediaCategories\\");
226 UNICODE_STRING Name
= RTL_CONSTANT_STRING(L
"Name");
227 UNICODE_STRING GuidString
, Path
;
229 OBJECT_ATTRIBUTES ObjectAttributes
;
232 PKEY_VALUE_PARTIAL_INFORMATION KeyInfo
;
234 /* convert the guid to string */
235 Status
= RtlStringFromGUID(Category
, &GuidString
);
236 if (!NT_SUCCESS(Status
))
239 /* allocate buffer for the registry key */
241 Path
.MaximumLength
= MediaPath
.MaximumLength
+ GuidString
.MaximumLength
;
242 Path
.Buffer
= AllocateItem(NonPagedPool
, Path
.MaximumLength
);
245 /* not enough memory */
246 RtlFreeUnicodeString(&GuidString
);
247 return STATUS_INSUFFICIENT_RESOURCES
;
250 RtlAppendUnicodeStringToString(&Path
, &MediaPath
);
251 RtlAppendUnicodeStringToString(&Path
, &GuidString
);
253 /* free guid string */
254 RtlFreeUnicodeString(&GuidString
);
256 /* initialize object attributes */
257 InitializeObjectAttributes(&ObjectAttributes
, &Path
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
260 Status
= ZwOpenKey(&hKey
, GENERIC_READ
, &ObjectAttributes
);
262 DPRINT("ZwOpenKey() status 0x%08lx %wZ\n", Status
, &Path
);
264 /* free path buffer */
265 FreeItem(Path
.Buffer
);
267 /* check for success */
268 if (!NT_SUCCESS(Status
))
270 DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status
);
274 /* query the name size */
275 Status
= ZwQueryValueKey(hKey
, &Name
, KeyValuePartialInformation
, NULL
, 0, &Size
);
276 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_TOO_SMALL
)
278 /* failed to query for name key */
283 /* allocate buffer to read key info */
284 KeyInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
) AllocateItem(NonPagedPool
, Size
);
287 /* not enough memory */
289 return STATUS_INSUFFICIENT_RESOURCES
;
292 /* now read the info */
293 Status
= ZwQueryValueKey(hKey
, &Name
, KeyValuePartialInformation
, (PVOID
)KeyInfo
, Size
, &Size
);
298 if (!NT_SUCCESS(Status
))
300 /* failed to read key */
305 /* store key information */
306 *OutInformation
= KeyInfo
;
313 KspPinPropertyHandler(
315 IN PKSPROPERTY Property
,
317 IN ULONG DescriptorsCount
,
318 IN
const KSPIN_DESCRIPTOR
* Descriptors
,
319 IN ULONG DescriptorSize
)
322 KSMULTIPLE_ITEM
* Item
;
323 PIO_STACK_LOCATION IoStack
;
326 PKSDATARANGE_AUDIO
*WaveFormatOut
;
327 PKSDATAFORMAT_WAVEFORMATEX WaveFormatIn
;
328 PKEY_VALUE_PARTIAL_INFORMATION KeyInfo
;
329 const KSPIN_DESCRIPTOR
*Descriptor
;
330 NTSTATUS Status
= STATUS_NOT_SUPPORTED
;
332 const PKSDATARANGE
* DataRanges
;
335 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
336 Buffer
= Irp
->UserBuffer
;
338 //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);
340 /* convert to PKSP_PIN */
341 Pin
= (KSP_PIN
*)Property
;
343 if (Property
->Id
!= KSPROPERTY_PIN_CTYPES
)
345 if (Pin
->PinId
>= DescriptorsCount
)
347 /* invalid parameter */
348 return STATUS_INVALID_PARAMETER
;
352 if (DescriptorSize
== sizeof(KSPIN_DESCRIPTOR
))
354 /* it is simple pin descriptor */
355 Descriptor
= &Descriptors
[Pin
->PinId
];
359 /* get offset to pin descriptor */
360 Descriptor
= &(((PKSPIN_DESCRIPTOR_EX
)((ULONG_PTR
)Descriptors
+ Pin
->PinId
* DescriptorSize
))->PinDescriptor
);
365 case KSPROPERTY_PIN_CTYPES
:
366 (*(PULONG
)Buffer
) = DescriptorsCount
;
367 Irp
->IoStatus
.Information
= sizeof(ULONG
);
368 Status
= STATUS_SUCCESS
;
370 case KSPROPERTY_PIN_DATAFLOW
:
372 Size
= sizeof(KSPIN_DATAFLOW
);
373 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
375 Irp
->IoStatus
.Information
= Size
;
376 Status
= STATUS_BUFFER_TOO_SMALL
;
380 *((KSPIN_DATAFLOW
*)Buffer
) = Descriptor
->DataFlow
;
381 Irp
->IoStatus
.Information
= sizeof(KSPIN_DATAFLOW
);
382 Status
= STATUS_SUCCESS
;
385 case KSPROPERTY_PIN_DATARANGES
:
386 case KSPROPERTY_PIN_CONSTRAINEDDATARANGES
:
388 Size
= sizeof(KSMULTIPLE_ITEM
);
389 DPRINT("Id %lu PinId %lu DataRangesCount %lu ConstrainedDataRangesCount %lu\n", Property
->Id
, Pin
->PinId
, Descriptor
->DataRangesCount
, Descriptor
->ConstrainedDataRangesCount
);
391 if (Property
->Id
== KSPROPERTY_PIN_DATARANGES
|| Descriptor
->ConstrainedDataRangesCount
== 0)
393 DataRanges
= Descriptor
->DataRanges
;
394 Count
= Descriptor
->DataRangesCount
;
398 DataRanges
= Descriptor
->ConstrainedDataRanges
;
399 Count
= Descriptor
->ConstrainedDataRangesCount
;
402 for (Index
= 0; Index
< Count
; Index
++)
404 Size
+= ((DataRanges
[Index
]->FormatSize
+ 0x7) & ~0x7);
407 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== 0)
409 /* buffer too small */
410 Irp
->IoStatus
.Information
= Size
;
411 Status
= STATUS_BUFFER_OVERFLOW
;
415 Item
= (KSMULTIPLE_ITEM
*)Buffer
;
417 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== sizeof(ULONG
))
419 /* store the result size */
421 Irp
->IoStatus
.Information
= sizeof(ULONG
);
422 Status
= STATUS_SUCCESS
;
426 /* store descriptor size */
430 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== sizeof(KSMULTIPLE_ITEM
))
432 Irp
->IoStatus
.Information
= sizeof(KSMULTIPLE_ITEM
);
433 Status
= STATUS_SUCCESS
;
437 /* now copy all dataranges */
438 Data
= (PUCHAR
)(Item
+1);
440 /* alignment assert */
441 ASSERT(((ULONG_PTR
)Data
& 0x7) == 0);
443 for (Index
= 0; Index
< Count
; Index
++)
445 UNICODE_STRING GuidString
;
446 /* convert the guid to string */
447 RtlStringFromGUID(&DataRanges
[Index
]->MajorFormat
, &GuidString
);
448 DPRINT("Index %lu MajorFormat %S\n", Index
, GuidString
.Buffer
);
449 RtlStringFromGUID(&DataRanges
[Index
]->SubFormat
, &GuidString
);
450 DPRINT("Index %lu SubFormat %S\n", Index
, GuidString
.Buffer
);
451 RtlStringFromGUID(&DataRanges
[Index
]->Specifier
, &GuidString
);
452 DPRINT("Index %lu Specifier %S\n", Index
, GuidString
.Buffer
);
453 RtlStringFromGUID(&DataRanges
[Index
]->Specifier
, &GuidString
);
454 DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved %lu KSDATAFORMAT %lu\n", Index
,
455 DataRanges
[Index
]->FormatSize
, DataRanges
[Index
]->Flags
, DataRanges
[Index
]->SampleSize
, DataRanges
[Index
]->Reserved
, sizeof(KSDATAFORMAT
));
457 RtlMoveMemory(Data
, DataRanges
[Index
], DataRanges
[Index
]->FormatSize
);
458 Data
= ((PUCHAR
)Data
+ DataRanges
[Index
]->FormatSize
);
459 /* alignment assert */
460 ASSERT(((ULONG_PTR
)Data
& 0x7) == 0);
461 Data
= (PVOID
)(((ULONG_PTR
)Data
+ 0x7) & ~0x7);
464 Status
= STATUS_SUCCESS
;
465 Irp
->IoStatus
.Information
= Size
;
467 case KSPROPERTY_PIN_INTERFACES
:
469 if (Descriptor
->Interfaces
)
471 /* use mediums provided by driver */
472 return KsHandleSizedListQuery(Irp
, Descriptor
->InterfacesCount
, sizeof(KSPIN_MEDIUM
), Descriptor
->Interfaces
);
476 /* use standard medium */
477 return KsHandleSizedListQuery(Irp
, 1, sizeof(KSPIN_INTERFACE
), &StandardPinInterface
);
481 case KSPROPERTY_PIN_MEDIUMS
:
483 if (Descriptor
->MediumsCount
)
485 /* use mediums provided by driver */
486 return KsHandleSizedListQuery(Irp
, Descriptor
->MediumsCount
, sizeof(KSPIN_MEDIUM
), Descriptor
->Mediums
);
490 /* use standard medium */
491 return KsHandleSizedListQuery(Irp
, 1, sizeof(KSPIN_MEDIUM
), &StandardPinMedium
);
495 case KSPROPERTY_PIN_COMMUNICATION
:
497 Size
= sizeof(KSPIN_COMMUNICATION
);
498 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
500 Irp
->IoStatus
.Information
= Size
;
501 Status
= STATUS_BUFFER_TOO_SMALL
;
505 *((KSPIN_COMMUNICATION
*)Buffer
) = Descriptor
->Communication
;
507 Status
= STATUS_SUCCESS
;
508 Irp
->IoStatus
.Information
= Size
;
511 case KSPROPERTY_PIN_CATEGORY
:
513 if (!Descriptor
->Category
)
515 /* no pin category */
516 return STATUS_NOT_FOUND
;
521 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
523 /* buffer too small */
524 Irp
->IoStatus
.Information
= Size
;
525 Status
= STATUS_BUFFER_TOO_SMALL
;
529 /* copy category guid */
530 RtlMoveMemory(Buffer
, Descriptor
->Category
, sizeof(GUID
));
533 Status
= STATUS_SUCCESS
;
534 Irp
->IoStatus
.Information
= Size
;
537 case KSPROPERTY_PIN_NAME
:
539 if (Descriptor
->Name
)
542 Guid
= (LPGUID
)Descriptor
->Name
;
546 /* use pin category as fallback */
547 Guid
= (LPGUID
)Descriptor
->Category
;
552 /* no friendly name available */
553 return STATUS_NOT_FOUND
;
556 /* read friendly name category name */
557 Status
= KspReadMediaCategory(Guid
, &KeyInfo
);
558 if (!NT_SUCCESS(Status
))
560 /* failed to read category */
561 Irp
->IoStatus
.Information
= 0;
565 /* store required length */
566 Irp
->IoStatus
.Information
= KeyInfo
->DataLength
+ sizeof(WCHAR
);
568 /* check if buffer is too small */
569 if (KeyInfo
->DataLength
+ sizeof(WCHAR
) > IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
)
571 /* buffer too small */
572 Status
= STATUS_BUFFER_OVERFLOW
;
578 RtlMoveMemory(Irp
->UserBuffer
, &KeyInfo
->Data
, KeyInfo
->DataLength
);
580 /* null terminate name */
581 ((LPWSTR
)Irp
->UserBuffer
)[KeyInfo
->DataLength
/ sizeof(WCHAR
)] = L
'\0';
586 case KSPROPERTY_PIN_PROPOSEDATAFORMAT
:
587 Size
= sizeof(KSDATAFORMAT
);
588 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
590 Irp
->IoStatus
.Information
= Size
;
591 Status
= STATUS_BUFFER_TOO_SMALL
;
594 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
!= sizeof(KSDATAFORMAT_WAVEFORMATEX
))
597 Status
= STATUS_NOT_IMPLEMENTED
;
598 Irp
->IoStatus
.Information
= 0;
602 WaveFormatIn
= (PKSDATAFORMAT_WAVEFORMATEX
)Buffer
;
603 if (!Descriptor
->DataRanges
|| !Descriptor
->DataRangesCount
)
605 Status
= STATUS_UNSUCCESSFUL
;
606 Irp
->IoStatus
.Information
= 0;
609 WaveFormatOut
= (PKSDATARANGE_AUDIO
*)Descriptor
->DataRanges
;
610 for(Index
= 0; Index
< Descriptor
->DataRangesCount
; Index
++)
612 if (WaveFormatOut
[Index
]->DataRange
.FormatSize
!= sizeof(KSDATARANGE_AUDIO
))
618 if (WaveFormatOut
[Index
]->MinimumSampleFrequency
> WaveFormatIn
->WaveFormatEx
.nSamplesPerSec
||
619 WaveFormatOut
[Index
]->MaximumSampleFrequency
< WaveFormatIn
->WaveFormatEx
.nSamplesPerSec
||
620 WaveFormatOut
[Index
]->MinimumBitsPerSample
> WaveFormatIn
->WaveFormatEx
.wBitsPerSample
||
621 WaveFormatOut
[Index
]->MaximumBitsPerSample
< WaveFormatIn
->WaveFormatEx
.wBitsPerSample
||
622 WaveFormatOut
[Index
]->MaximumChannels
< WaveFormatIn
->WaveFormatEx
.nChannels
)
624 Irp
->IoStatus
.Status
= STATUS_NO_MATCH
;
625 Irp
->IoStatus
.Information
= 0;
626 return STATUS_NO_MATCH
;
630 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
631 Irp
->IoStatus
.Information
= 0;
632 return STATUS_SUCCESS
;
635 Status
= STATUS_NO_MATCH
;
636 Irp
->IoStatus
.Information
= 0;
639 DPRINT1("Unhandled property request %x\n", Property
->Id
);
640 Status
= STATUS_NOT_IMPLEMENTED
;
641 Irp
->IoStatus
.Information
= 0;
653 KsPinPropertyHandler(
655 IN PKSPROPERTY Property
,
657 IN ULONG DescriptorsCount
,
658 IN
const KSPIN_DESCRIPTOR
* Descriptor
)
660 return KspPinPropertyHandler(Irp
, Property
, Data
, DescriptorsCount
, Descriptor
, sizeof(KSPIN_DESCRIPTOR
));
666 KSDDKAPI NTSTATUS NTAPI
667 KsPinDataIntersectionEx(
671 IN ULONG DescriptorsCount
,
672 IN
const KSPIN_DESCRIPTOR
* Descriptor
,
673 IN ULONG DescriptorSize
,
674 IN PFNKSINTERSECTHANDLEREX IntersectHandler OPTIONAL
,
675 IN PVOID HandlerContext OPTIONAL
)
678 return STATUS_UNSUCCESSFUL
;
687 KsPinDataIntersection(
691 IN ULONG DescriptorsCount
,
692 IN
const KSPIN_DESCRIPTOR
* Descriptor
,
693 IN PFNKSINTERSECTHANDLER IntersectHandler
)
695 KSMULTIPLE_ITEM
* Item
;
696 KSDATARANGE
* DataRange
;
697 PIO_STACK_LOCATION IoStack
;
702 /* get current irp stack location */
703 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
705 /* calculate minimum data size */
706 Size
= sizeof(KSP_PIN
) + sizeof(KSMULTIPLE_ITEM
) + sizeof(KSDATARANGE
);
707 if (IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
< Size
)
709 /* buffer too small */
710 Irp
->IoStatus
.Information
= Size
;
711 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
712 return STATUS_BUFFER_TOO_SMALL
;
714 /* is pin id out of bounds */
715 if (Pin
->PinId
>= DescriptorsCount
)
718 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
719 Irp
->IoStatus
.Information
= 0;
720 return STATUS_INVALID_PARAMETER
;
724 Item
= (KSMULTIPLE_ITEM
*)(Pin
+ 1);
725 /* get first data range */
726 DataRange
= (KSDATARANGE
*)(Item
+ 1);
727 /* iterate through all data ranges */
728 for(Index
= 0; Index
< Item
->Count
; Index
++, DataRange
++)
730 /* call intersect handler */
731 Status
= IntersectHandler(Irp
, Pin
, DataRange
, Data
);
732 if (NT_SUCCESS(Status
))
734 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< DataRange
->FormatSize
)
736 /* buffer is too small */
737 Irp
->IoStatus
.Information
= DataRange
->FormatSize
;
738 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
739 return STATUS_BUFFER_TOO_SMALL
;
741 RtlMoveMemory(Irp
->UserBuffer
, DataRange
, sizeof(KSDATARANGE
));
742 Irp
->IoStatus
.Information
= sizeof(KSDATARANGE
);
743 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
744 return STATUS_SUCCESS
;
749 Irp
->IoStatus
.Information
= 0;
750 Irp
->IoStatus
.Status
= STATUS_NO_MATCH
;
751 return STATUS_NO_MATCH
;
761 KsHandleSizedListQuery(
763 IN ULONG DataItemsCount
,
764 IN ULONG DataItemSize
,
765 IN
const VOID
* DataItems
)
768 PIO_STACK_LOCATION IoStack
;
769 PKSMULTIPLE_ITEM Item
;
771 /* get current irp stack location */
772 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
775 Size
= DataItemSize
* DataItemsCount
+ sizeof(KSMULTIPLE_ITEM
);
777 /* get multiple item */
778 Item
= (PKSMULTIPLE_ITEM
)Irp
->UserBuffer
;
780 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== 0)
782 /* buffer too small */
783 Irp
->IoStatus
.Information
= Size
;
785 return STATUS_BUFFER_OVERFLOW
;
788 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== sizeof(ULONG
))
790 /* store just the size */
792 Irp
->IoStatus
.Information
= sizeof(ULONG
);
794 return STATUS_SUCCESS
;
798 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< sizeof(KSMULTIPLE_ITEM
))
800 /* buffer too small */
801 return STATUS_BUFFER_TOO_SMALL
;
804 Item
->Count
= DataItemsCount
;
805 Item
->Size
= DataItemSize
;
807 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== sizeof(KSMULTIPLE_ITEM
))
809 /* buffer can only hold the length descriptor */
810 Irp
->IoStatus
.Information
= sizeof(KSMULTIPLE_ITEM
);
811 return STATUS_SUCCESS
;
814 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
>= Size
)
817 RtlMoveMemory((PVOID
)(Item
+ 1), DataItems
, DataItemSize
* DataItemsCount
);
819 Irp
->IoStatus
.Information
= Size
;
821 return STATUS_SUCCESS
;
825 /* buffer too small */
826 return STATUS_BUFFER_TOO_SMALL
;