1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 ModuleName:
6 
7     MxEvent.h
8 
9 Abstract:
10 
11     Mode agnostic definition of event
12 
13     See MxEventKm.h and MxEventUm.h for mode
14     specific implementations
15 
16 Author:
17 
18 
19 
20 Revision History:
21 
22 
23 
24 --*/
25 
26 #pragma once
27 
28 class MxEvent
29 {
30 
31 private:
32     //
33     // MdEvent is typedef'ed to appropriate type for the mode
34     // in the mode specific file
35     //
36     MdEvent m_Event;
37 
38     DECLARE_DBGFLAG_INITIALIZED;
39 
40 public:
41     __inline
42     MxEvent(
43         );
44 
45     __inline
46     ~MxEvent(
47         );
48 
49     CHECK_RETURN_IF_USER_MODE
50     __inline
51     NTSTATUS
52     Initialize(
53         __in EVENT_TYPE Type,
54         __in BOOLEAN InitialState
55         );
56 
57     //
58     // GetEvent will return the underlying primitive event
59     // PKEVENT in case of kernel mode and event HANDLE in case of user-mode
60     //
61     __inline
62     PVOID
63     GetEvent(
64         );
65 
66     __inline
67     VOID
68     Set(
69         );
70 
71     __inline
72     VOID
73     SetWithIncrement(
74         __in KPRIORITY Priority
75         );
76 
77     __inline
78     VOID
79     Clear(
80         );
81 
82     __drv_when(Timeout == NULL && Alertable == FALSE, __drv_valueIs(==0))
83     __drv_when(Timeout != NULL && Alertable == FALSE, __drv_valueIs(==0;==258))
84     __drv_when(Timeout != NULL || Alertable == TRUE, _Must_inspect_result_)
85     __inline
86     NTSTATUS
87     WaitFor(
88         __in     KWAIT_REASON  WaitReason,
89         __in     KPROCESSOR_MODE  WaitMode,
90         __in     BOOLEAN  Alertable,
91         __in_opt PLARGE_INTEGER  Timeout
92         );
93 
94     //
95     // NOTE: In user mode this function can only be called
96     // for a notification event (and not for a
97     // synchronization event)
98     //
99     __inline
100     LONG
101     ReadState(
102         );
103 
104     __inline
105     VOID
106     Uninitialize(
107         );
108 
109     MxEvent*
110     GetSelfPointer(
111         VOID
112         )
113     {
114         //
115         // Since operator& is hidden, we still need to be able to get a pointer
116         // to this object, so we must make it an explicit method.
117         //
118         return this;
119     }
120 
121 private:
122     MxEvent* operator&(
123         VOID
124         )
125     {
126         //
127         // By making the address of operator private, we make it harder
128         // to accidentally use this object in an improper fashion, ie
129         // something like this is prevented:
130         //
131         // MxEvent event;
132         // KeWaitForSingleObject(&event, ...);
133         //
134         // However please note that in some cases event pointer is needed when
135         // event is passed around, in which case, GetSelfPointer() is used and
136         // this protection is circumvented. Calling code should be careful
137         // not to pass the pointer to KeWaitForSingleObject in such cases.
138         //
139         ASSERT(FALSE);
140         return NULL;
141     }
142 
143 };
144