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