[WIN32SS] Improve the FILE header section. Brought to you by Adam Stachowicz. CORE...
[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: win32ss/gdi/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 PVOID pvEvent;
123 NTSTATUS Status;
124
125 /* Allocate memory for the event structure */
126 EngEvent = ExAllocatePoolWithTag(NonPagedPool,
127 sizeof(ENG_EVENT),
128 GDITAG_ENG_EVENT);
129 if (!EngEvent) return NULL;
130
131 /* Zero it out */
132 EngEvent->fFlags = 0;
133 EngEvent->pKEvent = NULL;
134
135 /* Create a handle, and have Ob fill out the pKEvent field */
136 Status = ObReferenceObjectByHandle(hUserObject,
137 EVENT_ALL_ACCESS,
138 *ExEventObjectType,
139 UserMode,
140 &pvEvent,
141 NULL);
142 if (NT_SUCCESS(Status))
143 {
144 /* Pulse the event and set that it's mapped by user */
145 KePulseEvent(pvEvent, EVENT_INCREMENT, FALSE);
146 EngEvent->pKEvent = pvEvent;
147 EngEvent->fFlags |= ENG_EVENT_USERMAPPED;
148 }
149 else
150 {
151 /* Free the allocation */
152 ExFreePoolWithTag(EngEvent, GDITAG_ENG_EVENT);
153 EngEvent = NULL;
154 }
155
156 /* Support legacy interface */
157 if (Reserved1) *(PVOID*)Reserved1 = EngEvent;
158 return EngEvent;
159 }
160
161 BOOL
162 APIENTRY
163 EngUnmapEvent(
164 _In_ PEVENT Event)
165 {
166 /* Must be a usermapped event */
167 if (!(Event->fFlags & ENG_EVENT_USERMAPPED)) return FALSE;
168
169 /* Dereference the object, destroying it */
170 ObDereferenceObject(Event->pKEvent);
171
172 /* Free the Eng object */
173 ExFreePoolWithTag(Event, GDITAG_ENG_EVENT);
174 return TRUE;
175 }
176
177 BOOL
178 APIENTRY
179 EngWaitForSingleObject(
180 _In_ PEVENT Event,
181 _In_opt_ PLARGE_INTEGER TimeOut)
182 {
183 NTSTATUS Status;
184 DPRINT("EngWaitForSingleObject(%p %I64d)\n", Event, TimeOut->QuadPart);
185
186 /* Validate parameters */
187 if (!Event) return FALSE;
188
189 /* Check if it's a usermapped event and fail in that case */
190 if (Event->fFlags & ENG_EVENT_USERMAPPED)
191 {
192 /* Disallow deletion of usermapped events */
193 DPRINT1("Driver attempted to wait on a usermapped event!\n");
194 return FALSE;
195 }
196
197 /* Wait for the event */
198 Status = KeWaitForSingleObject(Event->pKEvent,
199 Executive,
200 KernelMode,
201 FALSE,
202 TimeOut);
203
204 /* Check if there is a failure or a timeout */
205 return NT_SUCCESS(Status);
206 }
207
208 /* EOF */