-/*
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/nt/event.c
* PURPOSE: Named event support
- *
+ *
* PROGRAMMERS: Alex Ionescu(alex@relsoft.net) - Fixed bugs/commented
* Philip Susi and David Welch
*/
EVENT_ALL_ACCESS};
static const INFORMATION_CLASS_INFO ExEventInfoClass[] = {
-
+
/* EventBasicInformation */
ICI_SQ_SAME( sizeof(EVENT_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY),
};
/* FUNCTIONS *****************************************************************/
-VOID
+VOID
INIT_FUNCTION
+STDCALL
ExpInitializeEventImplementation(VOID)
{
- /* Create the Event Object Type */
- ExEventObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
- RtlInitUnicodeString(&ExEventObjectType->TypeName, L"Event");
- ExEventObjectType->Tag = TAG('E', 'V', 'T', 'T');
- ExEventObjectType->PeakObjects = 0;
- ExEventObjectType->PeakHandles = 0;
- ExEventObjectType->TotalObjects = 0;
- ExEventObjectType->TotalHandles = 0;
- ExEventObjectType->PagedPoolCharge = 0;
- ExEventObjectType->NonpagedPoolCharge = sizeof(KEVENT);
- ExEventObjectType->Mapping = &ExpEventMapping;
- ExEventObjectType->Dump = NULL;
- ExEventObjectType->Open = NULL;
- ExEventObjectType->Close = NULL;
- ExEventObjectType->Delete = NULL;
- ExEventObjectType->Parse = NULL;
- ExEventObjectType->Security = NULL;
- ExEventObjectType->QueryName = NULL;
- ExEventObjectType->OkayToClose = NULL;
- ExEventObjectType->Create = NULL;
- ExEventObjectType->DuplicationNotify = NULL;
- ObpCreateTypeObject(ExEventObjectType);
+ OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
+ UNICODE_STRING Name;
+
+ DPRINT("Creating Event Object Type\n");
+
+ /* Create the Event Object Type */
+ RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
+ RtlInitUnicodeString(&Name, L"Event");
+ ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
+ ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KEVENT);
+ ObjectTypeInitializer.GenericMapping = ExpEventMapping;
+ ObjectTypeInitializer.PoolType = NonPagedPool;
+ ObjectTypeInitializer.ValidAccessMask = EVENT_ALL_ACCESS;
+ ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ExEventObjectType);
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtClearEvent(IN HANDLE EventHandle)
{
PKEVENT Event;
NTSTATUS Status;
-
+
PAGED_CODE();
-
+
/* Reference the Object */
Status = ObReferenceObjectByHandle(EventHandle,
EVENT_MODIFY_STATE,
ExGetPreviousMode(),
(PVOID*)&Event,
NULL);
-
+
/* Check for Success */
if(NT_SUCCESS(Status)) {
-
+
/* Clear the Event and Dereference */
KeClearEvent(Event);
ObDereferenceObject(Event);
}
-
+
/* Return Status */
return Status;
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtCreateEvent(OUT PHANDLE EventHandle,
IN ACCESS_MASK DesiredAccess,
PKEVENT Event;
HANDLE hEvent;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
- DPRINT("NtCreateEvent(0x%x, 0x%x, 0x%x)\n", EventHandle, DesiredAccess, ObjectAttributes);
-
+ DPRINT("NtCreateEvent(0x%p, 0x%x, 0x%p)\n", EventHandle, DesiredAccess, ObjectAttributes);
+
/* Check Output Safety */
if(PreviousMode != KernelMode) {
-
+
_SEH_TRY {
-
- ProbeForWrite(EventHandle,
- sizeof(HANDLE),
- sizeof(ULONG));
- } _SEH_HANDLE {
-
+
+ ProbeForWriteHandle(EventHandle);
+ } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
-
+
if(!NT_SUCCESS(Status)) return Status;
}
-
+
/* Create the Object */
Status = ObCreateObject(PreviousMode,
ExEventObjectType,
0,
0,
(PVOID*)&Event);
-
+
/* Check for Success */
if(NT_SUCCESS(Status)) {
-
+
/* Initalize the Event */
KeInitializeEvent(Event,
EventType,
InitialState);
-
+
/* Insert it */
Status = ObInsertObject((PVOID)Event,
NULL,
NULL,
&hEvent);
ObDereferenceObject(Event);
-
+
/* Check for success and return handle */
if(NT_SUCCESS(Status)) {
-
+
_SEH_TRY {
-
+
*EventHandle = hEvent;
-
- } _SEH_HANDLE {
-
+
+ } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtOpenEvent(OUT PHANDLE EventHandle,
IN ACCESS_MASK DesiredAccess,
HANDLE hEvent;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
- PAGED_CODE();
- DPRINT("NtOpenEvent(0x%x, 0x%x, 0x%x)\n", EventHandle, DesiredAccess, ObjectAttributes);
+
+ PAGED_CODE();
+ DPRINT("NtOpenEvent(0x%p, 0x%x, 0x%p)\n", EventHandle, DesiredAccess, ObjectAttributes);
/* Check Output Safety */
if(PreviousMode != KernelMode) {
-
+
_SEH_TRY {
-
- ProbeForWrite(EventHandle,
- sizeof(HANDLE),
- sizeof(ULONG));
- } _SEH_HANDLE {
-
+
+ ProbeForWriteHandle(EventHandle);
+ } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
-
+
if(!NT_SUCCESS(Status)) return Status;
}
-
+
/* Open the Object */
Status = ObOpenObjectByName(ObjectAttributes,
ExEventObjectType,
DesiredAccess,
NULL,
&hEvent);
-
+
/* Check for success and return handle */
if(NT_SUCCESS(Status)) {
-
+
_SEH_TRY {
-
+
*EventHandle = hEvent;
-
- } _SEH_HANDLE {
-
+
+ } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
-
+
/* Return status */
return Status;
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtPulseEvent(IN HANDLE EventHandle,
OUT PLONG PreviousState OPTIONAL)
PKEVENT Event;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
DPRINT("NtPulseEvent(EventHandle 0%x PreviousState 0%x)\n",
EventHandle, PreviousState);
/* Check buffer validity */
- if(PreviousState && PreviousMode == UserMode) {
-
+ if(PreviousState && PreviousMode != KernelMode) {
+
_SEH_TRY {
-
- ProbeForWrite(PreviousState,
- sizeof(LONG),
- sizeof(ULONG));
- } _SEH_HANDLE {
-
+
+ ProbeForWriteLong(PreviousState);
+ } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
if(!NT_SUCCESS(Status)) return Status;
}
-
+
/* Open the Object */
Status = ObReferenceObjectByHandle(EventHandle,
EVENT_MODIFY_STATE,
PreviousMode,
(PVOID*)&Event,
NULL);
-
+
/* Check for success */
if(NT_SUCCESS(Status)) {
-
+
/* Pulse the Event */
LONG Prev = KePulseEvent(Event, EVENT_INCREMENT, FALSE);
ObDereferenceObject(Event);
-
- /* Return it */
+
+ /* Return it */
if(PreviousState) {
-
+
_SEH_TRY {
-
+
*PreviousState = Prev;
-
- } _SEH_HANDLE {
-
+
+ } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtQueryEvent(IN HANDLE EventHandle,
IN EVENT_INFORMATION_CLASS EventInformationClass,
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
PEVENT_BASIC_INFORMATION BasicInfo = (PEVENT_BASIC_INFORMATION)EventInformation;
-
+
PAGED_CODE();
- DPRINT("NtQueryEvent(0x%x, 0x%x, 0x%x)\n", EventHandle, EventInformationClass);
-
+ DPRINT("NtQueryEvent(0x%p, 0x%x)\n", EventHandle, EventInformationClass);
+
/* Check buffers and class validity */
- DefaultQueryInfoBufferCheck(EventInformationClass,
- ExEventInfoClass,
- EventInformation,
- EventInformationLength,
- ReturnLength,
- PreviousMode,
- &Status);
+ Status = DefaultQueryInfoBufferCheck(EventInformationClass,
+ ExEventInfoClass,
+ sizeof(ExEventInfoClass) / sizeof(ExEventInfoClass[0]),
+ EventInformation,
+ EventInformationLength,
+ ReturnLength,
+ PreviousMode);
if(!NT_SUCCESS(Status)) {
-
+
/* Invalid buffers */
DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status);
return Status;
}
-
+
/* Get the Object */
Status = ObReferenceObjectByHandle(EventHandle,
EVENT_QUERY_STATE,
PreviousMode,
(PVOID*)&Event,
NULL);
-
+
/* Check for success */
if(NT_SUCCESS(Status)) {
_SEH_TRY {
-
+
/* Return Event Type and State */
BasicInfo->EventType = Event->Header.Type;
BasicInfo->EventState = KeReadStateEvent(Event);
/* Return length */
if(ReturnLength) *ReturnLength = sizeof(EVENT_BASIC_INFORMATION);
-
- } _SEH_HANDLE {
-
+
+ } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
-
+
/* Dereference the Object */
ObDereferenceObject(Event);
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtResetEvent(IN HANDLE EventHandle,
OUT PLONG PreviousState OPTIONAL)
PKEVENT Event;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
DPRINT("NtResetEvent(EventHandle 0%x PreviousState 0%x)\n",
EventHandle, PreviousState);
/* Check buffer validity */
- if(PreviousState && PreviousMode == UserMode) {
-
+ if(PreviousState && PreviousMode != KernelMode) {
+
_SEH_TRY {
-
- ProbeForWrite(PreviousState,
- sizeof(LONG),
- sizeof(ULONG));
- } _SEH_HANDLE {
-
+
+ ProbeForWriteLong(PreviousState);
+ } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
if(!NT_SUCCESS(Status)) return Status;
PreviousMode,
(PVOID*)&Event,
NULL);
-
+
/* Check for success */
if(NT_SUCCESS(Status)) {
-
+
/* Reset the Event */
LONG Prev = KeResetEvent(Event);
ObDereferenceObject(Event);
-
- /* Return it */
+
+ /* Return it */
if(PreviousState) {
-
+
_SEH_TRY {
-
+
*PreviousState = Prev;
-
- } _SEH_HANDLE {
-
+
+ } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtSetEvent(IN HANDLE EventHandle,
OUT PLONG PreviousState OPTIONAL)
PKEVENT Event;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
DPRINT("NtSetEvent(EventHandle 0%x PreviousState 0%x)\n",
EventHandle, PreviousState);
/* Check buffer validity */
- if(PreviousState != NULL && PreviousMode == UserMode) {
-
+ if(PreviousState != NULL && PreviousMode != KernelMode) {
+
_SEH_TRY {
-
- ProbeForWrite(PreviousState,
- sizeof(LONG),
- sizeof(ULONG));
- } _SEH_HANDLE {
-
+
+ ProbeForWriteLong(PreviousState);
+ } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
if(!NT_SUCCESS(Status)) return Status;
PreviousMode,
(PVOID*)&Event,
NULL);
-
+
/* Check for success */
if(NT_SUCCESS(Status)) {
LONG Prev = KeSetEvent(Event, EVENT_INCREMENT, FALSE);
ObDereferenceObject(Event);
- /* Return it */
+ /* Return it */
if(PreviousState) {
-
+
_SEH_TRY {
-
+
*PreviousState = Prev;
-
- } _SEH_HANDLE {
-
+
+ } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
}