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 RtlCreateUnicodeString(&ExMutantObjectType
->TypeName
, L
"Mutant");
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
;
107 PreviousMode
= ExGetPreviousMode();
109 if(PreviousMode
== UserMode
)
113 ProbeForWrite(MutantHandle
,
119 Status
= _SEH_GetExceptionCode();
123 if(!NT_SUCCESS(Status
))
129 Status
= ObCreateObject(PreviousMode
,
138 if(NT_SUCCESS(Status
))
140 KeInitializeMutant(Mutant
,
143 Status
= ObInsertObject((PVOID
)Mutant
,
149 ObDereferenceObject(Mutant
);
151 if(NT_SUCCESS(Status
))
155 *MutantHandle
= hMutant
;
159 Status
= _SEH_GetExceptionCode();
173 NtOpenMutant(OUT PHANDLE MutantHandle
,
174 IN ACCESS_MASK DesiredAccess
,
175 IN POBJECT_ATTRIBUTES ObjectAttributes
)
178 KPROCESSOR_MODE PreviousMode
;
179 NTSTATUS Status
= STATUS_SUCCESS
;
181 DPRINT("NtOpenMutant(0x%x, 0x%x, 0x%x)\n", MutantHandle
, DesiredAccess
, ObjectAttributes
);
183 PreviousMode
= ExGetPreviousMode();
185 if(PreviousMode
== UserMode
)
189 ProbeForWrite(MutantHandle
,
195 Status
= _SEH_GetExceptionCode();
199 if(!NT_SUCCESS(Status
))
205 Status
= ObOpenObjectByName(ObjectAttributes
,
213 if(NT_SUCCESS(Status
))
217 *MutantHandle
= hMutant
;
221 Status
= _SEH_GetExceptionCode();
234 NtQueryMutant(IN HANDLE MutantHandle
,
235 IN MUTANT_INFORMATION_CLASS MutantInformationClass
,
236 OUT PVOID MutantInformation
,
237 IN ULONG MutantInformationLength
,
238 OUT PULONG ResultLength OPTIONAL
)
241 KPROCESSOR_MODE PreviousMode
;
242 NTSTATUS Status
= STATUS_SUCCESS
;
244 PreviousMode
= ExGetPreviousMode();
246 DefaultQueryInfoBufferCheck(MutantInformationClass
,
249 MutantInformationLength
,
253 if(!NT_SUCCESS(Status
))
255 DPRINT1("NtQueryMutant() failed, Status: 0x%x\n", Status
);
259 Status
= ObReferenceObjectByHandle(MutantHandle
,
265 if(NT_SUCCESS(Status
))
267 switch(MutantInformationClass
)
269 case MutantBasicInformation
:
271 PMUTANT_BASIC_INFORMATION BasicInfo
= (PMUTANT_BASIC_INFORMATION
)MutantInformation
;
275 BasicInfo
->Count
= KeReadStateMutant(Mutant
);
276 BasicInfo
->Owned
= (Mutant
->OwnerThread
!= NULL
);
277 BasicInfo
->Abandoned
= Mutant
->Abandoned
;
279 if(ResultLength
!= NULL
)
281 *ResultLength
= sizeof(MUTANT_BASIC_INFORMATION
);
286 Status
= _SEH_GetExceptionCode();
293 Status
= STATUS_NOT_IMPLEMENTED
;
297 ObDereferenceObject(Mutant
);
308 NtReleaseMutant(IN HANDLE MutantHandle
,
309 IN PLONG PreviousCount OPTIONAL
)
312 KPROCESSOR_MODE PreviousMode
;
313 NTSTATUS Status
= STATUS_SUCCESS
;
315 DPRINT("NtReleaseMutant(MutantHandle 0%x PreviousCount 0%x)\n",
316 MutantHandle
, PreviousCount
);
318 PreviousMode
= ExGetPreviousMode();
320 if(PreviousCount
!= NULL
&& PreviousMode
== UserMode
)
324 ProbeForWrite(PreviousCount
,
330 Status
= _SEH_GetExceptionCode();
334 if(!NT_SUCCESS(Status
))
340 Status
= ObReferenceObjectByHandle(MutantHandle
,
346 if(NT_SUCCESS(Status
))
348 LONG Prev
= KeReleaseMutant(Mutant
, MUTANT_INCREMENT
, 0, FALSE
);
349 ObDereferenceObject(Mutant
);
351 if(PreviousCount
!= NULL
)
355 *PreviousCount
= Prev
;
359 Status
= _SEH_GetExceptionCode();