2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/event.c
5 * PURPOSE: KS Event functions
6 * PROGRAMMER: Johannes Anderwald
12 KspSynchronizedEventRoutine(
13 IN KSEVENTS_LOCKTYPE EventsFlags
,
15 IN PKSEVENT_SYNCHRONIZED_ROUTINE SynchronizedRoutine
,
18 BOOLEAN Result
= FALSE
;
21 if (EventsFlags
== KSEVENTS_NONE
)
23 /* no synchronization required */
24 Result
= SynchronizedRoutine(Ctx
);
26 else if (EventsFlags
== KSEVENTS_SPINLOCK
)
29 KeAcquireSpinLock((PKSPIN_LOCK
)EventsLock
, &OldLevel
);
30 Result
= SynchronizedRoutine(Ctx
);
31 KeReleaseSpinLock((PKSPIN_LOCK
)EventsLock
, OldLevel
);
33 else if (EventsFlags
== KSEVENTS_MUTEX
)
36 KeWaitForSingleObject(EventsLock
, Executive
, KernelMode
, FALSE
, NULL
);
37 Result
= SynchronizedRoutine(Ctx
);
38 KeReleaseMutex((PRKMUTEX
)EventsLock
, FALSE
);
40 else if (EventsFlags
== KSEVENTS_FMUTEX
)
42 /* use a fast mutex */
43 ExAcquireFastMutex((PFAST_MUTEX
)EventsLock
);
44 Result
= SynchronizedRoutine(Ctx
);
45 ExReleaseFastMutex((PFAST_MUTEX
)EventsLock
);
47 else if (EventsFlags
== KSEVENTS_FMUTEXUNSAFE
)
49 /* acquire fast mutex unsafe */
50 KeEnterCriticalRegion();
51 ExAcquireFastMutexUnsafe((PFAST_MUTEX
)EventsLock
);
52 Result
= SynchronizedRoutine(Ctx
);
53 ExReleaseFastMutexUnsafe((PFAST_MUTEX
)EventsLock
);
54 KeLeaveCriticalRegion();
56 else if (EventsFlags
== KSEVENTS_INTERRUPT
)
58 /* use interrupt for locking */
59 Result
= KeSynchronizeExecution((PKINTERRUPT
)EventsLock
, (PKSYNCHRONIZE_ROUTINE
)SynchronizedRoutine
, (PVOID
)Ctx
);
61 else if (EventsFlags
== KSEVENTS_ERESOURCE
)
63 /* use an eresource */
64 KeEnterCriticalRegion();
65 ExAcquireResourceExclusiveLite((PERESOURCE
)EventsLock
, TRUE
);
66 Result
= SynchronizedRoutine(Ctx
);
67 ExReleaseResourceLite((PERESOURCE
)EventsLock
);
68 KeLeaveCriticalRegion();
83 IN ULONG EventSetsCount
,
84 IN KSEVENT_SET
* EventSet
,
85 IN OUT PLIST_ENTRY EventsList OPTIONAL
,
86 IN KSEVENTS_LOCKTYPE EventsFlags OPTIONAL
,
87 IN PVOID EventsLock OPTIONAL
)
90 return STATUS_SUCCESS
;
99 KsEnableEventWithAllocator(
101 IN ULONG EventSetsCount
,
102 IN PKSEVENT_SET EventSet
,
103 IN OUT PLIST_ENTRY EventsList OPTIONAL
,
104 IN KSEVENTS_LOCKTYPE EventsFlags OPTIONAL
,
105 IN PVOID EventsLock OPTIONAL
,
106 IN PFNKSALLOCATOR Allocator OPTIONAL
,
107 IN ULONG EventItemSize OPTIONAL
)
110 return STATUS_UNSUCCESSFUL
;
118 PIO_STACK_LOCATION IoStack
;
119 PKSEVENTDATA EventData
;
120 PKSEVENT_ENTRY EventEntry
;
123 /* get current irp stack location */
124 IoStack
= IoGetCurrentIrpStackLocation(Ctx
->Irp
);
127 EventData
= (PKSEVENTDATA
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
129 if (!Ctx
|| !Ctx
->List
|| !Ctx
->FileObject
|| !Ctx
->Irp
)
131 /* invalid parameter */
135 /* point to first entry */
136 Entry
= Ctx
->List
->Flink
;
138 while(Entry
!= Ctx
->List
)
140 /* get event entry */
141 EventEntry
= (PKSEVENT_ENTRY
)CONTAINING_RECORD(Entry
, KSEVENT_ENTRY
, ListEntry
);
143 if (EventEntry
->EventData
== EventData
&& EventEntry
->FileObject
== Ctx
->FileObject
)
145 /* found the entry */
146 RemoveEntryList(&EventEntry
->ListEntry
);
147 Ctx
->EventEntry
= EventEntry
;
151 /* move to next item */
152 Entry
= Entry
->Flink
;
154 /* entry not found */
166 IN OUT PLIST_ENTRY EventsList
,
167 IN KSEVENTS_LOCKTYPE EventsFlags
,
170 PIO_STACK_LOCATION IoStack
;
173 /* get current irp stack location */
174 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
176 /* is there a event entry */
177 if (IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(KSEVENTDATA
))
179 if (IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
== 0)
181 /* caller wants to free event items */
182 KsFreeEventList(IoStack
->FileObject
, EventsList
, EventsFlags
, EventsLock
);
183 return STATUS_SUCCESS
;
185 /* invalid parameter */
186 return STATUS_INVALID_BUFFER_SIZE
;
189 /* setup event ctx */
190 Ctx
.List
= EventsList
;
191 Ctx
.FileObject
= IoStack
->FileObject
;
193 Ctx
.EventEntry
= NULL
;
195 if (KspSynchronizedEventRoutine(EventsFlags
, EventsLock
, KspDisableEvent
, &Ctx
))
197 /* was the event entry found */
201 KsDiscardEvent(Ctx
.EventEntry
);
202 return STATUS_SUCCESS
;
204 /* event was not found */
205 return STATUS_UNSUCCESSFUL
;
208 /* invalid parameters */
209 return STATUS_INVALID_PARAMETER
;
219 IN PKSEVENT_ENTRY EventEntry
)
231 PKSEVENT_ENTRY EventEntry
;
233 /* check valid input */
234 if (!Ctx
|| !Ctx
->List
)
237 if (IsListEmpty(Ctx
->List
))
240 /* remove first entry */
241 Entry
= RemoveHeadList(Ctx
->List
);
244 /* list is empty, bye-bye */
248 /* get event entry */
249 EventEntry
= (PKSEVENT_ENTRY
)CONTAINING_RECORD(Entry
, KSEVENT_ENTRY
, ListEntry
);
251 /* store event entry */
252 Ctx
->EventEntry
= EventEntry
;
265 IN PFILE_OBJECT FileObject
,
266 IN OUT PLIST_ENTRY EventsList
,
267 IN KSEVENTS_LOCKTYPE EventsFlags
,
272 /* setup event ctx */
273 Ctx
.List
= EventsList
;
274 Ctx
.FileObject
= FileObject
;
275 Ctx
.EventEntry
= NULL
;
277 while(KspSynchronizedEventRoutine(EventsFlags
, EventsLock
, KspFreeEventList
, &Ctx
))
281 KsDiscardEvent(Ctx
.EventEntry
);
294 IN PKSEVENT_ENTRY EntryEvent
)
297 return STATUS_UNSUCCESSFUL
;
307 IN PKSEVENT_ENTRY EventEntry
,
312 return STATUS_UNSUCCESSFUL
;
322 IN GUID
* Set OPTIONAL
,
324 IN PLIST_ENTRY EventsList
,
325 IN KSEVENTS_LOCKTYPE EventsFlags
,
339 IN PKSEVENT_ENTRY EventEntry
)
341 PKSBASIC_HEADER Header
= (PKSBASIC_HEADER
)((ULONG_PTR
)Object
- sizeof(KSBASIC_HEADER
));
343 ExInterlockedInsertTailList(&Header
->EventList
, &EventEntry
->ListEntry
, &Header
->EventListLock
);
351 KsDefaultAddEventHandler(
353 IN PKSEVENTDATA EventData
,
354 IN OUT PKSEVENT_ENTRY EventEntry
)
356 PIO_STACK_LOCATION IoStack
;
357 PKSIOBJECT_HEADER ObjectHeader
;
358 PKSBASIC_HEADER Header
;
360 /* first get the io stack location */
361 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
363 /* now get the object header */
364 ObjectHeader
=(PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
367 ASSERT(ObjectHeader
->ObjectType
);
369 /* obtain basic header */
370 Header
= (PKSBASIC_HEADER
)((ULONG_PTR
)ObjectHeader
->ObjectType
- sizeof(KSBASIC_HEADER
));
372 /* now insert the event entry */
373 ExInterlockedInsertTailList(&Header
->EventList
, &EventEntry
->ListEntry
, &Header
->EventListLock
);
376 return STATUS_SUCCESS
;
389 IN
const GUID
* EventSet OPTIONAL
,
392 IN PVOID Data OPTIONAL
,
393 IN PFNKSGENERATEEVENTCALLBACK CallBack OPTIONAL
,
394 IN PVOID CallBackContext OPTIONAL
)