ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

event.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.