ReactOS 0.4.15-dev-7924-g5949c20
mutant.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel
4 * FILE: ntoskrnl/ex/mutant.c
5 * PURPOSE: Executive Management of Mutants
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 * Thomas Weidenmueller
8 */
9
10/* INCLUDES *****************************************************************/
11
12#include <ntoskrnl.h>
13#define NDEBUG
14#include <debug.h>
15
16/* DATA **********************************************************************/
17
19
21{
26};
27
29{
30 /* MutantBasicInformation */
32};
33
34/* FUNCTIONS *****************************************************************/
35
36VOID
39{
40 DPRINT("ExpDeleteMutant(ObjectBody 0x%p)\n", ObjectBody);
41
42 /* Make sure to release the Mutant */
43 KeReleaseMutant((PKMUTANT)ObjectBody,
45 TRUE,
46 FALSE);
47}
48
49CODE_SEG("INIT")
53{
54 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
57 DPRINT("Creating Mutant Object Type\n");
58
59 /* Create the Event Pair Object Type */
60 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
61 RtlInitUnicodeString(&Name, L"Mutant");
62 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
63 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KMUTANT);
64 ObjectTypeInitializer.GenericMapping = ExpMutantMapping;
65 ObjectTypeInitializer.PoolType = NonPagedPool;
66 ObjectTypeInitializer.DeleteProcedure = ExpDeleteMutant;
67 ObjectTypeInitializer.ValidAccessMask = MUTANT_ALL_ACCESS;
68 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
69 Status = ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ExMutantObjectType);
70 if (!NT_SUCCESS(Status)) return FALSE;
71 return TRUE;
72}
73
74/*
75 * @implemented
76 */
83{
85 HANDLE hMutant;
86 PKMUTANT Mutant;
88 PAGED_CODE();
89 DPRINT("NtCreateMutant(0x%p, 0x%x, 0x%p)\n",
90 MutantHandle, DesiredAccess, ObjectAttributes);
91
92 /* Check if we were called from user-mode */
94 {
95 /* Enter SEH Block */
97 {
98 /* Check handle pointer */
99 ProbeForWriteHandle(MutantHandle);
100 }
102 {
103 /* Return the exception code */
105 }
106 _SEH2_END;
107 }
108
109 /* Create the Mutant Object*/
114 NULL,
115 sizeof(KMUTANT),
116 0,
117 0,
118 (PVOID*)&Mutant);
119
120 /* Check for success */
121 if(NT_SUCCESS(Status))
122 {
123 /* Initialize the Kernel Mutant */
124 DPRINT("Initializing the Mutant\n");
126
127 /* Insert the Object */
128 Status = ObInsertObject((PVOID)Mutant,
129 NULL,
131 0,
132 NULL,
133 &hMutant);
134
135 /* Check for success */
136 if (NT_SUCCESS(Status))
137 {
138 /* Enter SEH for return */
140 {
141 /* Return the handle to the caller */
142 *MutantHandle = hMutant;
143 }
145 {
146 /* Get the exception code */
148 }
149 _SEH2_END;
150 }
151 }
152
153 /* Return Status */
154 return Status;
155}
156
157/*
158 * @implemented
159 */
161NTAPI
165{
166 HANDLE hMutant;
169 PAGED_CODE();
170 DPRINT("NtOpenMutant(0x%p, 0x%x, 0x%p)\n",
171 MutantHandle, DesiredAccess, ObjectAttributes);
172
173 /* Check if we were called from user-mode */
175 {
176 /* Enter SEH Block */
178 {
179 /* Check handle pointer */
180 ProbeForWriteHandle(MutantHandle);
181 }
183 {
184 /* Return the exception code */
186 }
187 _SEH2_END;
188 }
189
190 /* Open the Object */
194 NULL,
196 NULL,
197 &hMutant);
198
199 /* Check for success */
200 if(NT_SUCCESS(Status))
201 {
202 /* Enter SEH for return */
204 {
205 /* Return the handle to the caller */
206 *MutantHandle = hMutant;
207 }
209 {
211 }
212 _SEH2_END;
213 }
214
215 /* Return Status */
216 return Status;
217}
218
219/*
220 * @implemented
221 */
223NTAPI
225 IN MUTANT_INFORMATION_CLASS MutantInformationClass,
226 OUT PVOID MutantInformation,
227 IN ULONG MutantInformationLength,
229{
230 PKMUTANT Mutant;
233 PMUTANT_BASIC_INFORMATION BasicInfo =
234 (PMUTANT_BASIC_INFORMATION)MutantInformation;
235 PAGED_CODE();
236
237 /* Check buffers and parameters */
238 Status = DefaultQueryInfoBufferCheck(MutantInformationClass,
240 sizeof(ExMutantInfoClass) /
241 sizeof(ExMutantInfoClass[0]),
243 MutantInformation,
244 MutantInformationLength,
246 NULL,
248 if(!NT_SUCCESS(Status))
249 {
250 DPRINT("NtQueryMutant() failed, Status: 0x%x\n", Status);
251 return Status;
252 }
253
254 /* Open the Object */
255 Status = ObReferenceObjectByHandle(MutantHandle,
259 (PVOID*)&Mutant,
260 NULL);
261 /* Check for Status */
262 if (NT_SUCCESS(Status))
263 {
264 /* Enter SEH Block for return */
266 {
267 /* Fill out the Basic Information Requested */
268 DPRINT("Returning Mutant Information\n");
269 BasicInfo->CurrentCount = KeReadStateMutant(Mutant);
270 BasicInfo->OwnedByCaller = (Mutant->OwnerThread ==
272 BasicInfo->AbandonedState = Mutant->Abandoned;
273
274 /* Return the Result Length if requested */
276 }
278 {
280 }
281 _SEH2_END;
282
283 /* Release the Object */
284 ObDereferenceObject(Mutant);
285 }
286
287 /* Return Status */
288 return Status;
289}
290
291/*
292 * @implemented
293 */
295NTAPI
297 IN PLONG PreviousCount OPTIONAL)
298{
299 PKMUTANT Mutant;
302 PAGED_CODE();
303 DPRINT("NtReleaseMutant(MutantHandle 0x%p PreviousCount 0x%p)\n",
304 MutantHandle,
305 PreviousCount);
306
307 /* Check if we were called from user-mode */
308 if ((PreviousCount) && (PreviousMode != KernelMode))
309 {
310 /* Entry SEH Block */
312 {
313 /* Make sure the state pointer is valid */
314 ProbeForWriteLong(PreviousCount);
315 }
317 {
318 /* Return the exception code */
320 }
321 _SEH2_END;
322 }
323
324 /* Open the Object */
325 Status = ObReferenceObjectByHandle(MutantHandle,
326 0, /* No access rights required */
329 (PVOID*)&Mutant,
330 NULL);
331
332 /* Check for Success and release if such */
333 if (NT_SUCCESS(Status))
334 {
335 /*
336 * Release the mutant. doing so might raise an exception which we're
337 * required to catch!
338 */
340 {
341 /* Release the mutant */
342 LONG Prev = KeReleaseMutant(Mutant,
344 FALSE,
345 FALSE);
346
347 /* Return the previous count if requested */
348 if (PreviousCount) *PreviousCount = Prev;
349 }
351 {
352 /* Get the exception code */
354 }
355 _SEH2_END;
356
357 /* Dereference it */
358 ObDereferenceObject(Mutant);
359 }
360
361 /* Return Status */
362 return Status;
363}
364
365/* EOF */
#define PAGED_CODE()
#define CODE_SEG(...)
unsigned char BOOLEAN
struct NameRec_ * Name
Definition: cdprocs.h:460
LONG NTSTATUS
Definition: precomp.h:26
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define NonPagedPool
Definition: env_spec_w32.h:307
#define ExGetPreviousMode
Definition: ex.h:140
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
Status
Definition: gdiplustypes.h:25
#define KeGetCurrentThread
Definition: hal.h:55
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:349
#define ICIF_QUERY
Definition: icif.h:18
#define IQS_SAME(Type, Alignment, Flags)
Definition: icif.h:37
#define ICIF_PROBE_READ_WRITE
Definition: icif.h:24
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define OBJ_OPENLINK
Definition: winternl.h:230
VOID NTAPI ExpDeleteMutant(PVOID ObjectBody)
Definition: mutant.c:38
NTSTATUS NTAPI NtQueryMutant(IN HANDLE MutantHandle, IN MUTANT_INFORMATION_CLASS MutantInformationClass, OUT PVOID MutantInformation, IN ULONG MutantInformationLength, OUT PULONG ResultLength OPTIONAL)
Definition: mutant.c:224
GENERIC_MAPPING ExpMutantMapping
Definition: mutant.c:20
NTSTATUS NTAPI NtOpenMutant(OUT PHANDLE MutantHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: mutant.c:162
BOOLEAN NTAPI ExpInitializeMutantImplementation(VOID)
Definition: mutant.c:52
static const INFORMATION_CLASS_INFO ExMutantInfoClass[]
Definition: mutant.c:28
POBJECT_TYPE ExMutantObjectType
Definition: mutant.c:18
NTSTATUS NTAPI NtCreateMutant(OUT PHANDLE MutantHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN BOOLEAN InitialOwner)
Definition: mutant.c:79
NTSTATUS NTAPI NtReleaseMutant(IN HANDLE MutantHandle, IN PLONG PreviousCount OPTIONAL)
Definition: mutant.c:296
#define KernelMode
Definition: asm.h:34
#define MUTANT_ALL_ACCESS
Definition: extypes.h:110
enum _MUTANT_INFORMATION_CLASS MUTANT_INFORMATION_CLASS
struct _MUTANT_BASIC_INFORMATION * PMUTANT_BASIC_INFORMATION
#define MUTANT_INCREMENT
Definition: extypes.h:84
struct _MUTANT_BASIC_INFORMATION MUTANT_BASIC_INFORMATION
#define MUTANT_QUERY_STATE
Definition: extypes.h:109
#define SYNCHRONIZE
Definition: nt_native.h:61
ULONG ACCESS_MASK
Definition: nt_native.h:40
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STANDARD_RIGHTS_READ
Definition: nt_native.h:65
#define STANDARD_RIGHTS_WRITE
Definition: nt_native.h:66
#define STANDARD_RIGHTS_EXECUTE
Definition: nt_native.h:67
static __inline NTSTATUS DefaultQueryInfoBufferCheck(_In_ ULONG Class, _In_ const INFORMATION_CLASS_INFO *ClassList, _In_ ULONG ClassListEntries, _In_ ULONG Flags, _In_opt_ PVOID Buffer, _In_ ULONG BufferLength, _In_opt_ PULONG ReturnLength, _In_opt_ PULONG_PTR ReturnLengthPtr, _In_ KPROCESSOR_MODE PreviousMode)
Probe helper that validates the provided parameters whenever a NtQuery*** system call is invoked from...
Definition: probe.h:219
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
LONG NTAPI KeReadStateMutant(IN PKMUTANT Mutant)
Definition: mutex.c:87
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2935
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2532
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:1039
NTSTATUS NTAPI ObCreateObjectType(IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
Definition: oblife.c:1136
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
long LONG
Definition: pedump.c:60
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
#define ProbeForWriteLong(Ptr)
Definition: probe.h:37
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
#define DPRINT
Definition: sndvol32.h:71
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
BOOLEAN Abandoned
Definition: ketypes.h:844
struct _KTHREAD *RESTRICTED_POINTER OwnerThread
Definition: ketypes.h:843
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
OB_DELETE_METHOD DeleteProcedure
Definition: obtypes.h:369
ULONG DefaultNonPagedPoolCharge
Definition: obtypes.h:365
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_In_ BOOLEAN InitialOwner
Definition: kefuncs.h:565
struct _KMUTANT KMUTANT
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ObDereferenceObject
Definition: obfuncs.h:203
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103