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
;
334 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
335 Buffer
= Irp
->UserBuffer
;
337 //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);
339 /* convert to PKSP_PIN */
340 Pin
= (KSP_PIN
*)Property
;
342 if (Property
->Id
!= KSPROPERTY_PIN_CTYPES
)
344 if (Pin
->PinId
>= DescriptorsCount
)
346 /* invalid parameter */
347 return STATUS_INVALID_PARAMETER
;
351 if (DescriptorSize
== sizeof(KSPIN_DESCRIPTOR
))
353 /* it is simple pin descriptor */
354 Descriptor
= &Descriptors
[Pin
->PinId
];
358 /* get offset to pin descriptor */
359 Descriptor
= &(((PKSPIN_DESCRIPTOR_EX
)((ULONG_PTR
)Descriptors
+ Pin
->PinId
* DescriptorSize
))->PinDescriptor
);
364 case KSPROPERTY_PIN_CTYPES
:
365 (*(PULONG
)Buffer
) = DescriptorsCount
;
366 Irp
->IoStatus
.Information
= sizeof(ULONG
);
367 Status
= STATUS_SUCCESS
;
369 case KSPROPERTY_PIN_DATAFLOW
:
371 Size
= sizeof(KSPIN_DATAFLOW
);
372 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
374 Irp
->IoStatus
.Information
= Size
;
375 Status
= STATUS_BUFFER_TOO_SMALL
;
379 *((KSPIN_DATAFLOW
*)Buffer
) = Descriptor
->DataFlow
;
380 Irp
->IoStatus
.Information
= sizeof(KSPIN_DATAFLOW
);
381 Status
= STATUS_SUCCESS
;
384 case KSPROPERTY_PIN_DATARANGES
:
385 case KSPROPERTY_PIN_CONSTRAINEDDATARANGES
:
387 Size
= sizeof(KSMULTIPLE_ITEM
);
388 DPRINT("Id %lu PinId %lu DataRangesCount %lu ConstrainedDataRangesCount %lu\n", Property
->Id
, Pin
->PinId
, Descriptor
->DataRangesCount
, Descriptor
->ConstrainedDataRangesCount
);
390 if (Property
->Id
== KSPROPERTY_PIN_DATARANGES
|| Descriptor
->ConstrainedDataRangesCount
== 0)
392 DataRanges
= Descriptor
->DataRanges
;
393 Count
= Descriptor
->DataRangesCount
;
397 DataRanges
= Descriptor
->ConstrainedDataRanges
;
398 Count
= Descriptor
->ConstrainedDataRangesCount
;
401 for (Index
= 0; Index
< Count
; Index
++)
403 Size
+= ((DataRanges
[Index
]->FormatSize
+ 0x7) & ~0x7);
406 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== 0)
408 /* buffer too small */
409 Irp
->IoStatus
.Information
= Size
;
410 Status
= STATUS_BUFFER_OVERFLOW
;
414 Item
= (KSMULTIPLE_ITEM
*)Buffer
;
416 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== sizeof(ULONG
))
418 /* store the result size */
420 Irp
->IoStatus
.Information
= sizeof(ULONG
);
421 Status
= STATUS_SUCCESS
;
425 /* store descriptor size */
429 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== sizeof(KSMULTIPLE_ITEM
))
431 Irp
->IoStatus
.Information
= sizeof(KSMULTIPLE_ITEM
);
432 Status
= STATUS_SUCCESS
;
436 /* now copy all dataranges */
437 Data
= (PUCHAR
)(Item
+1);
439 /* alignment assert */
440 ASSERT(((ULONG_PTR
)Data
& 0x7) == 0);
442 for (Index
= 0; Index
< Count
; Index
++)
444 UNICODE_STRING GuidString
;
445 /* convert the guid to string */
446 RtlStringFromGUID(&DataRanges
[Index
]->MajorFormat
, &GuidString
);
447 DPRINT("Index %lu MajorFormat %S\n", Index
, GuidString
.Buffer
);
448 RtlStringFromGUID(&DataRanges
[Index
]->SubFormat
, &GuidString
);
449 DPRINT("Index %lu SubFormat %S\n", Index
, GuidString
.Buffer
);
450 RtlStringFromGUID(&DataRanges
[Index
]->Specifier
, &GuidString
);
451 DPRINT("Index %lu Specifier %S\n", Index
, GuidString
.Buffer
);
452 RtlStringFromGUID(&DataRanges
[Index
]->Specifier
, &GuidString
);
453 DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved %lu KSDATAFORMAT %lu\n", Index
,
454 DataRanges
[Index
]->FormatSize
, DataRanges
[Index
]->Flags
, DataRanges
[Index
]->SampleSize
, DataRanges
[Index
]->Reserved
, sizeof(KSDATAFORMAT
));
456 RtlMoveMemory(Data
, DataRanges
[Index
], DataRanges
[Index
]->FormatSize
);
457 Data
= ((PUCHAR
)Data
+ DataRanges
[Index
]->FormatSize
);
458 /* alignment assert */
459 ASSERT(((ULONG_PTR
)Data
& 0x7) == 0);
460 Data
= (PVOID
)(((ULONG_PTR
)Data
+ 0x7) & ~0x7);
463 Status
= STATUS_SUCCESS
;
464 Irp
->IoStatus
.Information
= Size
;
466 case KSPROPERTY_PIN_INTERFACES
:
468 if (Descriptor
->Interfaces
)
470 /* use mediums provided by driver */
471 return KsHandleSizedListQuery(Irp
, Descriptor
->InterfacesCount
, sizeof(KSPIN_MEDIUM
), Descriptor
->Interfaces
);
475 /* use standard medium */
476 return KsHandleSizedListQuery(Irp
, 1, sizeof(KSPIN_INTERFACE
), &StandardPinInterface
);
480 case KSPROPERTY_PIN_MEDIUMS
:
482 if (Descriptor
->MediumsCount
)
484 /* use mediums provided by driver */
485 return KsHandleSizedListQuery(Irp
, Descriptor
->MediumsCount
, sizeof(KSPIN_MEDIUM
), Descriptor
->Mediums
);
489 /* use standard medium */
490 return KsHandleSizedListQuery(Irp
, 1, sizeof(KSPIN_MEDIUM
), &StandardPinMedium
);
494 case KSPROPERTY_PIN_COMMUNICATION
:
496 Size
= sizeof(KSPIN_COMMUNICATION
);
497 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
499 Irp
->IoStatus
.Information
= Size
;
500 Status
= STATUS_BUFFER_TOO_SMALL
;
504 *((KSPIN_COMMUNICATION
*)Buffer
) = Descriptor
->Communication
;
506 Status
= STATUS_SUCCESS
;
507 Irp
->IoStatus
.Information
= Size
;
510 case KSPROPERTY_PIN_CATEGORY
:
513 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
515 Irp
->IoStatus
.Information
= Size
;
516 Status
= STATUS_BUFFER_TOO_SMALL
;
519 if (Descriptor
->Category
)
521 RtlMoveMemory(Buffer
, Descriptor
->Category
, sizeof(GUID
));
524 Status
= STATUS_SUCCESS
;
525 Irp
->IoStatus
.Information
= Size
;
528 case KSPROPERTY_PIN_NAME
:
529 if (!Descriptor
->Name
)
531 Irp
->IoStatus
.Information
= 0;
532 Status
= STATUS_SUCCESS
;
536 Status
= KspReadMediaCategory((LPGUID
)Descriptor
->Name
, &KeyInfo
);
537 if (!NT_SUCCESS(Status
))
539 Irp
->IoStatus
.Information
= 0;
543 Irp
->IoStatus
.Information
= KeyInfo
->DataLength
+ sizeof(WCHAR
);
545 if (KeyInfo
->DataLength
+ sizeof(WCHAR
) > IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
)
547 Status
= STATUS_BUFFER_OVERFLOW
;
552 RtlMoveMemory(Irp
->UserBuffer
, &KeyInfo
->Data
, KeyInfo
->DataLength
);
553 ((LPWSTR
)Irp
->UserBuffer
)[KeyInfo
->DataLength
/ sizeof(WCHAR
)] = L
'\0';
556 case KSPROPERTY_PIN_PROPOSEDATAFORMAT
:
557 Size
= sizeof(KSDATAFORMAT
);
558 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
560 Irp
->IoStatus
.Information
= Size
;
561 Status
= STATUS_BUFFER_TOO_SMALL
;
564 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
!= sizeof(KSDATAFORMAT_WAVEFORMATEX
))
567 Status
= STATUS_NOT_IMPLEMENTED
;
568 Irp
->IoStatus
.Information
= 0;
572 WaveFormatIn
= (PKSDATAFORMAT_WAVEFORMATEX
)Buffer
;
573 if (!Descriptor
->DataRanges
|| !Descriptor
->DataRangesCount
)
575 Status
= STATUS_UNSUCCESSFUL
;
576 Irp
->IoStatus
.Information
= 0;
579 WaveFormatOut
= (PKSDATARANGE_AUDIO
*)Descriptor
->DataRanges
;
580 for(Index
= 0; Index
< Descriptor
->DataRangesCount
; Index
++)
582 if (WaveFormatOut
[Index
]->DataRange
.FormatSize
!= sizeof(KSDATARANGE_AUDIO
))
588 if (WaveFormatOut
[Index
]->MinimumSampleFrequency
> WaveFormatIn
->WaveFormatEx
.nSamplesPerSec
||
589 WaveFormatOut
[Index
]->MaximumSampleFrequency
< WaveFormatIn
->WaveFormatEx
.nSamplesPerSec
||
590 WaveFormatOut
[Index
]->MinimumBitsPerSample
> WaveFormatIn
->WaveFormatEx
.wBitsPerSample
||
591 WaveFormatOut
[Index
]->MaximumBitsPerSample
< WaveFormatIn
->WaveFormatEx
.wBitsPerSample
||
592 WaveFormatOut
[Index
]->MaximumChannels
< WaveFormatIn
->WaveFormatEx
.nChannels
)
594 Irp
->IoStatus
.Status
= STATUS_NO_MATCH
;
595 Irp
->IoStatus
.Information
= 0;
596 return STATUS_NO_MATCH
;
600 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
601 Irp
->IoStatus
.Information
= 0;
602 return STATUS_SUCCESS
;
605 Status
= STATUS_NO_MATCH
;
606 Irp
->IoStatus
.Information
= 0;
609 DPRINT1("Unhandled property request %x\n", Property
->Id
);
610 Status
= STATUS_NOT_IMPLEMENTED
;
611 Irp
->IoStatus
.Information
= 0;
623 KsPinPropertyHandler(
625 IN PKSPROPERTY Property
,
627 IN ULONG DescriptorsCount
,
628 IN
const KSPIN_DESCRIPTOR
* Descriptor
)
630 return KspPinPropertyHandler(Irp
, Property
, Data
, DescriptorsCount
, Descriptor
, sizeof(KSPIN_DESCRIPTOR
));
636 KSDDKAPI NTSTATUS NTAPI
637 KsPinDataIntersectionEx(
641 IN ULONG DescriptorsCount
,
642 IN
const KSPIN_DESCRIPTOR
* Descriptor
,
643 IN ULONG DescriptorSize
,
644 IN PFNKSINTERSECTHANDLEREX IntersectHandler OPTIONAL
,
645 IN PVOID HandlerContext OPTIONAL
)
648 return STATUS_UNSUCCESSFUL
;
657 KsPinDataIntersection(
661 IN ULONG DescriptorsCount
,
662 IN
const KSPIN_DESCRIPTOR
* Descriptor
,
663 IN PFNKSINTERSECTHANDLER IntersectHandler
)
665 KSMULTIPLE_ITEM
* Item
;
666 KSDATARANGE
* DataRange
;
667 PIO_STACK_LOCATION IoStack
;
672 /* get current irp stack location */
673 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
675 /* calculate minimum data size */
676 Size
= sizeof(KSP_PIN
) + sizeof(KSMULTIPLE_ITEM
) + sizeof(KSDATARANGE
);
677 if (IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
< Size
)
679 /* buffer too small */
680 Irp
->IoStatus
.Information
= Size
;
681 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
682 return STATUS_BUFFER_TOO_SMALL
;
684 /* is pin id out of bounds */
685 if (Pin
->PinId
>= DescriptorsCount
)
688 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
689 Irp
->IoStatus
.Information
= 0;
690 return STATUS_INVALID_PARAMETER
;
694 Item
= (KSMULTIPLE_ITEM
*)(Pin
+ 1);
695 /* get first data range */
696 DataRange
= (KSDATARANGE
*)(Item
+ 1);
697 /* iterate through all data ranges */
698 for(Index
= 0; Index
< Item
->Count
; Index
++, DataRange
++)
700 /* call intersect handler */
701 Status
= IntersectHandler(Irp
, Pin
, DataRange
, Data
);
702 if (NT_SUCCESS(Status
))
704 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< DataRange
->FormatSize
)
706 /* buffer is too small */
707 Irp
->IoStatus
.Information
= DataRange
->FormatSize
;
708 Irp
->IoStatus
.Status
= STATUS_BUFFER_TOO_SMALL
;
709 return STATUS_BUFFER_TOO_SMALL
;
711 RtlMoveMemory(Irp
->UserBuffer
, DataRange
, sizeof(KSDATARANGE
));
712 Irp
->IoStatus
.Information
= sizeof(KSDATARANGE
);
713 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
714 return STATUS_SUCCESS
;
719 Irp
->IoStatus
.Information
= 0;
720 Irp
->IoStatus
.Status
= STATUS_NO_MATCH
;
721 return STATUS_NO_MATCH
;
731 KsHandleSizedListQuery(
733 IN ULONG DataItemsCount
,
734 IN ULONG DataItemSize
,
735 IN
const VOID
* DataItems
)
738 PIO_STACK_LOCATION IoStack
;
739 PKSMULTIPLE_ITEM Item
;
741 /* get current irp stack location */
742 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
745 Size
= DataItemSize
* DataItemsCount
+ sizeof(KSMULTIPLE_ITEM
);
747 /* get multiple item */
748 Item
= (PKSMULTIPLE_ITEM
)Irp
->UserBuffer
;
750 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== 0)
752 /* buffer too small */
753 Irp
->IoStatus
.Information
= Size
;
755 return STATUS_BUFFER_OVERFLOW
;
758 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== sizeof(ULONG
))
760 /* store just the size */
762 Irp
->IoStatus
.Information
= sizeof(ULONG
);
764 return STATUS_SUCCESS
;
768 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< sizeof(KSMULTIPLE_ITEM
))
770 /* buffer too small */
771 return STATUS_BUFFER_TOO_SMALL
;
774 Item
->Count
= DataItemsCount
;
775 Item
->Size
= DataItemSize
;
777 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
== sizeof(KSMULTIPLE_ITEM
))
779 /* buffer can only hold the length descriptor */
780 Irp
->IoStatus
.Information
= sizeof(KSMULTIPLE_ITEM
);
781 return STATUS_SUCCESS
;
784 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
>= Size
)
787 RtlMoveMemory((PVOID
)(Item
+ 1), DataItems
, DataItemSize
* DataItemsCount
);
789 Irp
->IoStatus
.Information
= Size
;
791 return STATUS_SUCCESS
;
795 /* buffer too small */
796 return STATUS_BUFFER_TOO_SMALL
;