2005-01-26 13:58:37 +00:00
|
|
|
/* $Id:$
|
|
|
|
*
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
2005-01-07 06:54:27 +00:00
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* FILE: ntoskrnl/nt/event.c
|
|
|
|
* PURPOSE: Named event support
|
2005-01-26 13:58:37 +00:00
|
|
|
*
|
|
|
|
* PROGRAMMERS: Philip Susi and David Welch
|
2005-01-07 06:54:27 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
|
|
|
|
#include <ntoskrnl.h>
|
|
|
|
#define NDEBUG
|
|
|
|
#include <internal/debug.h>
|
|
|
|
|
|
|
|
/* GLOBALS *******************************************************************/
|
|
|
|
|
|
|
|
POBJECT_TYPE EXPORTED ExEventObjectType = NULL;
|
|
|
|
|
|
|
|
static GENERIC_MAPPING ExpEventMapping = {
|
2005-02-28 16:44:38 +00:00
|
|
|
STANDARD_RIGHTS_READ | SYNCHRONIZE | EVENT_QUERY_STATE,
|
|
|
|
STANDARD_RIGHTS_WRITE | SYNCHRONIZE | EVENT_MODIFY_STATE,
|
|
|
|
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | EVENT_QUERY_STATE,
|
|
|
|
EVENT_ALL_ACCESS};
|
|
|
|
|
|
|
|
static const INFORMATION_CLASS_INFO ExEventInfoClass[] = {
|
|
|
|
|
|
|
|
/* EventBasicInformation */
|
|
|
|
ICI_SQ_SAME( sizeof(EVENT_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY),
|
2005-01-22 03:54:23 +00:00
|
|
|
};
|
2005-01-07 06:54:27 +00:00
|
|
|
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
VOID
|
|
|
|
INIT_FUNCTION
|
2005-01-07 06:54:27 +00:00
|
|
|
ExpInitializeEventImplementation(VOID)
|
|
|
|
{
|
2005-02-28 16:44:38 +00:00
|
|
|
/* Create the Event Object Type */
|
|
|
|
ExEventObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
|
|
|
|
RtlpCreateUnicodeString(&ExEventObjectType->TypeName, L"Event", NonPagedPool);
|
|
|
|
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);
|
2005-01-07 06:54:27 +00:00
|
|
|
}
|
|
|
|
|
2005-01-22 03:54:23 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2005-02-28 16:44:38 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
2005-01-07 06:54:27 +00:00
|
|
|
NtClearEvent(IN HANDLE EventHandle)
|
|
|
|
{
|
2005-02-28 16:44:38 +00:00
|
|
|
PKEVENT Event;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
PAGED_CODE();
|
2005-02-22 22:19:14 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
/* Reference the Object */
|
2005-01-07 06:54:27 +00:00
|
|
|
Status = ObReferenceObjectByHandle(EventHandle,
|
2005-02-28 16:44:38 +00:00
|
|
|
EVENT_MODIFY_STATE,
|
|
|
|
ExEventObjectType,
|
|
|
|
ExGetPreviousMode(),
|
|
|
|
(PVOID*)&Event,
|
|
|
|
NULL);
|
2005-01-22 03:54:23 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
/* Check for Success */
|
|
|
|
if(NT_SUCCESS(Status)) {
|
|
|
|
|
|
|
|
/* Clear the Event and Dereference */
|
|
|
|
KeClearEvent(Event);
|
|
|
|
ObDereferenceObject(Event);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return Status */
|
|
|
|
return Status;
|
2005-01-07 06:54:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-01-21 23:35:19 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2005-02-28 16:44:38 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
2005-01-21 23:35:19 +00:00
|
|
|
NtCreateEvent(OUT PHANDLE EventHandle,
|
2005-02-28 16:44:38 +00:00
|
|
|
IN ACCESS_MASK DesiredAccess,
|
|
|
|
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
|
|
|
IN EVENT_TYPE EventType,
|
|
|
|
IN BOOLEAN InitialState)
|
2005-01-21 23:35:19 +00:00
|
|
|
{
|
2005-02-28 16:44:38 +00:00
|
|
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
|
|
|
PKEVENT Event;
|
|
|
|
HANDLE hEvent;
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2005-02-22 22:19:14 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
PAGED_CODE();
|
2005-01-21 23:35:19 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
/* Check Output Safety */
|
|
|
|
if(PreviousMode == UserMode) {
|
|
|
|
|
|
|
|
_SEH_TRY {
|
|
|
|
|
|
|
|
ProbeForWrite(EventHandle,
|
|
|
|
sizeof(HANDLE),
|
|
|
|
sizeof(ULONG));
|
|
|
|
} _SEH_HANDLE {
|
|
|
|
|
|
|
|
Status = _SEH_GetExceptionCode();
|
|
|
|
|
|
|
|
} _SEH_END;
|
2005-01-22 13:34:27 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
if(!NT_SUCCESS(Status)) return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create the Object */
|
|
|
|
Status = ObCreateObject(PreviousMode,
|
|
|
|
ExEventObjectType,
|
|
|
|
ObjectAttributes,
|
|
|
|
PreviousMode,
|
|
|
|
NULL,
|
|
|
|
sizeof(KEVENT),
|
|
|
|
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,
|
|
|
|
DesiredAccess,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
&hEvent);
|
|
|
|
ObDereferenceObject(Event);
|
2005-01-21 23:35:19 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
/* Check for success and return handle */
|
|
|
|
if(NT_SUCCESS(Status)) {
|
|
|
|
|
|
|
|
_SEH_TRY {
|
|
|
|
|
|
|
|
*EventHandle = hEvent;
|
|
|
|
|
|
|
|
} _SEH_HANDLE {
|
|
|
|
|
|
|
|
Status = _SEH_GetExceptionCode();
|
|
|
|
|
|
|
|
} _SEH_END;
|
|
|
|
}
|
|
|
|
}
|
2005-01-07 06:54:27 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
/* Return Status */
|
|
|
|
return Status;
|
|
|
|
}
|
2005-01-07 06:54:27 +00:00
|
|
|
|
2005-01-22 03:54:23 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2005-02-28 16:44:38 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
2005-01-07 06:54:27 +00:00
|
|
|
NtOpenEvent(OUT PHANDLE EventHandle,
|
2005-02-28 16:44:38 +00:00
|
|
|
IN ACCESS_MASK DesiredAccess,
|
|
|
|
IN POBJECT_ATTRIBUTES ObjectAttributes)
|
2005-01-07 06:54:27 +00:00
|
|
|
{
|
2005-02-28 16:44:38 +00:00
|
|
|
HANDLE hEvent;
|
|
|
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2005-01-22 03:54:23 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
PAGED_CODE();
|
|
|
|
DPRINT("NtOpenEvent(0x%x, 0x%x, 0x%x)\n", EventHandle, DesiredAccess, ObjectAttributes);
|
|
|
|
|
|
|
|
/* Check Output Safety */
|
|
|
|
if(PreviousMode == UserMode) {
|
|
|
|
|
|
|
|
_SEH_TRY {
|
|
|
|
|
|
|
|
ProbeForWrite(EventHandle,
|
|
|
|
sizeof(HANDLE),
|
|
|
|
sizeof(ULONG));
|
|
|
|
} _SEH_HANDLE {
|
|
|
|
|
|
|
|
Status = _SEH_GetExceptionCode();
|
|
|
|
|
|
|
|
} _SEH_END;
|
2005-01-22 03:54:23 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
if(!NT_SUCCESS(Status)) return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Open the Object */
|
|
|
|
Status = ObOpenObjectByName(ObjectAttributes,
|
|
|
|
ExEventObjectType,
|
|
|
|
NULL,
|
|
|
|
PreviousMode,
|
|
|
|
DesiredAccess,
|
|
|
|
NULL,
|
|
|
|
&hEvent);
|
2005-01-07 06:54:27 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
/* Check for success and return handle */
|
|
|
|
if(NT_SUCCESS(Status)) {
|
|
|
|
|
|
|
|
_SEH_TRY {
|
|
|
|
|
|
|
|
*EventHandle = hEvent;
|
|
|
|
|
|
|
|
} _SEH_HANDLE {
|
|
|
|
|
|
|
|
Status = _SEH_GetExceptionCode();
|
|
|
|
|
|
|
|
} _SEH_END;
|
|
|
|
}
|
2005-01-22 03:54:23 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
/* Return status */
|
|
|
|
return Status;
|
2005-01-07 06:54:27 +00:00
|
|
|
}
|
|
|
|
|
2005-01-22 03:54:23 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2005-02-28 16:44:38 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
2005-01-07 06:54:27 +00:00
|
|
|
NtPulseEvent(IN HANDLE EventHandle,
|
2005-02-28 16:44:38 +00:00
|
|
|
OUT PLONG PreviousState OPTIONAL)
|
2005-01-07 06:54:27 +00:00
|
|
|
{
|
2005-02-28 16:44:38 +00:00
|
|
|
PKEVENT Event;
|
|
|
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2005-01-22 03:54:23 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
PAGED_CODE();
|
|
|
|
DPRINT("NtPulseEvent(EventHandle 0%x PreviousState 0%x)\n",
|
|
|
|
EventHandle, PreviousState);
|
|
|
|
|
|
|
|
/* Check buffer validity */
|
|
|
|
if(PreviousState && PreviousMode == UserMode) {
|
|
|
|
|
|
|
|
_SEH_TRY {
|
|
|
|
|
|
|
|
ProbeForWrite(PreviousState,
|
|
|
|
sizeof(LONG),
|
|
|
|
sizeof(ULONG));
|
|
|
|
} _SEH_HANDLE {
|
|
|
|
|
|
|
|
Status = _SEH_GetExceptionCode();
|
|
|
|
|
|
|
|
} _SEH_END;
|
2005-01-22 03:54:23 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
if(!NT_SUCCESS(Status)) return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Open the Object */
|
|
|
|
Status = ObReferenceObjectByHandle(EventHandle,
|
|
|
|
EVENT_MODIFY_STATE,
|
|
|
|
ExEventObjectType,
|
|
|
|
PreviousMode,
|
|
|
|
(PVOID*)&Event,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
/* Check for success */
|
|
|
|
if(NT_SUCCESS(Status)) {
|
|
|
|
|
|
|
|
/* Pulse the Event */
|
|
|
|
LONG Prev = KePulseEvent(Event, EVENT_INCREMENT, FALSE);
|
|
|
|
ObDereferenceObject(Event);
|
2005-01-22 03:54:23 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
/* Return it */
|
|
|
|
if(PreviousState) {
|
|
|
|
|
|
|
|
_SEH_TRY {
|
|
|
|
|
|
|
|
*PreviousState = Prev;
|
|
|
|
|
|
|
|
} _SEH_HANDLE {
|
|
|
|
|
|
|
|
Status = _SEH_GetExceptionCode();
|
|
|
|
|
|
|
|
} _SEH_END;
|
|
|
|
}
|
2005-01-22 03:54:23 +00:00
|
|
|
}
|
2005-01-07 06:54:27 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
/* Return Status */
|
2005-01-22 03:54:23 +00:00
|
|
|
return Status;
|
2005-01-07 06:54:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-01-22 03:54:23 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2005-02-28 16:44:38 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
2005-01-07 06:54:27 +00:00
|
|
|
NtQueryEvent(IN HANDLE EventHandle,
|
2005-02-28 16:44:38 +00:00
|
|
|
IN EVENT_INFORMATION_CLASS EventInformationClass,
|
|
|
|
OUT PVOID EventInformation,
|
|
|
|
IN ULONG EventInformationLength,
|
|
|
|
OUT PULONG ReturnLength OPTIONAL)
|
2005-01-07 06:54:27 +00:00
|
|
|
{
|
2005-02-28 16:44:38 +00:00
|
|
|
PKEVENT Event;
|
|
|
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
PEVENT_BASIC_INFORMATION BasicInfo = (PEVENT_BASIC_INFORMATION)EventInformation;
|
|
|
|
|
|
|
|
/* Check buffers and class validity */
|
|
|
|
DefaultQueryInfoBufferCheck(EventInformationClass,
|
|
|
|
ExEventInfoClass,
|
|
|
|
EventInformation,
|
|
|
|
EventInformationLength,
|
|
|
|
ReturnLength,
|
|
|
|
PreviousMode,
|
|
|
|
&Status);
|
|
|
|
if(!NT_SUCCESS(Status)) {
|
|
|
|
|
|
|
|
/* Invalid buffers */
|
|
|
|
DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
2005-01-22 03:54:23 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
/* Get the Object */
|
|
|
|
Status = ObReferenceObjectByHandle(EventHandle,
|
|
|
|
EVENT_QUERY_STATE,
|
|
|
|
ExEventObjectType,
|
|
|
|
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 {
|
|
|
|
|
|
|
|
Status = _SEH_GetExceptionCode();
|
|
|
|
|
|
|
|
} _SEH_END;
|
|
|
|
|
|
|
|
/* Dereference the Object */
|
|
|
|
ObDereferenceObject(Event);
|
2005-01-22 03:54:23 +00:00
|
|
|
}
|
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
/* Return status */
|
2005-01-22 03:54:23 +00:00
|
|
|
return Status;
|
2005-01-07 06:54:27 +00:00
|
|
|
}
|
|
|
|
|
2005-01-22 03:54:23 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2005-02-28 16:44:38 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
2005-01-07 06:54:27 +00:00
|
|
|
NtResetEvent(IN HANDLE EventHandle,
|
2005-02-28 16:44:38 +00:00
|
|
|
OUT PLONG PreviousState OPTIONAL)
|
2005-01-07 06:54:27 +00:00
|
|
|
{
|
2005-02-28 16:44:38 +00:00
|
|
|
PKEVENT Event;
|
|
|
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2005-02-22 22:19:14 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
PAGED_CODE();
|
|
|
|
|
|
|
|
DPRINT("NtResetEvent(EventHandle 0%x PreviousState 0%x)\n",
|
|
|
|
EventHandle, PreviousState);
|
|
|
|
|
|
|
|
/* Check buffer validity */
|
|
|
|
if(PreviousState && PreviousMode == UserMode) {
|
|
|
|
|
|
|
|
_SEH_TRY {
|
|
|
|
|
|
|
|
ProbeForWrite(PreviousState,
|
|
|
|
sizeof(LONG),
|
|
|
|
sizeof(ULONG));
|
|
|
|
} _SEH_HANDLE {
|
|
|
|
|
|
|
|
Status = _SEH_GetExceptionCode();
|
|
|
|
|
|
|
|
} _SEH_END;
|
2005-01-22 03:54:23 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
if(!NT_SUCCESS(Status)) return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Open the Object */
|
|
|
|
Status = ObReferenceObjectByHandle(EventHandle,
|
|
|
|
EVENT_MODIFY_STATE,
|
|
|
|
ExEventObjectType,
|
|
|
|
PreviousMode,
|
|
|
|
(PVOID*)&Event,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
/* Check for success */
|
|
|
|
if(NT_SUCCESS(Status)) {
|
|
|
|
|
|
|
|
/* Reset the Event */
|
|
|
|
LONG Prev = KeResetEvent(Event);
|
|
|
|
ObDereferenceObject(Event);
|
2005-01-22 03:54:23 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
/* Return it */
|
|
|
|
if(PreviousState) {
|
|
|
|
|
|
|
|
_SEH_TRY {
|
|
|
|
|
|
|
|
*PreviousState = Prev;
|
|
|
|
|
|
|
|
} _SEH_HANDLE {
|
|
|
|
|
|
|
|
Status = _SEH_GetExceptionCode();
|
|
|
|
|
|
|
|
} _SEH_END;
|
|
|
|
}
|
2005-01-22 03:54:23 +00:00
|
|
|
}
|
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
/* Return Status */
|
2005-01-22 03:54:23 +00:00
|
|
|
return Status;
|
2005-01-07 06:54:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2005-02-28 16:44:38 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
2005-01-07 06:54:27 +00:00
|
|
|
NtSetEvent(IN HANDLE EventHandle,
|
2005-02-28 16:44:38 +00:00
|
|
|
OUT PLONG PreviousState OPTIONAL)
|
2005-01-07 06:54:27 +00:00
|
|
|
{
|
2005-02-28 16:44:38 +00:00
|
|
|
PKEVENT Event;
|
|
|
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2005-02-22 22:19:14 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
PAGED_CODE();
|
|
|
|
|
|
|
|
DPRINT1("NtSetEvent(EventHandle 0%x PreviousState 0%x)\n",
|
|
|
|
EventHandle, PreviousState);
|
|
|
|
|
|
|
|
/* Check buffer validity */
|
|
|
|
if(PreviousState != NULL && PreviousMode == UserMode) {
|
|
|
|
|
|
|
|
_SEH_TRY {
|
|
|
|
|
|
|
|
ProbeForWrite(PreviousState,
|
|
|
|
sizeof(LONG),
|
|
|
|
sizeof(ULONG));
|
|
|
|
} _SEH_HANDLE {
|
|
|
|
|
|
|
|
Status = _SEH_GetExceptionCode();
|
|
|
|
|
|
|
|
} _SEH_END;
|
2005-01-22 03:54:23 +00:00
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
if(!NT_SUCCESS(Status)) return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Open the Object */
|
|
|
|
Status = ObReferenceObjectByHandle(EventHandle,
|
|
|
|
EVENT_MODIFY_STATE,
|
|
|
|
ExEventObjectType,
|
|
|
|
PreviousMode,
|
|
|
|
(PVOID*)&Event,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
/* Check for success */
|
|
|
|
if(NT_SUCCESS(Status)) {
|
|
|
|
|
|
|
|
/* Set the Event */
|
|
|
|
LONG Prev = KeSetEvent(Event, EVENT_INCREMENT, FALSE);
|
|
|
|
ObDereferenceObject(Event);
|
|
|
|
|
|
|
|
/* Return it */
|
|
|
|
if(PreviousState) {
|
|
|
|
|
|
|
|
_SEH_TRY {
|
|
|
|
|
|
|
|
*PreviousState = Prev;
|
|
|
|
|
|
|
|
} _SEH_HANDLE {
|
|
|
|
|
|
|
|
Status = _SEH_GetExceptionCode();
|
|
|
|
|
|
|
|
} _SEH_END;
|
|
|
|
}
|
2005-01-22 03:54:23 +00:00
|
|
|
}
|
|
|
|
|
2005-02-28 16:44:38 +00:00
|
|
|
/* Return Status */
|
2005-01-22 03:54:23 +00:00
|
|
|
return Status;
|
2005-01-07 06:54:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|