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/nt/mutant.c
23 * PURPOSE: Synchronization primitives
24 * PROGRAMMER: David Welch (welch@cwcom.net)
29 /* INCLUDES *****************************************************************/
32 #define NTOS_MODE_KERNEL
34 #include <ntos/synch.h>
35 #include <internal/ob.h>
38 #include <internal/debug.h>
40 POBJECT_TYPE ExMutantObjectType
= NULL
;
42 static GENERIC_MAPPING ExpMutantMapping
= {
43 STANDARD_RIGHTS_READ
| SYNCHRONIZE
| MUTANT_QUERY_STATE
,
44 STANDARD_RIGHTS_WRITE
| SYNCHRONIZE
,
45 STANDARD_RIGHTS_EXECUTE
| SYNCHRONIZE
| MUTANT_QUERY_STATE
,
48 /* FUNCTIONS *****************************************************************/
52 NtpCreateMutant(PVOID ObjectBody
,
55 POBJECT_ATTRIBUTES ObjectAttributes
)
57 DPRINT("NtpCreateMutant(ObjectBody %x, Parent %x, RemainingPath %S)\n",
58 ObjectBody
, Parent
, RemainingPath
);
60 if (RemainingPath
!= NULL
&& wcschr(RemainingPath
+1, '\\') != NULL
)
62 return(STATUS_UNSUCCESSFUL
);
65 return(STATUS_SUCCESS
);
70 NtpDeleteMutant(PVOID ObjectBody
)
72 DPRINT("NtpDeleteMutant(ObjectBody %x)\n", ObjectBody
);
74 KeReleaseMutant((PKMUTANT
)ObjectBody
,
82 NtInitializeMutantImplementation(VOID
)
84 ExMutantObjectType
= ExAllocatePool(NonPagedPool
,sizeof(OBJECT_TYPE
));
86 RtlCreateUnicodeString(&ExMutantObjectType
->TypeName
, L
"Mutant");
88 ExMutantObjectType
->Tag
= TAG('M', 'T', 'N', 'T');
89 ExMutantObjectType
->MaxObjects
= ULONG_MAX
;
90 ExMutantObjectType
->MaxHandles
= ULONG_MAX
;
91 ExMutantObjectType
->TotalObjects
= 0;
92 ExMutantObjectType
->TotalHandles
= 0;
93 ExMutantObjectType
->PagedPoolCharge
= 0;
94 ExMutantObjectType
->NonpagedPoolCharge
= sizeof(KMUTANT
);
95 ExMutantObjectType
->Mapping
= &ExpMutantMapping
;
96 ExMutantObjectType
->Dump
= NULL
;
97 ExMutantObjectType
->Open
= NULL
;
98 ExMutantObjectType
->Close
= NULL
;
99 ExMutantObjectType
->Delete
= NtpDeleteMutant
;
100 ExMutantObjectType
->Parse
= NULL
;
101 ExMutantObjectType
->Security
= NULL
;
102 ExMutantObjectType
->QueryName
= NULL
;
103 ExMutantObjectType
->OkayToClose
= NULL
;
104 ExMutantObjectType
->Create
= NtpCreateMutant
;
105 ExMutantObjectType
->DuplicationNotify
= NULL
;
107 ObpCreateTypeObject(ExMutantObjectType
);
112 NtCreateMutant(OUT PHANDLE MutantHandle
,
113 IN ACCESS_MASK DesiredAccess
,
114 IN POBJECT_ATTRIBUTES ObjectAttributes
,
115 IN BOOLEAN InitialOwner
)
120 Status
= ObCreateObject(ExGetPreviousMode(),
129 if (!NT_SUCCESS(Status
))
134 KeInitializeMutant(Mutant
,
137 Status
= ObInsertObject ((PVOID
)Mutant
,
144 ObDereferenceObject(Mutant
);
151 NtOpenMutant(OUT PHANDLE MutantHandle
,
152 IN ACCESS_MASK DesiredAccess
,
153 IN POBJECT_ATTRIBUTES ObjectAttributes
)
155 return(ObOpenObjectByName(ObjectAttributes
,
166 NtQueryMutant(IN HANDLE MutantHandle
,
167 IN CINT MutantInformationClass
,
168 OUT PVOID MutantInformation
,
170 OUT PULONG ResultLength
)
172 PMUTANT_BASIC_INFORMATION Info
;
176 Info
= (PMUTANT_BASIC_INFORMATION
)MutantInformation
;
178 if (MutantInformationClass
> MutantBasicInformation
)
179 return(STATUS_INVALID_INFO_CLASS
);
181 if (Length
< sizeof(MUTANT_BASIC_INFORMATION
))
182 return(STATUS_INFO_LENGTH_MISMATCH
);
184 Status
= ObReferenceObjectByHandle(MutantHandle
,
190 if (!NT_SUCCESS(Status
))
195 Info
->Count
= KeReadStateMutant(Mutant
);
196 Info
->Owned
= (Mutant
->OwnerThread
!= NULL
);
197 Info
->Abandoned
= Mutant
->Abandoned
;
199 ObDereferenceObject(Mutant
);
201 return(STATUS_SUCCESS
);
206 NtReleaseMutant(IN HANDLE MutantHandle
,
207 IN PULONG ReleaseCount OPTIONAL
)
213 Status
= ObReferenceObjectByHandle(MutantHandle
,
219 if (!NT_SUCCESS(Status
))
224 Count
= KeReleaseMutant(Mutant
,
228 ObDereferenceObject(Mutant
);
230 if (ReleaseCount
!= NULL
)
232 *ReleaseCount
= Count
;
235 return(STATUS_SUCCESS
);