3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS kernel
22 * FILE: ntoskrnl/ex/mutant.c
23 * PURPOSE: Synchronization primitives
24 * PROGRAMMER: David Welch (welch@cwcom.net)
29 /* INCLUDES *****************************************************************/
33 #include <internal/debug.h>
35 POBJECT_TYPE ExMutantObjectType
= NULL
;
37 static GENERIC_MAPPING ExpMutantMapping
= {
38 STANDARD_RIGHTS_READ
| SYNCHRONIZE
| MUTANT_QUERY_STATE
,
39 STANDARD_RIGHTS_WRITE
| SYNCHRONIZE
,
40 STANDARD_RIGHTS_EXECUTE
| SYNCHRONIZE
| MUTANT_QUERY_STATE
,
43 /* FUNCTIONS *****************************************************************/
47 ExpCreateMutant(PVOID ObjectBody
,
50 POBJECT_ATTRIBUTES ObjectAttributes
)
52 DPRINT("NtpCreateMutant(ObjectBody %x, Parent %x, RemainingPath %S)\n",
53 ObjectBody
, Parent
, RemainingPath
);
55 if (RemainingPath
!= NULL
&& wcschr(RemainingPath
+1, '\\') != NULL
)
57 return(STATUS_UNSUCCESSFUL
);
60 return(STATUS_SUCCESS
);
65 ExpDeleteMutant(PVOID ObjectBody
)
67 DPRINT("NtpDeleteMutant(ObjectBody %x)\n", ObjectBody
);
69 KeReleaseMutant((PKMUTANT
)ObjectBody
,
77 ExpInitializeMutantImplementation(VOID
)
79 ExMutantObjectType
= ExAllocatePool(NonPagedPool
,sizeof(OBJECT_TYPE
));
81 RtlCreateUnicodeString(&ExMutantObjectType
->TypeName
, L
"Mutant");
83 ExMutantObjectType
->Tag
= TAG('M', 'T', 'N', 'T');
84 ExMutantObjectType
->PeakObjects
= 0;
85 ExMutantObjectType
->PeakHandles
= 0;
86 ExMutantObjectType
->TotalObjects
= 0;
87 ExMutantObjectType
->TotalHandles
= 0;
88 ExMutantObjectType
->PagedPoolCharge
= 0;
89 ExMutantObjectType
->NonpagedPoolCharge
= sizeof(KMUTANT
);
90 ExMutantObjectType
->Mapping
= &ExpMutantMapping
;
91 ExMutantObjectType
->Dump
= NULL
;
92 ExMutantObjectType
->Open
= NULL
;
93 ExMutantObjectType
->Close
= NULL
;
94 ExMutantObjectType
->Delete
= ExpDeleteMutant
;
95 ExMutantObjectType
->Parse
= NULL
;
96 ExMutantObjectType
->Security
= NULL
;
97 ExMutantObjectType
->QueryName
= NULL
;
98 ExMutantObjectType
->OkayToClose
= NULL
;
99 ExMutantObjectType
->Create
= ExpCreateMutant
;
100 ExMutantObjectType
->DuplicationNotify
= NULL
;
102 ObpCreateTypeObject(ExMutantObjectType
);
107 NtCreateMutant(OUT PHANDLE MutantHandle
,
108 IN ACCESS_MASK DesiredAccess
,
109 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
110 IN BOOLEAN InitialOwner
)
115 Status
= ObCreateObject(ExGetPreviousMode(),
124 if (!NT_SUCCESS(Status
))
129 KeInitializeMutant(Mutant
,
132 Status
= ObInsertObject ((PVOID
)Mutant
,
139 ObDereferenceObject(Mutant
);
146 NtOpenMutant(OUT PHANDLE MutantHandle
,
147 IN ACCESS_MASK DesiredAccess
,
148 IN POBJECT_ATTRIBUTES ObjectAttributes
)
150 return(ObOpenObjectByName(ObjectAttributes
,
161 NtQueryMutant(IN HANDLE MutantHandle
,
162 IN MUTANT_INFORMATION_CLASS MutantInformationClass
,
163 OUT PVOID MutantInformation
,
164 IN ULONG MutantInformationLength
,
165 OUT PULONG ResultLength OPTIONAL
)
167 MUTANT_BASIC_INFORMATION SafeMutantInformation
;
171 if (MutantInformationClass
> MutantBasicInformation
)
172 return(STATUS_INVALID_INFO_CLASS
);
174 if (MutantInformationLength
< sizeof(MUTANT_BASIC_INFORMATION
))
175 return(STATUS_INFO_LENGTH_MISMATCH
);
177 Status
= ObReferenceObjectByHandle(MutantHandle
,
183 if (!NT_SUCCESS(Status
))
188 SafeMutantInformation
.Count
= KeReadStateMutant(Mutant
);
189 SafeMutantInformation
.Owned
= (Mutant
->OwnerThread
!= NULL
);
190 SafeMutantInformation
.Abandoned
= Mutant
->Abandoned
;
192 ObDereferenceObject(Mutant
);
194 Status
= MmCopyToCaller(MutantInformation
, &SafeMutantInformation
, sizeof(MUTANT_BASIC_INFORMATION
));
195 if(NT_SUCCESS(Status
))
197 if(ResultLength
!= NULL
)
199 ULONG RetLen
= sizeof(MUTANT_BASIC_INFORMATION
);
200 Status
= MmCopyToCaller(ResultLength
, &RetLen
, sizeof(ULONG
));
204 Status
= STATUS_SUCCESS
;
213 NtReleaseMutant(IN HANDLE MutantHandle
,
214 IN PLONG PreviousCount OPTIONAL
)
220 Status
= ObReferenceObjectByHandle(MutantHandle
,
226 if (!NT_SUCCESS(Status
))
231 Count
= KeReleaseMutant(Mutant
,
235 ObDereferenceObject(Mutant
);
237 if (PreviousCount
!= NULL
)
239 Status
= MmCopyToCaller(PreviousCount
, &Count
, sizeof(LONG
));
243 Status
= STATUS_SUCCESS
;