[CONSRV]
[reactos.git] / win32ss / gdi / eng / engevent.c
1 /*
2 * PROJECT: ReactOS Win32K
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: subsystems/win32/win32k/eng/engevent.c
5 * PURPOSE: Event Support Routines
6 * PROGRAMMERS: Aleksey Bragin <aleksey@reactos.org>
7 * ReactOS Portable Systems Group
8 */
9
10 /* INCLUDES *******************************************************************/
11
12 #include <win32k.h>
13
14 #include <ntddvdeo.h>
15
16 #define NDEBUG
17 #include <debug.h>
18
19 /* PUBLIC FUNCTIONS ***********************************************************/
20
21 _Must_inspect_result_
22 _Success_(return != FALSE)
23 BOOL
24 APIENTRY
25 EngCreateEvent(
26 _Outptr_ PEVENT *ppEvent)
27 {
28 BOOLEAN Result = TRUE;
29 PENG_EVENT EngEvent;
30
31 /* Allocate memory for the event structure */
32 EngEvent = ExAllocatePoolWithTag(NonPagedPool,
33 sizeof(ENG_EVENT) + sizeof(KEVENT),
34 GDITAG_ENG_EVENT);
35 if (EngEvent)
36 {
37 /* Set KEVENT pointer */
38 EngEvent->fFlags = 0;
39 EngEvent->pKEvent = EngEvent + 1;
40
41 /* Initialize the kernel event */
42 KeInitializeEvent(EngEvent->pKEvent,
43 SynchronizationEvent,
44 FALSE);
45
46 /* Pass pointer to our structure to the caller */
47 *ppEvent = EngEvent;
48 DPRINT("EngCreateEvent() created %p\n", EngEvent);
49 }
50 else
51 {
52 /* Out of memory */
53 DPRINT("EngCreateEvent() failed\n");
54 Result = FALSE;
55 }
56
57 /* Return result */
58 return Result;
59 }
60
61 BOOL
62 APIENTRY
63 EngDeleteEvent(
64 _In_ _Post_ptr_invalid_ PEVENT Event)
65 {
66 DPRINT("EngDeleteEvent(%p)\n", Event);
67
68 /* Check if it's a usermapped event */
69 if (Event->fFlags & ENG_EVENT_USERMAPPED)
70 {
71 /* Disallow deletion of usermapped events */
72 DPRINT1("Driver attempted to delete a usermapped event!\n");
73 return FALSE;
74 }
75
76 /* Free the allocated memory */
77 ExFreePoolWithTag(Event, GDITAG_ENG_EVENT);
78
79 /* Return success */
80 return TRUE;
81 }
82
83 VOID
84 APIENTRY
85 EngClearEvent(
86 _In_ PEVENT Event)
87 {
88 /* Clear the event */
89 KeClearEvent(Event->pKEvent);
90 }
91
92 LONG
93 APIENTRY
94 EngSetEvent(
95 _In_ PEVENT Event)
96 {
97 /* Set the event */
98 return KeSetEvent(Event->pKEvent,
99 IO_NO_INCREMENT,
100 FALSE);
101 }
102
103 LONG
104 APIENTRY
105 EngReadStateEvent(
106 _In_ PEVENT Event)
107 {
108 /* Read the event state */
109 return KeReadStateEvent(Event->pKEvent);
110 }
111
112 PEVENT
113 APIENTRY
114 EngMapEvent(
115 _In_ HDEV hDev,
116 _In_ HANDLE hUserObject,
117 _Reserved_ PVOID Reserved1,
118 _Reserved_ PVOID Reserved2,
119 _Reserved_ PVOID Reserved3)
120 {
121 PENG_EVENT EngEvent;
122 NTSTATUS Status;
123
124 /* Allocate memory for the event structure */
125 EngEvent = ExAllocatePoolWithTag(NonPagedPool,
126 sizeof(ENG_EVENT),
127 GDITAG_ENG_EVENT);
128 if (!EngEvent) return NULL;
129
130 /* Zero it out */
131 EngEvent->fFlags = 0;
132 EngEvent->pKEvent = NULL;
133
134 /* Create a handle, and have Ob fill out the pKEvent field */
135 Status = ObReferenceObjectByHandle(EngEvent,
136 EVENT_ALL_ACCESS,
137 *ExEventObjectType,
138 UserMode,
139 &EngEvent->pKEvent,
140 NULL);
141 if (NT_SUCCESS(Status))
142 {
143 /* Pulse the event and set that it's mapped by user */
144 KePulseEvent(EngEvent->pKEvent, EVENT_INCREMENT, FALSE);
145 EngEvent->fFlags |= ENG_EVENT_USERMAPPED;
146 }
147 else
148 {
149 /* Free the allocation */
150 ExFreePoolWithTag(EngEvent, GDITAG_ENG_EVENT);
151 EngEvent = NULL;
152 }
153
154 /* Support legacy interface */
155 if (Reserved1) *(PVOID*)Reserved1 = EngEvent;
156 return EngEvent;
157 }
158
159 BOOL
160 APIENTRY
161 EngUnmapEvent(
162 _In_ PEVENT Event)
163 {
164 /* Must be a usermapped event */
165 if (!(Event->fFlags & ENG_EVENT_USERMAPPED)) return FALSE;
166
167 /* Dereference the object, destroying it */
168 ObDereferenceObject(Event->pKEvent);
169
170 /* Free the Eng object */
171 ExFreePoolWithTag(Event, GDITAG_ENG_EVENT);
172 return TRUE;
173 }
174
175 BOOL
176 APIENTRY
177 EngWaitForSingleObject(
178 _In_ PEVENT Event,
179 _In_opt_ PLARGE_INTEGER TimeOut)
180 {
181 NTSTATUS Status;
182 DPRINT("EngWaitForSingleObject(%p %I64d)\n", Event, TimeOut->QuadPart);
183
184 /* Validate parameters */
185 if (!Event) return FALSE;
186
187 /* Check if it's a usermapped event and fail in that case */
188 if (Event->fFlags & ENG_EVENT_USERMAPPED)
189 {
190 /* Disallow deletion of usermapped events */
191 DPRINT1("Driver attempted to wait on a usermapped event!\n");
192 return FALSE;
193 }
194
195 /* Wait for the event */
196 Status = KeWaitForSingleObject(Event->pKEvent,
197 Executive,
198 KernelMode,
199 FALSE,
200 TimeOut);
201
202 /* Check if there is a failure or a timeout */
203 return NT_SUCCESS(Status);
204 }
205
206 /* EOF */