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