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 */ 209