Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenevent.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Kernel 00004 * FILE: ntoskrnl/ex/event.c 00005 * PURPOSE: Event support 00006 * PROGRAMMERS: Alex Ionescu(alex@relsoft.net) 00007 * Thomas Weidenmueller 00008 */ 00009 00010 /* INCLUDES *****************************************************************/ 00011 00012 #include <ntoskrnl.h> 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 #if defined (ALLOC_PRAGMA) 00017 #pragma alloc_text(INIT, ExpInitializeEventImplementation) 00018 #endif 00019 00020 /* GLOBALS *******************************************************************/ 00021 00022 POBJECT_TYPE _ExEventObjectType = NULL; 00023 00024 GENERIC_MAPPING ExpEventMapping = 00025 { 00026 STANDARD_RIGHTS_READ | SYNCHRONIZE | EVENT_QUERY_STATE, 00027 STANDARD_RIGHTS_WRITE | SYNCHRONIZE | EVENT_MODIFY_STATE, 00028 STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | EVENT_QUERY_STATE, 00029 EVENT_ALL_ACCESS}; 00030 00031 static const INFORMATION_CLASS_INFO ExEventInfoClass[] = 00032 { 00033 /* EventBasicInformation */ 00034 ICI_SQ_SAME( sizeof(EVENT_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY), 00035 }; 00036 00037 /* FUNCTIONS *****************************************************************/ 00038 00039 VOID 00040 INIT_FUNCTION 00041 NTAPI 00042 ExpInitializeEventImplementation(VOID) 00043 { 00044 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; 00045 UNICODE_STRING Name; 00046 DPRINT("Creating Event Object Type\n"); 00047 00048 /* Create the Event Object Type */ 00049 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); 00050 RtlInitUnicodeString(&Name, L"Event"); 00051 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); 00052 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KEVENT); 00053 ObjectTypeInitializer.GenericMapping = ExpEventMapping; 00054 ObjectTypeInitializer.PoolType = NonPagedPool; 00055 ObjectTypeInitializer.ValidAccessMask = EVENT_ALL_ACCESS; 00056 ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ExEventObjectType); 00057 } 00058 00059 /* 00060 * @implemented 00061 */ 00062 NTSTATUS 00063 NTAPI 00064 NtClearEvent(IN HANDLE EventHandle) 00065 { 00066 PKEVENT Event; 00067 NTSTATUS Status; 00068 PAGED_CODE(); 00069 00070 /* Reference the Object */ 00071 Status = ObReferenceObjectByHandle(EventHandle, 00072 EVENT_MODIFY_STATE, 00073 ExEventObjectType, 00074 ExGetPreviousMode(), 00075 (PVOID*)&Event, 00076 NULL); 00077 00078 /* Check for Success */ 00079 if(NT_SUCCESS(Status)) 00080 { 00081 /* Clear the Event and Dereference */ 00082 KeClearEvent(Event); 00083 ObDereferenceObject(Event); 00084 } 00085 00086 /* Return Status */ 00087 return Status; 00088 } 00089 00090 /* 00091 * @implemented 00092 */ 00093 NTSTATUS 00094 NTAPI 00095 NtCreateEvent(OUT PHANDLE EventHandle, 00096 IN ACCESS_MASK DesiredAccess, 00097 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, 00098 IN EVENT_TYPE EventType, 00099 IN BOOLEAN InitialState) 00100 { 00101 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); 00102 PKEVENT Event; 00103 HANDLE hEvent; 00104 NTSTATUS Status; 00105 PAGED_CODE(); 00106 DPRINT("NtCreateEvent(0x%p, 0x%x, 0x%p)\n", 00107 EventHandle, DesiredAccess, ObjectAttributes); 00108 00109 /* Check if we were called from user-mode */ 00110 if (PreviousMode != KernelMode) 00111 { 00112 /* Enter SEH Block */ 00113 _SEH2_TRY 00114 { 00115 /* Check handle pointer */ 00116 ProbeForWriteHandle(EventHandle); 00117 } 00118 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00119 { 00120 /* Return the exception code */ 00121 _SEH2_YIELD(return _SEH2_GetExceptionCode()); 00122 } 00123 _SEH2_END; 00124 } 00125 00126 /* Create the Object */ 00127 Status = ObCreateObject(PreviousMode, 00128 ExEventObjectType, 00129 ObjectAttributes, 00130 PreviousMode, 00131 NULL, 00132 sizeof(KEVENT), 00133 0, 00134 0, 00135 (PVOID*)&Event); 00136 00137 /* Check for Success */ 00138 if(NT_SUCCESS(Status)) 00139 { 00140 /* Initalize the Event */ 00141 KeInitializeEvent(Event, 00142 EventType, 00143 InitialState); 00144 00145 /* Insert it */ 00146 Status = ObInsertObject((PVOID)Event, 00147 NULL, 00148 DesiredAccess, 00149 0, 00150 NULL, 00151 &hEvent); 00152 00153 /* Check for success */ 00154 if(NT_SUCCESS(Status)) 00155 { 00156 /* Enter SEH for return */ 00157 _SEH2_TRY 00158 { 00159 /* Return the handle to the caller */ 00160 *EventHandle = hEvent; 00161 } 00162 _SEH2_EXCEPT(ExSystemExceptionFilter()) 00163 { 00164 /* Get the exception code */ 00165 Status = _SEH2_GetExceptionCode(); 00166 } 00167 _SEH2_END; 00168 } 00169 } 00170 00171 /* Return Status */ 00172 return Status; 00173 } 00174 00175 /* 00176 * @implemented 00177 */ 00178 NTSTATUS 00179 NTAPI 00180 NtOpenEvent(OUT PHANDLE EventHandle, 00181 IN ACCESS_MASK DesiredAccess, 00182 IN POBJECT_ATTRIBUTES ObjectAttributes) 00183 { 00184 HANDLE hEvent; 00185 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); 00186 NTSTATUS Status; 00187 PAGED_CODE(); 00188 DPRINT("NtOpenEvent(0x%p, 0x%x, 0x%p)\n", 00189 EventHandle, DesiredAccess, ObjectAttributes); 00190 00191 /* Check if we were called from user-mode */ 00192 if (PreviousMode != KernelMode) 00193 { 00194 /* Enter SEH Block */ 00195 _SEH2_TRY 00196 { 00197 /* Check handle pointer */ 00198 ProbeForWriteHandle(EventHandle); 00199 } 00200 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00201 { 00202 /* Return the exception code */ 00203 _SEH2_YIELD(return _SEH2_GetExceptionCode()); 00204 } 00205 _SEH2_END; 00206 } 00207 00208 /* Open the Object */ 00209 Status = ObOpenObjectByName(ObjectAttributes, 00210 ExEventObjectType, 00211 PreviousMode, 00212 NULL, 00213 DesiredAccess, 00214 NULL, 00215 &hEvent); 00216 00217 /* Check for success */ 00218 if (NT_SUCCESS(Status)) 00219 { 00220 /* Enter SEH for return */ 00221 _SEH2_TRY 00222 { 00223 /* Return the handle to the caller */ 00224 *EventHandle = hEvent; 00225 } 00226 _SEH2_EXCEPT(ExSystemExceptionFilter()) 00227 { 00228 /* Get the exception code */ 00229 Status = _SEH2_GetExceptionCode(); 00230 } 00231 _SEH2_END; 00232 } 00233 00234 /* Return status */ 00235 return Status; 00236 } 00237 00238 /* 00239 * @implemented 00240 */ 00241 NTSTATUS 00242 NTAPI 00243 NtPulseEvent(IN HANDLE EventHandle, 00244 OUT PLONG PreviousState OPTIONAL) 00245 { 00246 PKEVENT Event; 00247 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); 00248 NTSTATUS Status; 00249 PAGED_CODE(); 00250 DPRINT("NtPulseEvent(EventHandle 0%x PreviousState 0%x)\n", 00251 EventHandle, PreviousState); 00252 00253 /* Check if we were called from user-mode */ 00254 if((PreviousState) && (PreviousMode != KernelMode)) 00255 { 00256 /* Entry SEH Block */ 00257 _SEH2_TRY 00258 { 00259 /* Make sure the state pointer is valid */ 00260 ProbeForWriteLong(PreviousState); 00261 } 00262 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00263 { 00264 /* Return the exception code */ 00265 _SEH2_YIELD(return _SEH2_GetExceptionCode()); 00266 } 00267 _SEH2_END; 00268 } 00269 00270 /* Open the Object */ 00271 Status = ObReferenceObjectByHandle(EventHandle, 00272 EVENT_MODIFY_STATE, 00273 ExEventObjectType, 00274 PreviousMode, 00275 (PVOID*)&Event, 00276 NULL); 00277 00278 /* Check for success */ 00279 if(NT_SUCCESS(Status)) 00280 { 00281 /* Pulse the Event */ 00282 LONG Prev = KePulseEvent(Event, EVENT_INCREMENT, FALSE); 00283 ObDereferenceObject(Event); 00284 00285 /* Check if caller wants the old state back */ 00286 if(PreviousState) 00287 { 00288 /* Entry SEH Block for return */ 00289 _SEH2_TRY 00290 { 00291 /* Return previous state */ 00292 *PreviousState = Prev; 00293 } 00294 _SEH2_EXCEPT(ExSystemExceptionFilter()) 00295 { 00296 /* Get the exception code */ 00297 Status = _SEH2_GetExceptionCode(); 00298 } 00299 _SEH2_END; 00300 } 00301 } 00302 00303 /* Return Status */ 00304 return Status; 00305 } 00306 00307 /* 00308 * @implemented 00309 */ 00310 NTSTATUS 00311 NTAPI 00312 NtQueryEvent(IN HANDLE EventHandle, 00313 IN EVENT_INFORMATION_CLASS EventInformationClass, 00314 OUT PVOID EventInformation, 00315 IN ULONG EventInformationLength, 00316 OUT PULONG ReturnLength OPTIONAL) 00317 { 00318 PKEVENT Event; 00319 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); 00320 NTSTATUS Status; 00321 PEVENT_BASIC_INFORMATION BasicInfo = 00322 (PEVENT_BASIC_INFORMATION)EventInformation; 00323 PAGED_CODE(); 00324 DPRINT("NtQueryEvent(0x%p, 0x%x)\n", EventHandle, EventInformationClass); 00325 00326 /* Check buffers and class validity */ 00327 Status = DefaultQueryInfoBufferCheck(EventInformationClass, 00328 ExEventInfoClass, 00329 sizeof(ExEventInfoClass) / 00330 sizeof(ExEventInfoClass[0]), 00331 EventInformation, 00332 EventInformationLength, 00333 ReturnLength, 00334 NULL, 00335 PreviousMode); 00336 if(!NT_SUCCESS(Status)) 00337 { 00338 /* Invalid buffers */ 00339 DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status); 00340 return Status; 00341 } 00342 00343 /* Get the Object */ 00344 Status = ObReferenceObjectByHandle(EventHandle, 00345 EVENT_QUERY_STATE, 00346 ExEventObjectType, 00347 PreviousMode, 00348 (PVOID*)&Event, 00349 NULL); 00350 00351 /* Check for success */ 00352 if(NT_SUCCESS(Status)) 00353 { 00354 /* Entry SEH Block */ 00355 _SEH2_TRY 00356 { 00357 /* Return Event Type and State */ 00358 BasicInfo->EventType = Event->Header.Type; 00359 BasicInfo->EventState = KeReadStateEvent(Event); 00360 00361 /* Return length */ 00362 if(ReturnLength) *ReturnLength = sizeof(EVENT_BASIC_INFORMATION); 00363 } 00364 _SEH2_EXCEPT(ExSystemExceptionFilter()) 00365 { 00366 /* Get the exception code */ 00367 Status = _SEH2_GetExceptionCode(); 00368 } 00369 _SEH2_END; 00370 00371 /* Dereference the Object */ 00372 ObDereferenceObject(Event); 00373 } 00374 00375 /* Return status */ 00376 return Status; 00377 } 00378 00379 /* 00380 * @implemented 00381 */ 00382 NTSTATUS 00383 NTAPI 00384 NtResetEvent(IN HANDLE EventHandle, 00385 OUT PLONG PreviousState OPTIONAL) 00386 { 00387 PKEVENT Event; 00388 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); 00389 NTSTATUS Status; 00390 PAGED_CODE(); 00391 DPRINT("NtResetEvent(EventHandle 0%x PreviousState 0%x)\n", 00392 EventHandle, PreviousState); 00393 00394 /* Check if we were called from user-mode */ 00395 if ((PreviousState) && (PreviousMode != KernelMode)) 00396 { 00397 /* Entry SEH Block */ 00398 _SEH2_TRY 00399 { 00400 /* Make sure the state pointer is valid */ 00401 ProbeForWriteLong(PreviousState); 00402 } 00403 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00404 { 00405 /* Return the exception code */ 00406 _SEH2_YIELD(return _SEH2_GetExceptionCode()); 00407 } 00408 _SEH2_END; 00409 } 00410 00411 /* Open the Object */ 00412 Status = ObReferenceObjectByHandle(EventHandle, 00413 EVENT_MODIFY_STATE, 00414 ExEventObjectType, 00415 PreviousMode, 00416 (PVOID*)&Event, 00417 NULL); 00418 00419 /* Check for success */ 00420 if(NT_SUCCESS(Status)) 00421 { 00422 /* Reset the Event */ 00423 LONG Prev = KeResetEvent(Event); 00424 ObDereferenceObject(Event); 00425 00426 /* Check if caller wants the old state back */ 00427 if(PreviousState) 00428 { 00429 /* Entry SEH Block for return */ 00430 _SEH2_TRY 00431 { 00432 /* Return previous state */ 00433 *PreviousState = Prev; 00434 } 00435 _SEH2_EXCEPT(ExSystemExceptionFilter()) 00436 { 00437 /* Get the exception code */ 00438 Status = _SEH2_GetExceptionCode(); 00439 } 00440 _SEH2_END; 00441 } 00442 } 00443 00444 /* Return Status */ 00445 return Status; 00446 } 00447 00448 /* 00449 * @implemented 00450 */ 00451 NTSTATUS 00452 NTAPI 00453 NtSetEvent(IN HANDLE EventHandle, 00454 OUT PLONG PreviousState OPTIONAL) 00455 { 00456 PKEVENT Event; 00457 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); 00458 NTSTATUS Status; 00459 PAGED_CODE(); 00460 DPRINT("NtSetEvent(EventHandle 0%x PreviousState 0%x)\n", 00461 EventHandle, PreviousState); 00462 00463 /* Check if we were called from user-mode */ 00464 if ((PreviousState) && (PreviousMode != KernelMode)) 00465 { 00466 /* Entry SEH Block */ 00467 _SEH2_TRY 00468 { 00469 /* Make sure the state pointer is valid */ 00470 ProbeForWriteLong(PreviousState); 00471 } 00472 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00473 { 00474 /* Return the exception code */ 00475 _SEH2_YIELD(return _SEH2_GetExceptionCode()); 00476 } 00477 _SEH2_END; 00478 } 00479 00480 /* Open the Object */ 00481 Status = ObReferenceObjectByHandle(EventHandle, 00482 EVENT_MODIFY_STATE, 00483 ExEventObjectType, 00484 PreviousMode, 00485 (PVOID*)&Event, 00486 NULL); 00487 if (NT_SUCCESS(Status)) 00488 { 00489 /* Set the Event */ 00490 LONG Prev = KeSetEvent(Event, EVENT_INCREMENT, FALSE); 00491 ObDereferenceObject(Event); 00492 00493 /* Check if caller wants the old state back */ 00494 if (PreviousState) 00495 { 00496 /* Entry SEH Block for return */ 00497 _SEH2_TRY 00498 { 00499 /* Return previous state */ 00500 *PreviousState = Prev; 00501 } 00502 _SEH2_EXCEPT(ExSystemExceptionFilter()) 00503 { 00504 Status = _SEH2_GetExceptionCode(); 00505 } 00506 _SEH2_END; 00507 } 00508 } 00509 00510 /* Return Status */ 00511 return Status; 00512 } 00513 00514 /* 00515 * @implemented 00516 */ 00517 NTSTATUS 00518 NTAPI 00519 NtSetEventBoostPriority(IN HANDLE EventHandle) 00520 { 00521 PKEVENT Event; 00522 NTSTATUS Status; 00523 PAGED_CODE(); 00524 00525 /* Open the Object */ 00526 Status = ObReferenceObjectByHandle(EventHandle, 00527 EVENT_MODIFY_STATE, 00528 ExEventObjectType, 00529 ExGetPreviousMode(), 00530 (PVOID*)&Event, 00531 NULL); 00532 if (NT_SUCCESS(Status)) 00533 { 00534 /* Set the Event */ 00535 KeSetEventBoostPriority(Event, NULL); 00536 ObDereferenceObject(Event); 00537 } 00538 00539 /* Return Status */ 00540 return Status; 00541 } 00542 00543 /* EOF */ Generated on Sat May 26 2012 04:23:19 for ReactOS by
1.7.6.1
|