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