3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ex/mutant.c
6 * PURPOSE: Synchronization primitives
8 * PROGRAMMERS: David Welch (welch@cwcom.net)
11 /* INCLUDES *****************************************************************/
15 #include <internal/debug.h>
17 POBJECT_TYPE ExMutantObjectType
= NULL
;
19 static GENERIC_MAPPING ExpMutantMapping
= {
20 STANDARD_RIGHTS_READ
| SYNCHRONIZE
| MUTANT_QUERY_STATE
,
21 STANDARD_RIGHTS_WRITE
| SYNCHRONIZE
,
22 STANDARD_RIGHTS_EXECUTE
| SYNCHRONIZE
| MUTANT_QUERY_STATE
,
25 static const INFORMATION_CLASS_INFO ExMutantInfoClass
[] =
27 ICI_SQ_SAME( sizeof(MUTANT_BASIC_INFORMATION
), sizeof(ULONG
), ICIF_QUERY
), /* MutantBasicInformation */
30 /* FUNCTIONS *****************************************************************/
34 ExpCreateMutant(PVOID ObjectBody
,
37 POBJECT_ATTRIBUTES ObjectAttributes
)
39 DPRINT("NtpCreateMutant(ObjectBody %x, Parent %x, RemainingPath %S)\n",
40 ObjectBody
, Parent
, RemainingPath
);
42 if (RemainingPath
!= NULL
&& wcschr(RemainingPath
+1, '\\') != NULL
)
44 return(STATUS_UNSUCCESSFUL
);
47 return(STATUS_SUCCESS
);
52 ExpDeleteMutant(PVOID ObjectBody
)
54 DPRINT("NtpDeleteMutant(ObjectBody %x)\n", ObjectBody
);
56 KeReleaseMutant((PKMUTANT
)ObjectBody
,
64 ExpInitializeMutantImplementation(VOID
)
66 ExMutantObjectType
= ExAllocatePool(NonPagedPool
,sizeof(OBJECT_TYPE
));
68 RtlpCreateUnicodeString(&ExMutantObjectType
->TypeName
, L
"Mutant", NonPagedPool
);
70 ExMutantObjectType
->Tag
= TAG('M', 'T', 'N', 'T');
71 ExMutantObjectType
->PeakObjects
= 0;
72 ExMutantObjectType
->PeakHandles
= 0;
73 ExMutantObjectType
->TotalObjects
= 0;
74 ExMutantObjectType
->TotalHandles
= 0;
75 ExMutantObjectType
->PagedPoolCharge
= 0;
76 ExMutantObjectType
->NonpagedPoolCharge
= sizeof(KMUTANT
);
77 ExMutantObjectType
->Mapping
= &ExpMutantMapping
;
78 ExMutantObjectType
->Dump
= NULL
;
79 ExMutantObjectType
->Open
= NULL
;
80 ExMutantObjectType
->Close
= NULL
;
81 ExMutantObjectType
->Delete
= ExpDeleteMutant
;
82 ExMutantObjectType
->Parse
= NULL
;
83 ExMutantObjectType
->Security
= NULL
;
84 ExMutantObjectType
->QueryName
= NULL
;
85 ExMutantObjectType
->OkayToClose
= NULL
;
86 ExMutantObjectType
->Create
= ExpCreateMutant
;
87 ExMutantObjectType
->DuplicationNotify
= NULL
;
89 ObpCreateTypeObject(ExMutantObjectType
);
97 NtCreateMutant(OUT PHANDLE MutantHandle
,
98 IN ACCESS_MASK DesiredAccess
,
99 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
100 IN BOOLEAN InitialOwner
)
102 KPROCESSOR_MODE PreviousMode
;
105 NTSTATUS Status
= STATUS_SUCCESS
;
109 PreviousMode
= ExGetPreviousMode();
111 if(PreviousMode
== UserMode
)
115 ProbeForWrite(MutantHandle
,
121 Status
= _SEH_GetExceptionCode();
125 if(!NT_SUCCESS(Status
))
131 Status
= ObCreateObject(PreviousMode
,
140 if(NT_SUCCESS(Status
))
142 KeInitializeMutant(Mutant
,
145 Status
= ObInsertObject((PVOID
)Mutant
,
151 ObDereferenceObject(Mutant
);
153 if(NT_SUCCESS(Status
))
157 *MutantHandle
= hMutant
;
161 Status
= _SEH_GetExceptionCode();
175 NtOpenMutant(OUT PHANDLE MutantHandle
,
176 IN ACCESS_MASK DesiredAccess
,
177 IN POBJECT_ATTRIBUTES ObjectAttributes
)
180 KPROCESSOR_MODE PreviousMode
;
181 NTSTATUS Status
= STATUS_SUCCESS
;
185 DPRINT("NtOpenMutant(0x%x, 0x%x, 0x%x)\n", MutantHandle
, DesiredAccess
, ObjectAttributes
);
187 PreviousMode
= ExGetPreviousMode();
189 if(PreviousMode
== UserMode
)
193 ProbeForWrite(MutantHandle
,
199 Status
= _SEH_GetExceptionCode();
203 if(!NT_SUCCESS(Status
))
209 Status
= ObOpenObjectByName(ObjectAttributes
,
217 if(NT_SUCCESS(Status
))
221 *MutantHandle
= hMutant
;
225 Status
= _SEH_GetExceptionCode();
238 NtQueryMutant(IN HANDLE MutantHandle
,
239 IN MUTANT_INFORMATION_CLASS MutantInformationClass
,
240 OUT PVOID MutantInformation
,
241 IN ULONG MutantInformationLength
,
242 OUT PULONG ResultLength OPTIONAL
)
245 KPROCESSOR_MODE PreviousMode
;
246 NTSTATUS Status
= STATUS_SUCCESS
;
250 PreviousMode
= ExGetPreviousMode();
252 DefaultQueryInfoBufferCheck(MutantInformationClass
,
255 MutantInformationLength
,
259 if(!NT_SUCCESS(Status
))
261 DPRINT1("NtQueryMutant() failed, Status: 0x%x\n", Status
);
265 Status
= ObReferenceObjectByHandle(MutantHandle
,
271 if(NT_SUCCESS(Status
))
273 switch(MutantInformationClass
)
275 case MutantBasicInformation
:
277 PMUTANT_BASIC_INFORMATION BasicInfo
= (PMUTANT_BASIC_INFORMATION
)MutantInformation
;
281 BasicInfo
->Count
= KeReadStateMutant(Mutant
);
282 BasicInfo
->Owned
= (Mutant
->OwnerThread
!= NULL
);
283 BasicInfo
->Abandoned
= Mutant
->Abandoned
;
285 if(ResultLength
!= NULL
)
287 *ResultLength
= sizeof(MUTANT_BASIC_INFORMATION
);
292 Status
= _SEH_GetExceptionCode();
299 Status
= STATUS_NOT_IMPLEMENTED
;
303 ObDereferenceObject(Mutant
);
314 NtReleaseMutant(IN HANDLE MutantHandle
,
315 IN PLONG PreviousCount OPTIONAL
)
318 KPROCESSOR_MODE PreviousMode
;
319 NTSTATUS Status
= STATUS_SUCCESS
;
323 DPRINT("NtReleaseMutant(MutantHandle 0%x PreviousCount 0%x)\n",
324 MutantHandle
, PreviousCount
);
326 PreviousMode
= ExGetPreviousMode();
328 if(PreviousCount
!= NULL
&& PreviousMode
== UserMode
)
332 ProbeForWrite(PreviousCount
,
338 Status
= _SEH_GetExceptionCode();
342 if(!NT_SUCCESS(Status
))
348 Status
= ObReferenceObjectByHandle(MutantHandle
,
354 if(NT_SUCCESS(Status
))
356 LONG Prev
= KeReleaseMutant(Mutant
, MUTANT_INCREMENT
, 0, FALSE
);
357 ObDereferenceObject(Mutant
);
359 if(PreviousCount
!= NULL
)
363 *PreviousCount
= Prev
;
367 Status
= _SEH_GetExceptionCode();