ReactOS 0.4.15-dev-8102-g108db8f
KeMutex.c File Reference
#include <kmt_test.h>
Include dependency graph for KeMutex.c:

Go to the source code of this file.

Macros

#define ULONGS_PER_POINTER   (sizeof(PVOID) / sizeof(ULONG))
 
#define MUTANT_SIZE   (2 + 6 * ULONGS_PER_POINTER)
 
#define CheckMutex(Mutex, State, New, ExpectedApcDisable)
 
#define CheckApcs(KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, Irql)
 

Functions

static _IRQL_requires_min_ (PASSIVE_LEVEL)
 
static VOID TestMutex (VOID)
 
 START_TEST (KeMutex)
 

Macro Definition Documentation

◆ CheckApcs

#define CheckApcs (   KernelApcsDisabled,
  SpecialApcsDisabled,
  AllApcsDisabled,
  Irql 
)
Value:
do \
{ \
ok_eq_bool(KeAreApcsDisabled(), KernelApcsDisabled || SpecialApcsDisabled); \
ok_eq_int(Thread->KernelApcDisable, KernelApcsDisabled); \
if (pKeAreAllApcsDisabled) \
ok_eq_bool(pKeAreAllApcsDisabled(), AllApcsDisabled); \
ok_eq_int(Thread->SpecialApcDisable, SpecialApcsDisabled); \
ok_irql(Irql); \
} while (0)
_Out_ PKIRQL Irql
Definition: csq.h:179
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
BOOLEAN NTAPI KeAreApcsDisabled(VOID)
Definition: apc.c:958

◆ CheckMutex

#define CheckMutex (   Mutex,
  State,
  New,
  ExpectedApcDisable 
)

◆ MUTANT_SIZE

#define MUTANT_SIZE   (2 + 6 * ULONGS_PER_POINTER)

◆ ULONGS_PER_POINTER

#define ULONGS_PER_POINTER   (sizeof(PVOID) / sizeof(ULONG))

Function Documentation

◆ _IRQL_requires_min_()

static _IRQL_requires_min_ ( PASSIVE_LEVEL  )
static

Definition at line 11 of file KeMutex.c.

24 { \
26 ok_eq_uint((Mutex)->Header.Type, MutantObject); \
27 ok_eq_uint((Mutex)->Header.Abandoned, 0x55); \
28 ok_eq_uint((Mutex)->Header.Size, MUTANT_SIZE); \
29 ok_eq_uint((Mutex)->Header.DpcActive, 0x55); \
30 ok_eq_pointer((Mutex)->Header.WaitListHead.Flink, \
31 &(Mutex)->Header.WaitListHead); \
32 ok_eq_pointer((Mutex)->Header.WaitListHead.Blink, \
33 &(Mutex)->Header.WaitListHead); \
34 if ((State) <= 0) \
35 { \
36 ok_eq_long((Mutex)->Header.SignalState, State); \
37 ok_eq_pointer((Mutex)->MutantListEntry.Flink, &Thread->MutantListHead); \
38 ok_eq_pointer((Mutex)->MutantListEntry.Blink, &Thread->MutantListHead); \
39 ok_eq_pointer(Thread->MutantListHead.Flink, &(Mutex)->MutantListEntry); \
40 ok_eq_pointer(Thread->MutantListHead.Blink, &(Mutex)->MutantListEntry); \
41 ok_eq_pointer((Mutex)->OwnerThread, Thread); \
42 } \
43 else \
44 { \
45 ok_eq_long((Mutex)->Header.SignalState, State); \
46 if (New) \
47 { \
48 ok_eq_pointer((Mutex)->MutantListEntry.Flink, \
49 (PVOID)0x5555555555555555ULL); \
50 ok_eq_pointer((Mutex)->MutantListEntry.Blink, \
51 (PVOID)0x5555555555555555ULL); \
52 } \
53 ok_eq_pointer(Thread->MutantListHead.Flink, &Thread->MutantListHead); \
54 ok_eq_pointer(Thread->MutantListHead.Blink, &Thread->MutantListHead); \
55 ok_eq_pointer((Mutex)->OwnerThread, NULL); \
56 } \
57 ok_eq_uint((Mutex)->Abandoned, 0); \
58 ok_eq_uint((Mutex)->ApcDisable, ExpectedApcDisable); \
59} while (0)
60
61#define CheckApcs(KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, Irql) do \
62{ \
63 ok_eq_bool(KeAreApcsDisabled(), KernelApcsDisabled || SpecialApcsDisabled); \
64 ok_eq_int(Thread->KernelApcDisable, KernelApcsDisabled); \
65 if (pKeAreAllApcsDisabled) \
66 ok_eq_bool(pKeAreAllApcsDisabled(), AllApcsDisabled); \
67 ok_eq_int(Thread->SpecialApcDisable, SpecialApcsDisabled); \
68 ok_irql(Irql); \
69} while (0)
70
71static
72VOID
73TestMutant(VOID)
74{
76 KMUTANT Mutant;
77 LONG State;
78 LONG i;
80
82 RtlFillMemory(&Mutant, sizeof(Mutant), 0x55);
83 KeInitializeMutant(&Mutant, FALSE);
84 CheckMutex(&Mutant, 1L, TRUE, 0);
86
87 RtlFillMemory(&Mutant, sizeof(Mutant), 0x55);
88 KeInitializeMutant(&Mutant, TRUE);
90 CheckMutex(&Mutant, 0L, TRUE, 0);
91 State = KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
93 CheckMutex(&Mutant, 1L, FALSE, 0);
95
96 /* Acquire and release */
100 FALSE,
101 NULL);
103 CheckMutex(&Mutant, 0L, TRUE, 0);
105
106 State = KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
107 ok_eq_long(State, 0L);
108 CheckMutex(&Mutant, 1L, FALSE, 0);
110
111 /* Acquire recursively */
112 for (i = 0; i < 8; i++)
113 {
116 Executive,
118 FALSE,
119 NULL);
122 CheckMutex(&Mutant, -i, FALSE, 0);
124 }
125
126 for (i = 0; i < 7; i++)
127 {
129 State = KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
131 ok_eq_long(State, -7L + i);
132 CheckMutex(&Mutant, -6L + i, FALSE, 0);
134 }
135
136 State = KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
137 ok_eq_long(State, 0L);
138 CheckMutex(&Mutant, 1L, FALSE, 0);
140
141 /* Pretend to acquire it recursively -MINLONG times */
144 Executive,
146 FALSE,
147 NULL);
150 CheckMutex(&Mutant, 0L, FALSE, 0);
152
153 Mutant.Header.SignalState = MINLONG + 1;
156 Executive,
158 FALSE,
159 NULL);
162 CheckMutex(&Mutant, (LONG)MINLONG, FALSE, 0);
164
166 KeWaitForSingleObject(&Mutant,
167 Executive,
169 FALSE,
170 NULL);
172 CheckMutex(&Mutant, (LONG)MINLONG, FALSE, 0);
174
175 State = KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
177 CheckMutex(&Mutant, (LONG)MINLONG + 1L, FALSE, 0);
179
180 Mutant.Header.SignalState = -1;
181 State = KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
182 ok_eq_long(State, -1L);
183 CheckMutex(&Mutant, 0L, FALSE, 0);
185
186 State = KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
187 ok_eq_long(State, 0L);
188 CheckMutex(&Mutant, 1L, FALSE, 0);
190
191 /* Now release it once too often */
193 KeReleaseMutant(&Mutant, 1, FALSE, FALSE);
195 CheckMutex(&Mutant, 1L, FALSE, 0);
197}
#define CheckMutex(Mutex, State, New, ExpectedApcDisable)
#define MUTANT_SIZE
#define CheckApcs(KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, Irql)
#define ok_eq_hex(value, expected)
Definition: apitest.h:77
#define ok_eq_long(value, expected)
Definition: apitest.h:62
LONG NTSTATUS
Definition: precomp.h:26
Definition: Header.h:9
Header(const std::string &filename_)
Definition: Header.h:18
Definition: Mutex.h:16
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define KeGetCurrentThread
Definition: hal.h:55
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:599
#define KmtStartSeh()
Definition: kmt_test.h:282
#define KmtEndSeh(ExpectedStatus)
Definition: kmt_test.h:288
#define for
Definition: utility.h:88
#define KernelMode
Definition: asm.h:34
@ MutantObject
Definition: ketypes.h:408
LONG NTAPI KeReleaseMutant(IN PKMUTANT Mutant, IN KPRIORITY Increment, IN BOOLEAN Abandon, IN BOOLEAN Wait)
Definition: mutex.c:98
VOID NTAPI KeInitializeMutant(IN PKMUTANT Mutant, IN BOOLEAN InitialOwner)
Definition: mutex.c:22
#define STATUS_MUTANT_LIMIT_EXCEEDED
Definition: ntstatus.h:634
#define STATUS_MUTANT_NOT_OWNED
Definition: ntstatus.h:306
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
#define New(t)
Definition: rtf.h:1086
#define STATUS_SUCCESS
Definition: shellext.h:65
#define MINLONG
Definition: umtypes.h:115
_In_ KPRIORITY _In_ BOOLEAN Abandoned
Definition: kefuncs.h:582
@ Executive
Definition: ketypes.h:415

◆ START_TEST()

START_TEST ( KeMutex  )

Definition at line 323 of file KeMutex.c.

324{
325 pKeAreAllApcsDisabled = KmtGetSystemRoutineAddress(L"KeAreAllApcsDisabled");
326 if (skip(pKeAreAllApcsDisabled != NULL, "KeAreAllApcsDisabled unavailable\n"))
327 {
328 /* We can live without this function here */
329 }
330
331 TestMutant();
332 TestMutex();
333}
static VOID TestMutex(VOID)
Definition: KeMutex.c:201
#define skip(...)
Definition: atltest.h:64
PVOID KmtGetSystemRoutineAddress(IN PCWSTR RoutineName)

◆ TestMutex()

static VOID TestMutex ( VOID  )
static

Definition at line 201 of file KeMutex.c.

202{
205 LONG State;
206 LONG i;
208
210 RtlFillMemory(&Mutex, sizeof(Mutex), 0x55);
212 CheckMutex(&Mutex, 1L, TRUE, 1);
214
215 RtlFillMemory(&Mutex, sizeof(Mutex), 0x55);
217 CheckMutex(&Mutex, 1L, TRUE, 1);
219
220 /* Acquire and release */
222 Executive,
224 FALSE,
225 NULL);
227 CheckMutex(&Mutex, 0L, FALSE, 1);
229
231 ok_eq_long(State, 0L);
232 CheckMutex(&Mutex, 1L, FALSE, 1);
234
235 /* Acquire recursively */
236 for (i = 0; i < 8; i++)
237 {
240 Executive,
242 FALSE,
243 NULL);
246 CheckMutex(&Mutex, -i, FALSE, 1);
248 }
249
250 for (i = 0; i < 7; i++)
251 {
255 ok_eq_long(State, -7L + i);
256 CheckMutex(&Mutex, -6L + i, FALSE, 1);
258 }
259
261 ok_eq_long(State, 0L);
262 CheckMutex(&Mutex, 1L, FALSE, 1);
264
265 /* Pretend to acquire it recursively -MINLONG times */
268 Executive,
270 FALSE,
271 NULL);
274 CheckMutex(&Mutex, 0L, FALSE, 1);
276
277 Mutex.Header.SignalState = MINLONG + 1;
280 Executive,
282 FALSE,
283 NULL);
288
291 Executive,
293 FALSE,
294 NULL);
298
301 CheckMutex(&Mutex, (LONG)MINLONG + 1L, FALSE, 1);
303
304 Mutex.Header.SignalState = -1;
306 ok_eq_long(State, -1L);
307 CheckMutex(&Mutex, 0L, FALSE, 1);
309
311 ok_eq_long(State, 0L);
312 CheckMutex(&Mutex, 1L, FALSE, 1);
314
315 /* Now release it once too often */
319 CheckMutex(&Mutex, 1L, FALSE, 1);
321}
VOID NTAPI KeInitializeMutex(IN PKMUTEX Mutex, IN ULONG Level)
Definition: mutex.c:67
LONG NTAPI KeReleaseMutex(IN PKMUTEX Mutex, IN BOOLEAN Wait)
Definition: mutex.c:189

Referenced by START_TEST().