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
;
76 UNICODE_STRING GuidString2
;
78 /* did the caller miss the connect parameter */
80 return STATUS_INVALID_PARAMETER
;
82 /* set create param size */
83 Size
= sizeof(KSPIN_CONNECT
);
85 /* fetch create parameters */
86 Status
= KspCopyCreateRequest(Irp
,
89 (PVOID
*)&ConnectDetails
);
91 /* check for success */
92 if (!NT_SUCCESS(Status
))
95 /* is pin id out of bounds */
96 if (ConnectDetails
->PinId
>= DescriptorsCount
)
98 FreeItem(ConnectDetails
);
99 return STATUS_INVALID_PARAMETER
;
102 if (DescriptorSize
== sizeof(KSPIN_DESCRIPTOR
))
104 /* standard pin descriptor */
105 Descriptor
= (PKSPIN_DESCRIPTOR
)((ULONG_PTR
)Descriptors
+ sizeof(KSPIN_DESCRIPTOR
) * ConnectDetails
->PinId
);
109 /* extended / variable pin descriptor */
110 Descriptor
= &((PKSPIN_DESCRIPTOR_EX
)((ULONG_PTR
)Descriptors
+ DescriptorSize
* ConnectDetails
->PinId
))->PinDescriptor
;
114 /* does the pin have interface details filled in */
115 if (Descriptor
->InterfacesCount
&& Descriptor
->Interfaces
)
117 /* use provided pin interface count */
118 Count
= Descriptor
->InterfacesCount
;
119 Interface
= (PKSPIN_INTERFACE
)Descriptor
->Interfaces
;
123 /* use standard pin interface */
125 Interface
= &StandardPinInterface
;
128 /* now check the interface */
131 RtlStringFromGUID(&ConnectDetails
->Interface
.Set
, &GuidString2
);
134 UNICODE_STRING GuidString
;
135 RtlStringFromGUID(&Interface
[Index
].Set
, &GuidString
);
137 DPRINT("Driver Interface %S Id %u\n", GuidString
.Buffer
, Interface
[Index
].Id
);
138 DPRINT("Connect Interface %S Id %u\n", GuidString2
.Buffer
, ConnectDetails
->Interface
.Id
);
140 RtlFreeUnicodeString(&GuidString
);
142 if (IsEqualGUIDAligned(&Interface
[Index
].Set
, &ConnectDetails
->Interface
.Set
) &&
143 Interface
[Index
].Id
== ConnectDetails
->Interface
.Id
)
145 /* found a matching interface */
149 /* iterate to next interface */
151 }while(Index
< Count
);
152 RtlFreeUnicodeString(&GuidString2
);
156 /* pin doesnt support this interface */
157 FreeItem(ConnectDetails
);
158 return STATUS_NO_MATCH
;
161 /* does the pin have medium details filled in */
162 if (Descriptor
->MediumsCount
&& Descriptor
->Mediums
)
164 /* use provided pin interface count */
165 Count
= Descriptor
->MediumsCount
;
166 Medium
= (PKSPIN_MEDIUM
)Descriptor
->Mediums
;
170 /* use standard pin interface */
172 Medium
= &StandardPinMedium
;
175 /* now check the interface */
178 RtlStringFromGUID(&ConnectDetails
->Medium
.Set
, &GuidString2
);
181 UNICODE_STRING GuidString
;
182 RtlStringFromGUID(&Medium
[Index
].Set
, &GuidString
);
184 DPRINT("Driver Medium %S Id %u\n", GuidString
.Buffer
, Medium
[Index
].Id
);
185 DPRINT("Connect Medium %S Id %u\n", GuidString2
.Buffer
, ConnectDetails
->Medium
.Id
);
187 RtlFreeUnicodeString(&GuidString
);
189 if (IsEqualGUIDAligned(&Medium
[Index
].Set
, &ConnectDetails
->Medium
.Set
) &&
190 Medium
[Index
].Id
== ConnectDetails
->Medium
.Id
)
192 /* found a matching interface */
197 /* iterate to next medium */
199 }while(Index
< Count
);
200 RtlFreeUnicodeString(&GuidString2
);
204 /* pin doesnt support this medium */
205 FreeItem(ConnectDetails
);
206 return STATUS_NO_MATCH
;
210 /// implement format checking
212 *Connect
= ConnectDetails
;
213 return STATUS_SUCCESS
;
222 KsValidateConnectRequest(
224 IN ULONG DescriptorsCount
,
225 IN KSPIN_DESCRIPTOR
* Descriptor
,
226 OUT PKSPIN_CONNECT
* Connect
)
228 return KspValidateConnectRequest(Irp
, DescriptorsCount
, Descriptor
, sizeof(KSPIN_DESCRIPTOR
), Connect
);
232 KspReadMediaCategory(
234 PKEY_VALUE_PARTIAL_INFORMATION
*OutInformation
)
236 UNICODE_STRING MediaPath
= RTL_CONSTANT_STRING(L
"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control\\MediaCategories\\");
237 UNICODE_STRING Name
= RTL_CONSTANT_STRING(L
"Name");
238 UNICODE_STRING GuidString
, Path
;
240 OBJECT_ATTRIBUTES ObjectAttributes
;
243 PKEY_VALUE_PARTIAL_INFORMATION KeyInfo
;
245 /* convert the guid to string */
246 Status
= RtlStringFromGUID(Category
, &GuidString
);
247 if (!NT_SUCCESS(Status
))
250 /* allocate buffer for the registry key */
252 Path
.MaximumLength
= MediaPath
.MaximumLength
+ GuidString
.MaximumLength
;
253 Path
.Buffer
= AllocateItem(NonPagedPool
, Path
.MaximumLength
);
256 /* not enough memory */
257 RtlFreeUnicodeString(&GuidString
);
258 return STATUS_INSUFFICIENT_RESOURCES
;
261 RtlAppendUnicodeStringToString(&Path
, &MediaPath
);
262 RtlAppendUnicodeStringToString(&Path
, &GuidString
);
264 /* free guid string */
265 RtlFreeUnicodeString(&GuidString
);
267 /* initialize object attributes */
268 InitializeObjectAttributes(&ObjectAttributes
, &Path
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
271 Status
= ZwOpenKey(&hKey
, GENERIC_READ
, &ObjectAttributes
);
273 DPRINT("ZwOpenKey() status 0x%08lx %wZ\n", Status
, &Path
);
275 /* free path buffer */
276 FreeItem(Path
.Buffer
);
278 /* check for success */
279 if (!NT_SUCCESS(Status
))
281 DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status
);
285 /* query the name size */
286 Status
= ZwQueryValueKey(hKey
, &Name
, KeyValuePartialInformation
, NULL
, 0, &Size
);
287 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_TOO_SMALL
)
289 /* failed to query for name key */
294 /* allocate buffer to read key info */
295 KeyInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
) AllocateItem(NonPagedPool
, Size
);
298 /* not enough memory */
300 return STATUS_INSUFFICIENT_RESOURCES
;
303 /* now read the info */
304 Status
= ZwQueryValueKey(hKey
, &Name
, KeyValuePartialInformation
, (PVOID
)KeyInfo
, Size
, &Size
);
309 if (!NT_SUCCESS(Status
))
311 /* failed to read key */
316 /* store key information */
317 *OutInformation
= KeyInfo
;
324 KspPinPropertyHandler(
326 IN PKSPROPERTY Property
,
328 IN ULONG DescriptorsCount
,
329 IN
const KSPIN_DESCRIPTOR
* Descriptors
,
330 IN ULONG DescriptorSize
)
333 KSMULTIPLE_ITEM
* Item
;
334 PIO_STACK_LOCATION IoStack
;
337 PKSDATARANGE_AUDIO
*WaveFormatOut
;
338 PKSDATAFORMAT_WAVEFORMATEX WaveFormatIn
;
339 PKEY_VALUE_PARTIAL_INFORMATION KeyInfo
;
340 const KSPIN_DESCRIPTOR
*Descriptor
;
341 NTSTATUS Status
= STATUS_NOT_SUPPORTED
;
343 const PKSDATARANGE
* DataRanges
;
346 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
349 //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);
351 /* convert to PKSP_PIN */
352 Pin
= (KSP_PIN
*)Property
;
354 if (Property
->Id
!= KSPROPERTY_PIN_CTYPES
)
356 if (Pin
->PinId
>= DescriptorsCount
)
358 /* invalid parameter */
359 return STATUS_INVALID_PARAMETER
;
364 (*(PULONG
)Buffer
) = DescriptorsCount
;
365 Irp
->IoStatus
.Information
= sizeof(ULONG
);
366 return STATUS_SUCCESS
;
370 if (DescriptorSize
== sizeof(KSPIN_DESCRIPTOR
))
372 /* it is simple pin descriptor */
373 Descriptor
= &Descriptors
[Pin
->PinId
];
377 /* get offset to pin descriptor */
378 Descriptor
= &(((PKSPIN_DESCRIPTOR_EX
)((ULONG_PTR
)Descriptors
+ Pin
->PinId
* DescriptorSize
))->PinDescriptor
);
383 case KSPROPERTY_PIN_DATAFLOW
:
385 Size
= sizeof(KSPIN_DATAFLOW
);
386 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
388 Irp
->IoStatus
.Information
= Size
;
389 Status
= STATUS_BUFFER_TOO_SMALL
;
393 *((KSPIN_DATAFLOW
*)Buffer
) = Descriptor
->DataFlow
;
394 Irp
->IoStatus
.Information
= sizeof(KSPIN_DATAFLOW
);
395 Status
= STATUS_SUCCESS
;
398 case KSPROPERTY_PIN_DATARANGES
:
399 case KSPROPERTY_PIN_CONSTRAINEDDATARANGES
:
401 Size
= sizeof(KSMULTIPLE_ITEM
);
402 DPRINT("Id %lu PinId %lu DataRangesCount %lu ConstrainedDataRangesCount %lu\n", Property
->Id
, Pin
->PinId
, Descriptor
->DataRangesCount
, Descriptor
->ConstrainedDataRangesCount
);
404 if (Property
->Id
== KSPROPERTY_PIN_DATARANGES
|| Descriptor
->ConstrainedDataRangesCount
== 0)
406 DataRanges
= Descriptor
->DataRanges
;
407 Count
= Descriptor
->DataRangesCount
;
411 DataRanges
= Descriptor
->ConstrainedDataRanges
;
412 Count
= Descriptor
->ConstrainedDataRangesCount
;
415 for (Index
= 0; Index
< Count
; Index
++)
417 Size
+= ((DataRanges
[Index
]->FormatSize
+ 0x7) & ~0x7);
420 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== 0)
422 /* buffer too small */
423 Irp
->IoStatus
.Information
= Size
;
424 Status
= STATUS_BUFFER_OVERFLOW
;
428 Item
= (KSMULTIPLE_ITEM
*)Buffer
;
430 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== sizeof(ULONG
))
432 /* store the result size */
434 Irp
->IoStatus
.Information
= sizeof(ULONG
);
435 Status
= STATUS_SUCCESS
;
439 /* store descriptor size */
443 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== sizeof(KSMULTIPLE_ITEM
))
445 Irp
->IoStatus
.Information
= sizeof(KSMULTIPLE_ITEM
);
446 Status
= STATUS_SUCCESS
;
450 /* now copy all dataranges */
451 Data
= (PUCHAR
)(Item
+1);
453 /* alignment assert */
454 ASSERT(((ULONG_PTR
)Data
& 0x7) == 0);
456 for (Index
= 0; Index
< Count
; Index
++)
458 UNICODE_STRING GuidString
;
459 /* convert the guid to string */
460 RtlStringFromGUID(&DataRanges
[Index
]->MajorFormat
, &GuidString
);
461 DPRINT("Index %lu MajorFormat %S\n", Index
, GuidString
.Buffer
);
462 RtlStringFromGUID(&DataRanges
[Index
]->SubFormat
, &GuidString
);
463 DPRINT("Index %lu SubFormat %S\n", Index
, GuidString
.Buffer
);
464 RtlStringFromGUID(&DataRanges
[Index
]->Specifier
, &GuidString
);
465 DPRINT("Index %lu Specifier %S\n", Index
, GuidString
.Buffer
);
466 RtlStringFromGUID(&DataRanges
[Index
]->Specifier
, &GuidString
);
467 DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved %lu KSDATAFORMAT %lu\n", Index
,
468 DataRanges
[Index
]->FormatSize
, DataRanges
[Index
]->Flags
, DataRanges
[Index
]->SampleSize
, DataRanges
[Index
]->Reserved
, sizeof(KSDATAFORMAT
));
470 RtlMoveMemory(Data
, DataRanges
[Index
], DataRanges
[Index
]->FormatSize
);
471 Data
= ((PUCHAR
)Data
+ DataRanges
[Index
]->FormatSize
);
472 /* alignment assert */
473 ASSERT(((ULONG_PTR
)Data
& 0x7) == 0);
474 Data
= (PVOID
)(((ULONG_PTR
)Data
+ 0x7) & ~0x7);
477 Status
= STATUS_SUCCESS
;
478 Irp
->IoStatus
.Information
= Size
;
480 case KSPROPERTY_PIN_INTERFACES
:
482 if (Descriptor
->Interfaces
)
484 /* use mediums provided by driver */
485 return KsHandleSizedListQuery(Irp
, Descriptor
->InterfacesCount
, sizeof(KSPIN_MEDIUM
), Descriptor
->Interfaces
);
489 /* use standard medium */
490 return KsHandleSizedListQuery(Irp
, 1, sizeof(KSPIN_INTERFACE
), &StandardPinInterface
);
494 case KSPROPERTY_PIN_MEDIUMS
:
496 if (Descriptor
->MediumsCount
)
498 /* use mediums provided by driver */
499 return KsHandleSizedListQuery(Irp
, Descriptor
->MediumsCount
, sizeof(KSPIN_MEDIUM
), Descriptor
->Mediums
);
503 /* use standard medium */
504 return KsHandleSizedListQuery(Irp
, 1, sizeof(KSPIN_MEDIUM
), &StandardPinMedium
);
508 case KSPROPERTY_PIN_COMMUNICATION
:
510 Size
= sizeof(KSPIN_COMMUNICATION
);
511 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
513 Irp
->IoStatus
.Information
= Size
;
514 Status
= STATUS_BUFFER_TOO_SMALL
;
518 *((KSPIN_COMMUNICATION
*)Buffer
) = Descriptor
->Communication
;
520 Status
= STATUS_SUCCESS
;
521 Irp
->IoStatus
.Information
= Size
;
524 case KSPROPERTY_PIN_CATEGORY
:
526 if (!Descriptor
->Category
)
528 /* no pin category */
529 return STATUS_NOT_FOUND
;
534 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
536 /* buffer too small */
537 Irp
->IoStatus
.Information
= Size
;
538 Status
= STATUS_BUFFER_TOO_SMALL
;
542 /* copy category guid */
543 RtlMoveMemory(Buffer
, Descriptor
->Category
, sizeof(GUID
));
546 Status
= STATUS_SUCCESS
;
547 Irp
->IoStatus
.Information
= Size
;
550 case KSPROPERTY_PIN_NAME
:
552 if (Descriptor
->Name
)
555 Guid
= (LPGUID
)Descriptor
->Name
;
559 /* use pin category as fallback */
560 Guid
= (LPGUID
)Descriptor
->Category
;
565 /* no friendly name available */
566 return STATUS_NOT_FOUND
;
569 /* read friendly name category name */
570 Status
= KspReadMediaCategory(Guid
, &KeyInfo
);
571 if (!NT_SUCCESS(Status
))
573 /* failed to read category */
574 Irp
->IoStatus
.Information
= 0;
578 /* store required length */
579 Irp
->IoStatus
.Information
= KeyInfo
->DataLength
+ sizeof(WCHAR
);
581 /* check if buffer is too small */
582 if (KeyInfo
->DataLength
+ sizeof(WCHAR
) > IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
)
584 /* buffer too small */
585 Status
= STATUS_BUFFER_OVERFLOW
;
591 RtlMoveMemory(Irp
->AssociatedIrp
.SystemBuffer
, &KeyInfo
->Data
, KeyInfo
->DataLength
);
593 /* null terminate name */
594 ((LPWSTR
)Irp
->AssociatedIrp
.SystemBuffer
)[KeyInfo
->DataLength
/ sizeof(WCHAR
)] = L
'\0';
599 case KSPROPERTY_PIN_PROPOSEDATAFORMAT
:
600 Size
= sizeof(KSDATAFORMAT
);
601 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
603 Irp
->IoStatus
.Information
= Size
;
604 Status
= STATUS_BUFFER_TOO_SMALL
;
607 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
!= sizeof(KSDATAFORMAT_WAVEFORMATEX
))
610 Status
= STATUS_NOT_IMPLEMENTED
;
611 Irp
->IoStatus
.Information
= 0;
615 WaveFormatIn
= (PKSDATAFORMAT_WAVEFORMATEX
)Buffer
;
616 if (!Descriptor
->DataRanges
|| !Descriptor
->DataRangesCount
)
618 Status
= STATUS_UNSUCCESSFUL
;
619 Irp
->IoStatus
.Information
= 0;
622 WaveFormatOut
= (PKSDATARANGE_AUDIO
*)Descriptor
->DataRanges
;
623 for(Index
= 0; Index
< Descriptor
->DataRangesCount
; Index
++)
625 if (WaveFormatOut
[Index
]->DataRange
.FormatSize
!= sizeof(KSDATARANGE_AUDIO
))
631 if (WaveFormatOut
[Index
]->MinimumSampleFrequency
> WaveFormatIn
->WaveFormatEx
.nSamplesPerSec
||
632 WaveFormatOut
[Index
]->MaximumSampleFrequency
< WaveFormatIn
->WaveFormatEx
.nSamplesPerSec
||
633 WaveFormatOut
[Index
]->MinimumBitsPerSample
> WaveFormatIn
->WaveFormatEx
.wBitsPerSample
||
634 WaveFormatOut
[Index
]->MaximumBitsPerSample
< WaveFormatIn
->WaveFormatEx
.wBitsPerSample
||
635 WaveFormatOut
[Index
]->MaximumChannels
< WaveFormatIn
->WaveFormatEx
.nChannels
)
637 Irp
->IoStatus
.Status
= STATUS_NO_MATCH
;
638 Irp
->IoStatus
.Information
= 0;
639 return STATUS_NO_MATCH
;
643 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
644 Irp
->IoStatus
.Information
= 0;
645 return STATUS_SUCCESS
;
648 Status
= STATUS_NO_MATCH
;
649 Irp
->IoStatus
.Information
= 0;
652 DPRINT1("Unhandled property request %x\n", Property
->Id
);
653 Status
= STATUS_NOT_IMPLEMENTED
;
654 Irp
->IoStatus
.Information
= 0;
666 KsPinPropertyHandler(
668 IN PKSPROPERTY Property
,
670 IN ULONG DescriptorsCount
,
671 IN
const KSPIN_DESCRIPTOR
* Descriptor
)
673 return KspPinPropertyHandler(Irp
, Property
, Data
, DescriptorsCount
, Descriptor
, sizeof(KSPIN_DESCRIPTOR
));
679 KSDDKAPI NTSTATUS NTAPI
680 KsPinDataIntersectionEx(
684 IN ULONG DescriptorsCount
,
685 IN
const KSPIN_DESCRIPTOR
* Descriptor
,
686 IN ULONG DescriptorSize
,
687 IN PFNKSINTERSECTHANDLEREX IntersectHandler OPTIONAL
,
688 IN PVOID HandlerContext OPTIONAL
)
691 return STATUS_UNSUCCESSFUL
;
700 KsPinDataIntersection(
704 IN ULONG DescriptorsCount
,
705 IN
const KSPIN_DESCRIPTOR
* Descriptor
,
706 IN PFNKSINTERSECTHANDLER IntersectHandler
)
708 KSMULTIPLE_ITEM
* Item
;
709 KSDATARANGE
* DataRange
;
710 PIO_STACK_LOCATION IoStack
;
715 /* get current irp stack location */
716 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
718 /* calculate minimum data size */
719 Size
= sizeof(KSP_PIN
) + sizeof(KSMULTIPLE_ITEM
) + sizeof(KSDATARANGE
);
720 if (IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
< Size
)
722 /* buffer too small */
723 Irp
->IoStatus
.Information
= Size
;
724 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
725 return STATUS_BUFFER_TOO_SMALL
;
727 /* is pin id out of bounds */
728 if (Pin
->PinId
>= DescriptorsCount
)
731 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
732 Irp
->IoStatus
.Information
= 0;
733 return STATUS_INVALID_PARAMETER
;
737 Item
= (KSMULTIPLE_ITEM
*)(Pin
+ 1);
738 /* get first data range */
739 DataRange
= (KSDATARANGE
*)(Item
+ 1);
740 /* iterate through all data ranges */
741 for(Index
= 0; Index
< Item
->Count
; Index
++, DataRange
++)
743 /* call intersect handler */
744 Status
= IntersectHandler(Irp
, Pin
, DataRange
, Data
);
745 if (NT_SUCCESS(Status
))
747 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< DataRange
->FormatSize
)
749 /* buffer is too small */
750 Irp
->IoStatus
.Information
= DataRange
->FormatSize
;
751 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
752 return STATUS_BUFFER_TOO_SMALL
;
754 RtlMoveMemory(Irp
->UserBuffer
, DataRange
, sizeof(KSDATARANGE
));
755 Irp
->IoStatus
.Information
= sizeof(KSDATARANGE
);
756 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
757 return STATUS_SUCCESS
;
762 Irp
->IoStatus
.Information
= 0;
763 Irp
->IoStatus
.Status
= STATUS_NO_MATCH
;
764 return STATUS_NO_MATCH
;
774 KsHandleSizedListQuery(
776 IN ULONG DataItemsCount
,
777 IN ULONG DataItemSize
,
778 IN
const VOID
* DataItems
)
781 PIO_STACK_LOCATION IoStack
;
782 PKSMULTIPLE_ITEM Item
;
784 /* get current irp stack location */
785 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
788 Size
= DataItemSize
* DataItemsCount
+ sizeof(KSMULTIPLE_ITEM
);
790 /* get multiple item */
791 Item
= (PKSMULTIPLE_ITEM
)Irp
->AssociatedIrp
.SystemBuffer
;
793 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== 0)
795 /* buffer too small */
796 Irp
->IoStatus
.Information
= Size
;
798 return STATUS_BUFFER_OVERFLOW
;
801 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== sizeof(ULONG
))
803 /* store just the size */
805 Irp
->IoStatus
.Information
= sizeof(ULONG
);
807 return STATUS_SUCCESS
;
811 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< sizeof(KSMULTIPLE_ITEM
))
813 /* buffer too small */
814 return STATUS_BUFFER_TOO_SMALL
;
817 Item
->Count
= DataItemsCount
;
818 Item
->Size
= DataItemSize
;
820 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== sizeof(KSMULTIPLE_ITEM
))
822 /* buffer can only hold the length descriptor */
823 Irp
->IoStatus
.Information
= sizeof(KSMULTIPLE_ITEM
);
824 return STATUS_SUCCESS
;
827 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
>= Size
)
830 RtlMoveMemory((PVOID
)(Item
+ 1), DataItems
, DataItemSize
* DataItemsCount
);
832 Irp
->IoStatus
.Information
= Size
;
834 return STATUS_SUCCESS
;
838 /* buffer too small */
839 return STATUS_BUFFER_TOO_SMALL
;