2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/event.c
5 * PURPOSE: KS property handling functions
6 * PROGRAMMER: Johannes Anderwald
14 IN PIO_STATUS_BLOCK IoStatus
,
15 IN
const KSPROPERTY_SET
* PropertySet
,
16 IN ULONG PropertySetCount
,
17 IN PKSPROPERTY Property
,
18 IN ULONG InputBufferLength
,
19 IN ULONG OutputBufferLength
,
20 OUT PFNKSHANDLER
*PropertyHandler
)
22 ULONG Index
, ItemIndex
;
24 for(Index
= 0; Index
< PropertySetCount
; Index
++)
26 if (IsEqualGUIDAligned(&Property
->Set
, PropertySet
[Index
].Set
))
28 for(ItemIndex
= 0; ItemIndex
< PropertySet
[Index
].PropertiesCount
; ItemIndex
++)
30 if (PropertySet
[Index
].PropertyItem
[ItemIndex
].PropertyId
== Property
->Id
)
32 if (PropertySet
[Index
].PropertyItem
[ItemIndex
].MinProperty
> InputBufferLength
)
34 /* too small input buffer */
35 IoStatus
->Information
= PropertySet
[Index
].PropertyItem
[ItemIndex
].MinProperty
;
36 return STATUS_INVALID_PARAMETER
;
39 if (PropertySet
[Index
].PropertyItem
[ItemIndex
].MinData
> OutputBufferLength
)
41 /* too small output buffer */
42 IoStatus
->Information
= PropertySet
[Index
].PropertyItem
[ItemIndex
].MinData
;
43 return STATUS_BUFFER_TOO_SMALL
;
46 if (Property
->Flags
& KSPROPERTY_TYPE_SET
)
47 *PropertyHandler
= PropertySet
[Index
].PropertyItem
[ItemIndex
].SetPropertyHandler
;
49 if (Property
->Flags
& KSPROPERTY_TYPE_GET
)
50 *PropertyHandler
= PropertySet
[Index
].PropertyItem
[ItemIndex
].GetPropertyHandler
;
52 return STATUS_SUCCESS
;
57 return STATUS_NOT_FOUND
;
64 IN ULONG PropertySetsCount
,
65 IN
const KSPROPERTY_SET
* PropertySet
,
66 IN PFNKSALLOCATOR Allocator OPTIONAL
,
67 IN ULONG PropertyItemSize OPTIONAL
)
70 PIO_STACK_LOCATION IoStack
;
72 PFNKSHANDLER PropertyHandler
;
74 /* get current irp stack */
75 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
77 /* check if inputbuffer at least holds KSPROPERTY item */
78 if (IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(KSPROPERTY
))
80 /* invalid parameter */
81 Irp
->IoStatus
.Information
= sizeof(KSPROPERTY
);
82 return STATUS_INVALID_BUFFER_SIZE
;
85 /* FIXME probe the input / output buffer if from user mode */
88 /* get input property request */
89 Property
= (PKSPROPERTY
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
92 ASSERT(PropertyItemSize
== 0 || PropertyItemSize
== sizeof(KSPROPERTY_ITEM
));
93 if (IsEqualGUIDAligned(&Property
->Set
, &KSPROPSETID_Topology
))
95 /* use KsTopologyPropertyHandler for this business */
96 return STATUS_INVALID_PARAMETER
;
99 /* find the property handler */
100 Status
= FindPropertyHandler(&Irp
->IoStatus
, PropertySet
, PropertySetsCount
, Property
, IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, &PropertyHandler
);
102 if (NT_SUCCESS(Status
))
104 /* call property handler */
105 Status
= PropertyHandler(Irp
, Property
, Irp
->UserBuffer
);
107 if (Status
== STATUS_BUFFER_TOO_SMALL
)
109 /* output buffer is too small */
112 /* allocate the requested amount */
113 Status
= Allocator(Irp
, Irp
->IoStatus
.Information
, FALSE
);
115 /* check if the block was allocated */
116 if (!NT_SUCCESS(Status
))
119 return STATUS_INSUFFICIENT_RESOURCES
;
122 /* re-call property handler */
123 Status
= PropertyHandler(Irp
, Property
, Irp
->UserBuffer
);
140 IN ULONG PropertySetsCount
,
141 IN
const KSPROPERTY_SET
* PropertySet
)
143 return KspPropertyHandler(Irp
, PropertySetsCount
, PropertySet
, NULL
, 0);
153 KsPropertyHandlerWithAllocator(
155 IN ULONG PropertySetsCount
,
156 IN PKSPROPERTY_SET PropertySet
,
157 IN PFNKSALLOCATOR Allocator OPTIONAL
,
158 IN ULONG PropertyItemSize OPTIONAL
)
160 return KspPropertyHandler(Irp
, PropertySetsCount
, PropertySet
, Allocator
, PropertyItemSize
);
164 FindFastPropertyHandler(
165 IN ULONG FastIoCount
,
166 IN
const KSFASTPROPERTY_ITEM
* FastIoTable
,
167 IN PKSPROPERTY PropertyId
,
168 OUT PFNKSFASTHANDLER
* FastPropertyHandler
)
172 /* iterate through all items */
173 for(Index
= 0; Index
< FastIoCount
; Index
++)
175 if (PropertyId
->Id
== FastIoTable
[Index
].PropertyId
)
177 if (PropertyId
->Flags
& KSPROPERTY_TYPE_SET
)
179 if (FastIoTable
[Index
].SetSupported
)
181 *FastPropertyHandler
= FastIoTable
[Index
].SetPropertyHandler
;
182 return STATUS_SUCCESS
;
186 if (PropertyId
->Flags
& KSPROPERTY_TYPE_GET
)
188 if (FastIoTable
[Index
].GetSupported
)
190 *FastPropertyHandler
= FastIoTable
[Index
].GetPropertyHandler
;
191 return STATUS_SUCCESS
;
197 /* no fast property handler found */
198 return STATUS_NOT_FOUND
;
208 KsFastPropertyHandler(
209 IN PFILE_OBJECT FileObject
,
210 IN PKSPROPERTY UNALIGNED Property
,
211 IN ULONG PropertyLength
,
212 IN OUT PVOID UNALIGNED Data
,
214 OUT PIO_STATUS_BLOCK IoStatus
,
215 IN ULONG PropertySetsCount
,
216 IN
const KSPROPERTY_SET
* PropertySet
)
218 KSPROPERTY PropRequest
;
219 KPROCESSOR_MODE Mode
;
220 NTSTATUS Status
= STATUS_SUCCESS
;
222 PFNKSFASTHANDLER FastPropertyHandler
;
224 if (PropertyLength
< sizeof(KSPROPERTY
))
226 /* invalid request */
230 /* get previous mode */
231 Mode
= ExGetPreviousMode();
233 if (Mode
== KernelMode
)
236 RtlMoveMemory(&PropRequest
, Property
, sizeof(KSPROPERTY
));
240 /* need to probe the buffer */
243 ProbeForRead(Property
, sizeof(KSPROPERTY
), sizeof(UCHAR
));
244 RtlMoveMemory(&PropRequest
, Property
, sizeof(KSPROPERTY
));
246 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
248 /* Exception, get the error code */
249 Status
= _SEH2_GetExceptionCode();
252 if (!NT_SUCCESS(Status
))
256 /* are there any property sets provided */
257 if (PropertySetsCount
)
259 /* iterate through all property sets count */
263 /* does the property id match */
264 if (IsEqualGUIDAligned(PropertySet
[Index
].Set
, &PropRequest
.Set
))
266 /* try to find a fast property handler */
267 Status
= FindFastPropertyHandler(PropertySet
[Index
].FastIoCount
, PropertySet
[Index
].FastIoTable
, &PropRequest
, &FastPropertyHandler
);
269 if (NT_SUCCESS(Status
))
271 /* call fast property handler */
272 ASSERT(PropertyLength
== sizeof(KSPROPERTY
)); /* FIXME check if property length is bigger -> copy params */
273 ASSERT(Mode
== KernelMode
); /* FIXME need to probe usermode output buffer */
274 return FastPropertyHandler(FileObject
, &PropRequest
, sizeof(KSPROPERTY
), Data
, DataLength
, IoStatus
);
277 /* move to next item */
279 }while(Index
< PropertySetsCount
);
290 KsDispatchSpecificProperty(
292 IN PFNKSHANDLER Handler
)
294 PIO_STACK_LOCATION IoStack
;
296 /* get current irp stack location */
297 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
299 return Handler(Irp
, IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
, Irp
->UserBuffer
);