mirror of
https://github.com/reactos/reactos.git
synced 2025-03-10 10:14:44 +00:00
290 lines
4.9 KiB
C
290 lines
4.9 KiB
C
![]() |
/*++
|
||
|
|
||
|
Copyright (c) Microsoft Corporation
|
||
|
|
||
|
ModuleName:
|
||
|
|
||
|
MxEventUm.h
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
User mode implementation of event
|
||
|
class defined in MxEvent.h
|
||
|
|
||
|
Author:
|
||
|
|
||
|
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
typedef struct {
|
||
|
HANDLE Event;
|
||
|
#if DBG
|
||
|
EVENT_TYPE Type; //tracked to allow ReadState only for notification events
|
||
|
#endif
|
||
|
} MdEvent;
|
||
|
|
||
|
#include "DbgMacros.h"
|
||
|
#include "MxEvent.h"
|
||
|
|
||
|
__inline
|
||
|
MxEvent::MxEvent()
|
||
|
{
|
||
|
CLEAR_DBGFLAG_INITIALIZED;
|
||
|
|
||
|
m_Event.Event = NULL;
|
||
|
}
|
||
|
|
||
|
__inline
|
||
|
MxEvent::~MxEvent()
|
||
|
{
|
||
|
//
|
||
|
// PLEASE NOTE: shared code must not rely of d'tor uninitializing the
|
||
|
// event. d'tor may not be invoked if the event is used in a structure
|
||
|
// which is allocated/deallocated using MxPoolAllocate/Free instead of
|
||
|
// new/delete
|
||
|
//
|
||
|
Uninitialize();
|
||
|
}
|
||
|
|
||
|
_Must_inspect_result_
|
||
|
__inline
|
||
|
NTSTATUS
|
||
|
MxEvent::Initialize(
|
||
|
__in EVENT_TYPE Type,
|
||
|
__in BOOLEAN InitialState
|
||
|
)
|
||
|
{
|
||
|
NTSTATUS status = STATUS_SUCCESS;
|
||
|
HANDLE event;
|
||
|
BOOL bManualReset;
|
||
|
|
||
|
if (NotificationEvent == Type)
|
||
|
{
|
||
|
bManualReset = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bManualReset = FALSE;
|
||
|
}
|
||
|
|
||
|
event = CreateEvent(
|
||
|
NULL,
|
||
|
bManualReset,
|
||
|
InitialState ? TRUE : FALSE,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
if (NULL == event) {
|
||
|
DWORD err = GetLastError();
|
||
|
status = WinErrorToNtStatus(err);
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
m_Event.Event = event;
|
||
|
|
||
|
#if DBG
|
||
|
m_Event.Type = Type;
|
||
|
#endif
|
||
|
|
||
|
SET_DBGFLAG_INITIALIZED;
|
||
|
|
||
|
exit:
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
__inline
|
||
|
PVOID
|
||
|
MxEvent::GetEvent(
|
||
|
)
|
||
|
{
|
||
|
ASSERT_DBGFLAG_INITIALIZED;
|
||
|
|
||
|
return m_Event.Event;
|
||
|
}
|
||
|
|
||
|
__inline
|
||
|
VOID
|
||
|
MxEvent::Set(
|
||
|
)
|
||
|
{
|
||
|
ASSERT_DBGFLAG_INITIALIZED;
|
||
|
|
||
|
SetEvent(m_Event.Event);
|
||
|
}
|
||
|
|
||
|
__inline
|
||
|
VOID
|
||
|
MxEvent::SetWithIncrement(
|
||
|
__in KPRIORITY Priority
|
||
|
)
|
||
|
{
|
||
|
UNREFERENCED_PARAMETER(Priority);
|
||
|
|
||
|
ASSERT_DBGFLAG_INITIALIZED;
|
||
|
|
||
|
Set();
|
||
|
}
|
||
|
|
||
|
__inline
|
||
|
VOID
|
||
|
MxEvent::Clear(
|
||
|
)
|
||
|
{
|
||
|
ASSERT_DBGFLAG_INITIALIZED;
|
||
|
|
||
|
ResetEvent(m_Event.Event);
|
||
|
}
|
||
|
|
||
|
__drv_when(Timeout != NULL, _Must_inspect_result_)
|
||
|
__inline
|
||
|
NTSTATUS
|
||
|
MxEvent::WaitFor(
|
||
|
__in KWAIT_REASON WaitReason,
|
||
|
__in KPROCESSOR_MODE WaitMode,
|
||
|
__in BOOLEAN Alertable,
|
||
|
__in_opt PLARGE_INTEGER Timeout
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
Waits for the event
|
||
|
|
||
|
Arguments:
|
||
|
WaitReason - Unused (only there to match km definition)
|
||
|
|
||
|
WaitMode - Unuses (only there to match km definition)
|
||
|
|
||
|
Altertable - Whether the wait is alertable
|
||
|
|
||
|
Timout - Timeout in 100 ns units, MUST BE NEGATIVE
|
||
|
(negative implies relative timeout)
|
||
|
|
||
|
Return Value:
|
||
|
Status corresponding to return value of WaitForSingleObjectEx
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
ASSERT_DBGFLAG_INITIALIZED;
|
||
|
|
||
|
DWORD retVal;
|
||
|
|
||
|
UNREFERENCED_PARAMETER(WaitReason);
|
||
|
UNREFERENCED_PARAMETER(WaitMode);
|
||
|
|
||
|
LONGLONG relativeTimeOut = 0;
|
||
|
LONGLONG timeoutInMs = 0;
|
||
|
DWORD dwTimeout = 0;
|
||
|
|
||
|
if (NULL != Timeout)
|
||
|
{
|
||
|
//
|
||
|
// Make sure that timeout is 0 or -ve (which implies relative timeout)
|
||
|
//
|
||
|
if (Timeout->QuadPart > 0)
|
||
|
{
|
||
|
Mx::MxAssertMsg(
|
||
|
"Absolute wait not supported in user mode",
|
||
|
FALSE
|
||
|
);
|
||
|
|
||
|
return STATUS_INVALID_PARAMETER;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Remove the -ve sign
|
||
|
//
|
||
|
if (Timeout->QuadPart < 0)
|
||
|
{
|
||
|
relativeTimeOut = -1 * Timeout->QuadPart;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Convert from 100ns units to milliseconds
|
||
|
//
|
||
|
timeoutInMs = (relativeTimeOut / (10 * 1000));
|
||
|
|
||
|
if (timeoutInMs > ULONG_MAX)
|
||
|
{
|
||
|
Mx::MxAssertMsg("Timeout too large", FALSE);
|
||
|
|
||
|
return STATUS_INVALID_PARAMETER;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dwTimeout = (DWORD) timeoutInMs;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
retVal = WaitForSingleObjectEx(
|
||
|
m_Event.Event,
|
||
|
(NULL == Timeout) ? INFINITE : dwTimeout,
|
||
|
Alertable
|
||
|
);
|
||
|
|
||
|
switch(retVal)
|
||
|
{
|
||
|
case WAIT_ABANDONED:
|
||
|
return STATUS_ABANDONED;
|
||
|
case WAIT_OBJECT_0:
|
||
|
return STATUS_SUCCESS;
|
||
|
case WAIT_TIMEOUT:
|
||
|
return STATUS_TIMEOUT;
|
||
|
case WAIT_FAILED:
|
||
|
{
|
||
|
DWORD err = GetLastError();
|
||
|
return WinErrorToNtStatus(err);
|
||
|
}
|
||
|
default:
|
||
|
{
|
||
|
//
|
||
|
// We shoudn't get here
|
||
|
//
|
||
|
Mx::MxAssert(FALSE);
|
||
|
return STATUS_UNSUCCESSFUL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LONG
|
||
|
__inline
|
||
|
MxEvent::ReadState(
|
||
|
)
|
||
|
{
|
||
|
ASSERT_DBGFLAG_INITIALIZED;
|
||
|
|
||
|
#if DBG
|
||
|
Mx::MxAssert(m_Event.Type == NotificationEvent);
|
||
|
#endif
|
||
|
|
||
|
if (WAIT_OBJECT_0 == WaitForSingleObject(
|
||
|
m_Event.Event,
|
||
|
0
|
||
|
)) {
|
||
|
return 1;
|
||
|
}
|
||
|
else {
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
__inline
|
||
|
VOID
|
||
|
MxEvent::Uninitialize(
|
||
|
)
|
||
|
{
|
||
|
if (NULL != m_Event.Event) {
|
||
|
CloseHandle(m_Event.Event);
|
||
|
m_Event.Event = NULL;
|
||
|
}
|
||
|
|
||
|
CLEAR_DBGFLAG_INITIALIZED;
|
||
|
}
|